Class GenericDomain<S extends GenericSimulation<S,A,C,D,DM,F,G>,A extends GenericActor<S,A,C,D,DM,F,G>,C extends GenericCondition<S,A,C,D,DM,F,G>,D extends GenericDomain<S,A,C,D,DM,F,G>,DM extends GenericDomainMember<S,A,C,D,DM,F,G>,F extends GenericFactory<S,A,C,D,DM,F,G>,G extends GenericGroup<S,A,C,D,DM,F,G>>

java.lang.Object
org.bzdev.devqsim.SimObject
org.bzdev.drama.generic.GenericSimObject<S,A,C,D,DM,F,G>
org.bzdev.drama.generic.GenericTaskObject<S,A,C,D,DM,F,G>
org.bzdev.drama.generic.GenericDomain<S,A,C,D,DM,F,G>
All Implemented Interfaces:
Comparable<D>, CondObserver<C,D>, NamedObjectOps
Direct Known Subclasses:
Domain

public abstract class GenericDomain<S extends GenericSimulation<S,A,C,D,DM,F,G>,A extends GenericActor<S,A,C,D,DM,F,G>,C extends GenericCondition<S,A,C,D,DM,F,G>,D extends GenericDomain<S,A,C,D,DM,F,G>,DM extends GenericDomainMember<S,A,C,D,DM,F,G>,F extends GenericFactory<S,A,C,D,DM,F,G>,G extends GenericGroup<S,A,C,D,DM,F,G>> extends GenericTaskObject<S,A,C,D,DM,F,G> implements Comparable<D>, CondObserver<C,D>
Class for domains. Domains are collections of actors and also are condition observers so that domains are notified when the conditions they are interested in change.

The operations provided in this class are the ones needed to associate a domain with domain members and conditions, and to forward notifications when a condition changes. Domain members represent actors. By default, each actor has a unique domain member, but actors can be configured so that multiple actors share a domain member, which reduces memory use when a number of actors have identical domain memberships.

A domain can be configured as a communication domain. In this case it can be used to determine if a path exists between a source and destination, and the corresponding delays and message filters. The method setMessageForwardingInfo(GenericMsgFrwdngInfo) associates a domain with an object that can determine the appropriate delays and message filters. When configured as a communication domain, a domain must call one of the configureAsCommunicationDomain methods. These tag the domain with an instance of CommDomainType to indicate the type of the communication domain. Subclasses determine how this tag should be used. On may optionally provide a set of additional instances of CommDomainType. The use of these is also left to subclasses.

  • Constructor Details

    • GenericDomain

      protected GenericDomain(S sim, String name, boolean intern) throws IllegalArgumentException
      Protected constructor without priority. The priority defaults to Integer.MAX_VALUE.
      Parameters:
      sim - the simulation
      name - the domain's name
      intern - true if the object can be looked up by using the methods in Simulation; false otherwise.
      Throws:
      IllegalArgumentException - typically means a name is already in use
    • GenericDomain

      protected GenericDomain(S sim, String name, boolean intern, int priority) throws IllegalArgumentException
      Protected constructor with priority.
      Parameters:
      sim - the simulation
      name - the domain's name
      intern - true if the object can be looked up by using the methods in Simulation; false otherwise.
      priority - determines the search order for domains (lowest priorities appear first)
      Throws:
      IllegalArgumentException - typically means a name is already in use
    • GenericDomain

      protected GenericDomain(S sim, String name, boolean intern, D parent) throws IllegalArgumentException
      Protected constructor with parent and without priority. The priority defaults to Integer.MAX_VALUE.
      Parameters:
      sim - the simulation
      name - the domain's name
      intern - true if the object can be looked up by using the methods
      parent - the parent domain in Simulation; false otherwise.
      Throws:
      IllegalArgumentException - typically means a name is already in use or that a parent is not a communication domain
    • GenericDomain

      protected GenericDomain(S sim, String name, boolean intern, D parent, int priority) throws IllegalArgumentException
      Protected constructor with parent and priority.
      Parameters:
      sim - the simulation
      name - the domain's name
      intern - true if the object can be looked up by using the methods in Simulation; false otherwise.
      parent - the parent domain
      priority - determines the search order for domains (lowest priorities appear first)
      Throws:
      IllegalArgumentException - typically means a name is already in use
  • Method Details

    • getParent

      public D getParent()
      Get the parent domain. The parent domain is set by a constructor. A parent domain must be a communication domain, and a domain with a parent will be configured as a communication domain.
      Returns:
      the parent domain; null if none exists
    • onChildAdd

      protected void onChildAdd(D child)
      Handle creation of a new child domain If a reference to the child domain is kept, it should be a weak reference so that it will not inhibit garbage collection of the child.
      Parameters:
      child - the child domain that was added
    • onChildRemove

      protected void onChildRemove(D child)
      Handle destruction of a child domain. This allows any action performed by onChildAdd to be undone.
      Parameters:
      child - the child domain that is to be eliminated
    • canDelete

      public boolean canDelete()
      Determine if this simulation object can be deleted. A deleted object cannot be deleted (the default behavior of SimObject), but in addition, a domain cannot be deleted if it has child domains (i.e., other domains designate it as their parent).
      Specified by:
      canDelete in interface NamedObjectOps
      Returns:
      true if this object can be deleted; false otherwise
    • onDelete

      protected void onDelete()
      Complete the actions necessary to delete a named object. A subclass that overrides this method must call super.onDelete() at some point to complete the object deletion. This may not be within the onDelete method of the subclass if the deletion must be delayed for some reason (e.g., until some processing that is in progress has been completed). Once called, the object will be removed from the object-namer's tables and the object will be marked as deleted, so in general cleanup actions by a subclass should occur before it calls super.onDelete().
      Overrides:
      onDelete in class GenericTaskObject<S extends GenericSimulation<S,A,C,D,DM,F,G>,A extends GenericActor<S,A,C,D,DM,F,G>,C extends GenericCondition<S,A,C,D,DM,F,G>,D extends GenericDomain<S,A,C,D,DM,F,G>,DM extends GenericDomainMember<S,A,C,D,DM,F,G>,F extends GenericFactory<S,A,C,D,DM,F,G>,G extends GenericGroup<S,A,C,D,DM,F,G>>
    • getPriority

      public int getPriority()
      Get the priority. Priorities determine a search order in determining if actors can communicate with each other. Lower numbers are tried first.
      Returns:
      the priority.
      See Also:
    • compareTo

      public int compareTo(D object)
      Compare two Domains. The order in which domains are searched is dependent on their priorities. Those with higher priority values are searched later, following the usual convention for priority queues. If the priority values are the same, the search order is based on the domain's name. The DomainMember class uses a TreeSet so that an iterator will will return members in the proper order.
      Specified by:
      compareTo in interface Comparable<S extends GenericSimulation<S,A,C,D,DM,F,G>>
      Parameters:
      object - a domain
      Returns:
      s negative integer if this domain should appear before object; 0 if this domain and object have the same priority and name; a positive integer if this domain should appear after object
      See Also:
    • containsGroup

      public boolean containsGroup(G g)
      Determine if this domain contains a specified group.
      Parameters:
      g - the group
      Returns:
      true if g has joined this domain; false otherwise
    • groupSet

      public Set<G> groupSet()
      Get the group set.
      Returns:
      a set of the groups that have joined this domain
    • groupSetSize

      public int groupSetSize()
      Get the number of groups that have joined this domain. This method is slightly faster than calling groupSet().size().
      Returns:
      the number of groups that have joined this domain
    • isCommunicationDomain

      public final boolean isCommunicationDomain()
      Determine if a domain is a communication domain
      Returns:
      true if the domain is a communication domain; false otherwise
    • getCommDomainType

      public CommDomainType getCommDomainType()
      Get the communication-domain type.
      Returns:
      the communication-domain type; null if there is none
    • getCommDomainTypeSet

      public Set<CommDomainType> getCommDomainTypeSet()
      Get the set of communication-domain types. A value of null will be returned in this is not a communication domain. The set returned includes both the primary communication-domain type and any additional communication-domain types that may be defined.
      Returns:
      the set of communication-domain types; null if there is none
    • addCommDomainTypeSet

      protected void addCommDomainTypeSet(Set<CommDomainType> typeSet)
      Add additional communication-domain types. Additional communication domains are not used by this package, nor by the package org.bzdev.drama. They are provided for use by other simulation packages based on this package. The intention is for additional types to be treated as properties that may have to be present for messages to be sent. This method cannot be called twice or after the two-argument variant of configureAsCommunicationDomain(CommDomainType,Set) is called.
      Parameters:
      typeSet - a set of communication-domain types
      Throws:
      IllegalStateException - called at the wrong time
    • configureAsCommunicationDomain

      protected void configureAsCommunicationDomain(CommDomainType type, Set<CommDomainType> typeSet)
      Configure a domain as a communication domain given a set of communication-domain types. The first argument provides the domain's communication-domain type. Additional communication domains are not used by this package, nor by the package org.bzdev.drama. They are provided for use by other simulation packages based on this package. The intention is for additional types to be treated as properties that may have to be present for messages to be sent. This must be called before isCommunicationDomain is called. Methods with this name may be called only once per domain.
      Parameters:
      type - the type of the communication domain
      typeSet - a set of additional communication-domain types
      Throws:
      IllegalStateException - this method was called after a call to isCommunicationDomain
      See Also:
    • configureAsCommunicationDomain

      protected void configureAsCommunicationDomain(CommDomainType type)
      Configure a domain as a communication domain. This must be called before isCommunicationDomain is called. Methods with this name may be called only once per domain.
      Parameters:
      type - the type of the communication domain
      Throws:
      IllegalStateException - this method was called after a call to isCommunicationDomain
      IllegalArgumentException - the argument was null
    • configureAsCommunicationDomain

      protected void configureAsCommunicationDomain(String typeName)
      Configure a domain as a communication domain given the name of a communication domain type. This must be called before isCommunicationDomain is called and the implementation calls configureAsCommunicationDomain(CommDomainType).
      Parameters:
      typeName - the name of the communication domain type
      Throws:
      IllegalArgumentException - the argument was null
      IllegalStateException - this method was called after a call to isCommunicationDomain
    • communicationMatch

      protected CommDomainInfo<D> communicationMatch(A a1, A a2)
      Check if two actors can communicate if at least one of them is in this domain. The default behavior is to delegate the decision to communicationMatch(dm1,dm2) where dm1 is the domain member for a1 and dm2 is the domain member for a2.

      The GenericSimulation methods named findCommDomain uses communicationMatch methods as part of their implementations, and constitute the only use of the communicationMatch in this package.

      To change the behavior of this method, one should override the communicationMatchByDomain and communicationMatchByDomainAncestor methods or override the findCommDomain methods in GenericSimulation instead.

      Parameters:
      a1 - the actor sending a message
      a2 - the actor receiving a message
      Returns:
      a communication-domain-info object if communication is allowed; null otherwise
      See Also:
    • communicationMatch

      protected CommDomainInfo<D> communicationMatch(DM dm1, DM dm2)
      Check if communication between actors associated with two domain members is allowed when at least on of the domain members is contained by this domain. Check if this domain allows communication between actors given their domain members. The default behavior is to
      • return null if this domain is not a communication domain.
      • return a non-null value if dm1 and dm2 are members of this domain and this.communicationMatchByDomain(dm1, dm2) returns true.
      • return a null value if dm1 and dm2 are members of this domain and this.communicationMatchByDomain(dm1, dm2) returns false.
      • Perform a search if either dm1 or dm2 (but not both) is a member of this domain; otherwise return null
      There are two search options.
      • If dm1 is a member of the current domain, the following search is performed:
        1. The search starts with this domain. A test domain d is set to null, and a "parent" domain p is set to the current domain.
        2. if p is null or p is not a communication domain, the this portion of the search terminates.
        3. If p contains dm2, d is set to p
        4. If dm2 is a member of a domain that has p as an ancestor or if d has been set, then the value of p.communicationMatchByDomainAncestor(dm1,dm2,this,d) is returned (a null value of d is replaced with a child domain of p that contains dm2 during this call); otherwise repeat from step 2 after replacing p with its parent.
      • If the previous search failed or was not performed and if dm2 is a member of the current domain, the following search is performed:
        1. p is set to the parent of this domain.
        2. if p is null or p is not a communication domain, null is returned.
        3. if p contains domain member dm1, the return value is p.communicationMatchByDomainAncestor(dm1,dm2,p,this) otherwise repeat from Step 2 after replacing p with its parent.
      • If neither search succeeded, null is returned.

          The GenericSimulation methods named findCommDomain uses communicationMatch methods as part of their implementations, and constitute the only use of the communicationMatch in this package.

          To change the behavior of this method, one should override the communicationMatchByDomain and communicationMatchByDomainAncestor methods or override the findCommDomain methods in GenericSimulation instead.

      Parameters:
      dm1 - the domain member of an actor sending a message
      dm2 - the domain member of an actor receiving a message
      Returns:
      a communication-domain-info object if communication is allowed; null otherwise
      See Also:
    • communicationMatchByDomain

      protected boolean communicationMatchByDomain(DM dm1, DM dm2)
      Determine if there is a communication match for two domain members. A match implies that the actors associated with the first domain member can send a message to the actors associated with the second domain member. This method is called when the two domain members are members of this domain. The default behavior (which may be overridden by a subclass) is to return true, which allows communication between actors whose domain members have joined this domain. The effect of message filters is not included.

      This method can be overridden to make communication more restrictive. The only methods from this package that call this method are the communicationMatch methods defined by this class.

      Parameters:
      dm1 - the first domain member
      dm2 - the second domain member
      Returns:
      true if two domain members match for communication; false otherwise
    • createCommDomainInfo

      protected final CommDomainInfo<D> createCommDomainInfo(D srcDomain, D ancestorDomain, D destDomain)
      Create a CommDomainInfo object. This method is provided for convenience - it allows the caller to ignore type parameters and merely calls a constructor.
      Parameters:
      srcDomain - the domain for a message source
      ancestorDomain - the closest common ancestor for the source and destination domains
      destDomain - the domain for a message destination
      Returns:
      the new communication domain
    • communicationMatchByDomainAncestor

      protected CommDomainInfo<D> communicationMatchByDomainAncestor(DM dm1, DM dm2, D domain1, D domain2)
      Determine if there is a communication match for two domain members with this domain as a common ancestor domain. A match implies that the actors associated with the first domain member can send a message to the actors associated with the second domain member. This method is called by the default implementations of communicationMatch(GenericDomainMember,GenericDomainMember), whose documentation describes how this method is used. One should note, that the domain on which this method is called is a common ancestor of the two domains passed as arguments, that dm1 is a member of domain1, and dm2 is a member of domain2. The common ancestor's implementation of this method is the one that determines when communication is possible for the source and destination actors.

      The default implementation always returns a non-null value. Subclasses can override this to provide different behavior (e.g., to disallow communication between specific pairs of domain members). The effect of message filters is not included. When a non null value is returned, the returned value should be createCommDomainInfo(domain1, this, domain2). When communication between two domain members in different domains is not allowed, this method, when called on the closest common ancestor domain, should return null.

      The only methods from this package that call this method are the communicationMatch methods defined by this class.

      Parameters:
      dm1 - the domain member of an actor sending a message
      dm2 - the domain member of an actor receiving a message
      domain1 - either this domain or a domain that has this domain as an ancestor and that is also a domain containing dm1 or the ancestor of a domain containing dm1
      domain2 - either this domain or a domain that has this domain as an ancestor and that is also a domain containing dm2 or the ancestor of a domain containing dm2; otherwise null, in which case a domain containing dm2 and that is either this domain or a domain that has this domain as an ancestor will be chosen.
      Returns:
      a communication-domain-info object if communication is allowed; null otherwise
    • communicationMatch

      protected CommDomainInfo<D> communicationMatch(A ac, G g)
      Check if this domain allows an actor to communication with a group given that either the actor or the group is a member of this domain. This method merely calls communicationMatch(dm,g) where dm is the domain member for actor ac.

      The GenericSimulation methods named findCommDomain uses communicationMatch methods as part of their implementations, and constitute the only use of the communicationMatch in this package.

      To change the behavior of this method, one should override the communicationMatchByDomain and communicationMatchByDomainAncestor methods or override the findCommDomain methods in GenericSimulation instead.

      Parameters:
      ac - the actor for which communications will be started
      g - the group receiving a message
      Returns:
      a communication-domain-info object if communication is allowed; null otherwise
      See Also:
    • communicationMatch

      protected CommDomainInfo<D> communicationMatch(DM dm1, G g)
      Check if this domain allows a domain member's actors to communication with a group given that the domain member or the group is a member of this domain. The default implementation will
      • return null if this domain is not a communication domain or if neither dm1 nor g is are members of this domain.
      • return a non-null value if dm1 and g are members of this domain and communicationMatchByDomain(dm1, g) returns true.
      • return a null value if dm1 and g are members of this domain and communicationMatchByDomain(dm1, g) returns false.
      • perform a search if either dm1 or g (but not both) are members of this domain.
      The search has two cases.
      • The first search covers the case where dm1 is a member of this domain:
        1. p is set to this domain and d is set to null.
        2. if p is null or p is not a communication domain, the first search fails.
        3. g is a member of domain p, d is set to p.
        4. if p is an ancestor of a domain containing g or if d is not null, then the value of p.communicationMatchByDomainAncestor(dm1, g, this, d) is returned (a null value of d is replaced with a child domain of p that contains g during this call); otherwise the search continues at step 2 with p set to its parent.
      • If the first search fails and g is a member of this domain, then the second search is started:
        1. p is set to the parent of this domain.
        2. if p is null or p is not a communication domain, the second search fails.
        3. dm1 is a member of p, then the value of p.communicationMatchByDomainAncestor(dm1, g, p, this) is returned; otherwise the search continues at step 2 with p set to its parent.

      The GenericSimulation methods named findCommDomain uses communicationMatch methods as part of their implementations, and constitute the only use of the communicationMatch in this package.

      To change the behavior of this method, one should override the communicationMatchByDomain and communicationMatchByDomainAncestor methods or override the findCommDomain methods in GenericSimulation instead.

      Parameters:
      dm1 - the domain member of the agent for which communications will be started
      g - the group receiving a message
      Returns:
      a communication-domain-info object if communication is allowed; null otherwise
      See Also:
    • communicationMatchByDomain

      protected boolean communicationMatchByDomain(DM dm, G g)
      Determine if there is a communication match for a domain member and a group. A match implies that the actors associated with the domain member can send a message to a group. This method is called when the the domain member has joined this domain and the group is associated with this domain. The default implementation always returns true. The effect of message filters is not included.

      This method can be overridden to make communication more restrictive. The only methods from this package that call this method are the communicationMatch methods defined by this class.

      Parameters:
      dm - the domain member
      g - the group
      Returns:
      true if two domain members match for communication; false otherwise
    • communicationMatchByDomainAncestor

      protected CommDomainInfo<D> communicationMatchByDomainAncestor(DM dm, G g, D domain1, D domain2)
      Determine if there is a communication match for a domain member and a group given a parent domain. A match implies that the actors associated with the first domain member can send a message to the group. This method is called by the default implementations of communicationMatch(GenericDomainMember,GenericGroup), whose documentation describes how this method is used. One should note, that the domain on which this method is called is a common ancestor of the two domains passed as arguments, that dm is a member of domain1, and g is a member of domain2. The common ancestor's implementation of this method is the one that determines when communication is possible for the source and destination actors.

      The default implementation always returns a non-null value. Subclasses can override this to provide different behavior (e.g., to disallow communication between specific pairs of domain members). The effect of message filters is not included. When a non null value is returned, the returned value should be createCommDomainInfo(domain1, this, domain2). When communication between a domain member and a group in a different domain is not allowed, this method, when called on the closest common ancestor domain, should return null.

      The only methods from this package that call this method are the communicationMatch methods defined by this class.

      Parameters:
      dm - the domain member of an actor sending a message
      g - the domain member of an actor receiving a message
      domain1 - either this domain or a domain that has this domain as an ancestor and that is also a domain containing dm1 or the ancestor of a domain containing dm1
      domain2 - either this domain or a domain that has this domain as an ancestor and that is also a domain containing g or the ancestor of a domain containing g; otherwise null, in which case a domain containing g and that is either this domain or a domain that has this domain as an ancestor will be chosen.
      Returns:
      a communication-domain-info object if communication is allowed; null otherwise
    • communicationMatch

      protected CommDomainInfo<D> communicationMatch(G g1, G g2)
      Check if this domain member allows a group to communicate with another group given that at least one of these two groups are members of this domain. The default implementation behaves as follows:
      • return null if this domain is not a communication domain or if neither g1 nor g2 is are members of this domain.
      • return a non-null value if g1 and g2 are members of this domain and this.communicationMatchByDomain(g1, g2) returns true.
      • return a null value if g1 and g2 are members of this domain and this.communicationMatchByDomain(g1, g2) returns false.
      • perform a search if either g1 or g2 (but not both) are members of this domain.
      There are two cases for the search:
      • The first search covers the case where g1 is a member of this domain. The search algorithm is the following.
        1. Set p to this domain and d to null.
        2. If p is null or p is not a communication domain, this search fails.
        3. If g2 is a member of p, the d is set to p.
        4. if p is an ancestor of a domain containing g2 or if d is not null, then the value of p.communicationMatchByDomainAncestor(g1,g2,this,d) is returned (a null value of d is replaced with a child domain of p that contains g2 during this call); otherwise stop 2 is repeated with p set to its parent.
      • If the first search failed or did not occur and if cg2 is a member of this domain, then the second search is performed. The algorithm for this second search is the following.
        1. Set p to the parent of this domain.
        2. If p is null or p is not a communication domain, return null.
        3. if p is the ancestor of one of g1's domains, then the value of p.communicationMatchByDomainAncestor(g1,g2,p,this) is returned; otherwise step 2 is repeated with p set to its parent.

      The GenericSimulation methods named findCommDomain uses communicationMatch methods as part of their implementations, and constitute the only use of the communicationMatch in this package.

      To change the behavior of this method, one should override the communicationMatchByDomain and communicationMatchByDomainAncestor methods or override the findCommDomain methods in GenericSimulation instead.

      Parameters:
      g1 - the group for which communications will be started
      g2 - the group receiving a message
      Returns:
      a communication-domain-info object if communication is allowed; null otherwise
      See Also:
    • communicationMatchByDomain

      protected boolean communicationMatchByDomain(G g1, G g2)
      Check if this domain allows a group to relay a message to another group. The default implementation, which may be overridden by a subclass, always returns true. The caller tests if this domain is a communication domain and that g1 and g2 are associated with this domain. The effect of message filters is not included.

      This method can be overridden to make communication more restrictive. The only methods from this package that call this method are the communicationMatch methods defined by this class.

      Parameters:
      g1 - the group relaying a message
      g2 - the group receiving a message
      Returns:
      true if a group may relay a message; false otherwise
    • communicationMatchByDomainAncestor

      protected CommDomainInfo<D> communicationMatchByDomainAncestor(G g1, G g2, D domain1, D domain2)
      Check if this domain allows a group to relay a message to another group via a parent domain. A match implies that the actors associated with the first domain member can send a message to the group. This method is called by the default implementations of communicationMatch(GenericGroup,GenericGroup), whose documentation describes how this method is used. One should note, that the domain on which this method is called is a common ancestor of the two domains passed as arguments, that g1 is a member of domain1, and g2 is a member of domain2. The common ancestor's implementation of this method is the one that determines when communication is possible for the source and destination actors.

      The default implementation always returns a non-null value. Subclasses can override this to provide different behavior (e.g., to disallow communication between specific pairs of domain members). The effect of message filters is not included. When a non null value is returned, the returned value should be createCommDomainInfo(domain1, this, domain2). When communication between two groups in different domains is not allowed, this method, when called on the closest common ancestor domain, should return null.

      The only methods from this package that call this method are the communicationMatch methods defined by this class.

      Parameters:
      g1 - the domain member of an actor sending a message
      g2 - the domain member of an actor receiving a message
      domain1 - either this domain or a domain that has this domain as an ancestor and that is also a domain containing g1 or the ancestor of a domain containing g1
      domain2 - either this domain or a domain that has this domain as an ancestor and that is also a domain containing g2 or the ancestor of a domain containing 2; otherwise null, in which case a domain containing 2 and that is either this domain or a domain that has this domain as an ancestor will be chosen.
      Returns:
      a communication-domain-info object if communication is allowed; null otherwise
    • communicationMatch

      protected CommDomainInfo<D> communicationMatch(G g, A a)
      Check if this domain allows a group to communication with an actor given that either the group or the actor are members of this domain. This method just calls communicationMatch(g,dm) with dm set to a's domain member.

      The GenericSimulation methods named findCommDomain uses communicationMatch methods as part of their implementations, and constitute the only use of the communicationMatch in this package.

      To change the behavior of this method, one should override the communicationMatchByDomain and communicationMatchByDomainAncestor methods or override the findCommDomain methods in GenericSimulation instead.

      Parameters:
      g - the group for which communications will be started
      a - the actor receiving a message
      Returns:
      a communication-domain-info object if communication is allowed; null otherwise
      See Also:
    • communicationMatch

      protected CommDomainInfo<D> communicationMatch(G g, DM dm)
      Check if this domain allows a group to communicate with actors associated with a domain member given that either the group or the domain member or both are members of this domain. The default implementation will
      • return null if this domain is not a communication domain or if neither g nor dm is are members of this domain.
      • return a non-null value if g and dm are members of this domain and this.communicationMatchByDomain(g, dm) returns true.
      • return a null value if dm and g are members of this domain and this.communicationMatchByDomain(g, dm) returns false.
      • perform a search if either g or dm (but not both) are members of this domain.
      There are two cases for the search:
      • If this domain contains g, then the following algorithm is used.
        1. The variable p is set to this domain and d is set to null.
        2. If p is null or p is not a communication domain, then the first case fails.
        3. If p contains the domain member dm, the d = p.
        4. If p is an ancestor of a domain that contains dm, or if d is not null, then the value of p.communicationMatchByDomainAncestor(g,dm,this,d) is returned (a null value of d is replaced with a child domain of p that contains dm during this call); otherwise Step 2 is repeated with p set to its parent.
      • If this domain contains dm or if the first case failed, then the following algorithm is used.
        1. The variable p is set to this domain's parent.
        2. if p is null or if p is not a commune notion domain, null is returned.
        3. if p contains the group g, the the value of p.communicationMatchByDomainAncestor(g,dm,p,this) is returned; otherwise Step 2 is repeated with p set to its parent.

      The GenericSimulation methods named findCommDomain uses communicationMatch methods as part of their implementations, and constitute the only use of the communicationMatch in this package.

      To change the behavior of this method, one should override the communicationMatchByDomain and communicationMatchByDomainAncestor methods or override the findCommDomain methods in GenericSimulation instead.

      Parameters:
      g - the group for which communications will be started
      dm - the domain member for the actor receiving a message
      Returns:
      a communication-domain-info object if communication is allowed; null otherwise
      See Also:
    • communicationMatchByDomain

      protected boolean communicationMatchByDomain(G g, DM dm)
      Check if this domain allows a group to relay messages to the actors associated with a domain member dm. This method will be called only when dm has joined this domain and g is associated with this domain. The effect of message filters is not included.

      This method can be overridden to make communication more restrictive. The only methods from this package that call this method are the communicationMatch methods defined by this class.

      Parameters:
      g - the group
      dm - the domain member
      Returns:
      true if messages can be relayed; false otherwise
    • communicationMatchByDomainAncestor

      protected CommDomainInfo<D> communicationMatchByDomainAncestor(G g, DM dm, D domain1, D domain2)
      Check if this domain allows a group to relay a message to the actor(s) with a specific domain member. A match implies that the group can send a message to the actors associated with the domain member's actors. This method is called by the default implementations of communicationMatch(GenericGroup,GenericDomainMember), whose documentation describes how this method is used. One should note, that the domain on which this method is called is a common ancestor of the two domains passed as arguments, that g is a member of domain1, and dm is a member of domain2. The common ancestor's implementation of this method is the one that determines when communication is possible for the source and destination actors.

      The default implementation always returns a non-null value. Subclasses can override this to provide different behavior (e.g., to disallow communication between specific pairs of domain members). The effect of message filters is not included. When a non null value is returned, the returned value should be createCommDomainInfo(domain1, this, domain2). When communication between a group and a domain member in a different domain is not allowed, this method, when called on the closest common ancestor domain, should return null.

      The only methods from this package that call this method are the communicationMatch methods defined by this class.

      Parameters:
      g - the domain member of an actor sending a message
      dm - the domain member of an actor receiving a message
      domain1 - either this domain or a domain that has this domain as an ancestor and that is also a domain containing g or the ancestor of a domain containing g
      domain2 - either this domain or a domain that has this domain as an ancestor and that is also a domain containing dm or the ancestor of a domain containing dm; otherwise null, in which case a domain containing dm and that is either this domain or a domain that has this domain as an ancestor will be chosen.
      Returns:
      a communication-domain-info object if communication is allowed; null otherwise
    • onJoinedDomain

      protected void onJoinedDomain(A actor, boolean tracksCondition)
      Note that an actor has joined this domain, either directly or due to being part of a shared domain that has joined or is joining this domain.

      The default method does nothing. It can be overridden when some domain-specific action is needed when an actor joins this domain. It is a good practice when overriding this method to call super.onJoinedDomain with the same arguments.

      Parameters:
      actor - the actor that is joining this domain
      tracksCondition - true if the actor will be configured to obtain notifications when a condition associated with this domain changes; false otherwise
    • onLeftDomain

      protected void onLeftDomain(A actor)
      Note that an actor has left this domain, either directly or due to being part of a shared domain that has just left this domain.

      The default method does nothing. It can be overridden when some domain-specific action is needed when an actor leaves this domain. It is a good practice when overriding this method to call super.onJoinedDomain with the same arguments.

      Parameters:
      actor - the actor that is to leave this domain
    • onJoinedDomain

      protected void onJoinedDomain(G group)
      Note that a group has joined this domain.

      The default method does nothing. It can be overridden when some domain-specific action is needed when a group joins this domain. It is a good practice when overriding this method to call super.onJoinedDomain with the same arguments.

      Parameters:
      group - the group that is joining this domain
    • onLeftDomain

      protected void onLeftDomain(G group)
      Note that a group has just left this domain.

      The default method does nothing. It can be overridden when some domain-specific action is needed when a group leaves this domain. It is a good practice when overriding this method to call super.onJoinedDomain with the same arguments.

      Parameters:
      group - the group that has just left this domain
    • containsDomainMember

      public boolean containsDomainMember(DM domainMember)
      Determine if a domain member is a member of a domain
      Parameters:
      domainMember - a domain member
      Returns:
      true if the domain member is a member of this domain; false otherwise
    • containsActor

      public boolean containsActor(A actor)
      Determine if an actor is a member of a domain.
      Parameters:
      actor - the actor to check
      Returns:
      true if the actor's domain member is a member of this domain; false otherwise
    • domainMemberSet

      public Set<DM> domainMemberSet()
      Get a set of shared domain members.
      Returns:
      a set of the shared domain members for this domain
    • actorSet

      public Set<A> actorSet()
      Get a set of actors.
      Returns:
      a set containing those actors whose domain members are members of this domain
    • actorSetSize

      public int actorSetSize()
      Get the number of actors in a domain. Note - using this function can be significantly more efficient that calling actorSet().size().
      Returns:
      the number of actors in this domain
    • setMessageForwardingInfo

      public void setMessageForwardingInfo(GenericMsgFrwdngInfo<S,A,C,D,DM,F,G> info)
      Configure message-forwarding parameters.
      Parameters:
      info - an object providing the delay and message filter that a domain will use for a given message source and destination; null will restore the default
    • getMFI

      protected GenericMsgFrwdngInfo<S,A,C,D,DM,F,G> getMFI()
      Get the class determining delays and message filters associated with this domain.
      Returns:
      an object providing delays and message filters associated with this domain
    • getDelay

      public long getDelay(A src, Object msg, D sourceDomain, D destDomain, A dest)
      Get the delay for a message given a source actor and its domain, and a destination actor and its domain. The originator's domain and the destination's domain must have this domain as their closest common ancestor. The delay is the sum of the delays of all the domains traversed in following parent domains to the closest common ancestor from the source and then to the destination. Each domain traversed provides a single delay for the total. This method is applicable only to communication domains. The implementation uses an instance of GenericMsgFrwdngInfo or one of its subclasses to determine the delay contributed by each domain.

      Implementation Note: the classes in this package call GenericSimulation methods named findCommDomain to get an instance of CommDomainInfo, the methods of which determine a source and destination domain, and a common ancestor domain. If the source domain and the destination domain are identical, the source domain is used to look up the delay. Otherwise a sum of terms is used. Starting from the source domain, one looks up a delay using the source domain's delay table (an instance of GenericMsgFrwdngInfo) for the delay contribution for a hop from the source to the parent domain. For the second hop the parent's delay table is used to determine a delay contribution for the hop from source domain to the parent's parent domain. This is repeated iteratively until the common ancestor domain is reached. A similar procedure is used starting from the destination domain. Then the total is returned as the delay. For each domain determining a delay, the GenericMsgFrwdngInfo for that domain determines the contribution to the total delay.

      Parameters:
      src - the source/originator of the message
      msg - the message
      sourceDomain - the originator's domain
      destDomain - the destination's domain
      dest - the destination
      Returns:
      the delay in units of simulation ticks
    • getDelay

      public long getDelay(A src, Object msg, D sourceDomain, D destDomain, G dest)
      Get the delay for a message given a source actor and its domain, and a destination group and its domain. The originator's domain and the destination's domain must have this domain as their closest common ancestor. The delay is the sum of the delays of all the domains traversed in following parent domains to the closest common ancestor from the source and then to the destination. Each domain traversed provides a single delay for the total. This method is applicable only to communication domains. The implementation uses an instance of GenericMsgFrwdngInfo or one of its subclasses to determine the delay contributed by each domain.

      Implementation Note: the classes in this package call GenericSimulation methods named findCommDomain to get an instance of CommDomainInfo, the methods of which determine a source and destination domain, and a common ancestor domain. If the source domain and the destination domain are identical, the source domain is used to look up the delay. Otherwise a sum of terms is used. Starting from the source domain, one looks up a delay using the source domain's delay table (an instance of GenericMsgFrwdngInfo) for the delay contribution for a hop from the source to the parent domain. For the second hop the parent's delay table is used to determine a delay contribution for the hop from source domain to the parent's parent domain. This is repeated iteratively until the common ancestor domain is reached. A similar procedure is used starting from the destination domain. Then the total is returned as the delay. For each domain determining a delay, the GenericMsgFrwdngInfo for that domain determines the contribution to the total delay.

      Parameters:
      src - the source/originator of the message
      msg - the message
      sourceDomain - the originator's domain
      destDomain - the destination's domain
      dest - the destination
      Returns:
      the delay in units of simulation ticks
    • getDelay

      public long getDelay(G src, Object msg, D sourceDomain, D destDomain, G dest)
      Get the delay for a message given a source group and its domain, and a destination group and its domain. The originator's domain and the destination's domain must have this domain as their closest common ancestor. The delay is the sum of the delays of all the domains traversed in following parent domains to the closest common ancestor from the source and then to the destination. Each domain traversed provides a single delay for the total. This method is applicable only to communication domains. The implementation uses an instance of GenericMsgFrwdngInfo or one of its subclasses to determine the delay contributed by each domain.

      Implementation Note: the classes in this package call GenericSimulation methods named findCommDomain to get an instance of CommDomainInfo, the methods of which determine a source and destination domain, and a common ancestor domain. If the source domain and the destination domain are identical, the source domain is used to look up the delay. Otherwise a sum of terms is used. Starting from the source domain, one looks up a delay using the source domain's delay table (an instance of GenericMsgFrwdngInfo) for the delay contribution for a hop from the source to the parent domain. For the second hop the parent's delay table is used to determine a delay contribution for the hop from source domain to the parent's parent domain. This is repeated iteratively until the common ancestor domain is reached. A similar procedure is used starting from the destination domain. Then the total is returned as the delay. For each domain determining a delay, the GenericMsgFrwdngInfo for that domain determines the contribution to the total delay.

      Parameters:
      src - the source/originator of the message
      msg - the message
      sourceDomain - the originator's domain
      destDomain - the destination's domain
      dest - the destination
      Returns:
      the delay in units of simulation ticks
    • getDelay

      public long getDelay(G src, Object msg, D sourceDomain, D destDomain, A dest)
      Get the delay for a message given a source group and its domain, and a destination actor and its domain. The originator's domain and the destination's domain must have this domain as their closest common ancestor. The delay is the sum of the delays of all the domains traversed in following parent domains to the closest common ancestor from the source and then to the destination. Each domain traversed provides a single delay for the total. This method is applicable only to communication domains. The implementation uses an instance of GenericMsgFrwdngInfo or one of its subclasses to determine the delay contributed by each domain.

      Implementation Note: the classes in this package call GenericSimulation methods named findCommDomain to get an instance of CommDomainInfo, the methods of which determine a source and destination domain, and a common ancestor domain. If the source domain and the destination domain are identical, the source domain is used to look up the delay. Otherwise a sum of terms is used. Starting from the source domain, one looks up a delay using the source domain's delay table (an instance of GenericMsgFrwdngInfo) for the delay contribution for a hop from the source to the parent domain. For the second hop the parent's delay table is used to determine a delay contribution for the hop from source domain to the parent's parent domain. This is repeated iteratively until the common ancestor domain is reached. A similar procedure is used starting from the destination domain. Then the total is returned as the delay. For each domain determining a delay, the GenericMsgFrwdngInfo for that domain determines the contribution to the total delay.

      Parameters:
      src - the source/originator of the message
      msg - the message
      sourceDomain - the originator's domain
      destDomain - the destination's domain
      dest - the destination
      Returns:
      the delay in units of simulation ticks
    • getMessageFilter

      public MessageFilter getMessageFilter(A src, Object msg, D sourceDomain, D destDomain, A dest)
      Get the message filter for a message given a source actor and its domain, and a destination actor and its domain. The originator's domain and the destination's domain must have this domain as their closest common ancestor. The filter returned is a compound filter that applies the filters of all the domains traversed in following parent domains to the closest common ancestor from the source and then to the destination. Each domain traversed provides a single filter, possibly null to indicate no filtering for the total. The compound filter applies these filters in the order in which the domains are traversed. This method is applicable only to communication domains. The implementation uses an instance of GenericMsgFrwdngInfo or one of its subclasses to determine the message filter contributed by each domain.
      Parameters:
      src - the source/originator of the message
      msg - the message
      sourceDomain - the originator's domain
      destDomain - the destination's domain
      dest - the destination
      Returns:
      the message filter; null if there is none
    • getMessageFilter

      public MessageFilter getMessageFilter(A src, Object msg, D sourceDomain, D destDomain, G dest)
      Get the message filter for a message given a source actor and its domain, and a destination group and its domain. The originator's domain and the destination's domain must have this domain as their closest common ancestor. The filter returned is a compound filter that applies the filters of all the domains traversed in following parent domains to the closest common ancestor from the source and then to the destination. Each domain traversed provides a single filter, possibly null to indicate no filtering for the total. The compound filter applies these filters in the order in which the domains are traversed. This method is applicable only to communication domains. The implementation uses an instance of GenericMsgFrwdngInfo or one of its subclasses to determine the message filter contributed by each domain.
      Parameters:
      src - the source/originator of the message
      msg - the message
      sourceDomain - the originator's domain
      destDomain - the destination's domain
      dest - the destination
      Returns:
      the message filter; null if there is none
    • getMessageFilter

      public MessageFilter getMessageFilter(G src, Object msg, D sourceDomain, D destDomain, A dest)
      Get the message filter for a message given a source group and its domain, and a destination actor and its domain. The originator's domain and the destination's domain must have this domain as their closest common ancestor. The filter returned is a compound filter that applies the filters of all the domains traversed in following parent domains to the closest common ancestor from the source and then to the destination. Each domain traversed provides a single filter, possibly null to indicate no filtering for the total. The compound filter applies these filters in the order in which the domains are traversed. This method is applicable only to communication domains. The implementation uses an instance of GenericMsgFrwdngInfo or one of its subclasses to determine the message filter contributed by each domain.
      Parameters:
      src - the source/originator of the message
      msg - the message
      sourceDomain - the originator's domain
      destDomain - the destination's domain
      dest - the destination
      Returns:
      the message filter; null if there is none
    • getMessageFilter

      public MessageFilter getMessageFilter(G src, Object msg, D sourceDomain, D destDomain, G dest)
      Get the message filter for a message given a source group and its domain, and a destination group and its domain. The originator's domain and the destination's domain must have this domain as their closest common ancestor. The filter returned is a compound filter that applies the filters of all the domains traversed in following parent domains to the closest common ancestor from the source and then to the destination. Each domain traversed provides a single filter, possibly null to indicate no filtering for the total. The compound filter applies these filters in the order in which the domains are traversed. This method is applicable only to communication domains. The originator's domain and the destination's domain must have this domain as their closest common ancestor. The filter returned is a compound filter that applies the filters of all the domains traversed in following parent domains to the closest common ancestor from the source and then to the destination. Each domain traversed provides a single filter, possibly null to indicate no filtering for the total. The compound filter applies these filters in the order in which the domains are traversed. This method is applicable only to communication domains.
      Parameters:
      src - the source/originator of the message
      msg - the message
      sourceDomain - the originator's domain
      destDomain - the destination's domain
      dest - the destination
      Returns:
      the message filter; null if there is none
    • getCondObserverImpl

      public CondObserverImpl<C,D> getCondObserverImpl()
      Description copied from interface: CondObserver
      Get the condition-observer implementation for a condition observer. This method is intended for use by classes in the org.bzdev.drama.generic package.
      Specified by:
      getCondObserverImpl in interface CondObserver<S extends GenericSimulation<S,A,C,D,DM,F,G>,A extends GenericActor<S,A,C,D,DM,F,G>>
      Returns:
      the condition-observer implementation
    • addCondition

      public boolean addCondition(C c)
      Description copied from interface: CondObserver
      Associate a condition with an observer.
      Specified by:
      addCondition in interface CondObserver<S extends GenericSimulation<S,A,C,D,DM,F,G>,A extends GenericActor<S,A,C,D,DM,F,G>>
      Parameters:
      c - the condition
      Returns:
      true on success; false on failure
    • removeCondition

      public boolean removeCondition(C c)
      Description copied from interface: CondObserver
      Disassociate a condition with a condition observer.
      Specified by:
      removeCondition in interface CondObserver<S extends GenericSimulation<S,A,C,D,DM,F,G>,A extends GenericActor<S,A,C,D,DM,F,G>>
      Parameters:
      c - the condition
      Returns:
      true on success; false on failure
    • hasCondition

      public boolean hasCondition(C c)
      Description copied from interface: CondObserver
      Determine if a condition observer has (is associated with) a condition.
      Specified by:
      hasCondition in interface CondObserver<S extends GenericSimulation<S,A,C,D,DM,F,G>,A extends GenericActor<S,A,C,D,DM,F,G>>
      Parameters:
      c - the condition
      Returns:
      true if the condition observer has condition c; false otherwise
    • conditionSet

      public Set<C> conditionSet()
      Description copied from interface: CondObserver
      Get a set of conditions
      Specified by:
      conditionSet in interface CondObserver<S extends GenericSimulation<S,A,C,D,DM,F,G>,A extends GenericActor<S,A,C,D,DM,F,G>>
      Returns:
      the set of conditions that are associated with this condition observer
    • setConditionChangeQMode

      public void setConditionChangeQMode(boolean value)
      Description copied from interface: CondObserver
      Set whether condition-change notifications should be queued or sent immediately. Setting this mode to true will improve performance when many conditions are changed at the same simulation time. If the mode is changed from true to false while there are some queued notifications, those will be forwarded.
      Specified by:
      setConditionChangeQMode in interface CondObserver<S extends GenericSimulation<S,A,C,D,DM,F,G>,A extends GenericActor<S,A,C,D,DM,F,G>>
      Parameters:
      value - true if notifications should be queued; false if they should be sent immediately.
    • getConditionChangeQMode

      public boolean getConditionChangeQMode()
      Description copied from interface: CondObserver
      Determine if condition-change notifications are queued.
      Specified by:
      getConditionChangeQMode in interface CondObserver<S extends GenericSimulation<S,A,C,D,DM,F,G>,A extends GenericActor<S,A,C,D,DM,F,G>>
      Returns:
      true if queued; false otherwise.
    • printConfiguration

      public void printConfiguration(String iPrefix, String prefix, boolean printName, PrintWriter out)
      Print this simulation object's configuration. Documentation for the use of this method is provided by the documentation for the SimObject method SimObject.printConfiguration(String,String,boolean,PrintWriter). When the thirs argument has a value of true, the object name and class name will be printed in a standard format with its indentation provided by the iPrefix argument. In addition, the configuration that is printed includes the following items.

      Defined in GenericDomain:

      • the priority for this domain.
      • the parent of this domain.
      • whether or not this domain is a communication domain.
      • a list of the communication domain types for this domain.
      • the conditions this domain observes
      • the domain members of this domain (i.e., the instances of GenericDomainMember that have joined this domain).
      • the actors that are not in a shared domain that have joined this domain.
      • the groups that have joined this domain.
      Overrides:
      printConfiguration in class GenericSimObject<S extends GenericSimulation<S,A,C,D,DM,F,G>,A extends GenericActor<S,A,C,D,DM,F,G>,C extends GenericCondition<S,A,C,D,DM,F,G>,D extends GenericDomain<S,A,C,D,DM,F,G>,DM extends GenericDomainMember<S,A,C,D,DM,F,G>,F extends GenericFactory<S,A,C,D,DM,F,G>,G extends GenericGroup<S,A,C,D,DM,F,G>>
      Parameters:
      iPrefix - the prefix to use for an initial line when printName is true with null treated as an empty string
      prefix - a prefix string (typically whitespace) to put at the start of each line other than the initial line that is printed when printName is true
      printName - requests printing the name of an object
      out - the output print writer
    • clone

      protected Object clone() throws CloneNotSupportedException
      Creates and returns a copy of this object. This method will throw the exception CloneNotSupportedException if the object is interned.
      Overrides:
      clone in class Object
      Throws:
      CloneNotSupportedException - a clone could not be created
      See Also:
    • isInterned

      public boolean isInterned()
      Determine if an object is interned in a object namer's tables.
      Specified by:
      isInterned in interface NamedObjectOps
      Returns:
      true if the object is interned; false if not
    • getObjectNamer

      protected Simulation getObjectNamer()
      Get the object namer for a named object.
      Returns:
      the object namer for this named object
    • getName

      public final String getName()
      Get an object's name.
      Specified by:
      getName in interface NamedObjectOps
      Returns:
      the name of the object
    • delete

      public final boolean delete()
      Delete an object. An object can only be deleted once. If this method returns true, the object (if interned) will have been removed from the object namer tables.

      The implementations provided by DefaultNamedObect and generated because of a @NamedObject annotation provide a protected method named onDelete. A subclass that overrides onDelete() must call the onDelete method of its superclass after it's onDelete method has been called and any cleanup actions performed. In some cases, this may happen at a later time (e.g., if a thread is used for some of the cleanup operations or if it is otherwise necessary to wait).

      Specified by:
      delete in interface NamedObjectOps
      Returns:
      true if the deletion request was accepted; false otherwise
    • isDeleted

      public final boolean isDeleted()
      Determine if an object has been deleted. An object is deleted if the method delete() has been called and returned true.
      Specified by:
      isDeleted in interface NamedObjectOps
      Returns:
      true if deleted; false otherwise
    • deletePending

      public final boolean deletePending()
      Determine if an object is being deleted. An deletion is pending if the method delete() has been called and returned true but the deletion has not been completed.
      Specified by:
      deletePending in interface NamedObjectOps
      Returns:
      true if deletion is pending; false otherwise