Public dispatch system
superclass: EnvirDispatch
experimental.
Dispatchers like Public can be used for any EnvironmentRedirect, such as LazyEnvir and ProxySpace. They cause a mirroring of parts of the environment to multiple locations. This done by sending the code itself, which is very flexible and leightweight but it also means that one has to be careful not to do harm to the other systems. Code is only sent if it interprets without error on the sender side. Timing is still not yet synchronized, although it works pretty well for not too costly code.
see also: public_proxy_space
class methods:
*new(envir) create a new instance (with an EnvironmentRedirect)
*all a dictionary of all available dispatchers. dispatchers with the same name
send to and receive from each other (alternative: provide a sendToName)
*startListen(addr) start to receive messages from the network
addr: whom to listen to. nil: listen to all. (default)
*stopListen stop listening
instance methods:
addresses_(list) a list of addresses (NetAddr) to which to send to.
this list can contain also the sender's address, which it then sends to,
but does not get evaluated.
sendingKeys_(list) keys from which to send (list of symbols). If nil, do not send, if \all, send to all.
listeningKeys_(list) keys at which to receive (list of symbols). If nil, do not send, if \all, send to all.
put(key, obj) put an object in the space (see superclass).
if this key is sending, send object to all. object must be reproducible
as a compileString!. (closed functions, patterns with no open functions)
at(key) returns an object from the space at that key (see superclass).
join(channel, nickname) join a channel with a nickname
leave leave the channel
public_(bool) if public is set to false, no broadcasting happens.
basicSafety_(bool) if true (default), the "worst" commands are rejected - like unixCmd etc.
logSelf_(bool) if logSelf is set to true, my own changes are passed into
the action function (e.g. the log window)
logAll_(bool) if logAll is true, I can see all messages that are coming in,
even if they do not effect me (listeningKeys != \all).
This is only allowed if sendingKeys are set to \all
channel_(name) set / get channel name
nickname_(string) set / get nickname
action_(func) action to be evaluated when receiving a message (optional) function args: dispatch, nickname, key, receivedString
note: if you want to call the os from this action (e.g. for GUI), you need to
use defer { }
makeLogWindow create a log window.
lurk / boss / merge change behaviour diametrically (just try it out)
// example
(
var addresses;
Public.startListen; // start an osc responder to dispatch the messages
addresses = [NetAddr("127.0.0.1", 57120)]; // this is loopback for now. Port must be 57120 (sc-lang)
d = Public.new; // create 2 new instances (one "remote" one "local")
e = Public.new;
d.addresses = addresses; // set the addresses - this can be done at any time laterto add new ones.
e.addresses = addresses;
e.join(\waitingroom, \eve); // join a channel, provide a unique nickname.
d.join(\waitingroom, \ade);
e.sendingKeys = \all; // if keys are set to \all, the spaces are enitirelly open.
d.sendingKeys = \all;
d.listeningKeys = \all;
e.listeningKeys = \all;
// create two new environment redirect (works basically like an environment)
a = EnvironmentRedirect.new;
b = EnvironmentRedirect.new;
// set their dispatch variables. the envir is registered in the dispatch implicitly
a.dispatch = d;
b.dispatch = e;
)
(
e.makeLogWindow; // see what is going on
d.makeLogWindow;
)
// using the environment
a[\x] = 5;
b[\x]; // 5 is in b now as well.
b[\x] = { 1.0.rand };
a[\x].postcs;
a[\x] = Array.rand(20, 0, 10);
b[\x];
b[\x] = "hi adam";
a[\x] = "hi eve";
// clear all.
a.clear;
b.clear;
// using Public with Pdef
(
var addresses;
Public.startListen; // start an osc responder to dispatch the messages
addresses = [NetAddr("127.0.0.1", 57120)]; // this is loopback for now. Port must be 57120 (sc-lang)
d = Public.new; // create 2 new instances (one "remote" one "local")
e = Public.new;
d.addresses = addresses; // set the addresses - this can be done at any time laterto add new ones.
e.addresses = addresses;
e.join(\waitingroom, \eve); // join a channel, provide a unique nickname.
d.join(\waitingroom, \ade);
e.sendingKeys = \all; // if keys are set to \all, the spaces are enitirelly open.
d.sendingKeys = \all;
d.listeningKeys = \all;
e.listeningKeys = \all;
// create a LazyEnvir
a = EnvironmentRedirect.new;
b = EnvironmentRedirect.new;
// set their dispatch variables. the envir is registered in the dispatch implicitly
a.dispatch = d;
b.dispatch = e;
Pdef.all = b;
)
(
e.makeLogWindow; // see what is going on
d.makeLogWindow;
)