diff --git a/bin/data/scenes/sourceengine/mds_mcdonalds.json b/bin/data/scenes/sourceengine/mds_mcdonalds.json index 93efcd9c..0968a1ce 100644 --- a/bin/data/scenes/sourceengine/mds_mcdonalds.json +++ b/bin/data/scenes/sourceengine/mds_mcdonalds.json @@ -1,8 +1,8 @@ { "import": "./base_sourceengine.json", "assets": [ - { "filename": "./maps/mds_mcdonalds.bsp" } - // { "filename": "./maps/mds_mcdonalds/graph.json" } + // { "filename": "./maps/mds_mcdonalds.bsp" } + { "filename": "./maps/mds_mcdonalds/graph.json" } ], "metadata": { "graph": { diff --git a/bin/data/scenes/sourceengine/sourceengine.json b/bin/data/scenes/sourceengine/sourceengine.json index 065d566b..bdb37541 100644 --- a/bin/data/scenes/sourceengine/sourceengine.json +++ b/bin/data/scenes/sourceengine/sourceengine.json @@ -1,7 +1,7 @@ { // "import": "./rp_downtown_v2.json" // "import": "./ss2_medsci1.json" -// "import": "./mds_mcdonalds.json" - "import": "./cs_office.json" + "import": "./mds_mcdonalds.json" +// "import": "./cs_office.json" // "import": "./gm_construct.json" } \ No newline at end of file diff --git a/engine/inc/uf/engine/entity/entity.h b/engine/inc/uf/engine/entity/entity.h index 812a6b96..a66a741d 100644 --- a/engine/inc/uf/engine/entity/entity.h +++ b/engine/inc/uf/engine/entity/entity.h @@ -110,10 +110,9 @@ namespace uf { template T loadChild( const uf::Serializer&, bool = true ); template T loadChild( const uf::stl::string&, bool = true ); - #if UF_HOOKS_HASH_KEYS - uf::hashed_string formatHookName( const uf::stl::string& n ); - static uf::hashed_string formatHookName( const uf::stl::string& n, size_t uid, bool fetch = false ); - + inline uf::hashed_string formatHookName( const uf::stl::string_view& n ); + static inline uf::hashed_string formatHookName( const uf::stl::string_view& n, size_t uid, bool fetch = false ); + inline size_t resolveHookKey( size_t hash ) const { return hash; } inline size_t resolveHookKey( const uf::stl::string& name ) { return this->formatHookName(name); } @@ -125,7 +124,7 @@ namespace uf { template inline void queueHook( const K& name, float timeout = 0 ); template inline void queueHook( const K& name, const V&, float = 0 ); - template uf::Hooks::return_t lazyCallHook(const K& name, Args&&... args) { + template inline uf::Hooks::return_t lazyCallHook(const K& name, Args&&... args) { if ( uf::Object::deferLazyCalls ) { this->queueHook(name, std::forward(args)..., 0.0f); return {}; @@ -136,27 +135,6 @@ namespace uf { template inline uf::Hooks::return_t callHook( const K& name, Args&&... args ) { return uf::hooks.call( this->resolveHookKey(name), std::forward(args)... ); } - #else - uf::stl::string formatHookName( const uf::stl::string& n ); - static uf::stl::string formatHookName( const uf::stl::string& n, size_t uid, bool fetch = false ); - - template size_t addHook( const uf::stl::string& name, T function ); - - template inline void queueHook( const K& name, float timeout = 0 ); - template inline void queueHook( const K& name, const V&, float = 0 ); - - template uf::Hooks::return_t lazyCallHook(const K& name, Args&&... args) { - if ( uf::Object::deferLazyCalls ) { - this->queueHook(name, std::forward(args)..., 0.0f); - return {}; - } - return this->callHook( name, std::forward(args)... ); - } - - template inline uf::Hooks::return_t callHook( const K& name, Args&&... args ) { - return uf::hooks.call( this->formatHookName( name ), std::forward(args)... ); - } - #endif uf::stl::string resolveURI( const uf::stl::string& filename, const uf::stl::string& root = "" ); uf::asset::Payload resolveToPayload( const uf::stl::string& filename, const uf::stl::string& mime = "" ); diff --git a/engine/inc/uf/engine/object/object.inl b/engine/inc/uf/engine/object/object.inl index 651c2cff..37c34732 100644 --- a/engine/inc/uf/engine/object/object.inl +++ b/engine/inc/uf/engine/object/object.inl @@ -17,7 +17,39 @@ T uf::Object::loadChild( const uf::stl::string& filename, bool initialize ) { return this->loadChild(filename, initialize); } -#if UF_HOOKS_HASH_KEYS +uf::hashed_string uf::Object::formatHookName( const uf::stl::string_view& n ) { + constexpr uf::stl::string_view PARENT_UID_SUFFIX = "%P-UID%"; + constexpr uf::stl::string_view UID_SUFFIX = "%UID%"; + + if ( n.ends_with(PARENT_UID_SUFFIX) ) { + size_t uid = this->hasParent() ? this->getParent().getUid() : this->getUid(); + uf::hashed_string hash{uf::stl::string_view(n).substr(0, n.size() - PARENT_UID_SUFFIX.size())}; + return uf::algo::fnv1a( ::fmt::format("{}", uid), hash ); + } + if ( n.ends_with(UID_SUFFIX) ) { + size_t uid = this->getUid(); + uf::hashed_string hash{uf::stl::string_view(n).substr(0, n.size() - UID_SUFFIX.size())}; + return uf::algo::fnv1a( ::fmt::format("{}", uid), hash ); + } + + return n; +} +uf::hashed_string uf::Object::formatHookName( const uf::stl::string_view& n, size_t uid, bool fetch ) { + if ( fetch ) { + auto* object = (uf::Object*) uf::Entity::globalFindByUid( uid ); + if ( object ) return object->formatHookName( n ); + } + + constexpr uf::stl::string_view UID_SUFFIX = "%UID%"; + + if ( n.ends_with(UID_SUFFIX) ) { + uf::hashed_string hash = uf::stl::string_view(n).substr(0, n.size() - UID_SUFFIX.size()); + return uf::algo::fnv1a( ::fmt::format("{}", uid), hash ); + } + + return n; +} + template size_t uf::Object::addHook( const size_t& name, T callback ) { size_t id = uf::hooks.addHook( name, callback ); @@ -25,16 +57,6 @@ size_t uf::Object::addHook( const size_t& name, T callback ) { metadata.hooks.bound[name].emplace_back(id); return id; } -#else -template -size_t uf::Object::addHook( const uf::stl::string& n, T callback ) { - auto name = this->formatHookName( n ); - size_t id = uf::hooks.addHook( name, callback ); - auto& metadata = this->getComponent(); - metadata.hooks.bound[name].emplace_back(id); - return id; -} -#endif template inline void uf::Object::queueHook( const K& name, float d ) { auto& metadata = this->getComponent(); diff --git a/engine/inc/uf/spec/window/universal.h b/engine/inc/uf/spec/window/universal.h index 933a0ff1..576d772a 100644 --- a/engine/inc/uf/spec/window/universal.h +++ b/engine/inc/uf/spec/window/universal.h @@ -18,7 +18,7 @@ namespace spec { typedef pod::Vector2i vector_t; struct Event { - uf::stl::string name; + uf::Hooks::name_t name; // ugh pod::Hook::userdata_t payload; }; protected: diff --git a/engine/inc/uf/utils/hook/hook.h b/engine/inc/uf/utils/hook/hook.h index 56c44e0d..5ac0116c 100644 --- a/engine/inc/uf/utils/hook/hook.h +++ b/engine/inc/uf/utils/hook/hook.h @@ -36,7 +36,7 @@ namespace pod { }; } -#define UF_HOOKS_HASH_KEYS 0 +#define UF_HOOKS_HASH_KEYS 1 namespace uf { class UF_API Hooks { diff --git a/engine/inc/uf/utils/math/hash.h b/engine/inc/uf/utils/math/hash.h index c9d8be38..5033b3e4 100644 --- a/engine/inc/uf/utils/math/hash.h +++ b/engine/inc/uf/utils/math/hash.h @@ -19,23 +19,19 @@ namespace uf { using FNV = FNV1a; constexpr size_t fnv1a(const char* str, size_t hash = FNV::basis) { - return *str ? fnv1a(str + 1, (hash ^ static_cast(*str)) * FNV::prime) : hash; + return *str ? fnv1a(str + 1, (hash ^ static_cast(static_cast(*str))) * FNV::prime) : hash; } - constexpr size_t fnv1a(const uf::stl::string_view str) { - size_t hash = FNV::basis; + constexpr size_t fnv1a(const uf::stl::string_view str, size_t hash = FNV::basis) { for (char c : str) hash = (hash ^ static_cast(c)) * FNV::prime; return hash; } - /* - inline size_t fnv1a(const uf::stl::string& str) { - return fnv1a(uf::stl::string_view(str)); + inline size_t fnv1a(const uf::stl::string& str, size_t hash = FNV::basis) { + return fnv1a(uf::stl::string_view(str), hash); } - */ - template, int> = 0> - inline size_t fnv1a(const T& v) { - size_t hash = FNV::basis; + template && !std::is_array_v && !std::is_pointer_v, int> = 0> + inline size_t fnv1a(const T& v, size_t hash = FNV::basis) { const uint8_t* bytes = reinterpret_cast(&v); for (size_t i = 0; i < sizeof(T); ++i) { hash = (hash ^ static_cast(bytes[i])) * FNV::prime; @@ -43,10 +39,13 @@ namespace uf { return hash; } - template - inline size_t fnv1a(const uf::stl::vector& values) { - size_t hash = FNV::basis; + template + constexpr size_t fnv1a(const char (&str)[N], size_t hash = FNV::basis) { + return fnv1a(uf::stl::string_view(str, N - 1), hash); + } + template + inline size_t fnv1a(const uf::stl::vector& values, size_t hash = FNV::basis) { if constexpr (std::is_same_v) { for (bool b : values) { hash = (hash ^ static_cast(b)) * FNV::prime; diff --git a/engine/inc/uf/utils/string/hash.h b/engine/inc/uf/utils/string/hash.h index 29174ff1..be06dce2 100644 --- a/engine/inc/uf/utils/string/hash.h +++ b/engine/inc/uf/utils/string/hash.h @@ -22,12 +22,13 @@ namespace uf { typedef size_t hash_t; size_t hash; - uf::stl::string string; - constexpr hashed_string() : hash(0), string("NULL") {} - constexpr hashed_string(size_t h) : hash(h), string("NULL") {} - constexpr hashed_string(const char* s) : hash(uf::algo::fnv1a(s)), string(s) {} - inline hashed_string(const uf::stl::string& s) : hash(uf::algo::fnv1a(s)), string(s) {} + constexpr hashed_string() : hash(0) {} + constexpr hashed_string(size_t h) : hash(h) {} + constexpr hashed_string(const char* s) : hash(uf::algo::fnv1a(s)) {} + template constexpr hashed_string(const char (&s)[N]) : hash(uf::algo::fnv1a(s)) {} + inline hashed_string(const uf::stl::string& s) : hash(uf::algo::fnv1a(s)) {} + inline hashed_string(const uf::stl::string_view& s) : hash(uf::algo::fnv1a(s)) {} constexpr operator size_t() const { return hash; } diff --git a/engine/src/engine/object/object.cpp b/engine/src/engine/object/object.cpp index e23809f3..376c085d 100644 --- a/engine/src/engine/object/object.cpp +++ b/engine/src/engine/object/object.cpp @@ -65,62 +65,6 @@ void uf::Object::queueDeletion() { this->callHook("entity:Destroy.%UID%"); } -#if UF_HOOKS_HASH_KEYS -uf::hashed_string uf::Object::formatHookName( const uf::stl::string& n, size_t uid, bool fetch ) { - if ( fetch ) { - auto* object = (uf::Object*) uf::Entity::globalFindByUid( uid ); - if ( object ) return object->formatHookName( n ); - } - - size_t hash = {}; - uf::hash( hash, n ); - if ( n.ends_with("%UID%") ) uf::hash( hash, uid ); - - uf::hashed_string res = hash; - res.string = n; - return res; -} - - -uf::hashed_string uf::Object::formatHookName( const uf::stl::string& n ) { - size_t uid = this->getUid(); - size_t parent = this->hasParent() ? this->getParent().getUid() : uid; - - size_t hash = {}; - uf::hash( hash, n ); - if ( n.ends_with("%P-UID%") ) uf::hash( hash, parent ); - else if ( n.ends_with("%UID%") ) uf::hash( hash, uid ); - - uf::hashed_string res = hash; - res.string = n; - return res; -} -#else -uf::stl::string uf::Object::formatHookName( const uf::stl::string& n, size_t uid, bool fetch ) { - if ( fetch ) { - auto* object = (uf::Object*) uf::Entity::globalFindByUid( uid ); - if ( object ) return object->formatHookName( n ); - } - - uf::stl::string res = n; - if ( n.ends_with("%UID%") ) res = uf::string::replace( res, "%UID%", ::fmt::format( "{}", uid ) ); - - return res; -} - - -uf::stl::string uf::Object::formatHookName( const uf::stl::string& n ) { - size_t uid = this->getUid(); - size_t parent = this->hasParent() ? this->getParent().getUid() : uid; - - uf::stl::string res = n; - if ( n.ends_with("%P-UID%") ) res = uf::string::replace( res, "%P-UID%", ::fmt::format( "{}", parent ) ); - else if ( n.ends_with("%UID%") ) res = uf::string::replace( res, "%UID%", ::fmt::format( "{}", uid ) ); - - return res; -} -#endif - bool uf::Object::load( const uf::stl::string& f, bool inheritRoot ) { uf::Serializer json; uf::stl::string root = ""; diff --git a/engine/src/spec/window/windows.cpp b/engine/src/spec/window/windows.cpp index 61846747..311a30d1 100644 --- a/engine/src/spec/window/windows.cpp +++ b/engine/src/spec/window/windows.cpp @@ -865,7 +865,7 @@ void spec::win32::Window::processEvents() { }; #if UF_HOOK_USE_JSON ext::json::Value json; - json["type"] = event.type + "." + ((event.key.state == -1)?"Pressed":"Released"); + json["type"] = ::fmt::format("{}.{}", event.type, (event.key.state == -1) ? "Pressed" : "Released"); json["invoker"] = event.invoker; json["key"]["code"] = ""; json["key"]["raw"] = 0; @@ -881,15 +881,16 @@ void spec::win32::Window::processEvents() { event.key.code = code; event.key.raw = key; + auto eventName = ::fmt::format("{}.{}", event.type, code); #if UF_HOOK_USE_USERDATA this->pushEvent(event.type, event); - this->pushEvent(event.type + "." + code, event); + this->pushEvent(eventName, event); #endif #if UF_HOOK_USE_JSON json["key"]["code"] = code; json["key"]["raw"] = key; this->pushEvent(event.type, json); - this->pushEvent(event.type + "." + code, json); + this->pushEvent(eventName, json); #endif } } @@ -1144,13 +1145,14 @@ void spec::win32::Window::processEvent(UINT message, WPARAM wParam, LPARAM lPara } } }; + auto eventName = ::fmt::format("{}.{}", event.type, event.key.code); #if UF_HOOK_USE_USERDATA this->pushEvent(event.type, event); - this->pushEvent(event.type + "." + event.key.code, event); + this->pushEvent(eventName, event); #endif #if UF_HOOK_USE_JSON ext::json::Value json; - json["type"] = event.type + "." + ((event.key.state == -1)?"Pressed":"Released"); + json["type"] = ::fmt::format("{}.{}", event.type, (event.key.state == -1) ? "Pressed" : "Released"); json["invoker"] = event.invoker; json["key"]["state"] = (event.key.state == -1) ? "Down" : "Up"; json["key"]["async"] = event.key.async; @@ -1163,7 +1165,7 @@ void spec::win32::Window::processEvent(UINT message, WPARAM wParam, LPARAM lPara json["key"]["raw"] = event.key.raw; json["key"]["lparam"] = lParam; this->pushEvent(event.type, json); - this->pushEvent(event.type + "." + event.key.code, json); + this->pushEvent(eventName, json); #endif } } break;