w11 - cpp 0.794
Backend server for Rlink and w11
Loading...
Searching...
No Matches
RtclContext.cpp
Go to the documentation of this file.
1// $Id: RtclContext.cpp 1186 2019-07-12 17:49:59Z mueller $
2// SPDX-License-Identifier: GPL-3.0-or-later
3// Copyright 2011-2018 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
4//
5// Revision History:
6// Date Rev Version Comment
7// 2018-12-18 1089 1.0.7 use c++ style casts
8// 2018-12-02 1076 1.0.6 use nullptr
9// 2018-11-16 1070 1.0.5 use auto; use emplace,make_pair; use range loop
10// 2017-02-04 866 1.0.4 rename fMapContext -> fContextMap
11// 2013-02-03 481 1.0.3 use Rexception
12// 2013-01-12 474 1.0.2 add FindProxy() method
13// 2011-03-12 368 1.0.1 drop fExitSeen, get exit handling right
14// 2011-02-18 362 1.0 Initial version
15// 2011-02-13 361 0.1 First draft
16// ---------------------------------------------------------------------------
17
22#include <iostream>
23
24#include "RtclContext.hpp"
25
27
28using namespace std;
29
35// all method definitions in namespace Retro
36namespace Retro {
37
39
40//------------------------------------------+-----------------------------------
42
43RtclContext::RtclContext(Tcl_Interp* interp)
44 : fInterp(interp),
45 fSetClass(),
46 fSetProxy()
47{}
48
49//------------------------------------------+-----------------------------------
51
53{}
54
55//------------------------------------------+-----------------------------------
57
59{
60 auto ret = fSetClass.insert(pobj);
61 if (ret.second == false) // or use !(ret.second)
62 throw Rexception("RtclContext::RegisterClass()",
63 "Bad args: duplicate pointer");
64 return;
65}
66
67//------------------------------------------+-----------------------------------
69
71{
72 fSetClass.erase(pobj);
73 return;
74}
75
76//------------------------------------------+-----------------------------------
78
80{
81 auto ret = fSetProxy.insert(pobj);
82 if (ret.second == false) // or use !(ret.second)
83 throw Rexception("RtclContext::RegisterProxy()",
84 "Bad args: duplicate pointer");
85 return;
86}
87
88//------------------------------------------+-----------------------------------
90
92{
93 fSetProxy.erase(pobj);
94 return;
95}
96
97//------------------------------------------+-----------------------------------
99
101{
102 auto it = fSetProxy.find(pobj);
103 return it != fSetProxy.end();
104}
105
106//------------------------------------------+-----------------------------------
108
109bool RtclContext::CheckProxy(RtclProxyBase* pobj, const string& type)
110{
111 auto it = fSetProxy.find(pobj);
112 if (it == fSetProxy.end()) return false;
113 return (*it)->Type() == type;
114}
115
116//------------------------------------------+-----------------------------------
118
119void RtclContext::ListProxy(std::vector<RtclProxyBase*>& list,
120 const std::string& type)
121{
122 list.clear();
123 for (auto& po: fSetProxy) {
124 if (type.length() == 0 || po->Type()==type) {
125 list.push_back(po);
126 }
127 }
128 return;
129}
130
131//------------------------------------------+-----------------------------------
133
134RtclProxyBase* RtclContext::FindProxy(const std::string& type,
135 const std::string& name)
136{
137 for (auto& po: fSetProxy) {
138 if (type.length() == 0 || po->Type()==type) {
139 const char* cmdname = Tcl_GetCommandName(fInterp, po->Token());
140 if (name == cmdname) return po;
141 }
142 }
143 return nullptr;
144}
145
146//------------------------------------------+-----------------------------------
148
149RtclContext& RtclContext::Find(Tcl_Interp* interp)
150{
151 RtclContext* pcntx = 0;
152 auto it = fContextMap.find(interp);
153 if (it != fContextMap.end()) {
154 pcntx = it->second;
155 } else {
156 pcntx = new RtclContext(interp);
157 fContextMap.emplace(make_pair(interp, pcntx));
158 Tcl_CreateExitHandler(reinterpret_cast<Tcl_ExitProc*>(ThunkTclExitProc),
159 reinterpret_cast<ClientData>(pcntx));
160
161 }
162 return *pcntx;
163}
164
165//------------------------------------------+-----------------------------------
167
168// Note: tcl exit handlers are executed in inverse order of creation.
169// If Find() is called before any Class or Proxy cleanup handlers
170// are created the exit handler created in Find() will be called
171// last, when all map entries have been erased.
172
173void RtclContext::ThunkTclExitProc(ClientData cdata)
174{
175 RtclContext* pcntx = reinterpret_cast<RtclContext*>(cdata);
176 if (pcntx->fSetClass.empty() && pcntx->fSetProxy.empty()) {
177 delete pcntx;
178 } else {
179 cerr << "RtclContext::ThunkTclExitProc called when maps non-empty" << endl;
180 }
181 return;
182}
183
184} // end namespace Retro
FIXME_docs.
Definition: Rexception.hpp:29
void UnRegisterClass(RtclClassBase *pobj)
FIXME_docs.
Definition: RtclContext.cpp:70
cset_t fSetClass
set for Class objects
Definition: RtclContext.hpp:66
void RegisterProxy(RtclProxyBase *pobj)
FIXME_docs.
Definition: RtclContext.cpp:79
virtual ~RtclContext()
Destructor.
Definition: RtclContext.cpp:52
void ListProxy(std::vector< RtclProxyBase * > &list, const std::string &type)
FIXME_docs.
RtclProxyBase * FindProxy(const std::string &type, const std::string &name)
FIXME_docs.
bool CheckProxy(RtclProxyBase *pobj)
FIXME_docs.
Tcl_Interp * fInterp
associated tcl interpreter
Definition: RtclContext.hpp:65
RtclContext(Tcl_Interp *interp)
Default constructor.
Definition: RtclContext.cpp:43
void UnRegisterProxy(RtclProxyBase *pobj)
FIXME_docs.
Definition: RtclContext.cpp:91
static xmap_t fContextMap
map of contexts
Definition: RtclContext.hpp:69
static RtclContext & Find(Tcl_Interp *interp)
FIXME_docs.
pset_t fSetProxy
set for Proxy objects
Definition: RtclContext.hpp:67
static void ThunkTclExitProc(ClientData cdata)
FIXME_docs.
void RegisterClass(RtclClassBase *pobj)
FIXME_docs.
Definition: RtclContext.cpp:58
std::map< Tcl_Interp *, RtclContext * > xmap_t
Definition: RtclContext.hpp:38
Declaration of class ReventLoop.
Definition: ReventLoop.cpp:47