[MUD-Dev] Re: processors

Adam Wiggins adam at angel.com
Mon Feb 1 10:52:58 New Zealand Daylight Time 1999

On Sun, 31 Jan 1999, J C Lawrence wrote:
> diablo <diablo at best.com> wrote:
> > A 3 second task would take 20 seconds, but this only happened with a
> > heavy player load. Our tasks are held in a table indexed to some
> > number (some sort of ticker in linux? I don't know the proper names
> > for anything). That table is polled every time the game searches for
> > player input (it cycles through all our player lines constantly),
> > and if a task is found to be either overdue or ready to go off, it
> > goes off. 
> Ouch.
> Cheaper:
>   1) Keep the table, but sort it by due time and pProcess the table
> only up to the first record that has a due date in the future.  You
> need to take care in your table and sort code to make it minimally
> expensive (choice of sorting algorithm), and in your storage format to
> ensure minimal traversal and ordering expense (no buffer copies, only
> pointer copies if possible).  

Standard event handlers.  I've written them at the start of so many projects
now I think I could do it blind, typing with my nose, and still finish
in less than 90 seconds.

In fact, here we go:

typedef float Tick;

class Event
	friend class EventManager;

	Event(Tick time)
		RipenTime = EventManager::GetCurrentTime() + time;

	virtual void Ripen() = 0;

	bool RipensBefore(Event *e)	{ return (RipenTime < e->RipenTime); }
	bool RipensBy(Tick time)	{ return (RipenTime <= time); }
	Tick RipenTime;			// time at which event ripens
	bool HasRipened;		// flag for deletion
	Event *Next;

class EventManager
	EventManager() { Events = NULL; GameTick = 0; }
	static void Update()
		bool update = false;

		// Execute each event that is due to ripen
		Event *e;
		for (e = Events; e; e = e->Next)
			if (e->RipensBy(GameTick))
				e->HasRipened = true;
				update = true;

		// Second pass, delete all ripened events
		if (update)
			Event *next, *prev = NULL;
			for (e = Events; e; e = Next)
				next = e->Next;

				if (!e->HasRipened)
					prev = e;
					if (prev)
						prev->Next = e->Next;
						events = e->Next;

					delete e;

		// Increment the game timer
		GameTick += TimeManager::GetTicksEllapsedLastUpdate();

	static void AddEvent(Event *newEvent);
		// Descend the list until a later event is found
		Event *e, *prev = NULL;
		for (e = events; e && e->RipensBefore(newEvent); e = e->Next)
			prev = e;

		// Insert the new event before that event
		newEvent->HasRipened = false;
		newEvent->Next = e;
		if (prev)
			prev->Next = newEvent;
			Events = newEvent;
	static Tick GetCurrentTime()		{ return GameTick; }

	static Event *Events;
	static Tick GameTick;

This could, of course, easily be converted to C (I'd be happy to do so
if anyone desires, it'd take probably another 90 seconds).
Those into design patterns would probably also do the event manager as
a singleton (or perhaps have multiple event managers for different types
of events) rather than using all statics, but I wanted to keep the example

Adam W.

More information about the MUD-Dev mailing list