Branch data Line data Source code
1 : : // Copyright 2026 HPActor Contributors
2 : : //
3 : : // Licensed under the Apache License, Version 2.0 (the "License");
4 : : // you may not use this file except in compliance with the License.
5 : : // You may obtain a copy of the License at
6 : : //
7 : : // http://www.apache.org/licenses/LICENSE-2.0
8 : : //
9 : : // Unless required by applicable law or agreed to in writing, software
10 : : // distributed under the License is distributed on an "AS IS" BASIS,
11 : : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : : // See the License for the specific language governing permissions and
13 : : // limitations under the License.
14 : :
15 : : #pragma once
16 : :
17 : : #include <hpactor/actor/abstract_actor.hpp>
18 : : #include <hpactor/mailbox/mailbox_policy.hpp>
19 : : #include <hpactor/ref/actor_address.hpp>
20 : : #include <hpactor/ref/actor_proxy.hpp>
21 : :
22 : : #include <variant>
23 : :
24 : : namespace hpactor {
25 : :
26 : : // Forward declaration
27 : : class ActorSystem;
28 : :
29 : : // -----------------------------------------------------------------------------
30 : : // Actor - opaque handle to a local actor
31 : : // -----------------------------------------------------------------------------
32 : : class Actor {
33 : : public:
34 : 115 : Actor() = default;
35 : :
36 : 372 : explicit Actor(std::shared_ptr<AbstractActor> ptr)
37 : 372 : : actor_(std::move(ptr)) {}
38 : :
39 : 48 : ActorId id() const {
40 : 48 : if (actor_) {
41 : 42 : return actor_->id();
42 : : }
43 : 6 : return ActorId{};
44 : : }
45 : :
46 : : ActorType type() const {
47 : : if (actor_) {
48 : : return actor_->type();
49 : : }
50 : : return ActorType{0};
51 : : }
52 : :
53 : 1041 : ActorAddress address() const {
54 : 1041 : if (actor_) {
55 : 1033 : return actor_->address();
56 : : }
57 : 8 : return ActorAddress{};
58 : : }
59 : :
60 : : operator ActorAddress() const {
61 : : return address();
62 : : }
63 : :
64 : 993 : explicit operator bool() const {
65 : 993 : return actor_ != nullptr;
66 : : }
67 : :
68 : : void swap(Actor& other) noexcept {
69 : : actor_.swap(other.actor_);
70 : : }
71 : :
72 : : // Access the underlying actor (for internal use)
73 : 735 : std::shared_ptr<AbstractActor> get() const {
74 : 735 : return actor_;
75 : : }
76 : :
77 : : private:
78 : : std::shared_ptr<AbstractActor> actor_;
79 : : };
80 : :
81 : : // -----------------------------------------------------------------------------
82 : : // ActorRef - unified reference to a local or remote actor
83 : : // -----------------------------------------------------------------------------
84 : : // ActorRef provides location-transparent access to actors. It can hold
85 : : // either a local Actor or a remote ActorProxy, and dispatches operations
86 : : // appropriately based on the underlying reference type.
87 : : // -----------------------------------------------------------------------------
88 : : class ActorRef {
89 : : public:
90 : : // Default constructor creates an invalid reference
91 : 1 : ActorRef() = default;
92 : :
93 : : // Construct from a local actor
94 : 33 : ActorRef(Actor actor) : ref_(std::move(actor)) {}
95 : :
96 : : // Construct from a remote actor proxy
97 : 14 : ActorRef(ActorProxy proxy) : ref_(std::move(proxy)) {}
98 : :
99 : : // Get the actor's address
100 : 337 : ActorAddress address() const {
101 : 337 : if (is_local()) {
102 : 333 : return std::get<Actor>(ref_).address();
103 : : } else {
104 : 4 : return std::get<ActorProxy>(ref_).address();
105 : : }
106 : : }
107 : :
108 : : // Check if this is a local actor
109 : 1339 : bool is_local() const {
110 : 1339 : return std::holds_alternative<Actor>(ref_);
111 : : }
112 : :
113 : : // Check if this actor is valid
114 : 332 : explicit operator bool() const {
115 : 332 : if (is_local()) {
116 : 331 : return static_cast<bool>(std::get<Actor>(ref_));
117 : : } else {
118 : 1 : return static_cast<bool>(std::get<ActorProxy>(ref_));
119 : : }
120 : : }
121 : :
122 : : // Get the endpoint where this actor resides
123 : 1 : EndPoint endpoint() const {
124 : 1 : return address().endpoint;
125 : : }
126 : :
127 : : // Send a message to this actor
128 : : void send(const ActorAddress& target, TypedMessage msg);
129 : :
130 : : // Try-send returning an admission result.
131 : : // For local actors, delegates to ActorSystem::try_deliver_local().
132 : : // For remote actors, delegates to ActorProxy::try_send() (best-effort).
133 : : mailbox::EnqueueResult try_send(const ActorAddress& target, TypedMessage msg,
134 : : mailbox::DeliveryOptions options = {});
135 : :
136 : : // Access underlying Actor (for internal use)
137 : 332 : Actor* get_actor() {
138 : 332 : if (is_local()) {
139 : 332 : return &std::get<Actor>(ref_);
140 : : }
141 : 0 : return nullptr;
142 : : }
143 : :
144 : : // Access underlying ActorProxy (for internal use)
145 : 2 : ActorProxy* get_proxy() {
146 : 2 : if (!is_local()) {
147 : 2 : return &std::get<ActorProxy>(ref_);
148 : : }
149 : 0 : return nullptr;
150 : : }
151 : :
152 : : private:
153 : : std::variant<Actor, ActorProxy> ref_;
154 : : };
155 : :
156 : : } // namespace hpactor
|