ref: 05d9123a707dec0eaa0ab079b94e69cdb750c6db
dir: /appl/spree/spree.m/
Spree: module
{
MAXPLAYERS: con 100;
Attribute: adt {
name: string;
val: string;
visibility: Sets->Set; # set of members that can see attr
needupdate: Sets->Set; # set of members that have not got an update queued
};
Attributes: adt {
a: array of list of ref Attribute;
set: fn(attr: self ref Attributes, name, val: string, vis: Sets->Set): (int, ref Attribute);
get: fn(attr: self ref Attributes, name: string): ref Attribute;
new: fn(): ref Attributes;
};
Range: adt {
start: int;
end: int;
};
Object: adt {
id: int;
attrs: ref Attributes;
visibility: Sets->Set;
parentid: int;
children: cyclic array of ref Object; # not actually cyclic
cliqueid: int;
objtype: string;
transfer: fn(o: self ref Object, r: Range, dst: ref Object, i: int);
setvisibility: fn(o: self ref Object, visibility: Sets->Set);
setattrvisibility: fn(o: self ref Object, name: string, visibility: Sets->Set);
setattr: fn(o: self ref Object, name: string, val: string, vis: Sets->Set);
getattr: fn(o: self ref Object, name: string): string;
delete: fn(o: self ref Object);
deletechildren: fn(o: self ref Object, r: Range);
};
Rq: adt {
pick {
Init =>
opts: string;
Command =>
member: ref Member;
cmd: string;
Join =>
member: ref Member;
cmd: string;
suspended: int;
Leave =>
member: ref Member;
Notify =>
srcid: int;
cmd: string;
}
};
# this might also be known as a "group", as there's nothing
# inherently clique-like about it; it's just a group of members
# mutually creating and manipulating objects.
Clique: adt {
id: int;
fileid: int;
fname: string;
objects: array of ref Object;
archive: ref Archives->Archive;
freelist: list of int;
mod: Engine;
memberids: Sets->Set; # set of allocated member ids
suspended: list of ref Member;
request: chan of ref Rq;
reply: chan of string;
hungup: int;
started: int;
parentid: int;
notes: list of (int, int, string); # (src, dest, note)
new: fn(parent: self ref Clique, archive: ref Archives->Archive, owner: string): (int, string, string); # returns (cliqueid, filename, error)
newobject: fn(clique: self ref Clique, parent: ref Object, visibility: Sets->Set, objtype: string): ref Object;
start: fn(clique: self ref Clique);
action: fn(clique: self ref Clique, cmd: string,
objs: list of int, rest: string, whoto: Sets->Set);
breakmsg: fn(clique: self ref Clique, whoto: Sets->Set);
show: fn(clique: self ref Clique, member: ref Member);
member: fn(clique: self ref Clique, id: int): ref Member;
membernamed: fn(clique: self ref Clique, name: string): ref Member;
members: fn(clique: self ref Clique): list of ref Member;
owner: fn(clique: self ref Clique): string;
hangup: fn(clique: self ref Clique);
fcreate: fn(clique: self ref Clique, i: int, pq: int, d: Sys->Dir): string;
fremove: fn(clique: self ref Clique, i: int): string;
notify: fn(clique: self ref Clique, cliqueid: int, msg: string);
};
# a Member is involved in one clique only
Member: adt {
id: int;
cliqueid: int;
obj2ext: array of int;
ext2obj: array of ref Object;
freelist: list of int;
name: string;
updating: int;
suspended: int;
ext: fn(member: self ref Member, id: int): int;
obj: fn(member: self ref Member, id: int): ref Object;
del: fn(member: self ref Member, suspend: int);
};
init: fn(ctxt: ref Draw->Context, argv: list of string);
archivenames: fn(): list of string;
newarchivename: fn(): string;
rand: fn(n: int): int;
};
Engine: module {
init: fn(srvmod: Spree, clique: ref Spree->Clique, argv: list of string): string;
command: fn(member: ref Spree->Member, e: string): string;
join: fn(member: ref Spree->Member , e: string, suspended: int): string;
leave: fn(member: ref Spree->Member): int;
notify: fn(fromid: int, s: string);
readfile: fn(f: int, offset: big, count: int): array of byte;
};
Archives: module {
PATH: con "/dis/spree/archives.dis";
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 Spree->Object;
};
init: fn(mod: Spree);
write: fn(clique: ref Spree->Clique, info: list of (string, string), file: string, members: Sets->Set): string;
read: fn(file: string): (ref Archive, string);
readheader: fn(file: string): (ref Archive, string);
};