Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | Related Pages

GCS::GAgent Class Reference

Defines the behaviour of an element. More...

#include <GAgent.h>

Inheritance diagram for GCS::GAgent:

Inheritance graph
[legend]
Collaboration diagram for GCS::GAgent:

Collaboration graph
[legend]
List of all members.

Public Slots

virtual void receiveInfluence (GCS::GElementInfluence &)

Signals

void sendInfluence (const GCS::GElementID &target, GCS::GElementInfluence &influence)
void radiateInfluence (GCS::GElementInfluence &influence)
void parentChanged (const GCS::GElementID &oldParent, const GCS::GElementID &newParent)
void energyChanged (const GCS::GEnergy &changedEnergy)
void formChanged (const GCS::GForm &changedForm)
void agentChanged (const GCS::GAgent &changedAgent)
void childElementCreated (GCS::GElement *newElement)
void childElementRemoved (const GCS::GElementID &childID)

Public Member Functions

 GAgent (QObject *parent=0, const char *name=0)
virtual ~GAgent ()
virtual bool isParked () const

Protected Slots

virtual void beginPark ()
virtual void threadStart (double seconds_elapsed)

Protected Member Functions

virtual void run ()
GObjectrequestObject ()
GEnergyrequestEnergy ()
GFormrequestForm ()
const QPtrList< GAgent > & requestAgents () const
const GElementIDgetElementID () const
const GElementIDgetConnectionID () const

Protected Attributes

bool shutdown

Private Attributes

GObjectObject
const QPtrList< GAgent > * Agents

Friends

class GElement

Detailed Description

Defines the behaviour of an element.

Author:
Raphael Langerhorst
Agents are used to give the element functionality or life. All actions of the element come from its agents, even all laws (gravity, ...) that the element adhers to are implemented by agents;

To implement an agent this class must be inherited and all desired abstract methods have to be implemented. In particular GAgent::run() and GAgent::receiveInfluence() are of interest. Additionally the virtual methods for parking and resuming execution can be used for various purposes. Especially threadStart() can be used to react to the time passed between parking the agent and resuming execution.

Implementing agents directly on top of this class is of course the most powerful way for agent implementation. But it could be a wise idea to create another agent interface layer that is for example capable of scripting and runtime code morphing.

Signals that represent data changes such as energyChanged() have to be emitted by the agent on purpose, they are not automated.

This gives greater control over message broadcasting and thus it is easier to minimize overhead when the agent makes multiple changes. But this also means more responsibility for the agent developer.

Todo:
Changed signals such as energyChanged() should also be received

by the agent since other agents could emit these and it should

be possible to react to these events.

signal for reparenting


Constructor & Destructor Documentation

GCS::GAgent::GAgent QObject *  parent = 0,
const char *  name = 0
 

The constructor does not need any kind of parameter. The optional parameters are forwarded to the constructor of QObject.

virtual GCS::GAgent::~GAgent  )  [inline, virtual]
 

The virtual destructor makes sure that inherited classes are cleanly destroyed when only a pointer to GAgent is used for freeing memory. Please make sure that all subclasses of GAgent have a virtual destructor.


Member Function Documentation

void GCS::GAgent::agentChanged const GCS::GAgent changedAgent  )  [signal]
 

Emitted when the agent changed it's state/data.

Note:
not automated!

void GCS::GAgent::beginPark  )  [protected, virtual, slot]
 

Called when the agent should start to park itself. An Agent is considered to be parked when the thread ceases to execute. By default, this method sets shutdown to true and returns immediately.

See also:
shutdown

void GCS::GAgent::childElementCreated GCS::GElement newElement  )  [signal]
 

Emitted when a child element has been created.

Note:
: if you create a child and don't emit this signal it is NOT guranteed that your element get's recognized by the GWE.

void GCS::GAgent::childElementRemoved const GCS::GElementID childID  )  [signal]
 

Emitted when a child element was removed (deleted). note: This signal should NOT be emitted when the child just changed its parent. The GWE is responsible for removing the specified element from memory.

void GCS::GAgent::energyChanged const GCS::GEnergy changedEnergy  )  [signal]
 

Emitted when the element's energy has changed.

Note:
not automated!

void GCS::GAgent::formChanged const GCS::GForm changedForm  )  [signal]
 

Emitted when the element's form has changed.

Note:
not automated!

const GElementID & GCS::GAgent::getConnectionID  )  const [protected]
 

Returns:
the element's connection ID (const reference)

const GElementID & GCS::GAgent::getElementID  )  const [protected]
 

Returns:
the element's ID (const reference)

bool GCS::GAgent::isParked  )  const [virtual]
 

Tells whether the agent is currently executing or not.

Note:
QThread is executing run() as a thread! If no additional threads are created then there is no need to reimplement this method because the current implementation will check QThread::running()

If you reimplement this method be sure to call the base method with GAgent::isParked() and immediately return false if this call returns false:

bool CustomAgent::isParked() { if (!GAgent::isParked()) return false; //check other threads that belong to this agent }

Normally you don't need to reimplement this but it might be possible that a subclass of GAgent uses several threads and then a simple check of the agent's main thread wouldn't be enough.

void GCS::GAgent::parentChanged const GCS::GElementID oldParent,
const GCS::GElementID newParent
[signal]
 

Emitted when the element moves out of its current parent region into another parent region.

Note:
This means a restructuring of the element hierarchy! The GWE might be interested in this.

void GCS::GAgent::radiateInfluence GCS::GElementInfluence influence  )  [signal]
 

If an influence is not supposed to be sent to a specific target, then it can also be radiated with this signal. It depends on the implementation in the GWE which elements receive this influence. Currently this includes the parent, all direct children and all elements that are in contact with this element (in terms of location and form). But this always depends on the GWE in use, please check the relevant documentation.

See also:
GWE::GWEInterface

void GCS::GAgent::receiveInfluence GCS::GElementInfluence  )  [virtual, slot]
 

When an influence reaches an element it is forwarded to every agent of that element through this slot. All influence handling should go here.

Note:
Please be aware that receiveInfluence and all agent threads of the element, GAgent::run(), might be executed in parallel! Consider using locking mechanisms for the element's form, energy and object. All of them inherit QMutex, use it. Also consider using QMutexLocker because it makes locking quite easy.

Reimplemented in GBE::GAttractAgent, GBE::GDynamicGeneratorAgent, GBE::GInfluenceableAgent, GBE::GInvestigationAgent, and GBE::GReparentAgent.

const QPtrList< GAgent > & GCS::GAgent::requestAgents  )  const [protected]
 

Returns:
the element's agents as a list (const reference)

GEnergy * GCS::GAgent::requestEnergy  )  [protected]
 

Returns:
the element's energy

GForm * GCS::GAgent::requestForm  )  [protected]
 

Returns:
the element's form

GObject * GCS::GAgent::requestObject  )  [protected]
 

Returns:
the element's object

void GCS::GAgent::run  )  [protected, virtual]
 

When agents are started this code is executed as a thread. This is where the agent's functionality is defined.

See also:
GAgent::receiveInfluence

Reimplemented in GBE::GEnergyFormAgent, GBE::GInvestigationAgent, GBE::GMoveAgent, and GBE::GRadiatingAgent.

void GCS::GAgent::sendInfluence const GCS::GElementID target,
GCS::GElementInfluence influence
[signal]
 

This signal is used to send influences to a specific destination element.

void GCS::GAgent::threadStart double  seconds_elapsed  )  [protected, virtual, slot]
 

Causes the internal thread to start executing run(). This is used by GElement to start the agent.

See also:
beginPark();


Friends And Related Function Documentation

friend class GElement [friend]
 

GElement needs to set private properties and connect to protected slots.


Member Data Documentation

const QPtrList<GAgent>* GCS::GAgent::Agents [private]
 

This list stores all agents that are in the same element. Since it is not clean code to change other agents directly they are accessible read only.

Note:
When an agent was never added to an element this pointer is NULL!! Such agents should never be executed on their own.
See also:
GElement::addAgent()

GObject* GCS::GAgent::Object [private]
 

This is a pointer to the element's object; all changes to the element are done by accessing the object through this pointer; all requestXXXX() methods use it;

Note:
When an agent was never added to an element this pointer is NULL!! Such agents should never be executed on their own.
See also:
GElement::addAgent()

bool GCS::GAgent::shutdown [protected]
 

The default implementation of beginPark() sets this value to true. It can be used inside the run() method to check if the agent should park (this is done by returning from the run method).

A standard run() method would look like this:

void CustomAgent::run() { while(!shutdown) { //do something msleep(breaktime); //take a nap (very important) } }


The documentation for this class was generated from the following files:
Generated on Thu Oct 21 21:18:20 2004 for G System by doxygen 1.3.6