![]()
An SAO can be placed onto a named machine or will otherwise be placed on a machine chosen by the run-time system.
All member function calls to the object originating outside the object are forwarded over the communication substrate, and are queued: such calls are referred to as messages. Calls of local member functions (i.e. one member function of an SAO calling another on the same object) are dealt with immediately, and do not become messages. These are referred to as local member function calls.
All message calls on an object require a pointer to the object as returned >from `new': this can be passed to other SAO's in parameter lists.
All messages with void return type are by default non-blocking and all message with non-void return type are by default blocking. All messages with reference and pointer parameters (except pointers to active objects) are required to be blocking. Local member function calls are always blocking.
Returning reference and pointer parameters (except to active objects) is banned. Direct access to data members of an SAO from outside the object is banned.
An SAO deals with only one message at a time. All messages from a single source are guaranteed to keep their ordering, but messages from different sources will have arbitrary interleaving. All messages are dealt with in the order they are queued, regardless of source, except for `exception' messages which cause execution to be interrupted and the relevant exception handler to be called. A default exception handler is defined that causes an error message to be sent to the error stream, a standard exception to be propagated and the objects destructor to be called.
An SAO that is not dealing with a message will always retrieve the next message from the queue in due course unless the queue is empty, in which case it will wait for messages to arrive. An SAO that is not dealing with a message and that does not have an empty queue will not be blocked by the state of other active or passive objects (i.e. acts as if it has its own thread).
There is no flow control by default. The message queue will extend until memory is exhausted at which point a defined exception is raised. Messages received after that point may be lost.
The member function blockWait() is defined which is always blocking and which always returns true and cannot be elided by the compiler. It will always return after all previous messages >from the caller to the SAO have been processed. The public member function isactive() is provided, which returns true iff the object is active.
Aside: The following point depends on other definitions. In particular there is the notion of there being two types of classes:
- C++ classes
- EUROPA classes, which are classes that inherit from public virtual bases class EUROPA (and nothing else).
Only the latter have the mechanisms in place to allow them to be distributed (they have necessary but not sufficient mechanisms).
This distinction is made for two reasons:
- Because of the C++ policy of `you don't pay for what you don't use': it allows the programmer to create classes that do not have the overhead implied by being distributable.
- So that the standard meanings and implementations of C++ classes are preserved.
SAO classes (that is classes that inherit from EuropaSimpleActiveObject) cannot have as direct or indirect base classes any non-EUROPA class.
![]()