00001 /* 00002 * 00003 * Scheduler class for Win32/CSL/Lua 00004 * Header 00005 * 00006 * Brent Lehman 00007 * 28 November 2003 00008 * 00009 * 00010 */ 00011 00012 00013 // Designed to be run in the program's main thread. 00014 // 00015 // Here's what I have in mind for its use with CSL and Lua: 00016 // 1. Main program does whatever initialization it needs 00017 // 2. Main program instantiates Scheduler, giving it a script 00018 // file and making the Scheduler a global property within 00019 // the script so code within the script can access it 00020 // 3. Scheduler runs Lua script 00021 // 4. Main body of Lua script adds events to Scheduler's queue 00022 // 5. Lua script returns 00023 // 6. Scheduler enters event loop, exiting when queue is empty 00024 // 7. Events take the form of calls to functions in Lua script; 00025 // these functions do whatever they need to do, which might 00026 // include adding new events to the queue 00027 // 00028 // Note that the Lua script functions are still in memory and 00029 // available for execution after the script returns in step 5. 00030 // 00031 // Each event has a time value that specifies when it should 00032 // occur. These time values are relative to the beginning of 00033 // the performance. When the Scheduler receives an event for 00034 // addition to the queue that is out of chronological order 00035 // with respect to the other events on the queue, it backtracks 00036 // from the end until it finds the right spot to add the event. 00037 // The Scheduler also offers a utility for adding a group of 00038 // events that is faster per event than calling the add 00039 // function for each event would be. 00040 // 00041 // Since event times are specified relative to the beginning of 00042 // the performance rather than relative to the last event, a 00043 // script's various functions can add events independently; 00044 // that is, no function need worry about the fact that some 00045 // other function's event might currently be last on the queue. 00046 // Every function can pretend that it's the only one generating 00047 // events. 00048 // 00049 // Thus, some functions that add events need to know what the 00050 // current performance time is. This is mildly annoying 00051 // because musicians using this facility will want to do the 00052 // least possible amount of housekeeping. Another approach 00053 // would be to have multiple "voices", and have each event know 00054 // which voice it belongs to. Then event times could be 00055 // relative to the last event in that same voice and script 00056 // functions wouldn't need to keep track of time. This just 00057 // adds a different kind of housekeeping, though, and could be 00058 // said to be a less elegant solution because of the extra data 00059 // each event would need to carry around. 00060 00061 00062 #ifndef WIN32_LEAN_AND_MEAN 00063 #define WIN32_LEAN_AND_MEAN 00064 #endif 00065 //#include "windows.h" 00066 #include "mmsystem.h" 00067 #include "CSL_Kernel.h" 00068 00069 00070 namespace csl { 00071 00072 struct SchedulerEvent 00073 { 00074 unsigned int time; 00075 char* action; 00076 int action_size; 00077 SchedulerEvent* prev_event; 00078 SchedulerEvent* next_event; 00079 }; 00080 00081 00082 class Scheduler 00083 { 00084 00085 SchedulerEvent* events; 00086 SchedulerEvent* next_event; 00087 SchedulerEvent* last_event; 00088 bool* space_free; 00089 int allocated_spaces; 00090 int filled_spaces; 00091 int first_free_space; 00092 int new_chunk_size; 00093 volatile bool running; 00094 volatile unsigned int earliest_possible_event_time; 00095 int dawn_of_time; 00096 int unsigned now; 00097 volatile int now_precision; 00098 00099 int _find_free_space(); 00100 00101 public: 00102 00103 Scheduler(int starting_size=64, int adding_size=64); 00104 ~Scheduler(); 00105 00106 void add_event(unsigned int time, char* action); 00107 void add_events(unsigned int* times, char** actions, int num_events); 00108 00109 void go(); 00110 void stop(); 00111 00112 bool is_running(); 00113 unsigned int current_time(); 00114 int resolution(); 00115 00116 }; 00117 00118 }
1.4.5-20051010