// Copyright (c) 2022 Dominic Masters // // This software is released under the MIT License. // https://opensource.org/licenses/MIT #pragma once #include "scene/SceneItemComponent.hpp" #include "visualnovel/ui/VisualNovelTextbox.hpp" #include "visualnovel/ui/VisualNovelFader.hpp" namespace Dawn { class IVisualNovelEvent; class VisualNovelManager : public SceneItemComponent { private: IVisualNovelEvent* currentEvent = nullptr; public: UICanvas *uiCanvas = nullptr; VisualNovelTextbox *textBox = nullptr; VisualNovelFader *fader = nullptr; AudioSource *audioBackground = nullptr; AudioSource *audioCharacter = nullptr; /** Event listener for unpaused scene updates. */ void onUnpausedUpdate(); /** * Constructs a visual novel manager, scene item component. * * @param item Item that the VN manager belongs to. */ VisualNovelManager(SceneItem *item); /** * Sets the currently active visual novel event. This is assumed to be * the only way to handle events (no multiples currently). * * @param event Event to set. */ template T * setEvent(T *event) { auto oldCurrent = this->currentEvent; this->currentEvent = event; if(this->hasInitialized && event != nullptr) event->start(oldCurrent); delete oldCurrent; return event; } /** * Override to the SceneItemComponent on start event. * */ void onStart() override; /** * Dispose / Cleanup the VN manager. * */ ~VisualNovelManager(); friend class IVisualNovelEvent; }; class IVisualNovelEvent { protected: VisualNovelManager *manager; IVisualNovelEvent *doNext = nullptr; bool_t hasStarted = false; virtual void onStart(IVisualNovelEvent *previous) = 0; virtual bool_t onUpdate() = 0; virtual void onEnd() = 0; public: IVisualNovelEvent(VisualNovelManager *manager); /** * Chains an event to be executed after this event has finished. * * @param next Event to process next. * @return Whatever you pass in to next. */ template T * then(T *next) { this->doNext = next; return next; } /** * Begins this visual novel event, internally updates some flags and * calls the event to do its own start logic. * * @param previous Previous event, this is for doing logic based chains. */ void start(IVisualNovelEvent *previous); /** * Performs a tick on this event. The event can then decide whether or not * it has finished processing. * * @return True if the event is still active, otherwise false. */ bool_t update(); /** * End this current event. Returns the "next event" to process. Most of * the events can handle this with the simple ->then() chaining, but some * events may chose to do complex if-style logic. * * @return Event to run next. */ IVisualNovelEvent * end(); /** * Dispose the VN event. */ virtual ~IVisualNovelEvent(); friend class VisualNovelManager; }; }