~ubuntu-branches/ubuntu/vivid/inform/vivid

« back to all changes in this revision

Viewing changes to inform-6.31.1/include/daemons.h

  • Committer: Bazaar Package Importer
  • Author(s): Jan Christoph Nordholz
  • Date: 2008-05-26 22:09:44 UTC
  • mfrom: (2.1.1 lenny)
  • Revision ID: james.westby@ubuntu.com-20080526220944-ba7phz0d1k4vo7wx
Tags: 6.31.1+dfsg-1
* Remove a considerable number of files from the package
  due to unacceptable licensing terms.
* Repair library symlinks.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
! ---------------------------------------------------------------------------- !
 
2
!   Daemons.h by Andrew Plotkin and Roger Firth (roger.firth@tesco.net,
 
3
!                                   to whom all problems should be notified).
 
4
!
 
5
!       2.0 Oct 2001
 
6
!           Converted to Inform 6 and Glulx by Roger Firth.
 
7
!
 
8
!       1.0 Oct 1995
 
9
!           Original version for Inform 5.5 by Andrew Plotkin.
 
10
!
 
11
!   This file is in the public domain.
 
12
! ---------------------------------------------------------------------------- !
 
13
!   Installation: add the lines:
 
14
!
 
15
!       Replace StartDaemon;
 
16
!       Replace StartTimer;
 
17
!
 
18
!   before your Include "Parser" line. Also, add the line:
 
19
!
 
20
!       Include "daemons";
 
21
!
 
22
!   near the end of your game AFTER you've defined an object which uses a
 
23
!   "daemon_priority" property.
 
24
!
 
25
! ---------------------------------------------------------------------------- !
 
26
!
 
27
!   This is a package which you can include to make the daemons and timers of
 
28
!   the Inform libraries behave predictably. They will execute in the order
 
29
!   defined by the optional "daemon_priority" property of each object in the
 
30
!   daemon/timer list. Higher priorities go first; if priorities are equal,
 
31
!   they execute in the order in which they were started up. The default
 
32
!   daemon_priority is zero, but you can assign any numerical value to the
 
33
!   property, including negative ones.
 
34
!
 
35
!   There are a few restrictions:
 
36
!
 
37
!   - daemon_priority must be a simple variable containing a number; it cannot
 
38
!     be an embedded routine which returns a number.
 
39
!   - you should assign a new value to a daemon_priority property only while
 
40
!     the object's daemon/timer is *not* running. This means that if an object
 
41
!     has both a daemon and a timer, they must run at the same priority.
 
42
!   - it is illegal to call StartDaemon() or StartTimer() from inside a
 
43
!     daemon or timer routine. It *is* legal to call StopDaemon() or
 
44
!     StopTimer() at any time.
 
45
!
 
46
!   A bonus utility routine IsDaemonActive(obj) returns 1 if obj currently has
 
47
!   an active daemon, 2 for an active timer, 3 for both, 0 for neither.
 
48
!
 
49
!   Here is an example daemon:
 
50
!
 
51
!   Object  myDaemon
 
52
!     with  daemon_priority 1000,
 
53
!           daemon [;
 
54
!               ...
 
55
!               ];
 
56
!
 
57
! ---------------------------------------------------------------------------- !
 
58
 
 
59
#ifndef WORD_HIGHBIT;               ! Is already defined in Glulx compiler.
 
60
Constant WORD_HIGHBIT $8000;        ! Topmost bit in Z-machine word, used by
 
61
#endif;                             ! the Library to flag daemons in the_timers.
 
62
 
 
63
!   GetPriority() is a utility routine which masks out the daemon-or-timer flag
 
64
!   and fetches the value of the daemon_priority property.
 
65
!
 
66
[ GetPriority obj;
 
67
    obj = obj & ~WORD_HIGHBIT;
 
68
    if (obj provides daemon_priority) return obj.daemon_priority;
 
69
    return 0;
 
70
    ];
 
71
 
 
72
!   StartDaemonOrTimer() is a utility routine which inserts the given object
 
73
!   in the_timers list, at the position defined by its daemon_priority. That is,
 
74
!   the object is inserted after all objects with a greater-or-equal priority,
 
75
!   and before all objects with a lesser priority.
 
76
!
 
77
[ StartDaemonOrTimer obj
 
78
    i j;
 
79
 
 
80
    ! If obj already in the list, do nothing
 
81
    for (i=0 : i<active_timers : i++)
 
82
        if (the_timers-->i == obj) rfalse;
 
83
 
 
84
    ! Compress the list, removing empty slots
 
85
    for (i=0,j=0 : i<active_timers : i++)
 
86
        if (the_timers-->i) {
 
87
            if (i > j) {
 
88
                the_timers-->j = the_timers-->i;
 
89
                the_timers-->i = 0;
 
90
                }
 
91
            j++;
 
92
            }
 
93
 
 
94
    ! Check for capacity to run another daemon/timer
 
95
    active_timers = j;
 
96
    if (active_timers == MAX_TIMERS) { RunTimeError(4); rfalse; }
 
97
 
 
98
    ! Find the first slot at a lower priority
 
99
    for (i=0 : i<active_timers : i++)
 
100
        if (GetPriority(the_timers-->i) <  GetPriority(obj)) break;
 
101
 
 
102
    ! Shift upwards that slot and those above it
 
103
    for ( : j>i : j--) the_timers-->j = the_timers-->(j-1);
 
104
 
 
105
    ! Insert the new object
 
106
    the_timers-->i = obj;
 
107
    return ++active_timers;
 
108
    ];
 
109
 
 
110
!    Replacement for the standard Library version of StartDaemon().
 
111
!
 
112
[ StartDaemon obj;
 
113
    StartDaemonOrTimer(obj+WORD_HIGHBIT);
 
114
    ];
 
115
 
 
116
!    Replacement for the standard Library version of StartTimer().
 
117
!
 
118
[ StartTimer obj timer;
 
119
    if (obj.&time_left == 0) { RunTimeError(5, obj); return; }
 
120
    if (StartDaemonOrTimer(obj)) obj.time_left = timer;
 
121
    ];
 
122
 
 
123
! ---------------------------------------------------------------------------- !
 
124
 
 
125
System_file;
 
126
 
 
127
!   IsDaemonActive() tests whether an object's daemon and/or timer is
 
128
!   currently scheduled to run.
 
129
!
 
130
[ IsDaemonActive obj
 
131
    i j;
 
132
    for (i=0,j=0 : i<active_timers : i++) {
 
133
        if (the_timers-->i == obj) j = 2;
 
134
        else if (the_timers-->i == obj + WORD_HIGHBIT) j++;
 
135
        }
 
136
    return j;
 
137
    ];
 
138
 
 
139
! ---------------------------------------------------------------------------- !
 
140