1 ///////////////////////////////////////////////////////////////////////////////
2 //            Copyright (C) 2004-2011 by The Allacrost Project
3 //            Copyright (C) 2012-2016 by Bertram (Valyria Tear)
4 //                         All Rights Reserved
5 //
6 // This code is licensed under the GNU GPL version 2. It is free software
7 // and you may modify it and/or redistribute it under the terms of this license.
8 // See https://www.gnu.org/copyleft/gpl.html for details.
9 ///////////////////////////////////////////////////////////////////////////////
10 
11 #ifndef __MAP_EVENT_SUPERVISOR_HEADER__
12 #define __MAP_EVENT_SUPERVISOR_HEADER__
13 
14 #include "modes/map/map_events.h"
15 
16 namespace vt_map
17 {
18 
19 namespace private_map
20 {
21 
22 /** ****************************************************************************
23 *** \brief Manages, processes, and launches map events
24 ***
25 *** The EventSupervisor serves as an assistant to the MapMode class, much like the
26 *** other map supervisor classes. As such, this class is only created as a member
27 *** of the MapMode class. The first responsibility of the EventSupervisor is to
28 *** retain all of the MapEvent objects that have been created. The second responsibility
29 *** of this class is to initialize and begin the first event in a n-length chain
30 *** of events, where n can be equal to one or any higher interger value.
31 ***
32 *** When an event chain begins, the first (base) event of the chain is started.
33 *** Immediately after starting the first event, the supervisor will examine its event
34 *** links to determine which, if any, children events begin relative to the start of
35 *** the base event. If they are to start a certain time after the start of the parent
36 *** event, they are placed in a container and their countdown timers are initialized.
37 *** These timers will count down on every update call to the event manager and after
38 *** the timers expire, these events will be launched. When an active event ends, again
39 *** its event links are examined to determine if any children events exist that start
40 *** relative to the end of the parent event.
41 *** ***************************************************************************/
42 class EventSupervisor
43 {
44     friend class MapEvent;
45 public:
EventSupervisor()46     EventSupervisor():
47         _is_updating(false)
48     {}
49 
50     ~EventSupervisor();
51 
52     /** \brief Marks a specified event as active and starts the event
53     *** \param event_id The ID of the event to activate
54     *** \param launch_time The time to wait before launching the event.
55     *** The specified event to start may be linked to several children, grandchildren, etc. events.
56     *** If the event has no children, it will activate only the single event requested. Otherwise
57     *** all events in the chain will become activated at the appropriate time.
58     **/
59     void StartEvent(const std::string& event_id);
60     void StartEvent(const std::string& event_id, uint32_t launch_time);
61 
62     /** \brief Marks a specified event as active and starts the event
63     *** \param event A pointer to the event to begin
64     *** \param launch_time The time to wait before launching the event.
65     *** The specified event to start may be linked to several children, grandchildren, etc. events.
66     *** If the event has no children, it will activate only the single event requested. Otherwise
67     *** all events in the chain will become activated at the appropriate time.
68     **/
69     void StartEvent(MapEvent* event);
70     void StartEvent(MapEvent* event, uint32_t launch_time);
71 
72     /** \brief Pauses the active events by preventing them from updating
73     *** \param event_id The ID of the active event(s) to pause
74     *** If the event corresponding to the ID is not active, a warning will be issued and no change
75     *** will occur.
76     **/
77     void PauseEvent(const std::string& event_id);
78 
79     /** \brief Pauses the given sprite events
80     *** \param sprite The sprite to pause the sprite events from
81     **/
82     void PauseAllEvents(VirtualSprite* sprite);
83 
84     /** \brief Resumes a paused event
85     *** \param event_id The ID of the active event(s) to resume
86     *** If the event corresponding to the ID is not paused, a warning will be issued and no change
87     *** will occur.
88     **/
89     void ResumeEvent(const std::string& event_id);
90 
91     /** \brief Resumes the given sprite events
92     *** \param sprite The sprite to resume the sprite events from
93     **/
94     void ResumeAllEvents(VirtualSprite* sprite);
95 
96     /** \brief Terminates an event if it is active
97     *** \param event_id The ID of the event(s) to terminate
98     *** \param event Mapevent(s) to terminate
99     *** \param trigger_event_links Tells whether the launching of any of the events' children should occur, true by default.
100     *** \note If there is no active event that corresponds to the event ID, the function will do nothing.
101     **/
102     void EndEvent(const std::string& event_id, bool trigger_event_links = true);
103     void EndEvent(MapEvent* event, bool trigger_event_links = true);
104 
105     /** \brief Terminates all the SpriteEvents (active, paused, or incoming) for the given sprite.
106     ***
107     *** This is very useful when wanting to break an active event chain controlling a sprite
108     *** and liberate it for something else.
109     *** Note that you should start the new sprite event chain *after* this call.
110     **/
111     void EndAllEvents(VirtualSprite* sprite);
112 
113     //! \brief Updates the state of all active and launch events
114     void Update();
115 
116     /** \brief Determines if a chosen event is active
117     *** \param event_id The ID of the event to check
118     *** \return True if the event is active, false if it is not or the event could not be found
119     **/
120     bool IsEventActive(const std::string& event_id) const;
121 
122     //! \brief Returns true if any events are active
HasActiveEvent()123     bool HasActiveEvent() const {
124         return !_active_events.empty();
125     }
126 
127     //! \brief Returns true if any events are being prepared to be launched after their timers expire
HasActiveDelayedEvent()128     bool HasActiveDelayedEvent() const {
129         return !_active_delayed_events.empty();
130     }
131 
132     /** \brief Returns a pointer to a specified event stored by this class
133     *** \param event_id The ID of the event to retrieve
134     *** \return A MapEvent pointer (which may need to be casted to the proper event type), or nullptr if no event was found
135     **/
136     MapEvent* GetEvent(const std::string& event_id) const;
137 
DoesEventExist(const std::string & event_id)138     bool DoesEventExist(const std::string& event_id) const
139     { return !(GetEvent(event_id) == nullptr); }
140 
141 private:
142     //! \brief A container for all map events, where the event's ID serves as the key to the std::map
143     std::map<std::string, MapEvent*> _all_events;
144 
145     //! \brief A list of all events which have started but are not yet finished
146     std::vector<MapEvent*> _active_events;
147 
148     //! \brief A list of all events which have been paused
149     std::vector<MapEvent*> _paused_events;
150 
151     /** \brief A list of all events that are waiting on their launch timers to expire before being started
152     *** The interger part of this std::pair is the countdown timer for this event to be launched
153     **/
154     std::vector<std::pair<int32_t, MapEvent*> > _active_delayed_events;
155 
156     /** \brief A list of all events that are waiting on their launch timers to expire before being started
157     *** The interger part of this std::pair is the countdown timer for this event to be launched
158     *** Those ones are put on hold by PauseAllEvents() and PauseEvent();
159     **/
160     std::vector<std::pair<int32_t, MapEvent*> > _paused_delayed_events;
161 
162     /** States whether the event supervisor is parsing the active events queue, thus any modifications
163     *** there on active events should be avoided.
164     **/
165     volatile bool _is_updating;
166 
167     /** \brief A function that is called whenever an event starts or finishes to examine that event's links
168     *** \param parent_event The event that has just started or finished
169     *** \param event_start The event has just started if this member is true, or if it just finished it will be false
170     **/
171     void _ExamineEventLinks(MapEvent* parent_event, bool event_start);
172 
173     /** \brief Registers a map event object with the event supervisor
174     *** \param new_event A pointer to the new event
175     *** \return whether the event was successfully registered.
176     *** \note This function should be called by the MapEvent constructor only
177     **/
178     bool _RegisterEvent(MapEvent* new_event);
179 };
180 
181 } // namespace private_map
182 
183 } // namespace vt_map
184 
185 #endif // __MAP_EVENT_SUPERVISOR_HEADER__
186