1 /**
2 Abstract base class for the game's main loop.
3 
4 Copyright:
5 Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur.  
6 Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md)  
7 Copyright (c) 2017-2018 Godot-D contributors  
8 
9 License: $(LINK2 https://opensource.org/licenses/MIT, MIT License)
10 
11 
12 */
13 module godot.mainloop;
14 import std.meta : AliasSeq, staticIndexOf;
15 import std.traits : Unqual;
16 import godot.d.traits;
17 import godot.core;
18 import godot.c;
19 import godot.d.bind;
20 import godot.d.reference;
21 import godot.globalenums;
22 import godot.object;
23 import godot.classdb;
24 import godot.inputevent;
25 /**
26 Abstract base class for the game's main loop.
27 
28 $(D MainLoop) is the abstract base class for a Godot project's game loop. It is inherited by $(D SceneTree), which is the default game loop implementation used in Godot projects, though it is also possible to write and use one's own $(D MainLoop) subclass instead of the scene tree.
29 Upon the application start, a $(D MainLoop) implementation must be provided to the OS; otherwise, the application will exit. This happens automatically (and a $(D SceneTree) is created) unless a main $(D Script) is provided from the command line (with e.g. `godot -s my_loop.gd`, which should then be a $(D MainLoop) implementation.
30 Here is an example script implementing a simple $(D MainLoop):
31 
32 
33 extends MainLoop
34 
35 var time_elapsed = 0
36 var keys_typed = []
37 var quit = false
38 
39 func _initialize():
40     print("Initialized:")
41     print("  Starting time: %s" % str(time_elapsed))
42 
43 func _idle(delta):
44     time_elapsed += delta
45     # Return true to end the main loop.
46     return quit
47 
48 func _input_event(event):
49     # Record keys.
50     if event is InputEventKey and event.pressed and !event.echo:
51         keys_typed.append(OS.get_scancode_string(event.scancode))
52         # Quit on Escape press.
53         if event.scancode == KEY_ESCAPE:
54             quit = true
55     # Quit on any mouse click.
56     if event is InputEventMouseButton:
57         quit = true
58 
59 func _finalize():
60     print("Finalized:")
61     print("  End time: %s" % str(time_elapsed))
62     print("  Keys typed: %s" % var2str(keys_typed))
63 
64 
65 */
66 @GodotBaseClass struct MainLoop
67 {
68 	package(godot) enum string _GODOT_internal_name = "MainLoop";
69 public:
70 @nogc nothrow:
71 	union { /** */ godot_object _godot_object; /** */ GodotObject _GODOT_base; }
72 	alias _GODOT_base this;
73 	alias BaseClasses = AliasSeq!(typeof(_GODOT_base), typeof(_GODOT_base).BaseClasses);
74 	package(godot) __gshared bool _classBindingInitialized = false;
75 	package(godot) static struct GDNativeClassBinding
76 	{
77 		__gshared:
78 		@GodotName("_drop_files") GodotMethod!(void, PoolStringArray, long) _dropFiles;
79 		@GodotName("_finalize") GodotMethod!(void) _finalize;
80 		@GodotName("_global_menu_action") GodotMethod!(void, Variant, Variant) _globalMenuAction;
81 		@GodotName("_idle") GodotMethod!(bool, double) _idle;
82 		@GodotName("_initialize") GodotMethod!(void) _initialize;
83 		@GodotName("_input_event") GodotMethod!(void, InputEvent) _inputEvent;
84 		@GodotName("_input_text") GodotMethod!(void, String) _inputText;
85 		@GodotName("_iteration") GodotMethod!(bool, double) _iteration;
86 		@GodotName("finish") GodotMethod!(void) finish;
87 		@GodotName("idle") GodotMethod!(bool, double) idle;
88 		@GodotName("init") GodotMethod!(void) _init;
89 		@GodotName("input_event") GodotMethod!(void, InputEvent) inputEvent;
90 		@GodotName("input_text") GodotMethod!(void, String) inputText;
91 		@GodotName("iteration") GodotMethod!(bool, double) iteration;
92 	}
93 	/// 
94 	pragma(inline, true) bool opEquals(in MainLoop other) const
95 	{ return _godot_object.ptr is other._godot_object.ptr; }
96 	/// 
97 	pragma(inline, true) typeof(null) opAssign(typeof(null) n)
98 	{ _godot_object.ptr = n; return null; }
99 	/// 
100 	pragma(inline, true) bool opEquals(typeof(null) n) const
101 	{ return _godot_object.ptr is n; }
102 	/// 
103 	size_t toHash() const @trusted { return cast(size_t)_godot_object.ptr; }
104 	mixin baseCasts;
105 	/// Construct a new instance of MainLoop.
106 	/// Note: use `memnew!MainLoop` instead.
107 	static MainLoop _new()
108 	{
109 		static godot_class_constructor constructor;
110 		if(constructor is null) constructor = _godot_api.godot_get_class_constructor("MainLoop");
111 		if(constructor is null) return typeof(this).init;
112 		return cast(MainLoop)(constructor());
113 	}
114 	@disable new(size_t s);
115 	/// 
116 	enum Constants : int
117 	{
118 		/**
119 		Notification received from the OS when the mouse enters the game window.
120 		Implemented on desktop and web platforms.
121 		*/
122 		notificationWmMouseEnter = 1002,
123 		/**
124 		Notification received from the OS when the mouse leaves the game window.
125 		Implemented on desktop and web platforms.
126 		*/
127 		notificationWmMouseExit = 1003,
128 		/**
129 		Notification received from the OS when the game window is focused.
130 		Implemented on all platforms.
131 		*/
132 		notificationWmFocusIn = 1004,
133 		/**
134 		Notification received from the OS when the game window is unfocused.
135 		Implemented on all platforms.
136 		*/
137 		notificationWmFocusOut = 1005,
138 		/**
139 		Notification received from the OS when a quit request is sent (e.g. closing the window with a "Close" button or Alt+F4).
140 		Implemented on desktop platforms.
141 		*/
142 		notificationWmQuitRequest = 1006,
143 		/**
144 		Notification received from the OS when a go back request is sent (e.g. pressing the "Back" button on Android).
145 		Specific to the Android platform.
146 		*/
147 		notificationWmGoBackRequest = 1007,
148 		/**
149 		Notification received from the OS when an unfocus request is sent (e.g. another OS window wants to take the focus).
150 		No supported platforms currently send this notification.
151 		*/
152 		notificationWmUnfocusRequest = 1008,
153 		/**
154 		Notification received from the OS when the application is exceeding its allocated memory.
155 		Specific to the iOS platform.
156 		*/
157 		notificationOsMemoryWarning = 1009,
158 		/**
159 		Notification received when translations may have changed. Can be triggered by the user changing the locale. Can be used to respond to language changes, for example to change the UI strings on the fly. Useful when working with the built-in translation support, like $(D GodotObject.tr).
160 		*/
161 		notificationTranslationChanged = 1010,
162 		/**
163 		Notification received from the OS when a request for "About" information is sent.
164 		Specific to the macOS platform.
165 		*/
166 		notificationWmAbout = 1011,
167 		/**
168 		Notification received from Godot's crash handler when the engine is about to crash.
169 		Implemented on desktop platforms if the crash handler is enabled.
170 		*/
171 		notificationCrash = 1012,
172 		/**
173 		Notification received from the OS when an update of the Input Method Engine occurs (e.g. change of IME cursor position or composition string).
174 		Specific to the macOS platform.
175 		*/
176 		notificationOsImeUpdate = 1013,
177 		/**
178 		Notification received from the OS when the app is resumed.
179 		Specific to the Android platform.
180 		*/
181 		notificationAppResumed = 1014,
182 		/**
183 		Notification received from the OS when the app is paused.
184 		Specific to the Android platform.
185 		*/
186 		notificationAppPaused = 1015,
187 	}
188 	/**
189 	Called when files are dragged from the OS file manager and dropped in the game window. The arguments are a list of file paths and the identifier of the screen where the drag originated.
190 	*/
191 	void _dropFiles(in PoolStringArray files, in long from_screen)
192 	{
193 		Array _GODOT_args = Array.make();
194 		_GODOT_args.append(files);
195 		_GODOT_args.append(from_screen);
196 		String _GODOT_method_name = String("_drop_files");
197 		this.callv(_GODOT_method_name, _GODOT_args);
198 	}
199 	/**
200 	Called before the program exits.
201 	*/
202 	void _finalize()
203 	{
204 		Array _GODOT_args = Array.make();
205 		String _GODOT_method_name = String("_finalize");
206 		this.callv(_GODOT_method_name, _GODOT_args);
207 	}
208 	/**
209 	Called when the user performs an action in the system global menu (e.g. the Mac OS menu bar).
210 	*/
211 	void _globalMenuAction(VariantArg0, VariantArg1)(in VariantArg0 id, in VariantArg1 meta)
212 	{
213 		Array _GODOT_args = Array.make();
214 		_GODOT_args.append(id);
215 		_GODOT_args.append(meta);
216 		String _GODOT_method_name = String("_global_menu_action");
217 		this.callv(_GODOT_method_name, _GODOT_args);
218 	}
219 	/**
220 	Called each idle frame with the time since the last idle frame as argument (in seconds). Equivalent to $(D Node._process).
221 	If implemented, the method must return a boolean value. `true` ends the main loop, while `false` lets it proceed to the next frame.
222 	*/
223 	bool _idle(in double delta)
224 	{
225 		Array _GODOT_args = Array.make();
226 		_GODOT_args.append(delta);
227 		String _GODOT_method_name = String("_idle");
228 		return this.callv(_GODOT_method_name, _GODOT_args).as!(RefOrT!bool);
229 	}
230 	/**
231 	Called once during initialization.
232 	*/
233 	void _initialize()
234 	{
235 		Array _GODOT_args = Array.make();
236 		String _GODOT_method_name = String("_initialize");
237 		this.callv(_GODOT_method_name, _GODOT_args);
238 	}
239 	/**
240 	Called whenever an $(D InputEvent) is received by the main loop.
241 	*/
242 	void _inputEvent(InputEvent event)
243 	{
244 		Array _GODOT_args = Array.make();
245 		_GODOT_args.append(event);
246 		String _GODOT_method_name = String("_input_event");
247 		this.callv(_GODOT_method_name, _GODOT_args);
248 	}
249 	/**
250 	Deprecated callback, does not do anything. Use $(D _inputEvent) to parse text input. Will be removed in Godot 4.0.
251 	*/
252 	void _inputText(in String text)
253 	{
254 		Array _GODOT_args = Array.make();
255 		_GODOT_args.append(text);
256 		String _GODOT_method_name = String("_input_text");
257 		this.callv(_GODOT_method_name, _GODOT_args);
258 	}
259 	/**
260 	Called each physics frame with the time since the last physics frame as argument (`delta`, in seconds). Equivalent to $(D Node._physicsProcess).
261 	If implemented, the method must return a boolean value. `true` ends the main loop, while `false` lets it proceed to the next frame.
262 	*/
263 	bool _iteration(in double delta)
264 	{
265 		Array _GODOT_args = Array.make();
266 		_GODOT_args.append(delta);
267 		String _GODOT_method_name = String("_iteration");
268 		return this.callv(_GODOT_method_name, _GODOT_args).as!(RefOrT!bool);
269 	}
270 	/**
271 	Should not be called manually, override $(D _finalize) instead. Will be removed in Godot 4.0.
272 	*/
273 	void finish()
274 	{
275 		checkClassBinding!(typeof(this))();
276 		ptrcall!(void)(GDNativeClassBinding.finish, _godot_object);
277 	}
278 	/**
279 	Should not be called manually, override $(D _idle) instead. Will be removed in Godot 4.0.
280 	*/
281 	bool idle(in double delta)
282 	{
283 		checkClassBinding!(typeof(this))();
284 		return ptrcall!(bool)(GDNativeClassBinding.idle, _godot_object, delta);
285 	}
286 	/**
287 	Should not be called manually, override $(D _initialize) instead. Will be removed in Godot 4.0.
288 	*/
289 	void _init()
290 	{
291 		checkClassBinding!(typeof(this))();
292 		ptrcall!(void)(GDNativeClassBinding._init, _godot_object);
293 	}
294 	/**
295 	Should not be called manually, override $(D _inputEvent) instead. Will be removed in Godot 4.0.
296 	*/
297 	void inputEvent(InputEvent event)
298 	{
299 		checkClassBinding!(typeof(this))();
300 		ptrcall!(void)(GDNativeClassBinding.inputEvent, _godot_object, event);
301 	}
302 	/**
303 	Should not be called manually, override $(D _inputText) instead. Will be removed in Godot 4.0.
304 	*/
305 	void inputText(in String text)
306 	{
307 		checkClassBinding!(typeof(this))();
308 		ptrcall!(void)(GDNativeClassBinding.inputText, _godot_object, text);
309 	}
310 	/**
311 	Should not be called manually, override $(D _iteration) instead. Will be removed in Godot 4.0.
312 	*/
313 	bool iteration(in double delta)
314 	{
315 		checkClassBinding!(typeof(this))();
316 		return ptrcall!(bool)(GDNativeClassBinding.iteration, _godot_object, delta);
317 	}
318 }