[tremulous] qcommon/cmd.c 中的 cmd_list
2008-11-01 09:16:03| 分类:
3d_quake3
| 标签:
|举报
|字号大中小 订阅
接上篇,qcommon/cmd.c 中除了 Cbuf_XXX 之外,主要还实现了 Cmd_XXX 一类函数。
还记得星际中的 show me the money,我们要在游戏中实现一个简单的 command interpreter,如何做?Cmd_XXX 给出了一个简单的方式。如下:
// struct
typedef void (*xcommand_t)(void);
typedef struct cmd_function_s {
struct cmd_function_s *next;
char *name;
xcommand_t function;
} cmd_function_t;
// global var
cmd_function_t *cmd_list = NULL;
通过链表管理一个 name/fn pairs,每次输入 command,就遍历链表,找到对应的 fn,执行一下即可。:-) 实现简单,但又很实用。下面是我写的一个'具体而微'的版本,参考之。
---------------------------- mycmd.c ---------------------------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// macro
#define MAX_LINE_SIZE 256
// struct
typedef void (*xcommand_t)(void);
typedef struct cmd_function_s {
struct cmd_function_s *next;
char *name;
xcommand_t function;
} cmd_function_t;
// global var
cmd_function_t *cmd_list = NULL;
// func
void Cmd_Execute(const char *context)
{
cmd_function_t *cmd;
int found = 0;
for (cmd = cmd_list; cmd != NULL; cmd = cmd->next)
{
if ( strcmp(cmd->name, context) == 0 )
{
found = 1;
if ( cmd->function )
cmd->function();
break;
}
}
if (!found)
printf("[%s] cmd not found!\n", context);
}
void Cmd_AddCommand(const char *cmdname, xcommand_t fn)
{
cmd_function_t *cmd;
int namelen;
cmd = malloc(sizeof(cmd_function_t));
namelen = strlen(cmdname)+1;
cmd->name = malloc(namelen);
strncpy(cmd->name, cmdname, namelen);
cmd->function = fn;
cmd->next = cmd_list;
cmd_list = cmd;
}
// ---- usage
void Show_f()
{
printf("my show\n");
}
void Goodday_f()
{
printf("good day\n");
}
int main()
{
char line[MAX_LINE_SIZE];
Cmd_AddCommand("show me the money", Show_f);
Cmd_AddCommand("gooday", Goodday_f);
while (1)
{
gets(line);
if ( strcmp(line, "quit") == 0 )
break;
Cmd_Execute(line);
}
return 0;
}
---------------------------- mycmd.c ---------------------------
:-) 如何,很简单吧。quake中的版本,只是再多加如了参数的概念,比这稍微复杂一点点而已。
评论这张
转发至微博
转发至微博
评论