Basic foundation for Block registry
This commit is contained in:
parent
6584a2c022
commit
b722c5530c
|
@ -0,0 +1,19 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace Feather
|
||||||
|
{
|
||||||
|
// Represents a type of block and its behavior.
|
||||||
|
class Block
|
||||||
|
{
|
||||||
|
using string = std::string;
|
||||||
|
|
||||||
|
const Identifier m_id;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Block(string&& name) : m_id(name) {}
|
||||||
|
|
||||||
|
inline const Identifier& GetIdentifier() const { return m_id; }
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
@ -8,6 +9,7 @@
|
||||||
|
|
||||||
namespace Feather
|
namespace Feather
|
||||||
{
|
{
|
||||||
|
// Represents the state data of a particular instance of a Block
|
||||||
class BlockState
|
class BlockState
|
||||||
{
|
{
|
||||||
friend struct std::hash<BlockState>;
|
friend struct std::hash<BlockState>;
|
||||||
|
@ -54,4 +56,4 @@ struct std::hash<Feather::BlockState>
|
||||||
|
|
||||||
return accum;
|
return accum;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
#include "Registry.h"
|
#include "Registry.h"
|
||||||
|
#include "block/Block.h"
|
||||||
|
|
||||||
#include "rapidjson/document.h"
|
#include "rapidjson/document.h"
|
||||||
#include "rapidjson/filereadstream.h"
|
#include "rapidjson/filereadstream.h"
|
||||||
|
@ -14,6 +15,7 @@
|
||||||
namespace Feather
|
namespace Feather
|
||||||
{
|
{
|
||||||
IDMapper<BlockState> Registry::BLOCK_STATES;
|
IDMapper<BlockState> Registry::BLOCK_STATES;
|
||||||
|
RegistryMap<Block> Registry::BLOCKS;
|
||||||
|
|
||||||
void Registry::Init()
|
void Registry::Init()
|
||||||
{
|
{
|
||||||
|
@ -40,15 +42,18 @@ namespace Feather
|
||||||
doc.Parse(text.c_str());
|
doc.Parse(text.c_str());
|
||||||
|
|
||||||
|
|
||||||
for (auto& block : doc.GetObject())
|
for (auto& blockData : doc.GetObject())
|
||||||
{
|
{
|
||||||
// TODO
|
const char* blockName = blockData.name.GetString();
|
||||||
//if (block.value.HasMember("properties")) {}
|
Block block(blockName);
|
||||||
|
|
||||||
//Log::Info("{}: {} states", block.name.GetString(), block.value["states"].Size());
|
// TODO
|
||||||
for (auto& stateData : block.value["states"].GetArray())
|
//if (blockData.value.HasMember("properties")) {}
|
||||||
|
|
||||||
|
//Log::Info("{}: {} states", blockData.name.GetString(), blockData.value["states"].Size());
|
||||||
|
for (auto& stateData : blockData.value["states"].GetArray())
|
||||||
{
|
{
|
||||||
std::string* name = new std::string(block.name.GetString());
|
std::string* name = new std::string(blockName);
|
||||||
BlockState state(*name);
|
BlockState state(*name);
|
||||||
|
|
||||||
if (stateData.HasMember("properties"))
|
if (stateData.HasMember("properties"))
|
||||||
|
@ -64,9 +69,11 @@ namespace Feather
|
||||||
BLOCK_STATES.AddMapping(stateData["id"].GetInt(), state);
|
BLOCK_STATES.AddMapping(stateData["id"].GetInt(), state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BLOCKS.Register(block.GetIdentifier(), std::move(block));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Log::Info("Loaded {} block states.", BLOCK_STATES.Size());
|
Log::Info("Loaded {} blocks and {} block states.", BLOCKS.Size(), BLOCK_STATES.Size());
|
||||||
|
|
||||||
//StringBuffer buf;
|
//StringBuffer buf;
|
||||||
//Writer<StringBuffer> writer(buf);
|
//Writer<StringBuffer> writer(buf);
|
||||||
|
@ -79,4 +86,4 @@ namespace Feather
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,23 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "IDMapper.h"
|
#include "IDMapper.h"
|
||||||
|
#include "RegistryMap.h"
|
||||||
#include "block/state/BlockState.h"
|
#include "block/state/BlockState.h"
|
||||||
|
|
||||||
|
|
||||||
namespace Feather
|
namespace Feather
|
||||||
{
|
{
|
||||||
|
class Block;
|
||||||
|
|
||||||
class Registry
|
class Registry
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
// Maps block Identifier to Block
|
||||||
|
static RegistryMap<Block> BLOCKS;
|
||||||
|
|
||||||
|
// Maps numeric ID to BlockState
|
||||||
static IDMapper<BlockState> BLOCK_STATES;
|
static IDMapper<BlockState> BLOCK_STATES;
|
||||||
|
|
||||||
static void Init();
|
static void Init();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "resources/Identifier.h"
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
namespace Feather
|
||||||
|
{
|
||||||
|
// Registry that maps Identifiers to objects
|
||||||
|
// TODO: optimize ownership (move, forward, copying, etc). perhaps use pointers
|
||||||
|
template <class T>
|
||||||
|
class RegistryMap
|
||||||
|
{
|
||||||
|
std::map<Identifier, T> map;
|
||||||
|
|
||||||
|
public:
|
||||||
|
inline void Register(const Identifier& id, T&& value)
|
||||||
|
{
|
||||||
|
map.insert({ id, std::move(value) });
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const T& Get(const Identifier& id) const { return map.at(id); }
|
||||||
|
|
||||||
|
//inline Identifier& GetKey(T& value) const {}
|
||||||
|
|
||||||
|
inline size_t Size() const { return map.size(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
class DefaultedRegistry : public RegistryMap<T>
|
||||||
|
{
|
||||||
|
using string = std::string;
|
||||||
|
|
||||||
|
const Identifier defaultKey;
|
||||||
|
T& defaultValue;
|
||||||
|
|
||||||
|
public:
|
||||||
|
DefaultedRegistry(const string&& defaultKey) : defaultKey(Identifier(defaultKey)) {}
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,93 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Common.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
|
#include <ostream>
|
||||||
|
#include <cctype>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace Feather
|
||||||
|
{
|
||||||
|
// Namespaced ID, like "minecraft:lily_pad", also known as ResourceLocation
|
||||||
|
class Identifier
|
||||||
|
{
|
||||||
|
using string = std::string;
|
||||||
|
using string_view = std::string_view;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
const string m_namespace;
|
||||||
|
const string m_path;
|
||||||
|
|
||||||
|
public:
|
||||||
|
inline static const string_view DEFAULT_NAMESPACE = "minecraft";
|
||||||
|
inline static const char SEPARATOR = ':';
|
||||||
|
|
||||||
|
|
||||||
|
Identifier(const string&& ns, const string&& path) :
|
||||||
|
m_namespace(ns.empty() ? DEFAULT_NAMESPACE : ns),
|
||||||
|
m_path(path)
|
||||||
|
{
|
||||||
|
Assert(IsValidNamespace(m_namespace), "Identifier namespace contains non [a-z0-9_.-] character: {}", m_namespace);
|
||||||
|
Assert(IsValidPath(m_path), "Identifier path contains non [a-z0-9/._-] character: {}", m_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
Identifier(const string& id) : Identifier(id, id.find(SEPARATOR)) {}
|
||||||
|
|
||||||
|
inline const string_view& GetNamespace() const { return m_namespace; }
|
||||||
|
inline const string_view& GetPath() const { return m_path; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Operators
|
||||||
|
|
||||||
|
inline bool operator==(const Identifier& id) const { return this == &id || (m_namespace == id.m_namespace && m_path == id.m_path); }
|
||||||
|
|
||||||
|
inline bool operator<(const Identifier& id) const { return this != &id && (m_path < id.m_path || m_namespace < id.m_namespace); }
|
||||||
|
|
||||||
|
friend inline std::ostream& operator<<(std::ostream& st, const Identifier& id)
|
||||||
|
{
|
||||||
|
return st << id.m_namespace.data() << ":" << id.m_path.data();
|
||||||
|
}
|
||||||
|
protected:
|
||||||
|
|
||||||
|
// Construct an Identifier having found the separator character, if any
|
||||||
|
Identifier(const string& id, const size_t split) : Identifier(
|
||||||
|
split == string::npos ? "" : id.substr(0, split),
|
||||||
|
split == string::npos ? id : id.substr(split + 1))
|
||||||
|
{}
|
||||||
|
|
||||||
|
// Identifiers: 0-9 a-z _ : / . -
|
||||||
|
inline static bool AllowedChar(char c)
|
||||||
|
{
|
||||||
|
return ('0' <= c && c <= '9') || ('a' <= c && c <= 'z') || c == '_' || c == ':' || c == '/' || c == '.' || c == '-';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Paths cannot contain :
|
||||||
|
inline static bool IsValidPath(const string& ns)
|
||||||
|
{
|
||||||
|
return std::all_of(ns.begin(), ns.end(), [](char c) { return AllowedChar(c) && c != ':'; });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Namespaces cannot contain : or /
|
||||||
|
inline static bool IsValidNamespace(const string& ns)
|
||||||
|
{
|
||||||
|
return std::all_of(ns.begin(), ns.end(), [](char c) { return AllowedChar(c) && c != '/' && c != ':'; });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct std::hash<Feather::Identifier>
|
||||||
|
{
|
||||||
|
size_t operator()(const Feather::Identifier& id) const
|
||||||
|
{
|
||||||
|
using std::hash;
|
||||||
|
using std::string_view;
|
||||||
|
|
||||||
|
// based on Mojang's ResourceLocation.hashCode()
|
||||||
|
return 31 * hash<string_view>{}(id.GetNamespace()) + hash<string_view>{}(id.GetPath());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
|
@ -16,6 +16,7 @@ using std::stringstream;
|
||||||
|
|
||||||
namespace Feather
|
namespace Feather
|
||||||
{
|
{
|
||||||
|
// TODO: move this to ChunkSection
|
||||||
const GlobalPalette<BlockState> World::GLOBAL_PALETTE = GlobalPalette<BlockState>(
|
const GlobalPalette<BlockState> World::GLOBAL_PALETTE = GlobalPalette<BlockState>(
|
||||||
Registry::BLOCK_STATES,
|
Registry::BLOCK_STATES,
|
||||||
new BlockState("minecraft:air") // temp
|
new BlockState("minecraft:air") // temp
|
||||||
|
|
|
@ -29,6 +29,7 @@ namespace Feather
|
||||||
void PrepareSpawn();
|
void PrepareSpawn();
|
||||||
|
|
||||||
// global palette of all block states
|
// global palette of all block states
|
||||||
|
// TODO: move this to ChunkSection
|
||||||
static const GlobalPalette<BlockState> GLOBAL_PALETTE;
|
static const GlobalPalette<BlockState> GLOBAL_PALETTE;
|
||||||
|
|
||||||
Chunk* GetChunk(ChunkPos pos);
|
Chunk* GetChunk(ChunkPos pos);
|
||||||
|
|
Loading…
Reference in New Issue