1 /* 2 *Copyright (C) 2018 Laurent Tréguier 3 * 4 *This file is part of DLS. 5 * 6 *DLS is free software: you can redistribute it and/or modify 7 *it under the terms of the GNU General Public License as published by 8 *the Free Software Foundation, either version 3 of the License, or 9 *(at your option) any later version. 10 * 11 *DLS is distributed in the hope that it will be useful, 12 *but WITHOUT ANY WARRANTY; without even the implied warranty of 13 *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 *GNU General Public License for more details. 15 * 16 *You should have received a copy of the GNU General Public License 17 *along with DLS. If not, see <http://www.gnu.org/licenses/>. 18 * 19 */ 20 21 module dls.protocol.state; 22 23 import dls.protocol.interfaces : InitializeParams; 24 25 private InitializeParams _initState; 26 private InitializeParams.InitializationOptions _commandLineOptions; 27 28 static this() 29 { 30 _initState = new InitializeParams(); 31 _commandLineOptions = new InitializeParams.InitializationOptions(); 32 } 33 34 @property InitializeParams initState() 35 { 36 return _initState; 37 } 38 39 @property void initState(InitializeParams params) 40 { 41 import dls.protocol.logger : logger; 42 import dls.util.disposable_fiber : DisposableFiber; 43 44 assert(params !is null); 45 _initState = params; 46 47 if (!params.trace.isNull) 48 { 49 logger.trace = params.trace; 50 } 51 52 if (_initState.initializationOptions.isNull) 53 { 54 _initState.initializationOptions = _commandLineOptions; 55 } 56 else 57 { 58 merge(params.initializationOptions.get(), _commandLineOptions); 59 } 60 61 DisposableFiber.safeMode = initOptions.safeMode; 62 } 63 64 @property InitializeParams.InitializationOptions initOptions() 65 { 66 return initState.initializationOptions.isNull ? _commandLineOptions 67 : _initState.initializationOptions; 68 } 69 70 @property void initOptions(InitializeParams.InitializationOptions options) 71 { 72 assert(options !is null); 73 _commandLineOptions = options; 74 } 75 76 private void merge(T)(ref T options, const T addins) 77 { 78 import std.meta : Alias; 79 import std.traits : isSomeFunction, isType; 80 import dls.protocol.logger : logger; 81 82 static if (is(T == class)) 83 { 84 immutable reference = new T(); 85 } 86 else 87 { 88 immutable reference = T.init; 89 } 90 91 foreach (member; __traits(allMembers, T)) 92 { 93 alias m = Alias!(__traits(getMember, T, member)); 94 alias optionsMember = Alias!(mixin("options." ~ member)); 95 alias addinsMember = Alias!(mixin("addins." ~ member)); 96 97 static if (__traits(getProtection, m) != "public" || isType!m || isSomeFunction!m) 98 { 99 continue; 100 } 101 else static if (is(typeof(m) == class)) 102 { 103 merge(mixin("options." ~ member), mixin("addins." ~ member)); 104 } 105 else 106 { 107 if (mixin("options." ~ member) == mixin("reference." ~ member)) 108 { 109 mixin("options." ~ member) = mixin("addins." ~ member); 110 } 111 } 112 } 113 }