src/scripting/thread_queue.cpp

Go to the documentation of this file.
00001 //  SuperTux
00002 //  Copyright (C) 2006 Matthias Braun <matze@braunis.de>
00003 //
00004 //  This program is free software: you can redistribute it and/or modify
00005 //  it under the terms of the GNU General Public License as published by
00006 //  the Free Software Foundation, either version 3 of the License, or
00007 //  (at your option) any later version.
00008 //
00009 //  This program is distributed in the hope that it will be useful,
00010 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 //  GNU General Public License for more details.
00013 //
00014 //  You should have received a copy of the GNU General Public License
00015 //  along with this program.  If not, see <http://www.gnu.org/licenses/>.
00016 
00017 #include "scripting/thread_queue.hpp"
00018 
00019 #include "scripting/squirrel_util.hpp"
00020 #include "util/log.hpp"
00021 
00022 namespace scripting
00023 {
00024 
00025 ThreadQueue::ThreadQueue() :
00026   threads()
00027 {
00028 }
00029 
00030 ThreadQueue::~ThreadQueue()
00031 {
00032 }
00033 
00034 void
00035 ThreadQueue::add(HSQUIRRELVM vm)
00036 {
00037   // create a weakref to the VM
00038   HSQOBJECT vm_obj = vm_to_object(vm);
00039   sq_pushobject(global_vm, vm_obj);
00040   sq_weakref(global_vm, -1);
00041 
00042   HSQOBJECT object;
00043   if(SQ_FAILED(sq_getstackobj(global_vm, -1, &object))) {
00044     sq_pop(global_vm, 2);
00045     throw SquirrelError(global_vm, "Couldn't get thread weakref from vm");
00046   }
00047   sq_addref(global_vm, &object);
00048   threads.push_back(object);
00049 
00050   sq_pop(global_vm, 2);
00051 }
00052 
00053 void
00054 ThreadQueue::wakeup()
00055 {
00056   // we traverse the list in reverse orders and use indices. This should be
00057   // robust for scripts that add new entries to the list while we're traversing
00058   // it
00059   size_t i = threads.size() - 1;
00060   size_t end = (size_t) 0 - 1;
00061   size_t size_begin = threads.size();
00062   while(i != end) {
00063     HSQOBJECT object = threads[i];
00064 
00065     sq_pushobject(global_vm, object);
00066     sq_getweakrefval(global_vm, -1);
00067 
00068     HSQUIRRELVM scheduled_vm;
00069     if(sq_gettype(global_vm, -1) == OT_THREAD &&
00070        SQ_SUCCEEDED(sq_getthread(global_vm, -1, &scheduled_vm))) {
00071       if(SQ_FAILED(sq_wakeupvm(scheduled_vm, SQFalse, SQFalse, SQTrue, SQFalse))) {
00072         log_warning << "Couldn't wakeup scheduled squirrel VM" << std::endl;
00073       }
00074     }
00075 
00076     sq_release(global_vm, &object);
00077     sq_pop(global_vm, 1);
00078     i--;
00079   }
00080 
00081   threads.erase(threads.begin(), threads.begin() + size_begin);
00082 }
00083 
00084 }
00085 
00086 /* EOF */

Generated on Mon Jun 9 03:38:21 2014 for SuperTux by  doxygen 1.5.1