/* Copyright (C) 1999-2000 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. */ module Arts { // MCOP protocol enum HeaderMagic { MCOP_MAGIC = 0x4d434f50 }; /* gets marshalled as "MCOP" */ /* decimal 1296256848 */ enum MessageType { mcopMessageInvalid = 0, /* never send this */ mcopServerHello = 1, mcopClientHello = 2, mcopAuthAccept = 3, mcopInvocation = 4, mcopReturn = 5, mcopOnewayInvocation = 6 }; /** * This type is sent as header of each MCOP message. */ struct Header { /** * the value 0x504f434d, which is marshalled as MCOP */ HeaderMagic magic; long messageLength; MessageType messageType; }; /** * This is sent as start of each normal (twoway) invocation */ struct Invocation { /** * The ID of the object receiving the request */ long objectID; /** * The ID of the method that is to be invoked */ long methodID; /** * A unique number of the request (needed to send the return code back) */ long requestID; }; /** * This is sent as start of each oneway invocation */ struct OnewayInvocation { /** * The ID of the object receiving the request */ long objectID; /** * The ID of the method that is to be invoked */ long methodID; }; /** * Body of the mcopServerHello MCOP message */ struct ServerHello { string mcopVersion; string serverID; sequence authProtocols; string authSeed; }; /** * Body of the mcopClientHello MCOP message */ struct ClientHello { string serverID; string authProtocol; string authData; }; /** * The message you get when you connect a MCOP server. The MCOP server can * send you some useful information here. Usually, it will send you * * GlobalComm= * InterfaceRepo= * * But as this is called "hints" it doesn't necessarily need to happen. */ struct AuthAccept { sequence hints; }; /** * An object reference */ struct ObjectReference { /** * A unique ID for the server the object is located on, (a server ID may * i.e. be composed of start time, hostname, and pid) */ string serverID; /** * The number of the object under that server */ long objectID; /** * where the server holding object can be reached */ sequence urls; }; // Interface definitions /** * The definition of a parameter of a method * * hints is reserved for future extensions, such as default, min and maxvalues */ struct ParamDef { string type; string name; sequence hints; }; /** * Twoway methods are such where the calling process does a call and is * suspended until some result (maybe even a void result) gets back. * * Oneway methods are one shot and forget methods: you send the invocation, * and continue. Maybe it will be received, maybe executed later. You will * never hear the result. */ enum MethodType { methodOneway = 1, methodTwoway = 2 }; /** * The definition of a method. * * hints is reserved for future extensions, such as default, min and maxvalues */ struct MethodDef { string name; string type; MethodType flags; sequence signature; sequence hints; }; /** * an attribute * * flags should contain things like * * @li attribute is readonly/writeonly/readwrite * @li attribute is incoming/outgoing stream * @li if it's a stream, it also should contain the information whether it is * asynchronous or synchronous * @li NB20000320: see InterfaceDef for the meaning of streamDefault */ enum AttributeType { streamIn = 1, streamOut = 2, streamMulti = 4, attributeStream = 8, attributeAttribute = 16, streamAsync = 32, streamDefault = 64 }; /** * The definition of an attribute and/or stream * * hints is reserved for future extensions, such as default, min and maxvalues */ struct AttributeDef { string name; string type; AttributeType flags; sequence hints; }; /** * InterfaceDef - interface definition structure * * defines what methods/attributes a particular interface supports: these * do not contain the methods/attributes of inherited interfaces. * * inheritedInterfaces only contains the names of Interfaces that this one * inherits in exactly one step. So to see if interface XYZ is inherited * from ABC, you need to check the "inheritedInterfaces" of XYZ, and their * "inheritedInterfaces" and their "inheritedInterfaces" and so on. * * - NB20000320: defaultPorts allows to connect to those port by default if * connection is made in the corresponding direction. * It cannot be just an attribute flag because of the syntax * on a separate line. * * hints is reserved for future extensions, such as default, min and maxvalues */ struct InterfaceDef { string name; sequence inheritedInterfaces; sequence methods; sequence attributes; sequence defaultPorts; sequence hints; }; // Type definitions (struct's and such) /** * One component of a struct * * hints is reserved for future extensions, such as default, min and maxvalues */ struct TypeComponent { string type; string name; sequence hints; }; /** * The definition of a struct * * hints is reserved for future extensions, such as default, min and maxvalues */ struct TypeDef { string name; sequence contents; sequence hints; }; /** * One item of an enum value * * hints is reserved for future extensions, such as default, min and maxvalues */ struct EnumComponent { string name; long value; sequence hints; }; /** * The definition of an enum * * hints is reserved for future extensions, such as default, min and maxvalues */ struct EnumDef { /** * name if the enum, "_anonymous_" for anonymous enum - of course, when * using namespaces, this can also lead to things like "Arts::_anonymous_", * which would mean an anonymous enum in the Arts namespace */ string name; sequence contents; sequence hints; }; /** * The contents of an idl file * * hints is reserved for future extensions, such as default, min and maxvalues */ struct ModuleDef { string moduleName; sequence enums; sequence types; sequence interfaces; sequence hints; }; /** * The interface repository */ interface InterfaceRepo { /** * inserts the contents of a module into the interface repository * * @returns an ID which can be used to remove the entry again */ long insertModule(ModuleDef newModule); /** * removes the contents of a module from the interface repository */ void removeModule(long moduleID); /** * queries the definition of an interface */ InterfaceDef queryInterface(string name); /** * queries the definition of a type */ TypeDef queryType(string name); /** * queries the definition of an enum value */ EnumDef queryEnum(string name); /** * queries all interfaces that inherit a given interface */ sequence queryChildren(string name); /** * queries all interfaces */ sequence queryInterfaces(); /** * queries all types */ sequence queryTypes(); /** * queries all enums */ sequence queryEnums(); }; enum TypeIdentification { tiUnknown = 0, tiVoid = 1, tiLong = 2, tiByte = 3, tiString = 4, tiBoolean = 5, tiFloat = 6, tiEnum = 128, tiType = 129, tiInterface = 130 }; interface InterfaceRepoV2 : InterfaceRepo { /** * identifies whether a type is a primitive, enum, type or interface, * or not known at all */ TypeIdentification identifyType(string name); }; /** * Flow System interface */ /** * Internal use: implement distributed asynchronous streams. * * The FlowSystemSender object transmits the packets that should be sent * over the stream via _allocCustomMessage (Object_base). */ interface FlowSystemSender { /** * This method is invoked whenever the receiver has finished processing * a packet of the stream */ oneway void processed(); /** * This method is for telling the local FlowSystemSender to break the * connection to the remote Receiver (it's not intended to be called * remotely) */ void disconnect(); }; /** * Internal use: implement distributed asynchronous streams. * * The FlowSystemReceiver object receives and extracts the packets sent by * the sender object and injects them in the notification system again. */ interface FlowSystemReceiver { /** * The custom message ID which should be used to send the stream packets */ readonly attribute long receiveHandlerID; /** * This method is for telling the local FlowSystemReceiver to break the * connection to the remote Sender (it's not intended to be called * remotely) */ void disconnect(); }; /** * A flow system. * * Flow systems handle the streaming between MCOP objects. As this streaming * is network transparent (at least for asynchronous streams) they have this * remote interface. */ interface FlowSystem { /** * This starts a scheduling node * * Don't use this manually. Use object->_node()->connect(...) instead. */ void startObject(object node); /** * This stops a scheduling node * * Don't use this manually. Use object->_node()->connect(...) instead. */ void stopObject(object node); /** * This connects two objects, maybe even remote * * it is important that * - sourceObject/sourcePort points to the node the signal flow is * coming from * - destObject/destPort points to the node/port the signal flow is * going to * * Don't use this manually. Use object->_node()->connect(...) instead. */ void connectObject(object sourceObject, string sourcePort, object destObject, string destPort); /** * This disconnects two objects, maybe even remote * * it is important that * @li sourceObject/sourcePort points to the node the signal flow is * coming from * @li destObject/destPort points to the node/port the signal flow is * going to * * Don't use this manually. Use object->_node()->connect(...) instead. */ void disconnectObject(object sourceObject, string sourcePort, object destObject, string destPort); /** * queries the stream flags - returns 0 when such a stream isn't * present */ AttributeType queryFlags(object node, string port); /** * directly sets an audio port to a fixed value */ void setFloatValue(object node, string port, float value); /** * network transparent connections */ FlowSystemReceiver createReceiver(object destObject, string destPort, FlowSystemSender sender); }; /** * A global communication space used to obtain initial object references * * MCOP needs a way to connect to initial (global) object references. This * is done by these global communication spaces. */ interface GlobalComm { /** * puts a variable/value pair into the global communication * space - it will not change the value of the variable if it is * already present. Returns true if success, false if the variable * was already there. */ boolean put(string variable, string value); /** * gets the value of a variable out of the global communication * space - it returns an empty string when the variable isn't there */ string get(string variable); /** * removes a variable from the global communication space */ void erase(string variable); }; /** * global communication based on the /tmp/mcop- directory */ interface TmpGlobalComm : GlobalComm { }; /* * Trading interfaces follow - trading is used to locate objects with certain * properties. This is especially recommended, if you want to allow that after * your code has been released, people can extend it, without changing your * code, by adding new components. */ /** * TraderOffer - this contains an offer of an object (which is usually returned * as result of a query. */ interface TraderOffer { /** * You can use this interface name to create one of the objects that * fulfill your query */ readonly attribute string interfaceName; /** * This allows you to query additional information about the offer, * such as the author of the plugin, the name of the library that * implements it (if it is a library) or similar. * * Since some properties support having multiple values, this always * returns a sequence, which may be empty if the property isn't * present at all. */ sequence getProperty(string name); }; /** * TraderQuery - this is a query against the trader. The idea is simple: you * say what you need, and the trader offers you components that do what you * want. */ interface TraderQuery { /** * This restricts the query to only objects which support a "property" * with the value "value". For instance, you could say * * aquery.supports("Interface","Arts::PlayObject"); * * to restrict the matching objects to only those that support the * interface Arts::PlayObject */ void supports(string property, string value); /** * This performs the query, and returns a set of results */ sequence query(); }; /** * Arts::Object is the base object that every interface implicitely inherits * * it is also the source for generation of the Object_stub stuff * (use mcopidl -e Arts::Object to avoid code generation for this interface) */ interface Object { /** * access to the flow system this object is running in */ readonly attribute FlowSystem _flowSystem; /** * returns the ID for methodinvocations to this specific method * methodID = 0 => _lookupMethod (always) */ long _lookupMethod(MethodDef methodDef); /** * returns the name of the interface * methodID = 1 => _interfaceName (always) */ string _interfaceName(); /** * returns the interface description to a given interface * methodID = 2 => _queryInterface (always) */ InterfaceDef _queryInterface(string name); /** * returns the type description to a given type * methodID = 3 => _queryType (always) */ TypeDef _queryType(string name); /** * returns the enum description to a given enum * methodID = 4 => _queryEnum (always) */ EnumDef _queryEnum(string name); /** * stringifies the object to one string */ string _toString(); /** * Run-time type compatibility check */ boolean _isCompatibleWith(string interfacename); /** * prepares object for remote transmission (so that it will not be freed * soon, since the remote receiver expects it to be there after receiving * it) */ void _copyRemote(); /** * declares that the object is used remotely now (do that only after * _copyRemote) */ void _useRemote(); /** * declares that the object is no longer used remotely */ void _releaseRemote(); /** * add a child object - this makes this object hold a strong reference to * the child object (i.e. the child object will stay alive at least as * long as the object does) * * if there is already a child with the same name, a postfix will be added * automatically (i.e. if you add an object named "view" twice, the first * will be called view, the second view1). */ string _addChild(object child, string name); /** * removes a child object */ boolean _removeChild(string name); /** * gets a child object */ object _getChild(string name); /** * lists all children */ sequence _queryChildren(); }; /** * a simple struct which can hold any other type */ struct Any { string type; sequence value; }; /** * TraderEntries as produced by the loader */ struct TraderEntry { string interfaceName; sequence lines; }; /** * loader to load plugins (implemented in some language/binary format) */ interface Loader { object loadObject(TraderOffer offer); /* * this is used for the type system to cache your trader data and * module data as long as it stays unchanged */ readonly attribute string dataVersion; /* * the trader entries of the components that can be loaded */ readonly attribute sequence traderEntries; /* * the interface information of the components that can be loaded */ readonly attribute sequence modules; }; };