summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--source/Bindings.cpp34
-rw-r--r--source/Bindings.h2
-rw-r--r--source/World.cpp56
-rw-r--r--source/World.h38
4 files changed, 125 insertions, 5 deletions
diff --git a/source/Bindings.cpp b/source/Bindings.cpp
index ca6b42902..46c5f0f07 100644
--- a/source/Bindings.cpp
+++ b/source/Bindings.cpp
@@ -1,6 +1,6 @@
/*
** Lua binding: AllToLua
-** Generated automatically by tolua++-1.0.92 on 08/11/13 19:12:37.
+** Generated automatically by tolua++-1.0.92 on 08/11/13 20:59:51.
*/
#ifndef __cplusplus
@@ -13434,6 +13434,37 @@ static int tolua_AllToLua_cWorld_SaveAllChunks00(lua_State* tolua_S)
}
#endif //#ifndef TOLUA_DISABLE
+/* method: QueueSaveAllChunks of class cWorld */
+#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_QueueSaveAllChunks00
+static int tolua_AllToLua_cWorld_QueueSaveAllChunks00(lua_State* tolua_S)
+{
+#ifndef TOLUA_RELEASE
+ tolua_Error tolua_err;
+ if (
+ !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) ||
+ !tolua_isnoobj(tolua_S,2,&tolua_err)
+ )
+ goto tolua_lerror;
+ else
+#endif
+ {
+ cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0);
+#ifndef TOLUA_RELEASE
+ if (!self) tolua_error(tolua_S,"invalid 'self' in function 'QueueSaveAllChunks'", NULL);
+#endif
+ {
+ self->QueueSaveAllChunks();
+ }
+ }
+ return 0;
+#ifndef TOLUA_RELEASE
+ tolua_lerror:
+ tolua_error(tolua_S,"#ferror in function 'QueueSaveAllChunks'.",&tolua_err);
+ return 0;
+#endif
+}
+#endif //#ifndef TOLUA_DISABLE
+
/* method: GetNumChunks of class cWorld */
#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetNumChunks00
static int tolua_AllToLua_cWorld_GetNumChunks00(lua_State* tolua_S)
@@ -29878,6 +29909,7 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S)
tolua_function(tolua_S,"GetBiomeAt",tolua_AllToLua_cWorld_GetBiomeAt00);
tolua_function(tolua_S,"GetName",tolua_AllToLua_cWorld_GetName00);
tolua_function(tolua_S,"SaveAllChunks",tolua_AllToLua_cWorld_SaveAllChunks00);
+ tolua_function(tolua_S,"QueueSaveAllChunks",tolua_AllToLua_cWorld_QueueSaveAllChunks00);
tolua_function(tolua_S,"GetNumChunks",tolua_AllToLua_cWorld_GetNumChunks00);
tolua_function(tolua_S,"GetGeneratorQueueLength",tolua_AllToLua_cWorld_GetGeneratorQueueLength00);
tolua_function(tolua_S,"GetLightingQueueLength",tolua_AllToLua_cWorld_GetLightingQueueLength00);
diff --git a/source/Bindings.h b/source/Bindings.h
index d80c98782..10f874e41 100644
--- a/source/Bindings.h
+++ b/source/Bindings.h
@@ -1,6 +1,6 @@
/*
** Lua binding: AllToLua
-** Generated automatically by tolua++-1.0.92 on 08/11/13 19:12:37.
+** Generated automatically by tolua++-1.0.92 on 08/11/13 20:59:52.
*/
/* Exported function */
diff --git a/source/World.cpp b/source/World.cpp
index af66d1ead..9212202e9 100644
--- a/source/World.cpp
+++ b/source/World.cpp
@@ -1,3 +1,4 @@
+
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
#include "BlockID.h"
@@ -242,7 +243,7 @@ cWorld::cWorld(const AString & a_WorldName) :
m_WeatherInterval(24000), // Guaranteed 1 day of sunshine at server start :)
m_TickThread(*this)
{
- LOGD("cWorld::cWorld(%s)", a_WorldName.c_str());
+ LOGD("cWorld::cWorld(\"%s\")", a_WorldName.c_str());
cMakeDir::MakeDir(m_WorldName.c_str());
}
@@ -587,6 +588,7 @@ void cWorld::Tick(float a_Dt)
m_ChunkMap->Tick(a_Dt);
TickQueuedBlocks(a_Dt);
+ TickQueuedTasks();
GetSimulatorManager()->Simulate(a_Dt);
@@ -781,6 +783,27 @@ void cWorld::TickSpawnMobs(float a_Dt)
+void cWorld::TickQueuedTasks(void)
+{
+ // Make a copy of the tasks to avoid deadlocks on accessing m_Tasks
+ cTasks Tasks;
+ {
+ cCSLock Lock(m_CSTasks);
+ std::swap(Tasks, m_Tasks);
+ }
+
+ // Execute and delete each task:
+ for (cTasks::iterator itr = m_Tasks.begin(), end = m_Tasks.end(); itr != end; ++itr)
+ {
+ (*itr)->Run(*this);
+ delete *itr;
+ } // for itr - m_Tasks[]
+}
+
+
+
+
+
void cWorld::WakeUpSimulators(int a_BlockX, int a_BlockY, int a_BlockZ)
{
return m_ChunkMap->WakeUpSimulators(a_BlockX, a_BlockY, a_BlockZ);
@@ -2307,6 +2330,25 @@ void cWorld::SaveAllChunks(void)
+void cWorld::QueueSaveAllChunks(void)
+{
+ QueueTask(new cWorld::cTaskSaveAllChunks);
+}
+
+
+
+
+
+void cWorld::QueueTask(cTask * a_Task)
+{
+ cCSLock Lock(m_CSTasks);
+ m_Tasks.push_back(a_Task);
+}
+
+
+
+
+
void cWorld::AddEntity(cEntity * a_Entity)
{
m_ChunkMap->AddEntity(a_Entity);
@@ -2552,3 +2594,15 @@ cFluidSimulator * cWorld::InitializeFluidSimulator(cIniFile & a_IniFile, const c
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// cWorld::cTaskSaveAllChunks:
+
+void cWorld::cTaskSaveAllChunks::Run(cWorld & a_World)
+{
+ a_World.SaveAllChunks();
+}
+
+
+
+
diff --git a/source/World.h b/source/World.h
index a12a9e40e..d84920470 100644
--- a/source/World.h
+++ b/source/World.h
@@ -69,6 +69,24 @@ public:
public:
cLock(cWorld & a_World);
} ;
+
+ /// A common ancestor for all tasks queued onto the tick thread
+ class cTask
+ {
+ public:
+ virtual void Run(cWorld & a_World) = 0;
+ } ;
+
+ typedef std::vector<cTask *> cTasks;
+
+ class cTaskSaveAllChunks :
+ public cTask
+ {
+ protected:
+ // cTask overrides:
+ virtual void Run(cWorld & a_World) override;
+ } ;
+
// tolua_begin
@@ -461,10 +479,17 @@ public:
if(a_Z < 0 && a_Z % cChunkDef::Width != 0) a_ChunkZ--;
}
- void SaveAllChunks(void); // tolua_export
+ /// Saves all chunks immediately. Dangerous interface, may deadlock, use QueueSaveAllChunks() instead
+ void SaveAllChunks(void); // tolua_export
+
+ /// Queues a task to save all chunks onto the tick thread. The prefferred way of saving chunks from external sources
+ void QueueSaveAllChunks(void); // tolua_export
+
+ /// Queues a task onto the tick thread. The task object will be deleted once the task is finished
+ void QueueTask(cTask * a_Task);
/// Returns the number of chunks loaded
- int GetNumChunks() const; // tolua_export
+ int GetNumChunks() const; // tolua_export
/// Returns the number of chunks loaded and dirty, and in the lighting queue
void GetChunkStats(int & a_NumValid, int & a_NumDirty, int & a_NumInLightingQueue);
@@ -629,6 +654,12 @@ private:
cChunkSender m_ChunkSender;
cLightingThread m_Lighting;
cTickThread m_TickThread;
+
+ /// Guards the m_Tasks
+ cCriticalSection m_CSTasks;
+
+ /// Tasks that have been queued onto the tick thread; guarded by m_CSTasks
+ cTasks m_Tasks;
cWorld(const AString & a_WorldName);
@@ -639,6 +670,9 @@ private:
void TickWeather(float a_Dt); // Handles weather each tick
void TickSpawnMobs(float a_Dt); // Handles mob spawning each tick
+ /// Executes all tasks queued onto the tick thread
+ void TickQueuedTasks(void);
+
/// Creates a new fluid simulator, loads its settings from the inifile (a_FluidName section)
cFluidSimulator * InitializeFluidSimulator(cIniFile & a_IniFile, const char * a_FluidName, BLOCKTYPE a_SimulateBlock, BLOCKTYPE a_StationaryBlock);
}; // tolua_export