UUID & start on IDs
This commit is contained in:
parent
1297af3db1
commit
387bc84985
|
@ -7,12 +7,14 @@ set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
|
|||
|
||||
FILE(GLOB_RECURSE SOURCES
|
||||
core/src/*.cpp
|
||||
shadow-entity/src/*.cpp
|
||||
shadow-renderer/src/*.cpp
|
||||
shadow-reflection/src/*.cpp
|
||||
shadow-utility/src/*.cpp
|
||||
)
|
||||
FILE(GLOB_RECURSE HEADERS
|
||||
core/inc/*.h
|
||||
shadow-entity/inc/*.h
|
||||
shadow-renderer/inc/*.h
|
||||
shadow-reflection/inc/*.h
|
||||
shadow-utility/inc/*.h
|
||||
|
@ -24,6 +26,7 @@ target_include_directories(shadow-engine
|
|||
PRIVATE ${SDL2_INCLUDE_DIRS}
|
||||
PUBLIC
|
||||
core/inc
|
||||
shadow-entity/inc
|
||||
shadow-renderer/inc
|
||||
shadow-reflection/inc
|
||||
shadow-utility/inc
|
||||
|
|
64
projs/shadow/shadow-engine/core/inc/id/UUID.h
Normal file
64
projs/shadow/shadow-engine/core/inc/id/UUID.h
Normal file
|
@ -0,0 +1,64 @@
|
|||
#pragma once
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
|
||||
// ShadowEntity temporary namespace
|
||||
namespace SE {
|
||||
|
||||
/**
|
||||
* Universally Unique ID.
|
||||
* 128 Bits.
|
||||
*
|
||||
* Unique per runtime only - the suitability for serialization is undetermined.
|
||||
*/
|
||||
|
||||
class UUID {
|
||||
|
||||
/**
|
||||
* Data storage; 128 bits.
|
||||
* 2 x 64 bit
|
||||
* 4 x 32 bit
|
||||
* 16 x 8 bit
|
||||
*/
|
||||
|
||||
union Data {
|
||||
uint64_t u64[2];
|
||||
uint32_t u32[4];
|
||||
uint8_t u8[16];
|
||||
};
|
||||
|
||||
public:
|
||||
// Create a new, unused, UUID.
|
||||
static UUID Generate();
|
||||
// Check whether the UUID is correctly formed.
|
||||
static bool IsValidStr(char const* str);
|
||||
|
||||
// Create an empty UUID.
|
||||
inline UUID() { std::memset(&data.u8, 0, 16); }
|
||||
// Create a UUID based on the given values.
|
||||
inline UUID(uint64_t i0, uint64_t i1) { data.u64[0] = i0; data.u64[1] = i1; }
|
||||
inline UUID(uint32_t i0, uint32_t i1, uint32_t i2, uint32_t i3) { data.u32[0] = i0; data.u32[1] = i1; data.u32[2] = i2; data.u32[3] = i3; }
|
||||
inline explicit UUID(std::string const& str) : UUID(str.c_str()) {}
|
||||
// Create a UUID from the given format.
|
||||
explicit UUID(char const* str);
|
||||
|
||||
// Check whether the UUID is nonzero.
|
||||
inline bool IsValid() const { return data.u64[0] != 0 && data.u64[1] != 0; }
|
||||
// Set the UUID to zero.
|
||||
inline void Clear() { std::memset(&data.u8, 0, 16); }
|
||||
|
||||
// Get a section of the UUID's data as the given bit width.
|
||||
inline uint8_t GetU8(size_t idx) const { return data.u8[idx]; }
|
||||
inline uint32_t GetU32(size_t idx) const { return data.u32[idx]; }
|
||||
inline uint64_t GetU64(size_t idx) const { return data.u64[idx]; }
|
||||
|
||||
// Check whether this and a given UUID are in/equal.
|
||||
__inline bool operator==(UUID const& other) const { return data.u64[0] == other.data.u64[0] && data.u64[1] == other.data.u64[1]; }
|
||||
__inline bool operator!=(UUID const& other) const { return !(*this == other); }
|
||||
|
||||
private:
|
||||
|
||||
Data data {};
|
||||
};
|
||||
}
|
56
projs/shadow/shadow-engine/core/src/id/UUID.cpp
Normal file
56
projs/shadow/shadow-engine/core/src/id/UUID.cpp
Normal file
|
@ -0,0 +1,56 @@
|
|||
#include <id/UUID.h>
|
||||
|
||||
namespace SE {
|
||||
static_assert(sizeof(UUID) == 16, "UUID has incorrect size");
|
||||
|
||||
/**
|
||||
* Verify that a string has the correct format;
|
||||
* XXXXXXXX-XXXX-XXX-XXXXX-XXXXXXXXXXXX
|
||||
*
|
||||
* The length must be 36.
|
||||
* There must be dashes at index 8, 13, 18 and 23.
|
||||
* @param str the input string
|
||||
* @return whether the UUID string is correctly formed
|
||||
*/
|
||||
bool UUID::IsValidStr(const char *str) {
|
||||
size_t const len = strlen(str);
|
||||
if (len != 36) return false;
|
||||
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
char c = str[i];
|
||||
if (c == '-') {
|
||||
if (i != 8 && i != 13 && i != 18 && i != 23) return false;
|
||||
} else if (! std::isxdigit(c)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
UUID::UUID(char const* str ) {
|
||||
// A single byte is two hex characters.
|
||||
// Store them here so that we can use them later.
|
||||
char c0 = '\0', c1;
|
||||
|
||||
size_t const len = strlen( str );
|
||||
uint32_t byteIdx = 0;
|
||||
|
||||
for (size_t i = 0; i < len; i++ ) {
|
||||
char const c = str[i];
|
||||
if ( c == '-' )
|
||||
continue;
|
||||
|
||||
// Scan for pairs of characters.
|
||||
// Only assign a byte if two have been parsed.
|
||||
if (c0 == '\0') {
|
||||
c0 = c;
|
||||
} else {
|
||||
c1 = c;
|
||||
data.u8[byteIdx++] = std::stoi(std::string(c0, c1));
|
||||
// Reset the first char so that we can return to scanning a pair.
|
||||
c0 = '\0';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
60
projs/shadow/shadow-engine/shadow-entity/inc/id/ID.h
Normal file
60
projs/shadow/shadow-engine/shadow-entity/inc/id/ID.h
Normal file
|
@ -0,0 +1,60 @@
|
|||
#pragma once
|
||||
|
||||
#include <id/UUID.h> // Shadow-Engine/core/inc/id
|
||||
|
||||
namespace SE {
|
||||
|
||||
// An ID for a section of the scene (which may be unloaded separately of the level; for ie. open world Cells.)
|
||||
using EntitySectionID = UUID;
|
||||
// An ID for a scene (which contains all sections and entities).
|
||||
using EntitySceneID = UUID;
|
||||
|
||||
/**
|
||||
* Contains the common data and functions for the Entity System's identifiers.
|
||||
*/
|
||||
struct IDContainer {
|
||||
public:
|
||||
IDContainer() = default;
|
||||
explicit IDContainer(uint64_t v) : id(v) {}
|
||||
|
||||
// Check if the ID is valid (non-zero)
|
||||
__inline bool Valid() const { return id != 0; }
|
||||
// Set this ID to be invalid (zero).
|
||||
__inline void Invalidate() { id = 0; }
|
||||
// Check for in/equality against another ID.
|
||||
__inline bool operator==(IDContainer const& other) const { return id == other.id; }
|
||||
__inline bool operator!=(IDContainer const& other) const { return id != other.id; }
|
||||
|
||||
uint64_t id;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* An ID used for an Entity.
|
||||
* Is only guaranteed to be unique in the current scene (ie. a level change may also change the IDs of the entities within).
|
||||
*/
|
||||
struct EntityID : public IDContainer {
|
||||
/**
|
||||
* @return a new, unused Entity ID.
|
||||
*/
|
||||
static EntityID Generate();
|
||||
|
||||
EntityID() = default;
|
||||
explicit EntityID(uint64_t v) : IDContainer(v) {}
|
||||
};
|
||||
|
||||
/**
|
||||
* An ID used for a Component (a segment of data attached to an Entity).
|
||||
* Is only guaranteed to be unique in the current scene (ie. a level change may also change the IDs of the components within).
|
||||
*/
|
||||
struct ComponentID : public IDContainer {
|
||||
/**
|
||||
* @return a new, unused Component ID.
|
||||
*/
|
||||
static ComponentID Generate();
|
||||
|
||||
ComponentID() = default;
|
||||
explicit ComponentID(uint64_t v) : IDContainer(v) {}
|
||||
};
|
||||
}
|
||||
|
16
projs/shadow/shadow-engine/shadow-entity/src/id/ID.cpp
Normal file
16
projs/shadow/shadow-engine/shadow-entity/src/id/ID.cpp
Normal file
|
@ -0,0 +1,16 @@
|
|||
#include <id/ID.h>
|
||||
#include <atomic>
|
||||
|
||||
namespace SE {
|
||||
static std::atomic<uint64_t> entityID = 1;
|
||||
EntityID EntityID::Generate() {
|
||||
EntityID id(entityID++);
|
||||
return id;
|
||||
}
|
||||
|
||||
static std::atomic<uint64_t> componentID = 1;
|
||||
ComponentID ComponentID::Generate() {
|
||||
ComponentID id(componentID++);
|
||||
return id;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user