2012-02-13 13:47:03 -08:00
// WorldStorage.h
// Interfaces to the cWorldStorage class representing the chunk loading / saving thread
// This class decides which storage schema to use for saving; it queries all available schemas for loading
// Also declares the base class for all storage schemas, cWSSchema
2012-02-16 05:42:35 -08:00
// Helper serialization class cJsonChunkSerializer is declared as well
2012-02-13 13:47:03 -08:00
# pragma once
# ifndef WORLDSTORAGE_H_INCLUDED
# define WORLDSTORAGE_H_INCLUDED
2012-03-14 13:56:09 -07:00
# include "ChunkDef.h"
2012-02-13 13:47:03 -08:00
# include "cIsThread.h"
2012-02-16 05:42:35 -08:00
# include <json/json.h>
2012-03-24 04:14:34 -07:00
// fwd:
class cWorld ;
2012-02-13 13:47:03 -08:00
/// Interface that all the world storage schemas need to implement
2012-03-09 01:39:48 -08:00
class cWSSchema abstract
2012-02-13 13:47:03 -08:00
{
public :
2012-03-24 04:14:34 -07:00
cWSSchema ( cWorld * a_World ) : m_World ( a_World ) { }
2012-02-13 13:47:03 -08:00
virtual ~ cWSSchema ( ) { } // Force the descendants' destructors to be virtual
2012-02-16 05:42:35 -08:00
virtual bool LoadChunk ( const cChunkCoords & a_Chunk ) = 0 ;
virtual bool SaveChunk ( const cChunkCoords & a_Chunk ) = 0 ;
2012-02-13 13:47:03 -08:00
virtual const AString GetName ( void ) const = 0 ;
protected :
2012-03-24 04:14:34 -07:00
cWorld * m_World ;
2012-02-13 13:47:03 -08:00
} ;
typedef std : : list < cWSSchema * > cWSSchemaList ;
2012-02-16 05:42:35 -08:00
/// Helper class for serializing a chunk into Json
class cJsonChunkSerializer :
2012-03-14 13:56:09 -07:00
public cChunkDataCollector
2012-02-16 05:42:35 -08:00
{
public :
cJsonChunkSerializer ( void ) ;
Json : : Value & GetRoot ( void ) { return m_Root ; }
2012-03-14 13:56:09 -07:00
BLOCKTYPE * GetBlockData ( void ) { return m_BlockData ; }
2012-02-16 05:42:35 -08:00
bool HasJsonData ( void ) const { return m_HasJsonData ; }
protected :
2012-03-14 13:56:09 -07:00
// NOTE: block data is serialized into inherited cChunkDataCollector's m_BlockData[] array
2012-02-16 05:42:35 -08:00
// Entities and BlockEntities are serialized to Json
Json : : Value m_Root ;
Json : : Value m_AllChests ;
Json : : Value m_AllFurnaces ;
Json : : Value m_AllSigns ;
bool m_HasJsonData ;
2012-03-14 13:56:09 -07:00
// cChunkDataCollector overrides:
virtual void Entity ( cEntity * a_Entity ) override ;
virtual void BlockEntity ( cBlockEntity * a_Entity ) override ;
2012-02-16 05:42:35 -08:00
} ;
/// The actual world storage class
2012-02-13 13:47:03 -08:00
class cWorldStorage :
public cIsThread
{
typedef cIsThread super ;
public :
cWorldStorage ( void ) ;
~ cWorldStorage ( ) ;
2012-02-26 08:46:23 -08:00
void QueueLoadChunk ( int a_ChunkX , int a_ChunkY , int a_ChunkZ , bool a_Generate ) ; // Queues the chunk for loading; if not loaded, the chunk will be generated if a_Generate is true
2012-02-17 09:56:25 -08:00
void QueueSaveChunk ( int a_ChunkX , int a_ChunkY , int a_ChunkZ ) ;
2012-02-13 13:47:03 -08:00
2012-02-28 02:45:53 -08:00
/// Loads the chunk specified; returns true on success, false on failure
bool LoadChunk ( int a_ChunkX , int a_ChunkY , int a_ChunkZ ) ;
2012-02-26 08:46:23 -08:00
void UnqueueLoad ( int a_ChunkX , int a_ChunkY , int a_ChunkZ ) ;
2012-02-16 05:42:35 -08:00
void UnqueueSave ( const cChunkCoords & a_Chunk ) ;
2012-02-13 13:47:03 -08:00
2012-03-24 04:14:34 -07:00
bool Start ( cWorld * a_World , const AString & a_StorageSchemaName ) ; // Hide the cIsThread's Start() method, we need to provide args
2012-02-13 13:47:03 -08:00
void WaitForFinish ( void ) ;
2012-02-18 09:53:22 -08:00
void WaitForQueuesEmpty ( void ) ;
int GetLoadQueueLength ( void ) ;
int GetSaveQueueLength ( void ) ;
2012-02-13 13:47:03 -08:00
protected :
2012-02-26 08:46:23 -08:00
struct sChunkLoad
{
int m_ChunkX ;
int m_ChunkY ;
int m_ChunkZ ;
bool m_Generate ; // If true, the chunk will be generated if it cannot be loaded
sChunkLoad ( int a_ChunkX , int a_ChunkY , int a_ChunkZ , bool a_Generate ) : m_ChunkX ( a_ChunkX ) , m_ChunkY ( a_ChunkY ) , m_ChunkZ ( a_ChunkZ ) , m_Generate ( a_Generate ) { }
} ;
typedef std : : list < sChunkLoad > sChunkLoadQueue ;
2012-03-24 04:14:34 -07:00
cWorld * m_World ;
2012-02-13 13:47:03 -08:00
AString m_StorageSchemaName ;
2012-02-18 09:53:22 -08:00
// Both queues are locked by the same CS
cCriticalSection m_CSQueues ;
2012-02-26 08:46:23 -08:00
sChunkLoadQueue m_LoadQueue ;
2012-02-18 09:53:22 -08:00
cChunkCoordsList m_SaveQueue ;
2012-02-13 13:47:03 -08:00
2012-02-18 09:53:22 -08:00
cEvent m_Event ; // Set when there's any addition to the queues
cEvent m_evtRemoved ; // Set when an item has been removed from the queue, either by the worker thread or the Unqueue methods
2012-02-13 13:47:03 -08:00
2012-02-16 05:42:35 -08:00
/// All the storage schemas (all used for loading)
2012-02-13 13:47:03 -08:00
cWSSchemaList m_Schemas ;
2012-02-16 05:42:35 -08:00
/// The one storage schema used for saving
cWSSchema * m_SaveSchema ;
2012-02-13 13:47:03 -08:00
void InitSchemas ( void ) ;
virtual void Execute ( void ) override ;
2012-02-16 05:42:35 -08:00
/// Loads one chunk from the queue (if any queued); returns true if there are more chunks in the load queue
bool LoadOneChunk ( void ) ;
/// Saves one chunk from the queue (if any queued); returns true if there are more chunks in the save queue
bool SaveOneChunk ( void ) ;
2012-02-13 13:47:03 -08:00
} ;
# endif // WORLDSTORAGE_H_INCLUDED