Cannot convert from - to

Hello guys.
I am having a problem with this function:

void InitTask::make_task( AsyncTask::DoneStatus task2, PT(AsyncTaskManager) taskMgr )
{
	task = new GenericAsyncTask( "Task", &task2, (void*) NULL );
	taskMgr->add(task);
}

When i try to compile i get the error

To tell the truth i do not know how to fix it. I mean it must be AsyncTask::DoneStatus and the compiler says it shouldn’t. I would appreciate any ideas, thank you.

You’re passing a reference to the task2 parameter, which is of type AsyncTask::DoneStatus, whereas you should be passing a function pointer to the actual task function.

So for a few days i was trying few things and got to this error:

My base class is declared this way:

class InitWindow
{
	public:
		...

		AsyncTask:: DoneStatus StepInterv( GenericAsyncTask*, void* );

		PandaFramework getFrame();
		WindowFramework* getWindow();
		...


	protected:
		PandaFramework framework;
		WindowFramework* window;
	   ...

};

the class that takes the task as argument is:

class InitTask: public InitWindow
{
	public:
		void make_task( GenericAsyncTask::TaskFunc, PT(AsyncTaskManager) );		
      GenericAsyncTask* getTask();
		void* getData();

	private:
		PT(GenericAsyncTask) task;

};

void InitTask::make_task( GenericAsyncTask::TaskFunc task2, PT(AsyncTaskManager) taskMgr )
{
	task = new GenericAsyncTask( "Task", &task2, (void*) NULL );
	taskMgr->add(task);
}

In the main i create an object of type InitTask:

InitTask movement;
	movement.make_task( &InitWindow::StepInterv, act.getTaskMgr() );

I made a pointer to the member function but i am missing something again. When i place the StepInterv function out of the class as a global function and pass it just as StepInterv in movement.make_task it works perfect, but the moment i place it in the class as a member function it just starts nagging me about not being able to convert it. What am i missing here ? I have the feeling this is not the right pointer to pass but that’s my opinion.

If i try to declare it GenericAsyncTask::TaskFunc InitWindow::* task2 it get’s this error:

What am i doing wrong?(again)

It should be declared as a static method. If you need to pass a “this” pointer, you can cast it to “void*” and pass it as the additional parameter.

Okay it worked, thank you. There’s one more thing that is bugging me, you mention passing a pointer to void*. Before in one other of my posts you mention that i have to make a struct in which i am to store what i want to pass in the function and pass a pointer to that struct to the extra void* data argument. Okay that i do understand but i still can’t understand pointer to which task am i supposed to pass for the GenericAsyncTask* task argument?

You could pass a pointer to anything to the void* argument; you could pass a pointer to a struct in which you store custom data, or use it to store the “this” pointer of the relevant class it’s in, or a string containing the name of your favourite ice cream.

As for the GenericAsyncTask pointer; well, since it’s Panda that calls this function and not you, you don’t need to worry about it. It’s a pointer to the task object that you created when you did “new GenericAsyncTask”.

So in other words i do not pass pointer made by me for GenericAsyncTask argument, Panda does that for me. But that confuses me because to pass a pointer for the void* argument i have to pass something for the first argument which is GenericAsuncTask.

AsyncTask::DoneStatus InitWindow::TravCol( GenericAsyncTask* task, void* data )

If i don’t I get an error that the function doesn’t take only 1 parameter or something simmilar. Is there a way to go around it?

You don’t call TravCol. You call “new GenericAsyncTask”, passing your void* parameter, and then Panda stores that void* parameter and when it calls your TravCol every frame, it passes that same void* parameters as the second argument.

Okay i understand where i call the pointer. But here’s my dillema… I have this class:

class InitWindow
{
	public:
		...

		static AsyncTask:: DoneStatus StepInterv( GenericAsyncTask*, void* );
		static AsyncTask:: DoneStatus TravCol( GenericAsyncTask*, void* );

		PandaFramework getFrame();
		WindowFramework* getWindow();
		...


	protected:
		PandaFramework framework;
		WindowFramework* window;
	   PT(AsyncTaskManager) taskMgr;
      PT(CMetaInterval) pandaPace;
      CollisionHandlerQueue* queue;
      CollisionTraverser traverser;
};

Every variable from the protected i call with a get function and pass it as argument to other functions made by me so they could use these variables. Here’s the declaration of the TravCol function:

AsyncTask::DoneStatus InitWindow::TravCol( GenericAsyncTask* task, void* data )
{
	traverser.traverse( window->get_render() );
	if( queue->get_num_entries() == 1 )
	{
		pandaPace->pause();
	}
	return AsyncTask::DS_cont;
}

What happens here is that i get error for the traverser, window, queue etc. that they’re are not part of class, union or struct(Error code C2228). First thing i got in mind was to add few more arguments to the function so i can pass the get function for those variables, but because i have to adhere to the Panda function structure i can’t do that. So the last thing i thought about doing is as you suggeste to make a structure with the variables inside and pass a void pointer to that structure so i can call them inside, but here i hit a wall again - with the void pointer i can’t call anything as it doesn’t know where it points. And i’m stuck here…

You cast the void* pointer back into a “this”-like pointer, like this:

AsyncTask::DoneStatus InitWindow::TravCol( GenericAsyncTask* task, void* data )
{
   InitWindow *inst = (InitWindow*) data;
   inst->traverser.traverse( window->get_render() );

Make sure to pass the pointer to InitWindow to the GenericAsyncTask constructor (cast to void*).

Hmm i get an error i haven’t seen. Okay here how my function looks like(as you told me i put those two lines inside):

AsyncTask::DoneStatus InitWindow::TravCol( GenericAsyncTask* task, void* data )
{
	InitWindow *inst = (InitWindow*) data;
	inst->traverser.traverse( inst->window->get_render() );
	if( inst->queue->get_num_entries() == 1 )
	{
		inst->pandaPace->pause();
	}
	return AsyncTask::DS_cont;
}

For the void* pointer i pass this pointer:

int main(int argc, char *argv[])
{
	InitWindow var;
	void* ptr = &var;

   ...
   InitTask movement;
	movement.make_task( &InitWindow::TravCol, act.getTaskMgr(), ptr );
   ...

}

I tryied to pass a pointer to the struct i made but i get a simmilar error.
And the error i get when debugging:

EDIT:
It is an access violation. I’ll look around and see if i can fix it.

CollisionTraverser is reference counted. So you have to store it in a PT() pointer, like this:

PT(CollisionTraverser) _traverser;
_traverser = new CollisionTraverser;
_traverser->something

I tryied some things and i found that the problem comes from this line:

inst->traverser.traverse( inst->window->get_render() );

and more accurately from inst->traverser.

After that i saw your reply but when i declare PT(CollisiongTransfer) anywhere in my code
i get this error:

For reference, taken from pointerToBase.I:

////////////////////////////////////////////////////////////////////
//     Function: PointerToBase::reassign
//       Access: Protected
//  Description: This is the main work of the PointerTo family.  When
//               the pointer is reassigned, decrement the old
//               reference count and increment the new one.
////////////////////////////////////////////////////////////////////
template<class T>
INLINE void PointerToBase<T>::
reassign(To *ptr) {
  if (ptr != (To *)_void_ptr) {
    // First save the old pointer; we won't delete it until we have
    // assigned the new one.  We do this just in case there are
    // cascading effects from deleting this pointer that might
    // inadvertently delete the new one.  (Don't laugh--it's
    // happened!)
    To *old_ptr = (To *)_void_ptr;

    _void_ptr = (void *)ptr;
    if (ptr != (To *)NULL) {
      ptr->ref();                         // The compiler says that the error comes from this line
#ifdef DO_MEMORY_USAGE
      if (MemoryUsage::get_track_memory_usage()) {
        update_type(ptr);
      }
#endif
    }

    // Now delete the old pointer.
    if (old_ptr != (To *)NULL) {
      unref_delete(old_ptr);
    }
  }
}

Sorry, I had it so wrong. It’s not reference counted after all. Never mind my previous suggestion.

Could the problem be that you’re (somehow) not getting a valid InitWindow* pointer to the GenericAsyncTask constructor? Try printing out the value of “&var” in your main and the value of “inst” in TaskCol to make sure th they match.

CollisionTraverser is not reference counted, but CollisionHandlerQueue is. So you need PT(CollisionHandlerQueue) instead of CollisionHandlerQueue *.

David

Inst and &var have the same adress. But it seems that traverse doesn’t hold any information. When i check in this function:

void InitQueue:: init_queue( PT(CollisionHandlerQueue) queue, NodePath colNp, WindowFramework* window, CollisionTraverser traverser )
{
	queue = new CollisionHandlerQueue();
	if( queue != NULL )
	{
		traverser.add_collider( colNp, queue );
	}
}

the traverser gets it’s queue and handler, but the moment the function exits the values are lost.
After that when entering function:

AsyncTask::DoneStatus InitWindow::TravCol( GenericAsyncTask* task, void* data )
{
   InitWindow *inst = (InitWindow*) data;
   inst->traverser.traverse( inst->window->get_render() );
   PT(CollisionHandlerQueue) _queue;
   _queue = new CollisionHandlerQueue;
	if( _queue->get_num_entries() == 1 )
	{
		inst->pandaPace->pause();
	}
	return AsyncTask::DS_cont;
}

for this line: inst->traverser.traverse( inst->window->get_render() );
i get:

I presume that this error indicates that traverser doesn’t hold any infromation but that’s just my guess.

If i place ampersand infront of the argument traverser for function init_queue, i get violation access for the same line.( inst->traverser.traverse( inst->window->get_render() ); )

Why are you creating a new queue in TravCol? You need to create your queue in the init, and then hold it in a PT(CollisionHandlerQueue) on your class instance.

My bad, fixed it. About the problem, is it possible for the error to come from the inst->window->get_redner() line ?

I fixed the pointers that gave me the access errors. But i got stuck elsewhere. In the function init_queue i am working with the pointer queue, but after the function exits the information is lost.
Here is the function:

void InitQueue:: init_queue( PT(CollisionHandlerQueue) queue, NodePath colNp, WindowFramework* window, CollisionTraverser &traverser )
{
	queue = new CollisionHandlerQueue();
	if( queue != NULL )
	{
		traverser.add_collider( colNp, queue );
	}
	traverser.show_collisions( window->get_render() );

}

In main:

int main(int argc, char *argv[])
{
	InitWindow winframe;

        ...

	InitQueue sequence;
	sequence.init_queue( winframe.getQueue(), col.init_collision_fobj( act.getActor() ), winframe.getWindow(), winframe.getTraverser() );
	cerr << " \n MAIN \n";
	cerr << winframe.getQueue();
	cerr << " \n ---- \n ";

        ...
}

The “cerr << winframe.getQueue();” line returns only zeros. I may be wrong but i think that PT deletes the adress stored in queue after function return. If it is true i have to store the information queue holds somewhere but i can’t understand where. What i want to ask is a tip on what i am doing wrong, the rest i’ll do on my own.

Are you sure you’re holding it in a PT and not a regular pointer? In your original code you had this in your struct:

CollisionHandlerQueue* queue;

Whereas it should be:

PT(CollisionHandlerQueue) queue;