00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include <algorithm>
00018
00019 #include "scripting/squirrel_util.hpp"
00020 #include "scripting/time_scheduler.hpp"
00021 #include "util/log.hpp"
00022
00023 namespace scripting {
00024
00025 TimeScheduler* TimeScheduler::instance = NULL;
00026
00027 TimeScheduler::TimeScheduler() :
00028 schedule()
00029 {
00030 }
00031
00032 TimeScheduler::~TimeScheduler()
00033 {
00034 }
00035
00036 void
00037 TimeScheduler::update(float time)
00038 {
00039 while(!schedule.empty() && schedule.front().wakeup_time < time) {
00040 HSQOBJECT thread_ref = schedule.front().thread_ref;
00041
00042 sq_pushobject(global_vm, thread_ref);
00043 sq_getweakrefval(global_vm, -1);
00044
00045 HSQUIRRELVM scheduled_vm;
00046 if(sq_gettype(global_vm, -1) == OT_THREAD &&
00047 SQ_SUCCEEDED(sq_getthread(global_vm, -1, &scheduled_vm))) {
00048 if(SQ_FAILED(sq_wakeupvm(scheduled_vm, SQFalse, SQFalse, SQTrue, SQFalse))) {
00049 std::ostringstream msg;
00050 msg << "Error waking VM: ";
00051 sq_getlasterror(scheduled_vm);
00052 if(sq_gettype(scheduled_vm, -1) != OT_STRING) {
00053 msg << "(no info)";
00054 } else {
00055 const char* lasterr;
00056 sq_getstring(scheduled_vm, -1, &lasterr);
00057 msg << lasterr;
00058 }
00059 log_warning << msg.str() << std::endl;
00060 sq_pop(scheduled_vm, 1);
00061 }
00062 }
00063
00064 sq_release(global_vm, &thread_ref);
00065 sq_pop(global_vm, 2);
00066
00067 std::pop_heap(schedule.begin(), schedule.end());
00068 schedule.pop_back();
00069 }
00070 }
00071
00072 void
00073 TimeScheduler::schedule_thread(HSQUIRRELVM scheduled_vm, float time)
00074 {
00075
00076 SQObject vm_obj = vm_to_object(scheduled_vm);
00077 sq_pushobject(global_vm, vm_obj);
00078 sq_weakref(global_vm, -1);
00079
00080 ScheduleEntry entry;
00081 if(SQ_FAILED(sq_getstackobj(global_vm, -1, & entry.thread_ref))) {
00082 sq_pop(global_vm, 2);
00083 throw SquirrelError(global_vm, "Couldn't get thread weakref from vm");
00084 }
00085 entry.wakeup_time = time;
00086
00087 sq_addref(global_vm, & entry.thread_ref);
00088 sq_pop(global_vm, 2);
00089
00090 schedule.push_back(entry);
00091 std::push_heap(schedule.begin(), schedule.end());
00092 }
00093
00094 }
00095
00096