1 // Written in the D programming language.
2 /++
3 + Authors: KanzakiKino
4 + Copyright: KanzakiKino 2018
5 + License: LGPL-3.0
6 ++/
7 module w4d.app;
8 import w4d.event,
9 w4d.log;
10 import std.algorithm,
11 std.stdio;
12 import core.thread;
13 static import g4d;
14
15 /// A handler type to catch the exception thrown at inside of main loop.
16 alias ExceptionHandler = EventHandler!( bool, Exception );
17
18 /// An object of application.
19 /// Manages all tasks executing.
20 class App
21 {
22 protected Task[] _tasks;
23
24 /// Duration in milliseconds to sleep in each frames.
25 uint sleepDuration;
26 /// Status code that main function returns.
27 int returnCode;
28
29 // Arguments of main function.
30 immutable string[] args;
31
32 /// A handler to catch the exception thrown at inside of main loop.
33 ExceptionHandler onThrown;
34
35 ///
36 this ( in string[] args )
37 {
38 this.args = args.idup;
39 sleepDuration = 10;
40 }
41
42 /// Checks if 1 or more tasks are executing.
43 const @property alive () { return !!_tasks.length; }
44
45 /// Adds the task.
46 Task addTask ( Task newTask )
47 {
48 _tasks ~= newTask;
49 Log.trace( newTask, "was added as Task." );
50 return newTask;
51 }
52
53 /// Enters main loop.
54 /// Returns: Status code.
55 int exec ()
56 {
57 while ( alive ) {
58 try {
59 // Adding tasks is possible inside of remove template.
60 auto temp = _tasks;
61 _tasks = [];
62 _tasks ~= temp.remove!( x => x.exec(this) );
63
64 g4d.Window.pollEvents();
65 Thread.sleep( dur!"msecs"( sleepDuration ) );
66
67 } catch ( Exception e ) {
68 if ( !onThrown.call( e ) ) {
69 Log.info( "An exception wasn't caught by anyone." );
70 throw e;
71 }
72 }
73 }
74 return returnCode;
75 }
76
77 /// Terminates all tasks forcibly.
78 /// Escapes from main loop because all tasks will be deleted.
79 void terminate ()
80 {
81 _tasks = [];
82 Log.warn( "App is terminating forcibly." );
83 }
84 }
85
86 /// An interface of task that App does.
87 interface Task
88 {
89 /// Returns true to notify to finish the task.
90 bool exec ( App );
91 }