www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How to understand context type of a delegate?

reply NX <nightmarex1337 hotmail.com> writes:
I was sketching some simple event-listener code and looked up 
std.signals module for some inspiration. Documentation says that 
it only works if the delegate used for slots are a 
class/interface member function. Digging into the code it seems 
like it's because _d_toObject(void*) function is used by passing 
"ptr" variable of the delegate to it. If there was a way to 
distinguish context types of delegates this would not be a 
problem.

Is there a way to know what kind of context a delegate has either 
in compile time or runtime?

Also is there any way to check whether a pointer legitimately 
points to an Object instance?
Sep 05 2018
next sibling parent Kagamin <spam here.lot> writes:
Maybe poke into GC and see if it has ClassInfo associated with 
the allocated block.
Sep 06 2018
prev sibling parent Jacob Shtokolov <jacob.100205 gmail.com> writes:
On Wednesday, 5 September 2018 at 16:53:42 UTC, NX wrote:
 Is there a way to know what kind of context a delegate has 
 either in compile time or runtime?

 Also is there any way to check whether a pointer legitimately 
 points to an Object instance?
No and no. I was fighting this problem in std.signals but found only one way to fix that without breaking backwards compatibility: we can use core.memory.GC class in order to check whether the object was allocated by GC (GC.addrOf). If it was, we need to retain the delegate context pointer to prevent accidental deallocation of this class by GC. And if the object is not managed by GC, it means that the delegate's context is a simple anonymous function, struct function, or manually allocated delegate's heap (there are few more cases though). In this case we just allow the user to manage this object manually. So if he decides to deallocate the entity behind the context pointer, he should be ready for a segmentation fault if he didn't remove an object from listeners before deallocation. The main reason why std.signals allows only objects to be used as a delegate context is that every object is tracked by D runtime (by the so-called Monitor object) and even in the case of manual deallocation (if you're using the std.experimental.allocator), you will be notified about object destruction if you were subscribed to this event. This makes the implementation extremely safe, but the author of the original library didn't finish his work properly. So std.signals now is a good candidate for replacement. I'm working on the fix and will create a pull request soon. Not sure if it will be accepted, but this module definitely needs to be replaced. If you want to join me in this work, I can share additional details about the situation around std.signals in general. If you don't want to spend your time on this, check this module: https://github.com/buggins/dlangui/blob/master/src/dlangui/core/signals.d - it's a part of the DlangUI project which already contains most of the things you may need.
Sep 08 2018