🐷
C 言語で Command パターン
queue で Command パターン
queue で実装してみる。queue というかリングバッファというか。
#include <stdio.h>
#include <stdarg.h>
#define QUEUE_MAX 4
typedef void (*command)(int argc, ...);
command queue[QUEUE_MAX];
int start_index;
int end_index;
void enqueue(command cmd)
{
if(queue[end_index] != NULL)
{
printf("queue is full\n");
return;
}
queue[end_index] = cmd;
end_index++;
if(end_index >= QUEUE_MAX)
{
end_index = 0;
}
}
command dequeue(void)
{
command cmd;
cmd = queue[start_index];
queue[start_index] = NULL;
start_index++;
if(start_index >= QUEUE_MAX)
{
start_index = 0;
}
return cmd;
}
void initialize(void)
{
int i;
for(i = 0; i < QUEUE_MAX; i++)
{
queue[i] = NULL;
}
start_index = 0;
end_index = 0;
}
void command1(int argc, ...)
{
int i;
va_list args;
va_start(args, argc);
printf("command1\n");
for(i = 0; i < argc; i++)
{
int n;
n = va_arg(args, int);
printf("%d\n", n);
}
va_end(args);
}
void command2(int argc, ...)
{
int i;
va_list args;
va_start(args, argc);
printf("command2\n");
for(i = 0; i < argc; i++)
{
int n;
n = va_arg(args, int);
printf("%d\n", n);
}
va_end(args);
}
void test_queue(void)
{
int i;
printf("test_queue start\n");
initialize();
enqueue(command1);
enqueue(command2);
for(i = 0; i < 16; i++)
{
command v = dequeue();
if(v != NULL)
{
v(1, i);
}
}
printf("test_queue end\n");
}
int main(int ac, char** av)
{
test_queue();
return 0;
}
test_queue start
command1
0
command2
1
test_queue end
連結リストで Command パターン
連結リストで実装してみる。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
typedef void (*command_t)(int argc, ...);
struct node_t
{
struct node_t* next;
command_t cmd;
} root;
/* 先頭に追加 */
void put(command_t cmd)
{
struct node_t* _p;
struct node_t* _q;
for(_p = &root; _p->next != NULL; _p = _p->next)
;
_q = (struct node_t*)malloc(sizeof(struct node_t));
if(_q == NULL)
{
perror("put");
exit(0);
}
_q->cmd = cmd;
_q->next = _p->next;
_p->next = _q;
}
/* 先頭を削除 */
void get(void)
{
struct node_t* _p;
_p = root.next;
if(_p == NULL)
{
printf("root is empty\n");
return;
}
root.next = _p->next;
free(_p);
}
void command1(int argc, ...)
{
int i;
va_list args;
va_start(args, argc);
printf("command1\n");
for(i = 0; i < argc; i++)
{
int n;
n = va_arg(args, int);
printf("%d\n", n);
}
va_end(args);
}
void command2(int argc, ...)
{
int c;
int n;
va_list args;
printf("command2\n");
va_start(args, argc);
c = va_arg(args, int);
n = va_arg(args, int);
printf("c:%d n:%d\n", c, n);
va_end(args);
}
void run(void)
{
int n;
struct node_t* _p;
n = 0;
for(_p = &root; _p->next != NULL; _p = _p->next)
{
if(_p->next != NULL)
{
_p->next->cmd(2, n, n * 10);
n++;
}
}
}
void test_command(void)
{
printf("test_command start\n");
put(command1);
put(command2);
run();
printf("test_command end\n");
}
int main(int ac, char** av)
{
test_command();
return 0;
}
test_command start
command1
0
0
command2
c:1 n:10
test_command end
連結リストで優先度あり Command パターン
連結リストの配列にしただけです。0 が優先度高くて、20 が優先度低いです。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#define PRI_MAX 20
typedef void (*command_t)(int argc, ...);
struct node_t
{
struct node_t* next;
command_t cmd;
} root[PRI_MAX];
/* 先頭に追加 */
void put(int pri, command_t cmd)
{
int i;
struct node_t* _p;
struct node_t* _q;
for(_p = &root[pri]; _p->next != NULL; _p = _p->next)
;
_q = (struct node_t*)malloc(sizeof(struct node_t));
if(_q == NULL)
{
perror("put");
exit(0);
}
_q->cmd = cmd;
_q->next = _p->next;
_p->next = _q;
}
void command0(int argc, ...)
{
int pri;
int n;
va_list args;
va_start(args, argc);
pri = va_arg(args, int);
n = va_arg(args, int);
printf("command0 pri:%d n:%d\n", pri, n);
va_end(args);
}
void run(void)
{
int pri;
int n;
struct node_t* _p;
n = 0;
for(pri = 0; pri < PRI_MAX; pri++)
{
for(_p = &root[pri]; _p->next != NULL; _p = _p->next)
{
if(_p->next != NULL)
{
_p->next->cmd(2, pri, n);
n++;
}
}
}
}
void test_command(void)
{
printf("test_command start\n");
put(19, command0);
put(19, command0);
put(0, command0);
put(0, command0);
put(1, command0);
put(2, command0);
run();
printf("test_command end\n");
}
int main(int ac, char** av)
{
test_command();
return 0;
}
test_command start
command0 pri:0 n:0
command0 pri:0 n:1
command0 pri:1 n:2
command0 pri:2 n:3
command0 pri:19 n:4
command0 pri:19 n:5
test_command end
Discussion