Skip to content

Commit

Permalink
feat(netobj): ability to respond to the client
Browse files Browse the repository at this point in the history
  • Loading branch information
Wizzerinus committed Dec 18, 2023
1 parent 117803a commit ebb1fd9
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 3 deletions.
8 changes: 8 additions & 0 deletions src/magicnet/core/network_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,12 @@ class NetworkManager(MessengerNode, Generic[AnyNetObject]):

debug_mode: bool = False

current_message: NetMessage | None = dataclasses.field(default=None, init=False)

@property
def current_sender(self) -> ConnectionHandle | None:
return self.current_message.sent_from if self.current_message else None

@property
def managed_objects(self) -> dict[int, AnyNetObject]:
return self.object_manager.managed_objects
Expand Down Expand Up @@ -124,12 +130,14 @@ def process_datagram(self, messages: Iterable[NetMessage]):
if self.debug_mode:
self.emit(StandardEvents.DEBUG, f"Received message: {msg}")

self.current_message = msg
try:
self.dg_processor.process_message(msg)
except Exception as e: # noqa: BLE001
self.emit(
StandardEvents.EXCEPTION, "Error while processing a message", e
)
self.current_message = None

def open_server(self, **kwargs):
"""
Expand Down
10 changes: 8 additions & 2 deletions src/magicnet/netobjects/network_object.py
Original file line number Diff line number Diff line change
Expand Up @@ -261,13 +261,19 @@ def resolve_field(self, message: str) -> tuple[int, int]:
raise errors.UnknownObjectMessage(self.network_name, message)
return self.message_index[message]

def send_message(self, message: str, args: list | tuple = ()) -> None:
def send_message(
self,
message: str,
args: list | tuple = (),
*,
receiver: ConnectionHandle | None = None,
) -> None:
args = unpack_dataclasses(args)
role_id, field_id = self.resolve_field(message)
self.persist_field_data(role_id, field_id, list(args))
if self.object_state == ObjectState.GENERATED:
self.manager.object_manager.request_call_field(
self, role_id, field_id, args
receiver, self, role_id, field_id, args
)

@abc.abstractmethod
Expand Down
11 changes: 10 additions & 1 deletion src/magicnet/netobjects/network_object_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,10 +152,19 @@ def create_remote_object(self, obj: NetworkObject, owner: int = 0):
)
self.manager.send_message(msg)

def request_call_field(self, obj: NetworkObject, role: int, field: int, params):
def request_call_field(
self,
receiver: ConnectionHandle | None,
obj: NetworkObject,
role: int,
field: int,
params,
):
msg = NetMessage(
StandardMessageTypes.SET_OBJECT_FIELD, (obj.oid, role, field, params)
)
if receiver is not None:
msg.destination = receiver
self.manager.send_message(msg)

def request_visible_objects(self):
Expand Down
39 changes: 39 additions & 0 deletions tests/net_objects/test_net_fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,3 +153,42 @@ def net_delete(self) -> None:
cl_object = client.managed_objects.get(srv_object.oid)
assert cl_object.a == 0
assert cl_object.b == 100


def test_message_receiver():
@dataclasses.dataclass
class TestNetObject(NetworkObject):
network_name = "test_obj"
object_role = 0

value: int = 0

@NetworkField
def set_value(self, value: network_types.uint16 = 256):
self.value = value

@NetworkField
def set_my_value(self, val: network_types.uint16 = 256):
self.send_message("set_value", [val], receiver=self.manager.current_sender)

def net_create(self) -> None:
pass

def net_delete(self) -> None:
pass

tester = FlexibleNetworkObjectTester.create_and_start(TestNetObject, TestNetObject)
c1 = tester.make_client()
c2 = tester.make_client()

srv_object = TestNetObject(tester.server)
srv_object.send_message("set_value", [100])
srv_object.request_generate()

c1_object = c1.managed_objects[srv_object.oid]
c2_object = c2.managed_objects[srv_object.oid]
assert c1_object.value == c2_object.value == 100

c2_object.send_message("set_my_value", [200])
assert c2_object.value == 200
assert c1_object.value == 100

0 comments on commit ebb1fd9

Please sign in to comment.