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 }