|
|
|
/*
|
|
|
|
Copyright (C) 2000 Nicolas Brodu, nicolas.brodu@free.fr
|
|
|
|
Stefan Westerfeld, stefan@space.twc.de
|
|
|
|
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
|
|
modify it under the terms of the GNU Library General Public
|
|
|
|
License as published by the Free Software Foundation; either
|
|
|
|
version 2 of the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
Library General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU Library General Public License
|
|
|
|
along with this library; see the file COPYING.LIB. If not, write to
|
|
|
|
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
|
|
Boston, MA 02110-1301, USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* BC - Status (2002-03-08): Reference, SubClass, Object, DynamicCast.
|
|
|
|
*
|
|
|
|
* Part of the public API. Must be kept binary compatible by NOT TOUCHING
|
|
|
|
* AT ALL. Interaction with generated and written code.
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef MCOP_REFERENCE_H
|
|
|
|
#define MCOP_REFERENCE_H
|
|
|
|
|
|
|
|
#include "common.h"
|
|
|
|
#include <string>
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
#include "arts_export.h"
|
|
|
|
|
|
|
|
namespace Arts {
|
|
|
|
|
|
|
|
// Acts as a string or ObjectReference, but enables a different constructor
|
|
|
|
class ARTS_EXPORT Reference {
|
|
|
|
private:
|
|
|
|
ObjectReference myref;
|
|
|
|
std::string mys;
|
|
|
|
bool strMode;
|
|
|
|
public:
|
|
|
|
|
|
|
|
inline explicit Reference(const ObjectReference& ref) {
|
|
|
|
myref=ref;
|
|
|
|
strMode=false;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline explicit Reference(const std::string& s) {
|
|
|
|
mys=s;
|
|
|
|
strMode=true;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline explicit Reference(const char* c) {
|
|
|
|
mys=c;
|
|
|
|
strMode=true;
|
|
|
|
}
|
|
|
|
inline Reference& operator=(const std::string& s) {
|
|
|
|
mys=s;
|
|
|
|
strMode=true;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
inline Reference& operator=(const char*c) {
|
|
|
|
mys=c;
|
|
|
|
strMode=true;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
inline bool isString() const {return strMode;}
|
|
|
|
// inline operator const std::string() const {return mys;}
|
|
|
|
inline const std::string& string() const {return mys;}
|
|
|
|
// inline operator const ObjectReference() const {return myref;}
|
|
|
|
inline const ObjectReference& reference() const {return myref;}
|
|
|
|
};
|
|
|
|
|
|
|
|
// Acts as a string, but enables a different constructor
|
|
|
|
class ARTS_EXPORT SubClass {
|
|
|
|
private:
|
|
|
|
std::string mys;
|
|
|
|
public:
|
|
|
|
|
|
|
|
inline explicit SubClass(const std::string& s) : mys(s) {}
|
|
|
|
inline explicit SubClass(const char* c) : mys(c) {}
|
|
|
|
inline SubClass& operator=(const std::string& s) {mys=s; return *this;}
|
|
|
|
inline SubClass& operator=(const char*c) {mys=c; return *this;}
|
|
|
|
// inline operator const std::string() const {return mys;}
|
|
|
|
inline const std::string& string() const {return mys;}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
class ScheduleNode;
|
|
|
|
class FlowSystem;
|
|
|
|
|
|
|
|
// Object has _no_ virtual, and must not have. That way, all the
|
|
|
|
// wrappers can be passed as argument or return type, and there is also
|
|
|
|
// no virtual table bloat.
|
|
|
|
// Moreover, the virtual mechanism still works correctly thanks to the
|
|
|
|
// _pool->base redirection.
|
|
|
|
class ARTS_EXPORT Object {
|
|
|
|
protected:
|
|
|
|
// Pool of common variables for a bunch a wrappers
|
|
|
|
class Pool {
|
|
|
|
friend class Object;
|
|
|
|
Object_base* (*creator)();
|
|
|
|
bool created;
|
|
|
|
int count;
|
|
|
|
public:
|
|
|
|
Object_base* base;
|
|
|
|
inline Pool(Object_base* b)
|
|
|
|
: creator(0), created(true), count(1), base(b) {}
|
|
|
|
inline Pool(Object_base* (*cor)())
|
|
|
|
: creator(cor), created(false), count(1), base(0) {}
|
|
|
|
inline void Inc() {count++;}
|
|
|
|
inline void Dec() {
|
|
|
|
if (--count==0) {
|
|
|
|
if(base) base->_release();
|
|
|
|
delete this;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
inline void checkcreate() {
|
|
|
|
if (!created) {base = creator(); created=true;}
|
|
|
|
}
|
|
|
|
} *_pool;
|
|
|
|
|
|
|
|
inline Object(Object_base* (*cor)()) {
|
|
|
|
_pool = new Pool(cor);
|
|
|
|
}
|
|
|
|
inline Object(Pool* p) : _pool(p) {
|
|
|
|
_pool->Inc();
|
|
|
|
}
|
|
|
|
inline Object(Pool& p) : _pool(&p) {
|
|
|
|
_pool->Inc();
|
|
|
|
}
|
|
|
|
inline Object(Object_base* b) {
|
|
|
|
_pool = new Pool(b);
|
|
|
|
}
|
|
|
|
public:
|
|
|
|
typedef Object_base _base_class;
|
|
|
|
|
|
|
|
// Dynamic cast constructor of inherited classes needs to access the _pool
|
|
|
|
// of a generic object if casting successful. But it could not without this
|
|
|
|
inline Pool* _get_pool() const {return _pool;}
|
|
|
|
|
|
|
|
inline ~Object() {
|
|
|
|
_pool->Dec();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Those constructors are public, since we don't need an actual creator.
|
|
|
|
// They enable generic object creation (like from a subclass defined at
|
|
|
|
// run-time!)
|
|
|
|
inline Object(const SubClass& s) {
|
|
|
|
_pool = new Pool(Object_base::_create(s.string()));
|
|
|
|
}
|
|
|
|
inline Object(const Reference &r) {
|
|
|
|
_pool = new Pool(r.isString()?(Object_base::_fromString(r.string())):(Object_base::_fromReference(r.reference(),true)));
|
|
|
|
}
|
|
|
|
inline Object(const Object& target) : _pool(target._pool) {
|
|
|
|
_pool->Inc();
|
|
|
|
}
|
|
|
|
inline Object() { // creates a null object
|
|
|
|
_pool = new Pool((Object_base*)0);
|
|
|
|
}
|
|
|
|
inline Object& operator=(const Object& target) {
|
|
|
|
if (_pool == target._pool) return *this;
|
|
|
|
_pool->Dec();
|
|
|
|
_pool = target._pool;
|
|
|
|
_pool->Inc();
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
// No problem for the creator, this class has protected constructors.
|
|
|
|
// So creator should give back an actual implementation
|
|
|
|
inline Object_base* _base() const {
|
|
|
|
_pool->checkcreate();
|
|
|
|
return _pool->base;
|
|
|
|
}
|
|
|
|
|
|
|
|
// null, error?
|
|
|
|
inline bool isNull() const {
|
|
|
|
_pool->checkcreate();
|
|
|
|
return !(_pool->base);
|
|
|
|
}
|
|
|
|
inline bool error() const {
|
|
|
|
_pool->checkcreate();
|
|
|
|
return _pool->base && _pool->base->_error();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Comparision
|
|
|
|
inline bool _isEqual(const Object& other) const {
|
|
|
|
if(isNull() != other.isNull()) return false;
|
|
|
|
|
|
|
|
// we can assume that things are created here, as we've
|
|
|
|
// called isNull of both wrappers once
|
|
|
|
if(!isNull())
|
|
|
|
return _pool->base->_isEqual(other._pool->base);
|
|
|
|
|
|
|
|
// both null references
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Object_base wrappers
|
|
|
|
|
|
|
|
// Custom messaging - see Object_base for comments
|
|
|
|
inline Buffer *_allocCustomMessage(long handlerID) const {
|
|
|
|
_pool->checkcreate();
|
|
|
|
assert(_pool->base);
|
|
|
|
return _pool->base->_allocCustomMessage(handlerID);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void _sendCustomMessage(Buffer *data) const {
|
|
|
|
_pool->checkcreate();
|
|
|
|
assert(_pool->base);
|
|
|
|
_pool->base->_sendCustomMessage(data);
|
|
|
|
}
|
|
|
|
|
|
|
|
// generic capabilities, which allow find out what you can do with an
|
|
|
|
// object even if you don't know it's interface
|
|
|
|
inline long _lookupMethod(const MethodDef& methodDef) const {
|
|
|
|
_pool->checkcreate();
|
|
|
|
assert(_pool->base);
|
|
|
|
return _pool->base->_lookupMethod(methodDef);
|
|
|
|
}
|
|
|
|
inline std::string _interfaceName() const {
|
|
|
|
_pool->checkcreate();
|
|
|
|
assert(_pool->base);
|
|
|
|
return _pool->base->_interfaceName();
|
|
|
|
}
|
|
|
|
inline InterfaceDef _queryInterface(const std::string& name) const {
|
|
|
|
_pool->checkcreate();
|
|
|
|
assert(_pool->base);
|
|
|
|
return _pool->base->_queryInterface(name);
|
|
|
|
}
|
|
|
|
inline TypeDef _queryType(const std::string& name) const {
|
|
|
|
_pool->checkcreate();
|
|
|
|
assert(_pool->base);
|
|
|
|
return _pool->base->_queryType(name);
|
|
|
|
}
|
|
|
|
inline EnumDef _queryEnum(const std::string& name) const {
|
|
|
|
_pool->checkcreate();
|
|
|
|
assert(_pool->base);
|
|
|
|
return _pool->base->_queryEnum(name);
|
|
|
|
}
|
|
|
|
// Stringification
|
|
|
|
inline std::string _toString() const {
|
|
|
|
_pool->checkcreate();
|
|
|
|
assert(_pool->base);
|
|
|
|
return _pool->base->_toString();
|
|
|
|
}
|
|
|
|
inline std::string toString() const {return _toString();}
|
|
|
|
|
|
|
|
// stuff for streaming (put in a seperate interface?)
|
|
|
|
inline void calculateBlock(unsigned long cycles) const {
|
|
|
|
_pool->checkcreate();
|
|
|
|
assert(_pool->base);
|
|
|
|
_pool->base->calculateBlock(cycles);
|
|
|
|
}
|
|
|
|
// Node info
|
|
|
|
inline ScheduleNode *_node() const {
|
|
|
|
_pool->checkcreate();
|
|
|
|
assert(_pool->base);
|
|
|
|
return _pool->base->_node();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Ah! Flowsystem is not defined yet, so cannot be returned inline.
|
|
|
|
FlowSystem _flowSystem() const;
|
|
|
|
|
|
|
|
inline void _copyRemote() const {
|
|
|
|
_pool->checkcreate();
|
|
|
|
assert(_pool->base);
|
|
|
|
_pool->base->_copyRemote();
|
|
|
|
}
|
|
|
|
inline void _useRemote() const {
|
|
|
|
_pool->checkcreate();
|
|
|
|
assert(_pool->base);
|
|
|
|
_pool->base->_useRemote();
|
|
|
|
}
|
|
|
|
inline void _releaseRemote() const {
|
|
|
|
_pool->checkcreate();
|
|
|
|
assert(_pool->base);
|
|
|
|
_pool->base->_releaseRemote();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Default I/O info
|
|
|
|
inline std::vector<std::string> _defaultPortsIn() const {
|
|
|
|
_pool->checkcreate();
|
|
|
|
assert(_pool->base);
|
|
|
|
return _pool->base->_defaultPortsIn();
|
|
|
|
}
|
|
|
|
inline std::vector<std::string> _defaultPortsOut() const {
|
|
|
|
_pool->checkcreate();
|
|
|
|
assert(_pool->base);
|
|
|
|
return _pool->base->_defaultPortsOut();
|
|
|
|
}
|
|
|
|
|
|
|
|
// aggregation
|
|
|
|
inline std::string _addChild(Arts::Object child, const std::string& name) const {
|
|
|
|
_pool->checkcreate();
|
|
|
|
assert(_pool->base);
|
|
|
|
return _pool->base->_addChild(child, name);
|
|
|
|
}
|
|
|
|
inline bool _removeChild(const std::string& name) const {
|
|
|
|
_pool->checkcreate();
|
|
|
|
assert(_pool->base);
|
|
|
|
return _pool->base->_removeChild(name);
|
|
|
|
}
|
|
|
|
inline Arts::Object _getChild(const std::string& name) const {
|
|
|
|
_pool->checkcreate();
|
|
|
|
assert(_pool->base);
|
|
|
|
return _pool->base->_getChild(name);
|
|
|
|
}
|
|
|
|
inline std::vector<std::string> * _queryChildren() const {
|
|
|
|
_pool->checkcreate();
|
|
|
|
assert(_pool->base);
|
|
|
|
return _pool->base->_queryChildren();
|
|
|
|
}
|
|
|
|
// Do we really need those in the Wrapper?
|
|
|
|
// And would it really be sensible to make _cast wrappers?
|
|
|
|
/* inline void _release() const {
|
|
|
|
_pool->checkcreate();
|
|
|
|
assert(_pool->base);
|
|
|
|
return _pool->base->_release();
|
|
|
|
}
|
|
|
|
inline Object_base *_copy() const {
|
|
|
|
_poo->checkcreate();
|
|
|
|
assert(_pool->base);
|
|
|
|
return _pool->base->_copy();
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
|
|
|
|
// Object::null() returns a null object (and not just a reference to one)
|
|
|
|
inline static Object null() {return Object((Object_base*)0);}
|
|
|
|
inline static Object _from_base(Object_base* b) {return Object(b);}
|
|
|
|
};
|
|
|
|
|
|
|
|
// Enables a different constructor, that should do the cast
|
|
|
|
class ARTS_EXPORT DynamicCast {
|
|
|
|
private:
|
|
|
|
Object obj;
|
|
|
|
public:
|
|
|
|
inline explicit DynamicCast(const Object& o) : obj(o) {}
|
|
|
|
inline const Object& object() const {return obj;}
|
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|