From de44c37a4416844ef606d145e1459385c6243a33 Mon Sep 17 00:00:00 2001 From: mrq Date: Mon, 28 Sep 2020 00:00:00 -0500 Subject: [PATCH] Commit for 2020.09.28.7z --- Makefile | 8 + engine/inc/uf/engine/behavior/behavior.h | 26 +- engine/inc/uf/engine/behavior/macros.inl | 45 +++ engine/inc/uf/engine/entity/behavior.h | 5 + engine/inc/uf/engine/entity/entity.h | 23 +- .../inc/uf/engine/instantiator/instantiator.h | 65 +-- .../uf/engine/instantiator/instantiator.inl | 176 ++++++++- engine/inc/uf/engine/instantiator/macros.inl | 61 +++ engine/inc/uf/engine/object/behavior.h | 5 + engine/inc/uf/engine/object/object.h | 19 +- engine/inc/uf/engine/scene/behavior.h | 5 + engine/inc/uf/engine/scene/scene.h | 19 +- engine/src/engine/behavior/behavior.cpp | 31 +- engine/src/engine/entity/behavior.cpp | 35 ++ engine/src/engine/entity/entity.cpp | 76 +--- .../src/engine/instantiator/instantiator.cpp | 66 ++-- engine/src/engine/object/behavior.cpp | 112 ++++++ engine/src/engine/object/object.cpp | 135 ++----- engine/src/engine/scene/behavior.cpp | 22 ++ engine/src/engine/scene/scene.cpp | 45 +-- ext/behaviors/base/base.cpp | 374 ++++++++++++++++++ .../behavior_test.h => behaviors/base/base.h} | 8 +- ext/behaviors/scene_raytracing/behavior.cpp | 210 ++++++++++ ext/behaviors/scene_raytracing/behavior.h | 17 + ext/scenes/map/behavior_test.cpp | 35 -- ext/scenes/map/scene.cpp | 10 - ext/scenes/raytrace/scene.cpp | 2 +- 27 files changed, 1254 insertions(+), 381 deletions(-) create mode 100644 engine/inc/uf/engine/behavior/macros.inl create mode 100644 engine/inc/uf/engine/entity/behavior.h create mode 100644 engine/inc/uf/engine/instantiator/macros.inl create mode 100644 engine/inc/uf/engine/object/behavior.h create mode 100644 engine/inc/uf/engine/scene/behavior.h create mode 100644 engine/src/engine/entity/behavior.cpp create mode 100644 engine/src/engine/object/behavior.cpp create mode 100644 engine/src/engine/scene/behavior.cpp create mode 100644 ext/behaviors/base/base.cpp rename ext/{scenes/map/behavior_test.h => behaviors/base/base.h} (58%) create mode 100644 ext/behaviors/scene_raytracing/behavior.cpp create mode 100644 ext/behaviors/scene_raytracing/behavior.h delete mode 100644 ext/scenes/map/behavior_test.cpp diff --git a/Makefile b/Makefile index 9a8e220b..bd1ab76f 100644 --- a/Makefile +++ b/Makefile @@ -110,3 +110,11 @@ clean-win64: @-rm -f $(OBJS_WIN64_DLL) @-rm -f $(OBJS_EXT_WIN64_DLL) @-rm -f $(OBJS_WIN64) + +clean-uf-win64: + @-rm $(EX_WIN64_DLL) + @-rm -f $(OBJS_WIN64_DLL) + +clean-ext-win64: + @-rm $(EXT_EX_WIN64_DLL) + @-rm -f $(OBJS_EXT_WIN64_DLL) \ No newline at end of file diff --git a/engine/inc/uf/engine/behavior/behavior.h b/engine/inc/uf/engine/behavior/behavior.h index 691bcf2b..65368bc8 100644 --- a/engine/inc/uf/engine/behavior/behavior.h +++ b/engine/inc/uf/engine/behavior/behavior.h @@ -6,13 +6,17 @@ #include #include +namespace uf { + class UF_API Entity; + class UF_API Object; +} namespace pod { struct UF_API Behavior { typedef std::type_index type_t; - typedef std::function function_t; + typedef std::function function_t; - type_t type; + type_t type = std::type_index(typeid(pod::Behavior)); function_t initialize; function_t tick; function_t render; @@ -31,6 +35,15 @@ namespace uf { void render(); void destroy(); + bool hasBehavior( const pod::Behavior& ); + template + bool hasBehavior() { + for ( auto& behavior : this->m_behaviors ) { + if ( behavior.type == getType() ) return true; + } + return false; + } + void addBehavior( const pod::Behavior& ); template @@ -60,11 +73,4 @@ namespace uf { } -#define UF_BEHAVIOR_ENTITY_HEADER( OBJ )\ - class UF_API OBJ ## Behavior {\ - public:\ - void initialize();\ - void tick();\ - void render();\ - void destroy();\ - }; +#include "macros.inl" \ No newline at end of file diff --git a/engine/inc/uf/engine/behavior/macros.inl b/engine/inc/uf/engine/behavior/macros.inl new file mode 100644 index 00000000..974a5fb1 --- /dev/null +++ b/engine/inc/uf/engine/behavior/macros.inl @@ -0,0 +1,45 @@ +#pragma once + +#define UF_BEHAVIOR_VIRTUAL 1 + +#define UF_BEHAVIOR_ENTITY_H( OBJ )\ + class UF_API OBJ ## Behavior {\ + public:\ + static void attach( uf::Entity& );\ + static void initialize( uf::Object& );\ + static void tick( uf::Object& );\ + static void render( uf::Object& );\ + static void destroy( uf::Object& );\ + }; +#if UF_BEHAVIOR_VIRTUAL + #define UF_BEHAVIOR_VIRTUAL_H() \ + virtual void initialize();\ + virtual void destroy();\ + virtual void tick();\ + virtual void render(); + + #define UF_BEHAVIOR_ENTITY_CPP_VIRTUAL_DEFINITIONS( OBJ )\ + void uf::OBJ::initialize(){ uf::Behaviors::initialize(); }\ + void uf::OBJ::tick(){ uf::Behaviors::tick(); }\ + void uf::OBJ::render(){ uf::Behaviors::render(); }\ + void uf::OBJ::destroy(){ uf::Behaviors::destroy(); } +#else + #define UF_BEHAVIOR_VIRTUAL_H() + #define UF_BEHAVIOR_ENTITY_CPP_VIRTUAL_DEFINITIONS( OBJ ) +#endif +#define UF_BEHAVIOR_ENTITY_CPP_BEGIN( OBJ )\ + uf::OBJ::OBJ() { \ + uf::OBJ ## Behavior::attach( *this );\ + }\ + UF_BEHAVIOR_ENTITY_CPP_VIRTUAL_DEFINITIONS( OBJ )\ + void uf::OBJ ## Behavior::attach( uf::Entity& self ) {\ + self.addBehavior(pod::Behavior{\ + .type = uf::Behaviors::getType(),\ + .initialize = uf::OBJ ## Behavior::initialize,\ + .tick = uf::OBJ ## Behavior::tick,\ + .render = uf::OBJ ## Behavior::render,\ + .destroy = uf::OBJ ## Behavior::destroy,\ + });\ + } +#define UF_BEHAVIOR_ENTITY_CPP_END( OBJ )\ + diff --git a/engine/inc/uf/engine/entity/behavior.h b/engine/inc/uf/engine/entity/behavior.h new file mode 100644 index 00000000..b4ef84d2 --- /dev/null +++ b/engine/inc/uf/engine/entity/behavior.h @@ -0,0 +1,5 @@ +#pragma once + +namespace uf { + UF_BEHAVIOR_ENTITY_H(Entity) +} \ No newline at end of file diff --git a/engine/inc/uf/engine/entity/entity.h b/engine/inc/uf/engine/entity/entity.h index 57d3cd25..c5cf0f8b 100644 --- a/engine/inc/uf/engine/entity/entity.h +++ b/engine/inc/uf/engine/entity/entity.h @@ -9,16 +9,8 @@ #include namespace uf { -/* - class UF_API EntityBehavior { - public: - void initialize(); - void destroy(); - void tick(); - void render(); - }; -*/ class UF_API Entity : public uf::Behaviors { + friend class EntityBehavior; public: typedef std::vector container_t; protected: @@ -30,9 +22,9 @@ namespace uf { std::size_t m_uid = 0; std::string m_name = "Entity"; + public: static uf::MemoryPool memoryPool; - Entity( bool = false ); virtual ~Entity(); // identifiers const std::string& getName() const; @@ -65,11 +57,10 @@ namespace uf { static uf::Entity* globalFindByUid( size_t id ); static uf::Entity* globalFindByName( const std::string& name ); - // behavior - virtual void initialize(); - virtual void destroy(); - virtual void tick(); - virtual void render(); + Entity(); + UF_BEHAVIOR_VIRTUAL_H() }; } -#include "entity.inl" \ No newline at end of file + +#include "entity.inl" +#include "behavior.h" \ No newline at end of file diff --git a/engine/inc/uf/engine/instantiator/instantiator.h b/engine/inc/uf/engine/instantiator/instantiator.h index 97ae9a43..0520026a 100644 --- a/engine/inc/uf/engine/instantiator/instantiator.h +++ b/engine/inc/uf/engine/instantiator/instantiator.h @@ -7,37 +7,58 @@ #include #include -#define NAMESPACE_CONCAT -#define UF_OBJECT_REGISTER_CPP( OBJ ) \ -namespace {\ - static uf::StaticInitialization REGISTER_UF_ ## OBJ( []{\ - uf::instantiator::add( #OBJ );\ - });\ -} -#define EXT_OBJECT_REGISTER_CPP( OBJ ) \ -namespace {\ - static uf::StaticInitialization REGISTER_EXT_ ## OBJ( []{\ - uf::instantiator::add( #OBJ );\ - });\ +namespace pod { + struct UF_API Instantiator { + typedef std::function function_t; + typedef std::vector behaviors_t; + function_t function; + behaviors_t behaviors; + }; + + template + struct UF_API NamedTypes { + typedef std::type_index type_t; + typedef std::unordered_map container_t; + typedef std::unordered_map map_t; + container_t names; + map_t map; + + type_t getType( const std::string& name ); + template type_t getType(); + template std::string getName(); + + bool has( const std::string& name ); + template bool has(); + + template void add( const std::string& name, const C& c ); + + C& get( const std::string& name ); + template C& get(); + }; } namespace uf { namespace instantiator { - typedef std::function function_t; - extern UF_API std::unordered_map* names; - extern UF_API std::unordered_map* map; + extern UF_API pod::NamedTypes* objects; + extern UF_API pod::NamedTypes* behaviors; uf::Entity* UF_API alloc( size_t ); - void UF_API free( uf::Entity* ); - uf::Entity* UF_API instantiate( const std::string& ); - - template void add( const std::string& name ); - template T* alloc(); - template T& instantiate( size_t size ); + void UF_API free( uf::Entity* ); + + template void registerObject( const std::string& name ); + template void registerBehavior( const std::string& name ); + template void registerBinding( const std::string& name ); + void UF_API registerBinding( const std::string& object, const std::string& behavior ); + + uf::Entity& UF_API instantiate( const std::string& ); template T& instantiate(); template T* _instantiate(); + + void UF_API bind( const std::string&, uf::Entity& ); + template void bind( uf::Entity& ); }; } -#include "instantiator.inl" \ No newline at end of file +#include "instantiator.inl" +#include "macros.inl" \ No newline at end of file diff --git a/engine/inc/uf/engine/instantiator/instantiator.inl b/engine/inc/uf/engine/instantiator/instantiator.inl index 11f105cc..ef8dc18d 100644 --- a/engine/inc/uf/engine/instantiator/instantiator.inl +++ b/engine/inc/uf/engine/instantiator/instantiator.inl @@ -1,32 +1,174 @@ +template +pod::NamedTypes::type_t pod::NamedTypes::getType( const std::string& name ) { + for ( auto pair : names ) if ( pair.second == name ) return pair.first; + return getType(); +} +template +template pod::NamedTypes::type_t pod::NamedTypes::getType() { + return std::type_index(typeid(T)); +} +template +template std::string pod::NamedTypes::getName() { + return names[getType()]; +} +template +bool pod::NamedTypes::has( const std::string& name ) { + return names.count(getType(name)) > 0; +}template +template bool pod::NamedTypes::has() { + return names.count(getType()) > 0; +} +template +template void pod::NamedTypes::add( const std::string& name, const C& c ) { + names[getType()] = name; + map[name] = c; +} +template +C& pod::NamedTypes::get( const std::string& name ) { + return map[name]; +} +template +template +C& pod::NamedTypes::get() { + return map[getName()]; +} + template T* uf::instantiator::alloc() { return (T*) alloc( sizeof(T) ); -// return new T; +} + +template void uf::instantiator::registerObject( const std::string& name ) { + if ( !objects ) objects = new pod::NamedTypes; + auto& container = *uf::instantiator::objects; + container.add(name, { + .function = _instantiate + }); + + std::cout << "Registered instantiation for " << name << std::endl; +} +template void uf::instantiator::registerBehavior( const std::string& name ) { + if ( !behaviors ) behaviors = new pod::NamedTypes; + auto& container = *uf::instantiator::behaviors; + container.add(name, pod::Behavior{ + .type = uf::Behaviors::getType(), + .initialize = T::initialize, + .tick = T::tick, + .render = T::render, + .destroy = T::destroy, + }); + + std::cout << "Registered behavior for " << name << std::endl; +} + +template void uf::instantiator::registerBinding( const std::string& name ) { + if ( !objects ) objects = new pod::NamedTypes; + auto& container = *uf::instantiator::objects; + auto& instantiator = container.get(); + instantiator.behaviors.emplace_back(name); + + std::cout << "Registered binding for " << name << std::endl; +} + +template +T& uf::instantiator::instantiate() { + T* entity = alloc(); + ::new (entity) T(); + T& object = *entity; + uf::instantiator::bind( object ); + return object; } template -void uf::instantiator::add( const std::string& name ) { - if ( !names ) names = new std::unordered_map; - if ( !map ) map = new std::unordered_map; +T* uf::instantiator::_instantiate() { + return &instantiate(); +} +template +void uf::instantiator::bind( uf::Entity& entity ) { + auto& instantiator = uf::instantiator::objects->get(); + for ( auto& name : instantiator.behaviors ) { + auto& behavior = uf::instantiator::behaviors->get( name ); + entity.addBehavior(behavior); + } +} +/* +template +T* uf::instantiator::alloc() { + return (T*) alloc( sizeof(T) ); +} + +template +std::string uf::instantiator::getName() { + auto type = getType(); auto& names = *uf::instantiator::names; - auto& map = *uf::instantiator::map; + return names[type]; +} - names[std::type_index(typeid(T))] = name; - map[name] = _instantiate; +template +uf::instantiator::type_t uf::instantiator::getType() { + return std::type_index(typeid(T)); +} + +template +T& uf::instantiator::instantiate() { + T* entity = alloc(); + ::new (entity) T(); + T& object = *entity; + uf::instantiator::bind( object ); + return object; +} +template +T* uf::instantiator::_instantiate() { + return &instantiate(); +} + +template +void uf::instantiator::add( const std::string& name ) { + if ( !map ) map = new std::unordered_map; + if ( !names ) names = new std::unordered_map; + + auto& map = *uf::instantiator::map; + auto& names = *uf::instantiator::names; + + auto type = getType(); + names[type] = name; + map[name] = { + .function = _instantiate + }; std::cout << "Registered instantiation for " << name << std::endl; } template -T& uf::instantiator::instantiate( size_t size ) { - T* entity = alloc(); - ::new (entity) T(); - return *entity; +void uf::instantiator::add( const pod::Behavior& behavior ) { + if ( !registered() ) return; + auto type = getType(); + auto& map = *uf::instantiator::map; + auto& instantiator = map[getName()]; + instantiator.behaviors.emplace_back(behavior); } -template -T& uf::instantiator::instantiate() { - return instantiate( sizeof(T) ); +template +void uf::instantiator::add() { + return uf::instantiator::add(pod::Behavior{ + .type = uf::Behaviors::getType(), + .initialize = U::initialize, + .tick = U::tick, + .render = U::render, + .destroy = U::destroy, + }); } + template -T* uf::instantiator::_instantiate() { - return &instantiate( sizeof(T) ); -} \ No newline at end of file +bool uf::instantiator::registered() { + return uf::instantiator::map->count(getName()) > 0; +} + +template +void uf::instantiator::bind( T& object ) { + if ( !registered() ) return; + auto& map = *uf::instantiator::map; + auto& instantiator = map[getName()]; + for ( auto& behavior : instantiator.behaviors ) { + object.addBehavior(behavior); + } +} +*/ \ No newline at end of file diff --git a/engine/inc/uf/engine/instantiator/macros.inl b/engine/inc/uf/engine/instantiator/macros.inl new file mode 100644 index 00000000..7b749d05 --- /dev/null +++ b/engine/inc/uf/engine/instantiator/macros.inl @@ -0,0 +1,61 @@ +#pragma once + +#define NAMESPACE_CONCAT +#define UF_OBJECT_REGISTER_CPP( OBJ ) \ +namespace {\ + static uf::StaticInitialization REGISTER_UF_ ## OBJ( []{\ + uf::instantiator::registerObject( #OBJ );\ + });\ +} +#define EXT_OBJECT_REGISTER_CPP( OBJ ) \ +namespace {\ + static uf::StaticInitialization REGISTER_EXT_ ## OBJ( []{\ + uf::instantiator::registerObject( #OBJ );\ + });\ +} +#define UF_BEHAVIOR_REGISTER_CPP( BEHAVIOR ) \ +namespace {\ + static uf::StaticInitialization REGISTER_UF_ ## BEHAVIOR( []{\ + uf::instantiator::registerBehavior( #BEHAVIOR );\ + });\ +} +#define EXT_BEHAVIOR_REGISTER_CPP( BEHAVIOR ) \ +namespace {\ + static uf::StaticInitialization REGISTER_EXT_ ## BEHAVIOR( []{\ + uf::instantiator::registerBehavior( #BEHAVIOR );\ + });\ +} + +#define UF_OBJECT_REGISTER_BEGIN( OBJ )\ +namespace {\ + static uf::StaticInitialization REGISTER_EXT_ ## OBJ( []{\ + std::string name = #OBJ;\ + uf::instantiator::registerObject( name ); + +#define UF_OBJECT_BIND_BEHAVIOR( BEHAVIOR )\ + uf::instantiator::registerBinding( name, #BEHAVIOR ); + +#define UF_OBJECT_REGISTER_BEHAVIOR( BEHAVIOR )\ + uf::instantiator::registerBehavior( #BEHAVIOR );\ + UF_OBJECT_BIND_BEHAVIOR( BEHAVIOR ) + +#define UF_OBJECT_REGISTER_END()\ + });\ +} + +#define EXT_OBJECT_REGISTER_BEGIN( OBJ )\ +namespace {\ + static uf::StaticInitialization REGISTER_EXT_ ## OBJ( []{\ + std::string name = #OBJ;\ + uf::instantiator::registerObject( name ); + +#define EXT_OBJECT_BIND_BEHAVIOR( BEHAVIOR )\ + uf::instantiator::registerBinding( name, #BEHAVIOR ); + +#define EXT_OBJECT_REGISTER_BEHAVIOR( BEHAVIOR )\ + uf::instantiator::registerBehavior( #BEHAVIOR );\ + EXT_OBJECT_BIND_BEHAVIOR( BEHAVIOR ) + +#define EXT_OBJECT_REGISTER_END()\ + });\ +} diff --git a/engine/inc/uf/engine/object/behavior.h b/engine/inc/uf/engine/object/behavior.h new file mode 100644 index 00000000..aa402c1e --- /dev/null +++ b/engine/inc/uf/engine/object/behavior.h @@ -0,0 +1,5 @@ +#pragma once + +namespace uf { + UF_BEHAVIOR_ENTITY_H(Object) +} \ No newline at end of file diff --git a/engine/inc/uf/engine/object/object.h b/engine/inc/uf/engine/object/object.h index a1b1263d..45d502dd 100644 --- a/engine/inc/uf/engine/object/object.h +++ b/engine/inc/uf/engine/object/object.h @@ -3,16 +3,15 @@ #include #include #include +#include + #include #include namespace uf { class UF_API Object : public uf::Entity { public: - virtual void initialize(); - virtual void destroy(); - virtual void tick(); - virtual void render(); + static uf::Timer timer; bool reload( bool = false ); bool load( const std::string&, bool = false ); @@ -23,5 +22,15 @@ namespace uf { void queueHook( const std::string&, const std::string& = "", double = 0 ); std::vector callHook( const std::string&, const std::string& = "" ); std::size_t addHook( const std::string&, const uf::HookHandler::Readable::function_t& ); + + Object(); + #if UF_BEHAVIOR_VIRTUAL + virtual void initialize(); + virtual void tick(); + virtual void render(); + virtual void destroy(); + #endif }; -} \ No newline at end of file +} + +#include "behavior.h" \ No newline at end of file diff --git a/engine/inc/uf/engine/scene/behavior.h b/engine/inc/uf/engine/scene/behavior.h new file mode 100644 index 00000000..39b2c346 --- /dev/null +++ b/engine/inc/uf/engine/scene/behavior.h @@ -0,0 +1,5 @@ +#pragma once + +namespace uf { + UF_BEHAVIOR_ENTITY_H(Scene) +} \ No newline at end of file diff --git a/engine/inc/uf/engine/scene/scene.h b/engine/inc/uf/engine/scene/scene.h index b06b97b6..19c7ec53 100644 --- a/engine/inc/uf/engine/scene/scene.h +++ b/engine/inc/uf/engine/scene/scene.h @@ -4,14 +4,7 @@ namespace uf { class UF_API Scene : public uf::Object { - protected: - // void* m_graphics; public: - virtual void initialize(); - virtual void tick(); - virtual void render(); - virtual void destroy(); - virtual uf::Entity& getController(); virtual const uf::Entity& getController() const; @@ -21,6 +14,14 @@ namespace uf { template const T& getController() const { return *((const T*) &this->getController()); } + + Scene(); + #if UF_BEHAVIOR_VIRTUAL + virtual void initialize(); + virtual void tick(); + virtual void render(); + virtual void destroy(); + #endif }; namespace scene { @@ -34,4 +35,6 @@ namespace uf { void UF_API render(); void UF_API destroy(); } -} \ No newline at end of file +} + +#include "behavior.h" \ No newline at end of file diff --git a/engine/src/engine/behavior/behavior.cpp b/engine/src/engine/behavior/behavior.cpp index 06134f20..53db932c 100644 --- a/engine/src/engine/behavior/behavior.cpp +++ b/engine/src/engine/behavior/behavior.cpp @@ -1,27 +1,36 @@ #include +#include +bool uf::Behaviors::hasBehavior( const pod::Behavior& target ) { + for ( auto& behavior : this->m_behaviors ) { + if ( behavior.type == target.type ) return true; + } + return false; +} void uf::Behaviors::addBehavior( const pod::Behavior& behavior ) { - std::cout << "[!!!] behavior attached" << std::endl; + if ( hasBehavior( behavior ) ) return; this->m_behaviors.emplace_back(behavior); } void uf::Behaviors::initialize() { - for ( auto it = this->m_behaviors.rbegin(); it != this->m_behaviors.rend(); ++it ) { - std::cout << "[!!!] behavior called: initialize" << std::endl; - it->initialize(); - } + uf::Object& self = *((uf::Object*) this); + for ( auto& behavior : this->m_behaviors ) behavior.initialize(self); } void uf::Behaviors::tick() { - for ( auto it = this->m_behaviors.rbegin(); it != this->m_behaviors.rend(); ++it ) - it->tick(); + uf::Object& self = *((uf::Object*) this); + for ( auto it = this->m_behaviors.rbegin(); it != this->m_behaviors.rend(); ++it ) { + it->tick(self); + } } void uf::Behaviors::render() { - for ( auto it = this->m_behaviors.rbegin(); it != this->m_behaviors.rend(); ++it ) - it->render(); + uf::Object& self = *((uf::Object*) this); + for ( auto it = this->m_behaviors.rbegin(); it != this->m_behaviors.rend(); ++it ) { + it->render(self); + } } void uf::Behaviors::destroy() { + uf::Object& self = *((uf::Object*) this); for ( auto it = this->m_behaviors.rbegin(); it != this->m_behaviors.rend(); ++it ) { - std::cout << "[!!!] behavior called: destroy" << std::endl; - it->destroy(); + it->destroy(self); } } \ No newline at end of file diff --git a/engine/src/engine/entity/behavior.cpp b/engine/src/engine/entity/behavior.cpp new file mode 100644 index 00000000..f9bd9ff9 --- /dev/null +++ b/engine/src/engine/entity/behavior.cpp @@ -0,0 +1,35 @@ +#include + +UF_BEHAVIOR_ENTITY_CPP_BEGIN(Entity) +#define this ((uf::Entity*) &self) +void uf::EntityBehavior::initialize( uf::Object& self ) { + if ( this->m_uid == 0 ) + this->m_uid = ++uf::Entity::uids; +} +void uf::EntityBehavior::tick( uf::Object& self ) { + for ( uf::Entity* kv : this->m_children ) { + if ( !kv ) continue; + if ( kv->getUid() == 0 ) continue; + kv->tick(); + } +} +void uf::EntityBehavior::render( uf::Object& self ) { + for ( uf::Entity* kv : this->m_children ) { + if ( !kv ) continue; + if ( kv->getUid() == 0 ) continue; + kv->render(); + } +} +void uf::EntityBehavior::destroy( uf::Object& self ) { + for ( uf::Entity* kv : this->m_children ) { + if ( !kv ) continue; + if ( kv->getUid() == 0 ) continue; + kv->destroy(); + kv->setParent(); + delete kv; + } + this->m_children.clear(); + this->m_uid = 0; +} +#undef this +UF_BEHAVIOR_ENTITY_CPP_END(Entity) \ No newline at end of file diff --git a/engine/src/engine/entity/entity.cpp b/engine/src/engine/entity/entity.cpp index 5acacae7..27f29357 100644 --- a/engine/src/engine/entity/entity.cpp +++ b/engine/src/engine/entity/entity.cpp @@ -5,9 +5,6 @@ uf::Entity uf::Entity::null; std::size_t uf::Entity::uids = 0; uf::MemoryPool uf::Entity::memoryPool; -uf::Entity::Entity( bool shouldInitialize ){ - if ( shouldInitialize ) this->initialize(); -} uf::Entity::~Entity(){ this->destroy(); } @@ -51,7 +48,7 @@ std::size_t uf::Entity::getUid() const { } void* uf::Entity::operator new(size_t size, const std::string& type ) { - return type != "" && size == sizeof(uf::Entity) ? uf::instantiator::instantiate( type ) : uf::instantiator::alloc( size ); + return type != "" && size == sizeof(uf::Entity) ? &uf::instantiator::instantiate( type ) : uf::instantiator::alloc( size ); } void uf::Entity::operator delete( void* pointer ) { uf::instantiator::free( (uf::Entity*) pointer ); @@ -119,73 +116,4 @@ uf::Entity* uf::Entity::globalFindByName( const std::string& name ) { if ( entity->getName() == name ) return entity; } return NULL; -} - - -void uf::Entity::initialize( ){ - if ( this->m_uid == 0 ) this->m_uid = ++uf::Entity::uids; - - uf::Behaviors::initialize(); -} -void uf::Entity::tick( ){ - uf::Behaviors::tick(); - - for ( uf::Entity* kv : this->m_children ) { - if ( !kv ) continue; - if ( kv->getUid() == 0 ) continue; - kv->tick(); - } -} -void uf::Entity::render( ){ - uf::Behaviors::render(); - - for ( uf::Entity* kv : this->m_children ) { - if ( !kv ) continue; - if ( kv->getUid() == 0 ) continue; - kv->render(); - } -} -void uf::Entity::destroy( ){ - uf::Behaviors::destroy(); - - for ( uf::Entity* kv : this->m_children ) { - if ( !kv ) continue; - if ( kv->getUid() == 0 ) continue; - kv->destroy(); - kv->setParent(); - delete kv; - } - this->m_children.clear(); - this->m_uid = 0; -} - -/* -void uf::EntityBehavior::initialize( uf::Entity& base ){ - if ( base.m_uid == 0 ) base.m_uid = ++uf::Entity::uids; -} -void uf::EntityBehavior::destroy( uf::Entity& entity ){ - for ( uf::Entity* kv : base.m_children ) { - if ( !kv ) continue; - if ( kv->getUid() == 0 ) continue; - kv->destroy(); - kv->setParent(); - delete kv; - } - base.m_children.clear(); - base.m_uid = 0; -} -void uf::EntityBehavior::tick( uf::Entity& entity ){ - for ( uf::Entity* kv : base.m_children ) { - if ( !kv ) continue; - if ( kv->getUid() == 0 ) continue; - kv->tick(); - } -} -void uf::EntityBehavior::render( uf::Entity& entity ){ - for ( uf::Entity* kv : base.m_children ) { - if ( !kv ) continue; - if ( kv->getUid() == 0 ) continue; - kv->render(); - } -} -*/ \ No newline at end of file +} \ No newline at end of file diff --git a/engine/src/engine/instantiator/instantiator.cpp b/engine/src/engine/instantiator/instantiator.cpp index fee1539e..ea0fbea9 100644 --- a/engine/src/engine/instantiator/instantiator.cpp +++ b/engine/src/engine/instantiator/instantiator.cpp @@ -1,16 +1,11 @@ #include +#include #include -std::unordered_map* uf::instantiator::names = NULL; -std::unordered_map* uf::instantiator::map = NULL; +pod::NamedTypes* uf::instantiator::objects = NULL; +pod::NamedTypes* uf::instantiator::behaviors = NULL; uf::Entity* uf::instantiator::alloc( size_t size ) { -/* - uf::Entity* pointer = (uf::Entity*) uf::Entity::memoryPool.alloc( NULL, size ); - std::cout << "malloc uf::Entity: "<< pointer <<" (size: " << size << ")" << std::endl; - return pointer; -*/ -// uf::MemoryPool& memoryPool = uf::MemoryPool::global.size() > 0 ? uf::MemoryPool::global : uf::Entity::memoryPool; #if UF_MEMORYPOOL_INVALID_MALLOC uf::MemoryPool& memoryPool = uf::Entity::memoryPool.size() > 0 ? uf::Entity::memoryPool : uf::MemoryPool::global; return (uf::Entity*) memoryPool.alloc( NULL, size ); @@ -25,19 +20,8 @@ uf::Entity* uf::instantiator::alloc( size_t size ) { else pointer = (uf::Entity*) malloc( size ); return pointer; #endif -/* - uf::Entity* pointer = ( memoryPool.size() <= 0 ) ? (uf::Entity*) ::malloc( size ) : (uf::Entity*) memoryPool.alloc( NULL, size ); - // std::cout << "malloc uf::Entity: "<< pointer <<" (size: " << size << ")" << std::endl; - return pointer; -*/ -/* - std::cout << "malloc uf::Entity (size: " << size << ")" << std::endl; - if ( memoryPool.size() <= 0 ) return (uf::Entity*) ::malloc( size ); - return (uf::Entity*) memoryPool.alloc( NULL, size ); -*/ } void uf::instantiator::free( uf::Entity* pointer ) { -// uf::MemoryPool& memoryPool = uf::MemoryPool::global.size() > 0 ? uf::MemoryPool::global : uf::Entity::memoryPool; #if UF_MEMORYPOOL_INVALID_FREE uf::MemoryPool& memoryPool = uf::Entity::memoryPool.size() > 0 ? uf::Entity::memoryPool : uf::MemoryPool::global; memoryPool.free( pointer ); @@ -50,15 +34,39 @@ void uf::instantiator::free( uf::Entity* pointer ) { if ( memoryPool ) memoryPool->free( pointer ); else ::free( pointer ); #endif -/* - // std::cout << "free uf::Entity: " << pointer << std::endl; - if ( !uf::Entity::memoryPool.free( pointer ) ) - ::free(pointer); -*/ } -uf::Entity* uf::instantiator::instantiate( const std::string& name ) { - // std::cout << "instantiating " << name << std::endl; - auto& map = *uf::instantiator::map; - assert( map.count(name) > 0 ); - return map[name](); + +void uf::instantiator::registerBinding( const std::string& object, const std::string& behavior ) { + if ( !objects ) objects = new pod::NamedTypes; + auto& instantiator = uf::instantiator::objects->get( object ); + instantiator.behaviors.emplace_back( behavior ); + + std::cout << "Registered binding: " << object << " and " << behavior << std::endl; +} + +uf::Entity& uf::instantiator::instantiate( const std::string& name ) { + if ( !uf::instantiator::objects->has( name ) ) { + auto& object = uf::instantiator::instantiate(); + return *((uf::Entity*) &object); + } + auto& instantiator = uf::instantiator::objects->get( name ); + auto& entity = *instantiator.function(); + bind( name, entity ); + return entity; +} + +void uf::instantiator::bind( const std::string& name, uf::Entity& entity ) { + // was actually a behavior name, single bind + if ( !uf::instantiator::objects->has( name ) ) { + if ( !uf::instantiator::behaviors->has( name ) ) return; + auto& behavior = uf::instantiator::behaviors->get( name ); + entity.addBehavior(behavior); + return; + } + + auto& instantiator = uf::instantiator::objects->get( name ); + for ( auto& name : instantiator.behaviors ) { + auto& behavior = uf::instantiator::behaviors->get( name ); + entity.addBehavior(behavior); + } } \ No newline at end of file diff --git a/engine/src/engine/object/behavior.cpp b/engine/src/engine/object/behavior.cpp new file mode 100644 index 00000000..74077a31 --- /dev/null +++ b/engine/src/engine/object/behavior.cpp @@ -0,0 +1,112 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +UF_BEHAVIOR_ENTITY_CPP_BEGIN(Object) +#define this (&self) +void uf::ObjectBehavior::initialize( uf::Object& self ) { + uf::Serializer& metadata = this->getComponent(); + if ( metadata["system"]["type"].isNull() || metadata["system"]["defaults"]["asset load"].asBool() ) { + // Default load: GLTF model + this->addHook( "asset:Load.%UID%", [&](const std::string& event)->std::string{ + uf::Serializer json = event; + std::string filename = json["filename"].asString(); + + if ( uf::string::extension(filename) != "glb" ) return "false"; + int8_t LOAD_FLAGS = 0; + if ( metadata["model"]["flags"]["GENERATE_NORMALS"].asBool() ) + LOAD_FLAGS |= ext::gltf::LoadMode::GENERATE_NORMALS; // 0x1 << 0; + if ( metadata["model"]["flags"]["APPLY_TRANSFORMS"].asBool() ) + LOAD_FLAGS |= ext::gltf::LoadMode::APPLY_TRANSFORMS; // 0x1 << 1; + if ( metadata["model"]["flags"]["SEPARATE_MESHES"].asBool() ) + LOAD_FLAGS |= ext::gltf::LoadMode::SEPARATE_MESHES; // 0x1 << 2; + if ( metadata["model"]["flags"]["RENDER"].asBool() ) + LOAD_FLAGS |= ext::gltf::LoadMode::RENDER; // 0x1 << 3; + if ( metadata["model"]["flags"]["COLLISION"].asBool() ) + LOAD_FLAGS |= ext::gltf::LoadMode::COLLISION; // 0x1 << 4; + if ( metadata["model"]["flags"]["AABB"].asBool() ) + LOAD_FLAGS |= ext::gltf::LoadMode::AABB; // 0x1 << 5; + + ext::gltf::load( *this, filename, LOAD_FLAGS ); + return "true"; + }); + } +} +void uf::ObjectBehavior::destroy( uf::Object& self ) { + uf::Serializer& metadata = this->getComponent(); + for( Json::Value::iterator it = metadata["system"]["hooks"]["alloc"].begin() ; it != metadata["system"]["hooks"]["alloc"].end() ; ++it ) { + std::string name = it.key().asString(); + for ( size_t i = 0; i < metadata["system"]["hooks"]["alloc"][name].size(); ++i ) { + size_t id = metadata["system"]["hooks"]["alloc"][name][(int) i].asUInt(); + uf::hooks.removeHook(name, id); + } + } +} +void uf::ObjectBehavior::tick( uf::Object& self ) { + // listen for metadata file changes + uf::Serializer& metadata = this->getComponent(); + if ( metadata["system"]["hot reload"]["enabled"].asBool() ) { + size_t mtime = uf::string::mtime( metadata["system"]["source"].asString() ); + if ( metadata["system"]["hot reload"]["mtime"].asUInt64() < mtime ) { + std::cout << metadata["system"]["hot reload"]["mtime"] << ": " << mtime << std::endl; + metadata["system"]["hot reload"]["mtime"] = mtime; + this->reload(); + //this->queueHook("metadata:Reload.%UID%"); + } + } + + // Call queued hooks + { + if ( !uf::Object::timer.running() ) uf::Object::timer.start(); + float curTime = uf::Object::timer.elapsed().asDouble(); + uf::Serializer newQueue = Json::Value(Json::arrayValue); + for ( auto& member : metadata["system"]["hooks"]["queue"] ) { + uf::Serializer payload = member["payload"]; + std::string name = member["name"].asString(); + float timeout = member["timeout"].asFloat(); + if ( timeout < curTime ) { + this->callHook( name, payload ); + } else { + newQueue.append(member); + } + } + if ( metadata.isObject() ) metadata["system"]["hooks"]["queue"] = newQueue; + } +} +void uf::ObjectBehavior::render( uf::Object& self ) { + auto& metadata = this->getComponent(); + if ( metadata["system"]["type"].isNull() || metadata["system"]["defaults"]["render"].asBool() ) { + /* Update uniforms */ if ( this->hasComponent() ) { + auto& scene = uf::scene::getCurrentScene(); + auto& graphic = this->getComponent(); + auto& transform = this->getComponent>(); + auto& controller = scene.getController(); + auto& camera = controller.getComponent(); + + if ( !graphic.initialized ) return; + + auto& uniforms = graphic.material.shaders.front().uniforms.front().get(); + uniforms.matrices.model = uf::transform::model( transform ); + for ( std::size_t i = 0; i < 2; ++i ) { + uniforms.matrices.view[i] = camera.getView( i ); + uniforms.matrices.projection[i] = camera.getProjection( i ); + } + + uniforms.color[0] = 1; + uniforms.color[1] = 1; + uniforms.color[2] = 1; + uniforms.color[3] = 1; + + graphic.material.shaders.front().updateBuffer( uniforms, 0, false ); + }; + } +} +#undef this +UF_BEHAVIOR_ENTITY_CPP_END(Entity) \ No newline at end of file diff --git a/engine/src/engine/object/object.cpp b/engine/src/engine/object/object.cpp index 2468a177..7e27776e 100644 --- a/engine/src/engine/object/object.cpp +++ b/engine/src/engine/object/object.cpp @@ -9,9 +9,8 @@ #include #include +uf::Timer uf::Object::timer(false); namespace { - uf::Timer timer(false); - std::string grabURI( std::string filename, std::string root = "" ) { if ( filename.substr(0,8) == "https://" ) return filename; std::string extension = uf::string::extension(filename); @@ -26,116 +25,13 @@ namespace { } } -UF_OBJECT_REGISTER_CPP(Object) -void uf::Object::initialize() { - uf::Entity::initialize(); - - uf::Serializer& metadata = this->getComponent(); - if ( metadata["system"]["type"].isNull() || metadata["system"]["defaults"]["asset load"].asBool() ) { - // Default load: GLTF model - this->addHook( "asset:Load.%UID%", [&](const std::string& event)->std::string{ - uf::Serializer json = event; - std::string filename = json["filename"].asString(); - - if ( uf::string::extension(filename) != "glb" ) return "false"; - int8_t LOAD_FLAGS = 0; - if ( metadata["model"]["flags"]["GENERATE_NORMALS"].asBool() ) - LOAD_FLAGS |= ext::gltf::LoadMode::GENERATE_NORMALS; // 0x1 << 0; - if ( metadata["model"]["flags"]["APPLY_TRANSFORMS"].asBool() ) - LOAD_FLAGS |= ext::gltf::LoadMode::APPLY_TRANSFORMS; // 0x1 << 1; - if ( metadata["model"]["flags"]["SEPARATE_MESHES"].asBool() ) - LOAD_FLAGS |= ext::gltf::LoadMode::SEPARATE_MESHES; // 0x1 << 2; - if ( metadata["model"]["flags"]["RENDER"].asBool() ) - LOAD_FLAGS |= ext::gltf::LoadMode::RENDER; // 0x1 << 3; - if ( metadata["model"]["flags"]["COLLISION"].asBool() ) - LOAD_FLAGS |= ext::gltf::LoadMode::COLLISION; // 0x1 << 4; - if ( metadata["model"]["flags"]["AABB"].asBool() ) - LOAD_FLAGS |= ext::gltf::LoadMode::AABB; // 0x1 << 5; - - ext::gltf::load( *this, filename, LOAD_FLAGS ); - return "true"; - }); - } -} -void uf::Object::destroy() { - uf::Serializer& metadata = this->getComponent(); - for( Json::Value::iterator it = metadata["system"]["hooks"]["alloc"].begin() ; it != metadata["system"]["hooks"]["alloc"].end() ; ++it ) { - std::string name = it.key().asString(); - for ( size_t i = 0; i < metadata["system"]["hooks"]["alloc"][name].size(); ++i ) { - size_t id = metadata["system"]["hooks"]["alloc"][name][(int) i].asUInt(); - uf::hooks.removeHook(name, id); - } - } - - uf::Entity::destroy(); -} -void uf::Object::tick() { - uf::Entity::tick(); - - // listen for metadata file changes - uf::Serializer& metadata = this->getComponent(); - if ( metadata["system"]["hot reload"]["enabled"].asBool() ) { - size_t mtime = uf::string::mtime( metadata["system"]["source"].asString() ); - if ( metadata["system"]["hot reload"]["mtime"].asUInt64() < mtime ) { - std::cout << metadata["system"]["hot reload"]["mtime"] << ": " << mtime << std::endl; - metadata["system"]["hot reload"]["mtime"] = mtime; - this->reload(); - //this->queueHook("metadata:Reload.%UID%"); - } - } - - // Call queued hooks - { - if ( !timer.running() ) timer.start(); - float curTime = timer.elapsed().asDouble(); - uf::Serializer newQueue = Json::Value(Json::arrayValue); - for ( auto& member : metadata["system"]["hooks"]["queue"] ) { - uf::Serializer payload = member["payload"]; - std::string name = member["name"].asString(); - float timeout = member["timeout"].asFloat(); - if ( timeout < curTime ) { - this->callHook( name, payload ); - } else { - newQueue.append(member); - } - } - if ( metadata.isObject() ) metadata["system"]["hooks"]["queue"] = newQueue; - } -} -void uf::Object::render() { - uf::Entity::render(); - - auto& metadata = this->getComponent(); - if ( metadata["system"]["type"].isNull() || metadata["system"]["defaults"]["render"].asBool() ) { - /* Update uniforms */ if ( this->hasComponent() ) { - auto& scene = uf::scene::getCurrentScene(); - auto& graphic = this->getComponent(); - auto& transform = this->getComponent>(); - auto& controller = scene.getController(); - auto& camera = controller.getComponent(); - - if ( !graphic.initialized ) return; - - auto& uniforms = graphic.material.shaders.front().uniforms.front().get(); - uniforms.matrices.model = uf::transform::model( transform ); - for ( std::size_t i = 0; i < 2; ++i ) { - uniforms.matrices.view[i] = camera.getView( i ); - uniforms.matrices.projection[i] = camera.getProjection( i ); - } - - uniforms.color[0] = 1; - uniforms.color[1] = 1; - uniforms.color[2] = 1; - uniforms.color[3] = 1; - - graphic.material.shaders.front().updateBuffer( uniforms, 0, false ); - }; - } -} - +UF_OBJECT_REGISTER_BEGIN(Object) + UF_OBJECT_REGISTER_BEHAVIOR(EntityBehavior) + UF_OBJECT_REGISTER_BEHAVIOR(ObjectBehavior) +UF_OBJECT_REGISTER_END() void uf::Object::queueHook( const std::string& name, const std::string& payload, double timeout ) { - if ( !timer.running() ) timer.start(); - float start = timer.elapsed().asDouble(); + if ( !uf::Object::timer.running() ) uf::Object::timer.start(); + float start = uf::Object::timer.elapsed().asDouble(); uf::Serializer queue; queue["name"] = name; queue["payload"] = uf::Serializer{payload}; @@ -212,6 +108,21 @@ bool uf::Object::load( const uf::Serializer& json ) { // Set name this->m_name = json["name"].isString() ? json["name"].asString() : json["type"].asString(); } + // Bind behaviors + if ( json["type"].isString() ) { + uf::instantiator::bind( json["type"].asString(), *this ); + } + { + uf::Serializer target; + if ( metadata["system"]["behaviors"].isArray() ) { + target = metadata["system"]["behaviors"]; + } else if ( json["behaviors"].isArray() ) { + target = json["behaviors"]; + } + for ( uint i = 0; i < target.size(); ++i ) { + uf::instantiator::bind( target[i].asString(), *this ); + } + } // Set transform { bool load = json["transform"].isObject(); @@ -444,7 +355,7 @@ std::size_t uf::Object::loadChild( const uf::Serializer& json, bool initialize ) uf::Entity* entity; std::string type = json["type"].asString(); if ( json["ignore"].asBool() ) return 0; - entity = uf::instantiator::instantiate(type); + entity = &uf::instantiator::instantiate(type); if ( !((uf::Object*) entity)->load(json) ) { uf::iostream << "Error @ " << __FILE__ << ":" << __LINE__ << " loading `" << json << "!" << "\n"; diff --git a/engine/src/engine/scene/behavior.cpp b/engine/src/engine/scene/behavior.cpp new file mode 100644 index 00000000..07df93c3 --- /dev/null +++ b/engine/src/engine/scene/behavior.cpp @@ -0,0 +1,22 @@ +#include +#include +#include +#include + +UF_BEHAVIOR_ENTITY_CPP_BEGIN(Scene) +#define this ((uf::Scene*) &self) +void uf::SceneBehavior::initialize( uf::Object& self ) { + uf::renderer::scenes.push_back(this); + uf::renderer::rebuild = true; +} +void uf::SceneBehavior::tick( uf::Object& self ) { +} +void uf::SceneBehavior::render( uf::Object& self ) { +} +void uf::SceneBehavior::destroy( uf::Object& self ) { + auto it = std::find(uf::renderer::scenes.begin(), uf::renderer::scenes.end(), this); + if ( it != uf::renderer::scenes.end() ) uf::renderer::scenes.erase(it); + uf::renderer::rebuild = true; +} +#undef self +UF_BEHAVIOR_ENTITY_CPP_END(Scene) \ No newline at end of file diff --git a/engine/src/engine/scene/scene.cpp b/engine/src/engine/scene/scene.cpp index f35d270e..56a3bdf8 100644 --- a/engine/src/engine/scene/scene.cpp +++ b/engine/src/engine/scene/scene.cpp @@ -3,31 +3,11 @@ #include #include -UF_OBJECT_REGISTER_CPP(Scene) -void uf::Scene::initialize() { - uf::renderer::scenes.push_back(this); - uf::renderer::rebuild = true; - - uf::Object::initialize(); -} -void uf::Scene::tick() { - uf::Object::tick(); -} -void uf::Scene::render() { - uf::Object::render(); - -} -void uf::Scene::destroy() { - uf::Object::destroy(); - - { - auto it = std::find(uf::renderer::scenes.begin(), uf::renderer::scenes.end(), this); - if ( it != uf::renderer::scenes.end() ) uf::renderer::scenes.erase(it); - uf::renderer::rebuild = true; - } -} - - +UF_OBJECT_REGISTER_BEGIN(Scene) + UF_OBJECT_REGISTER_BEHAVIOR(EntityBehavior) + UF_OBJECT_REGISTER_BEHAVIOR(ObjectBehavior) + UF_OBJECT_REGISTER_BEHAVIOR(SceneBehavior) +UF_OBJECT_REGISTER_END() uf::Entity& uf::Scene::getController() { static uf::Entity* cachedController = NULL; if ( uf::renderer::currentRenderMode ) { @@ -58,7 +38,12 @@ const uf::Entity& uf::Scene::getController() const { #include std::vector uf::scene::scenes; uf::Scene& uf::scene::loadScene( const std::string& name, const std::string& filename ) { - uf::Scene* scene = (uf::Scene*) uf::instantiator::instantiate( name ); + uf::Scene* scene; + if ( uf::instantiator::objects->has( name ) ) { + scene = (uf::Scene*) &uf::instantiator::instantiate( name ); + } else { + scene = new uf::Scene; + } uf::scene::scenes.push_back(scene); std::string target = name; @@ -70,13 +55,17 @@ uf::Scene& uf::scene::loadScene( const std::string& name, const std::string& fil target = match[2]; } target = uf::string::lowercase( target ); - scene->load(filename != "" ? filename : "./scenes/" + target + "/scene.json"); scene->initialize(); return *scene; } uf::Scene& uf::scene::loadScene( const std::string& name, const uf::Serializer& data ) { - uf::Scene* scene = (uf::Scene*) uf::instantiator::instantiate( name ); + uf::Scene* scene; + if ( uf::instantiator::objects->has( name ) ) { + scene = (uf::Scene*) &uf::instantiator::instantiate( name ); + } else { + scene = new uf::Scene; + } uf::scene::scenes.push_back(scene); if ( data != "" ) scene->load(data); scene->initialize(); diff --git a/ext/behaviors/base/base.cpp b/ext/behaviors/base/base.cpp new file mode 100644 index 00000000..e9fb09af --- /dev/null +++ b/ext/behaviors/base/base.cpp @@ -0,0 +1,374 @@ +#include "base.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include + +#include + +#include + +#include "../../ext.h" +#include "../../gui/gui.h" + +EXT_BEHAVIOR_REGISTER_CPP(SceneBehavior) +#define this ((uf::Scene*) &self) +void ext::SceneBehavior::initialize( uf::Object& self ) { + uf::Asset& assetLoader = this->getComponent(); + uf::Serializer& metadata = this->getComponent(); + + this->addHook( "system:Quit.%UID%", [&](const std::string& event)->std::string{ + std::cout << event << std::endl; + ext::ready = false; + return "true"; + }); + + this->addHook( "world:Music.LoadPrevious.%UID%", [&](const std::string& event)->std::string{ + uf::Serializer json = event; + + if ( metadata["previous bgm"]["filename"] == "" ) return "false"; + + std::string filename = metadata["previous bgm"]["filename"].asString(); + float timestamp = metadata["previous bgm"]["timestamp"].asFloat(); + +// std::cout << metadata["previous bgm"] << std::endl; + + uf::Audio& audio = this->getComponent(); + if ( audio.playing() ) { + metadata["previous bgm"]["filename"] = audio.getFilename(); + metadata["previous bgm"]["timestamp"] = audio.getTime(); + audio.stop(); + } + audio.load(filename); + audio.setVolume(metadata["volumes"]["bgm"].asFloat()); + audio.setTime(timestamp); + audio.play(); + + return "true"; + }); + this->addHook( "asset:Load.%UID%", [&](const std::string& event)->std::string{ + uf::Serializer json = event; + std::string filename = json["filename"].asString(); + + if ( uf::string::extension(filename) != "ogg" ) return "false"; + const uf::Audio* audioPointer = NULL; + try { audioPointer = &assetLoader.get(filename); } catch ( ... ) {} + if ( !audioPointer ) return "false"; + + uf::Audio& audio = this->getComponent(); + if ( audio.playing() ) audio.stop(); + + audio.load(filename); + audio.setVolume(metadata["volumes"]["bgm"].asFloat()); + audio.play(); + + return "true"; + }); + + this->addHook( "menu:Pause", [&](const std::string& event)->std::string{ + static uf::Timer timer(false); + if ( !timer.running() ) timer.start(); + if ( timer.elapsed().asDouble() < 1 ) return "false"; + timer.reset(); + + uf::Serializer json = event; + ext::Gui* manager = (ext::Gui*) this->findByName("Gui Manager"); + if ( !manager ) return "false"; + uf::Serializer payload; + ext::Gui* gui = (ext::Gui*) manager->findByUid( (payload["uid"] = manager->loadChild("/scenes/worldscape/gui/pause/menu.json", false)).asUInt64() ); + uf::Serializer& metadata = gui->getComponent(); + metadata["menu"] = json["menu"]; + gui->initialize(); + return payload; + }); + this->addHook( "world:Entity.LoadAsset", [&](const std::string& event)->std::string{ + uf::Serializer json = event; + + std::string asset = json["asset"].asString(); + std::string uid = json["uid"].asString(); + + assetLoader.load(asset, "asset:Load." + uid); + + return "true"; + }); + /* store viewport size */ { + metadata["window"]["size"]["x"] = uf::renderer::width; + metadata["window"]["size"]["y"] = uf::renderer::height; + + this->addHook( "window:Resized", [&](const std::string& event)->std::string{ + uf::Serializer json = event; + + pod::Vector2ui size; { + size.x = json["window"]["size"]["x"].asUInt64(); + size.y = json["window"]["size"]["y"].asUInt64(); + } + + metadata["window"] = json["window"]; + + return "true"; + }); + } + + // lock control + { + uf::Serializer payload; + payload["state"] = false; + uf::hooks.call("window:Mouse.CursorVisibility", payload); + uf::hooks.call("window:Mouse.Lock"); + } +} +void ext::SceneBehavior::tick( uf::Object& self ) { + uf::Serializer& metadata = this->getComponent(); + uf::Asset& assetLoader = this->getComponent(); + + /* check if audio needs to loop */ try { + uf::Audio& bgm = this->getComponent(); + float current = bgm.getTime(); + float end = bgm.getDuration(); + float epsilon = 0.005f; + if ( current + epsilon >= end || !bgm.playing() ) { + // intro to main transition + std::string filename = bgm.getFilename(); + filename = assetLoader.getOriginal(filename); + if ( filename.find("_intro") != std::string::npos ) { + assetLoader.load(uf::string::replace( filename, "_intro", "" ), "asset:Load." + std::to_string(this->getUid())); + // loop + } else { + bgm.setTime(0); + if ( !bgm.playing() ) bgm.play(); + } + } + } catch ( ... ) { + + } + + /* Regain control if nothing requests it */ { + ext::Gui* menu = (ext::Gui*) this->findByName("Gui: Menu"); + if ( !menu ) { + uf::Serializer payload; + payload["state"] = false; + uf::hooks.call("window:Mouse.CursorVisibility", payload); + uf::hooks.call("window:Mouse.Lock"); + } + } + + /* Print Entity Information */ { + static uf::Timer timer(false); + if ( !timer.running() ) timer.start(); + if ( uf::Window::isKeyPressed("U") && timer.elapsed().asDouble() >= 1 ) { timer.reset(); + auto& allocations = uf::Entity::memoryPool.allocations(); + uf::iostream << "Current size: " << allocations.size() << "\n"; //" | UIDs: " << uf::Entity::uids << "\n"; + uint orphans = 0; + uint empty = 0; + for ( auto& allocation : allocations ) { + uf::Entity* e = (uf::Entity*) allocation.pointer; + if ( !e->hasParent() ) { + ++orphans; + uf::iostream << "Orphan: " << e->getName() << ": " << e << "\n"; + } + } + uf::iostream << "Orphans: " << orphans << "\n"; + uf::iostream << "Empty: " << empty << "\n"; + } + } + + /* Updates Sound Listener */ { + auto& controller = this->getController(); + auto& transform = controller.getComponent>(); + + ext::oal.listener( "POSITION", { transform.position.x, transform.position.y, transform.position.z } ); + ext::oal.listener( "VELOCITY", { 0, 0, 0 } ); + ext::oal.listener( "ORIENTATION", { 0, 0, 1, 1, 0, 0 } ); + } + + if ( uf::scene::getCurrentScene().getUid() == this->getUid() ) { + /* Update lights */ if ( metadata["light"]["should"].asBool() ) { + // if ( !uf::renderer::currentRenderMode || uf::renderer::currentRenderMode->name != "" ) return; + + auto& scene = uf::scene::getCurrentScene(); + + std::vector blitters; + auto& renderMode = uf::renderer::getRenderMode("", true); + bool hasCompute = uf::renderer::hasRenderMode("C:RT:" + std::to_string(this->getUid()), true); + if ( hasCompute ) { + // auto& renderMode = uf::renderer::getRenderMode("C:RT:" + std::to_string(this->getUid()), true); + // auto* renderModePointer = (uf::renderer::ComputeRenderMode*) &renderMode; + // if ( renderModePointer->compute.initialized ) { + // blitters.push_back(&renderModePointer->compute); + // } else { + // hasCompute = false; + // } + } else if ( renderMode.getType() == "Deferred (Stereoscopic)" ) { + auto* renderModePointer = (uf::renderer::StereoscopicDeferredRenderMode*) &renderMode; + blitters.push_back(&renderModePointer->blitters.left); + blitters.push_back(&renderModePointer->blitters.right); + } else if ( renderMode.getType() == "Deferred" ) { + auto* renderModePointer = (uf::renderer::DeferredRenderMode*) &renderMode; + blitters.push_back(&renderModePointer->blitter); + } + auto& controller = scene.getController(); + auto& camera = controller.getComponent(); + + // auto& uniforms = blitter.uniforms; + struct UniformDescriptor { + struct Matrices { + alignas(16) pod::Matrix4f view[2]; + alignas(16) pod::Matrix4f projection[2]; + } matrices; + alignas(16) pod::Vector4f ambient; + struct { + alignas(8) pod::Vector2f range; + alignas(16) pod::Vector4f color; + } fog; + struct Light { + alignas(16) pod::Vector4f position; + alignas(16) pod::Vector4f color; + alignas(8) pod::Vector2i type; + alignas(16) pod::Matrix4f view; + alignas(16) pod::Matrix4f projection; + } lights; + }; + + struct SpecializationConstant { + int32_t maxLights = 32; + } specializationConstants; + + for ( size_t _ = 0; _ < blitters.size(); ++_ ) { + auto& blitter = *blitters[_]; + + uint8_t* buffer; + size_t len; + auto* shader = &blitter.material.shaders.front(); + + for ( auto& _ : blitter.material.shaders ) { + if ( _.uniforms.empty() ) continue; + auto& userdata = _.uniforms.front(); + buffer = (uint8_t*) (void*) userdata; + len = userdata.data().len; + shader = &_; + specializationConstants = _.specializationConstants.get(); + } + + if ( !buffer ) continue; + + UniformDescriptor* uniforms = (UniformDescriptor*) buffer; + for ( std::size_t i = 0; i < 2; ++i ) { + uniforms->matrices.view[i] = camera.getView( i ); + uniforms->matrices.projection[i] = camera.getProjection( i ); + } + { + uniforms->ambient.x = metadata["light"]["ambient"][0].asFloat(); + uniforms->ambient.y = metadata["light"]["ambient"][1].asFloat(); + uniforms->ambient.z = metadata["light"]["ambient"][2].asFloat(); + uniforms->ambient.w = metadata["light"]["kexp"].asFloat(); + } + { + uniforms->fog.color.x = metadata["light"]["fog"]["color"][0].asFloat(); + uniforms->fog.color.y = metadata["light"]["fog"]["color"][1].asFloat(); + uniforms->fog.color.z = metadata["light"]["fog"]["color"][2].asFloat(); + + uniforms->fog.range.x = metadata["light"]["fog"]["range"][0].asFloat(); + uniforms->fog.range.y = metadata["light"]["fog"]["range"][1].asFloat(); + } + { + std::vector entities; + std::function filter = [&]( uf::Entity* entity ) { + if ( !entity || entity->getName() != "Light" ) return; + entities.push_back(entity); + }; + for ( uf::Scene* scene : uf::renderer::scenes ) { if ( !scene ) continue; + scene->process(filter); + } + { + const pod::Vector3& position = controller.getComponent>().position; + std::sort( entities.begin(), entities.end(), [&]( const uf::Entity* l, const uf::Entity* r ){ + if ( !l ) return false; if ( !r ) return true; + if ( !l->hasComponent>() ) return false; if ( !r->hasComponent>() ) return true; + return uf::vector::magnitude( uf::vector::subtract( l->getComponent>().position, position ) ) < uf::vector::magnitude( uf::vector::subtract( r->getComponent>().position, position ) ); + } ); + } + + { + uf::Serializer& metadata = controller.getComponent(); + if ( metadata["light"]["should"].asBool() ) entities.push_back(&controller); + } + UniformDescriptor::Light* lights = (UniformDescriptor::Light*) &buffer[sizeof(UniformDescriptor) - sizeof(UniformDescriptor::Light)]; + for ( size_t i = 0; i < specializationConstants.maxLights; ++i ) { + UniformDescriptor::Light& light = lights[i]; + light.position = { 0, 0, 0, 0 }; + light.color = { 0, 0, 0, 0 }; + light.type = { 0, 0 }; + } + + blitter.material.textures.clear(); + + for ( size_t i = 0; i < specializationConstants.maxLights && i < entities.size(); ++i ) { + UniformDescriptor::Light& light = lights[i]; + uf::Entity* entity = entities[i]; + + pod::Transform<>& transform = entity->getComponent>(); + uf::Serializer& metadata = entity->getComponent(); + uf::Camera& camera = entity->getComponent(); + + light.position.x = transform.position.x; + light.position.y = transform.position.y; + light.position.z = transform.position.z; + + light.view = camera.getView(); + light.projection = camera.getProjection(); + + if ( entity == &controller ) light.position.y += 2; + + light.position.w = metadata["light"]["radius"][1].asFloat(); + + light.color.x = metadata["light"]["color"][0].asFloat(); + light.color.y = metadata["light"]["color"][1].asFloat(); + light.color.z = metadata["light"]["color"][2].asFloat(); + + light.color.w = metadata["light"]["power"].asFloat(); + + light.type.x = metadata["light"]["type"].asUInt64(); + light.type.y = metadata["light"]["shadows"]["enabled"].asBool(); + + if ( !hasCompute && entity->hasComponent() ) { + auto& renderMode = entity->getComponent(); + auto& renderTarget = renderMode.renderTarget; + + uint8_t i = 0; + for ( auto& attachment : renderTarget.attachments ) { + if ( !(attachment.usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) ) continue; + // if ( (attachment.usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) ) continue; + if ( (attachment.layout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR) ) continue; + auto& texture = blitter.material.textures.emplace_back(); + texture.aliasAttachment(attachment); + light.type.y = true; + break; + } + } else { + light.type.y = false; + } + } + } + blitter.getPipeline().update( blitter ); + shader->updateBuffer( (void*) buffer, len, 0, false ); + } + } + } +} +void ext::SceneBehavior::render( uf::Object& self ) { +} +void ext::SceneBehavior::destroy( uf::Object& self ) { +} +#undef this \ No newline at end of file diff --git a/ext/scenes/map/behavior_test.h b/ext/behaviors/base/base.h similarity index 58% rename from ext/scenes/map/behavior_test.h rename to ext/behaviors/base/base.h index 2fec26ff..b2be8b33 100644 --- a/ext/scenes/map/behavior_test.h +++ b/ext/behaviors/base/base.h @@ -1,12 +1,14 @@ #pragma once -#include "../base.h" +#include +#include +#include +#include namespace ext { - class EXT_API TestBehavior { + class EXT_API SceneBehavior { public: static void attach( uf::Object& ); - static void initialize( uf::Object& ); static void tick( uf::Object& ); static void render( uf::Object& ); diff --git a/ext/behaviors/scene_raytracing/behavior.cpp b/ext/behaviors/scene_raytracing/behavior.cpp new file mode 100644 index 00000000..cdd465e2 --- /dev/null +++ b/ext/behaviors/scene_raytracing/behavior.cpp @@ -0,0 +1,210 @@ +#include "behavior.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include + +#include + +#include + +#include "../../ext.h" +#include "../../gui/gui.h" + +EXT_BEHAVIOR_REGISTER_CPP(RayTracingSceneBehavior) +#define this ((uf::Scene*) &self) +void ext::RayTracingSceneBehavior::initialize( uf::Object& self ) { + uf::Serializer& metadata = this->getComponent(); + uf::Asset& assetLoader = this->getComponent(); + + { + auto& renderMode = this->getComponent(); + std::string name = "C:RT:" + std::to_string((int) this->getUid()); + uf::renderer::addRenderMode( &renderMode, name ); + if ( metadata["light"]["shadows"]["resolution"].isArray() ) { + renderMode.width = metadata["light"]["shadows"]["resolution"][0].asUInt64(); + renderMode.height = metadata["light"]["shadows"]["resolution"][1].asUInt64(); + } else { + renderMode.width = metadata["light"]["shadows"]["resolution"].asUInt64(); + renderMode.height = metadata["light"]["shadows"]["resolution"].asUInt64(); + } + { + struct Shape { + pod::Vector4f values; + pod::Vector3f diffuse; + float specular; + uint32_t id; + pod::Vector3ui _pad; + }; + + std::vector shapes; + { + shapes.push_back( {{1.75f, -0.5f, 0.0f, 1.0f }, { 0.0f, 1.0f, 0.0f}, 32.0f, 1} ); + shapes.push_back( {{0.0f, 1.0f, -0.5f, 1.0f }, {0.65f, 0.77f, 0.97f}, 32.0f, 1} ); + shapes.push_back( {{-1.75f, -0.75f, -0.5f, 1.25f }, { 0.9f, 0.76f, 0.46f}, 32.0f, 1} ); + } + { + float roomDim = 12.0f; + shapes.push_back( {{0.0f, 1.0f, 0.0f, roomDim}, {1.0f, 1.0f, 1.0f}, 32.0f, 2} ); + shapes.push_back( {{0.0f, -1.0f, 0.0f, roomDim}, {1.0f, 1.0f, 1.0f}, 32.0f, 2} ); + shapes.push_back( {{0.0f, 0.0f, 1.0f, roomDim}, {1.0f, 1.0f, 1.0f}, 32.0f, 2} ); + shapes.push_back( {{0.0f, 0.0f, -1.0f, roomDim}, {0.0f, 0.0f, 0.0f}, 32.0f, 2} ); + shapes.push_back( {{-1.0f, 0.0f, 0.0f, roomDim}, {1.0f, 0.0f, 0.0f}, 32.0f, 2} ); + shapes.push_back( {{1.0f, 0.0f, 0.0f, roomDim}, {0.0f, 1.0f, 0.0f}, 32.0f, 2} ); + } + renderMode.compute.device = &uf::renderer::device; + renderMode.compute.initializeBuffer( + (void*) shapes.data(), + shapes.size() * sizeof(Shape), + VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, + true + ); + } + } +} +void ext::RayTracingSceneBehavior::tick( uf::Object& self ) { + uf::Serializer& metadata = this->getComponent(); + uf::Asset& assetLoader = this->getComponent(); +#if 1 + if ( this->hasComponent() ) { + auto& renderMode = this->getComponent(); + /* Add lights to scene */ if ( renderMode.compute.initialized ) { + struct UniformDescriptor { + alignas(16) pod::Matrix4f matrices[2]; + alignas(16) pod::Vector4f ambient; + struct { + alignas(8) pod::Vector2f range; + alignas(16) pod::Vector4f color; + } fog; + struct Light { + alignas(16) pod::Vector4f position; + alignas(16) pod::Vector4f color; + alignas(8) pod::Vector2i type; + alignas(16) pod::Matrix4f view; + alignas(16) pod::Matrix4f projection; + } lights; + }; + + struct SpecializationConstant { + int32_t eyes = 2; + int32_t maxLights = 16; + } specializationConstants; + + auto& shader = renderMode.compute.material.shaders.front(); + specializationConstants = shader.specializationConstants.get(); + + struct PushConstant { + uint32_t marchingSteps; + uint32_t rayBounces; + float shadowFactor; + float reflectionStrength; + float reflectionFalloff; + }; + auto& pushConstant = shader.pushConstants.front().get(); + pushConstant.marchingSteps = metadata["rays"]["marching steps"].asUInt64(); + pushConstant.rayBounces = metadata["rays"]["ray bounces"].asUInt64(); + pushConstant.shadowFactor = metadata["rays"]["shadow factor"].asFloat(); + pushConstant.reflectionStrength = metadata["rays"]["reflection"]["strength"].asFloat(); + pushConstant.reflectionFalloff = metadata["rays"]["reflection"]["falloff"].asFloat(); + + auto& scene = uf::scene::getCurrentScene(); + auto& controller = scene.getController(); + auto& camera = controller.getComponent(); + auto& transform = controller.getComponent>(); + + auto& userdata = shader.uniforms.front(); + size_t uniforms_len = userdata.data().len; + uint8_t* uniforms_buffer = (uint8_t*) (void*) userdata; + UniformDescriptor* uniforms = (UniformDescriptor*) uniforms_buffer; + for ( size_t i = 0; i < 2; ++i ) { + uniforms->matrices[i] = uf::matrix::inverse( camera.getProjection(i) * camera.getView(i) ); + } + + { + uniforms->ambient.x = metadata["light"]["ambient"][0].asFloat(); + uniforms->ambient.y = metadata["light"]["ambient"][1].asFloat(); + uniforms->ambient.z = metadata["light"]["ambient"][2].asFloat(); + uniforms->ambient.w = metadata["light"]["kexp"].asFloat(); + } + { + uniforms->fog.color.x = metadata["light"]["fog"]["color"][0].asFloat(); + uniforms->fog.color.y = metadata["light"]["fog"]["color"][1].asFloat(); + uniforms->fog.color.z = metadata["light"]["fog"]["color"][2].asFloat(); + + uniforms->fog.range.x = metadata["light"]["fog"]["range"][0].asFloat(); + uniforms->fog.range.y = metadata["light"]["fog"]["range"][1].asFloat(); + } + + std::vector entities; + std::function filter = [&]( uf::Entity* entity ) { + if ( !entity || entity->getName() != "Light" ) return; + entities.push_back(entity); + }; + for ( uf::Scene* scene : uf::renderer::scenes ) { if ( !scene ) continue; + scene->process(filter); + } + { + const pod::Vector3& position = controller.getComponent>().position; + std::sort( entities.begin(), entities.end(), [&]( const uf::Entity* l, const uf::Entity* r ){ + if ( !l ) return false; if ( !r ) return true; + if ( !l->hasComponent>() ) return false; if ( !r->hasComponent>() ) return true; + return uf::vector::magnitude( uf::vector::subtract( l->getComponent>().position, position ) ) < uf::vector::magnitude( uf::vector::subtract( r->getComponent>().position, position ) ); + } ); + } + + { + uf::Serializer& metadata = controller.getComponent(); + if ( metadata["light"]["should"].asBool() ) entities.push_back(&controller); + } + UniformDescriptor::Light* lights = (UniformDescriptor::Light*) &uniforms_buffer[sizeof(UniformDescriptor) - sizeof(UniformDescriptor::Light)]; + for ( size_t i = 0; i < specializationConstants.maxLights && i < entities.size(); ++i ) { + UniformDescriptor::Light& light = lights[i]; + uf::Entity* entity = entities[i]; + + pod::Transform<>& transform = entity->getComponent>(); + uf::Serializer& metadata = entity->getComponent(); + uf::Camera& camera = entity->getComponent(); + + light.position.x = transform.position.x; + light.position.y = transform.position.y; + light.position.z = transform.position.z; + + if ( entity == &controller ) light.position.y += 2; + + light.position.w = metadata["light"]["radius"][1].asFloat(); + + light.color.x = metadata["light"]["color"][0].asFloat(); + light.color.y = metadata["light"]["color"][1].asFloat(); + light.color.z = metadata["light"]["color"][2].asFloat(); + + light.color.w = metadata["light"]["power"].asFloat(); + } + + + shader.updateBuffer( (void*) uniforms_buffer, uniforms_len, 0, false ); + } + } +#endif +} +void ext::RayTracingSceneBehavior::render( uf::Object& self ) { +} +void ext::RayTracingSceneBehavior::destroy( uf::Object& self ) { + if ( this->hasComponent() ) { + auto& renderMode = this->getComponent(); + uf::renderer::removeRenderMode( &renderMode, false ); + } +} +#undef this \ No newline at end of file diff --git a/ext/behaviors/scene_raytracing/behavior.h b/ext/behaviors/scene_raytracing/behavior.h new file mode 100644 index 00000000..d020acb0 --- /dev/null +++ b/ext/behaviors/scene_raytracing/behavior.h @@ -0,0 +1,17 @@ +#pragma once + +#include +#include +#include +#include + +namespace ext { + class EXT_API RayTracingSceneBehavior { + public: + static void attach( uf::Object& ); + static void initialize( uf::Object& ); + static void tick( uf::Object& ); + static void render( uf::Object& ); + static void destroy( uf::Object& ); + }; +} \ No newline at end of file diff --git a/ext/scenes/map/behavior_test.cpp b/ext/scenes/map/behavior_test.cpp deleted file mode 100644 index 7fbbb218..00000000 --- a/ext/scenes/map/behavior_test.cpp +++ /dev/null @@ -1,35 +0,0 @@ -#include "behavior_test.h" - -#include - -#define this (&self) -void ext::TestBehavior::attach( uf::Object& self ) { - self.addBehavior({ - .type = uf::Behaviors::getType(), - .initialize = [&]() { - ext::TestBehavior::initialize( self ); - }, - .tick = [&]() { - ext::TestBehavior::tick( self ); - }, - .render = [&]() { - ext::TestBehavior::render( self ); - }, - .destroy = [&]() { - ext::TestBehavior::destroy( self ); - }, - }); -} -void ext::TestBehavior::initialize( uf::Object& self ) { - -} -void ext::TestBehavior::tick( uf::Object& self ) { - -} -void ext::TestBehavior::render( uf::Object& self ) { - -} -void ext::TestBehavior::destroy( uf::Object& self ) { - -} -#undef this \ No newline at end of file diff --git a/ext/scenes/map/scene.cpp b/ext/scenes/map/scene.cpp index 7436876d..dc06e099 100644 --- a/ext/scenes/map/scene.cpp +++ b/ext/scenes/map/scene.cpp @@ -22,19 +22,9 @@ #include "../../ext.h" #include "../../gui/gui.h" -#include "behavior_test.h" - EXT_OBJECT_REGISTER_CPP(TestScene_Map) void ext::TestScene_Map::initialize() { ext::Scene::initialize(); - - { - uf::Object* object = new uf::Object; - this->addChild(*object); - ext::TestBehavior::attach( *object ); - - object->initialize(); - } } void ext::TestScene_Map::render() { diff --git a/ext/scenes/raytrace/scene.cpp b/ext/scenes/raytrace/scene.cpp index 30b65be6..aa11be29 100644 --- a/ext/scenes/raytrace/scene.cpp +++ b/ext/scenes/raytrace/scene.cpp @@ -21,7 +21,7 @@ #include "../../ext.h" #include "../../gui/gui.h" -EXT_OBJECT_REGISTER_CPP(TestScene_RayTracing) +// EXT_OBJECT_REGISTER_CPP(TestScene_RayTracing) void ext::TestScene_RayTracing::initialize() { ext::Scene::initialize(); uf::Serializer& metadata = this->getComponent();