Jump to content

Member function Callback


photo

Recommended Posts

Functions such as:

engine.controls.setKeyPressCallback("WindowsControls::keyPressed");

 

The given callback function seems to need to be a global function.

Is there any way we can use a member function, since I would like my WindowsControls to be an object.

Link to comment

Functions such as:

engine.controls.setKeyPressCallback("WindowsControls::keyPressed");

 

The given callback function seems to need to be a global function.

Is there any way we can use a member function, since I would like my WindowsControls to be an object.

 

Kind of... It's a bit ugly but it looks like this.

 

 
class Foo {
 Foo() {
   setCallback("Foo::button_clicked_",this);
 }
 void button_clicked_(Foo foo) { foo.button_clicked();}
 void button_clicked() {
   // do actual code here
 }
};

the underscore at the end of the called function is just a convention I use. magic is in passing the object itself.

Link to comment
  • 2 weeks later...

Hey,

 

I finally got around to giving this a try. However:

setKeyPressedCallback() takes only 1 argument.

 

Your method works for setContactCallback for example, but doesn't seem to work for setKeyPressedCallback/setKeyRelease etc.

Link to comment

Hi Manguste,

 

Thanks you for the suggestion. I had already been using that approach.

 

class WindowsControls : Controls{

WindowsControls(ActionInterface actionInterface);
~WindowsControls();

void update();

void keyReleased(int key);
void keyPressed(int key);
void buttonPressed(int button);

};
namespace Windows{
   WindowsControls controls;
}

 

I also enclosed the global variable into a namespace. However, I'm not a big fan of this, as this approach effectively makes the class to be a singleton.

 

I think Unigine should implement something like this:


#ifndef CALLBACK_H_
#define CALLBACK_H_

class Callback{
string function;

int argc;
int a;
int b;
int c;


Callback(string function, int argc = 0, int a = 0, int b = 0, int c = 0);

int callback();

int callback0();
int callback1();
int callback2();
int callback3();
};



void Callback::__Callback__(string function, int argc = 0, int a = 0, int b = 0, int c = 0){
this.function = function;
this.argc = argc;
this.a = a;
this.b = b;
this.c = c;
}

int Callback::callback(){
return call("callback" + string(argc));
}


int Callback::callback0(){
return call(function);
}
int Callback::callback1(){
return call(function, a);
}
int Callback::callback2(){
return call(function, a, :);
}
int Callback::callback3(){
return call(function, a, b, c);

}

class MemberCallback : Callback{
int object;

MemberCallback(int object, string function, int argc = 0, int a = 0, int b = 0, int c = 0);


int callback0();
int callback1();
int callback2();
int callback3();
};


void MemberCallback::__MemberCallback__(int object, string function, int argc = 0, int a = 0, int b = 0, int c = 0){
Callback::__Callback__(function, a, b, c);
this.object = object;
}


int MemberCallback::callback0(){
if(object != NULL){
return object.call(function);
}else{
return call(function);
}
}
int MemberCallback::callback1(){
if(object != NULL){
return object.call(function, a);
}else{
return call(function, a);
}
}
int MemberCallback::callback2(){
if(object != NULL){
return object.call(function, a, B);
}else{
return call(function, a, B);
}
}
int MemberCallback::callback3(){
if(object != NULL){
return object.call(function, a, b, c);
}else{
return call(function, a, b, c);
}
}


#endif

 

I've only implemented up to 3 args, since I rarely write functions with more than 3 args.

Link to comment

Awesome.

 

Just so you know, the implementation posted was written moments before posting... so likely bugs abound :) Has not been tested.

 

A few corrections have been made since:


void MemberCallback::__MemberCallback__(int object, string function, int argc = 0, int a = 0, int b = 0, int c = 0){
__Callback__(function, argc, a, b, c);
this.object = object;
}

 

This second modification brings into question why a polymorphic call from an inherited method does not call the subclass' method? Or, is it because the call() does not consider polymorphism?

// forced to add this:

int MemberCallback::callback(){
   return call("callback" + string(argc));
}

 

To clarify, without the above identical overriding of the superclass' callback() if you have:


int Callback::callback0(){
     log.message("super"); // for debug purposes
     return 1;
}

int MemberCallback::callback0(){
	log.message("subclass"); // for debug purposes
	return 1;
}

Callback cb = new MemberCallback(obj, "function", 1);
cb.callback(); // this call calls superclass' inherited implementation
                     // but superclasses' implementation will now execute: 	call("callback0");
// Polymorphic call would call  MemberCallback::callback0 and print "subclass"
// Instead, we get a console print out of: "super"
// Which indicates that despite the class being a MemberCallback, the inherited implementation calls upon the super class' callback0

Link to comment
×
×
  • Create New...