w11 - cpp 0.794
Backend server for Rlink and w11
Loading...
Searching...
No Matches
RtclRlinkServer.cpp
Go to the documentation of this file.
1// $Id: RtclRlinkServer.cpp 1186 2019-07-12 17:49:59Z mueller $
2// SPDX-License-Identifier: GPL-3.0-or-later
3// Copyright 2013-2019 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
4//
5// Revision History:
6// Date Rev Version Comment
7// 2019-06-07 1160 1.2.4 use RtclStats::Exec()
8// 2019-02-23 1114 1.2.3 use std::bind instead of lambda
9// 2018-12-17 1087 1.2.2 use std::lock_guard instead of boost
10// 2018-12-14 1081 1.2.1 use std::bind instead of boost
11// 2018-12-01 1076 1.2 use unique_ptr
12// 2018-11-16 1070 1.1.2 use auto; use range loop
13// 2017-04-02 865 1.1.1 M_dump: use GetArgsDump and Dump detail
14// 2015-04-04 662 1.1 add M_get, M_set; remove 'server -trace'
15// 2014-08-22 584 1.0.6 use nullptr
16// 2013-05-01 513 1.0.5 TraceLevel now uint32_t
17// 2013-04-26 510 1.0.4 change M_attn, now -info instead of -show
18// 2013-04-21 509 1.0.3 add server -resume
19// 2013-02-05 483 1.0.2 ClassCmdConfig: use RtclArgs
20// 2013-02-05 482 1.0.1 add shared_ptr to RlinkConnect object
21// 2013-01-12 474 1.0 Initial version
22// ---------------------------------------------------------------------------
23
28#include <ctype.h>
29
30#include <stdexcept>
31#include <iostream>
32#include <vector>
33#include <string>
34#include <memory>
35#include <functional>
36
38#include "librtcltools/Rtcl.hpp"
42#include "RtclRlinkConnect.hpp"
43
44#include "RtclRlinkServer.hpp"
45
46using namespace std;
47using namespace std::placeholders;
48
54// all method definitions in namespace Retro
55namespace Retro {
56
57//------------------------------------------+-----------------------------------
59
60RtclRlinkServer::RtclRlinkServer(Tcl_Interp* interp, const char* name)
61 : RtclProxyOwned<RlinkServer>("RlinkServer", interp, name,
62 new RlinkServer()),
63 fspConn(),
64 fGets(),
65 fSets()
66{
67 AddMeth("server", bind(&RtclRlinkServer::M_server, this, _1));
68 AddMeth("attn", bind(&RtclRlinkServer::M_attn, this, _1));
69 AddMeth("stats", bind(&RtclRlinkServer::M_stats, this, _1));
70 AddMeth("print", bind(&RtclRlinkServer::M_print, this, _1));
71 AddMeth("dump", bind(&RtclRlinkServer::M_dump, this, _1));
72 AddMeth("get", bind(&RtclRlinkServer::M_get, this, _1));
73 AddMeth("set", bind(&RtclRlinkServer::M_set, this, _1));
74 AddMeth("$default", bind(&RtclRlinkServer::M_default, this, _1));
75
76 // attributes of RlinkConnect
77 RlinkServer* pobj = &Obj();
78 fGets.Add<uint32_t> ("tracelevel",
79 bind(&RlinkServer::TraceLevel, pobj));
80
81 fSets.Add<uint32_t> ("tracelevel",
82 bind(&RlinkServer::SetTraceLevel, pobj, _1));
83
84 // attributes of buildin RlinkContext
85 RlinkContext* pcntx = &Obj().Context();
86 fGets.Add<bool> ("statchecked",
87 bind(&RlinkContext::StatusIsChecked, pcntx));
88 fGets.Add<uint8_t> ("statvalue",
89 bind(&RlinkContext::StatusValue, pcntx));
90 fGets.Add<uint8_t> ("statmask",
91 bind(&RlinkContext::StatusMask, pcntx));
92
93 fSets.Add<uint8_t> ("statvalue",
94 bind(&RlinkContext::SetStatusValue, pcntx, _1));
95 fSets.Add<uint8_t> ("statmask",
96 bind(&RlinkContext::SetStatusMask, pcntx, _1));
97}
98
99//------------------------------------------+-----------------------------------
101
103{}
104
105//------------------------------------------+-----------------------------------
107
109{
110 string parent;
111 if (!args.GetArg("parent", parent)) return kERR;
112
113 // locate RlinkConnect proxy and object -> setup Server->Connect linkage
115 "RlinkConnect", parent);
116 if (pprox == nullptr)
117 return args.Quit(string("-E: object '") + parent +
118 "' not found or not type RlinkConnect");
119
120 // make RtclRlinkServer object be co-owner of RlinkConnect object
121 fspConn = dynamic_cast<RtclRlinkConnect*>(pprox)->ObjSPtr();
122 // set RlinkConnect in RlinkServer (make RlinkServer also co-owner)
124
125 return kOK;
126}
127
128//------------------------------------------+-----------------------------------
130
132{
133 static RtclNameSet optset("-start|-stop|-resume|-test");
134 string opt;
135 if (args.NextOpt(opt, optset)) {
136 if (opt == "-start") { // server -start
137 if (!args.AllDone()) return kERR;
138 if (Obj().IsActive()) return args.Quit("-E: server already running");
139 Obj().Start();
140 } else if (opt == "-stop") { // server -stop
141 if (!args.AllDone()) return kERR;
142 Obj().Stop();
143 } else if (opt == "-resume") { // server -resume
144 if (Obj().IsActive()) return args.Quit("-E: server already running");
145 if (!args.AllDone()) return kERR;
146 Obj().Resume();
147 } else if (opt == "-test") { // server -test
148 if (!args.AllDone()) return kERR;
149 args.SetResult(Obj().IsActive());
150 }
151
152 } else { // server
153 if (!args.OptValid()) return kERR;
154 if (!args.AllDone()) return kERR;
155 args.SetResult(Obj().IsActive());
156 }
157
158 return kOK;
159}
160
161//------------------------------------------+-----------------------------------
163
165{
166 static RtclNameSet optset("-add|-remove|-info|-test|-list");
167
168 Tcl_Interp* interp = args.Interp();
169
170 string opt;
171
172 if (args.NextOpt(opt, optset)) {
173 if (opt == "-add") { // attn -add mask script
174 uint16_t mask=0;
175 Tcl_Obj* script=0;
176 if (!args.GetArg("mask", mask,0xff,1)) return kERR;
177 if (!args.GetArg("script", script)) return kERR;
178 if (!args.AllDone()) return kERR;
179
180 ahdl_uptr_t up(new RtclAttnShuttle(mask, script));
181 try {
182 up->Add(&Obj(), interp);
183 } catch (exception& e) {
184 return args.Quit(string("-E: handler rejected: ")+e.what());
185 }
186 fAttnHdl.push_back(move(up));
187 return kOK;
188
189 } else if (opt == "-remove") { // attn -remove mask
190 uint16_t mask=0;
191 if (!args.GetArg("mask", mask)) return kERR;
192 if (!args.AllDone()) return kERR;
193 if (!fAttnHdl.empty()) {
194 for (auto it = fAttnHdl.end(); it != fAttnHdl.begin(); ) {
195 it--;
196 if ((*it)->Mask() == mask) {
197 fAttnHdl.erase(it);
198 return kOK;
199 }
200 }
201 }
202 return args.Quit(string("-E: no handler defined for '") +
203 args.PeekArgString(-1) + "'");
204
205 } else if (opt == "-info") { // attn -info mask
206 uint16_t mask=0;
207 if (!args.GetArg("mask", mask)) return kERR;
208 if (!args.AllDone()) return kERR;
209 RtclOPtr pres(Tcl_NewListObj(0,nullptr));
210 for (auto& po : fAttnHdl) {
211 if (po->Mask() & mask) {
212 RtclOPtr pele(Tcl_NewListObj(0,nullptr));
213 Tcl_ListObjAppendElement(nullptr, pele,
214 Tcl_NewIntObj(po->Mask()) );
215 Tcl_ListObjAppendElement(nullptr, pele, po->Script() );
216 Tcl_ListObjAppendElement(nullptr, pres, pele);
217 }
218 }
219 args.SetResult(pres);
220 return kOK;
221
222 } else if (opt == "-test") { // attn -test mask
223 uint16_t mask=0;
224 if (!args.GetArg("mask", mask)) return kERR;
225 if (!args.AllDone()) return kERR;
226 int nhdl = 0;
227 for (auto& po: fAttnHdl) {
228 if (po->Mask() & mask) {
229 nhdl += 1;
230 int rc = Tcl_EvalObjEx(interp, po->Script(), TCL_EVAL_GLOBAL);
231 if (rc != kOK) return rc;
232 }
233 }
234 if (nhdl) return kOK;
235 return args.Quit(string("-E: no handler defined for '") +
236 args.PeekArgString(-1) + "'");
237
238 } else if (opt == "-list") { // attn -list
239 if (!args.AllDone()) return kERR;
240 vector<uint16_t> vres;
241 for (auto& po : fAttnHdl) {
242 vres.push_back(po->Mask());
243 }
244 args.SetResult(Rtcl::NewListIntObj(vres));
245 }
246
247 } else { // attn
248 if (!args.OptValid()) return kERR;
249 if (!args.AllDone()) return kERR;
250 uint16_t mask=0;
251 for (auto& po: fAttnHdl) {
252 mask |= po->Mask();
253 }
254 args.SetResult(mask);
255 }
256
257 return kOK;
258}
259
260//------------------------------------------+-----------------------------------
262
264{
266 if (!RtclStats::GetArgs(args, cntx)) return kERR;
267 if (!RtclStats::Exec(args, cntx, Obj().Stats())) return kERR;
268 return kOK;
269}
270
271//------------------------------------------+-----------------------------------
273
275{
276 if (!args.AllDone()) return kERR;
277
278 ostringstream sos;
279 Obj().Print(sos);
280 args.SetResult(sos);
281 return kOK;
282}
283
284//------------------------------------------+-----------------------------------
286
288{
289 int detail=0;
290 if (!GetArgsDump(args, detail)) return kERR;
291 if (!args.AllDone()) return kERR;
292
293 ostringstream sos;
294 Obj().Dump(sos, 0, "", detail);
295 args.SetResult(sos);
296 return kOK;
297}
298
299//------------------------------------------+-----------------------------------
301
303{
304 // synchronize with server thread (really needed ??)
305 lock_guard<RlinkConnect> lock(Obj().Connect());
306 return fGets.M_get(args);
307}
308
309//------------------------------------------+-----------------------------------
311
313{
314 // synchronize with server thread (really needed ??)
315 lock_guard<RlinkConnect> lock(Obj().Connect());
316 return fSets.M_set(args);
317}
318
319//------------------------------------------+-----------------------------------
321
323{
324 if (!args.AllDone()) return kERR;
325 ostringstream sos;
326 sos << "no default output defined yet...\n";
327 args.AppendResultLines(sos);
328 return kOK;
329}
330
331} // end namespace Retro
void SetStatusMask(uint8_t statmsk)
FIXME_docs.
uint8_t StatusValue() const
FIXME_docs.
bool StatusIsChecked() const
FIXME_docs.
uint8_t StatusMask() const
FIXME_docs.
void SetStatusValue(uint8_t stat)
FIXME_docs.
uint32_t TraceLevel() const
FIXME_docs.
Definition: RlinkServer.ipp:77
void SetConnect(const std::shared_ptr< RlinkConnect > &spconn)
FIXME_docs.
void Stop()
FIXME_docs.
void Print(std::ostream &os) const
FIXME_docs.
void SetTraceLevel(uint32_t level)
FIXME_docs.
void Dump(std::ostream &os, int ind=0, const char *text=0, int detail=0) const
FIXME_docs.
void Resume()
FIXME_docs.
void Start()
FIXME_docs.
RlinkContext & Context()
FIXME_docs.
Definition: RlinkServer.ipp:52
FIXME_docs.
Definition: RtclArgs.hpp:41
bool NextOpt(std::string &val)
FIXME_docs.
Definition: RtclArgs.cpp:368
const char * PeekArgString(int rind) const
FIXME_docs.
Definition: RtclArgs.cpp:461
void AppendResultLines(const std::string &str)
FIXME_docs.
Definition: RtclArgs.cpp:484
bool GetArg(const char *name, Tcl_Obj *&pval)
FIXME_docs.
Definition: RtclArgs.cpp:114
bool OptValid() const
FIXME_docs.
Definition: RtclArgs.ipp:52
int Quit(const std::string &str)
FIXME_docs.
Definition: RtclArgs.ipp:157
void SetResult(const std::string &str)
FIXME_docs.
Definition: RtclArgs.ipp:76
Tcl_Interp * Interp() const
FIXME_docs.
Definition: RtclArgs.ipp:28
bool AllDone()
FIXME_docs.
Definition: RtclArgs.cpp:447
void AddMeth(const std::string &name, methfo_t &&methfo)
FIXME_docs.
bool GetArgsDump(RtclArgs &args, int &detail)
FIXME_docs.
RtclProxyBase * FindProxy(const std::string &type, const std::string &name)
FIXME_docs.
static RtclContext & Find(Tcl_Interp *interp)
FIXME_docs.
int M_get(RtclArgs &args)
FIXME_docs.
Definition: RtclGetList.cpp:73
void Add(const std::string &name, get_uptr_t &&upget)
FIXME_docs.
Definition: RtclGetList.cpp:52
Implemenation (inline) of RtclOPtr.
Definition: RtclOPtr.hpp:23
Implemenation (all inline) of class RtclProxyOwned.
const std::shared_ptr< RlinkServer > & ObjSPtr()
FIXME_docs.
RlinkServer & Obj()
FIXME_docs.
int M_server(RtclArgs &args)
FIXME_docs.
int M_default(RtclArgs &args)
FIXME_docs.
std::unique_ptr< RtclAttnShuttle > ahdl_uptr_t
std::shared_ptr< RlinkConnect > fspConn
int M_dump(RtclArgs &args)
FIXME_docs.
int M_set(RtclArgs &args)
FIXME_docs.
int M_get(RtclArgs &args)
FIXME_docs.
alist_t fAttnHdl
list of attn handlers
int M_print(RtclArgs &args)
FIXME_docs.
RtclRlinkServer(Tcl_Interp *interp, const char *name)
Default constructor.
int M_attn(RtclArgs &args)
FIXME_docs.
int M_stats(RtclArgs &args)
FIXME_docs.
virtual int ClassCmdConfig(RtclArgs &args)
FIXME_docs.
void Add(const std::string &name, set_uptr_t &&upset)
FIXME_docs.
Definition: RtclSetList.cpp:52
int M_set(RtclArgs &args)
FIXME_docs.
Definition: RtclSetList.cpp:73
static bool Exec(RtclArgs &args, const Context &cntx, Rstats &stats)
FIXME_docs.
Definition: RtclStats.cpp:75
static bool GetArgs(RtclArgs &args, Context &cntx)
FIXME_docs.
Definition: RtclStats.cpp:37
Tcl_Obj * NewListIntObj(const uint8_t *data, size_t size)
Declaration of class ReventLoop.
Definition: ReventLoop.cpp:47
static const int kERR
Definition: RtclBvi.cpp:38
static const int kOK
Definition: RtclBvi.cpp:37