====== Creating an MFM Element ======
**You will need to have the MFM ready to build from source to do this.** Follow the instructions at [[Dev:clone_from_github|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:
<>
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 | | 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& window) const
{
const MDist md = MDist::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::IsType(atom, Element::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::THE_INSTANCE.GetDefaultAtom());
}
else if(cregCount < m_targetDensity.GetValue())
{
window.SetRelativeAtom(nonCregAtom,
Element_Creg::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::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.