Table of Contents

Abstract Elements

It may be useful to abstract the behavior of your Elements. In this tutorial, we are going to create two Elements which inherit from a common base Element.

For this tutorial, we are going to make three Elements: AbstractElement_Wanderer, Element_Wanderer_Cyan, and Element_Wanderer_Magenta. These are in the repository.

Create abstract class

First we need to create AbstractElement_Wanderer. This is going to be very similar to creating any other element, besides a few important differences.

First, we cannot use ElementParameters in the base class. This creates conflicts when saving .mfs files and all children will be loaded with the same parameters.

Second, our constructor must take a UUID and have no body, like this:

AbstractElement_Wanderer(UUID u) : Element<CC>(u)
{ }

We should also not define GetDefaultPhysicsColor, since the children will want to be different colors.

We also cannot define THE_INSTANCE, since an abstract class cannot be instantiated.

We need a behavior method which wanders the same for all children. This looks like:

virtual void Behavior(EventWindow<CC>& window) const
{
  SPoint wanderPt;
  Random& rand = window.GetRandom();
  MDist<R> md = MDist<R>::get();
  Dir d = (Dir)rand.Create(Dirs::DIR_COUNT);

  Dirs::FillDir(wanderPt, d);

  wanderPt *= Dirs::IsCorner(d) ? (GetWanderDistance() / 2) : GetWanderDistance();

  if(window.IsLiveSite(wanderPt))
  {
    if(window.GetRelativeAtom(wanderPt).GetType() ==
       Element_Empty<CC>::THE_INSTANCE.GetType())
       {
         window.SwapAtoms(wanderPt, SPoint(0, 0));
       }
    }
  }
}

Finally, we need a new pure abstract method. This will allow a sub-class to tell this base class how far it would like to wander per event. We write it like this, in a protected section:

virtual u32 GetWanderDistance() const = 0;

Create child classes

Next, we need some child classes to inherit from this one. We will create two classes, which are nearly identical, to do this.

First, each of these classes gets an ElementParameterS32 named m_wanderDistance. These need to be initialized with unique tags!

Next, change the class definition and the constructor to use AbstractElement_Wanderer<CC> instead of Element<CC>.

Next, define DefaultPhysicsColor to return 0xff00ffff for the Cyan element, and 0xffff00ff for the Magenta element.

Finally, define GetWanderDistance as such:

protected:
 virtual u32 GetWanderDistance() const
 {
    return (u32)m_wanderDistance.GetValue();
 }