This question is for C++ in C4D 2023.
Situation
I'm creating an ObjectData
plugin, let's call the class Parent
. Parent
has various properties which allow the user to define its behavior.
Then there is another ObjectData
, let's call that one Child
. Child
is supposed to create a list of Nulls
. The count of Nulls
as well as their Shape
property must be defined by Parent
where one of the exposed properties of Parent
has an effect on the count while the Shape
is determined by some logic in Parent
.
The crucial part is that both the count and Shape
are always set together by Parent
. This event must be the trigger for Child
to purge its current Nulls
and rebuild them from the ground up using the desired Shape
. It is not acceptable to create the Nulls
at one point and simply changing the Shape
later on, both steps must always occur at the same time.
What is the best approach for Parent
to trigger this logic in Child
?
Idea 1: Message MSG_DESCRIPTION_POSTSETPARAMETER
Child
could listen to the MSG_DESCRIPTION_POSTSETPARAMETER
in the Message
function. This however will be triggered for each changed property separately so I can't exactly trigger the logic at the correct time, which would break the requirement. So I don't think this is the way. At least from what I know about this approach.
The code in Parent
would look something like this:
Int32 childNullsCount = getChildNullsCount();
Int32 childNullsShape = getChildNullsShape();
BaseObject* child = BaseObject::Alloc(Ochild);
BaseContainer& childData = child ->GetDataInstanceRef();
childData->SetInt32(CHILD_NULLS_COUNT, childNullsCount);
childData->SetInt32(CHILD_NULLS_SHAPE, childNullsShape);
Idea 2: Custom Message
I could define a new message ID and pass the data together.
Code in Parent
:
Int32 childNullsCount = getChildNullsCount();
Int32 childNullsShape = getChildNullsShape();
BaseObject* child = BaseObject::Alloc(Ochild);
// MSG_CHILD_CREATENULLS is defined somewhere else.
child->Message(MSG_CHILD_CREATENULLS, &CreateNullsData(childNullsCount, childNullsShape);
Code in Child
:
Bool Child::Message(GeListNode* node, Int32 type, void* data)
{
switch (type)
{
case MSG_CHILD_CREATENULLS:
CreateNullsData* createData = static_cast<CreateNullsData*>(data);
createNullsWithShape(createData->Count, createData->Shape);
break;
}
return true;
}
Idea 3: Custom function in Child
Child
could expose a function like this:
class Child : public ObjectData
{
public:
/* ... */
void CreateNulls(Int32 count, Int32 shape);
}
Parent
could then do:
Int32 childNullsCount = getChildNullsCount();
Int32 childNullsShape = getChildNullsShape();
BaseObject* child = BaseObject::Alloc(Ochild);
Child* castedChild = /* what code goes here to cast BaseObject* to Child*? */;
castedChild->CreateNulls(childNullsCount, childNullsShape);
Even if this isn't the way I'd still love to know how to cast BaseObject*
to Child*
.
Disclaimer
My actual plugin handles a more complex scenario which would obscure the question too much due to all the details so I'm trying to keep this topic very abstract.