/* Copyright(C) 2009 Yoshinori Oota All rights reserved. */
#include <stdio.h>
#include <stdlib.h>
struct State;
enum STATE_TYPE { SLEEPING ,WORKING ,EATING };
/* State Interface */
struct State {
void (*wakeup)();
void (*sayHello)();
void (*eat)();
void (*finish)();
void (*gotoBed)();
};
struct State* New_State(enum STATE_TYPE type);
void Delete_State(struct State* state);
/* Sleeping State */
void SleepingState_wakeup();
void SleepingState_sayHello();
void SleepingState_eat();
void SleepingState_finish();
void SleepingState_gotoBed();
/* Working State */
void WorkingState_wakeup();
void WorkingState_sayHello();
void WorkingState_eat();
void WorkingState_finish();
void WorkingState_gotoBed();
/* Eating State */
void EatingState_wakeup();
void EatingState_sayHello();
void EatingState_eat();
void EatingState_finish();
void EatingState_gotoBed();
/* Context Interface */
void Context_Initialise();
void Context_Set(struct State* next);
void Context_reqWakeup();
void Context_reqLetsEat();
void Context_reqHello();
void Context_reqFinish();
void Context_reqGotoBed();
void Context_Finalise();
/* State Class Implementation */
static struct State* gSLEEPING = NULL;
static struct State* gWORKING = NULL;
static struct State* gEATING = NULL;
struct State* gCurrentState = NULL;
struct State* New_State(enum STATE_TYPE type) {
struct State* state = NULL;
state =(struct State*)malloc(sizeof(struct State));
switch (type) {
case SLEEPING:
state->wakeup = &SleepingState_wakeup;
state->sayHello = &SleepingState_sayHello;
state->eat = &SleepingState_eat;
state->finish = &SleepingState_finish;
state->gotoBed = &SleepingState_gotoBed;
break;
case WORKING:
state->wakeup = &WorkingState_wakeup;
state->sayHello = &WorkingState_sayHello;
state->eat = &WorkingState_eat;
state->finish = &WorkingState_finish;
state->gotoBed = &WorkingState_gotoBed;
break;
case EATING:
state->wakeup = &EatingState_wakeup;
state->sayHello = &EatingState_sayHello;
state->eat = &EatingState_eat;
state->finish = &EatingState_finish;
state->gotoBed = &EatingState_gotoBed;
break;
}
return state;
}
void Delete_State(struct State* state) {
if (state == NULL) {
return;
}
free(state);
state = NULL;
return;
}
/* Sleeping */
void SleepingState_wakeup() {
printf("おはよう!\n");
Context_Set(gWORKING);
return;
}
void SleepingState_sayHello() { }
void SleepingState_eat() { }
void SleepingState_finish() { }
void SleepingState_gotoBed() { }
/* Working */
void WorkingState_wakeup() { }
void WorkingState_sayHello() {
printf("こんにちは\n");
return;
}
void WorkingState_eat() {
printf("いただきまーす\n");
Context_Set(gEATING);
return;
}
void WorkingState_finish() { }
void WorkingState_gotoBed() {
printf("おやすみなさい\n");
Context_Set(gSLEEPING);
return;
}
/* Eating */
void EatingState_wakeup() { }
void EatingState_sayHello() {
printf("こんにちは\n");
return;
}
void EatingState_eat() { }
void EatingState_finish() {
printf("ごちそうさま\n");
Context_Set(gWORKING);
return;
}
void EatingState_gotoBed() {
printf("ごちそうさま\n");
printf("おやすみなさい\n");
Context_Set(gSLEEPING);
return;
}
/* Context Implementation */
void Context_Initialise() {
gSLEEPING = New_State(SLEEPING);
gWORKING = New_State(WORKING);
gEATING = New_State(EATING);
gCurrentState = gSLEEPING;
return;
}
void Context_Clean() {
Delete_State(gSLEEPING);
Delete_State(gWORKING);
Delete_State(gEATING);
gCurrentState = NULL;
return;
}
void Context_Set(struct State* next) {
gCurrentState = next;
return;
}
void Context_reqWakeup() {
gCurrentState->wakeup();
return;
}
void Context_reqLetsEat() {
gCurrentState->eat();
return;
}
void Context_reqHello() {
gCurrentState->sayHello();
return;
}
void Context_reqFinish() {
gCurrentState->finish();
return;
}
void Context_reqGotoBed() {
gCurrentState->gotoBed();
return;
}
int main() {
Context_Initialise();
Context_reqWakeup(); /* おきろ! */
Context_reqHello(); /* こんにちは、*/
Context_reqLetsEat(); /* ご飯をたべよう */
/* おかしなリクエストをしてみる */
Context_reqWakeup(); /* おきろ! 無視されました */
Context_reqFinish(); /* 食事はおしまい */
Context_reqHello(); /* こんにちは */
Context_reqLetsEat(); /* ご飯をたべよう */
Context_reqGotoBed(); /* そろそろ寝よう。 両方挨拶できました */
/* あいさつしてみる */
Context_reqHello(); /* 無反応ですね。熟睡? */
Context_reqWakeup(); /* おきろーーーまた仕事だーーー */
Context_Clean();
return 0;
}
|