1 module dlangide.tools.d.dcdserver;
2 
3 import dlangui.core.logger;
4 import dlangui.core.files;
5 import dlangide.builders.extprocess;
6 import dlangide.workspace.project;
7 import std.conv : to;
8 import dlangide.tools.d.dcdinterface;
9 
10 
11 /// encapsulates running DCD server access
12 class DCDServer {
13 	private ExternalProcess dcdProcess;
14 	private ProtectedTextStorage stdoutTarget;
15     private int _port;
16     private bool _running;
17     private bool _error;
18 
19     /// port to connect to DCD
20     @property int port() {
21         return _port;
22     }
23     this(int port = DCD_SERVER_PORT_FOR_DLANGIDE) {
24         _port = port;
25     }
26     /// returns true if there was error while trying to run server last time
27     @property bool isError() {
28         return _error;
29     }
30     /// returns true if server seems running
31     @property bool isRunning() {
32         return _running;
33     }
34     /// start DCD server
35     bool start() {
36         if (dcdProcess || stdoutTarget) {
37             Log.e("Already started");
38             return false;
39         }
40         _error = false;
41         _running = false;
42         string dcdServerExecutable = findExecutablePath("dcd-server");
43         if (!dcdServerExecutable) {
44             Log.e("dcd-server executable is not found");
45             _error = true;
46             return false;
47         }
48 
49         string[] srcPaths = dmdSourcePaths();
50 		string[] arguments;
51         foreach(p; srcPaths)
52             arguments ~= "-I" ~ p;
53         if (_port != DCD_DEFAULT_PORT)
54             arguments ~= "-p" ~ to!string(_port);
55         Log.i("starting dcd-server: executable path is ", dcdServerExecutable, " args: ", arguments);
56         dcdProcess = new ExternalProcess();
57 		stdoutTarget = new ProtectedTextStorage();
58 		ExternalProcessState state = dcdProcess.run(dcdServerExecutable, arguments, null, stdoutTarget);
59         if (state != ExternalProcessState.Running) {
60             Log.e("Error while starting DCD: process state reported is ", state);
61             _error = true;
62             dcdProcess.kill();
63             dcdProcess.wait();
64             destroy(dcdProcess);
65             dcdProcess = null;
66             stdoutTarget = null;
67             return false;
68         }
69         Log.i("DCD server is started successfully");
70         _running = true;
71         return true;
72     }
73 
74     /// stop DCD server
75     bool stop() {
76         if (!dcdProcess) {
77             Log.e("Cannot stop DCD server - it's not started");
78             return false;
79         }
80         debug(DCD) Log.i("Current DCD server state: ", dcdProcess.poll());
81         Log.i("Stopping DCD server");
82         ExternalProcessState state = dcdProcess.kill();
83         state = dcdProcess.wait();
84         debug(DCD) Log.i("DCD server state: ", state);
85         destroy(dcdProcess);
86         dcdProcess = null;
87         stdoutTarget = null;
88         _running = false;
89         return true;
90     }
91 }