Skip to content

Commit

Permalink
Merge pull request #8 from arduino/msgpackrpc_api_update
Browse files Browse the repository at this point in the history
lib/msgpackrpc: Require a name when binding callables.
  • Loading branch information
iabdalkader committed Apr 11, 2024
2 parents 277efd5 + 932c256 commit 8942475
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 26 deletions.
48 changes: 38 additions & 10 deletions lib/msgpackrpc/example.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,38 @@
import gc


class Adder:
def __init__(self):
pass

def add(self, a, b):
logging.info(f"add({a}, {b}) is called")
return a + b
def add(a, b):
logging.info(f"add({a}, {b}) is called")
return a + b


def sub(a, b):
logging.info(f"sub({a}, {b}) is called")
return a - b


class Foo:
def __init__(self, name):
self.name = name

def add(self, a, b):
logging.info(f"{self.name}.add({a}, {b}) is called")
return a + b

def sub(self, a, b):
logging.info(f"{self.name}.sub({a}, {b}) is called")
return a - b


class Adder:
def __init__(self):
pass

def __call__(self, a, b):
logging.info(f"Adder({a}, {b}) is called")
return a + b


if __name__ == "__main__":
# Configure the logger.
# All message equal to or higher than the logger level are printed.
Expand All @@ -34,9 +52,19 @@ def sub(a, b):
# Create an RPC object
rpc = msgpackrpc.MsgPackRPC()

# Register objects or functions to be called by the remote processor.
rpc.bind(Adder())
rpc.bind(sub)
# Register remote functions.
rpc.bind("sub", sub)
rpc.bind("add", add)

# Register a callable object.
rpc.bind("adder", Adder())

# Register full objects. The following binds all public methods of an object to their
# respective qualified names. For instance, `foo1`'s methods will be bound to `foo1.add`
# and `foo1.sub`. Alternatively, bound methods can be registered individually, by calling
# bind on each method. For example, `rpc.bind("foo.add", foo.add)`.
rpc.bind("foo1", Foo("foo1"))
rpc.bind("foo2", Foo("foo2"))

# Start the remote processor and wait for it to be ready to communicate.
rpc.start(firmware=0x08180000, timeout=1000, num_channels=2)
Expand Down
33 changes: 17 additions & 16 deletions lib/msgpackrpc/msgpackrpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ def __init__(self, streaming=False):
self.msgid = 0
self.msgbuf = {}
self.msgio = MsgPackIO() if streaming else None
self.servers = []
self.callables = {}

def _bind_callback(self, src, name):
if log_level_enabled(logging.INFO):
Expand Down Expand Up @@ -135,30 +135,31 @@ def _send_msg(self, msgid, msgtype, fname, fargs, **kwargs):
return Future(msgid, self.msgbuf, fname, fargs)

def _dispatch(self, msgid, fname, fargs):
func = None
retobj = None
error = None
for obj in self.servers:
if callable(obj) and obj.__name__ == fname:
func = obj
elif hasattr(obj, fname):
func = getattr(obj, fname)
if func is not None:
break

if func is not None:
retobj = func(*fargs)

if fname in self.callables:
retobj = self.callables[fname](*fargs)
else:
error = "Unbound function called %s" % (fname)

self._send_msg(msgid, _MSG_TYPE_RESPONSE, error, retobj)

def bind(self, obj):
def bind(self, name, obj):
"""
Register an object or a function to be called by the remote processor.
obj: An object whose methods can be called by remote processors, or a function.
Bind a callable or an object to a name.
name: The name to which the callable or object is bound.
obj: A callable or an object to bind to the name. If an object is passed, all of its
public methods will be bound to their respective qualified names.
"""
self.servers.append(obj)
if callable(obj):
# Bind a single callable to its name.
self.callables[name] = obj
else:
# Bind all public methods of an object to their respective qualified names.
for k, v in obj.__class__.__dict__.items():
if callable(v) and not k.startswith("_"):
self.callables[name + "." + k] = getattr(obj, k)

def start(self, firmware=None, num_channels=2, timeout=3000):
"""
Expand Down

0 comments on commit 8942475

Please sign in to comment.