summaryrefslogtreecommitdiffstats
path: root/mcop/reference.h
diff options
context:
space:
mode:
Diffstat (limited to 'mcop/reference.h')
-rw-r--r--mcop/reference.h349
1 files changed, 349 insertions, 0 deletions
diff --git a/mcop/reference.h b/mcop/reference.h
new file mode 100644
index 0000000..ae59df6
--- /dev/null
+++ b/mcop/reference.h
@@ -0,0 +1,349 @@
+/*
+ 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., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, 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