Kernel SDK Developer's Guide > Comparing Rx-Objects > Comparing the Equivalence of Rx Objects
Comparing the Equivalence of Rx Objects

The OdRxObject class declares the isEqualTo() virtual method that compares whether two instances are equivalent according to some meaning, which is defined by the developer. In the default implementation, this method compares whether two objects are the same instance. Because the isEqualTo() method is virtual, a developer can redefine it in the derived class in order to compare objects. This method must return True when the instances are equivalent or False when the instances are not equivalent.

For example, if a screen point object is defined by integer-valued coordinates on a screen (row and column) and is assigned a color as an RGB value, the two screen points are equivalent if they are placed in the same screen position — that is, if their rows and columns are the same (the color can be different).

The example implements the xScreenPoint class to provide the functionality of a point, which must include creating a point, setting a position and color, getting a row, column, or color. This class will not have an equivalent. The example will derive the xScreenPoint class directly from the OdRxObject class. To implement the reference counting functionality, the example uses the OdRxObjectImpl template class when it derives the xScreenPoint class from the OdRxObject class. Next the example derives the xEquScreenPoint class from the xScreenPoint class, used only to redefine the isEqualTo() method for comparing points, then the example implements the main() function to test the instances of these classes.

To declare the standard RTTI methods, the example uses the ODRX_DECLARE_MEMBERS macro. To implement the standard RTTI methods, the example uses the ODRX_CONS_DEFINE_MEMBERS macro.

Step 1. Implementing the xScreenPoint class

The xScreenPoint class defines the color, row, and column as integer values. To specify the color, this class uses the ODRGB macros. To work with points, this class declares the setPoint() method that specifies the row, column, and color; the getRow() method that returns the current row of a screen point; the getColumn() method that returns the current column of a screen point; and the getColor() method that returns the current color of a point. The xScreenPoint class has the following definition:

class xScreenPoint : public OdRxObjectImpl<OdRxObject>
{
 private:
   OdInt16 row;
   OdInt16 column;
   OdUInt32 color;
   
 public:
   ODRX_DECLARE_MEMBERS(xScreenPoint);

   virtual OdInt16 getRow() const;
   virtual OdInt16 getColumn() const;
   virtual OdUInt32 getColor() const;
   virtual void setPoint(OdInt16 newRow, OdInt16 newColumn, OdUInt32 newColor);

   xScreenPoint();
   ~xScreenPoint();
};

typedef OdSmartPtr<xScreenPoint> xScreenPointPtr;

Its methods have the following implementation:

ODRX_CONS_DEFINE_MEMBERS(xScreenPoint, OdRxObject, NEWOBJ_CONSTR);

xScreenPoint::xScreenPoint() {  column = row = 0;  color = ODRGB(0,0,0);  }

xScreenPoint::~xScreenPoint() {}

OdInt16 xScreenPoint::getRow() const  {  return row;  }

OdInt16 xScreenPoint::getColumn() const  {  return column;  }

OdUInt32 xScreenPoint::getColor() const  {  return color;  }

void xScreenPoint::setPoint(OdInt16 newRow, OdInt16 newColumn, OdUInt32 newColor)
{
   row = newRow;   column = newColumn;
   color = newColor;
}

Step 2. Implementing the xEquScreenPoint class

To implement object comparison, derive the xEquScreenPoint class from the xScreenPoint class and redefine its isEqualTo() virtual method. The xEquScreenPoint class has the following definition:

class xEquScreenPoint : public xScreenPoint
{
 public:
   ODRX_DECLARE_MEMBERS(xEquScreenPoint);
   bool isEqualTo(const OdRxObject* pOther) const;

   xEquScreenPoint();
   ~xEquScreenPoint();
};

typedef OdSmartPtr<xEquScreenPoint> xEquScreenPointPtr;

The isEqualTo() method gets the pointer to the instance with which the current instance must be compared. It uses the isA() method to check whether the other instance has the same class. The other instance must be the xEquScreenPoint class. Then the isEqualTo() method converts the pointer and compares each point's row and column. The methods of the xEquScreenPoint class have the following implementation:

ODRX_CONS_DEFINE_MEMBERS(xEquScreenPoint, xScreenPoint, NEWOBJ_CONSTR);

xEquScreenPoint::xEquScreenPoint() : xScreenPoint()  {}

xEquScreenPoint::~xEquScreenPoint() {}

bool xEquScreenPoint::isEqualTo(const OdRxObject* pOther) const
{
  if(this->isA() != pOther->isA()) return false;
  
  xEquScreenPoint* pOtherPoint = (xEquScreenPoint*) pOther;
  
  return ((this->getRow() == pOtherPoint->getRow() && 
           this->getColumn() == pOtherPoint->getColumn()) ? true : false);
}

Step 3. Testing the xScreenPoint class and xEquScreenPoint class

For testing these classes, the example implements the main() function that creates the array of the xScreenPoint instances and the array of the xEquScreenPoint instances. Then it compares the element pairs of the arrays. Each array contains two pairs of points with the same coordinates and different colors. The TestEqualTo() function prints the address, row, column, and color of instances that it compares, and it prints the result of the comparison. The Main module has the following implementation:

#include "OdaCommon.h"
#include "OdToolKit.h"
#include "..\..\Teigha.dwg\Extensions\ExServices\ExHostAppServices.h"
#include "..\..\Teigha.dwg\Extensions\ExServices\ExSystemServices.h"

class MyApp : public ExSystemServices 
{
 protected:
   ODRX_USING_HEAP_OPERATORS(ExSystemServices);
 public:
   MyApp() {};
};

void TestEqualTo(xScreenPoint pArr[], int count)
{ 
  int i, j, l;
  for(l=1, i=0 ; i < count ; i++)
    for(j=i ; j < count ; j++, l++)
      odPrintConsoleString(L"\n%d Point [%x] (%d,%d)%x \tIsEqualTo [%x] (%d,%d)%x \t=> %s", l,
                           &pArr[i], pArr[i].getRow(), pArr[i].getColumn(), pArr[i].getColor(),
                           &pArr[j], pArr[j].getRow(), pArr[j].getColumn(), pArr[j].getColor(),
                           (pArr[i].isEqualTo(&pArr[j])) ? L"true" : L"false");
}

#include <conio.h>

int main()
{
  OdStaticRxObject<MyApp> svcs;

  odInitialize(&svcs);
  xScreenPoint::rxInit();
  xEquScreenPoint::rxInit();

  xScreenPoint Arr1[4];
  Arr1[0].setPoint(1, 1, ODRGB(1, 1, 1));
  Arr1[1].setPoint(2, 3, ODRGB(2, 2, 2));
  Arr1[2].setPoint(1, 1, ODRGB(4, 4, 4));
  Arr1[3].setPoint(2, 3, ODRGB(8, 8, 8));

  TestEqualTo(Arr1, 4);
  getch();

  odPrintConsoleString(L"\n");

  xEquScreenPoint Arr2[4];
  Arr2[0].setPoint(1, 1, ODRGB(1, 1, 1));
  Arr2[1].setPoint(2, 3, ODRGB(2, 2, 2));
  Arr2[2].setPoint(1, 1, ODRGB(4, 4, 4));
  Arr2[3].setPoint(2, 3, ODRGB(8, 8, 8));

  TestEqualTo(Arr2, 4);
  getch();

  xEquScreenPoint::rxUninit();
  xScreenPoint::rxUninit();
  odUninitialize();

  return 0;
}

The result for the xScreenPoint class is the following:

 1 Point [12ff24] (1,1)10101       IsEqualTo [12ff24] (1,1)10101   => true
 2 Point [12ff24] (1,1)10101       IsEqualTo [12ff38] (2,3)20202   => false
 3 Point [12ff24] (1,1)10101       IsEqualTo [12ff4c] (1,1)40404   => false
 4 Point [12ff24] (1,1)10101       IsEqualTo [12ff60] (2,3)80808   => false
 5 Point [12ff38] (2,3)20202       IsEqualTo [12ff38] (2,3)20202   => true
 6 Point [12ff38] (2,3)20202       IsEqualTo [12ff4c] (1,1)40404   => false
 7 Point [12ff38] (2,3)20202       IsEqualTo [12ff60] (2,3)80808   => false
 8 Point [12ff4c] (1,1)40404       IsEqualTo [12ff4c] (1,1)40404   => true
 9 Point [12ff4c] (1,1)40404       IsEqualTo [12ff60] (2,3)80808   => false
10 Point [12ff60] (2,3)80808       IsEqualTo [12ff60] (2,3)80808   => true

The result for the xEquScreenPoint class is the following:

 1 Point [12fed4] (1,1)10101       IsEqualTo [12fed4] (1,1)10101   => true
 2 Point [12fed4] (1,1)10101       IsEqualTo [12fee8] (2,3)20202   => false
 3 Point [12fed4] (1,1)10101       IsEqualTo [12fefc] (1,1)40404   => true
 4 Point [12fed4] (1,1)10101       IsEqualTo [12ff10] (2,3)80808   => false
 5 Point [12fee8] (2,3)20202       IsEqualTo [12fee8] (2,3)20202   => true
 6 Point [12fee8] (2,3)20202       IsEqualTo [12fefc] (1,1)40404   => false
 7 Point [12fee8] (2,3)20202       IsEqualTo [12ff10] (2,3)80808   => true
 8 Point [12fefc] (1,1)40404       IsEqualTo [12fefc] (1,1)40404   => true
 9 Point [12fefc] (1,1)40404       IsEqualTo [12ff10] (2,3)80808   => false
10 Point [12ff10] (2,3)80808       IsEqualTo [12ff10] (2,3)80808   => true

The isEqualTo() method of the xScreenPoint class returns True if the address of the two instances are the same (that is, the same instance). The isEqualTo() method of the xEquScreenPoint class returns True if the row and column of two instances are equal and the instances are different (that is, they have a different address and color, see lines 3, 7).

See Also

Comparing Rx Objects

Comparing the Value of Rx Objects

Copyright © 2002 – 2020. Open Design Alliance. All rights reserved.