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 }