arul wrote:Yes, that might help - UOClient is aware of those objects at the time those events are fired, so instantiating them over and over again is not necessary. Which also involves implementing some kind of entity cache at the UOClient (or it's wrappers) level. I think that might actually help a lot, since the CreateSomething functions are probably the most expensive elements in the call chain.
You're right there. I did not start with an entity cache at first, cause that required synchronization code (since multiple programs and threads would be using the same objects), that synchronization was added afterwards when I made the step from a single threaded to a free threaded com-model. Since I needed such an entity cache anyway to trigger events on a specific object (other than UOClient and UOAI, which already had such a cache), so the first thing I did when implementing more events was adding the cache for UOItems (a collection in the form of a synchronized AVL balanced binary tree, key'd by the ID of the item). I'll also add such a cache for UOMobiles and UOGumps, for most other things it should not matter. I think I will pass objects directly and trigger specific events on object different from a UOClient too anyway, cause the lookup in the entity cache does not seem to make the difference.
arul wrote:Yes, I agree that asynchronous events will help a lot, especially considering that synchronous event are almost of no practical use at all.
I ran a few tests already and it seems to improof a lot. Packets are now queued in a sync'd queue, there's always 1 async handler thread running and new ones are spawned (at max every 1 second) if too many packets are in the queue when adding a new one (currently it's something like 10, but thats not an optimal value probably). Also an async handler thread will shut down itself if it has to wait over half a second before getting anything from the queue. (1 thread is always running).
This solves multiple problems : when the server sends a load of packets (f.e. if I log into an over-crowded britain bank area) the work gets distributed; and also it prevents lockdown when eventhandlers in a user's app take too long to handle the event or don't return at all.
arul wrote:I'm still thinking of a packet logging app, sou I'll be actually collecting all packets

I mentioned function pointers because that's probably the fastest way how to deliver packets from UOAI to the user app - the queue or such similar structure can be implemented at the user app level.
With the improvements i'm currently working on, I think the onReceive and onSend events as already present will just stay as they are and work quite well.
It will still take some time though, i found a serious bug in the current version, where packet-handlers didnt get unadvised correctly (removal of packet-handlers) cause i was passing information in an incorrect form to the automation libraries (they actually crashed on an access violation, but somehow no error was generated in the compiled version)... it took me quite some time to figure this one out, so still a lot of work left on the eventhandling.
Greetz,
Artaxerxes