By default, the SARL agents are exchanging data and information by using events.
These events are received by the agent event handlers that are declared with the on
keyword.
In order to invoke these handlers, the SARL Run-time Environment (SRE) implements an event bus that is in
charge of routing the events for an agent.
This tutorial page explains how to override the event routing mechanism by defining a new skill for the standard built-in capacities in charge of the event routing in the agent.
The Behaviors
built-in capacity provides the tools to the agents for dynamically
registering and unregistering sub-behaviors, and it provides the *event listener that could
be used by external entities (such as the SRE’s communication service)
to give the events to the agents.
The key function that must be overridden is related to this last feature. The name of the
function is asEventListener
. This function replies an internal object that implements
the EventListener
interface. This object is invoked each time an event should delivered
to the agent.
This section describes step-by-step on to create a new Behaviors
implementation,
that is of course an agent skill.
Since the default built-in skill that is implementing the Behaviors
capacity is provided
by the SRE, it may be based on internal features that is neither accessible nor visible.
That’s why it is preferable to keep the reference to the original Behaviors
implementation
in order to let us invoking these low-level features.
Note In this tutorial, the new Behaviors
implementation will filter the incoming events according to a given type. In order words, only the events of the given type will pass through.
The SARL code of the new Behaviors
implementation is written into the skill with the name
FilteringEventDispatchingBehavior
:
skill FilteringEventDispatchingBehavior implements Behaviors {
val acceptedType : Class<? extends Event>
val behaviorDelegate : Behaviors
new (acceptedType : Class<? extends Event>, behaviorDelegate : Behaviors) {
this.acceptedType = acceptedType
this.behaviorDelegate = behaviorDelegate
}
}
In the previous code, the FilteringEventDispatchingBehavior
skill is an implementation of the built-in Behaviors
capacity.
It take as argument of its constructor the type of event that is accepted, and the reference to the original
Behaviors
implementation that is provided by the SRE.
There two arguments are stored into local attributes of the skill.
In the implementation of the Behaviors
capacity, the function asEventListener
is defined for
returning the event listener associated to the agent.
Thus, it is necessary to define this event listener.
We decided to declare it as an inner class of FilteringEventDispatchingBehavior
.
private static class FilteringEventListener implements EventListener {
val parent : FilteringEventDispatchingBehavior
new (parent : FilteringEventDispatchingBehavior) {
this.parent = parent
}
override receiveEvent(occ : Event) {
if (this.parent.acceptedType.isInstance(occ)) {
this.parent.behaviorDelegate.asEventListener.receiveEvent(occ)
}
}
@Pure
override getID : UUID {
this.parent.ID
}
}
This internal implementation of EventListener
has a reference to its containing skill, as argument of
the constructor. This reference is defined in order to have access to the filtering type and to the
original implementation of the Behaviors
capacity.
The type FilteringEventListener
must implement the function receiveEvent
that is invoked
each time an event must be delivered to the agent (either internal or external event).
The code of this function checks if the type of the event is compatible with the filtering type.
And, if it is compatible, it delivers the event to the agent by using the original Behaviors
capacity.
Now, it is necessary to reply an instance of the event listener (that is defined in the previous section) in
the FilteringEventDispatchingBehavior
skill.
@Pure
override asEventListener : EventListener {
new FilteringEventListener(this)
}
Several functions must be implemented into the FilteringEventListener
skill in order
to have a complete implementation of the Behaviors
capacity.
All the functions invoke their equivelent functions into the original built-in
capacity.
override hasRegisteredBehavior : boolean {
this.behaviorDelegate.hasRegisteredBehavior
}
override getRegisteredBehaviors : ConcurrentCollection<Behavior> {
this.behaviorDelegate.getRegisteredBehaviors
}
override registerBehavior(attitude : Behavior, filter : (Event) => boolean, initializationParameters : Object*) : Behavior {
this.behaviorDelegate.registerBehavior(attitude, filter, initializationParameters)
}
override unregisterBehavior(attitude : Behavior) : Behavior {
this.behaviorDelegate.unregisterBehavior(attitude)
}
override wake(^event : Event, scope : Scope<Address>) {
this.behaviorDelegate.wake(^event, scope)
}
override wake(beh : Behavior, ^event : Event) {
this.behaviorDelegate.wake(beh, ^event)
}
override wake(behs : Iterable<Behavior>, ^event : Event) {
this.behaviorDelegate.wake(behs, ^event)
}
The last step to implement in this tutorial is the registration of the new FilteringEventDispatchingBehavior
in place of the
built-in Behaviors
capacity.
This action is usually done during the initialization stage of the agent.
In the following code, the MyEvent
is assumed to be defined as a SARL event that is the only
one type of event accepted by the agents of type FilteringEventAgent
.
agent FilteringEventAgent {
on Initialize {
val originalSkill = getSkill(typeof(Behaviors))
val newSkill = new FilteringEventDispatchingBehavior(typeof(MyEvent), originalSkill)
setSkill(newSkill)
}
}
The initialization process does the following steps:
Behaviors
capacity that is provided by the SRE, into the local variable originalSkill
.FilteringEventDispatchingBehavior
skill by passing the event type under interest, and the reference to the original skill.FilteringEventDispatchingBehavior
skill, that will cause the replacement of the Behaviors
skill provided by the SRE.Copyright © 2014-2024 SARL.io, the Original Authors and Main Authors.
Documentation text and medias are licensed under the Creative Common CC-BY-SA-4.0; you may not use this file except in compliance with CC-BY-SA-4.0. You may obtain a copy of CC-BY-4.0.
Examples of SARL code are licensed under the Apache License, Version 2.0; you may not use this file except in compliance with the Apache License. You may obtain a copy of the Apache License.
You are free to reproduce the content of this page on copyleft websites such as Wikipedia.
Generated with the translator docs.generator 0.14.0.