Sigh.. Look. When you create and object, like a button, they have an *event* generator in them. In the case of a Button, this is usually "Click". So, when you create and object like that you usually do this:
mybutton = object_Handler.create("Button")
'Silly I know, but you have to put it on something. And this is an example only.
mybutton.parent = world.GetFrame
mybutton.name="Fred"
object_handler.connect("Fred_Click", "OnClick")
This is so that when you click the button it automatically calls "OnClick" in your program/script. Events are **not** objects. Objects are descreat chuncks of code that actually execute something. Events are simply data dumped into the system messaging archetecture using "FireEvent". Some place in "Botton" is a bit of code that says something like:
FireEvent(self.name + "_Click");
The event handler, I presume, keeps a table lookup that says, "The event Fred_Click should trigger a call to the address of "OnClick", which happens to be 'blah'."
I don't know where you get the idea that events are objects... But, point here is that the event handler architecture in most applications will start at the farthest "child" of the application, let it attempt to handle the event, then if that doesn't, it gets passed to the next highest level in the application. I.e. if a world window doesn't handle an event, then the main window is handed the event instead. MFC does things **way** differently. It handles "all events" in the main window code. this means every button, every scroll bar, every what ever, all gets passed "only" to the main window. No children ever see it, unless you use MFC's "message reflection" trick to explicitly redirect those messages to another object in the hierarchy, to give it a shot at dealing with the event first.
Now, most script engines don't have their own handler at all, or it relies on its "host" to do so. VBScript for example lets you return a reference to the script function, but requires that you pass that reference to a "connection point" handler in the hosting application. Fine if using IE, since IE also supplies the means to create the objects *and* it supplies the needed connection point system. You still can't use "createobject" to make something, then expect events to work with it, because IE doesn't have the reference data for the object to correctly inform its event generator who to "inform" about the event.
What is bloody confusing though is that connection points seem to imply that they directly call the code, since you are passing a reference to the specific address of the function to them. This may only be in the case of ActiveX though. Non-ActiveX may be forced to use the messaging system, which then means that inside an MFC application its not clear if LuaCOM or anything else will ever *see* the events, sicne they are children of an MFC application, which "shouldn't" pass any of that on to the script engine.
Its confusing as hell.
Now, the issue of using OnCallPlugin is simple. If events can't be handled in the *existing* system, then you need some way to capture and redirect them *external* to that system. What this means is creating all your GUI elements in an ActiveX EXE. This runs independently from Mushclient, but probably, for it to work right, also uses the Mushclient script bindings, like CallPlugin. Now, lets say this is a toolbar with 5 icons, which you click to cast spells, lets say "Light", "Heal", "Fireball", "Fear", "Heal: Fred". The last one heals a party member, so I can show why the code below "needs" to work the way it does. Each of these "could" simply be an event, which when clicked call the specific function needed. Without event management, you have to reinvent the wheel somehow to do this:
function OnCallPlugin (data)
if data contains "Light" then
call Cast_Light(right(data, len(data) - 10))
end if
if data contains "Heal" then
call Cast_Heal(right(data, len(data) - 10))
end if
...
end function
function Cast_Light(data)
send "cast light"
end function
function Cast_Heal(data)
if data <> "" then
send "cast heal " & data
else
send "cast heal"
end if
end function
In other words, the only way to handle a GUI system "not" created in scripting itself, or even "in" that scripting, without event management is to reinvent event management using OnCallPlugin as the "manager". And this just gets absurd when dealing with some pre-existing, closed source, 3rd party application. Lets say one that has 2-3 actually functions, none of which return the "state" of any part of the application, and two dozen *events* which are supposed to automatically inform the application that links to it of what those internal states are... Am I really the only person that thinks that having to code a new EXE for "every" such case, just to translate all the interfaces and events of that application to Mushclient function calls is a) rediculous and b) not something that probably more than 90% of the users of Mushclient are going to be able, never mind want, to do?
Its not about how many instances we "know about" right now where this is a problem or what work arounds exist for them. The issue is how many things are "no one" going to even bother trying to use with it, because the only way to do so is complicated, convoluted and completely redundant to what already existed to do the same thing.
Now.. I might be less frustrated if there was some "easy" way to make a generic EXE that was small, compact and worked by taking the lookup tables in an application/dll and building the correct internal lookups to make it work, including exposing all the same functions and data retrieval points. In other words you would tell "it" to connect the function name to the event and it would automatically translate the correct call to something the script could use... Its one idea I fiddled with, but it "still" requires, at the moment, using "OnCallPlugin" to handle the translated events. And it would be a pain in the ass to code in the first place.
There are many solutions. A lot of them are way more trouble and would waste even more time to get working right than just figuring out why events can't work in the present context and what needs to be done to fix it. The easiest, if we knew how, would be to fix it in the client. Everything else is bending the client, the component you are trying to host *and* the OS into a pretzel to accomidate the problem. And I don't mind doing that **if** its really necessary. I still don't think it actually is *yet*. |