Event system discussion

Discuss API design here.
your-name-here
Developer
Posts: 168
Joined: Sat Jul 07, 2012 1:58 am

Event system discussion

Postby your-name-here » Mon Jul 09, 2012 11:20 pm

This thread will serve as a discussion on the event system.

I think we need to sit down and brainstorm out what the python coders need called from the C++ plugin.

Questions to answer are:
1) Should be have functionality similar to es.registerForEvent?
2) Should the core plugin also call a handleEvent function in the sp.py whenever an event is called?

There was a thread that Ayuto posted about simplifying IGameEvent access. There are a few things to consider with that proposal.
To implement what was suggested, we'd have to read the event descriptor and parse out variables every time an event is fired. We need to
do this because python has no way of knowing what variables exist within an event. Nor does it have a way of knowing what type those variables
are. We're going to sacrifice performance (especially on noisy events like weapon_fire) for usability. Is this a cost that is worth it?

We should hammer out the specs for the event system before we delve into writing tons of code :)
User avatar
satoon101
Project Leader
Posts: 2697
Joined: Sat Jul 07, 2012 1:59 am

Postby satoon101 » Tue Jul 10, 2012 12:18 am

As far as having es.addons.registerForEvent functionality, I would say almost definitely. If we went with a system like the decorators system, where the scripter would have to declare a function/method as an event explicitly, and it was built into the C++ side, then I would say no. Otherwise, I would have to say yes.

Having thought a little more about the decorator system, it is starting to grow on me. Using that system would eliminate the need completely of the plugin itself automatically searching through a script to register functions with names of events for the event.



While I would love if an Event Variable would return the proper type, I am not sure we can do this properly. As ynh mentioned, we would have to "know" what type is expected, especially since an "stringed" integer "could" be what is "supposed" to be returned, and not an integer.

Satoon
Absolute
Junior Member
Posts: 13
Joined: Sat Jul 07, 2012 6:48 pm

Postby Absolute » Tue Jul 10, 2012 12:19 am

I think you should have to register functions for events on plugin load, that way you could even change the hook type (like SM does it).

Btw: the .res files contain how many variables the event will have and their types, why not parse that one once? (if you really want to have it the native way)
User avatar
satoon101
Project Leader
Posts: 2697
Joined: Sat Jul 07, 2012 1:59 am

Postby satoon101 » Tue Jul 10, 2012 1:51 am

http://forums.eventscripts.com/viewtopic.php?p=317004#p317004

Look at SuperDave's reply in that thread.

Satoon
User avatar
DanielB
Junior Member
Posts: 4
Joined: Sat Jul 07, 2012 2:33 am
Location: Australia
Contact:

Postby DanielB » Tue Jul 10, 2012 10:06 am

satoon101 wrote:As far as having es.addons.registerForEvent functionality, I would say almost definitely. If we went with a system like the decorators system, where the scripter would have to declare a function/method as an event explicitly, and it was built into the C++ side, then I would say no. Otherwise, I would have to say yes.


I think it would be useful for certain libraries too - ES2's popuplib for example needs to listen for es_client_command. Obviously this is an ES specific example.

satoon101 wrote:Look at SuperDave's reply in that thread.


That is problematic - especially in custom defined events where we only know what the res file contains (and the script author may or may nor abide to that).
We could perhaps have this functionality explicitly invoked in the decorator which will give a parameter to the event that will type and memorize (and throw exception if needed) the value on request.

It would be nice to have values in their proper types - other things aside how many times have you seen a comparison between a string and integer userid?

It's something that would be nice, but if we can't be sure of the type it's usefulness drops a bit. (That said, it still would be useful in a large number of situations)
Omega_K2
Senior Member
Posts: 227
Joined: Sat Jul 07, 2012 3:05 am
Location: Europe
Contact:

Postby Omega_K2 » Tue Jul 10, 2012 6:54 pm

1) I think having a function to register events manually is an absolute must have. There are situations where you have to register events manually; for example on the fly due to config changes (or because you stored the events to register in a DB). In addition you need it libaries.
Same goes for unregistering obiviously.

2) Well, yes, that would be needed if we implement the calling for custom-registered events in python. Might aswell be done in c++ and made be available in py (for speed?)

I think going both ways would be a good idea. Because you can still have that speed when you need it, and if you don't, you can just rely on the conversion mechanisims. As for decorators or registering events this is easy to implement; it would just be a keyword argument that defaults to one of these options. So basically, default behaviour could be to convert vars to their type, and if you don't want it, you just disable it upon registering the event either though a function or a decorator.
User avatar
satoon101
Project Leader
Posts: 2697
Joined: Sat Jul 07, 2012 1:59 am

Postby satoon101 » Tue Jul 10, 2012 7:12 pm

Well, if we went with the decorators system, libraries (though we are going to use modules instead of libraries for this plugin) will easily be able to use that same functionality to register for an event. Currently, within ES2.1, only 3 events are registered in 2 total libraries. Only 1 of those (player_disconnect) is a non-ES event.

Config changes could work the same way, especially if an addon was designed properly, and unloaded certain modules when configurations were changed.

I still think calling GetString, GetInt, etc is more explicit and is much better than the plugin "guessing" what type of value the addon wishes to be returned. I don't believe reading a .res file is the proper answer to that issue either.

Satoon
your-name-here
Developer
Posts: 168
Joined: Sat Jul 07, 2012 1:58 am

Postby your-name-here » Tue Jul 10, 2012 8:57 pm

satoon101 wrote:Well, if we went with the decorators system, libraries (though we are going to use modules instead of libraries for this plugin) will easily be able to use that same functionality to register for an event. Currently, within ES2.1, only 3 events are registered in 2 total libraries. Only 1 of those (player_disconnect) is a non-ES event.

Config changes could work the same way, especially if an addon was designed properly, and unloaded certain modules when configurations were changed.

I still think calling GetString, GetInt, etc is more explicit and is much better than the plugin "guessing" what type of value the addon wishes to be returned. I don't believe reading a .res file is the proper answer to that issue either.

Satoon


Honestly, the more I think about this, the more I agree. Essentially we'd have to make major changes to the event system in order to hide types. We'd have to parse through the .res file in order to put all the event variables in one data struct. I am starting to lean against this. You can still call getInt and getFloat and such on string types. The engine will do the proper conversion at runtime (as far as I know at least).

From a 30,000ft view, it looks like I need to expose a registerForEvent function that would allow python-eventname bindings. Then, when someone does es_load, I call a function in our core sp.py library. This library will import the addon via the import keyword (since the addons directory is already in the search path). The core library will then parse for decorators and call registerForEvent as it needs to.
User avatar
Ayuto
Project Leader
Posts: 2193
Joined: Sat Jul 07, 2012 8:17 am
Location: Germany

Postby Ayuto » Tue Jul 10, 2012 9:07 pm

What's about a simple try-except clause for getting a variable and an isinstance check for setting one? I guess that wouldn't cost much ressources. Also, I agree that a registerForEvent function could be usefull :)
your-name-here
Developer
Posts: 168
Joined: Sat Jul 07, 2012 1:58 am

Postby your-name-here » Tue Jul 10, 2012 9:18 pm

Ayuto wrote:What's about a simple try-except clause for getting a variable and an isinstance check for setting one? I guess that wouldn't cost much ressources. Also, I agree that a registerForEvent function could be usefull :)


Again, that would require me to write tons of code to parse through the .res file. You cannot know the type of the event variable unless you manually look at the .res file. Neither C++ nor Python can get at the types without parsing the event file. There are 5 event files. Keep in mind that I have no way of knowing which event belongs to what file. So that means I have to parse through 5 files in the worst case.

Not worth it honestly Ayuto. I think you'll be fine with .GetInt and .GetString. It forces scripters to be mindful of the types of vars they are dealing with.
User avatar
satoon101
Project Leader
Posts: 2697
Joined: Sat Jul 07, 2012 1:59 am

Postby satoon101 » Tue Jul 10, 2012 11:59 pm

Ayuto wrote:What's about a simple try-except clause for getting a variable and an isinstance check for setting one? I guess that wouldn't cost much ressources. Also, I agree that a registerForEvent function could be usefull :)
And again, what if the try/except works but the variable is "supposed" to be a string (like the Event Variable "text" for player_say) but casting it to an integer or float works?

Also, setting an Event Variable "should" only be used when creating a new event. If 2 scripts are loaded that both use the same event, it would depend on the load order whether the changed value of an Event Variable would affect the other script. And, changing the Event Variable's value does not actually change anything except for the value of that particular variable.

Satoon
User avatar
Ayuto
Project Leader
Posts: 2193
Joined: Sat Jul 07, 2012 8:17 am
Location: Germany

Postby Ayuto » Wed Jul 11, 2012 6:30 am

satoon101 wrote:And again, what if the try/except works but the variable is "supposed" to be a string (like the Event Variable "text" for player_say) but casting it to an integer or float works?
Yeah, I haven't thought about this situation.

satoon101 wrote:And, changing the Event Variable's value does not actually change anything except for the value of that particular variable.
Alright, and in some cases the value is used by any functions e.g. reason in player_disconnect for printing a meassage.
your-name-here
Developer
Posts: 168
Joined: Sat Jul 07, 2012 1:58 am

Postby your-name-here » Sat Jul 14, 2012 1:54 am

Ayuto wrote:Yeah, I haven't thought about this situation.

Alright, and in some cases the value is used by any functions e.g. reason in player_disconnect for printing a meassage.


Yes because sometimes the event is fired before the actual thing it signifies occurs :)
player_disconnect being one such case.
User avatar
satoon101
Project Leader
Posts: 2697
Joined: Sat Jul 07, 2012 1:59 am

Postby satoon101 » Sat Jul 14, 2012 5:36 pm

Ayuto wrote:Alright, and in some cases the value is used by any functions e.g. reason in player_disconnect for printing a meassage.
Not sure if you have tested this fully or not, but it doesn't seem true by my testing. If I change the 'reason' in the script, it still shows the original disconnect message when the player disconnects.

Satoon
User avatar
Ayuto
Project Leader
Posts: 2193
Joined: Sat Jul 07, 2012 8:17 am
Location: Germany

Postby Ayuto » Sun Jul 15, 2012 2:33 pm

I can just tell you that it worked for me, but I will test it again, when I will find some time. ;)
User avatar
satoon101
Project Leader
Posts: 2697
Joined: Sat Jul 07, 2012 1:59 am

Postby satoon101 » Sun Jul 15, 2012 3:31 pm

I did not have a second client when I tested, so that is why I did not think it worked. Now that my backup account received the Beta, I can test locally with 2 clients.

It still shows up in the server's console with the correct reason, but shows other clients the new one. However, this behavior is very rare. The vast majority of the time this sort of thing will not work.

Satoon
User avatar
BackRaw
Senior Member
Posts: 537
Joined: Sun Jul 15, 2012 1:46 am
Location: Germany
Contact:

Postby BackRaw » Sun Jul 15, 2012 10:57 pm

your-name-here wrote:Not worth it honestly Ayuto. I think you'll be fine with .GetInt and .GetString. It forces scripters to be mindful of the types of vars they are dealing with.
Which is good!
Chrisber
Junior Member
Posts: 21
Joined: Thu Jul 19, 2012 10:25 pm

Postby Chrisber » Fri Jul 20, 2012 7:08 am

BackRaw wrote:Which is good!

...and bad at the same time. This design speaks against the - more or less - strict typing of python. It is against its nature and that makes me think about to solve this.

@ynh: I know it's a lot of work, but where's the problem to parse the resource files? I've did the same in NativeTools and it worked like a charm. With parsing them and putting information about events using a std::multimap, I do not see any problems to resolve fast lookup. (Any how, C++ speed can be neglected, since Python itself is very slow compared to.)
User avatar
BackRaw
Senior Member
Posts: 537
Joined: Sun Jul 15, 2012 1:46 am
Location: Germany
Contact:

Postby BackRaw » Fri Jul 20, 2012 4:47 pm

Chrisber wrote:...and bad at the same time. This design speaks against the - more or less - strict typing of python. It is against its nature and that makes me think about to solve this.


Well, I meant that it's better than having a dict with pre-defined (string) variables...
your-name-here
Developer
Posts: 168
Joined: Sat Jul 07, 2012 1:58 am

Postby your-name-here » Fri Jul 20, 2012 5:39 pm

Chrisber wrote:...and bad at the same time. This design speaks against the - more or less - strict typing of python. It is against its nature and that makes me think about to solve this.

@ynh: I know it's a lot of work, but where's the problem to parse the resource files? I've did the same in NativeTools and it worked like a charm. With parsing them and putting information about events using a std::multimap, I do not see any problems to resolve fast lookup. (Any how, C++ speed can be neglected, since Python itself is very slow compared to.)


Again, I don't see the reason to do any of that. You're asking me to write tons of extra code to save people from typing out GetInt or GetFloat just because it doesn't agree with the philosophy of python. Remember what you're dealing with here: A Python wrapper around a C++ game engine. You're going to hit these issues everywhere (just take a look at user messages), not just events. I believe it is better to stick with GetInt/GetFloat and the like because tons of the engine structures use WriteInt/WriteFloat style functions. We'll remain consistent that way.

Return to “API Design”

Who is online

Users browsing this forum: No registered users and 16 guests