The Object Network

The NetObject Interface

This is a sketch of a C-based Object Network API, called the NetObject Interface.

The style of programming is reactive and more declarative than imperative. The Object Network creates a network of linked-up objects across hosts and devices that can observe each other's state and react to each other's notifications or state updates.

Example Usage

Here is an Internet of Things example. In the Object Network, you can distribute sensor, actuator and user interface objects onto local and remote networks. Things are represented by managed and distributed objects. You continue to write your sensor/actuator I/O-driving code as usual, but now interact with distributed object representations of those devices, and build your program logic on top of those objects.

net_object* no=net_object_new("light level", evaluate_light_input); net_object_set(no, "light", "0.3 0.2 0.1"); printf(no.uid); // "fe80::..:10bc/f0:21:e8:bb" Host 1: create an object for a light level sensor Set the "light" property to some RGB values Get this host's IPv6 address and that new object's UID
net_object* no=net_object_new("light", evaluate_light_logic, evaluate_light_output); net_object_set(no, "light", "0.5 0.8 0.2"); net_object_set(no, "light-level", "fe80::..:10bc/f0:21:e8:bb"); Host 2: create an object representing a light, These are a list of callbacks called in order - see later linking to the light level sensor by that IP/UID we showed above
boolean evaluate_light_logic(net_object* no){ printf(net_object_get(no, "light-level:light:1")); // "0.3" printf(net_object_get_d(no, "light-level:light:2")); // 0.2 char* ll=net_object_get(no, "light-level:light") if(ll) net_object_set(no, "light", ll); return true; } code to re-evaluate logic and handle I/O on notification also called on first bringing the object up this will be referred to as an "evaluate()" function evaluate() argument is the object observing this is logic code: sets its own light to match the remote sensor you can see through that "light-level" link, right into the "light" property of the sensor object on the other host reading through a link automatically sets up an observation if observed object changes, this evaluate() will be called again re-traversing the link refreshes the observation may return null if either the value is null or it's not been retrieved yet evaluate() called on one of many threads in pool this evaluate() block behaves like a transaction the transaction is opened on first write no other process can then write to this object and this process can't write to any other object any new state is only public after evaluate is done returning 'true' leaves the transaction open and calls next evaluate you should check the "is" of the notified; but only one type here
boolean evaluate_light_output(net_object* no){ printf("new light value: %.2f %.2f %.2f\n", net_object_get_d(no, "light:1"), net_object_get_d(no, "light:2"), net_object_get_d(no, "light:3")); return false; } output callback called after logic one above the callbacks supplied above are each called in order but only if the previous one returns true there's nothing special about any of them they just allow separation of your code into I/O drivers and logic strings with space-separated values can be indexed (base 1) values can be pulled with conversion to float, etc instead of "printf", would go and set the actual light
net_object_run_evaluators(no); boolean evaluate_light_input(net_object* no){ net_object_set_d(no, "light:1", 0.4); net_object_set_d(no, "light:2", 0.5); net_object_set_d(no, "light:3", 0.6); return false; } update the sensor: kick off new evaluate() calls this would be initiated by new sensor input state so those values would be incoming sensor values only this input evaluate() used here, returns false anyway
new light value: 0.4 0.5 0.6the update was notified and the light value set to match
Duncan Cragg, 2016

Contact me and/or subscribe to my blog and/or follow me on Twitter.