microoptimization of having hook system keyed to hashes rather than strings directly (and hash hook names containing '%UID%' with that entity's UID rather than replace the string)

This commit is contained in:
ecker 2026-06-09 19:54:24 -05:00
parent 0fdba55927
commit f9d7cf2dc8
29 changed files with 142 additions and 266 deletions

View File

@ -110,53 +110,32 @@ namespace uf {
template<typename T> T loadChild( const uf::Serializer&, bool = true );
template<typename T> T loadChild( const uf::stl::string&, bool = true );
/*
uf::hashed_string formatHookName( const uf::stl::string_view n, size_t uid, bool fetch );
uf::hashed_string formatHookName( const uf::stl::string_view n );
*/
uf::stl::string formatHookName( const uf::stl::string& n, size_t uid, bool fetch );
uf::stl::string formatHookName( const uf::stl::string& n );
template<typename T> size_t addHook( const uf::stl::string& name, T function );
uf::Hooks::return_t lazyCallHook( const uf::stl::string& );
uf::Hooks::return_t lazyCallHook( const uf::stl::string&, const pod::Hook::userdata_t& );
template<typename T> uf::Hooks::return_t lazyCallHook( const uf::stl::string& name, const T& payload );
void queueHook( const uf::stl::string&, float = 0 );
void queueHook( const uf::stl::string&, const ext::json::Value& json, float = 0 );
template<typename T> void queueHook( const uf::stl::string&, const T&, float = 0 );
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::Hooks::return_t callHook( const uf::stl::string& name ) {
return uf::hooks.call( this->formatHookName( name ) );
}
inline uf::Hooks::return_t callHook( const uf::stl::string& name, const pod::Hook::userdata_t& payload ) {
return uf::hooks.call( this->formatHookName( name ), payload );
}
template<typename T> inline uf::Hooks::return_t callHook( const uf::stl::string& name, const T& p ) {
return uf::hooks.call( this->formatHookName( name ), p );
inline size_t resolveHookKey(size_t hash) const { return hash; }
inline size_t resolveHookKey(const uf::stl::string& name) { return this->formatHookName(name); }
template<typename T> size_t addHook( const size_t& name, T function );
template<typename T> inline size_t addHook( const uf::stl::string& name, T function ) {
return this->addHook( this->formatHookName( name ), function );
}
/*
inline void queueHook( const size_t& name, float timeout = 0 ) {
return this->queueHook( name, timeout);
}
inline void queueHook( const size_t& name, const ext::json::Value& json, float timeout = 0 ) {
return this->queueHook( name, timeout);
}
template<typename T> inline void queueHook( const size_t& name, const T& payload, float timeout = 0 ) {
return this->queueHook( name, timeout);
}
inline uf::Hooks::return_t callHook( const size_t& name ) {
return uf::hooks.call( name );
}
inline uf::Hooks::return_t callHook( const size_t& name, const pod::Hook::userdata_t& payload ) {
return uf::hooks.call( name, payload );
}
template<typename T> inline uf::Hooks::return_t callHook( const size_t& name, const T& p ) {
return uf::hooks.call( name, p );
}
*/
template<typename K> inline void queueHook( const K& name, float timeout = 0 );
template<typename K, typename V> inline void queueHook( const K& name, const V&, float = 0 );
template<typename K, typename... Args> uf::Hooks::return_t lazyCallHook(const K& name, Args&&... args) {
if ( uf::Object::deferLazyCalls ) {
this->queueHook(name, std::forward<Args>(args)..., 0.0f);
return {};
}
return this->callHook( name, std::forward<Args>(args)... );
}
template<typename K, typename... Args> inline uf::Hooks::return_t callHook( const K& name, Args&&... args ) {
return uf::hooks.call( this->resolveHookKey(name), std::forward<Args>(args)... );
}
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 = "" );

View File

@ -17,9 +17,10 @@ namespace uf {
UF_BEHAVIOR_DEFINE_FUNCTIONS();
UF_BEHAVIOR_DEFINE_METADATA(
struct Queued {
uf::Hooks::name_t name = "";
uf::stl::string name = "";
size_t hash = 0;
double timeout = 0;
int_fast8_t type = 0;
int type = 0;
pod::Hook::userdata_t userdata{};
ext::json::Value json{};

View File

@ -16,33 +16,43 @@ T uf::Object::loadChild( const uf::stl::string& filename, bool initialize ) {
// T is reference
return this->loadChild(filename, initialize);
}
template<typename T>
size_t uf::Object::addHook( const uf::stl::string& name, T callback ) {
auto parsed = this->formatHookName( name );
std::size_t id = uf::hooks.addHook( parsed, callback );
size_t uf::Object::addHook( const size_t& name, T callback ) {
size_t id = uf::hooks.addHook( name, callback );
auto& metadata = this->getComponent<uf::ObjectBehavior::Metadata>();
metadata.hooks.bound[parsed].emplace_back(id);
metadata.hooks.bound[name].emplace_back(id);
return id;
}
template<typename T>
uf::Hooks::return_t uf::Object::lazyCallHook( const uf::stl::string& name, const T& p ) {
if ( uf::Object::deferLazyCalls ) {
this->queueHook( name, p, 0.0f );
return {};
}
return this->callHook( name, p );
}
template<typename T>
void uf::Object::queueHook( const uf::stl::string& name, const T& p, float d ) {
template<typename K> inline void uf::Object::queueHook( const K& name, float d ) {
auto& metadata = this->getComponent<uf::ObjectBehavior::Metadata>();
auto& queue = metadata.hooks.queue.emplace_back(uf::ObjectBehavior::Metadata::Queued{
.name = name,
.timeout = uf::time::current + d,
.type = 1,
});
queue.userdata.create<T>(p);
if constexpr ( std::is_same<K, size_t>::value ) {
queue.hash = name;
} else {
queue.name = name;
}
}
template<typename K, typename V>
void uf::Object::queueHook( const K& name, const V& p, float d ) {
auto& metadata = this->getComponent<uf::ObjectBehavior::Metadata>();
auto& queue = metadata.hooks.queue.emplace_back(uf::ObjectBehavior::Metadata::Queued{
.timeout = uf::time::current + d,
});
if constexpr ( std::is_same<K, size_t>::value ) {
queue.hash = name;
} else {
queue.name = name;
}
if constexpr ( std::is_same<V, ext::json::Value>::value ) {
queue.type = -1;
queue.json = p;
} else {
queue.type = 1;
queue.userdata.create<V>(p);
}
}

View File

@ -36,11 +36,16 @@ namespace pod {
};
}
#define UF_HOOKS_HASH_KEYS 1
namespace uf {
class UF_API Hooks {
public:
//typedef uf::hashed_string name_t;
#if UF_HOOKS_HASH_KEYS
typedef uf::hashed_string name_t;
#else
typedef uf::stl::string name_t;
#endif
typedef uf::stl::vector<pod::Hook> hooks_t;
typedef uf::stl::unordered_map<name_t, hooks_t> container_t;

View File

@ -18,6 +18,9 @@ namespace uf {
}
struct hashed_string {
typedef uf::stl::string string_t;
typedef size_t hash_t;
size_t hash;
constexpr hashed_string() : hash(0) {}

View File

@ -174,9 +174,5 @@ uf::Entity* uf::Entity::globalFindByName( const uf::stl::string& name ) {
}
uf::stl::string uf::string::toString( const uf::Entity& entity ) {
#if UF_USE_FMT
return ::fmt::format("({}): {}", entity.getUid(), entity.getName());
#else
return "(" + std::to_string(entity.getUid()) + ") :" + entity.getName();
#endif
}

View File

@ -54,7 +54,7 @@ void ext::BakingBehavior::initialize( uf::Object& self ) {
this->addHook( "entity:PostInitialization.%UID%", [&](){
metadata.output = this->resolveURI( metadataJson["baking"]["output"].as<uf::stl::string>(), metadataJson["baking"]["root"].as<uf::stl::string>() );
metadata.renderModeName = "B:" + std::to_string((int) this->getUid());
metadata.renderModeName = ::fmt::format("B:{}", this->getUid());
metadata.trigger.mode = metadataJson["baking"]["trigger"]["mode"].as( metadata.trigger.mode );
metadata.trigger.value = metadataJson["baking"]["trigger"]["value"].as( metadata.trigger.value );

View File

@ -97,7 +97,7 @@ void ext::LightBehavior::initialize( uf::Object& self ) {
camera.setProjection( uf::matrix::perspective( fov, (float) size.x / (float) size.y, radius.x, radius.y ) );
camera.update();
uf::stl::string name = "RT:" + std::to_string((int) this->getUid());
uf::stl::string name = ::fmt::format("RT:{}", this->getUid());
renderMode.blitter.process = false;
renderMode.execute = false;
renderMode.width = size.x;

View File

@ -85,10 +85,12 @@ void ext::ExtSceneBehavior::initialize( uf::Object& self ) {
*/
};
});
// I don't think this ever gets called
this->addHook( "world:Entity.LoadAsset", [&](pod::payloads::assetLoad& payload){
if ( !payload.object ) return;
uf::asset::load("asset:Load." + std::to_string(payload.object.uid), payload);
uf::asset::load(this->formatHookName("asset:Load.%UID%", payload.object.uid), payload);
});
this->addHook( "shader:Update.%UID%", [&](ext::json::Value& json){
metadata.shader.mode = json["mode"].as<uint32_t>();
@ -335,11 +337,7 @@ void ext::ExtSceneBehavior::tick( uf::Object& self ) {
for ( uf::Scene* scene : uf::scene::scenes ) {
if ( !scene ) continue;
#if UF_USE_FMT
uf::iostream << ::fmt::format("Scene: {}\n", uf::string::toString( *scene ));
#else
uf::iostream << "Scene: " << uf::string::toString( *scene ) << "\n";
#endif
scene->process([]( uf::Entity* entity, int depth ) {
uf::stl::string indent = ""; for ( auto i = 1; i < depth; ++i ) indent += "\t";
uf::stl::string location = "";
@ -349,11 +347,7 @@ void ext::ExtSceneBehavior::tick( uf::Object& self ) {
location = uf::string::toString( t.position ) + " " + uf::string::toString( t.orientation );
}
#if UF_USE_FMT
uf::iostream << ::fmt::format("{} {} {}\n", indent, uf::string::toString( *entity ), location );
#else
uf::iostream << indent << " " << uf::string::toString( *entity ) << " " << location << "\n";
#endif
}, 1);
}
}
@ -1174,7 +1168,7 @@ void ext::ExtSceneBehavior::bindBuffers( uf::Object& self, uf::renderer::Graphic
while ( textures3D.size() < metadata.max.textures3D ) textures3D.emplace_back().aliasTexture(uf::renderer::Texture3D::empty);
static uf::stl::unordered_map<uf::stl::string, UniformDescriptor> previousUniformsMap;
auto& previousUniforms = previousUniformsMap[shaderType+":"+shaderPipeline+":"+std::to_string((size_t) &graphic)];
auto& previousUniforms = previousUniformsMap[::fmt::format("{}:{}:{}", shaderType, shaderPipeline, (size_t)&graphic)];
// update uniform information
// hopefully write combining kicks in

View File

@ -119,7 +119,7 @@ void ext::VoxelizerSceneBehavior::initialize( uf::Object& self ) {
if ( metadata.fragmentSize.y == 0 ) metadata.fragmentSize.y = metadata.voxelSize.y;
auto& renderMode = this->getComponent<uf::renderer::RenderTargetRenderMode>();
metadata.renderModeName = "VXGI:" + std::to_string((int) this->getUid());
metadata.renderModeName = ::fmt::format("VXGI:{}", this->getUid());
renderMode.metadata.name = metadata.renderModeName;
if ( uf::renderer::settings::experimental::registerRenderMode ) uf::renderer::addRenderMode( &renderMode, metadata.renderModeName );

View File

@ -15,6 +15,12 @@
#include <uf/ext/xatlas/xatlas.h>
#endif
namespace {
uf::stl::string keyID( size_t id ) {
return ::fmt::format("{}", id);
}
}
namespace {
size_t process( uf::Object& object, pod::Graph& graph, pod::Node& parent ) {
auto& storage = uf::graph::getStorage( graph );
@ -23,7 +29,7 @@ namespace {
size_t meshID = graph.meshes.size();
size_t objectID = storage.entities.keys.size();
uf::stl::string keyName = graph.name + "[" + std::to_string(objectID) + "]";
uf::stl::string keyName = ::fmt::format("{}[{}]", graph.name, objectID);
auto& node = graph.nodes.emplace_back();
node.name = object.getName();
@ -34,12 +40,12 @@ namespace {
node.mesh = -1;
node.skin = -1;
storage.entities[std::to_string(objectID)] = &object;
storage.entities[::keyID(objectID)] = &object;
pod::Instance::Object instanceObject;
instanceObject.model = uf::transform::model( object.getComponent<pod::Transform<>>() );
instanceObject.previous = instanceObject.model;
storage.objects[std::to_string(objectID)] = instanceObject;
storage.objects[::keyID(objectID)] = instanceObject;
if ( object.hasComponent<uf::renderer::Graphic>() ) {
auto& graphic = object.getComponent<uf::renderer::Graphic>();
@ -51,7 +57,7 @@ namespace {
size_t textureID = graph.textures.size();
size_t texture2DID = graph.images.size();
uf::stl::string subName = keyName + "[" + std::to_string(sub++) + "]";
uf::stl::string subName = ::fmt::format("{}[{}]", keyName, sub++);
auto& material = storage.materials[graph.materials.emplace_back(subName)];
auto& texture = storage.textures[graph.textures.emplace_back(subName)];
auto& texture2D = storage.images[graph.images.emplace_back(subName)].handle;

View File

@ -210,7 +210,7 @@ namespace {
ext::json::reserve( json["buffers"], mesh.buffers.size() );
for ( auto i = 0; i < mesh.buffers.size(); ++i ) {
const uf::stl::string filename = settings.filename + ".buffer." + std::to_string(i) + "." + ( settings.compression == "none" ? "bin" : settings.compression );
const uf::stl::string filename = ::fmt::format("{}.buffer.{}.{}", settings.filename, i, settings.compression == "none" ? "bin" : settings.compression );
uf::io::write( filename, mesh.buffers[i] );
json["buffers"].emplace_back(uf::io::filename( filename ));
}
@ -292,14 +292,14 @@ uf::stl::string uf::graph::save( const pod::Graph& graph, const uf::stl::string&
auto& name = graph.meshes[i];
auto& mesh = /*graph.storage*/storage.meshes.map.at(name);
if ( !s.encodeBuffers ) {
s.filename = directory+"/mesh."+std::to_string(i)+".json";
s.filename = ::fmt::format("{}/mesh.{}.json", directory, i );
encode(mesh, s, graph).writeToFile(s.filename);
uf::Serializer json;
json["name"] = name;
json["filename"] = uf::io::filename(s.filename);
serializer["meshes"].emplace_back( json );
} else {
s.filename = directory+"/mesh."+std::to_string(i);
s.filename = ::fmt::format("{}/mesh.{}", directory, i );
auto json = encode(mesh, s, graph);
json["name"] = name;
serializer["meshes"].emplace_back(json);
@ -335,7 +335,7 @@ uf::stl::string uf::graph::save( const pod::Graph& graph, const uf::stl::string&
for ( size_t i = 0; i < graph.images.size(); ++i ) {
auto& name = graph.images[i];
auto& image = /*graph.storage*/storage.images.map.at(name).data;
uf::stl::string f = "image."+std::to_string(i)+".png";
uf::stl::string f = ::fmt::format("{}/image.{}.png", directory, i );
image.save(directory + "/" + f);
// export DC's .dtex
@ -343,7 +343,7 @@ uf::stl::string uf::graph::save( const pod::Graph& graph, const uf::stl::string&
// to-do: properly scale per my script
auto converted = image.scale( {32, 32}, "nearest" );
auto dtex = ext::texconv::convert( converted );
ext::texconv::save( dtex, directory + "/image."+std::to_string(i) );
ext::texconv::save( dtex, ::fmt::format("{}/image.{}", directory, i ) );
#endif
uf::Serializer json;
@ -407,9 +407,9 @@ uf::stl::string uf::graph::save( const pod::Graph& graph, const uf::stl::string&
if ( !settings.combined ) {
for ( auto i = 0; i < graph.animations.size(); ++i ) {
auto& name = graph.animations[i];
uf::stl::string f = "animation."+std::to_string(i)+".json";
uf::stl::string f =::fmt::format("animation.{}.json", i);
auto& animation = /*graph.storage*/storage.animations.map.at(name);
encode(animation, settings, graph).writeToFile(directory+"/"+f);
encode(animation, settings, graph).writeToFile(::fmt::format("{}/{}", directory, f));
serializer["animations"].emplace_back(f);
}
} else {

View File

@ -30,6 +30,9 @@
// to-do: fix LOD1+ breaking
namespace {
uf::stl::string keyedID( size_t id ) {
return ::fmt::format("{}", id);
}
size_t allocateObjectID( pod::Graph::Storage& storage ) {
return storage.entities.keys.size();
}
@ -812,7 +815,7 @@ void uf::graph::process( pod::Graph& graph ) {
for ( auto& name : graph.primitives ) {
auto& primitives = storage.primitives[name];
for ( auto& primitive : primitives ) {
filenames[primitive.instance.auxID] = uf::string::replace(UF_GRAPH_DEFAULT_LIGHTMAP, "%i", std::to_string(primitive.instance.auxID));
filenames[primitive.instance.auxID] = uf::string::replace(UF_GRAPH_DEFAULT_LIGHTMAP, "%i", ::keyedID(primitive.instance.auxID));
lightmapCount = std::max( lightmapCount, primitive.instance.auxID + 1 );
}
@ -1215,19 +1218,19 @@ void uf::graph::process( pod::Graph& graph, int32_t index, uf::Object& parent )
// convert metadata["valve"] into internal values:
auto& metadataValve = node.metadata["valve"];
if ( ext::json::isObject( metadataValve ) ) {
// bind door script
if ( ext::json::isObject( metadataValve["door"] ) ) {
node.metadata["door"] = metadataValve["door"];
loadJson["imports"].emplace_back("ent://door.json");
}
// bind io connectivity
if ( ext::json::isArray( metadataValve["connections"] ) || metadataValve["targetname"].is<uf::stl::string>() ) {
node.metadata["connections"] = metadataValve["connections"];
loadJson["assets"].emplace_back("ent://scripts/io.lua");
}
// assume all funcs are to have a physics body
if ( node.name.starts_with("func_") ) {
// bind door script
if ( ext::json::isObject( metadataValve["door"] ) ) {
node.metadata["door"] = metadataValve["door"];
loadJson["imports"].emplace_back("ent://door.json");
}
// assume all other funcs are to have a physics body
else if ( node.name.starts_with("func_") ) {
if ( ext::json::isNull( node.metadata["physics"] ) ) {
//node.metadata["physics"]["type"] = "bounding box";
node.metadata["physics"]["type"] = "mesh";
@ -1383,7 +1386,7 @@ void uf::graph::process( pod::Graph& graph, int32_t index, uf::Object& parent )
if ( 0 <= node.mesh && node.mesh < graph.meshes.size() ) {
{
node.object = ::allocateObjectID( storage );
auto objectKeyName = std::to_string( node.object );
auto objectKeyName = ::keyedID( node.object );
storage.entities[objectKeyName] = &entity;
storage.objects[objectKeyName] = pod::Instance::Object{
@ -1612,7 +1615,7 @@ bool uf::graph::tick( pod::Graph::Storage& storage ) {
#if UF_USE_VULKAN
if ( commands && !grouped.empty() ) {
auto objectKeyName = std::to_string(grouped.front().objectID);
auto objectKeyName = ::keyedID(grouped.front().objectID);
if ( storage.entities.map.count(objectKeyName) > 0 ) {
auto& entity = *storage.entities.map[objectKeyName];
if ( entity.hasComponent<uf::renderer::Graphic>() ) {
@ -2254,7 +2257,7 @@ void uf::graph::reload( pod::Graph& graph, pod::Node& node ) {
bool graphicOwner = graphMetadataJson["renderer"]["render"].as<bool>();
if ( graphicOwner ) {
auto objectKeyName = std::to_string(storage.instances.map[graph.primitives[node.mesh]].front().objectID);
auto objectKeyName = ::keyedID(storage.instances.map[graph.primitives[node.mesh]].front().objectID);
graphicOwner = storage.entities[objectKeyName] == &entity;
}
// update graphic

View File

@ -328,11 +328,19 @@ void uf::ObjectBehavior::tick( uf::Object& self ) {
else unprocessed.emplace_back(q);
}
for ( auto& q : executeQueue ) {
if ( q.type == 1 ) {
this->callHook( q.name, q.userdata );
if ( q.hash ) {
if ( q.type == 1 ) {
this->callHook( q.hash, q.userdata );
}
else if ( q.type == -1 ) this->callHook( q.hash, q.json );
else this->callHook( q.hash );
} else {
if ( q.type == 1 ) {
this->callHook( q.name, q.userdata );
}
else if ( q.type == -1 ) this->callHook( q.name, q.json );
else this->callHook( q.name );
}
else if ( q.type == -1 ) this->callHook( q.name, q.json );
else this->callHook( q.name );
}
queue = std::move(unprocessed);
}

View File

@ -65,110 +65,30 @@ void uf::Object::queueDeletion() {
this->callHook("entity:Destroy.%UID%");
}
uf::Hooks::return_t uf::Object::lazyCallHook( const uf::stl::string& name ) {
if ( uf::Object::deferLazyCalls ) {
this->queueHook( name, 0.0f );
return {};
}
return this->callHook( name );
}
uf::Hooks::return_t uf::Object::lazyCallHook( const uf::stl::string& name, const pod::Hook::userdata_t& payload ) {
if ( uf::Object::deferLazyCalls ) {
this->queueHook( name, payload, 0.0f );
return {};
}
return this->callHook( name, payload );
}
void uf::Object::queueHook( const uf::stl::string& name, float timeout ) {
auto& metadata = this->getComponent<uf::ObjectBehavior::Metadata>();
auto& queue = metadata.hooks.queue.emplace_back(uf::ObjectBehavior::Metadata::Queued{
.name = name,
.timeout = uf::time::current + timeout,
.type = 0,
});
}
void uf::Object::queueHook( const uf::stl::string& name, const ext::json::Value& payload, float timeout ) {
auto& metadata = this->getComponent<uf::ObjectBehavior::Metadata>();
auto& queue = metadata.hooks.queue.emplace_back(uf::ObjectBehavior::Metadata::Queued{
.name = name,
.timeout = uf::time::current + timeout,
.type = -1,
});
queue.json = payload;
}
/*
uf::hashed_string uf::Object::formatHookName( const uf::stl::string_view n, size_t uid, bool fetch ) {
uf::hashed_string uf::Object::formatHookName( const uf::stl::string& n, size_t uid, bool fetch ) {
if ( fetch ) {
uf::Object* object = (uf::Object*) uf::Entity::globalFindByUid( uid );
auto* object = (uf::Object*) uf::Entity::globalFindByUid( uid );
if ( object ) return object->formatHookName( n );
}
size_t uidPos = n.find("%UID%");
if ( uidPos == uf::stl::string_view::npos ) {
return n;
}
size_t hash = {};
uf::hash( hash, n );
if ( n.ends_with("%UID%") ) uf::hash( hash, uid );
uf::stl::string_view base = n.substr(0, uidPos);
uf::stl::string_view suffix = n.substr(uidPos + 5);
size_t seed = uf::hashed_string( base );
uf::hash( seed, uid );
if ( !suffix.empty() ) {
uf::hash( seed, suffix );
}
return seed;
return hash;
}
uf::hashed_string uf::Object::formatHookName( const uf::stl::string_view n ) {
if ( n.find("%UID%") == uf::stl::string_view::npos && n.find("%P-UID%") == uf::stl::string_view::npos ) {
return n;
}
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;
uf::stl::string name(n);
name = uf::string::replace(name, "%UID%", std::to_string(uid));
name = uf::string::replace(name, "%P-UID%", std::to_string(parent));
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 );
return name;
}
*/
uf::stl::string uf::Object::formatHookName( const uf::stl::string& n, size_t uid, bool fetch ) {
if ( fetch ) {
uf::Object* object = (uf::Object*) uf::Entity::globalFindByUid( uid );
if ( object ) return object->formatHookName( n );
}
uf::stl::unordered_map<uf::stl::string, uf::stl::string> formats = {
{"%UID%", std::to_string(uid)},
};
uf::stl::string name = n;
for ( auto& pair : formats ) {
name = uf::string::replace( name, pair.first, pair.second );
}
return name;
}
uf::stl::string uf::Object::formatHookName( const uf::stl::string& n ) {
size_t uid = this->getUid();
size_t parent = uid;
if ( this->hasParent() ) {
parent = this->getParent().getUid();
}
uf::stl::unordered_map<uf::stl::string, uf::stl::string> formats = {
{"%UID%", std::to_string(uid)},
{"%P-UID%", std::to_string(parent)},
};
uf::stl::string name = n;
for ( auto& pair : formats ) {
name = uf::string::replace( name, pair.first, pair.second );
}
return name;
return hash;
}
bool uf::Object::load( const uf::stl::string& f, bool inheritRoot ) {

View File

@ -175,14 +175,8 @@ uf::Scene& uf::scene::loadScene( const uf::stl::string& name, const uf::stl::str
uf::Scene* scene = uf::instantiator::objects->has( name ) ? (uf::Scene*) &uf::instantiator::instantiate( name ) : new uf::Scene;
uf::scene::scenes.emplace_back( scene );
#if UF_USE_FMT
uf::stl::string filename = _filename;
if ( _filename == "" ) {
filename = ::fmt::format("/{}/scene.json", uf::string::lowercase(name));
}
#else
const uf::stl::string filename = _filename != "" ? _filename : (uf::stl::string("/") + uf::string::lowercase(name) + "/scene.json");
#endif
if ( _filename == "" ) filename = ::fmt::format("/{}/scene.json", uf::string::lowercase(name));
scene->load(filename);
auto& metadata = scene->getComponent<uf::SceneBehavior::Metadata>();

View File

@ -366,17 +366,9 @@ void ext::gltf::load( pod::Graph& graph, const uf::stl::string& filename, const
const tinygltf::Buffer& buffer = model.buffers[view.buffer];
const void* dataPtr = &buffer.data[accessor.byteOffset + view.byteOffset];
#if UF_MATRIX_ALIGNED
skin.inverseBindMatrices.resize(accessor.count);
const float* buf = static_cast<const float*>(dataPtr);
for ( size_t i = 0; i < accessor.count; ++i ) {
memcpy( &skin.inverseBindMatrices[i], (const void*) &buf[i*16], sizeof(float) * 16 );
}
#else
skin.inverseBindMatrices.reserve(accessor.count);
const pod::Matrix4f* buf = static_cast<const pod::Matrix4f*>(dataPtr);
for ( size_t i = 0; i < accessor.count; ++i ) skin.inverseBindMatrices.emplace_back( buf[i] );
#endif
}
skin.joints.reserve( s.joints.size() );

View File

@ -155,7 +155,6 @@ namespace binds {
}
namespace io {
void print( sol::variadic_args va ) {
#if UF_USE_FMT
size_t count = va.size();
for ( auto value : va ) {
uf::stl::string str = ext::lua::state["tostring"]( value );
@ -164,16 +163,6 @@ namespace binds {
}
::fmt::print("\n");
std::cout.flush();
#else
size_t count = va.size();
for ( auto value : va ) {
uf::stl::string str = ext::lua::state["tostring"]( value );
std::cout << str;
if ( --count != 0 ) std::cout << "\t";
}
std::cout <<"\n";
std::cout.flush();
#endif
};
}
namespace math {

View File

@ -41,15 +41,10 @@ namespace binds {
}
*/
/*
size_t formatHookName(uf::Object& self, const uf::stl::string n ){
uf::hashed_string formatHookName(uf::Object& self, const uf::stl::string n ){
return self.formatHookName(n);
}
*/
uf::stl::string formatHookName(uf::Object& self, const uf::stl::string n ){
return self.formatHookName(n);
}
/*
sol::object getComponentFromEnum( uf::Object& self, binds::enums::Components type ) {
#define UF_LUA_RETRIEVE_COMPONENT_FROM_ENUM( E, T )\

View File

@ -97,7 +97,7 @@ uf::stl::string ext::al::getError( ALCenum error ) {
case AL_INVALID_OPERATION: return "AL_INVALID_OPERATION"; // the requested operation is not valid
case AL_OUT_OF_MEMORY: return "AL_OUT_OF_MEMORY"; // the requested operation resulted in OpenAL running out ofmemory
}
return "AL_UNKNOWN(" + std::to_string(error) + ")";
return ::fmt::format("AL_UNKNOWN({})", error);
}
uf::audio::Metadata* ext::al::create( const uf::stl::string& filename, bool streamed, uint8_t buffers ) {
#if UF_MEMORYPOOL_INVALID_MALLOC

View File

@ -202,7 +202,7 @@ bool ext::texconv::convert( const pod::TextureOptions& opts ) {
int padding = expectedSize - ( (int) after - (int) before );
if ( padding > 0 ){
writeZeroes( out, padding );
UF_MSG_INFO( "Added {} padding bytes", std::to_string( padding ) );
UF_MSG_INFO( "Added {} padding bytes", padding );
}
out.close();
UF_MSG_INFO( "Wrote texture {}", opts.output );

View File

@ -79,7 +79,7 @@ ext::vulkan::userdata_t ext::vulkan::jsonToUserdata( const ext::json::Value& pay
}
if ( ext::json::isArray(value) ) {
ext::json::forEach(value, [&]( size_t i, const ext::json::Value& element ){
variableName.emplace_back("["+std::to_string(i)+"]");
variableName.emplace_back(::fmt::format("[{}]", i));
parse(element);
});
#if UF_SHADER_TRACK_NAMES
@ -255,7 +255,7 @@ ext::vulkan::userdata_t ext::vulkan::jsonToUserdata( const ext::json::Value& pay
else if ( ext::json::isArray(input) ) {
ext::json::forEach( input, [&]( size_t i, const ext::json::Value& value){
#if UF_SHADER_TRACK_NAMES
variableName.emplace_back("["+std::to_string(i)+"]");
variableName.emplace_back(::fmt::format("[{}]", i));
SKIP_ADD = true;
#endif
parseDefinition(input[i], definition);
@ -366,9 +366,8 @@ void ext::vulkan::Shader::initialize( ext::vulkan::Device& device, const uf::stl
if ( name == "" ) name = comp.get_name(type.parent_type);
if ( name == "" ) name = comp.get_fallback_name(type_id);
if ( type.vecsize > 1 ) {
name = "<"+name+">";
if ( type.columns > 1 ) name = "Matrix"+std::to_string(type.vecsize)+"x"+std::to_string(type.columns)+name;
else name = "Vector"+std::to_string(type.vecsize)+name;
if ( type.columns > 1 ) name = ::fmt::format( "Matrix{}x{}<{}>", type.vecsize, type.columns, name );
else name = ::fmt::format("Vector{}<{}>", type.vecsize, name )
}
{
ext::json::Value source = value;
@ -385,7 +384,7 @@ void ext::vulkan::Shader::initialize( ext::vulkan::Device& device, const uf::stl
for ( size_t i = 0; i < arraySize; ++i ) {
value.emplace_back(source);
}
name += "[" + std::to_string(arraySize) + "]";
name += ::fmt::format("[{}]", arraySize);
size *= arraySize;
}
}
@ -465,7 +464,7 @@ void ext::vulkan::Shader::initialize( ext::vulkan::Device& device, const uf::stl
case spv::Dim::DimBuffer: tname = "Buffer"; break;
case spv::Dim::DimSubpassData: tname = "SubpassData"; break;
}
uf::stl::string key = std::to_string(binding);
uf::stl::string key = ::fmt::format("{}", binding);
#if UF_SHADER_PARSE_AS_JSON
metadata.json["definitions"]["textures"][key]["name"] = name;
metadata.json["definitions"]["textures"][key]["index"] = index;

View File

@ -322,7 +322,7 @@ namespace {
CASE_KEY_RETURN('9', "Num9");
CASE_KEY_RETURN('0', "Num0");
}
return std::to_string((int) key);
return ::fmt::format("{}", key);
}
uf::stl::string GetKeyName( WPARAM key, LPARAM flags = 0 ) {
return uf::string::uppercase( _GetKeyName( key, flags ) );

View File

@ -51,11 +51,7 @@ uf::stl::string uf::checkpoint::traverse( pod::Checkpoint* checkpoint ) {
case pod::Checkpoint::BEGIN: type = "BEGIN"; break;
case pod::Checkpoint::END: type = "END"; break;
}
#if UF_USE_FMT
res.emplace( res.begin(), ::fmt::format("[{}] [{}]: {}", type, checkpoint->info, checkpoint->name) );
#else
res.emplace( res.begin(), "[" + type + "] [" + checkpoint->info + "]: " + checkpoint->name );
#endif
checkpoint = checkpoint->previous;
}

View File

@ -55,14 +55,12 @@ void uf::console::initialize() {
// this could probably be its own function
uf::stl::string s_result = "";
#if UF_USE_FMT
for ( auto i = 0; i < results.size(); ++i ) {
auto& res = results[i];
if ( res.is<uf::stl::string>() ) s_result += ::fmt::format("\n[{}] => {}", i, res.as<uf::stl::string>());
else if ( res.is<ext::json::Value>() ) s_result += ::fmt::format("\n[{}] => {}", i, ext::json::encode( res.as<ext::json::Value>() ));
else s_result += ::fmt::format("\n[{}] => Userdata: {}", i, (void*) res);
}
#endif
return "Hook executed: " + match[1] + s_result;
});
@ -102,11 +100,7 @@ void uf::console::initialize() {
};
for ( uf::Scene* scene : uf::scene::scenes ) {
if ( !scene ) continue;
#if UF_USE_FMT
res += ::fmt::format("Scene: {}: {}\n", scene->getName(), scene->getUid());
#else
res += "Scene: " + scene->getName() + ": " + std::to_string(scene->getUid()) + "\n";
#endif
scene->process(filter, 1);
}

View File

@ -15,17 +15,9 @@ void uf::io::exception( const uf::stl::string& exception ) {
}
*/
uf::stl::string uf::io::log( const uf::stl::string& category, const uf::stl::string& file, const uf::stl::string& function, size_t line, const uf::stl::string& message ) {
#if UF_USE_FMT
auto string = ::fmt::format("[{}] [{}:{}@{}]: {}", category, file, function, line, message);
::fmt::print("{}\n", string);
uf::iostream.pushHistory(string);
#else
std::stringstream ss;
ss << "[" << category << "] [" << file << ":" << function << "@" << line << "]: " << message << "\n";
auto string = ss.str();
std::cout << string;
uf::iostream.pushHistory(string);
#endif
std::cout.flush();
uf::console::print( string );

View File

@ -85,7 +85,7 @@ char uf::IoStream::readChar(const bool& loop) {
auto ch = std::cin.get();
addCh(ch);
// ::info.input.history.push_back( std::to_string(ch) );
// ::info.input.history.push_back( ::fmt::format("{}", ch) );
return ch;
}
uf::stl::string uf::IoStream::readString(const bool& loop) {
@ -111,7 +111,7 @@ char uf::IoStream::writeChar( char ch ) {
if ( ch == '\n' ) std::cout << std::endl;
else std::cout << ch;
// ::info.input.history.push_back( std::to_string(ch) );
// ::info.input.history.push_back( ::fmt::format("{}", ch) );
return ch;
}
const uf::stl::string& uf::IoStream::writeString( const uf::stl::string& str ) {

View File

@ -264,7 +264,7 @@ bool uf::glyph::generateAtlas( const uf::stl::vector<pod::GlyphBox>& layout, con
// generate atlas
for ( const auto& g : layout ) {
auto key = uf::glyph::hashSettings( g.code, metadata );
auto hash = std::to_string( key );
auto hash = ::fmt::format( "{}", key );
auto& glyph = cache[key];
// already in atlas map
@ -304,7 +304,7 @@ void uf::glyph::generateMesh( const uf::stl::vector<pod::GlyphBox>& layout, cons
indices.reserve(layout.size() * 6);
for ( const auto& g : layout ) {
auto hash = std::to_string( uf::glyph::hashSettings(g.code, metadata) );
auto hash = ::fmt::format( "{}", uf::glyph::hashSettings(g.code, metadata) );
#if EXT_COLOR_FLOATS
auto& color = g.color;

View File

@ -107,7 +107,7 @@ endif
ifneq (,$(findstring simd,$(REQ_DEPS)))
ifeq (,$(findstring dreamcast,$(ARCH)))
FLAGS += -DUF_USE_SIMD -DUF_ALIGN_FOR_SIMD -DUF_MATRIX_ALIGNED
FLAGS += -DUF_USE_SIMD
endif
endif