Skip to content

Commit

Permalink
libcommon: Experimenting with a console command EventSequence handler
Browse files Browse the repository at this point in the history
Presently the cheat console commands use a somewhat awkward mechanic
where the arguments are converted to integers, packed into an array
and then fed to the relevant cheat code handler. This not only makes
them difficult to extend but also results in code duplication.

G_AddEventSequenceCommand() works identically to G_AddEventSequence()
except that the native function callback is replaced with a console
command execution.

With a little reqwiring work, most if not all the cheat code handlers
could be replaced with templated console command event sequences.

Presently unused.
  • Loading branch information
danij-deng committed Sep 5, 2012
1 parent bb87d54 commit a2bb038
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 7 deletions.
8 changes: 8 additions & 0 deletions doomsday/plugins/common/include/g_eventsequence.h
Expand Up @@ -67,6 +67,14 @@ int G_EventSequenceResponder(event_t* ev);
*/
void G_AddEventSequence(const char* sequence, eventsequencehandler_t callback);

/**
* Add a new event sequence.
*
* @param sequence Text description of the sequence.
* @param cmdTemplate Templated console command to be executed upon sequence completion.
*/
void G_AddEventSequenceCommand(const char* sequence, const char* commandTemplate);

#if __cplusplus
} // extern "C"
#endif
Expand Down
70 changes: 63 additions & 7 deletions doomsday/plugins/common/src/g_eventsequence.cpp
Expand Up @@ -28,10 +28,55 @@
#include "common.h"
#include "g_eventsequence.h"

/// Base class for all sequence complete handlers.
class ISequenceCompleteHandler
{
public:
virtual ~ISequenceCompleteHandler() {}
virtual void invoke(int player, EventSequenceArg* args, int numArgs) = 0;
};

/// Sequence complete Callback handler.
class SequenceCompleteHandler : public ISequenceCompleteHandler
{
public:
SequenceCompleteHandler(eventsequencehandler_t _callback) : callback(_callback) {}
virtual void invoke(int player, EventSequenceArg* args, int numArgs)
{
callback(player, args, numArgs);
}
private:
eventsequencehandler_t callback;
};

/// Sequence complete Command handler.
class SequenceCompleteCommandHandler : public ISequenceCompleteHandler
{
public:
SequenceCompleteCommandHandler(const char* _commandTemplate)
{
Str_Set(Str_InitStd(&commandTemplate), _commandTemplate);
}
virtual ~SequenceCompleteCommandHandler()
{
Str_Free(&commandTemplate);
}
virtual void invoke(int player, EventSequenceArg* args, int numArgs)
{
DENG_UNUSED(player);
DENG_UNUSED(args);
DENG_UNUSED(numArgs);
/// @todo Compose the real command substituting arguments in the template.
DD_Execute(true/*silent*/, Str_Text(&commandTemplate));
}
private:
Str commandTemplate;
};

class EventSequence
{
public:
EventSequence(const char* _sequence, eventsequencehandler_t _handler)
EventSequence(const char* _sequence, ISequenceCompleteHandler& _handler)
: sequence(), handler(_handler), pos(0), numArgs(0), args(0)
{
int len = strlen(_sequence);
Expand All @@ -47,7 +92,7 @@ class EventSequence
int arg = ch[1] - '0';
if(arg < 1 || arg > 9)
{
Con_Message("Warning: EventSequence: Bad suffix %c in sequence %s, sequence truncated.", *ch, _sequence);
Con_Message("Warning: EventSequence: Bad suffix %c in sequence %s, sequence truncated.", ch[1], _sequence);
len = ch - _sequence;
break;
}
Expand Down Expand Up @@ -76,6 +121,7 @@ class EventSequence
{
Str_Free(&sequence);
if(args) delete[] args;
delete &handler;
}

/**
Expand Down Expand Up @@ -121,15 +167,15 @@ class EventSequence
if(pos < Str_Length(&sequence)) return false;

// Sequence completed.
handler(player, args, numArgs);
handler.invoke(player, args, numArgs);
rewind();

return true;
}

private:
Str sequence;
eventsequencehandler_t handler;
ISequenceCompleteHandler& handler;
int pos;
int numArgs;
EventSequenceArg* args;
Expand Down Expand Up @@ -185,10 +231,20 @@ int G_EventSequenceResponder(event_t* ev)
return eventWasEaten;
}

void G_AddEventSequence(const char* sequence, eventsequencehandler_t handler)
void G_AddEventSequence(const char* sequence, eventsequencehandler_t callback)
{
if(!inited) Con_Error("G_AddEventSequence: Subsystem not presently initialized.");
if(!sequence || !sequence[0] || !handler) Con_Error("G_AddEventSequence: Invalid argument(s).");
if(!sequence || !sequence[0] || !callback) Con_Error("G_AddEventSequence: Invalid argument(s).");

SequenceCompleteHandler* handler = new SequenceCompleteHandler(callback);
sequences.push_back(new EventSequence(sequence, *handler));
}

void G_AddEventSequenceCommand(const char* sequence, const char* commandTemplate)
{
if(!inited) Con_Error("G_AddEventSequenceCommand: Subsystem not presently initialized.");
if(!sequence || !sequence[0] || !commandTemplate || !commandTemplate[0]) Con_Error("G_AddEventSequenceCommand: Invalid argument(s).");

sequences.push_back(new EventSequence(sequence, handler));
SequenceCompleteCommandHandler* handler = new SequenceCompleteCommandHandler(commandTemplate);
sequences.push_back(new EventSequence(sequence, *handler));
}

0 comments on commit a2bb038

Please sign in to comment.