1 module ddebug.common.debugger;
2 
3 import core.thread;
4 import dlangui.core.logger;
5 import ddebug.common.queue;
6 
7 enum ResponseCode : int {
8 	/// Operation finished successfully
9 	Ok = 0,
10 
11 	// more success codes here
12 
13 	/// General purpose failure code
14 	Fail = 1000,
15 	/// method is not implemented
16 	NotImplemented,
17 	/// error running debugger
18 	CannotRunDebugger,
19 
20 	// more error codes here
21 }
22 
23 alias Runnable = void delegate();
24 alias DebuggerResponse = void delegate(ResponseCode code, string msg);
25 
26 interface Debugger {
27 	/// start debugging
28 	void startDebugging(string debuggerExecutable, string executable, string[] args, string workingDir, DebuggerResponse response);
29 }
30 
31 
32 
33 /// proxy for debugger interface implementing async calls
34 class DebuggerProxy : Debugger {
35 	private DebuggerBase _debugger;
36 	private void delegate(Runnable runnable) _callbackDelegate;
37 
38 	this(DebuggerBase debugger, void delegate(Runnable runnable) callbackDelegate) {
39 		_debugger = debugger;
40 		_callbackDelegate = callbackDelegate;
41 	}
42 
43 	void startDebugging(string debuggerExecutable, string executable, string[] args, string workingDir, DebuggerResponse response) {
44 		_debugger.postRequest(delegate() {
45 				_debugger.startDebugging(debuggerExecutable, executable, args, workingDir,
46 					delegate(ResponseCode code, string msg) {
47 						_callbackDelegate( delegate() { response(code, msg); } );
48 					}
49 				);
50 		});
51 	}
52 
53 }
54 
55 class DebuggerBase : Thread, Debugger {
56 	private bool _stopRequested;
57 	private bool _finished;
58 	protected string _debuggerExecutable;
59 	protected BlockingQueue!Runnable _queue;
60 
61 	void postRequest(Runnable request) {
62 		_queue.put(request);
63 	}
64 
65 	this() {
66 		super(&run);
67 		_queue = new BlockingQueue!Runnable();
68 	}
69 
70 	~this() {
71 		stop();
72 		destroy(_queue);
73 		_queue = null;
74 	}
75 
76 	void stop() {
77 		Log.i("Debugger.stop()");
78 		_stopRequested = true;
79 		_queue.close();
80 	}
81 
82 	protected void onDebuggerThreadStarted() {
83 	}
84 
85 	protected void onDebuggerThreadFinished() {
86 	}
87 	
88 	/// thread func: execute all tasks from queue
89 	private void run() {
90 		onDebuggerThreadStarted();
91 		Log.i("Debugger thread started");
92 		while (!_stopRequested) {
93 			Runnable task;
94 			if (_queue.get(task, 0)) {
95 				task();
96 			}
97 		}
98 		Log.i("Debugger thread finished");
99 		_finished = true;
100 		onDebuggerThreadFinished();
101 	}
102 
103 	void startDebugging(string debuggerExecutable, string executable, string[] args, string workingDir, DebuggerResponse response) {
104 		response(ResponseCode.NotImplemented, "Not Implemented");
105 	}
106 
107 }