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:
parent
0fdba55927
commit
f9d7cf2dc8
@ -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 = "" );
|
||||
|
||||
|
||||
@ -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{};
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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) {}
|
||||
|
||||
@ -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
|
||||
}
|
||||
@ -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 );
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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 );
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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 ) {
|
||||
|
||||
@ -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>();
|
||||
|
||||
@ -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() );
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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 )\
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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 );
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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 ) );
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
@ -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 );
|
||||
|
||||
@ -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 ) {
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user