include "sys.m"; include "draw.m"; include "sets.m"; include "spree.m"; spree := load Spree Spree->PATH; Range, Object, Clique, Member: import spree; Set: import Sets; Archive: import Archives; Range: adt { start: int; end: int; }; Object: adt { transfer: fn(o: self ref Object, r: Range, dst: ref Object, i: int); setvisibility: fn(o: self ref Object, visibility: Set); setattrvisibility: fn(o: self ref Object, name: string, visibility: Set); setattr: fn(o: self ref Object, name: string, val: string, vis: Set); getattr: fn(o: self ref Object, name: string): string; delete: fn(o: self ref Object); deletechildren: fn(o: self ref Object, r: Range); id: int; parentid: int; children: array of ref Object; objtype: string; visibility: Set; # ...private data }; Clique: adt { new: fn(parent: self ref Clique, archive: ref Archive, owner: string): (int, string, string); newobject: fn(clique: self ref Clique, parent: ref Object, visibility: int, objtype: string): ref Object; action: fn(clique: self ref Clique, cmd: string, objs: list of int, rest: string, whoto: int); member: fn(clique: self ref Clique, id: int): ref Member; start: fn(clique: self ref Clique); breakmsg: fn(clique: self ref Clique, whoto: Sets->Set); members: fn(clique: self ref Clique): list of ref Member; owner: fn(clique: self ref Clique): string; hangup: fn(clique: self ref Clique); notify: fn(clique: self ref Clique, cliqueid: int, msg: string); objects: array of ref Object; cliqueid: int; # ...private data }; Member: adt { obj: fn(m: self ref Member, id: int): ref Object; del: fn(m: self ref Member, suspend: int); id: int; name: string; # ...private data }; Engine: module { init: fn(srvmod: Spree, clique: ref Clique, argv: list of string): string; command: fn(member: ref Member, e: string): string; join: fn(member: ref Member , e: string, suspended: int): string; leave: fn(member: ref Member): int; notify: fn(fromid: int, s: string); readfile: fn(f: int, offset: big, count: int): array of byte; }; Archives: module { Archive: adt { argv: list of string; # how to restart the session. members: array of string; # members involved. info: list of (string, string); # any other information. objects: array of ref Object; }; init: fn(mod: Spree); write: fn(clique: ref Clique, info: list of (string, string), file: string, members: Set): string; read: fn(file: string): (ref Archive, string); readheader: fn(file: string): (ref Archive, string); }; rand: fn(n: int): int;
This manual page describes the interface as presented to an engine once it has been loaded by spree. A loaded instance of an engine is responsible for a particular clique, in which one or more members participate. Messages sent by members are interpreted by the engine, which responds by making changes to the hierarchical object database held by the clique. Behind the scenes spree distributes updates to this database to members of the clique as appropriate (see spree(4) for details).
Note that the visibility set of an object does not alter the visibility of that object's attributes, but only that of its children (and of their children: in general an object is visible to a member if the intersection of all its ancestors' visibility sets contains that member).
Objects can be transferred inside the hierarchy from one parent to another. If an object is moved to a parent whose visibility conceals it from a member, then it will appear to that member to have been deleted; if it is later made visible, then it will be recreated for that member. A clique engine can almost always ignore this technicality, except for one thing: the identifier used by a particular member to identify an object is not necessarily the same as that used by the clique engine. Thus when an engine receives an object id in a member's message, it should convert it using the member.obj() function.
Read opens file and returns it as an Archive adt, say a. A.argv holds the command line arguments to the clique module (including the name of the module, its first element); a.members gives the names of all archived members - the id of an archived member is given by its index in the array; a.info gives the list of attributes an values as stored by write; a.objects holds the clique objects. Readheader is just like read except that it parses the header only, so will return an Archive adt such that a.objects is nil.
implement Cliquemodule; include "sys.m"; sys: Sys; include "draw.m"; include "../spree.m"; spree: Spree; Clique, Member: import spree; clique: ref Clique; clienttype(): string { return "chat"; } init(g: ref Clique, srvmod: Spree): string { (sys, clique, spree) = (load Sys Sys->PATH, g, srvmod); return nil; } join(nil: ref Member): string { return nil; } leave(nil: ref Member) { } command(member: ref Member, cmd: string): string { clique.action("say " + string member.id + " " + cmd, nil, nil, ~0); return nil; }
SPREE(2 ) | Rev: Thu Feb 15 14:43:27 GMT 2007 |