Merge pull request #2463 from cuberite/fixes
Prepared ScheduleTask for threading refactor
This commit is contained in:
commit
422bcef8ca
@ -374,7 +374,6 @@ static int tolua_cWorld_PrepareChunk(lua_State * tolua_S)
|
|||||||
|
|
||||||
|
|
||||||
class cLuaWorldTask :
|
class cLuaWorldTask :
|
||||||
public cWorld::cTask,
|
|
||||||
public cPluginLua::cResettable
|
public cPluginLua::cResettable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -384,11 +383,7 @@ public:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
void Run(cWorld & a_World)
|
||||||
int m_FnRef;
|
|
||||||
|
|
||||||
// cWorld::cTask overrides:
|
|
||||||
virtual void Run(cWorld & a_World) override
|
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CSPlugin);
|
cCSLock Lock(m_CSPlugin);
|
||||||
if (m_Plugin != nullptr)
|
if (m_Plugin != nullptr)
|
||||||
@ -396,6 +391,9 @@ protected:
|
|||||||
m_Plugin->Call(m_FnRef, &a_World);
|
m_Plugin->Call(m_FnRef, &a_World);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
int m_FnRef;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -433,9 +431,9 @@ static int tolua_cWorld_QueueTask(lua_State * tolua_S)
|
|||||||
return cManualBindings::lua_do_error(tolua_S, "Error in function call '#funcname#': Could not get function reference of parameter #1");
|
return cManualBindings::lua_do_error(tolua_S, "Error in function call '#funcname#': Could not get function reference of parameter #1");
|
||||||
}
|
}
|
||||||
|
|
||||||
auto task = std::make_shared<cLuaWorldTask>(*Plugin, FnRef);
|
auto ResettableTask = std::make_shared<cLuaWorldTask>(*Plugin, FnRef);
|
||||||
Plugin->AddResettable(task);
|
Plugin->AddResettable(ResettableTask);
|
||||||
self->QueueTask(task);
|
self->QueueTask(std::bind(&cLuaWorldTask::Run, ResettableTask, std::placeholders::_1));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -483,35 +481,6 @@ static int tolua_cWorld_SetSignLines(lua_State * tolua_S)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
class cLuaScheduledWorldTask :
|
|
||||||
public cWorld::cTask,
|
|
||||||
public cPluginLua::cResettable
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
cLuaScheduledWorldTask(cPluginLua & a_Plugin, int a_FnRef) :
|
|
||||||
cPluginLua::cResettable(a_Plugin),
|
|
||||||
m_FnRef(a_FnRef)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
int m_FnRef;
|
|
||||||
|
|
||||||
// cWorld::cTask overrides:
|
|
||||||
virtual void Run(cWorld & a_World) override
|
|
||||||
{
|
|
||||||
cCSLock Lock(m_CSPlugin);
|
|
||||||
if (m_Plugin != nullptr)
|
|
||||||
{
|
|
||||||
m_Plugin->Call(m_FnRef, &a_World);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int tolua_cWorld_ScheduleTask(lua_State * tolua_S)
|
static int tolua_cWorld_ScheduleTask(lua_State * tolua_S)
|
||||||
{
|
{
|
||||||
// Binding for cWorld::ScheduleTask
|
// Binding for cWorld::ScheduleTask
|
||||||
@ -548,11 +517,9 @@ static int tolua_cWorld_ScheduleTask(lua_State * tolua_S)
|
|||||||
return cManualBindings::lua_do_error(tolua_S, "Error in function call '#funcname#': Could not get function reference of parameter #1");
|
return cManualBindings::lua_do_error(tolua_S, "Error in function call '#funcname#': Could not get function reference of parameter #1");
|
||||||
}
|
}
|
||||||
|
|
||||||
int DelayTicks = static_cast<int>(tolua_tonumber(tolua_S, 2, 0));
|
auto ResettableTask = std::make_shared<cLuaWorldTask>(*Plugin, FnRef);
|
||||||
|
Plugin->AddResettable(ResettableTask);
|
||||||
auto task = std::make_shared<cLuaScheduledWorldTask>(*Plugin, FnRef);
|
World->ScheduleTask(static_cast<int>(tolua_tonumber(tolua_S, 2, 0)), std::bind(&cLuaWorldTask::Run, ResettableTask, std::placeholders::_1));
|
||||||
Plugin->AddResettable(task);
|
|
||||||
World->ScheduleTask(DelayTicks, static_cast<cWorld::cTaskPtr>(task));
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,7 +27,6 @@
|
|||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PISTON_TICK_DELAY 1
|
|
||||||
#define PISTON_MAX_PUSH_DISTANCE 12
|
#define PISTON_MAX_PUSH_DISTANCE 12
|
||||||
|
|
||||||
|
|
||||||
@ -156,15 +155,12 @@ void cBlockPistonHandler::ExtendPiston(int a_BlockX, int a_BlockY, int a_BlockZ,
|
|||||||
// Push blocks, from the furthest to the nearest:
|
// Push blocks, from the furthest to the nearest:
|
||||||
int oldx = a_BlockX, oldy = a_BlockY, oldz = a_BlockZ;
|
int oldx = a_BlockX, oldy = a_BlockY, oldz = a_BlockZ;
|
||||||
NIBBLETYPE currBlockMeta;
|
NIBBLETYPE currBlockMeta;
|
||||||
std::vector<Vector3i> ScheduledBlocks;
|
|
||||||
ScheduledBlocks.reserve(PISTON_MAX_PUSH_DISTANCE);
|
|
||||||
|
|
||||||
for (int i = dist + 1; i > 1; i--)
|
for (int i = dist + 1; i > 1; i--)
|
||||||
{
|
{
|
||||||
AddPistonDir(a_BlockX, a_BlockY, a_BlockZ, pistonMeta, -1);
|
AddPistonDir(a_BlockX, a_BlockY, a_BlockZ, pistonMeta, -1);
|
||||||
a_World->GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, currBlock, currBlockMeta);
|
a_World->GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, currBlock, currBlockMeta);
|
||||||
a_World->SetBlock(oldx, oldy, oldz, currBlock, currBlockMeta, false);
|
a_World->SetBlock(oldx, oldy, oldz, currBlock, currBlockMeta);
|
||||||
ScheduledBlocks.push_back(Vector3i(oldx, oldy, oldz));
|
|
||||||
oldx = a_BlockX;
|
oldx = a_BlockX;
|
||||||
oldy = a_BlockY;
|
oldy = a_BlockY;
|
||||||
oldz = a_BlockZ;
|
oldz = a_BlockZ;
|
||||||
@ -173,13 +169,11 @@ void cBlockPistonHandler::ExtendPiston(int a_BlockX, int a_BlockY, int a_BlockZ,
|
|||||||
int extx = a_BlockX;
|
int extx = a_BlockX;
|
||||||
int exty = a_BlockY;
|
int exty = a_BlockY;
|
||||||
int extz = a_BlockZ;
|
int extz = a_BlockZ;
|
||||||
ScheduledBlocks.push_back(Vector3i(extx, exty, extz));
|
|
||||||
AddPistonDir(a_BlockX, a_BlockY, a_BlockZ, pistonMeta, -1);
|
AddPistonDir(a_BlockX, a_BlockY, a_BlockZ, pistonMeta, -1);
|
||||||
// "a_Block" now at piston body, "ext" at future extension
|
// "a_Block" now at piston body, "ext" at future extension
|
||||||
|
|
||||||
a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, pistonBlock, pistonMeta | 0x8);
|
a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, pistonBlock, pistonMeta | 0x8);
|
||||||
a_World->SetBlock(extx, exty, extz, E_BLOCK_PISTON_EXTENSION, pistonMeta | (IsSticky(pistonBlock) ? 8 : 0), false);
|
a_World->SetBlock(extx, exty, extz, E_BLOCK_PISTON_EXTENSION, pistonMeta | (IsSticky(pistonBlock) ? 8 : 0));
|
||||||
a_World->ScheduleTask(PISTON_TICK_DELAY, static_cast<cWorld::cTaskPtr>(std::make_shared<cWorld::cTaskSendBlockToAllPlayers>(ScheduledBlocks)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -223,23 +217,14 @@ void cBlockPistonHandler::RetractPiston(int a_BlockX, int a_BlockY, int a_BlockZ
|
|||||||
if (CanPull(tempBlock, tempMeta))
|
if (CanPull(tempBlock, tempMeta))
|
||||||
{
|
{
|
||||||
// Pull the block
|
// Pull the block
|
||||||
a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, tempBlock, tempMeta, false);
|
a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, tempBlock, tempMeta);
|
||||||
a_World->SetBlock(tempx, tempy, tempz, E_BLOCK_AIR, 0, false);
|
a_World->SetBlock(tempx, tempy, tempz, E_BLOCK_AIR, 0);
|
||||||
|
|
||||||
std::vector<Vector3i> ScheduledBlocks;
|
|
||||||
ScheduledBlocks.push_back(Vector3i(a_BlockX, a_BlockY, a_BlockZ));
|
|
||||||
ScheduledBlocks.push_back(Vector3i(tempx, tempy, tempz));
|
|
||||||
a_World->ScheduleTask(PISTON_TICK_DELAY + 1, static_cast<cWorld::cTaskPtr>(std::make_shared<cWorld::cTaskSendBlockToAllPlayers>(ScheduledBlocks)));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retract without pulling
|
// Retract without pulling
|
||||||
a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0, false);
|
a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
|
||||||
|
|
||||||
std::vector<Vector3i> ScheduledBlocks;
|
|
||||||
ScheduledBlocks.push_back(Vector3i(a_BlockX, a_BlockY, a_BlockZ));
|
|
||||||
a_World->ScheduleTask(PISTON_TICK_DELAY + 1, static_cast<cWorld::cTaskPtr>(std::make_shared<cWorld::cTaskSendBlockToAllPlayers>(ScheduledBlocks)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
164
src/World.cpp
164
src/World.cpp
@ -839,7 +839,6 @@ void cWorld::Tick(std::chrono::milliseconds a_Dt, std::chrono::milliseconds a_La
|
|||||||
TickClients(static_cast<float>(a_Dt.count()));
|
TickClients(static_cast<float>(a_Dt.count()));
|
||||||
TickQueuedBlocks();
|
TickQueuedBlocks();
|
||||||
TickQueuedTasks();
|
TickQueuedTasks();
|
||||||
TickScheduledTasks();
|
|
||||||
|
|
||||||
GetSimulatorManager()->Simulate(static_cast<float>(a_Dt.count()));
|
GetSimulatorManager()->Simulate(static_cast<float>(a_Dt.count()));
|
||||||
|
|
||||||
@ -962,55 +961,39 @@ void cWorld::TickMobs(std::chrono::milliseconds a_Dt)
|
|||||||
|
|
||||||
void cWorld::TickQueuedTasks(void)
|
void cWorld::TickQueuedTasks(void)
|
||||||
{
|
{
|
||||||
// Make a copy of the tasks to avoid deadlocks on accessing m_Tasks
|
// Move the tasks to be executed to a seperate vector to avoid deadlocks on accessing m_Tasks
|
||||||
cTasks Tasks;
|
decltype(m_Tasks) Tasks;
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CSTasks);
|
cCSLock Lock(m_CSTasks);
|
||||||
std::swap(Tasks, m_Tasks);
|
if (m_Tasks.empty())
|
||||||
|
{
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Execute and delete each task:
|
// Partition everything to be executed by returning false to move to end of list if time reached
|
||||||
for (cTasks::iterator itr = Tasks.begin(), end = Tasks.end(); itr != end; ++itr)
|
auto MoveBeginIterator = std::partition(m_Tasks.begin(), m_Tasks.end(), [this](const decltype(m_Tasks)::value_type & a_Task)
|
||||||
{
|
{
|
||||||
(*itr)->Run(*this);
|
if (a_Task.first < std::chrono::duration_cast<cTickTimeLong>(m_WorldAge).count())
|
||||||
} // for itr - m_Tasks[]
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// Cut all the due tasks from m_Tasks into Tasks:
|
||||||
|
Tasks.insert(
|
||||||
|
Tasks.end(),
|
||||||
|
std::make_move_iterator(MoveBeginIterator),
|
||||||
|
std::make_move_iterator(m_Tasks.end())
|
||||||
|
);
|
||||||
|
m_Tasks.erase(MoveBeginIterator, m_Tasks.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Execute each task:
|
||||||
|
for (const auto & Task : Tasks)
|
||||||
|
|
||||||
|
|
||||||
void cWorld::TickScheduledTasks(void)
|
|
||||||
{
|
{
|
||||||
// Move the tasks to be executed to a seperate vector to avoid deadlocks on accessing m_Tasks
|
Task.second(*this);
|
||||||
cScheduledTasks Tasks;
|
|
||||||
{
|
|
||||||
cCSLock Lock(m_CSScheduledTasks);
|
|
||||||
auto WorldAge = m_WorldAge;
|
|
||||||
|
|
||||||
// Move all the due tasks from m_ScheduledTasks into Tasks:
|
|
||||||
for (auto itr = m_ScheduledTasks.begin(); itr != m_ScheduledTasks.end();) // Cannot use range-based for, we're modifying the container
|
|
||||||
{
|
|
||||||
if ((*itr)->m_TargetTick < std::chrono::duration_cast<cTickTimeLong>(WorldAge).count())
|
|
||||||
{
|
|
||||||
auto next = itr;
|
|
||||||
++next;
|
|
||||||
Tasks.push_back(std::move(*itr));
|
|
||||||
m_ScheduledTasks.erase(itr);
|
|
||||||
itr = next;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// All the eligible tasks have been moved, bail out now
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Execute and delete each task:
|
|
||||||
for (cScheduledTasks::iterator itr = Tasks.begin(), end = Tasks.end(); itr != end; ++itr)
|
|
||||||
{
|
|
||||||
(*itr)->m_Task->Run(*this);
|
|
||||||
} // for itr - m_Tasks[]
|
} // for itr - m_Tasks[]
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2662,7 +2645,7 @@ void cWorld::UnloadUnusedChunks(void)
|
|||||||
|
|
||||||
void cWorld::QueueUnloadUnusedChunks(void)
|
void cWorld::QueueUnloadUnusedChunks(void)
|
||||||
{
|
{
|
||||||
QueueTask(cpp14::make_unique<cWorld::cTaskUnloadUnusedChunks>());
|
QueueTask([](cWorld & a_World) { a_World.UnloadUnusedChunks(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -3161,43 +3144,33 @@ void cWorld::SaveAllChunks(void)
|
|||||||
|
|
||||||
void cWorld::QueueSaveAllChunks(void)
|
void cWorld::QueueSaveAllChunks(void)
|
||||||
{
|
{
|
||||||
QueueTask(std::make_shared<cWorld::cTaskSaveAllChunks>());
|
QueueTask([](cWorld & a_World) { a_World.SaveAllChunks(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cWorld::QueueTask(cTaskPtr a_Task)
|
void cWorld::QueueTask(std::function<void(cWorld &)> a_Task)
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CSTasks);
|
cCSLock Lock(m_CSTasks);
|
||||||
m_Tasks.push_back(std::move(a_Task));
|
m_Tasks.emplace_back(0, a_Task);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void cWorld::ScheduleTask(int a_DelayTicks, std::function<void (cWorld&)> a_Func)
|
|
||||||
{
|
|
||||||
cTaskLambda task(a_Func);
|
|
||||||
ScheduleTask(a_DelayTicks, static_cast<cTaskPtr>(std::make_shared<cTaskLambda>(task)));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void cWorld::ScheduleTask(int a_DelayTicks, cTaskPtr a_Task)
|
|
||||||
|
void cWorld::ScheduleTask(int a_DelayTicks, std::function<void (cWorld &)> a_Task)
|
||||||
{
|
{
|
||||||
Int64 TargetTick = a_DelayTicks + std::chrono::duration_cast<cTickTimeLong>(m_WorldAge).count();
|
Int64 TargetTick = a_DelayTicks + std::chrono::duration_cast<cTickTimeLong>(m_WorldAge).count();
|
||||||
|
|
||||||
// Insert the task into the list of scheduled tasks, ordered by its target tick
|
// Insert the task into the list of scheduled tasks
|
||||||
cCSLock Lock(m_CSScheduledTasks);
|
|
||||||
for (cScheduledTasks::iterator itr = m_ScheduledTasks.begin(), end = m_ScheduledTasks.end(); itr != end; ++itr)
|
|
||||||
{
|
{
|
||||||
if ((*itr)->m_TargetTick >= TargetTick)
|
cCSLock Lock(m_CSTasks);
|
||||||
{
|
m_Tasks.emplace_back(TargetTick, a_Task);
|
||||||
m_ScheduledTasks.insert(itr, cScheduledTaskPtr(new cScheduledTask(TargetTick, a_Task)));
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_ScheduledTasks.push_back(cScheduledTaskPtr(new cScheduledTask(TargetTick, a_Task)));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -3624,75 +3597,6 @@ void cWorld::AddQueuedPlayers(void)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// cWorld::cTaskSaveAllChunks:
|
|
||||||
|
|
||||||
void cWorld::cTaskSaveAllChunks::Run(cWorld & a_World)
|
|
||||||
{
|
|
||||||
a_World.SaveAllChunks();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// cWorld::cTaskUnloadUnusedChunks
|
|
||||||
|
|
||||||
void cWorld::cTaskUnloadUnusedChunks::Run(cWorld & a_World)
|
|
||||||
{
|
|
||||||
a_World.UnloadUnusedChunks();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// cWorld::cTaskSendBlockToAllPlayers
|
|
||||||
|
|
||||||
cWorld::cTaskSendBlockToAllPlayers::cTaskSendBlockToAllPlayers(std::vector<Vector3i> & a_SendQueue) :
|
|
||||||
m_SendQueue(a_SendQueue)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void cWorld::cTaskSendBlockToAllPlayers::Run(cWorld & a_World)
|
|
||||||
{
|
|
||||||
class cPlayerCallback :
|
|
||||||
public cPlayerListCallback
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
cPlayerCallback(std::vector<Vector3i> & a_SendQueue, cWorld & a_CallbackWorld) :
|
|
||||||
m_SendQueue(a_SendQueue),
|
|
||||||
m_World(a_CallbackWorld)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool Item(cPlayer * a_Player)
|
|
||||||
{
|
|
||||||
for (std::vector<Vector3i>::const_iterator itr = m_SendQueue.begin(); itr != m_SendQueue.end(); ++itr)
|
|
||||||
{
|
|
||||||
m_World.SendBlockTo(itr->x, itr->y, itr->z, a_Player);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
std::vector<Vector3i> m_SendQueue;
|
|
||||||
cWorld & m_World;
|
|
||||||
|
|
||||||
} PlayerCallback(m_SendQueue, a_World);
|
|
||||||
|
|
||||||
a_World.ForEachPlayer(PlayerCallback);
|
|
||||||
}
|
|
||||||
|
|
||||||
void cWorld::cTaskLambda::Run(cWorld & a_World)
|
|
||||||
{
|
|
||||||
m_func(a_World);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// cWorld::cChunkGeneratorCallbacks:
|
// cWorld::cChunkGeneratorCallbacks:
|
||||||
|
|
||||||
|
107
src/World.h
107
src/World.h
@ -98,70 +98,6 @@ public:
|
|||||||
cLock(cWorld & a_World);
|
cLock(cWorld & a_World);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/** A common ancestor for all tasks queued onto the tick thread */
|
|
||||||
class cTask
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
cTask(const cTask & other) = default;
|
|
||||||
virtual ~cTask() {}
|
|
||||||
virtual void Run(cWorld & a_World) = 0;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
cTask() {}
|
|
||||||
} ;
|
|
||||||
|
|
||||||
typedef SharedPtr<cTask> cTaskPtr;
|
|
||||||
typedef std::vector<cTaskPtr> cTasks;
|
|
||||||
|
|
||||||
|
|
||||||
class cTaskSaveAllChunks :
|
|
||||||
public cTask
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
// cTask overrides:
|
|
||||||
virtual void Run(cWorld & a_World) override;
|
|
||||||
} ;
|
|
||||||
|
|
||||||
|
|
||||||
class cTaskUnloadUnusedChunks :
|
|
||||||
public cTask
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
// cTask overrides:
|
|
||||||
virtual void Run(cWorld & a_World) override;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class cTaskSendBlockToAllPlayers :
|
|
||||||
public cTask
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
cTaskSendBlockToAllPlayers(std::vector<Vector3i> & a_SendQueue);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
// cTask overrides:
|
|
||||||
virtual void Run(cWorld & a_World) override;
|
|
||||||
|
|
||||||
std::vector<Vector3i> m_SendQueue;
|
|
||||||
};
|
|
||||||
|
|
||||||
class cTaskLambda :
|
|
||||||
public cTask
|
|
||||||
{
|
|
||||||
|
|
||||||
public:
|
|
||||||
cTaskLambda(std::function<void(cWorld&)> a_Func) :
|
|
||||||
m_func(a_Func)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual void Run(cWorld & a_World) override;
|
|
||||||
|
|
||||||
std::function<void(cWorld&)> m_func;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
static const char * GetClassStatic(void) // Needed for ManualBindings's ForEach templates
|
static const char * GetClassStatic(void) // Needed for ManualBindings's ForEach templates
|
||||||
{
|
{
|
||||||
return "cWorld";
|
return "cWorld";
|
||||||
@ -739,13 +675,10 @@ public:
|
|||||||
void QueueSaveAllChunks(void); // tolua_export
|
void QueueSaveAllChunks(void); // tolua_export
|
||||||
|
|
||||||
/** 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(cTaskPtr a_Task); // Exported in ManualBindings.cpp
|
void QueueTask(std::function<void(cWorld &)> a_Task); // Exported in ManualBindings.cpp
|
||||||
|
|
||||||
/** Queues a lambda task onto the tick thread, with the specified delay. */
|
/** Queues a lambda task onto the tick thread, with the specified delay. */
|
||||||
void ScheduleTask(int a_DelayTicks, std::function<void(cWorld&)> a_Func);
|
void ScheduleTask(int a_DelayTicks, std::function<void(cWorld &)> a_Task);
|
||||||
|
|
||||||
/** Queues a task onto the tick thread, with the specified delay. */
|
|
||||||
void ScheduleTask(int a_DelayTicks, cTaskPtr a_Task);
|
|
||||||
|
|
||||||
/** Returns the number of chunks loaded */
|
/** Returns the number of chunks loaded */
|
||||||
int GetNumChunks() const; // tolua_export
|
int GetNumChunks() const; // tolua_export
|
||||||
@ -914,27 +847,6 @@ private:
|
|||||||
} ;
|
} ;
|
||||||
|
|
||||||
|
|
||||||
/** A container for tasks that have been scheduled for a specific game tick */
|
|
||||||
class cScheduledTask
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Int64 m_TargetTick;
|
|
||||||
cTaskPtr m_Task;
|
|
||||||
|
|
||||||
/** Creates a new scheduled task; takes ownership of the task object passed to it. */
|
|
||||||
cScheduledTask(Int64 a_TargetTick, cTaskPtr a_Task) :
|
|
||||||
m_TargetTick(a_TargetTick),
|
|
||||||
m_Task(a_Task)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~cScheduledTask() {}
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef std::unique_ptr<cScheduledTask> cScheduledTaskPtr;
|
|
||||||
typedef std::list<cScheduledTaskPtr> cScheduledTasks;
|
|
||||||
|
|
||||||
|
|
||||||
AString m_WorldName;
|
AString m_WorldName;
|
||||||
|
|
||||||
/** The name of the overworld that portals in this world should link to.
|
/** The name of the overworld that portals in this world should link to.
|
||||||
@ -1062,16 +974,8 @@ private:
|
|||||||
/** Guards the m_Tasks */
|
/** Guards the m_Tasks */
|
||||||
cCriticalSection m_CSTasks;
|
cCriticalSection m_CSTasks;
|
||||||
|
|
||||||
/** Tasks that have been queued onto the tick thread; guarded by m_CSTasks */
|
/** Tasks that have been queued onto the tick thread, possibly to be executed at target tick in the future; guarded by m_CSTasks */
|
||||||
cTasks m_Tasks;
|
std::vector<std::pair<Int64, std::function<void(cWorld &)>>> m_Tasks;
|
||||||
|
|
||||||
/** Guards the m_ScheduledTasks */
|
|
||||||
cCriticalSection m_CSScheduledTasks;
|
|
||||||
|
|
||||||
/** Tasks that have been queued to be executed on the tick thread at target tick in the future.
|
|
||||||
Ordered by increasing m_TargetTick.
|
|
||||||
Guarded by m_CSScheduledTasks */
|
|
||||||
cScheduledTasks m_ScheduledTasks;
|
|
||||||
|
|
||||||
/** Guards m_Clients */
|
/** Guards m_Clients */
|
||||||
cCriticalSection m_CSClients;
|
cCriticalSection m_CSClients;
|
||||||
@ -1118,9 +1022,6 @@ 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