Skip to content

Instantly share code, notes, and snippets.

@urnenfeld
Last active December 26, 2020 01:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save urnenfeld/8dd867fa2f2780446d90c8736581377e to your computer and use it in GitHub Desktop.
Save urnenfeld/8dd867fa2f2780446d90c8736581377e to your computer and use it in GitHub Desktop.
EventScheduler class storing events. Expecting to dispatch them in E_UPDATE through ProceesTimedEvents()
template <class T, class ... Args> UniquePtr<T> MakeUniqueFromList(Args && ... args)
{
return UniquePtr<T>(new T {std::forward<Args>(args)...});
}
class EventScheduler {
public:
typedef struct {
WeakPtr<Object> sender;
StringHash eventType;
VariantMap eventData;
int time;
} tTimedEvent;
void SendEvent(StringHash eventType, VariantMap& eventData, unsigned time, WeakPtr<Object> sender)
{
// No smart pointer
// tTimedEvent* timedEvent = new tTimedEvent { sender, eventType, eventData, static_cast<int>(time) } ;
// Single statement avoid copy with EmplaceBack & Push
// newTimedEvents_.Push(MakeUniqueFromList<tTimedEvent>(sender, eventType, eventData, static_cast<int>(time)));
// newTimedEvents_.EmplaceBack(MakeUniqueFromList<tTimedEvent>(sender, eventType, eventData, static_cast<int>(time)));
// Emulating MakeUniqueFromList
newTimedEvents_.Push(UniquePtr<tTimedEvent>(new tTimedEvent {sender, eventType, eventData, static_cast<int>(time)}));
// With moving sematincs, no problem messing initial timeEntry
// UniquePtr<tTimedEvent> timeEntry( new tTimedEvent {sender, eventType, eventData, static_cast<int>(time)} );
// newTimedEvents_.Push(std::move(timeEntry));
}
void SendEvent(StringHash eventType, unsigned time, WeakPtr<Object> sender)
{
VariantMap noEventData;
// No smart pointer
// tTimedEvent* timedEvent = new tTimedEvent { sender, eventType, noEventData, static_cast<int>(time) } ;
// Single statement avoid copy
newTimedEvents_.Push(MakeUniqueFromList<tTimedEvent>(sender, eventType, noEventData, static_cast<int>(time)));
// With moving sematincs, no problem messing initial timeEntry
// UniquePtr<tTimedEvent> timeEntry( new tTimedEvent {sender, eventType, noEventData, static_cast<int>(time)} );
// newTimedEvents_.Push(std::move(timeEntry));
}
void ProceesTimedEvents()
{
int timeElapsed = static_cast<int>(time_.GetMSec(true));
// Processed events could introduce new schedules, they would be done in the "new" list, fusion them before processing.
if (newTimedEvents_.Size() > 0) {
for (Vector<UniquePtr<tTimedEvent>>::Iterator iter = newTimedEvents_.Begin(); iter != newTimedEvents_.End(); )
{
timedEvents_.Push(std::move(*(iter)));
iter = newTimedEvents_.Erase(iter);
}
}
if (timedEvents_.Size() > 0) {
for (Vector<UniquePtr<tTimedEvent>>::Iterator iter = timedEvents_.Begin(); iter != timedEvents_.End(); )
{
UniquePtr<tTimedEvent>& timedEvent = *(iter); // Alternative use (*(iter)) instead of intermediate uniq pointer
// XXX: Moving here messes the iterator
// UniquePtr<tTimedEvent> timedEvent = std::move(*(iter));
timedEvent->time -= timeElapsed;
if (timedEvent->time < 0) {
if (timedEvent->sender) {
timedEvent->sender->SendEvent(timedEvent->eventType, timedEvent->eventData);
}
iter = timedEvents_.Erase(iter);
// delete timedEvent;
} else {
++iter;
}
}
}
}
private:
Vector<UniquePtr<tTimedEvent>> timedEvents_;
Vector<UniquePtr<tTimedEvent>> newTimedEvents_;
Timer time_;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment