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
|
FILE(GLOB_RECURSE SOURCES
|
||||||
core/src/*.cpp
|
core/src/*.cpp
|
||||||
|
shadow-entity/src/*.cpp
|
||||||
shadow-renderer/src/*.cpp
|
shadow-renderer/src/*.cpp
|
||||||
shadow-reflection/src/*.cpp
|
shadow-reflection/src/*.cpp
|
||||||
shadow-utility/src/*.cpp
|
shadow-utility/src/*.cpp
|
||||||
)
|
)
|
||||||
FILE(GLOB_RECURSE HEADERS
|
FILE(GLOB_RECURSE HEADERS
|
||||||
core/inc/*.h
|
core/inc/*.h
|
||||||
|
shadow-entity/inc/*.h
|
||||||
shadow-renderer/inc/*.h
|
shadow-renderer/inc/*.h
|
||||||
shadow-reflection/inc/*.h
|
shadow-reflection/inc/*.h
|
||||||
shadow-utility/inc/*.h
|
shadow-utility/inc/*.h
|
||||||
|
@ -24,6 +26,7 @@ target_include_directories(shadow-engine
|
||||||
PRIVATE ${SDL2_INCLUDE_DIRS}
|
PRIVATE ${SDL2_INCLUDE_DIRS}
|
||||||
PUBLIC
|
PUBLIC
|
||||||
core/inc
|
core/inc
|
||||||
|
shadow-entity/inc
|
||||||
shadow-renderer/inc
|
shadow-renderer/inc
|
||||||
shadow-reflection/inc
|
shadow-reflection/inc
|
||||||
shadow-utility/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