function onViewRemoved() { mouse_observer_.releaseCallbacks(); // necessary if I've set OnMouseEntered, but not if I've only set OnMouseExited mouse_observer_ = null // Mouse Observer MUST be destroyed at this point }

function onMouseEntered() { print ("Mouse Entered\n"); }

function onMouseExitedControl() { print ("Mouse Exited\n"); }

mouse_observer_ = null;

}

Now this issue came up because I need the mouse observer destroyed at a known time (so it deregisters itself), now here is what I don't understand

Whether I use the callback assignment style marked #1 or #2 makes no apparent difference to the callback functionality, but it does make a difference to the life of the mouse_observer_ object.

If I use #2 form, then things are as I expect, I can comment out the releaseCallbacks call in onViewRemoved and when mouse_observer_ is set to null, the object is detroyed, its destructor is called, it unregisters itself, and all is hunky dory.

But if I use the #1 style call to set a callback, then setting mouse_observer_ to null DOES NOT destroy the object. UNLESS I first call releaseCallbacks.

Well I've been looking into things a bit more, and although I haven't yet found why passing the callback as a function affects the lifetime of the MouseObserver object, I've also found something else that is unintutitive, at least to me.

If I pass the callback as a function,

be it

Code:

mouse_observer_.setOnMouseEntered(onMouseEntered)

or

Code:

mouse_observer_.setOnMouseEntered(this.onMouseEntered)

the callback that is stored is teh the member of the class, not the object. So if you call it, none of the instance values will be available.

It seems I have to pass the "this" object seperately and create an Sqrat Function in C++.

Well I've been looking into things a bit more, and although I haven't yet found why passing the callback as a function affects the lifetime of the MouseObserver object, I've also found something else that is unintutitive, at least to me.

If I pass the callback as a function,

be it

Code:

mouse_observer_.setOnMouseEntered(onMouseEntered)

or

Code:

mouse_observer_.setOnMouseEntered(this.onMouseEntered)

the callback that is stored is teh the member of the class, not the object. So if you call it, none of the instance values will be available.

It seems I have to pass the "this" object seperately and create an Sqrat Function in C++.

I haven't yet found a neater way to do this.

Anybody got any input?

Well, I don't know SQRat, so I can't help much with the lifetime issue. I can only GUESS that there is a reference somewhere inside SQRat you're missing (see sq_addref and sq_release) or even inside the VM somewhere for whatever reason.

The issue about the this-object, though, is pretty normal. You always have to pass an environment/this-object when doing a call - for EACH AND EVERY call, to be exact. Usually in most examples, this is done by sq_pushroottable. But you can push ANY object as "this" for a call. If you pass around closures (function objects), however, you pass the plain closure itself without any this-object (which one is to use then? The one of the caller who passes it, the one of the class instance who takes it? It's choice of the programmer of course. Note again the "this" object is a matter of doing the call rather than passing a closure).

However, you can set a delegate on a closure using pure squirrel code, which probably is what you need.

The issue about the this-object, though, is pretty normal. You always have to pass an environment/this-object when doing a call - for EACH AND EVERY call, to be exact. Usually in most examples, this is done by sq_pushroottable. But you can push ANY object as "this" for a call. If you pass around closures (function objects), however, you pass the plain closure itself without any this-object (which one is to use then? The one of the caller who passes it, the one of the class instance who takes it? It's choice of the programmer of course. Note again the "this" object is a matter of doing the call rather than passing a closure).

I understand that the environment has to be passed, and one is, but it appears to be the class that is passed, not the actual object that the call is being made from. To me that seems a little illogical.

Quote:

However, you can set a delegate on a closure using pure squirrel code, which probably is what you need.

sorry, my bad. I remembered using delegates to solve such problem, but you actually can't set delegates on closures. Unfortunately right now I don't have the time to dig into this.However, you are in control of the call, so it shouldn't be much of an issue.

Quote:

I understand that the environment has to be passed, and one is, but it appears to be the class that is passed, not the actual object that the call is being made from. To me that seems a little illogical.

Not really, it's the same as in C++. Any class function should have the class instance as "this" pointer (in fact, it MUST have it to be able to access its own members at all).

In contrast, when you call a function outside of a class, it's actually in a table, so the this pointer is expected to be that table (though there are some limitations to that).

if you want to know about the caller in a method or function, you simply should pass it's object as parameter, for example

local a=CallAFunction(this) ; //when calling from inside a class instance

or

local a=CallAfunction(callee()) ; //when calling outside a class instance. Callee is the CURRENTLY running closure object.

In case of C++ doing a call, it's job of the C++ code to pass a proper "this". It looks like SQRat correctly passes a class isntance "this" pointer here. Okay, this is "negotiable" when it comes to callbacks :P

You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.