C++ Module: How do I cast a custom Object

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By hidemat

Hello. I’m having trouble casting a custom class that inherits from Object here is how I declared it:

class Leaf : public Object {
	GDCLASS(Leaf, Object);

protected:
	static void _bind_methods() {}

public:
	Leaf* parent = nullptr;
	float cost = 0;
	Array all_states;
	ObjectID action_id;
	AgentAction* get_action();

	Leaf(Leaf* p_parent, float p_cost, Array p_world_states, Array p_beliefs, AgentAction* p_action);

	Leaf();
	~Leaf();
};

These are the constructors and destructors. The _bind_method doesn’t do anything so it’s declared and defined in the header file:

Leaf::Leaf(Leaf* p_parent, float p_cost, Array p_world_states, Array p_beliefs, AgentAction *p_action)
{
	parent = p_parent;
	cost = p_cost;
	all_states = p_world_states.duplicate();
	all_states.append_array(p_beliefs.duplicate());

	if (p_action != nullptr) {
		action_id = p_action->get_instance_id();
	}
}

Leaf::Leaf() {}
Leaf::~Leaf() {}

This is the call in register_types.cpp:
GDREGISTER_CLASS(Leaf);

But when I try to call Leaf *cheapest = Object::cast_to<Leaf>(leaves[0]); I get a nullptr. leaves is an Array containing Leaf objects. I know from debuggin that it contains 1 leaf, but for some reason it fails to cast. Any ideas as to why this may be?

Not much help, but I can’t reproduce this. I used the Summator example from the docs and did the following:

void Summator::test_method()
{
    Summator *pSum = Object::cast_to<Summator>(return_array()[0]);
    pSum->add(3);
    print_line(pSum->get_total());

    memdelete(pSum);
}

Array Summator::return_array()
{
    Summator *pOb = memnew(Summator);
    pOb->add(2);
    print_line(pOb->get_total());
    Array ar;
    ar.push_back(pOb);

    return ar;
}

test_method gets called from a GDscript file in the scene. The output correctly prints 2 and then 5, so Object::cast_to succeeds here.

I noticed that there are different initialization levels for register_types. Did you try using a different one? I used:

void initialize_mymod_module(ModuleInitializationLevel p_level) 
{
	if (p_level == MODULE_INITIALIZATION_LEVEL_SCENE) {
        GDREGISTER_CLASS(Summator);
    }
}

omggomb | 2022-08-02 10:07