annotate recorder.pl @ 15:c91d53b19dbb tip

Meh?
author samer
date Wed, 19 Dec 2012 19:16:30 +0000
parents 24236c9c07b6
children
rev   line source
samer@3 1 :- module(recorder,
samer@3 2 [ recorder/2
samer@3 3 , save_events/1
samer@3 4 , load_events/1
samer@4 5 , get_events/1
samer@3 6 , player/2
samer@3 7 , player/3
samer@3 8 ]).
samer@0 9 /** <module> event recording
samer@0 10
samer@0 11 This module provides a way to capture and record events processed by
samer@0 12 the reactive programming framework of reactive.pl.
samer@0 13 */
samer@3 14 :- meta_predicate recorder(1,?), player(1,?), player(2,2,?).
samer@0 15 :- dynamic start_time/1, event/2.
samer@0 16
samer@0 17 :- use_module(library(fileutils)).
samer@12 18 :- use_module(library(utils),[min/3]).
samer@0 19 :- use_module(reactive).
samer@0 20
samer@0 21
samer@0 22 %% recorder( +Client:ptail, -Proc:process) is det.
samer@0 23 %
samer@0 24 % This predicate represents a reactive process that behaves as Client,
samer@0 25 % but records all events in the Prolog dynamic database. The type signature
samer@0 26 % implies that the term recorder(Client) is of type =|ptail|=. All previously
samer@0 27 % recorded events are deleted first. The time at which this predicate was
samer@0 28 % called is also recorded in the database.
samer@0 29
samer@0 30 recorder(Client,Proc) :-
samer@0 31 get_time(Now),
samer@0 32 retractall(event(_,_)),
samer@0 33 retractall(start_time(_)),
samer@0 34 assert(start_time(Now)),
samer@1 35 format('recording events for ~w.\n',[Client]),
samer@0 36 call(Client,C1),
samer@0 37 recorder_cont(C1,Proc).
samer@0 38
samer@0 39 recorder_on_event(E,C1,Proc) :-
samer@0 40 assert(E),
samer@0 41 step_event(E,C1,C2),
samer@0 42 recorder_cont(C2,Proc).
samer@0 43
samer@0 44 recorder_on_timeout(T,C1,Proc) :-
samer@0 45 step_timeout(T,C1,C2),
samer@0 46 recorder_cont(C2,Proc).
samer@0 47
samer@0 48 recorder_cont(C1,Proc) :-
samer@0 49 get_timeout(C1,T1),
samer@0 50 ( T1=inf
samer@0 51 -> req_message(E^recorder_on_event(E,C1), Proc)
samer@0 52 ; req_message_or_timeout(T1,
samer@0 53 recorder_on_timeout(T1,C1),
samer@0 54 E^recorder_on_event(E,C1), Proc)
samer@0 55 ).
samer@0 56
samer@3 57 %% player( +Client:ptail, +Trans:pred(A,A), -Proc:process) is det.
samer@0 58 %% player( +Client:ptail, -Proc:process) is det.
samer@0 59 %
samer@0 60 % This predicate represents a reactive process that behaves as Client,
samer@0 61 % but plays back events in the Prolog dynamic database. The events are
samer@0 62 % time shifted by the difference between the recorded start time and the
samer@0 63 % time at which player/2 is called. The type signature
samer@0 64 % implies that the term recorder(Client) is of type =|ptail|=.
samer@3 65 %
samer@3 66 % player/3 allows an event transformer pred(+EventIn:A,-EventOut:A) to be
samer@3 67 % specified. player/2 is equivalent to using=/2 as the transformer.
samer@0 68
samer@0 69 player(Client,Proc) :-
samer@0 70 get_time(Now),
samer@0 71 start_time(T0), DT is Now-T0,
samer@0 72 setof(event(T,Msg),T1^(event(T1,Msg),T is DT+T1),Events),
samer@0 73 call(Client,C1),
samer@0 74 player_cont(Events,C1,Proc).
samer@0 75
samer@3 76 player(Client,Trans,Proc) :-
samer@3 77 get_time(Now),
samer@3 78 start_time(T0), DT is Now-T0,
samer@3 79 setof(event(T,Msg),T1^Msg1^(event(T1,Msg1),T is DT+T1, call(Trans,Msg1,Msg)),Events),
samer@3 80 call(Client,C1),
samer@3 81 player_cont(Events,C1,Proc).
samer@3 82
samer@0 83 player_on_event(Events,C1,Proc) :-
samer@0 84 player_cont(Events,C1,Proc).
samer@0 85
samer@0 86 player_on_timeout(T,ET,Events,C1,Proc) :-
samer@0 87 ( T<ET
samer@0 88 -> step_timeout(T,C1,C2),
samer@0 89 player_cont(Events,C2,Proc)
samer@0 90 ; Events=[E1|EX],
samer@0 91 step_event(E1,C1,C2),
samer@0 92 player_cont(EX,C2,Proc)
samer@0 93 ).
samer@0 94
samer@0 95 player_cont([],C1,C1) :- !,
samer@0 96 writeln('Playback finished - continuing in interactive mode').
samer@0 97
samer@0 98 player_cont(Events,C1,Proc) :-
samer@0 99 Events=[event(ET,_)|_],
samer@0 100 get_timeout(C1,T1),
samer@0 101 min(ET,T1,TO),
samer@0 102
samer@0 103 req_message_or_timeout(TO,
samer@0 104 player_on_timeout(TO,ET,Events,C1),
samer@0 105 _^player_on_event(Events,C1), Proc).
samer@0 106
samer@0 107
samer@0 108 %% save_events(+FileName:atom) is det.
samer@0 109 % Save events in the event database to the named file (as Prolog clauses).
samer@0 110 save_events(File) :-
samer@0 111 with_output_to_file(File,(listing(start_time),listing(event))).
samer@0 112
samer@0 113
samer@0 114 %% load_events(+FileName:atom) is det.
samer@0 115 % Load events from the named file to the event database, after removing
samer@0 116 % any events currently in there.
samer@0 117 load_events(File) :-
samer@0 118 retractall(event(_,_)),
samer@0 119 retractall(start_time(_)),
samer@0 120 consult(File).
samer@0 121
samer@4 122
samer@4 123 %% get_events(-Events:list(event)) is det.
samer@4 124 % Gets the currently loaded events as a list. Event times are relative
samer@4 125 % to start time.
samer@4 126 get_events(Events) :-
samer@4 127 start_time(T0),
samer@4 128 setof(event(T,Msg),T1^(event(T1,Msg),T is T1-T0),Events).