Wow, you never stop, do you. :) Let me try to organize this so I can reply to everything you added:
Quote:
With the event time problem, I agree that processing the network events probably won't take too long, but I was thinking if you actually handled player input, and they happened to type something that was CPU or disk intensive.
You're right. My current setup processes the input after reading in the input. I didn't fall into the trap of "process only if you had input this cycle", but still, it would be better to rearrange it slightly.
So I think the best thing would be to rearrange the main loop slightly, so that we:
- poll sockets (select)
- read/write (process sockets in my code)
- a new sub-loop:
- do one player's input (look for newlines, commands, etc.)
- check if it's time for an update, OR, process the event queue (more later)
- move to next player's input
That should address the accuracy problem. More on the event queue later...
Quote:
I'm taking a guess here that whoever did that made changes to code that was initially working properly without fully understanding what they were doing. I would surmise that this happened ... [...]
*nod* That was my general assessment too. Somebody did something without really understanding how it worked... the classic "hack and slash" technique to programming. Actually, I think that things like that happened all over SMAUG, which is why there are many oddities in many random places, sometimes irrelevant, sometimes very relevant (like this select business.)
Quote:
Actually, I don't think this is strictly true. The select tells you that you can write *something* however that something might be only one byte.
On the other hand, you may write 100 bytes, but be able to write another 100.
What I would do is: [...]
Ah, yes, I hadn't thought of using the E_WOULDBLOCK error to indicate "stop sending data until next select". I'll modify my network code to reflect that (not at home right now), and I'll let you know how it goes.
Quote:
RE: event queue
I like the event queue idea a lot. It seems that while it doesn't directly solve any outstanding and obvious problems, it DOES add immense features to the game... notably the ease of adding events (your example of spell expiration is an excellent usage of such a system.)
One problem is that the class you showed is precise to the second, instead of to the millisecond. That's not necessarily a big deal and is trivial to fix. However, perhaps millisecond precision is overkill, so maybe the best system would be to count it in frame ticks. (This is generally 250ms, I believe.)
I had another idea that would make these event queues more convenient to use for repetitive actions. An event would be flagged as "repeating every x ticks", or optionally "repeating every x ticks, y times". When it is popped, if it's repeating, it's put right back on the queue by the event handler, with the right amount of time reset, unless we've repeated y times already.
This also has all sorts of nifty applications. Imagine a chain-reaction spell that would damage once every 5 seconds. The spell could optionally be passed a parameter, how many times it's been repeated already, so that it handles its damage accordingly.
Anyways, the main application for this was for the update() functions, like mob_update, char_update(), violence_update(), etc., which are scheduled extremely regularly. Such a solution would allow them to be very easily re-scheduled.
If the queue is a queue of pointers, then this sort of thing is even easier, with derived classes for different kinds of events (repeating, repeating x times, or even repeating x times, where the duration in between each repeat increases the more it repeats!)
Actually, I'm all excited about this :) It sounds like a truly excellent idea, and I'm going to implement it as soon as possible. |