AnimatLab  2
Test
RemoteControl.cpp
1 #include "StdAfx.h"
2 #include "IMovableItemCallback.h"
3 #include "ISimGUICallback.h"
4 #include "IMotorizedJoint.h"
5 #include "AnimatBase.h"
6 
7 #include "Node.h"
8 #include "Link.h"
9 #include "IPhysicsMovableItem.h"
10 #include "IPhysicsBody.h"
11 #include "BoundingBox.h"
12 #include "MovableItem.h"
13 #include "BodyPart.h"
14 #include "Joint.h"
15 #include "ReceptiveField.h"
16 #include "ContactSensor.h"
17 #include "RigidBody.h"
18 #include "Structure.h"
19 #include "NeuralModule.h"
20 #include "Adapter.h"
21 #include "NervousSystem.h"
22 #include "Organism.h"
23 #include "ActivatedItem.h"
24 #include "ActivatedItemMgr.h"
25 #include "DataChartMgr.h"
26 #include "ExternalStimuliMgr.h"
27 #include "KeyFrame.h"
28 #include "SimulationRecorder.h"
29 #include "OdorType.h"
30 #include "Odor.h"
31 #include "Light.h"
32 #include "LightManager.h"
33 #include "Simulator.h"
34 
35 #include "RobotInterface.h"
36 #include "RobotIOControl.h"
37 #include "RemoteControlLinkage.h"
38 #include "RemoteControl.h"
39 
40 namespace AnimatSim
41 {
42  namespace Robotics
43  {
44 
45 RemoteControl::RemoteControl(void)
46 {
48  m_bUseRemoteDataTypes = true;
49 }
50 
51 RemoteControl::~RemoteControl(void)
52 {
53 try
54 {
55  m_aryLinks.RemoveAll();
56 }
57 catch(...)
58 {Std_TraceMsg(0, "Caught Error in desctructor of RemoteControl\r\n", "", -1, false, true);}
59 }
60 
69 CStdPtrArray<RemoteControlLinkage> *RemoteControl::Links() {return &m_aryLinks;}
70 
79 CStdArray<RemoteControlLinkage *> *RemoteControl::InLinks() {return &m_aryInLinks;}
80 
89 CStdArray<RemoteControlLinkage *> *RemoteControl::OutLinks() {return &m_aryOutLinks;}
90 
91 CStdMap<std::string, int>* RemoteControl::DataIDMap() {return &m_aryDataIDMap;};
92 
93 void RemoteControl::ChangeSimStepCount(int iRate)
94 {
95  Std_IsAboveMin((int) 0, iRate, true, "ChangeSimStepCount");
96  m_iChangeSimStepCount = iRate;
97 
98  //Reset all the button data.
99 
100  int iCount = m_aryLinks.GetSize();
101  for(int iIndex=0; iIndex<iCount; iIndex++)
102  m_aryLinks[iIndex]->m_Data.m_iChangeSimStepCount = m_iChangeSimStepCount;
103 }
104 
105 int RemoteControl::ChangeSimStepCount() {return m_iChangeSimStepCount;}
106 
107 bool RemoteControl::UseRemoteDataTypes() {return m_bUseRemoteDataTypes;}
108 
109 #pragma region DataAccesMethods
110 
111 bool RemoteControl::AddItem(const std::string &strItemType, const std::string &strXml, bool bThrowError, bool bDoNotInit)
112 {
113  std::string strType = Std_CheckString(strItemType);
114 
115  if(strType == "REMOTECONTROLLINKAGE")
116  {
117  AddRemoteControlLinkage(strXml);
118  return true;
119  }
120 
121  return RobotIOControl::AddItem(strItemType, strXml, bThrowError, bDoNotInit);
122 }
123 
124 bool RemoteControl::RemoveItem(const std::string &strItemType, const std::string &strID, bool bThrowError)
125 {
126  std::string strType = Std_CheckString(strItemType);
127 
128  if(strType == "REMOTECONTROLLINKAGE")
129  {
131  return true;
132  }
133 
134  return RobotIOControl::RemoveItem(strItemType, strID, bThrowError);
135 }
136 #pragma region DataAccesMethods
137 
138 float *RemoteControl::GetDataPointer(const std::string &strDataType)
139 {
140  std::string strType = Std_CheckString(strDataType);
141 
142  int iCount = m_aryLinks.GetSize();
143  for(int iIndex=0; iIndex<iCount; iIndex++)
144  if(strType == Std_CheckString(m_aryLinks[iIndex]->PropertyName()))
145  {
146  int iLen = strType.length();
147  if(((iLen-5) >= 0) && strType.substr(strType.length() - 5, 5) == "START")
148  return &m_aryLinks[iIndex]->m_Data.m_fltStart;
149  else if(((iLen-4) >= 0) && strType.substr(strType.length() - 4, 4) == "STOP")
150  return &m_aryLinks[iIndex]->m_Data.m_fltStop;
151  else
152  return &m_aryLinks[iIndex]->m_Data.m_fltValue;
153  }
154 
155  return RobotIOControl::GetDataPointer(strDataType);
156 }
157 
158 bool RemoteControl::SetData(const std::string &strDataType, const std::string &strValue, bool bThrowError)
159 {
160  std::string strType = Std_CheckString(strDataType);
161 
162  if(RobotIOControl::SetData(strDataType, strValue, false))
163  return true;
164 
165  if(strType == "CHANGESIMSTEPCOUNT")
166  {
167  ChangeSimStepCount((int) atoi(strValue.c_str()));
168  return true;
169  }
170 
171  //If it was not one of those above then we have a problem.
172  if(bThrowError)
173  THROW_PARAM_ERROR(Al_Err_lInvalidDataType, Al_Err_strInvalidDataType, "Data Type", strDataType);
174 
175  return false;
176 }
177 
178 void RemoteControl::QueryProperties(CStdPtrArray<TypeProperty> &aryProperties)
179 {
180  RobotIOControl::QueryProperties(aryProperties);
181 
182  aryProperties.Add(new TypeProperty("ChangeSimStepCount", AnimatPropertyType::Integer, AnimatPropertyDirection::Set));
183 
184  int iCount = m_aryLinks.GetSize();
185  for(int iIndex=0; iIndex<iCount; iIndex++)
186  {
187  aryProperties.Add(new TypeProperty(m_aryLinks[iIndex]->m_Data.m_strProperty, AnimatPropertyType::Float, AnimatPropertyDirection::Get));
188  aryProperties.Add(new TypeProperty(m_aryLinks[iIndex]->m_Data.m_strProperty + "START", AnimatPropertyType::Float, AnimatPropertyDirection::Get));
189  aryProperties.Add(new TypeProperty(m_aryLinks[iIndex]->m_Data.m_strProperty + "STOP", AnimatPropertyType::Float, AnimatPropertyDirection::Get));
190  }
191 }
192 
193 #pragma endregion
194 
204 {
205  CStdXml oXml;
206  oXml.Deserialize(strXml);
207  oXml.FindElement("Root");
208  oXml.FindChildElement("Link");
209 
211 
212  lpPart->Initialize();
213 
214  return lpPart;
215 }
216 
227 void RemoteControl::RemoveRemoteControlLinkage(std::string strID, bool bThrowError)
228 {
229  int iPos = FindLinkageChildListPos(strID, bThrowError), iLinkPos = -1;
230 
231  RemoteControlLinkage *lpPart = m_aryLinks[iPos];
232 
233  if(lpPart->InLink())
234  iLinkPos = FindLinkageChildListPos(m_aryInLinks, strID, bThrowError);
235  else
236  iLinkPos = FindLinkageChildListPos(m_aryOutLinks, strID, bThrowError);
237 
238  StartPause();
239  if(lpPart->InLink())
240  m_aryInLinks.RemoveAt(iLinkPos);
241  else
242  m_aryOutLinks.RemoveAt(iLinkPos);
243 
244  m_aryLinks.RemoveAt(iPos);
245  ExitPause();
246 }
247 
248 
262 int RemoteControl::FindLinkageChildListPos(std::string strID, bool bThrowError)
263 {
264  std::string sID = Std_ToUpper(Std_Trim(strID));
265 
266  int iCount = m_aryLinks.GetSize();
267  for(int iIndex=0; iIndex<iCount; iIndex++)
268  if(m_aryLinks[iIndex]->ID() == sID)
269  return iIndex;
270 
271  if(bThrowError)
272  THROW_PARAM_ERROR(Al_Err_lPartInterfaceIDNotFound, Al_Err_strPartInterfaceIDNotFound, "ID", strID);
273 
274  return -1;
275 }
276 
290 int RemoteControl::FindLinkageChildListPos(CStdArray<RemoteControlLinkage *> &aryLinks, std::string strID, bool bThrowError)
291 {
292  std::string sID = Std_ToUpper(Std_Trim(strID));
293 
294  int iCount = aryLinks.GetSize();
295  for(int iIndex=0; iIndex<iCount; iIndex++)
296  if(aryLinks[iIndex]->ID() == sID)
297  return iIndex;
298 
299  if(bThrowError)
300  THROW_PARAM_ERROR(Al_Err_lPartInterfaceIDNotFound, Al_Err_strPartInterfaceIDNotFound, "ID", strID);
301 
302  return -1;
303 }
304 
305 RemoteControlLinkage *RemoteControl::FindLinkageWithPropertyName(std::string strName, bool bThrowError)
306 {
307  int iCount = m_aryLinks.GetSize();
308  for(int iIndex=0; iIndex<iCount; iIndex++)
309  if(m_aryLinks[iIndex]->PropertyName() == strName)
310  return m_aryLinks[iIndex];
311 
312  if(bThrowError)
313  THROW_PARAM_ERROR(Al_Err_lPartInterfaceIDNotFound, Al_Err_strPartInterfaceIDNotFound, "PropertyName", strName);
314 
315  return NULL;
316 }
317 
318 #pragma endregion
319 
320 void RemoteControl::ResetData()
321 {
322  int iCount = m_aryLinks.GetSize();
323  for(int iIndex=0; iIndex<iCount; iIndex++)
324  m_aryLinks[iIndex]->m_Data.ClearData();
325 }
326 
327 void RemoteControl::CheckStartedStopped()
328 {
329  int iCount = m_aryLinks.GetSize();
330  for(int iIndex=0; iIndex<iCount; iIndex++)
331  m_aryLinks[iIndex]->m_Data.CheckStartedStopped();
332 
334  //m_ButtonData[BUT_ID_RT].CheckStartedStopped();
335 }
336 
337 void RemoteControl::ClearStartStops()
338 {
339 
340  int iCount = m_aryLinks.GetSize();
341  for(int iIndex=0; iIndex<iCount; iIndex++)
342  m_aryLinks[iIndex]->m_Data.ClearStartStops();
343 
345  //m_ButtonData[BUT_ID_LOOKH].ClearStartStops();
346 }
347 
360 {
362 
363  if(m_bEnabled)
364  {
365  int iCount = m_aryLinks.GetSize();
366  for(int iIndex=0; iIndex<iCount; iIndex++)
367  if(m_aryLinks[iIndex]->Enabled())
368  m_aryLinks[iIndex]->SetupIO();
369  }
370 }
371 
372 
381 {
382  if(m_bEnabled)
383  {
384  //unsigned long long lStepStartTick = m_lpSim->GetTimerTick();
386 
387  int iCount = m_aryLinks.GetSize();
388  for(int iIndex=0; iIndex<iCount; iIndex++)
389  if(m_aryLinks[iIndex]->Enabled())
390  m_aryLinks[iIndex]->StepIO();
391 
392  //unsigned long long lEndStartTick = m_lpSim->GetTimerTick();
393  //m_fltStepIODuration = m_lpSim->TimerDiff_m(lStepStartTick, lEndStartTick);
394  }
395 }
396 
406 {
407  int iCount = m_aryLinks.GetSize();
408  for(int iIndex=0; iIndex<iCount; iIndex++)
409  if(m_aryLinks[iIndex]->Enabled())
410  m_aryLinks[iIndex]->ShutdownIO();
411 
412  //Put this last so everything gets its ShutdownIO called before we actually exit the thread.
414 }
415 
416 void RemoteControl::CreateDataIDMap()
417 {
418 }
419 
420 bool RemoteControl::FindDataToWrite(CStdArray<RemoteControlLinkage *> &aryWrites)
421 {
422  int iCount = m_aryOutLinks.GetSize();
423  for(int iIndex=0; iIndex<iCount; iIndex++)
424  {
425  if(fabs(m_aryOutLinks[iIndex]->m_Data.m_fltValue - m_aryOutLinks[iIndex]->m_Data.m_fltPrev) > 1e-10)
426  {
427  m_aryOutLinks[iIndex]->m_Data.m_fltPrev = m_aryOutLinks[iIndex]->m_Data.m_fltValue;
428  aryWrites.Add(m_aryOutLinks[iIndex]);
429  }
430  }
431 
432  if(aryWrites.GetSize() > 0)
433  return true;
434  else
435  return false;
436 }
437 
438 void RemoteControl::SetDataValue(int iID, float fltVal)
439 {
440  int iCount = m_aryInLinks.GetSize();
441  for(int iIndex=0; iIndex<iCount; iIndex++)
442  {
443  if(m_aryInLinks[iIndex]->m_Data.m_iButtonID == iID && fabs(fltVal - m_aryInLinks[iIndex]->m_Data.m_fltValue) > 1e-10)
444  {
445  m_aryInLinks[iIndex]->m_Data.m_fltPrev = m_aryInLinks[iIndex]->m_Data.m_fltValue;
446  m_aryInLinks[iIndex]->m_Data.m_fltValue = fltVal;
447  }
448  }
449 }
450 
452 {
454 
455  int iCount = m_aryLinks.GetSize();
456  for(int iIndex=0; iIndex<iCount; iIndex++)
457  m_aryLinks[iIndex]->Initialize();
458 
459  ResetData();
460 }
461 
463 {
465 
466  m_iCyclePartIdx = 0;
467  int iCount = m_aryLinks.GetSize();
468  for(int iIndex=0; iIndex<iCount; iIndex++)
469  m_aryLinks[iIndex]->ResetSimulation();
470 
471  ResetData();
472 }
473 
475 {
477 
478  int iCount = m_aryLinks.GetSize();
479  for(int iIndex=0; iIndex<iCount; iIndex++)
480  m_aryLinks[iIndex]->AfterResetSimulation();
481 }
482 
484 {
486 
487  int iCount = m_aryLinks.GetSize();
488  for(int iIndex=0; iIndex<iCount; iIndex++)
489  if(m_aryLinks[iIndex]->Enabled())
490  m_aryLinks[iIndex]->StepSimulation();
491 
492  ClearStartStops();
493 }
494 
495 void RemoteControl::Load(CStdXml &oXml)
496 {
497  RobotIOControl::Load(oXml);
498 
499  CreateDataIDMap();
500 
501  oXml.IntoElem(); //Into RigidBody Element
502 
503  ChangeSimStepCount(oXml.GetChildInt("ChangeSimStepCount", m_iChangeSimStepCount));
504 
505  if(oXml.FindChildElement("Links", false))
506  {
507  oXml.IntoElem(); //Into ChildBodies Element
508  int iChildCount = oXml.NumberOfChildren();
509 
510  for(int iIndex=0; iIndex<iChildCount; iIndex++)
511  {
512  oXml.FindChildByIndex(iIndex);
514  }
515  oXml.OutOfElem(); //OutOf ChildBodies Element
516  }
517 
518  oXml.OutOfElem(); //OutOf RigidBody Element
519 }
520 
533 {
534  RemoteControlLinkage *lpChild = NULL;
535  std::string strType;
536 
537 try
538 {
539  oXml.IntoElem(); //Into Child Element
540  std::string strModule = oXml.GetChildString("ModuleName", "");
541  strType = oXml.GetChildString("Type");
542  oXml.OutOfElem(); //OutOf Child Element
543 
544  lpChild = dynamic_cast<RemoteControlLinkage *>(m_lpSim->CreateObject(strModule, "RemoteControlLinkage", strType));
545  if(!lpChild)
546  THROW_TEXT_ERROR(Al_Err_lConvertingClassToType, Al_Err_strConvertingClassToType, "RemoteControlLinkage");
547 
548  lpChild->ParentRemoteControl(this);
549  lpChild->SetSystemPointers(m_lpSim, m_lpStructure, NULL, NULL, true);
550 
551  lpChild->Load(oXml);
552 
553  m_aryLinks.Add(lpChild);
554 
555  if(lpChild->InLink())
556  m_aryInLinks.Add(lpChild);
557  else
558  m_aryOutLinks.Add(lpChild);
559 
560  return lpChild;
561 }
562 catch(CStdErrorInfo oError)
563 {
564  if(lpChild) delete lpChild;
565  RELAY_ERROR(oError);
566  return NULL;
567 }
568 catch(...)
569 {
570  if(lpChild) delete lpChild;
571  THROW_ERROR(Std_Err_lUnspecifiedError, Std_Err_strUnspecifiedError);
572  return NULL;
573 }
574 }
575 
576 
577  }
578 }
virtual bool RemoveItem(const std::string &strItemType, const std::string &strID, bool bThrowError=true)
Removes a child item from this parent.
virtual void Deserialize(std::string &strXml)
Deserializes a string into an xml document.
Definition: StdXml.cpp:162
virtual CStdArray< RemoteControlLinkage * > * InLinks()
Gets the array of remote control in links.
virtual void StepSimulation()
Step the simulation for this object.
Base class file for all Animat simulation objects.
CStdPtrArray< RemoteControlLinkage > m_aryLinks
Definition: RemoteControl.h:14
Declares the nervous system class.
Declares the simulation recorder class.
Declares the Robot IO control interface base class.
virtual void SetSystemPointers(Simulator *lpSim, Structure *lpStructure, NeuralModule *lpModule, Node *lpNode, bool bVerify)
Sets the system pointers.
virtual bool FindChildElement(std::string strElementName, bool fThrowError=true)
Finds a child element by name.
Definition: StdXml.cpp:256
Root namespace for the base simulation library for AnimatLab.
virtual bool SetData(const std::string &strDataType, const std::string &strValue, bool bThrowError=true)
Set a variable based on a string data type name.
virtual void QueryProperties(CStdPtrArray< TypeProperty > &aryProperties)
Queries this object for a list of properties that can be changed using SetData.
virtual void Initialize()
Initializes this object.
virtual void Initialize()
Initializes this object.
Declares the body part class.
virtual void StepSimulation()
Step the simulation for this object.
CStdArray< RemoteControlLinkage * > m_aryOutLinks
Only the linkages that are outlinks.
Definition: RemoteControl.h:20
virtual bool FindElement(std::string strElementName, bool fThrowError=true)
Finds an element with the specified name.
Definition: StdXml.cpp:179
Simulator * m_lpSim
The pointer to a Simulation.
Definition: AnimatBase.h:43
Information about the standard error.
Definition: StdErrorInfo.h:19
virtual std::string ID()
Gets the unique GUID ID of this object.
Definition: AnimatBase.cpp:167
virtual bool IntoElem()
Goes into the next element where the cursor is located.
Definition: StdXml.cpp:42
virtual void ShutdownIO()
This method is called just before the IO thread is closed down. It gives the IO objects a chance to d...
virtual float * GetDataPointer(const std::string &strDataType)
Returns a float pointer to a data item of interest in this object.
Class that stores information about types for QueryProperty information.
Definition: TypeProperty.h:35
virtual void RemoveRemoteControlLinkage(std::string strID, bool bThrowError=true)
Removes the rigid body with the specified ID.
Declares the key frame class.
virtual void ResetSimulation()
Resets the simulation back to time 0.
virtual void ExitPause()
This method is waits until the m_bIOPaused flag is set back to false.
virtual bool SetData(const std::string &strDataType, const std::string &strValue, bool bThrowError=true)
Set a variable based on a string data type name.
Declares the joint class.
Declares the organism class.
virtual int GetChildInt(std::string strElementName)
Gets an integer value from the element with the specified name.
Definition: StdXml.cpp:456
virtual void StepIO()
This method is called from within the IO thread. It calls StepIO for each part.
bool Std_IsAboveMin(int iMinVal, int iVal, bool bThrowError, std::string strParamName, bool bInclusiveLimit)
Tests if a number is above a minimum value.
AnimatSim::Environment::Structure * m_lpStructure
The pointer to this items parent Structure. If this is not relevant for this object then this is NULL...
Definition: AnimatBase.h:46
virtual void ShutdownIO()
This method is called just before the IO thread is closed down. It gives the IO objects a chance to d...
std::string Std_Trim(std::string strVal)
Trims a string.
Declares a light object.
virtual void QueryProperties(CStdPtrArray< TypeProperty > &aryProperties)
Queries this object for a list of properties that can be changed using SetData.
Declares the activated item class.
virtual CStdSerialize * CreateObject(std::string strModule, std::string strClassName, std::string strType, bool bThrowError=true)
Creates an object using a class factory.
Definition: Simulator.cpp:3440
virtual float * GetDataPointer(const std::string &strDataType)
Returns a float pointer to a data item of interest in this object.
Declares a light manager object.
Declares the bounding box class.
virtual bool Enabled()
Tells whether this item is enabled or not. This is not actually used for all objects, only specific ones. I am putting it in the base class though to prevent numerous duplications.
Definition: AnimatBase.cpp:113
virtual bool AddItem(const std::string &strItemType, const std::string &strXml, bool bThrowError=true, bool bDoNotInit=false)
Adds a new object to this parent.
A standard xml manipulation class.
Definition: StdXml.h:19
virtual RemoteControlLinkage * AddRemoteControlLinkage(std::string strXml)
Creates and adds a robot IO control.
virtual CStdArray< RemoteControlLinkage * > * OutLinks()
Gets the array of remote control out links.
Declares the node class.
virtual void StepIO()
This method is called from within the IO thread. It calls StepIO for each part.
virtual std::string GetChildString(std::string strElementName)
Gets a string value from the element with the specified name.
Definition: StdXml.cpp:307
virtual void ResetSimulation()
Resets the simulation back to time 0.
void Std_TraceMsg(const int iLevel, std::string strMessage, std::string strSourceFile, int iSourceLine, bool bLogToFile, bool bPrintHeader)
Traces a message to the debugger window.
bool m_bEnabled
Tells if this item is enabled or not. If it is not enabled then it is not run.
Definition: AnimatBase.h:40
virtual int NumberOfChildren()
Gets the number of children of the current element.
Definition: StdXml.cpp:202
virtual bool OutOfElem()
Goes out of the element where the cursor is located.
Definition: StdXml.cpp:56
int m_iCyclePartIdx
The index of the part that should be processed on the current step.
virtual void Initialize()
Initializes this object.
CStdMap< std::string, int > m_aryDataIDMap
Used to map property names to IDs when UseRemoteDataTypes is true.
Definition: RemoteControl.h:23
Declares the data chart manager class.
virtual void SetupIO()
This method is called after all connections to whatever control board have been made. It calls each parts SetupIO method. For example, We connect to a Firmata microcontroller like an Arduino, and then do a setup that could take some time. We should not attempt to setup any of the pins until after the board itself has been setup. After that we need to loop through and setup all the parts.
virtual RemoteControlLinkage * LoadRemoteControlLinkage(CStdXml &oXml)
Loads a child IO Control.
Declares the rigid body class.
virtual void AfterResetSimulation()
Called after a simulation reset for some objects.
virtual void AfterResetSimulation()
Called after a simulation reset for some objects.
std::string Std_CheckString(std::string strVal)
Converts a string to upper case and trims it.
Declares the structure class.
Declares the odor type class.
virtual CStdPtrArray< RemoteControlLinkage > * Links()
Gets the array ofremote control links.
virtual bool RemoveItem(const std::string &strItemType, const std::string &strID, bool bThrowError=true)
Removes a child item from this parent.
virtual void SetupIO()
This method is called after all connections to whatever control board have been made. It calls each parts SetupIO method. For example, We connect to a Firmata microcontroller like an Arduino, and then do a setup that could take some time. We should not attempt to setup any of the pins until after the board itself has been setup. After that we need to loop through and setup all the parts.
Declares the robotics inerface for animatlab.
int m_iChangeSimStepCount
The number of simulation time slices to keep a start/stop signal active.
Definition: RemoteControl.h:26
Declares the odor class.
Declares the simulator class.
Declares the neural module class.
virtual bool FindChildByIndex(int iIndex, bool bThrowError=true)
Finds a child element by index.
Definition: StdXml.cpp:225
virtual bool InLink()
Gets the inlink value.
std::string Std_ToUpper(std::string strVal)
Converts a string to upper case.
Declares the activated item manager class.
virtual int FindLinkageChildListPos(std::string strID, bool bThrowError=true)
Finds the array index for the child part with the specified ID.
Declares the contact sensor class.
Declares the external stimuli manager class.
CStdArray< RemoteControlLinkage * > m_aryInLinks
Only the linkages that are inlinks.
Definition: RemoteControl.h:17
virtual void StartPause()
This method is waits until the m_bIOPaused flag is set to true.
virtual bool AddItem(const std::string &strItemType, const std::string &strXml, bool bThrowError=true, bool bDoNotInit=false)
Adds a new object to this parent.
Declares the receptive field class.