When you hook a vessel's methods, does the vessel still receive the callbacks itself? Or would they have to be manually called inside the function that the hooking library "reroutes" the callback to?
Well, I can only speak of my classes here, but in this case the original callbacks are called. Of course it is exactly as you've outlined in your last sentence. My functions call the original "manually", but aided by the system's original function table. I can't say much about Wraith's solution ATM.
Also, I understand that unless a common hooking library/method is used between two addons, there will be compatibility issues? Is it stable provided there are no such clashes?
It is true that two hooking libraries would collide one way or the other. My classes are as stable as such a hack can be: not really
.
Is there any simple documentation for your hooking classes?
I downloaded OMP and have been looking through the source code for how to use your classes, but I have not gotten far.
<snip>
I can understand that that gets a pointer to a vessel, installs a hook on it, and sets the vessels "events" to a Queue class in OrbiterHooking. Unfortunately, I don't see how HookingMethods relates to the hook at all. Is there any simpler examples that use your hooking classes?
Sorry, it is certainly no full package, so there is no documentation for it. Here is a small help:
int InstallVesselHook(VESSEL2 *link) ... installs the hooks of HookMethods for the appropriate vessel instance.
int RemoveVesselHook(VESSEL2 *link) ... releases the hooks for that instance again.
void CleanUpHooking() ... removes all open hookings.
Queue *GetEventQueue() ... gives you the event queue that holds all hook events. Using Dequeue() gives you the next event.
void SetEventsEnabled(bool enabled) ... switches the event recording globally on and off. Default is off, so you have to switch it on before you see any events in the queue.
bool GetEventsEnabled() ... gets the status of event recording.
The code additionally creates an event logfile in Modules/Plugin/Events.log .
As you can see, my classes used in OMP are using the HookMethods to build up a event queue that I can asynchronously transmit without blocking the callback itself. So they are specialized for this use-case, but you can of course modify the HookMethods to do whatever you want. The macros there show how the hook method's structure is layed out for callbacks with and without results. The non-trivial part is the assembler one that just calls the original method. Be aware that within the HookMethods, the "this->" pointer gives you the original class instance, not the one of the HookMethods instance.
If you need a specific function called for certain callbacks, I can assemble a small example for you. But I guess it is better to get Wraith's work running, as it seems to be more "designed" than mine.
regards,
Face
---------- Post added at 21:41 ---------- Previous post was at 20:34 ----------
OK, I've gone through Wraith's code a bit, and I must admit that I forgot most of the details, despite my involvement in VHL discussions. The VHL hooking method involves replacing of the complete virtual table pointer back and forth to call the original functions without help of assembler hacks. I could be mistaken, but I think this is the reason for it to crash in this version of Orbiter. There is the new VESSEL3 interface now, and it derives from VESSEL2.
It could very well be that simply replacing the complete virtual table pointer triggers the access violation that meson wrote about. However, the constructor trick worked because of it being a complete new class instance, only having the virtual table for VESSEL2. Still, that later instance did not receive the callbacks, thus never saw the hooked functions.
Nevertheless, Wraith's code is elegant. I'll take a look if I can integrate my assembler method into his library framework. Let's see...