来源:
A role in Teams is a distinct entity which contains a description of the facilities that the two participants in a team/sub-team relationship must provide. A role defines a relationship between teams and sub-teams. The relationship is expressed in terms of the event and belief exchanges implied by the relationship.
The role construct functions at two levels:
- To specify the requirements of a role for the tenderer (the team requiring the role) and the filler (the team providing the role). This specification allows run-time checking of the events that the role tenderers and fillers claim to handle and post. The role functions as an interface definition that declares what an entity that fills a given role must be capable of doing in terms of events handled and posted, and in terms of belief propagation. It is also necessary for the role tenderer to be able to handle events declared as posted, and post events declared as handled in the role specification. Like an interface in Java, the role specification does not contain implementation – only a description of the facilities that the two participants in the role relationship must provide.
- A role operates in a similar manner to a proxy by facilitating sub-tasking between participants in the role relationship. Specifically, role instances are invoked in plans to allow @teamAchieve statements to be issued to role performers.
Role definitions take the form shown below:
role RoleType extends Role
{
// declarations of events handled by the role performer
// declarations of events posted by the role performer
// declarations of teamdata synthesized from the role
// performer
// declarations of teamdata inherited by the role performer
// declarations of role container methods and members
// other Java methods and members
}
Each component of this definition is explained in the following table:
Syntax Term | Description |
role | A Teams Language keyword used to introduce a Role definition. |
RoleType | The name of your derived Role class |
extends Role | This part of the statement plays the same role as in Java – it indicates that the role being defined inherits from a Teams base class called Role. The Role base class implements all the underlying methods that provide a role's core functionality. |
Table 3-1: Components of a Role definition
The compiler generates two classes from a role definition. The first class is the RoleType. The second generated class class is a specialised "container" for instances of the RoleType called RoleTypeContainer. This latter class is used in Teams and TeamPlans to group the performers of a role.
When a team is declared to require a role (e.g. RoleType), the resulting Java class for the team will include a field of the corresponding container type, RoleTypeContainer. The access to individual role performers is indirect through such a container.
Further, in a teamplan, the declaration of using a role results in a RoleType member or RoleType array member local to the plan. This gives a modelling advantage by allowing teamplans to operate with selected, transient sub-groupings that only exist during and for the purpose of carrying out the teamplan.
The role functions as an interface definition that declares what an entity that fills a given role must be capable of doing in terms of events handled and posted, and in terms of belief propagation. It is also necessary for the role tenderer to be able to handle events declared as posted, and post events declared as handled in the role specification.
In general, a role definition will require declarations for the following:
- Events that the role performer must be able to handle and that the role performer may post upward to the role tenderer.
- Teamdata that the role performer may inherit from the role tenderer or that the role tenderer may synthesize from the role performer.
- Role Container methods that allow the definition of methods and members to be added to the automatically created RoleTypeContainer class.
Each declaration is described in the following sub-sections:
This statement declares that a role performer must be capable of handling an event of EventType. The reference becomes a data field referring to the appropriate event instance factory to be used by the JACK kernel. It is through this reference that the event's posting method can be accessed when it is necessary to create an event instance to be sent from the tendering team to the performing team.
The role events are sub-tasked through @teamAchieve statements. The role tenderer can sub-task a role performer with the events declared as handled.
This statement declares that a role tenderer must be capable of handling an event of EventType. reference becomes a data field of the generated EventType class initialisation to the appropriate event instance factory by the JACK kernel. It is through this reference that the event's posting method can be accessed when it is necessary to create an event instance to be sent from the performing team to the tendering team.
The role events are sub-tasked through @teamAchieve statements. The role performer can sub-task a role tenderer with the events declared as posted.
This is a statement for declaring a synthesizing team belief connection. reference identifies the beliefset (of type DataType) to be synthesized. There must be a corresponding declaration for the teamdata to be populated through this belief propagation in the team definition. It will be of the form:
#synthesizes teamdata SynthData data(role_ref.reference)
where role_ref refers to the reference in the #requires declaration for the role in the tendering team definition and reference is the reference in the #synthesizes declaration in the role definition. The data is directed from the role performing sub-team(s) to the tendering team.
This is described in more detail in the chapter on Team Belief Connections.
For an inheriting belief connection, a role definition needs to include an #inherits teamdata DataType reference statement detailing the type and reference name of the source beliefset/teamdata concerned. This statement is similar to the #synthesizes teamdata role statement, but is directed from the tendering team to the performing team.
This is described in more detail in the section on Team Belief Connections.
This statement allows the definition of methods to be added to the RoleTypeContainer class. The statement form is similar to a reasoning method in a JACK plan. An outline is given below:
#container method
public boolean doSomething(int x)
{
...
}
The generated RoleTypeContainer class extends a base class named RoleContainer. This base class provides a number of useful methods for inspecting the container and accessing the role performers. These are described in the section on the RoleContainer Base Class. The #container method statement may be used to provide user-defined methods in the role container.
This statement allows the definition of data members to be added to the RoleTypeContainer class.
The statement has the following form:
#container member
For example,
#container member public MyDataType my_data = initial_value;
The Role base class provides implementations needed for maintaining role relationships between teams. Role definitions extend Role with specific declarations, allowing the kernel to review and enforce type safety in terms of inter-team event handling and posting.
In a program, role objects have three different uses.
- The roles performed by a team are represented by role objects. The event handling and event posting of these roles are added to the requirements of the team instance that are checked at runtime.
- The roles required by a team are represented by role container objects, which keep role objects representing the particular fillers attached.
- When a team task is started, by one team issuing a @teamAchieve goal to a sub-team, then the team task in the sub-team is associated with a pair of role objects:
- one role object is to represent the role that the sub-team is acting within; and
- another role object is to represent the peer role that the tendering team is automatically attached to by virtue of utilising the role of the sub-team.
All three uses will use the specific role types that extend the Role base class. The base class in itself merely contains common data members, a few common methods and the service methods that specific role classes will override.
The Role class implements the following interface:
String actor
//
// Keeps the name of the team that the role object is a proxy for.
//
boolean mirror
//
// Is true when the role object identifies
// the role tenderer.
//
Role peer
//
// This is set only for role objects of team tasks, where it holds
// the peer role object for the team task.
//
int state
//
// Keeps the role object's activity state, which is one of INACTIVE,
// ACTIVE or DETACHED.
// This is discussed further in the section on
// Team Formation.
//
String tag
//
// Identification of the role object. This is assigned at
// role object construction to a unique identification number.
//
TaskJunction tasks
//
// Keeps track of team tasks in progress under this role. Note that
// for a team task, it is the peer of its role object that represents
// the role obligation, and thus where the tasks performed under that
// obligation are tracked.
//
Cursor noTasks()
//
// Returns tasks.idle(). This allows a team to check whether
// or not it is performing tasks within a particular role.
// noTasks will be true when it is not performing any
// tasks within the role.
//
void int setState(int n)
//
// Method to set the role object's activity state.
// This method would only be used explicitly for non-standard role
// change procedures.
//
The RoleContainer class is used as the base class for all role containers. It contains common members and methods, and stubs to be overridden by specific role containers.
The RoleContainer class implements the following interface:
boolean active
//
// This is set to true by default. A team can set it to false to
// prevent any new tasks from being started under that role. If it
// is set to false, any pre-existing tasks will continue to be
// performed. The standard role assignment protocol looks at this
// and refuses a role assignment when the performed role is not
// active.
//
String name
//
// This is the reference name associated with this role container.
// For a performed role, the reference name has the form
// "__HR_xxx_performs" where "xxx" is the role type for this
// container. For a required role, the reference name is given by
// the programmer.
//
String role
//
// The type name of role objects that the container is intended for.
//
Team team
//
// The team that the container belongs to.
//
int min = 0
//
// The minimum number of role objects that are expected to be in this
// role container.
//
int max = 0
//
// The maximum number of role objects that are expected to be in this
// role container, or zero for unlimited.
//
Role find(String actor)
//
// Returns the role object for an actor if the container contains it.
// The role container keeps roles tagged by the actor, and it can
// therefore only contain one role object for any given actor.
//
int size()
//
// Returns the number of role objects added to the role container.
//
Enumeration tags()
//
// Returns the current role object tags as a java.util.Enumeration
// object. These are also the actors defined as role fillers.
//
Role nextFiller()
//
// Uses nextTag() to find an active role filler.
//
String nextTag()
//
// The nextTag() method manages a local enumeration of tags
// to provide the available tags one at a time. If roles are added or
// removed the enumeration is reset, otherwise it will cycle through
// the tags indefinitely.
//
boolean rolesInitialized()
//
// Returns true if the min/max constraints are met.
//
A role definition for RoleType results in two classes:
- a class named RoleType that extends the Role base class; and
- a class named RoleTypeContainer that extends the RoleContainer base class.
The RoleType classes provide runtime type checking methods that the kernel uses.
The generated RoleTypeContainer class extends RoleContainer and provides a method createRole() for constructing RoleType objects within the context of the container.