Skip to content

Instantly share code, notes, and snippets.

@kachsheev
Last active December 10, 2020 14:13
Show Gist options
  • Save kachsheev/672c41bc11d64448818badfa714d4ae3 to your computer and use it in GitHub Desktop.
Save kachsheev/672c41bc11d64448818badfa714d4ae3 to your computer and use it in GitHub Desktop.
Pure C command pattern
#include "command_pattern.h"
/** private **/
static int executorRun(ExecutorPtr executor)
{
return executor->command->run(executor->command, executor->invoker);
}
static Executor executionContextInit(InvokerPtr invoker, CommandPtr command)
{
Executor excecutor = EXECUTOR_INVALID;
if (invoker && command)
{
executor.run = ExecutorRun;
executor.invoker = invoker;
executor.command = command;
}
return excecutor;
}
/** public **/
/* invoker */
Executor invokerCallExecutionContextInit(InvokerPtr invoker, CommandPtr command)
{
return (invoker && commandIsValid(command))
? invoker->executionContextInit(invoker, command)
: EXECUTOR_INVALID
}
/* command */
Command commandCreateDefault(CallbackCommandRun commandRun)
{
Command command = COMMAND_INVALID;
if (commandRun)
{
command.run = commandRun;
}
return command;
}
int commandIsValid(CommandPtr command)
{
return command && command->run;
}
/* executor */
int executorIsValid(ExecutorPtr executor)
{
return executor
&& excecutor->run != EXECUTOR_INVALID.run
&& excecutor->invoker != EXECUTOR_INVALID.invoker
&& excecutor->command != EXECUTOR_INVALID.command;
}
/* global */
const Executor EXECUTOR_INVALID = { 0, 0, 0 };
const Command COMMAND_INVALID = { 0 };
const Invoker INVOKER_DEFAULT = { executionContextInit };
#ifndef PURE_C_COMMAND_PATTERN
#define PURE_C_COMMAND_PATTERN
struct Invoker;
typedef struct Invoker Invoker;
typedef Invoker* InvokerPtr;
struct Command;
typedef struct Command Command;
typedef Command* CommandPtr;
struct Executor;
typedef struct Executor Executor;
typedef Executor* ExecutorPtr;
typedef Executor(*CallbackExecutionContextInit)(InvokerPtr, CommandPtr);
typedef int(*CallbackCommandRun)(CommandPtr, InvokerPtr);
typedef int(*CallbackExecutorRun)(ExecutorPtr);
/* invoker */
struct Invoker
{
CallbackExecutionContextInit executionContextInit;
};
Executor invokerCallExecutionContextInit(InvokerPtr invoker, CommandPtr command);
/* command */
struct Command
{
CallbackCommandRun run;
};
Command commandCreateDefault(CallbackCommandRun commandRun);
int commandIsValid(CommandPtr command);
/* executor */
struct Executor
{
CallbackExecutorRun run;
InvokerPtr invoker;
CommandPtr command;
};
int executorIsValid(ExecutorPtr executor);
/* global */
extern const Invoker INVOKER_DEFAULT;
extern const Command COMMAND_INVALID;
extern const Executor EXECUTOR_INVALID;
#endif /* PURE_C_COMMAND_PATTERN */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment