diff --git a/bin/data/scenes/sourceengine/ss2_medsci1.json b/bin/data/scenes/sourceengine/ss2_medsci1.json index c963a955..5c86088e 100644 --- a/bin/data/scenes/sourceengine/ss2_medsci1.json +++ b/bin/data/scenes/sourceengine/ss2_medsci1.json @@ -4,9 +4,9 @@ // { "filename": "./models/ss2_medsci1.glb" } // { "filename": "./models/ss2_medsci1/graph.json" } // { "filename": "./models/ss2_medsci1_small.glb" } - // { "filename": "./models/ss2_medsci1_small/graph.json" } + { "filename": "./models/ss2_medsci1_small/graph.json" } // { "filename": "./models/ss2_medsci1_smallish.glb" } - { "filename": "./models/ss2_medsci1_smallish/graph.json" } + // { "filename": "./models/ss2_medsci1_smallish/graph.json" } ], "metadata": { "graph": { diff --git a/engine/inc/uf/engine/scene/behavior.h b/engine/inc/uf/engine/scene/behavior.h index d61f6c7b..65313279 100644 --- a/engine/inc/uf/engine/scene/behavior.h +++ b/engine/inc/uf/engine/scene/behavior.h @@ -1,5 +1,12 @@ #pragma once +namespace pod { + struct CachedCamera { + uf::Camera camera; + size_t lastFrame = 0; + }; +} + namespace uf { namespace SceneBehavior { UF_BEHAVIOR_DEFINE_TYPE(); @@ -8,19 +15,12 @@ namespace uf { UF_BEHAVIOR_DEFINE_METADATA( uf::stl::vector graph; bool invalidationQueued = false; - #if 0 - struct { - uf::Entity* controller = NULL; - void* renderMode = NULL; - } cached; - #else + // we could keep a cache of controllers for each rendermode, but we have to invalidate the cache every time the graph regenerates struct { uf::stl::unordered_map controllers; - uf::stl::unordered_map cameras; - uf::stl::unordered_map frameNumbers; + uf::stl::unordered_map cameras; } cache; - #endif struct { pod::Thread::Tasks serial; diff --git a/engine/inc/uf/ext/oal/buffer.h b/engine/inc/uf/ext/openal/buffer.h similarity index 100% rename from engine/inc/uf/ext/oal/buffer.h rename to engine/inc/uf/ext/openal/buffer.h diff --git a/engine/inc/uf/ext/oal/oal.h b/engine/inc/uf/ext/openal/openal.h similarity index 100% rename from engine/inc/uf/ext/oal/oal.h rename to engine/inc/uf/ext/openal/openal.h diff --git a/engine/inc/uf/ext/oal/source.h b/engine/inc/uf/ext/openal/source.h similarity index 100% rename from engine/inc/uf/ext/oal/source.h rename to engine/inc/uf/ext/openal/source.h diff --git a/engine/inc/uf/ext/zlib/zlib.h b/engine/inc/uf/ext/zlib/zlib.h index c6065b35..892e52bb 100644 --- a/engine/inc/uf/ext/zlib/zlib.h +++ b/engine/inc/uf/ext/zlib/zlib.h @@ -28,9 +28,26 @@ namespace ext { } */ - uf::stl::vector UF_API decompressFromFile( const uf::stl::string& ); - uf::stl::vector UF_API decompressFromFile( const uf::stl::string& filename, size_t start, size_t len ); - uf::stl::vector UF_API decompressFromFile( const uf::stl::string& filename, const uf::stl::vector& ranges ); + uf::stl::vector& UF_API decompressFromFile( uf::stl::vector&, const uf::stl::string& ); + uf::stl::vector& UF_API decompressFromFile( uf::stl::vector&, const uf::stl::string& filename, size_t start, size_t len ); + uf::stl::vector& UF_API decompressFromFile( uf::stl::vector&, const uf::stl::string& filename, const uf::stl::vector& ranges ); + + inline uf::stl::vector decompressFromFile( const uf::stl::string& filename ) { + uf::stl::vector buffer; + decompressFromFile( buffer, filename ); + return buffer; + } + inline uf::stl::vector decompressFromFile( const uf::stl::string& filename, size_t start, size_t len ) { + uf::stl::vector buffer; + decompressFromFile( buffer, filename, start, len ); + return buffer; + } + inline uf::stl::vector decompressFromFile( const uf::stl::string& filename, const uf::stl::vector& ranges ) { + uf::stl::vector buffer; + decompressFromFile( buffer, filename, ranges ); + return buffer; + } + size_t UF_API compressToFile( const uf::stl::string&, const void*, size_t ); } diff --git a/engine/inc/uf/utils/audio/audio.h b/engine/inc/uf/utils/audio/audio.h index ca00795f..33d8d3b1 100644 --- a/engine/inc/uf/utils/audio/audio.h +++ b/engine/inc/uf/utils/audio/audio.h @@ -3,7 +3,7 @@ #include #if UF_USE_OPENAL -#include +#include #else namespace ext { namespace al { diff --git a/engine/inc/uf/utils/audio/metadata.h b/engine/inc/uf/utils/audio/metadata.h index 255a77d8..7d7b0700 100644 --- a/engine/inc/uf/utils/audio/metadata.h +++ b/engine/inc/uf/utils/audio/metadata.h @@ -5,8 +5,8 @@ #include #include -#include -#include +#include +#include #include // shoved here because dependencies diff --git a/engine/inc/uf/utils/io/file.h b/engine/inc/uf/utils/io/file.h index 65d5737a..0883d804 100644 --- a/engine/inc/uf/utils/io/file.h +++ b/engine/inc/uf/utils/io/file.h @@ -25,10 +25,34 @@ namespace uf { uf::stl::string UF_API sanitize( const uf::stl::string&, const uf::stl::string& = "" ); size_t UF_API size( const uf::stl::string& ); - uf::stl::string UF_API readAsString( const uf::stl::string&, const uf::stl::string& = "" ); - uf::stl::vector UF_API readAsBuffer( const uf::stl::string&, const uf::stl::string& = "" ); - uf::stl::vector UF_API readAsBuffer( const uf::stl::string&, size_t start, size_t len, const uf::stl::string& = "" ); - uf::stl::vector UF_API readAsBuffer( const uf::stl::string&, const uf::stl::vector& ranges, const uf::stl::string& = "" ); + uf::stl::string& UF_API readAsString( uf::stl::string&, const uf::stl::string&, const uf::stl::string& = "" ); + + uf::stl::vector& UF_API readAsBuffer( uf::stl::vector&, const uf::stl::string&, const uf::stl::string& = "" ); + uf::stl::vector& UF_API readAsBuffer( uf::stl::vector&, const uf::stl::string&, size_t start, size_t len, const uf::stl::string& = "" ); + uf::stl::vector& UF_API readAsBuffer( uf::stl::vector&, const uf::stl::string&, const uf::stl::vector& ranges, const uf::stl::string& = "" ); + + // yuck! + // wrapper in case this gets called without feeding into a buffer directly to avoid additional memory allocations + inline uf::stl::string readAsString( const uf::stl::string& filename, const uf::stl::string& hash = "" ) { + uf::stl::string string; + readAsString( filename, hash ); + return string; + } + inline uf::stl::vector readAsBuffer( const uf::stl::string& _filename, const uf::stl::string& hash = "" ) { + uf::stl::vector buffer; + readAsBuffer( buffer, _filename, hash ); + return buffer; + } + inline uf::stl::vector readAsBuffer( const uf::stl::string& _filename, size_t start, size_t len, const uf::stl::string& hash = "" ) { + uf::stl::vector buffer; + readAsBuffer( buffer, _filename, start, len, hash ); + return buffer; + } + inline uf::stl::vector readAsBuffer( const uf::stl::string& _filename, const uf::stl::vector& ranges, const uf::stl::string& hash = "" ) { + uf::stl::vector buffer; + readAsBuffer( buffer, _filename, ranges, hash ); + return buffer; + } size_t UF_API write( const uf::stl::string& filename, const void*, size_t = SIZE_MAX ); template inline size_t write( const uf::stl::string& filename, const uf::stl::vector& buffer, size_t size = SIZE_MAX ) { @@ -38,9 +62,25 @@ namespace uf { return write( filename, string.c_str(), std::min( string.size(), size ) ); } - uf::stl::vector UF_API decompress( const uf::stl::string& ); - uf::stl::vector UF_API decompress( const uf::stl::string&, size_t, size_t ); - uf::stl::vector UF_API decompress( const uf::stl::string&, const uf::stl::vector& ); + uf::stl::vector& UF_API decompress( uf::stl::vector&, const uf::stl::string& ); + uf::stl::vector& UF_API decompress( uf::stl::vector&, const uf::stl::string&, size_t, size_t ); + uf::stl::vector& UF_API decompress( uf::stl::vector&, const uf::stl::string&, const uf::stl::vector& ); + + inline uf::stl::vector decompress( const uf::stl::string& filename ) { + uf::stl::vector buffer; + decompress( buffer, filename ); + return buffer; + } + inline uf::stl::vector decompress( const uf::stl::string& filename, size_t start, size_t len ) { + uf::stl::vector buffer; + decompress( buffer, filename, start, len ); + return buffer; + } + inline uf::stl::vector decompress( const uf::stl::string& filename, const uf::stl::vector& ranges ) { + uf::stl::vector buffer; + decompress( buffer, filename, ranges ); + return buffer; + } size_t UF_API compress( const uf::stl::string&, const void*, size_t = SIZE_MAX ); template inline size_t compress( const uf::stl::string& filename, const uf::stl::vector& buffer, size_t size = SIZE_MAX ) { diff --git a/engine/inc/uf/utils/thread/thread.h b/engine/inc/uf/utils/thread/thread.h index 3b7cd1a1..e8b24cfb 100644 --- a/engine/inc/uf/utils/thread/thread.h +++ b/engine/inc/uf/utils/thread/thread.h @@ -57,6 +57,7 @@ namespace pod { inline void add( const pod::Thread::function_t& fun ) { container.emplace(fun); } inline void emplace( const pod::Thread::function_t& fun ) { container.emplace(fun); } inline void queue( const pod::Thread::function_t& fun ) { container.emplace(fun); } + inline bool empty() { return container.empty(); } inline void clear() { container = {}; } }; }; diff --git a/engine/src/engine/behavior/behavior.cpp b/engine/src/engine/behavior/behavior.cpp index 8a2751ff..3a692453 100644 --- a/engine/src/engine/behavior/behavior.cpp +++ b/engine/src/engine/behavior/behavior.cpp @@ -98,6 +98,7 @@ void uf::Behaviors::tick() { // if ( !m_graph.tickMT.empty() ) uf::thread::queue(m_graph.tickMT); if ( m_graph.tick.serial.empty() && m_graph.tick.parallel.empty() ) return; #if UF_GRAPH_PRINT_TRACE +#if 0 UF_TIMER_MULTITRACE_START("Starting tick: {}", uf::string::toString( self )); // for ( auto& behavior : m_behaviors ) if ( behavior.traits.ticks ) UF_MSG_DEBUG( behavior.type.name() ); for ( auto& fun : m_graph.tick.serial ) { @@ -109,6 +110,17 @@ void uf::Behaviors::tick() { UF_TIMER_MULTITRACE(""); } UF_TIMER_MULTITRACE_END("Finished tick: {}", uf::string::toString( self )) +#else + UF_TIMER_MULTITRACE_START("Starting tick: {}", uf::string::toString( self )); + for ( auto& behavior : m_behaviors ) { + if ( behavior.traits.ticks ) { + auto& fun = behavior.tick; + UF_MSG_DEBUG("{}: {}", uf::string::toString(self), behavior.type.name().str() ); + fun(self); + } + } + UF_TIMER_MULTITRACE_END("Finished tick: {}", uf::string::toString( self )) +#endif #else UF_BEHAVIOR_POLYFILL(tick.serial) UF_BEHAVIOR_POLYFILL(tick.parallel) diff --git a/engine/src/engine/ext/ext.cpp b/engine/src/engine/ext/ext.cpp index 69be0bc0..de9d3c6c 100644 --- a/engine/src/engine/ext/ext.cpp +++ b/engine/src/engine/ext/ext.cpp @@ -37,7 +37,7 @@ #include #include -#include +#include #include #include #include diff --git a/engine/src/engine/graph/graph.cpp b/engine/src/engine/graph/graph.cpp index 76ba30cf..bfdf0f09 100644 --- a/engine/src/engine/graph/graph.cpp +++ b/engine/src/engine/graph/graph.cpp @@ -2199,7 +2199,7 @@ void uf::graph::reload( pod::Graph& graph, pod::Node& node ) { if ( ranges.count(attribute.buffer) <= 0 ) { \ mesh.buffers[attribute.buffer].clear();\ } else {\ - mesh.buffers[attribute.buffer] = uf::io::readAsBuffer( mesh.buffer_paths[attribute.buffer], ranges[attribute.buffer] );\ + uf::io::readAsBuffer( mesh.buffers[attribute.buffer], mesh.buffer_paths[attribute.buffer], ranges[attribute.buffer] );\ }\ } @@ -2224,7 +2224,7 @@ void uf::graph::reload( pod::Graph& graph, pod::Node& node ) { #define STREAM_MESH_DATA( N ) \ for ( auto& attribute : mesh.N.attributes ) {\ if ( !mesh.buffers[attribute.buffer].empty() || mesh.buffer_paths.empty() ) continue;\ - mesh.buffers[attribute.buffer] = uf::io::readAsBuffer( mesh.buffer_paths[attribute.buffer] );\ + uf::io::readAsBuffer( mesh.buffers[attribute.buffer], mesh.buffer_paths[attribute.buffer] );\ } STREAM_MESH_DATA( index ); @@ -2318,7 +2318,7 @@ void uf::graph::reload( pod::Graph& graph, pod::Node& node ) { #define LOAD_MESH_DATA( N ) \ for ( auto& attribute : mesh.N.attributes ) {\ if ( !mesh.buffers[attribute.buffer].empty() || mesh.buffer_paths.empty() ) continue;\ - mesh.buffers[attribute.buffer] = uf::io::readAsBuffer( mesh.buffer_paths[attribute.buffer] );\ + uf::io::readAsBuffer( mesh.buffers[attribute.buffer], mesh.buffer_paths[attribute.buffer] );\ } LOAD_MESH_DATA( index ); diff --git a/engine/src/engine/scene/scene.cpp b/engine/src/engine/scene/scene.cpp index b56ba30c..887e4286 100644 --- a/engine/src/engine/scene/scene.cpp +++ b/engine/src/engine/scene/scene.cpp @@ -18,9 +18,14 @@ uf::Scene::Scene() UF_BEHAVIOR_ENTITY_CPP_ATTACH(uf::Scene) #define UF_SCENE_GLOBAL_GRAPH 1 #define UF_TICK_SINGLETHREAD_OVERRIDE 0 #define UF_TICK_MULTITHREAD_OVERRIDE 0 -#define UF_TICK_FROM_TASKS 1 #define UF_SCENE_INVALIDATE_IMMEDIATE 1 +#if UF_ENV_DREAMCAST + #define UF_TICK_FROM_TASKS 0 +#else + #define UF_TICK_FROM_TASKS 1 +#endif + #if UF_SCENE_GLOBAL_GRAPH namespace { uf::SceneBehavior::Metadata metadata; @@ -31,88 +36,67 @@ uf::Entity& uf::Scene::getController() { #if !UF_SCENE_GLOBAL_GRAPH auto& metadata = this->getComponent(); #endif - auto currentRenderMode = uf::renderer::getCurrentRenderMode(); - uf::Entity* controller = NULL; - if ( currentRenderMode ) { - auto& renderMode = *currentRenderMode; - auto& name = renderMode.getName(); - if ( metadata.cache.controllers.count(name) > 0 ) { - controller = metadata.cache.controllers[name]; - if ( controller->isValid() ) return *controller; - } + auto& cache = metadata.cache.controllers; - auto split = uf::string::split( name, ":" ); - if ( split.front() == "RT" ) { - controller = this->findByUid( std::stoi( split.back() ) ); - if ( controller->isValid() ) return *(metadata.cache.controllers[name] = controller); + auto currentRenderMode = uf::renderer::getCurrentRenderMode(); + if ( currentRenderMode ) { + auto& name = currentRenderMode->getName(); + if ( auto it = cache.find(name); it != cache.end() && it->second->isValid() ) { + return *(it->second); + } + if ( name.rfind("RT:", 0) == 0 ) { + auto uid = std::stoi(name.substr(3)); + if ( auto controller = this->findByUid(uid); controller && controller->isValid() ) { + return *(cache[name] = controller); + } } } - if ( metadata.cache.controllers.count("") > 0 ) { - controller = metadata.cache.controllers[""]; - if ( controller->isValid() ) return *controller; + if (auto it = cache.find(""); it != cache.end() && it->second->isValid()) { + return *(it->second); } - controller = this->findByName("Player"); - return *(metadata.cache.controllers[""] = controller ? controller : this); + + auto controller = this->findByName("Player"); + return *(cache[""] = (controller ? controller : this)); } const uf::Entity& uf::Scene::getController() const { uf::Scene& scene = *const_cast(this); return scene.getController(); } -uf::Camera& uf::Scene::getCamera( uf::Entity& controller ) { - auto currentRenderMode = uf::renderer::getCurrentRenderMode(); - if ( currentRenderMode && currentRenderMode->getName() != "" ) return controller.getComponent(); +uf::Camera& uf::Scene::getCamera(uf::Entity& controller) { + // ??? + if ( auto currentRenderMode = uf::renderer::getCurrentRenderMode(); currentRenderMode && !currentRenderMode->getName().empty() ) { + return controller.getComponent(); + } + #if !UF_SCENE_GLOBAL_GRAPH auto& metadata = this->getComponent(); #endif - auto& cachedCamera = metadata.cache.cameras[controller.getUid()]; + auto uid = controller.getUid(); + auto& cachedCamera = metadata.cache.cameras[uid].camera; + auto& lastFrame = metadata.cache.cameras[uid].lastFrame; - if ( metadata.cache.frameNumbers[controller.getUid()] != uf::time::frame ) { - metadata.cache.frameNumbers[controller.getUid()] = uf::time::frame; + if ( lastFrame != uf::time::frame ) { + auto& sourceCamera = controller.getComponent(); + cachedCamera.setTransform(uf::transform::flatten(sourceCamera.getTransform())); - auto& camera = controller.getComponent(); - // cachedCamera = camera; - cachedCamera.setTransform( uf::transform::flatten( camera.getTransform() ) ); for ( auto i = 0; i < uf::camera::maxViews; ++i ) { - cachedCamera.setView( camera.getView(i), i ); - cachedCamera.setProjection( camera.getProjection(i), i ); + cachedCamera.setView(sourceCamera.getView(i), i); + cachedCamera.setProjection(sourceCamera.getProjection(i), i); } cachedCamera.update(true); - -// UF_MSG_DEBUG("New frame time: {}: {} ({})", uf::time::frame, controller.getName(), controller.getUid()); + lastFrame = uf::time::frame; } - return cachedCamera; } +// ick const uf::Camera& uf::Scene::getCamera( const uf::Entity& controller ) const { - auto currentRenderMode = uf::renderer::getCurrentRenderMode(); - if ( currentRenderMode && currentRenderMode->getName() != "" ) return controller.getComponent(); -#if !UF_SCENE_GLOBAL_GRAPH - auto& metadata = this->getComponent(); -#endif - auto& cachedCamera = metadata.cache.cameras[controller.getUid()]; - - if ( metadata.cache.frameNumbers[controller.getUid()] != uf::time::frame ) { - metadata.cache.frameNumbers[controller.getUid()] = uf::time::frame; - - auto& camera = controller.getComponent(); - // cachedCamera = camera; - cachedCamera.setTransform( uf::transform::flatten( camera.getTransform() ) ); - for ( auto i = 0; i < uf::camera::maxViews; ++i ) { - cachedCamera.setView( camera.getView(i), i ); - cachedCamera.setProjection( camera.getProjection(i), i ); - } - cachedCamera.update(true); - -// UF_MSG_DEBUG("New frame time: {}: {} ({})", uf::time::frame, controller.getName(), controller.getUid()); - } - - return cachedCamera; + uf::Scene& scene = const_cast(*this); + uf::Entity& entity = const_cast(controller); + return scene.getCamera( entity ); } - - void uf::Scene::invalidateGraph() { #if !UF_SCENE_GLOBAL_GRAPH auto& metadata = this->getComponent(); @@ -154,41 +138,17 @@ const uf::stl::vector& uf::Scene::getGraph() { #if UF_TICK_FROM_TASKS auto* self = (uf::Object*) entity; auto/*&*/ behaviorGraph = entity->getGraph(); - if ( uf::scene::printTaskCalls ) { - for ( auto& behavior : self->getBehaviors() ) { - if ( !behavior.traits.ticks ) continue; - auto name = behavior.type.name().str(); - #if UF_TICK_MULTITHREAD_OVERRIDE - if ( true ) - #elif UF_TICK_SINGLETHREAD_OVERRIDE - if ( false ) - #else - if ( behavior.traits.multithread ) - #endif - metadata.tasks.parallel.queue([=]{ - auto start = uf::time::time(); - behavior.tick(*self); - UF_MSG_DEBUG("[{}us] Parallel {} task exectued: {}: {}", uf::time::time() - start, name, self->getName(), self->getUid()); - }); else metadata.tasks.serial.queue([=]{ - auto start = uf::time::time(); - behavior.tick(*self); - UF_MSG_DEBUG("[{}us] Serial {} task exectued: {}: {}", uf::time::time() - start, name, self->getName(), self->getUid()); - }); - } - } else { - #if UF_TICK_MULTITHREAD_OVERRIDE - for ( auto fun : behaviorGraph.tick.serial ) metadata.tasks.parallel.queue([=]{ fun(*self); }); - for ( auto fun : behaviorGraph.tick.parallel ) metadata.tasks.parallel.queue([=]{ fun(*self); }); - #elif UF_TICK_SINGLETHREAD_OVERRIDE - for ( auto fun : behaviorGraph.tick.serial ) metadata.tasks.serial.queue([=]{ fun(*self); }); - for ( auto fun : behaviorGraph.tick.parallel ) metadata.tasks.serial.queue([=]{ fun(*self); }); - #else - for ( auto fun : behaviorGraph.tick.serial ) metadata.tasks.serial.queue([=]{ fun(*self); }); - for ( auto fun : behaviorGraph.tick.parallel ) metadata.tasks.parallel.queue([=]{ fun(*self); }); - #endif - - } + #if UF_TICK_MULTITHREAD_OVERRIDE + for ( auto fun : behaviorGraph.tick.serial ) metadata.tasks.parallel.queue([=]{ fun(*self); }); + for ( auto fun : behaviorGraph.tick.parallel ) metadata.tasks.parallel.queue([=]{ fun(*self); }); + #elif UF_TICK_SINGLETHREAD_OVERRIDE + for ( auto fun : behaviorGraph.tick.serial ) metadata.tasks.serial.queue([=]{ fun(*self); }); + for ( auto fun : behaviorGraph.tick.parallel ) metadata.tasks.serial.queue([=]{ fun(*self); }); + #else + for ( auto fun : behaviorGraph.tick.serial ) metadata.tasks.serial.queue([=]{ fun(*self); }); + for ( auto fun : behaviorGraph.tick.parallel ) metadata.tasks.parallel.queue([=]{ fun(*self); }); + #endif #endif }); @@ -226,11 +186,6 @@ uf::Scene& uf::scene::loadScene( const uf::stl::string& name, const uf::stl::str #endif scene->initialize(); -// uf::physics::initialize(); -// uf::graph::initialize(); -// uf::renderer::states::renderSkip = false; -// uf::renderer::states::frameSkip = 60; - return *scene; } uf::Scene& uf::scene::loadScene( const uf::stl::string& name, const uf::Serializer& data ) { @@ -246,26 +201,12 @@ uf::Scene& uf::scene::loadScene( const uf::stl::string& name, const uf::Serializ #endif scene->initialize(); -// uf::physics::initialize(); -// uf::graph::initialize(); -// uf::renderer::states::renderSkip = false; -// uf::renderer::states::frameSkip = 60; - return *scene; } void uf::scene::unloadScene() { -// uf::renderer::states::frameSkip = 60; - uf::Scene* current = uf::scene::scenes.back(); -// current->destroy(); current->queueDeletion(); -// uf::physics::terminate(); -// uf::graph::destroy(); -/* - auto graph = current->getGraph(true); - for ( auto entity : graph ) entity->destroy(); -*/ // destroy phyiscs state if ( current->hasComponent() ) { uf::graph::destroy( current->getComponent() ); @@ -282,50 +223,21 @@ void uf::scene::unloadScene() { auto& blitter = renderMode.getBlitter(); renderMode.execute = false; blitter.process = false; - /* - if ( uf::renderer::settings::experimental::registerRenderMode ) { - uf::renderer::removeRenderMode( &renderMode, false ); - } - */ } if ( entity->hasComponent() ) { auto& renderMode = entity->getComponent(); auto& blitter = renderMode.getBlitter(); renderMode.execute = false; blitter.process = false; - /* - if ( uf::renderer::settings::experimental::registerRenderMode ) { - uf::renderer::removeRenderMode( &renderMode, false ); - } - */ } } uf::renderer::states::rebuild = true; uf::renderer::states::resized = true; - - /* - if ( rebuilded ) { - // rebuild swapchain - if ( uf::renderer::hasRenderMode("Swapchain", true) ) { - auto& renderMode = uf::renderer::getRenderMode("Swapchain", true); - renderMode.execute = false; - renderMode.rerecord = true; - renderMode.synchronize(); - - renderMode.destroy(); - renderMode.initialize( uf::renderer::device ); - if ( uf::renderer::settings::invariant::individualPipelines ) renderMode.bindPipelines(); - renderMode.createCommandBuffers(); - renderMode.tick(); - } - } - */ uf::scene::scenes.pop_back(); } uf::Scene& uf::scene::getCurrentScene() { - //UF_ASSERT( !uf::scene::scenes.empty() ); if ( uf::scene::scenes.empty() ) { return uf::Entity::null.as(); } @@ -341,6 +253,7 @@ void uf::scene::invalidateGraphs() { void uf::scene::tick() { if ( scenes.empty() ) return; + #if !UF_SCENE_INVALIDATE_IMMEDIATE if ( metadata.invalidationQueued ) { metadata.invalidationQueued = false; @@ -350,29 +263,30 @@ void uf::scene::tick() { } #endif - if ( uf::scene::printTaskCalls ) UF_MSG_DEBUG("Scene tick start"); - auto& scene = uf::scene::getCurrentScene(); + auto/*&*/ graph = scene.getGraph(true); uf::physics::tick( scene ); #if !UF_SCENE_GLOBAL_GRAPH auto& metadata = scene.getComponent(); #endif - auto/*&*/ graph = scene.getGraph(true); -#if UF_TICK_FROM_TASKS - // copy because executing from the tasks erases them all - auto tasks = metadata.tasks; - auto workers = uf::thread::execute( tasks.parallel ); - uf::thread::execute( tasks.serial ); - uf::thread::wait( workers ); -#else - for ( auto entity : graph ) entity->tick(); +#if UF_TICK_FROM_TASKS + // only dispatch if we have tasks that requested parallelization + if ( !metadata.tasks.parallel.empty() ) { + // copy because executing from the tasks erases them all + auto tasks = metadata.tasks; + auto workers = uf::thread::execute( tasks.parallel ); + uf::thread::execute( tasks.serial ); + uf::thread::wait( workers ); + } else #endif + for ( auto entity : graph ) { + entity->tick(); + } uf::graph::tick( scene ); - if ( uf::scene::printTaskCalls ) UF_MSG_DEBUG("Scene tick end"); } void uf::scene::render() { if ( scenes.empty() ) return; diff --git a/engine/src/ext/audio/pcm.cpp b/engine/src/ext/audio/pcm.cpp index 843ac490..9e1ff7e5 100644 --- a/engine/src/ext/audio/pcm.cpp +++ b/engine/src/ext/audio/pcm.cpp @@ -2,7 +2,7 @@ #if UF_USE_WAV #if UF_USE_OPENAL -#include +#include #endif #include diff --git a/engine/src/ext/audio/vorbis.cpp b/engine/src/ext/audio/vorbis.cpp index c7a03160..52df0174 100644 --- a/engine/src/ext/audio/vorbis.cpp +++ b/engine/src/ext/audio/vorbis.cpp @@ -2,7 +2,7 @@ #if UF_USE_VORBIS #if UF_USE_OPENAL -#include +#include #endif #include diff --git a/engine/src/ext/audio/wav.cpp b/engine/src/ext/audio/wav.cpp index 73c3be7b..d255696b 100644 --- a/engine/src/ext/audio/wav.cpp +++ b/engine/src/ext/audio/wav.cpp @@ -2,7 +2,7 @@ #if UF_USE_WAV #if UF_USE_OPENAL -#include +#include #endif #include diff --git a/engine/src/ext/lua/lua.cpp b/engine/src/ext/lua/lua.cpp index 87df5396..1e84aa30 100644 --- a/engine/src/ext/lua/lua.cpp +++ b/engine/src/ext/lua/lua.cpp @@ -332,7 +332,7 @@ bool ext::lua::run( const pod::LuaScript& s, bool safe ) { return false; } } else { - state.script_file( s.file ); + state.script_file( s.file, s.env ); } // is string with lua } else { @@ -344,7 +344,7 @@ bool ext::lua::run( const pod::LuaScript& s, bool safe ) { return false; } } else { - state.script( s.file ); + state.script( s.file, s.env ); } } return true; diff --git a/engine/src/ext/oal/oal.cpp b/engine/src/ext/openal/openal.cpp similarity index 97% rename from engine/src/ext/oal/oal.cpp rename to engine/src/ext/openal/openal.cpp index eddbc70f..e05186c1 100644 --- a/engine/src/ext/oal/oal.cpp +++ b/engine/src/ext/openal/openal.cpp @@ -1,7 +1,7 @@ #include #if UF_USE_OPENAL -#include +#include #include #include diff --git a/engine/src/ext/vulkan/device.cpp b/engine/src/ext/vulkan/device.cpp index 367a5951..2c606917 100644 --- a/engine/src/ext/vulkan/device.cpp +++ b/engine/src/ext/vulkan/device.cpp @@ -1412,7 +1412,7 @@ void ext::vulkan::Device::initialize() { uf::stl::vector buffer; // read from cache on disk if ( uf::io::exists( uf::io::root + "/cache/vulkan/cache.bin" ) ) { - buffer = uf::io::readAsBuffer( uf::io::root + "/cache/vulkan/cache.bin" ); + uf::io::readAsBuffer( buffer, uf::io::root + "/cache/vulkan/cache.bin" ); pipelineCacheCreateInfo.initialDataSize = buffer.size(); pipelineCacheCreateInfo.pInitialData = buffer.data(); } diff --git a/engine/src/ext/zlib/zlib.cpp b/engine/src/ext/zlib/zlib.cpp index 77c321ba..df97da83 100644 --- a/engine/src/ext/zlib/zlib.cpp +++ b/engine/src/ext/zlib/zlib.cpp @@ -37,8 +37,7 @@ uf::stl::vector ext::zlib::decompress( const void* data, size_t size ) return buffer; } */ -uf::stl::vector ext::zlib::decompressFromFile( const uf::stl::string& filename ) { - uf::stl::vector buffer; +uf::stl::vector& ext::zlib::decompressFromFile( uf::stl::vector& buffer, const uf::stl::string& filename ) { gzFile in = gzopen( filename.c_str(), "rb" ); if ( !in ) { @@ -49,8 +48,6 @@ uf::stl::vector ext::zlib::decompressFromFile( const uf::stl::string& f size_t read{}; uint8_t gzBuffer[ext::zlib::bufferSize]; while ( (read = gzread( in, gzBuffer, ext::zlib::bufferSize ) ) > 0 ) { - // buffer.reserve(buffer.size() + read); - // buffer.insert( buffer.end(), &gzBuffer[0], &gzBuffer[ext::zlib::bufferSize] ); size_t s = buffer.size(); buffer.resize(s + read); memcpy( &buffer[s], &gzBuffer[0], read ); @@ -64,23 +61,12 @@ size_t ext::zlib::compressToFile( const uf::stl::string& filename, const void* d UF_MSG_ERROR("Zlib: failed to open file for write: {}", filename); return 0; } -#if 1 gzwrite( out, data, size ); -#else - size_t wrote{}; - while ( wrote < size ) { - size_t write = std::min( ext::zlib::bufferSize, size - wrote ); - gzwrite( out, data + wrote, write ); - wrote += write; - } -#endif gzclose( out ); return uf::io::size( filename ); } -uf::stl::vector ext::zlib::decompressFromFile( const uf::stl::string& filename, size_t start, size_t len ) { - uf::stl::vector buffer; - +uf::stl::vector& ext::zlib::decompressFromFile( uf::stl::vector& buffer, const uf::stl::string& filename, size_t start, size_t len ) { gzFile in = gzopen(filename.c_str(), "rb"); if ( !in ) { UF_MSG_ERROR("Zlib: failed to open file for read: {}", filename); @@ -109,11 +95,9 @@ uf::stl::vector ext::zlib::decompressFromFile( const uf::stl::string& f return buffer; } -uf::stl::vector ext::zlib::decompressFromFile( const uf::stl::string& filename, const uf::stl::vector& ranges ) { - uf::stl::vector result; - +uf::stl::vector& ext::zlib::decompressFromFile( uf::stl::vector& buffer, const uf::stl::string& filename, const uf::stl::vector& ranges ) { if ( ranges.empty() ) { - return result; + return buffer; } // ensure they're ordered @@ -123,33 +107,33 @@ uf::stl::vector ext::zlib::decompressFromFile( const uf::stl::string& f gzFile in = gzopen(filename.c_str(), "rb"); if ( !in ) { UF_MSG_ERROR("Zlib: failed to open file for read: {}", filename); - return result; + return buffer; } for ( const auto& r : sortedRanges ) { if ( gzseek(in, static_cast(r.start), SEEK_SET) == -1 ) { UF_MSG_ERROR("Zlib: failed to seek to position {} in file {}", r.start, filename); gzclose(in); - return uf::stl::vector(); // Return empty on failure + return buffer; } - size_t oldSize = result.size(); - result.resize(oldSize + r.len); + size_t oldSize = buffer.size(); + buffer.resize(oldSize + r.len); - int bytesRead = gzread(in, result.data() + oldSize, static_cast(r.len)); + int bytesRead = gzread(in, buffer.data() + oldSize, static_cast(r.len)); if ( bytesRead < 0 ) { int errnum; const char* errMsg = gzerror(in, &errnum); UF_MSG_ERROR("Zlib read error: {}", errMsg ? errMsg : "unknown error"); gzclose(in); - return uf::stl::vector(); // Return empty on error + return buffer; } // In case EOF ended early - result.resize(oldSize + static_cast(bytesRead)); + buffer.resize(oldSize + static_cast(bytesRead)); } gzclose(in); - return result; + return buffer; } #endif \ No newline at end of file diff --git a/engine/src/utils/audio/audio.cpp b/engine/src/utils/audio/audio.cpp index 32a7ff89..8c950b3f 100644 --- a/engine/src/utils/audio/audio.cpp +++ b/engine/src/utils/audio/audio.cpp @@ -2,7 +2,7 @@ #include #if UF_USE_OPENAL - #include + #include #endif #if UF_USE_OPENAL diff --git a/engine/src/utils/io/file.cpp b/engine/src/utils/io/file.cpp index 7c9783fc..c243b95a 100644 --- a/engine/src/utils/io/file.cpp +++ b/engine/src/utils/io/file.cpp @@ -93,13 +93,13 @@ uf::stl::string uf::io::sanitize( const uf::stl::string& str, const uf::stl::str return path; } // would just use readAsBuffer and convert to string, but that's double the memory cost -uf::stl::string uf::io::readAsString( const uf::stl::string& _filename, const uf::stl::string& hash ) { - uf::stl::string buffer; +uf::stl::string& uf::io::readAsString( uf::stl::string& buffer, const uf::stl::string& _filename, const uf::stl::string& hash ) { + buffer.clear(); uf::stl::string filename = sanitize(_filename); uf::stl::string extension = uf::io::extension( filename ); if ( extension == "gz" ) { auto decompressed = uf::io::decompress( filename ); - buffer.reserve(decompressed.size()); + buffer.resize(decompressed.size()); buffer.assign(decompressed.begin(), decompressed.end()); } else { std::ifstream is(filename, std::ios::binary | std::ios::in | std::ios::ate); @@ -107,46 +107,46 @@ uf::stl::string uf::io::readAsString( const uf::stl::string& _filename, const uf UF_MSG_ERROR("Error: Could not open file: {}", filename); return buffer; } - is.seekg(0, std::ios::end); buffer.reserve(is.tellg()); is.seekg(0, std::ios::beg); + is.seekg(0, std::ios::end); buffer.resize(is.tellg()); is.seekg(0, std::ios::beg); buffer.assign((std::istreambuf_iterator(is)), std::istreambuf_iterator()); } uf::stl::string expected = ""; if ( hash != "" && (expected = uf::string::sha256( buffer )) != hash ) { UF_MSG_ERROR("Error: Hash mismatch for file {}; expecting {}, got {}", filename, hash, expected); - return ""; + // should probably clear } return buffer; } -uf::stl::vector uf::io::readAsBuffer( const uf::stl::string& _filename, const uf::stl::string& hash ) { - uf::stl::vector buffer; +uf::stl::vector& uf::io::readAsBuffer( uf::stl::vector& buffer, const uf::stl::string& _filename, const uf::stl::string& hash ) { + buffer.clear(); uf::stl::string filename = sanitize(_filename); uf::stl::string extension = uf::io::extension( filename ); if ( extension == "gz" || extension == "lz4" ) { - buffer = uf::io::decompress( filename ); + uf::io::decompress( buffer, filename ); } else { std::ifstream is(filename, std::ios::binary | std::ios::in | std::ios::ate); if ( !is.is_open() ) { UF_MSG_ERROR("Error: Could not open file: {}", filename); return buffer; } - is.seekg(0, std::ios::end); buffer.reserve(is.tellg()); is.seekg(0, std::ios::beg); + is.seekg(0, std::ios::end); buffer.resize(is.tellg()); is.seekg(0, std::ios::beg); buffer.assign((std::istreambuf_iterator(is)), std::istreambuf_iterator()); } uf::stl::string expected = ""; if ( !hash.empty() && (expected = uf::string::sha256( buffer )) != hash ) { UF_MSG_ERROR("Error: Hash mismatch for file {}; expecting {}, got {}", filename, hash, expected); - return uf::stl::vector(); + // should probably clear } return buffer; } -uf::stl::vector uf::io::readAsBuffer( const uf::stl::string& _filename, size_t start, size_t len, const uf::stl::string& hash ) { - uf::stl::vector buffer; +uf::stl::vector& uf::io::readAsBuffer( uf::stl::vector& buffer, const uf::stl::string& _filename, size_t start, size_t len, const uf::stl::string& hash ) { + buffer.clear(); uf::stl::string filename = sanitize(_filename); uf::stl::string extension = uf::io::extension(filename); if ( extension == "gz" || extension == "lz4" ) { - buffer = uf::io::decompress( filename, start, len ); + uf::io::decompress( buffer, filename, start, len ); } else { std::ifstream is(filename, std::ios::binary); if (!is.is_open()) { @@ -162,18 +162,18 @@ uf::stl::vector uf::io::readAsBuffer( const uf::stl::string& _filename, uf::stl::string expected; if ( !hash.empty() && (expected = uf::string::sha256( buffer )) != hash ) { UF_MSG_ERROR("Error: Hash mismatch for file {}; expecting {}, got {}", filename, hash, expected); - return uf::stl::vector(); + // should probably clear } return buffer; } -uf::stl::vector uf::io::readAsBuffer( const uf::stl::string& _filename, const uf::stl::vector& ranges, const uf::stl::string& hash ) { - uf::stl::vector buffer; +uf::stl::vector& uf::io::readAsBuffer( uf::stl::vector& buffer, const uf::stl::string& _filename, const uf::stl::vector& ranges, const uf::stl::string& hash ) { + buffer.clear(); uf::stl::string filename = sanitize(_filename); uf::stl::string extension = uf::io::extension(filename); if ( extension == "gz" || extension == "lz4" ) { - buffer = uf::io::decompress( filename, ranges ); + uf::io::decompress( buffer, filename, ranges ); } else { std::ifstream is(filename, std::ios::binary); if (!is.is_open()) { @@ -186,7 +186,7 @@ uf::stl::vector uf::io::readAsBuffer( const uf::stl::string& _filename, for (const auto& r : ranges) { totalBytes += r.len; } - buffer.reserve(totalBytes); + buffer.resize(totalBytes); // Read each range for (const auto& r : ranges) { @@ -201,7 +201,7 @@ uf::stl::vector uf::io::readAsBuffer( const uf::stl::string& _filename, uf::stl::string expected; if ( !hash.empty() && (expected = uf::string::sha256( buffer )) != hash ) { UF_MSG_ERROR("Error: Hash mismatch for file {}; expecting {}, got {}", filename, hash, expected); - return uf::stl::vector(); + // should probably clear } return buffer; } @@ -218,26 +218,26 @@ size_t uf::io::write( const uf::stl::string& filename, const void* buffer, size_ } // indirection for different compression formats, currently only using zlib's gzFile shit -uf::stl::vector uf::io::decompress( const uf::stl::string& filename ) { +uf::stl::vector& uf::io::decompress( uf::stl::vector& buffer, const uf::stl::string& filename ) { uf::stl::string extension = uf::io::extension( filename ); - if ( extension == "gz" ) return ext::zlib::decompressFromFile( filename ); -// if ( extension == "lz4" ) return ext::lz4::decompressFromFile( filename ); + if ( extension == "gz" ) return ext::zlib::decompressFromFile( buffer, filename ); +// if ( extension == "lz4" ) return ext::lz4::decompressFromFile( buffer, filename ); UF_MSG_ERROR("unsupported compression format requested: {}", extension); - return {}; + return buffer; } -uf::stl::vector uf::io::decompress( const uf::stl::string& filename, size_t start, size_t len ) { +uf::stl::vector& uf::io::decompress( uf::stl::vector& buffer, const uf::stl::string& filename, size_t start, size_t len ) { uf::stl::string extension = uf::io::extension( filename ); - if ( extension == "gz" ) return ext::zlib::decompressFromFile( filename, start, len ); -// if ( extension == "lz4" ) return ext::lz4::decompressFromFile( filename, start, len ); + if ( extension == "gz" ) return ext::zlib::decompressFromFile( buffer, filename, start, len ); +// if ( extension == "lz4" ) return ext::lz4::decompressFromFile( buffer, filename, start, len ); UF_MSG_ERROR("unsupported compression format requested: {}", extension); - return {}; + return buffer; } -uf::stl::vector uf::io::decompress( const uf::stl::string& filename, const uf::stl::vector& ranges ) { +uf::stl::vector& uf::io::decompress( uf::stl::vector& buffer, const uf::stl::string& filename, const uf::stl::vector& ranges ) { uf::stl::string extension = uf::io::extension( filename ); - if ( extension == "gz" ) return ext::zlib::decompressFromFile( filename, ranges ); -// if ( extension == "lz4" ) return ext::lz4::decompressFromFile( filename, ranges ); + if ( extension == "gz" ) return ext::zlib::decompressFromFile( buffer, filename, ranges ); +// if ( extension == "lz4" ) return ext::lz4::decompressFromFile( buffer, filename, ranges ); UF_MSG_ERROR("unsupported compression format requested: {}", extension); - return {}; + return buffer; } size_t uf::io::compress( const uf::stl::string& filename, const void* buffer, size_t size ) { uf::stl::string extension = uf::io::extension( filename );