Type checking in GMAT

Development related to the GMAT core and GUI

Type checking in GMAT

Postby DJCinSB » Thu Oct 01, 2009 4:26 pm

Sometimes it's important to check type for objects that are retrieved using GmatBase pointers. There are 4 GmatBase methods that let you do this. If you only need the core type for the object you are using, you can just call the GetType() method, which returns a value from the ObjectType enumeration in the Gmat namespace. The value returned this way provides information about the (intermediate) base class that the object was built on, but not necessarily the derived type of the object. So, for example, DifferentialCorrector objects report their type as a Gmat::Solver. You can retrieve a string describing the derived type by calling the GetTypeName() method; for differential correctors, that call returns the string "DifferentialCorrector." There are cases where you need type information about the intermediate class structure. GMAT provides this information using the IsOfType() methods, described in the following paragraphs.

GmatBase provides two public IsOfType methods:
Code: Select all
   bool    IsOfType(Gmat::ObjectType ofType) const;
   bool    IsOfType(std::string typeDescription) const;

that provide the ability to test class hierarchy types using either a value from the ObjectType enumeration or a text version of the type. These methods return true if the object has the input type in its class hierarchy.

An example of code in GMAT that uses this facility is the Optimize command. Optimize is a SolverBranchCommand, and it uses a Solver object to perform optimization. Not all solvers are optimizers, though, so the Optimize command checks to be sure that the inherited solver is an optimizer, and throws an exception if it is not. The code that does this checking looks like this:
Code: Select all
   if (mapObj->IsOfType("Optimizer") == false)
      throw CommandException("The object " + solverName +
            " is not an Optimizer, so the Optimize command cannot proceed "
            "with initialization.");

This facility is useful for relatively deep class hierarchies as well. For example, the Spacecraft class if derived from SpaceObject, which is a SpacePoint. SpacePoint is derived from GmatBase. The object referenced coordinate systems require SpacePoint objects, but a call to the GetType() method for a spacecraft returns Gmat::Spacecraft. However, if you test the type using the IsOfType(Gmat::SpacePoint), you get true, so you know that the Spacecraft class hierarchy includes the SpacePoint class, and can be used as a SpacePoint in the coordinate system code. Similarly, you can test -- with the same result -- by calling IsOfType("SpacePoint").

Now, suppose you are building a new class and need to have its type recognized in GMAT. There are 2 pieces of type information that need to be set in your default constructor. For base classes (Solver, for instance), you'll want to set both; the derived classes that don't contain an identifier in the ObjectType enumeration only need the string version. GmatBase has two vectors that it uses for this type checking magic:
Code: Select all
  /// The list of generic types that this class extends.
  ObjectTypeArray     objectTypes;
  /// The list types that this class extends, by name
  StringArray         objectTypeNames;

In your classes, you'll need to push the object type (if applicable) and type name to these members in the default constructors. (Copy constructors do that automatically via the GmatBase copy constructor code.) An example of what you want to do for an intermediate base class can be seen on the Solver class constructor, where you'll see these lines:
Code: Select all
  objectTypes.push_back(Gmat::SOLVER);
  objectTypeNames.push_back("Solver");

This loads the arrays so that type checking recognizes derived classes to be of type Gmat::SOLVER, and to be identified as members of the "Solver" class hierarchy. The derived classes typically only load up the string versions; for example, the FminconOptimizer does this:
Code: Select all
  objectTypeNames.push_back("FminconOptimizer");

but does not push anything to the enumerated type list. Similarly, the Optimizer intermediate class just pushed the "Optimizer" string into the StringArray. That is what makes the type checking for the inherited solver pointer in the Optimize command, shown above, work correctly for all of GMAT's optimizers.
DJCinSB
 
Posts: 274
Joined: Mon Jun 09, 2008 3:57 pm

Return to Core Development

Who is online

Users browsing this forum: No registered users and 5 guests

cron