// $Id: RtclContext.cpp 492 2013-02-24 22:14:47Z mueller $
|
// $Id: RtclContext.cpp 492 2013-02-24 22:14:47Z mueller $
|
//
|
//
|
// Copyright 2011-2013 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
// Copyright 2011-2013 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
//
|
//
|
// This program is free software; you may redistribute and/or modify it under
|
// This program is free software; you may redistribute and/or modify it under
|
// the terms of the GNU General Public License as published by the Free
|
// the terms of the GNU General Public License as published by the Free
|
// Software Foundation, either version 2, or at your option any later version.
|
// Software Foundation, either version 2, or at your option any later version.
|
//
|
//
|
// This program is distributed in the hope that it will be useful, but
|
// This program is distributed in the hope that it will be useful, but
|
// WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
|
// WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
|
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
// for complete details.
|
// for complete details.
|
//
|
//
|
// Revision History:
|
// Revision History:
|
// Date Rev Version Comment
|
// Date Rev Version Comment
|
// 2013-02-03 481 1.0.3 use Rexception
|
// 2013-02-03 481 1.0.3 use Rexception
|
// 2013-01-12 474 1.0.2 add FindProxy() method
|
// 2013-01-12 474 1.0.2 add FindProxy() method
|
// 2011-03-12 368 1.0.1 drop fExitSeen, get exit handling right
|
// 2011-03-12 368 1.0.1 drop fExitSeen, get exit handling right
|
// 2011-02-18 362 1.0 Initial version
|
// 2011-02-18 362 1.0 Initial version
|
// 2011-02-13 361 0.1 First draft
|
// 2011-02-13 361 0.1 First draft
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
|
|
/*!
|
/*!
|
\file
|
\file
|
\version $Id: RtclContext.cpp 492 2013-02-24 22:14:47Z mueller $
|
\version $Id: RtclContext.cpp 492 2013-02-24 22:14:47Z mueller $
|
\brief Implemenation of RtclContext.
|
\brief Implemenation of RtclContext.
|
*/
|
*/
|
|
|
#include <iostream>
|
#include <iostream>
|
|
|
#include "RtclContext.hpp"
|
#include "RtclContext.hpp"
|
|
|
#include "librtools/Rexception.hpp"
|
#include "librtools/Rexception.hpp"
|
|
|
using namespace std;
|
using namespace std;
|
|
|
/*!
|
/*!
|
\class Retro::RtclContext
|
\class Retro::RtclContext
|
\brief FIXME_docs
|
\brief FIXME_docs
|
*/
|
*/
|
|
|
// all method definitions in namespace Retro
|
// all method definitions in namespace Retro
|
namespace Retro {
|
namespace Retro {
|
|
|
typedef std::pair<RtclContext::cset_it_t, bool> cset_ins_t;
|
typedef std::pair<RtclContext::cset_it_t, bool> cset_ins_t;
|
typedef std::pair<RtclContext::pset_it_t, bool> pset_ins_t;
|
typedef std::pair<RtclContext::pset_it_t, bool> pset_ins_t;
|
|
|
RtclContext::xmap_t RtclContext::fMapContext;
|
RtclContext::xmap_t RtclContext::fMapContext;
|
|
|
//------------------------------------------+-----------------------------------
|
//------------------------------------------+-----------------------------------
|
//! Default constructor
|
//! Default constructor
|
|
|
RtclContext::RtclContext(Tcl_Interp* interp)
|
RtclContext::RtclContext(Tcl_Interp* interp)
|
: fInterp(interp),
|
: fInterp(interp),
|
fSetClass(),
|
fSetClass(),
|
fSetProxy()
|
fSetProxy()
|
{}
|
{}
|
|
|
//------------------------------------------+-----------------------------------
|
//------------------------------------------+-----------------------------------
|
//! Destructor
|
//! Destructor
|
|
|
RtclContext::~RtclContext()
|
RtclContext::~RtclContext()
|
{}
|
{}
|
|
|
//------------------------------------------+-----------------------------------
|
//------------------------------------------+-----------------------------------
|
//! FIXME_docs
|
//! FIXME_docs
|
|
|
void RtclContext::RegisterClass(RtclClassBase* pobj)
|
void RtclContext::RegisterClass(RtclClassBase* pobj)
|
{
|
{
|
cset_ins_t ret = fSetClass.insert(pobj);
|
cset_ins_t ret = fSetClass.insert(pobj);
|
if (ret.second == false) // or use !(ret.second)
|
if (ret.second == false) // or use !(ret.second)
|
throw Rexception("RtclContext::RegisterClass()",
|
throw Rexception("RtclContext::RegisterClass()",
|
"Bad args: duplicate pointer");
|
"Bad args: duplicate pointer");
|
return;
|
return;
|
}
|
}
|
|
|
//------------------------------------------+-----------------------------------
|
//------------------------------------------+-----------------------------------
|
//! FIXME_docs
|
//! FIXME_docs
|
|
|
void RtclContext::UnRegisterClass(RtclClassBase* pobj)
|
void RtclContext::UnRegisterClass(RtclClassBase* pobj)
|
{
|
{
|
fSetClass.erase(pobj);
|
fSetClass.erase(pobj);
|
return;
|
return;
|
}
|
}
|
|
|
//------------------------------------------+-----------------------------------
|
//------------------------------------------+-----------------------------------
|
//! FIXME_docs
|
//! FIXME_docs
|
|
|
void RtclContext::RegisterProxy(RtclProxyBase* pobj)
|
void RtclContext::RegisterProxy(RtclProxyBase* pobj)
|
{
|
{
|
pset_ins_t ret = fSetProxy.insert(pobj);
|
pset_ins_t ret = fSetProxy.insert(pobj);
|
if (ret.second == false) // or use !(ret.second)
|
if (ret.second == false) // or use !(ret.second)
|
throw Rexception("RtclContext::RegisterProxy()",
|
throw Rexception("RtclContext::RegisterProxy()",
|
"Bad args: duplicate pointer");
|
"Bad args: duplicate pointer");
|
return;
|
return;
|
}
|
}
|
|
|
//------------------------------------------+-----------------------------------
|
//------------------------------------------+-----------------------------------
|
//! FIXME_docs
|
//! FIXME_docs
|
|
|
void RtclContext::UnRegisterProxy(RtclProxyBase* pobj)
|
void RtclContext::UnRegisterProxy(RtclProxyBase* pobj)
|
{
|
{
|
fSetProxy.erase(pobj);
|
fSetProxy.erase(pobj);
|
return;
|
return;
|
}
|
}
|
|
|
//------------------------------------------+-----------------------------------
|
//------------------------------------------+-----------------------------------
|
//! FIXME_docs
|
//! FIXME_docs
|
|
|
bool RtclContext::CheckProxy(RtclProxyBase* pobj)
|
bool RtclContext::CheckProxy(RtclProxyBase* pobj)
|
{
|
{
|
pset_it_t it = fSetProxy.find(pobj);
|
pset_it_t it = fSetProxy.find(pobj);
|
return it != fSetProxy.end();
|
return it != fSetProxy.end();
|
}
|
}
|
|
|
//------------------------------------------+-----------------------------------
|
//------------------------------------------+-----------------------------------
|
//! FIXME_docs
|
//! FIXME_docs
|
|
|
bool RtclContext::CheckProxy(RtclProxyBase* pobj, const string& type)
|
bool RtclContext::CheckProxy(RtclProxyBase* pobj, const string& type)
|
{
|
{
|
pset_it_t it = fSetProxy.find(pobj);
|
pset_it_t it = fSetProxy.find(pobj);
|
if (it == fSetProxy.end()) return false;
|
if (it == fSetProxy.end()) return false;
|
return (*it)->Type() == type;
|
return (*it)->Type() == type;
|
}
|
}
|
|
|
//------------------------------------------+-----------------------------------
|
//------------------------------------------+-----------------------------------
|
//! FIXME_docs
|
//! FIXME_docs
|
|
|
void RtclContext::ListProxy(std::vector<RtclProxyBase*>& list,
|
void RtclContext::ListProxy(std::vector<RtclProxyBase*>& list,
|
const std::string& type)
|
const std::string& type)
|
{
|
{
|
list.clear();
|
list.clear();
|
for (pset_it_t it = fSetProxy.begin(); it != fSetProxy.end(); it++) {
|
for (pset_it_t it = fSetProxy.begin(); it != fSetProxy.end(); it++) {
|
if (type.length() == 0 || (*it)->Type()==type) {
|
if (type.length() == 0 || (*it)->Type()==type) {
|
list.push_back(*it);
|
list.push_back(*it);
|
}
|
}
|
}
|
}
|
return;
|
return;
|
}
|
}
|
|
|
//------------------------------------------+-----------------------------------
|
//------------------------------------------+-----------------------------------
|
//! FIXME_docs
|
//! FIXME_docs
|
|
|
RtclProxyBase* RtclContext::FindProxy(const std::string& type,
|
RtclProxyBase* RtclContext::FindProxy(const std::string& type,
|
const std::string& name)
|
const std::string& name)
|
{
|
{
|
for (pset_it_t it = fSetProxy.begin(); it != fSetProxy.end(); it++) {
|
for (pset_it_t it = fSetProxy.begin(); it != fSetProxy.end(); it++) {
|
if (type.length() == 0 || (*it)->Type()==type) {
|
if (type.length() == 0 || (*it)->Type()==type) {
|
const char* cmdname = Tcl_GetCommandName(fInterp, (*it)->Token());
|
const char* cmdname = Tcl_GetCommandName(fInterp, (*it)->Token());
|
if (name == cmdname) return *it;
|
if (name == cmdname) return *it;
|
}
|
}
|
}
|
}
|
return 0;
|
return 0;
|
}
|
}
|
|
|
//------------------------------------------+-----------------------------------
|
//------------------------------------------+-----------------------------------
|
//! FIXME_docs
|
//! FIXME_docs
|
|
|
RtclContext& RtclContext::Find(Tcl_Interp* interp)
|
RtclContext& RtclContext::Find(Tcl_Interp* interp)
|
{
|
{
|
RtclContext* pcntx = 0;
|
RtclContext* pcntx = 0;
|
xmap_it_t it = fMapContext.find(interp);
|
xmap_it_t it = fMapContext.find(interp);
|
if (it != fMapContext.end()) {
|
if (it != fMapContext.end()) {
|
pcntx = it->second;
|
pcntx = it->second;
|
} else {
|
} else {
|
pcntx = new RtclContext(interp);
|
pcntx = new RtclContext(interp);
|
fMapContext.insert(xmap_val_t(interp, pcntx));
|
fMapContext.insert(xmap_val_t(interp, pcntx));
|
Tcl_CreateExitHandler((Tcl_ExitProc*) ThunkTclExitProc, (ClientData) pcntx);
|
Tcl_CreateExitHandler((Tcl_ExitProc*) ThunkTclExitProc, (ClientData) pcntx);
|
|
|
}
|
}
|
return *pcntx;
|
return *pcntx;
|
}
|
}
|
|
|
//------------------------------------------+-----------------------------------
|
//------------------------------------------+-----------------------------------
|
//! FIXME_docs
|
//! FIXME_docs
|
|
|
// Note: tcl exit handlers are executed in inverse order of creation.
|
// Note: tcl exit handlers are executed in inverse order of creation.
|
// If Find() is called before any Class or Proxy cleanup handlers
|
// If Find() is called before any Class or Proxy cleanup handlers
|
// are created the exit handler created in Find() will be called
|
// are created the exit handler created in Find() will be called
|
// last, when all map entries have been erased.
|
// last, when all map entries have been erased.
|
|
|
void RtclContext::ThunkTclExitProc(ClientData cdata)
|
void RtclContext::ThunkTclExitProc(ClientData cdata)
|
{
|
{
|
RtclContext* pcntx = (RtclContext*) cdata;
|
RtclContext* pcntx = (RtclContext*) cdata;
|
if (pcntx->fSetClass.empty() && pcntx->fSetProxy.empty()) {
|
if (pcntx->fSetClass.empty() && pcntx->fSetProxy.empty()) {
|
delete pcntx;
|
delete pcntx;
|
} else {
|
} else {
|
cerr << "RtclContext::ThunkTclExitProc called when maps non-empty" << endl;
|
cerr << "RtclContext::ThunkTclExitProc called when maps non-empty" << endl;
|
}
|
}
|
return;
|
return;
|
}
|
}
|
|
|
} // end namespace Retro
|
} // end namespace Retro
|
|
|