Next Previous Up Top


5 Examples

5.4 Simulation Objects


5.4 Simulation Objects


In some applications, the user of a reified object -- the object calling a reified function -- needs to be known or accessed within the proxy. This is a quite well known and commonly required feature that many meta-object protocols have problems achieving.

Within the europa standard, this functionality can be obtained in a quite straighforward manner, as explained in the rest of this section. The solution relies on the ability to define member functions within reified classes are not reified, but executed directly by the proxy.

To illustrate this feature, we will take the example of a library offering Parallel Discrete Event Simulation based on active objects. A simulation is a collection of concurrently active simulation objects derived from a special class, let us say Sim_Process. Such classes have public member functions that represent the services being simulated. Typically, such a library can be defined using europa, first taking advantage of reification to control the execution of services within the simulation time, but also to achieve the parallel/distributed execution. One reason that leads to the need of the special functionality -- the object calling a reified function being accessed within the proxy -- is two fold:

Let us say we have a simulation object Sim_Supermarket, that represents a supermarket simulation, holding a service routine enter modelling the entrance of a new client.

The simulation class can feature a special routine, setup, defined on the Sim_Process as a non reified routine to be executed directly by the proxy -- using a technique similar to the Awaited routine defined in the future example (class Future, section 5.2.2). Then, the simulation object can be used as follows:

void main() {
	Sim_Supermarket* sim_obj;
	sim_obj = ec_new ((), Sim_Supermarket, ());
	sim_obj->setup(this,max_prority,time(10)); // Not reified
	sim_obj->enter(blond,woman,thin);           // Reified
	...
	sim_obj->setup(this,min_priority,time(10));
	sim_obj->enter(blond,man,tall);
	...
}

If one really requires to have both the call to the original function, and the extra parmeters within a single and somehow atomic call, a macro can be used to hide the two calls being executed:

#define SIM_CALL(object , call , setupl, setup2, setup3) \
	(object->setup(setupl,setup2,setup3), object->call)
SIM_CALL(sim_obj,enter(blond,woman,thin), this,max_priority,time(10));
SIM_CALL(sim_obj,enter(blond,man,tall), this,min_priority,time(10));

Please note that this technique provides a means to make the call atomic in a convenient manner as locking functions can be included within the macro. The technique is also valid when the service being called needs to return a value:

val = SIM_CALL(sim_obj,leave(blond,woman,thin),this,max_priority,time(10));

Another possibility, if a reified object is used by a unique client, is to set the user object at construction time. Then, the parameter this does not need to be specified for each call any more, and the control parameters can be set directly within the client, whenever they need to be modified; the proxy has the possibility to access them directly.

void main()
{
	Sim_Supermarket* sim_obj;
	sim_obj = ec_new ((), Sim_Supermarket, (this));
	prority = max_prority; time = 10;
	sim_obj->enter(blond,woman,thin);
	prority = min_priority
	sim_obj->enter(blond,man,tall);
}

Copyright 1997 EUROPA WG

Last updated: 26 Nov 1997