! A priority-daemons extension for Inform libraries 6/5. ! This is a pain in the ass to install, because you have to delete ! a large chunk of parserm and stick in calls to this stuff. Probably ! worthwhile, though. ! This version does not support timers. That's because I never use timers. ! We keep a simple-ass data structure: an array of daemon objects, ! no holes, sorted by priority from highest to lowest. Constant MAX_DAEMONS = 32; ! Constant DAEMONDEBUG; Property daemon_priority 0; Global daemon_index = -1; ! used during daemon iteration Global performing_daemons = false; Global num_daemons = 0; Array daemon_list --> MAX_DAEMONS; [ PerformDaemons obj; performing_daemons = true; #ifdef DAEMONDEBUG; print "^[PerformDaemons: ", num_daemons, " active...]^"; for (daemon_index = 0 : daemon_index < num_daemons : daemon_index++) { obj = daemon_list-->daemon_index; print "[", daemon_index, ": ", (object) obj, " (", obj.daemon_priority, ")]^"; } #endif; for (daemon_index = 0 : deadflag == 0 && daemon_index < num_daemons : daemon_index++) { obj = daemon_list-->daemon_index; #ifdef DAEMONDEBUG; print "[Running daemon ", daemon_index, ": ", (object) obj, " (", obj.daemon_priority, ")]^"; #endif; RunRoutines(obj, daemon); } #ifdef DAEMONDEBUG; print "[Daemons all finished.]^"; #endif; performing_daemons = false; daemon_index = -1; ! always reset to -1 after use ]; [ StartDaemon obj pri ix jx; if (num_daemons >= MAX_DAEMONS) { RunTimeError(4); return; } pri = obj.daemon_priority; for (ix=0 : ixix; if (jx == obj) { return; ! already in daemon list } if (pri > jx.daemon_priority) break; } ! now insert a daemon before object ix. for (jx=num_daemons-1 : jx >= ix : jx--) { daemon_list-->(jx+1) = daemon_list-->jx; } daemon_list-->ix = obj; if (daemon_index >= 0) { ! if the executing daemon is on or after object ix, kick the index forward ! so that it doesn't repeat itself. if (daemon_index >= ix) daemon_index++; } num_daemons++; ]; [ StopDaemon obj ix jx; for (ix=0 : ixix; if (jx == obj) { break; ! already in daemon list } } if (ix >= num_daemons) return; ! not running for (jx=ix : jx < num_daemons-1 : jx++) { daemon_list-->jx = daemon_list-->(jx+1); } daemon_list-->(num_daemons-1) = 0; if (daemon_index >= 0) { ! if the executing daemon is after object ix, kick the index backward ! so that it doesn't repeat itself. If it's equal, kick it backward ! anyway so that the next executing daemon is ix. if (daemon_index >= ix) daemon_index--; } num_daemons--; ];