1
0
Fork 0

added cWorld::ScheduleTask Function

ScheduleTask schedules a SceduledTask object to be run x ticks in the future.
In is exported to lua, fixes #150
This commit is contained in:
Tycho 2014-01-14 12:17:03 -08:00
parent f31043a5e7
commit 292ccdc09e
3 changed files with 121 additions and 4 deletions

View File

@ -941,10 +941,6 @@ protected:
}
} ;
static int tolua_cWorld_QueueTask(lua_State * tolua_S)
{
// Binding for cWorld::QueueTask
@ -980,7 +976,65 @@ static int tolua_cWorld_QueueTask(lua_State * tolua_S)
return 0;
}
class cLuaScheduledWorldTask :
public cWorld::cScheduledTask
{
public:
cLuaScheduledWorldTask(cPluginLua & a_Plugin, int a_FnRef, int a_Ticks) :
cScheduledTask(a_Ticks),
m_Plugin(a_Plugin),
m_FnRef(a_FnRef)
{
}
protected:
cPluginLua & m_Plugin;
int m_FnRef;
// cWorld::cTask overrides:
virtual void Run(cWorld & a_World) override
{
m_Plugin.Call(m_FnRef, &a_World);
}
};
static int tolua_cWorld_ScheduleTask(lua_State * tolua_S)
{
// Binding for cWorld::ScheduleTask
// Params: function, Ticks
// Retrieve the cPlugin from the LuaState:
cPluginLua * Plugin = GetLuaPlugin(tolua_S);
if (Plugin == NULL)
{
// An error message has been already printed in GetLuaPlugin()
return 0;
}
// Retrieve the args:
cWorld * self = (cWorld *)tolua_tousertype(tolua_S, 1, 0);
if (self == NULL)
{
return lua_do_error(tolua_S, "Error in function call '#funcname#': Not called on an object instance");
}
if (!lua_isfunction(tolua_S, 2))
{
return lua_do_error(tolua_S, "Error in function call '#funcname#': Expected a function for parameter #1");
}
// Create a reference to the function:
int FnRef = luaL_ref(tolua_S, LUA_REGISTRYINDEX);
if (FnRef == LUA_REFNIL)
{
return lua_do_error(tolua_S, "Error in function call '#funcname#': Could not get function reference of parameter #1");
}
int Ticks = (int) tolua_tonumber (tolua_S, 3, 0);
self->ScheduleTask(new cLuaScheduledWorldTask(*Plugin, FnRef,Ticks));
return 0;
}

View File

@ -690,6 +690,7 @@ void cWorld::Tick(float a_Dt, int a_LastTickDurationMSec)
TickClients(a_Dt);
TickQueuedBlocks();
TickQueuedTasks();
TickScheduledTasks();
GetSimulatorManager()->Simulate(a_Dt);
@ -861,6 +862,31 @@ void cWorld::TickQueuedTasks(void)
} // for itr - m_Tasks[]
}
void cWorld::TickScheduledTasks()
{
ScheduledTaskList Tasks;
// Make a copy of the tasks to avoid deadlocks on accessing m_Tasks
{
cCSLock Lock(m_CSScheduledTasks);
ScheduledTaskList::iterator itr = m_ScheduledTasks.begin();
while (itr != m_ScheduledTasks.end() && (*itr)->Ticks > 0)
{
Tasks.push_back(m_ScheduledTasks.front());
m_ScheduledTasks.pop_front();
}
for(;itr != m_ScheduledTasks.end(); itr++)
{
(*itr)->Ticks--;
}
}
// Execute and delete each task:
for (ScheduledTaskList::iterator itr = Tasks.begin(), end = Tasks.end(); itr != end; ++itr)
{
(*itr)->Run(*this);
delete *itr;
} // for itr - m_Tasks[]
}
@ -2571,6 +2597,19 @@ void cWorld::QueueTask(cTask * a_Task)
m_Tasks.push_back(a_Task);
}
void cWorld::ScheduleTask(cScheduledTask * a_Task)
{
cCSLock Lock(m_CSScheduledTasks);
for(ScheduledTaskList::iterator itr = m_ScheduledTasks.begin(); itr != m_ScheduledTasks.end(); itr++)
{
if((*itr)->Ticks >= a_Task->Ticks)
{
m_ScheduledTasks.insert(itr, a_Task);
return;
}
}
m_ScheduledTasks.push_back(a_Task);
}

View File

@ -82,7 +82,18 @@ public:
virtual void Run(cWorld & a_World) = 0;
} ;
/// A common ancestor for all scheduled tasks queued onto the tick thread
class cScheduledTask
{
public:
cScheduledTask(const int a_Ticks) : Ticks(a_Ticks) {};
virtual ~cScheduledTask() {};
virtual void Run(cWorld & a_World) = 0;
int Ticks;
};
typedef std::vector<cTask *> cTasks;
typedef std::list<cScheduledTask *> ScheduledTaskList;
class cTaskSaveAllChunks :
public cTask
@ -533,6 +544,9 @@ public:
/// Queues a task onto the tick thread. The task object will be deleted once the task is finished
void QueueTask(cTask * a_Task); // Exported in ManualBindings.cpp
// Queues a task onto the tick thread. The task object will be deleted once the task is finished
void ScheduleTask(cScheduledTask * a_Task);
/// Returns the number of chunks loaded
int GetNumChunks() const; // tolua_export
@ -745,9 +759,16 @@ private:
/// Guards the m_Tasks
cCriticalSection m_CSTasks;
/// Guards the m_ScheduledTasks
cCriticalSection m_CSScheduledTasks;
/// Tasks that have been queued onto the tick thread; guarded by m_CSTasks
cTasks m_Tasks;
/// Tasks that have been queued to be executed on the tick thread at some number of ticks in
/// the future; guarded by m_CSScheduledTasks
ScheduledTaskList m_ScheduledTasks;
/// Guards m_Clients
cCriticalSection m_CSClients;
@ -775,6 +796,9 @@ private:
/// Executes all tasks queued onto the tick thread
void TickQueuedTasks(void);
/// Executes all tasks queued onto the tick thread
void TickScheduledTasks(void);
/// Ticks all clients that are in this world
void TickClients(float a_Dt);