Process Management: Basic Implementation
Here's some psuedo-code for an abstract class Process which all other processes inherit from.
There - that's everything. It resembles C# to some extent, but I assure you that the code won't compile as it stands. I won't claim that it's bullet-proof or even the most ideal implementation, but it's been treating me pretty well. I included possible improvements within the comments.
Now to create a Process which actually does something, we inherit from this base Process and override the necessary methods. So here's an example of a Process I've written which simply waits until a certain amount of time has passed.
Simple, yea? You can make a bunch of little Processes just like that one which perform small pieces of functionality, and then those pieces can be combined to form bigger Processes that perform much larger tasks until, eventually, you can run the entire game through a series of well put-together Processes.
I've bombarded you with enough code for now. Next time I get on this topic, I'll talk about the top-level Process and how we actually put these Processes together. You'll be surprised at its elegance.
abstract class Process inherits GameEventSubscriber
{
//Keep a list of all this Process's children
private ListmChildren;
//Determines whether the Process is alive or not
private bool mIsAlive;
//Called automatically when the Process starts. This
//is where initialization for the Process should begin.
//This is in contrast to putting the initialization in
//the constructor, since we want to wait until the Process
//is actually running before starting up some of its
//functionality.
//All Processes should call the base Process's Start
//to provide some necessary functionality.
public virtual void Start()
{
mIsAlive = true;
post event (process started)
}
//Called automatically when the Process stops.
//This allows you to free up resources or perform
//certain functionality immediately when the Process
//stops running as opposed to waiting until the
//Process is destroyed.
//This method does not stop all of the children
//of this Process, which may be a possible
//improvement.
//All Process's should call the base's Stop to
//provide some necessary functionality.
public virtual void Stop()
{
mIsAlive = false;
post event (process stopped)
}
//Handles events sent to the Process.
public abstract void OnEvent(GameEvent e);
//Marks the Process as dead. This is how a Process
//signifies that it's finished with its functionality and can
//be stopped. However, it won't be stopped immediately.
//Would stopping it immediately be better?
//I'm not sure. ^_^
public void Kill()
{
mIsAlive = false;
}
//Returns whether the Process has been marked
//as dead or not.
public bool IsAlive()
{
return mIsAlive;
}
//Adds a child of this Process, automatically calling
//the child's Start method.
public void AddChild(Process child)
{
mChildren.Add(child);
child.Start();
}
//Removes all the children of this Process,
//stopping them appropriately. Any children
//of the removed children will also be stopped at this
//point.
public void RemoveAllChildren()
{
for each child in mChildren
child.RemoveAllChildren();
child.Stop();
mChildren.Remove(child);
}
//Removes all the dead children of this Process.
//This function will search through all children,
//grandchildren, etc, looking for dead Processes
//to remove. Thus, it is only necessary to call
//this method for the top-level Process for
//all the dead Processes to be removed properly.
//When a Process is removed in this manner,
//all of its children will be stopped appropriately.
//Ideally, this should be called at least once per
//frame to ensure that Processes do not linger
//around.
public void RemoveDeadChildren()
{
for each child in mChildren
if (not child.IsAlive())
child.RemoveAllChildren();
child.Stop();
mChildren.Remove(child);
else
child.RemoveDeadChildren();
}
}
There - that's everything. It resembles C# to some extent, but I assure you that the code won't compile as it stands. I won't claim that it's bullet-proof or even the most ideal implementation, but it's been treating me pretty well. I included possible improvements within the comments.
Now to create a Process which actually does something, we inherit from this base Process and override the necessary methods. So here's an example of a Process I've written which simply waits until a certain amount of time has passed.
class ProcessWait inherits from Process
{
private long mTime;
private long mTimeStart;
ProcessWait(long time)
{
mTime = time;
}
public override void Start()
{
base.Start();
//Get the time this Process started.
mTimeStart = GetTickCount();
//Tell the global GameEventService that this process
//will listen for game events of type GameEventFrame,
//which is an event that is fired each frame. Obviously,
//how you do this depends on your event-passing scheme.
GameEventService.Subscribe(this, GameEventFrame);
}
public override void Stop()
{
//Unregister this Process so that it no longer receives
//events while it is stopped.
GameEventService.Unsubscribe(this, GameEventFrame);
}
public override void OnEvent(GameEvent e)
{
//Each frame, do something
if (e is GameEventFrame)
{
//Check if mTime amount of time has passed since the
//Process started, and if so, the Process is finished. Thus,
//we go ahead and Kill it.
if (GetTickCount() - mTimeStart >= mTime)
{
Kill();
}
}
}
}
Simple, yea? You can make a bunch of little Processes just like that one which perform small pieces of functionality, and then those pieces can be combined to form bigger Processes that perform much larger tasks until, eventually, you can run the entire game through a series of well put-together Processes.
I've bombarded you with enough code for now. Next time I get on this topic, I'll talk about the top-level Process and how we actually put these Processes together. You'll be surprised at its elegance.

0 Comments:
Post a Comment
<< Home