Merge pull request #542 from worktycho/schedular
added cWorld::ScheduleTask Function
This commit is contained in:
commit
eb89de4c88
@ -941,10 +941,6 @@ protected:
|
|||||||
}
|
}
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int tolua_cWorld_QueueTask(lua_State * tolua_S)
|
static int tolua_cWorld_QueueTask(lua_State * tolua_S)
|
||||||
{
|
{
|
||||||
// Binding for cWorld::QueueTask
|
// Binding for cWorld::QueueTask
|
||||||
@ -980,7 +976,65 @@ static int tolua_cWorld_QueueTask(lua_State * tolua_S)
|
|||||||
return 0;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -690,6 +690,7 @@ void cWorld::Tick(float a_Dt, int a_LastTickDurationMSec)
|
|||||||
TickClients(a_Dt);
|
TickClients(a_Dt);
|
||||||
TickQueuedBlocks();
|
TickQueuedBlocks();
|
||||||
TickQueuedTasks();
|
TickQueuedTasks();
|
||||||
|
TickScheduledTasks();
|
||||||
|
|
||||||
GetSimulatorManager()->Simulate(a_Dt);
|
GetSimulatorManager()->Simulate(a_Dt);
|
||||||
|
|
||||||
@ -861,6 +862,31 @@ void cWorld::TickQueuedTasks(void)
|
|||||||
} // for itr - m_Tasks[]
|
} // 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);
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
24
src/World.h
24
src/World.h
@ -82,7 +82,18 @@ public:
|
|||||||
virtual void Run(cWorld & a_World) = 0;
|
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::vector<cTask *> cTasks;
|
||||||
|
typedef std::list<cScheduledTask *> ScheduledTaskList;
|
||||||
|
|
||||||
class cTaskSaveAllChunks :
|
class cTaskSaveAllChunks :
|
||||||
public cTask
|
public cTask
|
||||||
@ -534,6 +545,9 @@ public:
|
|||||||
/// Queues a task onto the tick thread. The task object will be deleted once the task is finished
|
/// 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
|
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
|
/// Returns the number of chunks loaded
|
||||||
int GetNumChunks() const; // tolua_export
|
int GetNumChunks() const; // tolua_export
|
||||||
|
|
||||||
@ -745,9 +759,16 @@ private:
|
|||||||
/// Guards the m_Tasks
|
/// Guards the m_Tasks
|
||||||
cCriticalSection m_CSTasks;
|
cCriticalSection m_CSTasks;
|
||||||
|
|
||||||
|
/// Guards the m_ScheduledTasks
|
||||||
|
cCriticalSection m_CSScheduledTasks;
|
||||||
|
|
||||||
/// Tasks that have been queued onto the tick thread; guarded by m_CSTasks
|
/// Tasks that have been queued onto the tick thread; guarded by m_CSTasks
|
||||||
cTasks m_Tasks;
|
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
|
/// Guards m_Clients
|
||||||
cCriticalSection m_CSClients;
|
cCriticalSection m_CSClients;
|
||||||
|
|
||||||
@ -775,6 +796,9 @@ private:
|
|||||||
/// Executes all tasks queued onto the tick thread
|
/// Executes all tasks queued onto the tick thread
|
||||||
void TickQueuedTasks(void);
|
void TickQueuedTasks(void);
|
||||||
|
|
||||||
|
/// Executes all tasks queued onto the tick thread
|
||||||
|
void TickScheduledTasks(void);
|
||||||
|
|
||||||
/// Ticks all clients that are in this world
|
/// Ticks all clients that are in this world
|
||||||
void TickClients(float a_Dt);
|
void TickClients(float a_Dt);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user