ODA BimRv SDK uses element IDs (instances of OdBmObjectId
) to reference database
elements. An element ID is a memory resident placeholder for a database element,
and an actual database element pointer can always be obtained from a valid element
ID. In general, a user will obtain a database element pointer by explicitly opening
the element via the element ID. An opened database element will be closed by the
associated smart pointer when the last smart pointer referring to the database
element goes out of scope, or it can be explicitly closed by calling the smart
pointer's release() function. Thus, database elements need not reside in memory
unless they have been explicitly opened. This mechanism provides transparent
partial loading functionality — a few key elements can be loaded, and the
remaining database elements can be loaded only if necessary when they are opened.
This greatly improves the execution speed for applications that need to access
only portions of a drawing.
An ID stores a unique identifier of an element across all databases loaded at run-time. An ID exists only during the current run-time session until the database is loaded into memory. The database associates an ID with an element and its handle. When a database is saved into a file, IDs are not saved. The database creates new IDs each time a database is loaded into memory. Programmatically, an ID is a specific structure named OdDbStub and contains a handle associated with an element, smart pointer to an element, pointer to a database, and pointer to an owner.
The OdBmObjectId
class implements an ID and represents the interface for getting and
modifying an identification value. The OdBmObjectId
class does not inherit the standard
database functionality; it is a specific structure for associating elements of a database.
This class declares a pointer to the specific internal class, named OdDbStub
, that contains
four members: smart pointer that addresses the referenced element in memory, handle
associated with the referenced element, pointer to the database that contains the referenced
element, and pointer to an owner that possesses the referenced element.
In the examples below, the pCmdCtx
variable stores a pointer to the command context
and the m_pDatabase
variable stores a pointer to the database element.
OdBmCommandContextPtr pDbCmdCtx(pCmdCtx);
OdBmDatabasePtr m_pDatabase = pDbCmdCtx->database();
OdSmartPtr<OdBmUserIO> pIO = pDbCmdCtx->userIO();
To create an ID, use its constructor. The OdBmObjectId
class has a single constructor
that creates an ID instance initialized by the kNull
value. For example:
// create an ID
OdBmObjectId id;
OdString message;
message.format(L"\nHandle = %llx, Db = %lx", (OdUInt64)id.getHandle(), id.database());
pIO->putString(message);
The OdBmObjectId
class declares a special notation — OdBm::kNull
— which
defines a null value for an ID instance, denoting an undefined identifier that refers to
nothing. An ID that equals kNull
is not associated with an element and has a handle equal to
zero.
To check whether an ID is null, use the isNull()
method which does not have arguments and
returns 'true' when an ID is set to kNull
or 'false' when an ID is associated with an object.
For example:
message.format(L"\nID %s", (id.isNull()) ? L"is kNull" : L"is associated");
pIO->putString(message);
To check an ID, you may also use the Not operator which calls the isNull() method and determines its returned value. For example:
id.setNull();
message.format(L"\nisNull() = %d", id.isNull());
pIO->putString(message); // =1 - kNull, =0 - not kNull
To set an ID to kNull, use the setNull() method which does not have arguments, does not return a value, and sets the ID to kNull. For example:
OdDbBaseDatabase* pIdDb = id.database();
if (pIdDb == NULL)
{
message.format(L"\nID is not associated with a database");
pIO->putString(message);
}
else
{
message.format(L"\nID is associated with database: %lx", pIdDb);
pIO->putString(message);
}
To get a database associated with an ID, use the database() method which does not have arguments and returns a pointer to the database element that contains the element associated with the ID, or NULL when the ID is not associated with an element or is set to kNull. For example:
OdDbHandle handle = id.getHandle();
if (handle.isNull())
{
message.format(L"\nID is not associated with a handle");
pIO->putString(message);
}
else
{
message.format(L"\nID is associated with handle = %s", handle.ascii().c_str());
pIO->putString(message);
}
To get a handle associated with an ID and referenced element, use the getHandle() method which does not have arguments and returns the handle assigned to the element associated with the ID or zero when the ID is not associated with an element or is set to kNull. To check the returned handle, use its isNull() method. For example:
message.format(L"\nID %s", (id.isValid()) ? L"is valid" : L"is invalid");
pIO->putString(message);
To get an element associated with an ID, use the safeOpenObject() method or openObject() method which requires the open mode as the first argument of the OdBm::OpenMode type, the erase status as the second argument of a boolean type, and returns the smart pointer to the element opened in the specified mode. The main difference between those methods is that openObject() method doesn't check the error code that was returned. safeOpenObject() method checks the returning error code and if error occurs - it generates an exception.
To check whether an ID is valid, use the isValid() method which does not have arguments and returns 'true' when an ID is valid or 'false' when an ID is invalid. When an element is marked as 'erased', it continues existing in the database, and its ID remains valid. When an element is permanently erased or an ID is kNull, the ID becomes invalid. For example:
OdBmElementPtr pObj = OdBmElement::createObject();
OdBmObjectId id_1;
OdBmObjectId id_2 = pObj->objectId(); // pObj is a pointer to an element
message.format(L"\nObj=%lx, Db=%lx, Handle=%llx, isNull=%d, isValid=%d", id_1.openObject().get(),
id_1.database(), (OdUInt64)id_1.getHandle(), id_1.isNull(), id_1.isValid());
pIO->putString(message);
message.format(L"\nObj=%lx, Db=%lx, Handle=%llx, isNull=%d, isValid=%d", id_2.openObject().get(),
id_2.database(), (OdUInt64)id_2.getHandle(), id_2.isNull(), id_2.isValid());
pIO->putString(message);
When an ID element is not associated with an element, the handle is set to '-1', the pointer to the database is set to NULL, the pointer to the element is set to NULL, the erase status is 'true', and the ID is invalid and identified as kNull. When an ID element is associated with an element, the handle has an identifier, the pointer to a database is set to the address of an existing database, the pointer to an element is set to the address of an existing instance, the erase status is 'false', and the ID is valid. For example:
OdBmDatabasePtr pDb1 = pDbCmdCtx->database();
OdBmDatabasePtr pDb2 = pDbCmdCtx->database();
OdBmObjectId id1 = pDb1->getOwnerFamilyId();
OdBmObjectId id2 = pDb2->getOwnerFamilyId();
OdBmObjectId id3 = pDb1->getOwnerFamilyContainingGroupId();
OdBmObjectId id4 = pDb2->getOwnerFamilyContainingGroupId();
message.format(L"\n1) %llx", (OdUInt64)id1.getHandle());
pIO->putString(message);
message.format(L"\n2) %llx", (OdUInt64)id2.getHandle());
pIO->putString(message);
message.format(L"\n3) %llx", (OdUInt64)id3.getHandle());
pIO->putString(message);
message.format(L"\n4) %llx", (OdUInt64)id4.getHandle());
pIO->putString(message);
// Compare the same element from different databases
message.format(L"\n(id1 == id2) = %d, (id1 != id2) = %d", (id1 == id2), (id1 != id2));
pIO->putString(message);
message.format(L"\n(id3 == id4) = %d, (id3 != id4) = %d", (id3 == id4), (id3 != id4));
pIO->putString(message);
// Compare the different elements from the same database
message.format(L"\n(id1 == id3) = %d, (id1 != id3) = %d", (id1 == id3), (id1 != id3));
pIO->putString(message);
message.format(L"\n(id2 == id4) = %d, (id2 != id4) = %d", (id2 == id4), (id2 != id4));
pIO->putString(message);
// Compare the different elements from different databases
message.format(L"\n(id1 == id4) = %d, (id1 != id4) = %d", (id1 == id4), (id1 != id4));
pIO->putString(message);
message.format(L"\n(id2 == id3) = %d, (id2 != id3) = %d", (id2 == id3), (id2 != id3));
pIO->putString(message);
/* Result is following:
(id1 == id2) = 1, (id1 != id2) = 0
(id3 == id4) = 1, (id3 != id4) = 0
(id1 == id3) = 0, (id1 != id3) = 1
(id2 == id4) = 0, (id2 != id4) = 1
(id1 == id4) = 0, (id1 != id4) = 1
(id2 == id3) = 0, (id2 != id3) = 1
*/
To compare IDs, use the comparison operators that compare the ID elements taking into account the handle and database. For example:
id1 = pDb1->getOwnerFamilyId();
id2 = id1;
message.format(L"\nH1=%llx, H2=%llx, (ID1==ID2)=%d", (OdUInt64)id1.getHandle(), (OdUInt64)id2.getHandle(), (id1 == id2));
pIO->putString(message);
To copy an ID, use the Assignment operator that copies one ID to another ID. For example:
Copyright © 2002 – 2022. Open Design Alliance. All rights reserved.
|