1 /*
2  * This file is part of EasyRPG Player.
3  *
4  * EasyRPG Player is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * EasyRPG Player is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with EasyRPG Player. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef EP_ASYNC_OP_H
19 #define EP_ASYNC_OP_H
20 
21 #include <utility>
22 #include <cassert>
23 
24 /**
25  * Represents an asynchronous game operation. These are usually created
26  * by event interpreters. When an async operation starts, the entire game
27  * loop is supposed to suspend, perform the async operation, and
28  * then resume from the suspension point.
29  **/
30 class AsyncOp {
31 	public:
32 		/** The different types of async operations */
33 		enum Type {
34 			eNone,
35 			eShowScreen,
36 			eEraseScreen,
37 			eCallInn,
38 			eQuickTeleport,
39 			eToTitle,
40 			eExitGame,
41 			eTerminateBattle,
42 			eSave,
43 			eLoad
44 		};
45 
46 		AsyncOp() = default;
47 
48 		/** @return a ShowScreen async operation */
49 		static AsyncOp MakeShowScreen(int transition_type);
50 
51 		/** @return an EraseScreen async operation */
52 		static AsyncOp MakeEraseScreen(int transition_type);
53 
54 		/** @return a CallInn async operation */
55 		static AsyncOp MakeCallInn();
56 
57 		/** @return a QuickTeleport async operation */
58 		static AsyncOp MakeQuickTeleport(int map_id, int x, int y);
59 
60 		/** @return a ToTitle async operation */
61 		static AsyncOp MakeToTitle();
62 
63 		/** @return an ExitGame async operation */
64 		static AsyncOp MakeExitGame();
65 
66 		/** @return a TerminateBattle async operation */
67 		static AsyncOp MakeTerminateBattle(int result);
68 
69 		/** @return a Save async operation */
70 		static AsyncOp MakeSave(int save_slot, int save_result_var);
71 
72 		/** @return a Load async operation */
73 		static AsyncOp MakeLoad(int save_slot);
74 
75 		/** @return the type of async operation */
76 		Type GetType() const;
77 
78 		/** @return true if this AsyncOp is active */
79 		bool IsActive() const;
80 
81 		/**
82 		 * @return the type of screen transition to perform
83 		 * @pre If GetType() is not eShowScreen or eEraseScreen, the return value is undefined.
84 		 **/
85 		int GetTransitionType() const;
86 
87 		/**
88 		 * @return the map id to teleport to
89 		 * @pre If GetType() is not eQuickTeleport, the return value is undefined.
90 		 */
91 		int GetTeleportMapId() const;
92 
93 		/**
94 		 * @return the x coordinate to teleport to
95 		 * @pre If GetType() is not eQuickTeleport, the return value is undefined.
96 		 */
97 		int GetTeleportX() const;
98 
99 		/**
100 		 * @return the y coordinate teleport to
101 		 * @pre If GetType() is not eQuickTeleport, the return value is undefined.
102 		 */
103 		int GetTeleportY() const;
104 
105 		/**
106 		 * @return the desired result of the battle to terminate.
107 		 * @pre If GetType() is not eTerminateBattle, the return value is undefined.
108 		 **/
109 		int GetBattleResult() const;
110 
111 		/**
112 		 * @return the desired slot to save or load
113 		 * @pre If GetType() is not eSave or eLoad, the return value is undefined.
114 		 **/
115 		 int GetSaveSlot() const;
116 
117 		/**
118 		 * @return the variable to set to 1 when the save was a success.
119 		 * @pre If GetType() is not eSave, the return value is undefined.
120 		 **/
121 		int GetSaveResultVar() const;
122 
123 	private:
124 		Type _type = eNone;
125 		int _args[3] = {};
126 
127 		template <typename... Args>
128 		explicit AsyncOp(Type type, Args&&... args);
129 
130 };
131 
GetType()132 inline AsyncOp::Type AsyncOp::GetType() const {
133 	return _type;
134 }
135 
IsActive()136 inline bool AsyncOp::IsActive() const {
137 	return GetType() != eNone;
138 }
139 
GetTransitionType()140 inline int AsyncOp::GetTransitionType() const {
141 	assert(GetType() == eShowScreen || GetType() == eEraseScreen);
142 	return _args[0];
143 }
144 
GetTeleportMapId()145 inline int AsyncOp::GetTeleportMapId() const {
146 	assert(GetType() == eQuickTeleport);
147 	return _args[0];
148 }
149 
GetTeleportX()150 inline int AsyncOp::GetTeleportX() const {
151 	assert(GetType() == eQuickTeleport);
152 	return _args[1];
153 }
154 
GetTeleportY()155 inline int AsyncOp::GetTeleportY() const  {
156 	assert(GetType() == eQuickTeleport);
157 	return _args[2];
158 }
159 
GetBattleResult()160 inline int AsyncOp::GetBattleResult() const {
161 	assert(GetType() == eTerminateBattle);
162 	return _args[0];
163 }
164 
GetSaveSlot()165 inline int AsyncOp::GetSaveSlot() const {
166 	assert(GetType() == eSave || GetType() == eLoad);
167 	return _args[0];
168 }
169 
GetSaveResultVar()170 inline int AsyncOp::GetSaveResultVar() const {
171 	assert(GetType() == eSave);
172 	return _args[1];
173 }
174 
175 
176 template <typename... Args>
AsyncOp(Type type,Args &&...args)177 inline AsyncOp::AsyncOp(Type type, Args&&... args)
178 	: _type(type), _args{std::forward<Args>(args)...}
179 {}
180 
MakeShowScreen(int transition_type)181 inline AsyncOp AsyncOp::MakeShowScreen(int transition_type) {
182 	return AsyncOp(eShowScreen, transition_type);
183 }
184 
MakeEraseScreen(int transition_type)185 inline AsyncOp AsyncOp::MakeEraseScreen(int transition_type) {
186 	return AsyncOp(eEraseScreen, transition_type);
187 }
188 
MakeCallInn()189 inline AsyncOp AsyncOp::MakeCallInn() {
190 	return AsyncOp(eCallInn);
191 }
192 
MakeQuickTeleport(int map_id,int x,int y)193 inline AsyncOp AsyncOp::MakeQuickTeleport(int map_id, int x, int y) {
194 	return AsyncOp(eQuickTeleport, map_id, x, y);
195 }
196 
MakeToTitle()197 inline AsyncOp AsyncOp::MakeToTitle() {
198 	return AsyncOp(eToTitle);
199 }
200 
MakeExitGame()201 inline AsyncOp AsyncOp::MakeExitGame() {
202 	return AsyncOp(eExitGame);
203 }
204 
MakeTerminateBattle(int transition_type)205 inline AsyncOp AsyncOp::MakeTerminateBattle(int transition_type) {
206 	return AsyncOp(eTerminateBattle, transition_type);
207 }
208 
MakeSave(int save_slot,int save_result_var)209 inline AsyncOp AsyncOp::MakeSave(int save_slot, int save_result_var) {
210 	return AsyncOp(eSave, save_slot, save_result_var);
211 }
212 
MakeLoad(int save_slot)213 inline AsyncOp AsyncOp::MakeLoad(int save_slot) {
214 	return AsyncOp(eLoad, save_slot);
215 }
216 
217 #endif
218 
219