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 import std.algorithm,
10        std.stdio;
11 import core.thread;
12 static import g4d;
13 
14 /// A handler type to catch the exception thrown at inside of main loop.
15 alias ExceptionHandler = EventHandler!( bool, Exception );
16 
17 /// An object of application.
18 /// Manages all tasks executing.
19 class App
20 {
21     protected Task[]   _tasks;
22     protected string[] _args;
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     /// A handler to catch the exception thrown at inside of main loop.
30     ExceptionHandler onThrown;
31 
32     ///
33     this ( in string[] args )
34     {
35         _args         = args.dup;
36         sleepDuration = 10;
37     }
38 
39     /// Checks if 1 or more tasks are executing.
40     const @property alive () { return !!_tasks.length; }
41 
42     /// Adds the task.
43     Task addTask ( Task newTask )
44     {
45         _tasks ~= newTask;
46         return newTask;
47     }
48 
49     /// Enters main loop.
50     /// Returns: Status code.
51     int exec ()
52     {
53         while ( alive ) {
54             try {
55                 // Adding tasks is possible inside of remove template.
56                 auto temp = _tasks;
57                 _tasks    = [];
58                 _tasks   ~= temp.remove!( x => x.exec(this) );
59 
60                 g4d.Window.pollEvents();
61                 Thread.sleep( dur!"msecs"( sleepDuration ) );
62             } catch ( Exception e ) {
63                 if ( !onThrown.call( e ) ) {
64                     e.writeln;
65                     break;
66                 }
67             }
68         }
69         return returnCode;
70     }
71 
72     /// Terminates all tasks forcibly.
73     /// Escapes from main loop because all tasks will be deleted.
74     void terminate ()
75     {
76         _tasks = [];
77     }
78 }
79 
80 /// An interface of task that App does.
81 interface Task
82 {
83     /// Returns true to notify to finish the task.
84     bool exec ( App );
85 }