/* Synchro Server - DMS - Aug. '98 - by Marc BARILLEY */ /* rev' - 01.2001 - by Julien ZORKO */ typeof NbPorts=I;; /* number of entries (initialized in the IniDMI function */ typeof states = [[CLIENT tab [I S]] r1];; /* [client tab [flag param]] */ /* this function return TRUE when the client in the tuple x ([CLIENT tab [I S]]) is the same as cli */ fun stateByClient (x, cli)= let x -> [c t] in c==cli;; /*--------------------------------- recursive function which send all the events buffered. - i is a counter (must be 0) - cli is the client to which the event will be sent - t is the table of the events -----------------------------------*/ fun seq (i, cli, t)= if i >= NbPorts then 0 else let t.i -> [_ param] in { _DMSevent this cli strcat "out" itoa i param nil; seq i+1 cli t } ;; /* test if all the port for a given client have been activated */ fun allFired (t, i)= if i>=NbPorts then 1 else let t.i -> [flag _] in flag && (allFired t i+1) ;; /* put all the client action port states to 0 (inactivated) */ fun reset (t, i)= if i>=NbPorts then t else ( set t.i = [0 nil]; reset t i+1 ) ;; /* This function computes an action 'in' */ fun ActivateIn (from, cli, i, param, rep) = let search_in_list states @stateByClient cli -> [client t] in ( /* if this is a new client, it is added to the list (states) */ if client == nil then ( set t = mktab NbPorts [0 nil]; set states = [cli t]::states ) else nil; /* the port state of the client is activated */ set t.i = [1 param]; /* if all the client ports are activated, the events are generated */ if allFired t 0 then ( seq 0 cli t; reset t 0; 0 ) else nil ) ;; /* Function called each time that an action port is activated */ fun activate (from, cli, action, param, rep)= if NbPorts==nil || NbPorts<=0 then nil else /*-- in --*/ if !strcmp substr action 0 2 "in" then let atoi substr action 2 (strlen action)-2 -> i in ActivateIn from cli i param rep /*-- now --*/ else if !strcmp action "now" then let search_in_list states @stateByClient cli -> [c t] in { seq 0 c t; 0 } /*-- reset --*/ else if !strcmp action "reset" then let search_in_list states @stateByClient cli -> [c t] in { reset t 0; 0 } else nil ;; fun logout (cli)= let search_in_list states @stateByClient cli -> s in set states = remove_from_list states s; 0;; fun IniDMI (param)= _DMSregisterDMI this @activate @logout @logout nil; let strextr _getpack _checkpack param ->l in set NbPorts=atoi getInfo l "synchro";;