Table of Contents

Creating an MFM Element

You will need to have the MFM ready to build from source to do this. Follow the instructions at Cloning from Github if you have not done so yet.

This tutorial highlights making a density regulating element which regulates nearby density based on some configurable parameters. The source for the final element is located at

MFMv2/src/elements/include/Element_Creg.h

Copy the Element Template

First, copy:

MFMv2/src/elements/include/Element_Template.h

to

MFMv2/src/elements/include/Element_Creg.h

Create the C++ Compilation file

In order for the compiler to be able to create a compiled version of this Element, you will need to create a small C++ file which associates with it. Create the file:

MFMv2/src/elements/src/Element_Creg.cpp

Add the line:

#include "Element_Creg.h"

to the top. This compiles the header in its entirety.

Renaming

Many things in the template need to be renamed to reflect the new Element. There are comments throughout the C++ template labeled:

<<TEMPLATE>>

Which supply you with renaming instructions. We are more or less going to rename everything we find called “Template” with “Creg”. When you are done following the tags, search the file an make sure there is nothing called “Template”.

Set up the Configurable Parameter

There is a sample configurable parameter in the Template, called m_sampleParameter. We are going to reuse this parameter as the attempted regulated density by the Creg. Rename it to m_targetDensity.

We need to set up the constructor for the Configurable Parameter next. Find the lines in the template constructor which set it up, and replace those lines with:

m_targetDensity(this, "density", "Target Density",
                      "The Creg will try to fill this many spots in its event "
                      "window with other Creg.", 0, 3, 41, 1)

The first argument is a pointer to this Element, which needs to be “this”.

The second argument is a very short name for this parameter.

The third argument is a display name for this parameter.

The fourth argument is a longer description of what this parameter does.

The fifth argument is the lowest value this parameter may be.

The sixth argument is the default value of this parameter.

The seventh argument is the highest value this parameter may be.

The eighth argument is the resolution of this parameter, meaning the the value of this parameter may only be multiples of this resolution.

Give values to virtual methods

The following virtual methods need different definitions corresponding to the Creg behavior.

Method Return Value Comments
PercentMovable 100 This Element is completely movable.
DefaultPhysicsColor 0xffff8300 Neon orange
DefaultLowlightColor 0xff774100 Half of Neon orange
GetDescription <description> Some description, not important.

Write behavior method

This is the most important part of the Element. Inside the behavior method, put:

virtual void Behavior(EventWindow<CC>& window) const
{
      const MDist<R> md = MDist<R>::get();
      Random& rand = window.GetRandom();

      SPoint cregAtom;
      s32 cregCount = 0;
      SPoint nonCregAtom;
      s32 nonCregCount = 0;

      for(u32 i = md.GetFirstIndex(0); i <= md.GetLastIndex(R); i++)
      {
        const SPoint& rel = md.GetPoint(i);
        const T& atom = window.GetRelativeAtom(rel);
        if(Atom<CC>::IsType(atom, Element<CC>::GetType()))
        {
          cregCount++;
          if(rand.OneIn(cregCount))
          {
            cregAtom = rel;
          }
        }
        else
        {
          nonCregCount++;
          if(rand.OneIn(nonCregCount))
          {
            nonCregAtom = rel;
          }
        }
      }

      if(cregCount > m_targetDensity.GetValue())
      {
        window.SetRelativeAtom(cregAtom,
        Element_Empty<CC>::THE_INSTANCE.GetDefaultAtom());
      }
      else if(cregCount < m_targetDensity.GetValue())
      {
        window.SetRelativeAtom(nonCregAtom,
        Element_Creg<CC>::THE_INSTANCE.GetDefaultAtom());
      }
    }
}

The first loop scans the event window. If it finds an atom of the same type as itself, it keeps track of where it is located and increments the count of Cregs. If not, it keeps track of where other elements are located.

If the number of Cregs is greater than the thresold, it will delete one of the elements that isn't a Creg. Otherwise, it will delete one that is a Creg.

Register Element witn StdElement.inc

Open:

MFMv2/src/drivers/mfmc/include/main.h

Put, at the end of the file:

#include "Element_Creg.h"

This elemental include file is used by all drivers so they know about the elements to use.

Register Element with a Driver

Open:

MFMv2/src/drivers/mfmc/src/main.cpp

In the bottom of the method “DefineNeededElements”, put the line:

NeedElement(&Element_Creg<OurCoreConfig>::THE_INSTANCE);

This places the Element into the toolbox, among other things.

Rebuild the MFM

Go to the root of the project and type

make

Sometimes make doesn't work so well and you may need to type:

make realclean; make

This will rebuild the entire project from scratch.