///////////////////////////////////////////////////////////////////////////////
|
// Copyright (C) 2002-2016, Open Design Alliance (the "Alliance").
|
// All rights reserved.
|
//
|
// This software and its documentation and related materials are owned by
|
// the Alliance. The software may only be incorporated into application
|
// programs owned by members of the Alliance, subject to a signed
|
// Membership Agreement and Supplemental Software License Agreement with the
|
// Alliance. The structure and organization of this software are the valuable
|
// trade secrets of the Alliance and its suppliers. The software is also
|
// protected by copyright law and international treaty provisions. Application
|
// programs incorporating this software must include the following statement
|
// with their copyright notices:
|
//
|
// This application incorporates Teigha(R) software pursuant to a license
|
// agreement with Open Design Alliance.
|
// Teigha(R) Copyright (C) 2002-2016 by Open Design Alliance.
|
// All rights reserved.
|
//
|
// By use of this software, its documentation or related materials, you
|
// acknowledge and accept the above terms.
|
///////////////////////////////////////////////////////////////////////////////
|
|
#ifndef _ODRXMULTICAST_H_
|
#define _ODRXMULTICAST_H_
|
|
#include "RxObject.h"
|
|
#include "TD_PackPush.h"
|
|
/** details
|
Provides ability to cast RxObject into set of classes as one step.
|
|
- Basic (investigate entire classes structure and set all pointers)
|
odrxMultiCast - Check all classes include protocol extensions
|
odrxMultiCastObject - Check all classes without protocol extensions check
|
odrxMultiCastX - Check all protocol extensions only
|
- Single shot (investigate classes structure until any first doesn't found and stop check)
|
odrxMultiCastFwd - scan forward (from OdRxObject class) with protocol extensions with second priority
|
odrxMultiCastFwdXPrior - scan forward (from OdRxObject class) with protocol extensions with first priority
|
odrxMultiCastFwdObject - scan forward (from OdRxObject class) without protocol extensions check
|
odrxMultiCastFwdX - scan forward (from OdRxObject class) protocol extensions only
|
odrxMultiCastBk - scan backward (from last inherited class) with protocol extensions with second priority
|
odrxMultiCastBkXPrior - scan backward (from last inherited class) with protocol extensions with first priority
|
odrxMultiCastBkObject - scan backward (from last inherited class) without protocol extensions check
|
odrxMultiCastBkX - scan backward (from last inherited class) protocol extensions only
|
|
\param pObject [in] - object for which check will be processed
|
\param pPointers [out] - array of pointers which will be set to found classes (use static_cast or c-style cast to convert pointers)
|
\param pClasses [in] - array of classes into which object cast must be processed
|
\param nClasses [in] - count of classes in pClasses and pointer in pPointers arrays
|
*/
|
|
inline // Returns count of available casts, pPointers must be non-zero
|
OdUInt32 odrxMultiCast(const OdRxObject *pObject, OdRxObjectPtr *pPointers, const OdRxClass **pClasses, OdUInt32 nClasses)
|
{
|
OdUInt32 nCasts = 0;
|
if (!pObject || !pPointers || !pClasses || !nClasses)
|
return nCasts;
|
OdRxClass *pClass = pObject->isA();
|
while (pClass)
|
{
|
for (OdUInt32 nClass = 0; nClass < nClasses; nClass++)
|
{
|
if (pPointers[nClass].isNull())
|
{
|
if (pClass == pClasses[nClass])
|
{
|
pPointers[nClass] = pObject;
|
nCasts++;
|
if (nCasts == nClasses)
|
return nCasts;
|
}
|
else
|
{
|
pPointers[nClass] = pClass->getX(pClasses[nClass]);
|
if (!pPointers[nClass].isNull())
|
{
|
nCasts++;
|
if (nCasts == nClasses)
|
return nCasts;
|
}
|
}
|
}
|
}
|
pClass = pClass->myParent();
|
}
|
return nCasts;
|
}
|
|
inline // If pCasts null returns bit mask, elsewhere count of casts
|
OdUInt32 odrxMultiCastObject(const OdRxObject *pObject, bool *pCasts, const OdRxClass **pClasses, OdUInt32 nClasses)
|
{
|
OdUInt32 nCasts = 0, nBits = 0;
|
if (!pObject || !pClasses || !nClasses)
|
return nCasts;
|
OdRxClass *pClass = pObject->isA();
|
while (pClass)
|
{
|
for (OdUInt32 nClass = 0; nClass < nClasses; nClass++)
|
{
|
if ((pCasts) ? !pCasts[nClass] : ((nBits & (1 << nClass)) == 0))
|
{
|
if (pClass == pClasses[nClass])
|
{
|
if (pCasts)
|
pCasts[nClass] = true;
|
else
|
nBits |= 1 << nClass;
|
nCasts++;
|
if (nCasts == nClasses)
|
return nCasts;
|
}
|
}
|
}
|
pClass = pClass->myParent();
|
}
|
return (pCasts) ? nCasts : nBits;
|
}
|
|
inline // Returns count of available casts, pPointers must be non-zero
|
OdUInt32 odrxMultiCastX(const OdRxObject *pObject, OdRxObjectPtr *pPointers, const OdRxClass **pClasses, OdUInt32 nClasses)
|
{
|
OdUInt32 nCasts = 0;
|
if (!pObject || !pPointers || !pClasses || !nClasses)
|
return nCasts;
|
OdRxClass *pClass = pObject->isA();
|
while (pClass)
|
{
|
for (OdUInt32 nClass = 0; nClass < nClasses; nClass++)
|
{
|
if (pPointers[nClass].isNull())
|
{
|
pPointers[nClass] = pClass->getX(pClasses[nClass]);
|
if (!pPointers[nClass].isNull())
|
{
|
nCasts++;
|
if (nCasts == nClasses)
|
return nCasts;
|
}
|
}
|
}
|
pClass = pClass->myParent();
|
}
|
return nCasts;
|
}
|
|
inline
|
OdUInt32 odrxMultiCastFwd_(OdRxClass *pClass, const OdRxObject *pObject, OdRxObjectPtr &pPointer, const OdRxClass **pClasses, OdUInt32 nClasses)
|
{
|
OdRxClass *pParent = pClass->myParent();
|
if (pParent)
|
{
|
OdUInt32 nIndex = odrxMultiCastFwd_(pParent, pObject, pPointer, pClasses, nClasses);
|
if (nIndex < nClasses)
|
return nIndex;
|
}
|
for (OdUInt32 nClass = 0; nClass < nClasses; nClass++)
|
{
|
if (pClass == pClasses[nClass])
|
{
|
pPointer = pObject;
|
return nClass;
|
}
|
else
|
{
|
pPointer = pClass->getX(pClasses[nClass]);
|
if (!pPointer.isNull())
|
return nClass;
|
}
|
}
|
return nClasses;
|
}
|
inline
|
OdUInt32 odrxMultiCastFwd(const OdRxObject *pObject, OdRxObjectPtr &pPointer, const OdRxClass **pClasses, OdUInt32 nClasses)
|
{
|
if (!pObject || !pClasses || !nClasses)
|
return nClasses;
|
OdRxClass *pClass = pObject->isA();
|
return odrxMultiCastFwd_(pClass, pObject, pPointer, pClasses, nClasses);
|
}
|
|
inline
|
OdUInt32 odrxMultiCastFwdXPrior_(OdRxClass *pClass, const OdRxObject *pObject, OdRxObjectPtr &pPointer, const OdRxClass **pClasses, OdUInt32 nClasses)
|
{
|
OdRxClass *pParent = pClass->myParent();
|
if (pParent)
|
{
|
OdUInt32 nIndex = odrxMultiCastFwdXPrior_(pParent, pObject, pPointer, pClasses, nClasses);
|
if (nIndex < nClasses)
|
return nIndex;
|
}
|
for (OdUInt32 nClass = 0; nClass < nClasses; nClass++)
|
{
|
pPointer = pClass->getX(pClasses[nClass]);
|
if (!pPointer.isNull())
|
return nClass;
|
if (pClass == pClasses[nClass])
|
{
|
pPointer = pObject;
|
return nClass;
|
}
|
}
|
return nClasses;
|
}
|
inline
|
OdUInt32 odrxMultiCastFwdXPrior(const OdRxObject *pObject, OdRxObjectPtr &pPointer, const OdRxClass **pClasses, OdUInt32 nClasses)
|
{
|
if (!pObject || !pClasses || !nClasses)
|
return nClasses;
|
OdRxClass *pClass = pObject->isA();
|
return odrxMultiCastFwdXPrior_(pClass, pObject, pPointer, pClasses, nClasses);
|
}
|
|
inline
|
OdUInt32 odrxMultiCastFwdObject_(OdRxClass *pClass, const OdRxObject *pObject, const OdRxClass **pClasses, OdUInt32 nClasses)
|
{
|
OdRxClass *pParent = pClass->myParent();
|
if (pParent)
|
{
|
OdUInt32 nIndex = odrxMultiCastFwdObject_(pParent, pObject, pClasses, nClasses);
|
if (nIndex < nClasses)
|
return nIndex;
|
}
|
for (OdUInt32 nClass = 0; nClass < nClasses; nClass++)
|
{
|
if (pClass == pClasses[nClass])
|
return nClass;
|
}
|
return nClasses;
|
}
|
inline
|
OdUInt32 odrxMultiCastFwdObject(const OdRxObject *pObject, const OdRxClass **pClasses, OdUInt32 nClasses)
|
{
|
if (!pObject || !pClasses || !nClasses)
|
return nClasses;
|
OdRxClass *pClass = pObject->isA();
|
return odrxMultiCastFwdObject_(pClass, pObject, pClasses, nClasses);
|
}
|
|
inline
|
OdUInt32 odrxMultiCastFwdX_(OdRxClass *pClass, const OdRxObject *pObject, OdRxObjectPtr &pPointer, const OdRxClass **pClasses, OdUInt32 nClasses)
|
{
|
OdRxClass *pParent = pClass->myParent();
|
if (pParent)
|
{
|
OdUInt32 nIndex = odrxMultiCastFwdX_(pParent, pObject, pPointer, pClasses, nClasses);
|
if (nIndex < nClasses)
|
return nIndex;
|
}
|
for (OdUInt32 nClass = 0; nClass < nClasses; nClass++)
|
{
|
pPointer = pClass->getX(pClasses[nClass]);
|
if (!pPointer.isNull())
|
return nClass;
|
}
|
return nClasses;
|
}
|
inline
|
OdUInt32 odrxMultiCastFwdX(const OdRxObject *pObject, OdRxObjectPtr &pPointer, const OdRxClass **pClasses, OdUInt32 nClasses)
|
{
|
if (!pObject || !pClasses || !nClasses)
|
return nClasses;
|
OdRxClass *pClass = pObject->isA();
|
return odrxMultiCastFwdX_(pClass, pObject, pPointer, pClasses, nClasses);
|
}
|
|
inline
|
OdUInt32 odrxMultiCastBk(const OdRxObject *pObject, OdRxObjectPtr &pPointer, const OdRxClass **pClasses, OdUInt32 nClasses)
|
{
|
if (!pObject || !pClasses || !nClasses)
|
return nClasses;
|
OdRxClass *pClass = pObject->isA();
|
while (pClass)
|
{
|
for (OdUInt32 nClass = 0; nClass < nClasses; nClass++)
|
{
|
if (pClass == pClasses[nClass])
|
{
|
pPointer = pObject;
|
return nClass;
|
}
|
else
|
{
|
pPointer = pClass->getX(pClasses[nClass]);
|
if (!pPointer.isNull())
|
return nClass;
|
}
|
}
|
pClass = pClass->myParent();
|
}
|
return nClasses;
|
}
|
|
inline
|
OdUInt32 odrxMultiCastBkXPrior(const OdRxObject *pObject, OdRxObjectPtr &pPointer, const OdRxClass **pClasses, OdUInt32 nClasses)
|
{
|
if (!pObject || !pClasses || !nClasses)
|
return nClasses;
|
OdRxClass *pClass = pObject->isA();
|
while (pClass)
|
{
|
for (OdUInt32 nClass = 0; nClass < nClasses; nClass++)
|
{
|
pPointer = pClass->getX(pClasses[nClass]);
|
if (!pPointer.isNull())
|
return nClass;
|
if (pClass == pClasses[nClass])
|
{
|
pPointer = pObject;
|
return nClass;
|
}
|
}
|
pClass = pClass->myParent();
|
}
|
return nClasses;
|
}
|
|
inline
|
OdUInt32 odrxMultiCastBkObject(const OdRxObject *pObject, const OdRxClass **pClasses, OdUInt32 nClasses)
|
{
|
if (!pObject || !pClasses || !nClasses)
|
return nClasses;
|
OdRxClass *pClass = pObject->isA();
|
while (pClass)
|
{
|
for (OdUInt32 nClass = 0; nClass < nClasses; nClass++)
|
{
|
if (pClass == pClasses[nClass])
|
return nClass;
|
}
|
pClass = pClass->myParent();
|
}
|
return nClasses;
|
}
|
|
inline
|
OdUInt32 odrxMultiCastBkX(const OdRxObject *pObject, OdRxObjectPtr &pPointer, const OdRxClass **pClasses, OdUInt32 nClasses)
|
{
|
if (!pObject || !pClasses || !nClasses)
|
return nClasses;
|
OdRxClass *pClass = pObject->isA();
|
while (pClass)
|
{
|
for (OdUInt32 nClass = 0; nClass < nClasses; nClass++)
|
{
|
pPointer = pClass->getX(pClasses[nClass]);
|
if (!pPointer.isNull())
|
return nClass;
|
}
|
pClass = pClass->myParent();
|
}
|
return nClasses;
|
}
|
|
#include "TD_PackPop.h"
|
|
#endif // _ODRXMULTICAST_H_
|