Implement global palette loading

This commit is contained in:
DankParrot 2020-08-12 20:10:44 -07:00
parent 144c980355
commit 9689e7996f
9 changed files with 203 additions and 1 deletions

View File

@ -1,5 +1,6 @@
#include "DedicatedServer.h"
#include "config/ServerProperties.h"
#include "data/Registry.h"
#include "PacketReader.h"
@ -15,7 +16,9 @@ namespace Feather
{
m_status.descriptionText = properties->motd.GetValue();
m_status.maxPlayers = properties->maxPlayers;
Registry::Init();
m_worldManager.LoadWorld(m_properties->levelName);
while (1)

56
src/data/IDMapper.h Normal file
View File

@ -0,0 +1,56 @@
#pragma once
#include <vector>
#include <unordered_map>
namespace Feather
{
template <typename T>
class IDMapper
{
std::vector<T> m_IDtoValue;
std::unordered_map<T, int> m_ValueToID;
int m_NextID = 0;
public:
IDMapper(int size = 512)
{
m_IDtoValue.reserve(size);
m_ValueToID.reserve(size);
}
inline void AddMapping(int id, T& value)
{
m_IDtoValue.insert(m_IDtoValue.begin() + id, value);
m_ValueToID.insert({ value, id });
if (m_NextID <= id) {
m_NextID = id + 1;
}
}
inline void Add(T& value)
{
AddMapping(m_NextID, value);
}
inline int GetID(T& value) const
{
return m_ValueToID.at(value);
}
inline const T& ByID(int id) const
{
return m_IDtoValue.at(id);
}
inline int Size() const
{
return m_IDtoValue.size();
}
};
}

67
src/data/Registry.cpp Normal file
View File

@ -0,0 +1,67 @@
#include "Common.h"
#include "Registry.h"
#include "rapidjson/document.h"
#include "rapidjson/filereadstream.h"
#include "rapidjson/stringbuffer.h"
#include "rapidjson/writer.h"
#include <iostream>
#include <fstream>
#include <string>
#include <cstdio>
namespace Feather
{
IDMapper<BlockState> Registry::BLOCK_STATES;
void Registry::Init()
{
static bool initialized = false;
if (initialized) return;
Log::Info("Loading data/blocks.json...");
{
using namespace rapidjson;
std::string text;
FILE* fp = fopen("data/blocks.json", "rb");
if (!fp) {
Log::Error("Failed to read data/blocks.json");
return;
}
fseek(fp, 0, SEEK_END);
text.resize(ftell(fp));
rewind(fp);
fread(&text[0], 1, text.size(), fp);
fclose(fp);
Document doc;
doc.Parse(text.c_str());
for (auto& block : doc.GetObject())
{
//Log::Info("{}: {} states", m.name.GetString(), m.value["states"].Size());
for (auto& stateData : block.value["states"].GetArray())
{
std::string* name = new std::string(block.name.GetString());
BlockState state(*name);
BLOCK_STATES.AddMapping(stateData["id"].GetInt(), state);
}
}
Log::Info("Loaded {} block states.", BLOCK_STATES.Size());
//StringBuffer buf;
//Writer<StringBuffer> writer(buf);
//doc.Accept(writer);
// FIXME: why does this crash
//Log::Info(text);
}
}
}

16
src/data/Registry.h Normal file
View File

@ -0,0 +1,16 @@
#pragma once
#include "IDMapper.h"
#include "block/state/BlockState.h"
namespace Feather
{
class Registry
{
public:
static IDMapper<BlockState> BLOCK_STATES;
static void Init();
};
}

View File

@ -7,6 +7,8 @@ feather_src = [
'nbt/NBT.cpp',
'data/Registry.cpp',
'network/NetworkManager.cpp',
'network/TCPListener.cpp',
'network/TCPClient.cpp',

35
src/world/Palette.h Normal file
View File

@ -0,0 +1,35 @@
#pragma once
#include "data/IDMapper.h"
namespace Feather
{
template <typename T>
class Palette
{
protected:
const IDMapper<T>& m_registry;
public:
Palette(const IDMapper<T>& registry) :
m_registry(registry)
{}
virtual int GetID(T& value) const = 0;
virtual const T& ByID(int id) const = 0;
};
template <typename T>
class GlobalPalette : public Palette<T>
{
const T* m_defaultValue;
public:
GlobalPalette(const IDMapper<T>& registry, const T* defaultValue) :
Palette(registry),
m_defaultValue(defaultValue)
{}
inline virtual int GetID(T& value) const final { return m_registry.GetID(value); }
inline virtual const T& ByID(int id) const final { return m_registry.ByID(id); }
};
}

View File

@ -0,0 +1,13 @@
#pragma once
#include "Palette.h"
namespace Feather
{
// A container that maps values from a local palette to a
template <typename T>
class PalettedContainer
{
const Palette<T>& m_globalPalette;
};
}

View File

@ -3,6 +3,7 @@
#include "World.h"
#include "nbt/NBT.h"
#include "RegionFile.h"
#include "data/Registry.h"
#include <iostream>
#include <fstream>
@ -15,6 +16,11 @@ using std::stringstream;
namespace Feather
{
const GlobalPalette<BlockState> World::GLOBAL_PALETTE = GlobalPalette<BlockState>(
Registry::BLOCK_STATES,
new BlockState("minecraft:air") // temp
);
static bool CheckPath(fs::path path, bool dir = false)
{
if (!fs::exists(path) || (dir && !fs::is_directory(path)))

View File

@ -1,6 +1,8 @@
#pragma once
#include "Common.h"
#include "Palette.h"
#include <cstdint>
#include <string>
@ -9,6 +11,8 @@ namespace Feather
class World
{
public:
// global palette of all block states
static const GlobalPalette<BlockState> GLOBAL_PALETTE;
struct LevelData
{
int32_t spawnX, spawnY, spawnZ;