Panagiotis Christopoulos Charitos 13 lat temu
rodzic
commit
dd45ec5550

+ 38 - 35
include/anki/event/Event.h

@@ -1,81 +1,84 @@
 #ifndef ANKI_EVENT_EVENT_H
 #define ANKI_EVENT_EVENT_H
 
+#include "anki/scene/Common.h"
+#include "anki/util/Flags.h"
+
 namespace anki {
 
-/// Abstract class for all events. All Event derived classes should be copy-able
-/// In order to recycle the events and save the mallocs
-class Event
+// Forward
+class EventManager;
+
+/// Abstract class for all events
+class Event: public Flags<U8>
 {
+	friend class EventManager;
+
 public:
-	/// The event type enum
-	enum EventType
+	/// Event flags
+	enum EventFlags
 	{
-		ET_SCENE_COLOR,
-		ET_MAIN_RENDERER_PPS_HDR,
-		ET_COUNT
+		EF_NONE = 0,
+		EF_REANIMATE = 1 << 0
 	};
 
-	/// Constructor
-	Event(EventType type, float startTime, float duration);
+	/// @name Constructors/Destructor
+	/// @{
 
-	/// Copy constructor
-	Event(const Event& b)
-	{
-		*this = b;
-	}
+	/// Constructor
+	Event(F32 startTime, F32 duration, EventManager* manager, 
+		U8 flags = EF_NONE);
 
 	virtual ~Event();
+	/// @}
 
 	/// @name Accessors
 	/// @{
-	float getStartTime() const
+	F32 getStartTime() const
 	{
 		return startTime;
 	}
 
-	float getDuration() const
+	F32 getDuration() const
 	{
 		return duration;
 	}
 
-	EventType getEventType() const
-	{
-		return type;
-	}
-
-	bool isDead(float crntTime) const
+	Bool isDead(F32 crntTime) const
 	{
 		return crntTime >= startTime + duration;
 	}
-	/// @}
 
-	/// Copy
-	Event& operator=(const Event& b);
+	SceneAllocator<U8> getSceneAllocator() const;
+	SceneAllocator<U8> getSceneFrameAllocator() const;
+	/// @}
 
+	/// This method should be implemented by the derived classes
 	/// @param[in] prevUpdateTime The time of the previous update (sec)
 	/// @param[in] crntTime The current time (sec)
-	void update(float prevUpdateTime, float crntTime);
+	virtual void update(F32 prevUpdateTime, F32 crntTime) = 0;
 
 protected:
-	/// This method should be implemented by the derived classes
-	virtual void updateSp(float prevUpdateTime, float crntTime) = 0;
-
 	/// Linear interpolation between values
 	/// @param[in] from Starting value
 	/// @param[in] to Ending value
 	/// @param[in] delta The percentage from the from "from" value. Values
-	/// from [0.0, 1.0]
+	///                  from [0.0, 1.0]
 	template<typename Type>
-	static Type interpolate(const Type& from, const Type& to, float delta)
+	static Type interpolate(const Type& from, const Type& to, F32 delta)
 	{
+		ANKI_ASSERT(delta >= 0 && delta <= 1.0);
 		return from * (1.0 - delta) + to * delta;
 	}
 
+	/// Return the delta between current time and when the event started
+	/// @return A number [0.0, 1.0]
+	F32 getDelta(F32 crntTime) const;
+
 private:
-	EventType type; ///< Self explanatory
-	float startTime; ///< The time the event will start. Eg 23:00
-	float duration; ///< The duration of the event
+	F32 startTime; ///< The time the event will start. Eg 23:00
+	F32 duration; ///< The duration of the event
+	EventManager* manager = nullptr; ///< Keep it here to access allocators etc
 };
 
 } // end namespace

+ 29 - 38
include/anki/event/EventManager.h

@@ -2,63 +2,54 @@
 #define ANKI_EVENT_MANAGER_H
 
 #include "anki/event/Event.h"
-#include "anki/util/Singleton.h"
 #include "anki/util/Vector.h"
 #include "anki/util/StdTypes.h"
+#include "anki/scene/Common.h"
+#include "anki/math/Math.h"
 
 namespace anki {
 
+// Forward
+class SceneGraph;
+class SceneAmbientColorEvent;
+
 /// This manager creates the events ands keeps tracks of them
 class EventManager
 {
 public:
-	typedef PtrVector<Event> EventsContainer;
+	typedef SceneVector<std::shared_ptr<Event>> EventsContainer;
 
-	EventManager();
+	EventManager(SceneGraph* scene);
 	~EventManager();
 
-	/// Create a new event
-	template<typename EventClass>
-	EventClass& createEvent(const EventClass& event);
+	/// @name Accessors
+	/// @{
+	SceneAllocator<U8> getSceneAllocator() const;
+	SceneAllocator<U8> getSceneFrameAllocator() const;
+	/// @}
+
+	/// @name Creators
+	/// @{
+
+	std::shared_ptr<Event> newSceneAmbientColorEvent(
+		F32 startTime, F32 duration, const Vec3& finalColor);
+	/// @}
 
 	/// Update
-	void updateAllEvents(float prevUpdateTime, float crntTime);
+	void updateAllEvents(F32 prevUpdateTime, F32 crntTime);
 
-private:
-	static const size_t MAX_EVENTS_SIZE = 1000;
+	/// Remove an event from the container
+	void unregisterEvent(Event* event);
 
+private:
+	SceneGraph* scene = nullptr;
 	EventsContainer events;
-	float prevUpdateTime;
-	float crntTime;
+	F32 prevUpdateTime;
+	F32 crntTime;
 
-	/// Find a dead event of a certain type
-	EventsContainer::iterator findADeadEvent(Event::EventType type);
+	std::shared_ptr<Event> registerEvent(Event* event);
 };
 
-/// The singleton EventManager
-typedef Singleton<EventManager> EventManagerSingleton;
-
-//==============================================================================
-template<typename EventClass>
-EventClass& EventManager::createEvent(const EventClass& event)
-{
-	EventsContainer::iterator it = findADeadEvent(event.getEventType());
-	EventClass* ev;
-
-	if(it == events.end()) // No dead event found
-	{
-		ev = new EventClass(event);
-		events.push_back(ev);
-	}
-	else // Re-use a dead event
-	{
-		ev = &static_cast<EventClass&>(*it);
-		*ev = event;
-	}
-
-	return *ev;
-}
-
-} // end namespace
+} // end namespace anki
 
 #endif

+ 29 - 0
include/anki/event/LightEvent.h

@@ -0,0 +1,29 @@
+#ifndef ANKI_EVENT_LIGHT_EVENT_H
+#define ANKI_EVENT_LIGHT_EVENT_H
+
+#include "anki/event/Event.h"
+
+namespace anki {
+
+/// @addtogroup event
+/// @{
+
+/// Light event
+class LightEvent: public Event
+{
+public:
+	/// @name Constructors/Destructor
+	/// @{
+
+	/// Constructor
+	LightEvent(F32 startTime, F32 duration, EventManager* manager,
+		const std::smart_ptr<SceneNode>& lightSn,
+		const F32* radiusFrom, const F32* radiusTo);
+	/// @}
+};
+
+/// @}
+
+} // end namespace anki
+
+#endif

+ 4 - 0
include/anki/event/MainRendererPpsHdrEvent.h

@@ -6,6 +6,8 @@
 
 namespace anki {
 
+#if 0
+
 /// Change the HDR properties
 class MainRendererPpsHdrEvent: public Event
 {
@@ -35,6 +37,8 @@ private:
 	void updateSp(float prevUpdateTime, float crntTime);
 };
 
+#endif
+
 } // end namespace
 
 #endif

+ 31 - 0
include/anki/event/SceneAmbientColorEvent.h

@@ -0,0 +1,31 @@
+#ifndef ANKI_EVENT_SCENE_AMBIENT_COLOR_EVENT_H
+#define ANKI_EVENT_SCENE_AMBIENT_COLOR_EVENT_H
+
+#include "anki/event/Event.h"
+#include "anki/math/Math.h"
+
+namespace anki {
+
+// Forward
+class SceneGraph;
+
+/// Change the scene color
+class SceneAmbientColorEvent: public Event
+{
+public:
+	/// Constructor
+	SceneAmbientColorEvent(F32 startTime, F32 duration, EventManager* manager,
+		const Vec3& finalColor, SceneGraph* scene);
+
+	/// Implements Event::update
+	void update(F32 prevUpdateTime, F32 crntTime);
+
+private:
+	Vec3 originalColor; ///< Original scene color. The constructor sets it
+	Vec3 finalColor;
+	SceneGraph* scene = nullptr;
+};
+
+} // end namespace anki
+
+#endif

+ 0 - 33
include/anki/event/SceneColorEvent.h

@@ -1,33 +0,0 @@
-#ifndef ANKI_EVENT_SCENE_COLOR_EVENT_H
-#define ANKI_EVENT_SCENE_COLOR_EVENT_H
-
-#include "anki/event/Event.h"
-#include "anki/math/Math.h"
-
-namespace anki {
-
-/// Change the scene color
-class SceneColorEvent: public Event
-{
-public:
-	/// Constructor
-	SceneColorEvent(float startTime, float duration,
-		const Vec3& finalColor);
-
-	/// Copy constructor
-	SceneColorEvent(const SceneColorEvent& b);
-
-	/// Copy
-	SceneColorEvent& operator=(const SceneColorEvent& b);
-
-private:
-	Vec3 originalColor; ///< Original scene color. The constructor sets it
-	Vec3 finalColor;
-
-	/// Implements Event::updateSp
-	void updateSp(float prevUpdateTime, float crntTime);
-};
-
-} // end namespace
-
-#endif

+ 12 - 0
include/anki/scene/Common.h

@@ -55,6 +55,18 @@ using SceneVector = Vector<T, SceneAllocator<T>>;
 template<typename T>
 using SceneFrameVector = Vector<T, SceneFrameAllocator<T>>;
 
+/// Deleter for shared pointers
+template<typename T>
+struct SceneSharedPtrDeleter
+{
+	void operator()(T* x)
+	{
+		ANKI_ASSERT(x);
+		SceneAllocator<U8> alloc = x->getSceneAllocator();
+		//ANKI_DELETE(x, alloc);
+	}
+};
+
 /// @}
 
 } // end namespace anki

+ 6 - 2
include/anki/scene/SceneGraph.h

@@ -4,11 +4,13 @@
 #include "anki/scene/Common.h"
 #include "anki/scene/SceneNode.h"
 #include "anki/scene/Visibility.h"
-#include "anki/scene/Sector.h"
+#include "anki/core/Timestamp.h"
 #include "anki/math/Math.h"
 #include "anki/util/Singleton.h"
-#include "anki/core/Timestamp.h"
+
+#include "anki/scene/Sector.h"
 #include "anki/physics/PhysWorld.h"
+#include "anki/event/EventManager.h"
 
 namespace anki {
 
@@ -150,6 +152,8 @@ private:
 
 	SectorGroup sectorGroup;
 
+	EventManager events;
+
 	/// Put a node in the appropriate containers
 	void registerNode(SceneNode* node);
 	void unregisterNode(SceneNode* node);

+ 27 - 17
src/event/Event.cpp

@@ -1,36 +1,46 @@
 #include "anki/event/Event.h"
+#include "anki/event/EventManager.h"
 #include "anki/util/Assert.h"
 
 namespace anki {
 
 //==============================================================================
-Event::Event(EventType type_, float startTime_, float duration_)
-	: type(type_), startTime(startTime_), duration(duration_)
-{}
+Event::Event(F32 startTime_, F32 duration_, EventManager* manager_, U8 flags)
+	:	Flags<U8>(flags), 
+		startTime(startTime_),
+		duration(duration_),
+		manager(manager_)
+{
+	ANKI_ASSERT(manager);
+}
 
 //==============================================================================
-Event& Event::operator=(const Event& b)
+SceneAllocator<U8> Event::getSceneAllocator() const
 {
-	type = b.type;
-	startTime = b.startTime;
-	duration = b.duration;
-	return *this;
+	return manager->getSceneAllocator();
 }
 
 //==============================================================================
-Event::~Event()
-{}
+SceneAllocator<U8> Event::getSceneFrameAllocator() const
+{
+	return manager->getSceneFrameAllocator();
+}
 
 //==============================================================================
-void Event::update(float prevUpdateTime, float crntTime)
+Event::~Event()
 {
-	ANKI_ASSERT(!isDead(crntTime));
-
-	// Dont update if its not the right time yet
-	if(startTime <= crntTime)
+	if(manager)
 	{
-		updateSp(prevUpdateTime, crntTime);
+		manager->unregisterEvent(this);
 	}
 }
 
-} // end namespace
+//==============================================================================
+F32 Event::getDelta(F32 crntTime) const
+{
+	F32 d = crntTime - startTime; // delta
+	F32 dp = d / duration; // delta as persentage
+	return dp;
+}
+
+} // end namespace anki

+ 78 - 16
src/event/EventManager.cpp

@@ -1,9 +1,12 @@
 #include "anki/event/EventManager.h"
+#include "anki/event/SceneAmbientColorEvent.h"
+#include "anki/scene/SceneGraph.h"
 
 namespace anki {
 
 //==============================================================================
-EventManager::EventManager()
+EventManager::EventManager(SceneGraph* scene_)
+	: scene(scene_), events(getSceneAllocator())
 {}
 
 //==============================================================================
@@ -11,37 +14,96 @@ EventManager::~EventManager()
 {}
 
 //==============================================================================
-void EventManager::updateAllEvents(float prevUpdateTime_, float crntTime_)
+SceneAllocator<U8> EventManager::getSceneAllocator() const
 {
-	prevUpdateTime = prevUpdateTime_;
-	crntTime = crntTime_;
+	return scene->getAllocator();
+}
+
+//==============================================================================
+SceneAllocator<U8> EventManager::getSceneFrameAllocator() const
+{
+	return scene->getFrameAllocator();
+}
+
+//==============================================================================
+std::shared_ptr<Event> EventManager::registerEvent(Event* event)
+{
+	ANKI_ASSERT(event);
+	SceneSharedPtrDeleter<Event> deleter;
+	std::shared_ptr<Event> ptr(event, deleter, getSceneAllocator());
+	events.push_back(ptr);
+	return ptr;
+}
 
-	for(Event* event : events)
+//==============================================================================
+void EventManager::unregisterEvent(Event* event)
+{
+	ANKI_ASSERT(event);
+	
+	EventsContainer::iterator it = events.begin();
+	for(; it != events.end(); it++)
 	{
-		if(!event->isDead(crntTime))
+		if(it->get() == event)
 		{
-			event->update(prevUpdateTime, crntTime);
+			break;
 		}
 	}
+
+	ANKI_ASSERT(it == events.end());
+	events.erase(it);
 }
 
 //==============================================================================
-EventManager::EventsContainer::iterator EventManager::
-	findADeadEvent(Event::EventType type)
+void EventManager::updateAllEvents(F32 prevUpdateTime_, F32 crntTime_)
 {
-	EventsContainer::iterator it = events.begin();
+	prevUpdateTime = prevUpdateTime_;
+	crntTime = crntTime_;
+
+	// Container to gather dead events
+	SceneFrameVector<EventsContainer::iterator> forDeletion(
+		getSceneFrameAllocator());
+	// XXX reserve on vector
 
-	while(it != events.end())
+	EventsContainer::iterator it = events.begin();
+	for(; it != events.end(); it++)
 	{
-		Event* event = *it;
-		if(event->isDead(crntTime) && event->getEventType() == type)
+		std::shared_ptr<Event>& pevent = *it;
+
+		// If not dead update it
+		if(!pevent->isDead(crntTime))
 		{
-			break;
+			if(pevent->getStartTime() <= crntTime)
+			{
+				pevent->update(prevUpdateTime, crntTime);
+			}
+		}
+		else
+		{
+			if(pevent->flagsEnabled(Event::EF_REANIMATE))
+			{
+				pevent->startTime = prevUpdateTime;
+				pevent->update(prevUpdateTime, crntTime);
+			}
+			else
+			{
+				forDeletion.push_back(it);
+			}
 		}
-		++it;
 	}
 
-	return it;
+	// Kick the dead events out
+	for(EventsContainer::iterator& it : forDeletion)
+	{
+		events.erase(it);
+	}
+}
+
+//==============================================================================
+std::shared_ptr<Event> EventManager::newSceneAmbientColorEvent(
+	F32 startTime, F32 duration, const Vec3& finalColor)
+{
+	return registerEvent(new SceneAmbientColorEvent(startTime, duration, this, 
+		finalColor, scene));
 }
 
 } // end namespace anki

+ 4 - 0
src/event/MainRendererPpsHdrEvent.cpp

@@ -3,6 +3,8 @@
 
 namespace anki {
 
+#if 0
+
 //==============================================================================
 MainRendererPpsHdrEvent::MainRendererPpsHdrEvent(float startTime,
 	float duration,
@@ -58,4 +60,6 @@ void MainRendererPpsHdrEvent::updateSp(float /*prevUpdateTime*/, float crntTime)
 		finalData.blurringDist, dp));*/
 }
 
+#endif
+
 } // end namespace

+ 25 - 0
src/event/SceneAmbientColorEvent.cpp

@@ -0,0 +1,25 @@
+#include "anki/event/SceneAmbientColorEvent.h"
+#include "anki/scene/SceneGraph.h"
+#include "anki/core/Logger.h"
+
+namespace anki {
+
+//==============================================================================
+SceneAmbientColorEvent::SceneAmbientColorEvent(F32 startTime, F32 duration, 
+	EventManager* manager, const Vec3& finalColor_, SceneGraph* scene_)
+	:	Event(startTime, duration, manager), 
+		finalColor(finalColor_), 
+		scene(scene_)
+{
+	ANKI_ASSERT(scene);
+	originalColor = scene->getAmbientColor();
+}
+
+//==============================================================================
+void SceneAmbientColorEvent::update(F32 /*prevUpdateTime*/, F32 crntTime)
+{
+	scene->setAmbientColor(
+		interpolate(originalColor, finalColor, getDelta(crntTime)));
+}
+
+} // end namespace anki

+ 0 - 41
src/event/SceneColorEvent.cpp

@@ -1,41 +0,0 @@
-#include "anki/event/SceneColorEvent.h"
-#include "anki/scene/SceneGraph.h"
-#include "anki/core/Logger.h"
-
-namespace anki {
-
-//==============================================================================
-SceneColorEvent::SceneColorEvent(float startTime, float duration,
-	const Vec3& finalColor_)
-	: Event(ET_SCENE_COLOR, startTime, duration), finalColor(finalColor_)
-{
-	originalColor = SceneGraphSingleton::get().getAmbientColor();
-}
-
-//==============================================================================
-SceneColorEvent::SceneColorEvent(const SceneColorEvent& b)
-	: Event(ET_SCENE_COLOR, 0.0, 0.0)
-{
-	*this = b;
-}
-
-//==============================================================================
-SceneColorEvent& SceneColorEvent::operator=(const SceneColorEvent& b)
-{
-	Event::operator=(b);
-	originalColor = b.originalColor;
-	finalColor = b.finalColor;
-	return *this;
-}
-
-//==============================================================================
-void SceneColorEvent::updateSp(float /*prevUpdateTime*/, float crntTime)
-{
-	float d = crntTime - getStartTime(); // delta
-	float dp = d / float(getDuration()); // delta as persentage
-
-	SceneGraphSingleton::get().setAmbientColor(
-		interpolate(originalColor, finalColor, dp));
-}
-
-} // end namespace anki

+ 2 - 1
src/scene/SceneGraph.cpp

@@ -95,7 +95,8 @@ SceneGraph::SceneGraph()
 	:	alloc(ANKI_CFG_SCENE_ALLOCATOR_SIZE),
 		frameAlloc(ANKI_CFG_SCENE_FRAME_ALLOCATOR_SIZE),
 		nodes(alloc),
-		sectorGroup(this)
+		sectorGroup(this),
+		events(this)
 {
 	nodes.reserve(ANKI_CFG_SCENE_NODES_AVERAGE_COUNT);
 

+ 0 - 3
src/script/event/EventManager.cpp

@@ -1,6 +1,3 @@
 #include "anki/script/Common.h"
 #include "anki/event/EventManager.h"
 
-#include "anki/event/SceneColorEvent.h"
-#include "anki/event/MainRendererPpsHdrEvent.h"
-

+ 3 - 0
src/script/event/SceneAmbientColorEvent.cpp

@@ -0,0 +1,3 @@
+#include "anki/script/Common.h"
+#include "anki/event/SceneAmbientColorEvent.h"
+

+ 0 - 3
src/script/event/SceneColorEvent.cpp

@@ -1,3 +0,0 @@
-#include "anki/script/Common.h"
-#include "anki/event/SceneColorEvent.h"
-

+ 1 - 2
testapp/Main.cpp

@@ -22,7 +22,6 @@
 #include "anki/util/HighRezTimer.h"
 #include "anki/resource/Skin.h"
 #include "anki/event/EventManager.h"
-#include "anki/event/SceneColorEvent.h"
 #include "anki/event/MainRendererPpsHdrEvent.h"
 #include "anki/resource/ShaderProgramPrePreprocessor.h"
 #include "anki/resource/Material.h"
@@ -436,7 +435,7 @@ void mainLoop()
 		mainLoopExtra();
 		SceneGraphSingleton::get().update(
 			prevUpdateTime, crntTime, MainRendererSingleton::get());
-		EventManagerSingleton::get().updateAllEvents(prevUpdateTime, crntTime);
+		//EventManagerSingleton::get().updateAllEvents(prevUpdateTime, crntTime);
 		MainRendererSingleton::get().render(SceneGraphSingleton::get());
 
 		if(InputSingleton::get().getKey(KC_ESCAPE))