/* Copyright(C) 2009 Yoshinori Oota All rights reserved. */
#include <stdio.h>
#include <stdlib.h>
struct Component;
struct Visitor;
void indent(int n);
enum COMPONENT_TYPE { LEAF ,COMPOSITE };
enum VISITOR_TYPE { DUMP ,COUNT };
/* Component List */
struct ComponentList {
struct Component* component_;
struct ComponentList* next_;
};
struct ComponentList* New_ComponentList(struct Component* component);
void Delete_ComponentList(struct ComponentList* list);
/* Component Interface */
struct Component {
enum COMPONENT_TYPE type_;
struct ComponentList* child_top_;
struct ComponentList* child_last_;
void (*accept)(struct Component* pthis ,struct Visitor* v);
void (*add)(struct Component* pthis ,struct Component* child);
void (*Operation)(struct Component* pthis ,int n);
};
struct Component* New_Component(enum COMPONENT_TYPE type);
void Delete_Component(struct Component* component);
void Leaf_accept (struct Component* pthis ,struct Visitor* v);
void Leaf_add(struct Component* pthis ,struct Component* child);
void Leaf_Operation(struct Component* pthis ,int n);
void Composite_accept(struct Component* pthis ,struct Visitor* v);
void Composite_add(struct Component* pthis ,struct Component* child);
void Composite_Operation(struct Component* pthis ,int n);
/* Visitor Interface */
struct Visitor {
int depth_; /* for Dump Visitor */
int leaf_count_; /* for Count Visitor */
int comp_count_; /* for Count Visitor */
void (*VisitLeaf)(struct Visitor* v ,struct Component* c);
void (*VisitComposite)(struct Visitor* v ,struct Component* c);
void (*Print)(struct Visitor* v);
};
void DumpVisitor_VisitLeaf(struct Visitor* pthis ,struct Component* c);
void DumpVisitor_VisitComposite(struct Visitor* pthis ,struct Component* c);
void CountVisitor_VisitLeaf(struct Visitor* pthis ,struct Component* c);
void CountVisitor_VisitComposite(struct Visitor* pthis ,struct Component* c);
void Visitor_Print(struct Visitor* pthis);
/* ComponentList Implementation */
struct ComponentList* New_ComponentList(struct Component* component) {
struct ComponentList* list = NULL;
list = (struct ComponentList*)malloc(sizeof(struct ComponentList));
list->component_ = component;
list->next_ = NULL;
return list;
}
void Delete_ComponentList(struct ComponentList* list) {
free(list);
list = NULL;
return;
}
/* Component Class Implementation */
struct Component* New_Component(enum COMPONENT_TYPE type) {
struct Component* component = NULL;
component = (struct Component*)malloc(sizeof(struct Component));
component->type_ = type;
component->child_top_ = NULL;
component->child_last_ = NULL;
switch (type) {
case LEAF:
component->accept = &Leaf_accept;
component->add = &Leaf_add;
component->Operation = &Leaf_Operation;
break;
case COMPOSITE:
component->accept = &Composite_accept;
component->add = &Composite_add;
component->Operation = &Composite_Operation;
break;
}
return component;
}
void Delete_Component(struct Component* component) {
struct ComponentList* cur = NULL;
struct ComponentList* tmp = NULL;
if (component->type_ == COMPOSITE) {
cur = component->child_top_;
while (cur != NULL) {
tmp = cur->next_;
Delete_Component(cur->component_);
Delete_ComponentList(cur);
cur = tmp;
}
}
Delete_Component(component);
return;
}
void Leaf_accept (struct Component* pthis ,struct Visitor* v) {
v->VisitLeaf(v ,pthis);
}
void Leaf_add(struct Component* pthis ,struct Component* child) {
return; /* No operation */
}
void Leaf_Operation(struct Component* pthis ,int n) {
indent(n);
printf("- Leaf\n");
return;
}
void Composite_accept(struct Component* pthis ,struct Visitor* v) {
struct ComponentList* cur = NULL;
struct Component* component = NULL;
v->VisitComposite(v, pthis);
cur = pthis->child_top_;
while (cur != NULL) {
component = cur->component_;
component->accept(component ,v);
cur = cur->next_;
}
return;
}
void Composite_add(struct Component* pthis ,struct Component* child) {
struct Component* cur = NULL;
struct ComponentList* list = NULL;
list = New_ComponentList(child);
if (pthis->child_top_ == NULL) {
pthis->child_top_ = list;
pthis->child_last_ = list;
} else {
pthis->child_last_->next_ = list;
pthis->child_last_ = list;
}
return;
}
void Composite_Operation(struct Component* pthis ,int n) {
struct Component* component = NULL;
struct ComponentList* cur = NULL;
indent(n);
printf("+ Composite\n");
cur = pthis->child_top_;
while (cur != NULL) {
++n;
component = cur->component_;
component->Operation(component ,n);
--n;
cur = cur->next_;
}
return;
}
/* Visitor Class Implementation */
struct Visitor* New_Visitor(enum VISITOR_TYPE type) {
struct Visitor* visitor = NULL;
visitor = (struct Visitor*)malloc(sizeof(struct Visitor));
visitor->depth_ = 0;
visitor->leaf_count_ = 0;
visitor->comp_count_ = 0;
switch (type) {
case DUMP:
visitor->VisitLeaf = &DumpVisitor_VisitLeaf;
visitor->VisitComposite = &DumpVisitor_VisitComposite;
visitor->Print = &Visitor_Print;
break;
case COUNT:
visitor->VisitLeaf = &CountVisitor_VisitLeaf;
visitor->VisitComposite = &CountVisitor_VisitComposite;
visitor->Print = &Visitor_Print;
break;
}
return visitor;
}
void Delete_Visitor(struct Visitor* v) {
free(v);
v = NULL;
return;
}
void DumpVisitor_VisitLeaf(struct Visitor* pthis ,struct Component* c) {
int i = 0;
for (; i < pthis->depth_; ++i) {
printf(" ");
}
printf("- Leaf\n");
return;
}
void DumpVisitor_VisitComposite (struct Visitor* pthis ,struct Component* c) {
int i = 0;
for (; i < pthis->depth_; ++i) {
printf(" ");
}
printf("+ Composite\n");
++pthis->depth_;
return;
}
void Visitor_Print (struct Visitor* pthis) {
printf("Leaf: %d\n" ,pthis->leaf_count_);
printf("Composite: %d\n" ,pthis->comp_count_);
return;
}
void CountVisitor_VisitLeaf(struct Visitor* pthis ,struct Component* c) {
++(pthis->leaf_count_);
return;
}
void CountVisitor_VisitComposite(struct Visitor* pthis ,struct Component* c) {
++(pthis->comp_count_);
return;
}
void indent(int n) {
while (n != 0) {
printf(" ");
--n;
}
return;
}
struct Component* makeComposite() {
/* 以下のような構造を作る
* Composite -+- Leaf
* +- Leaf
* +- Composite -+- Leaf
* +- Leaf */
struct Component* composite1 = NULL;
struct Component* composite2 = NULL;
composite1 = New_Component(COMPOSITE);
composite1->add(composite1 ,New_Component(LEAF));
composite1->add(composite1 ,New_Component(LEAF));
composite2 = New_Component(COMPOSITE);
composite2->add(composite2 ,New_Component(LEAF));
composite2->add(composite2 ,New_Component(LEAF));
composite2->add(composite2 ,composite1);
return composite2;
}
int main() {
struct Component* component = NULL;
struct Visitor* dumper = NULL;
struct Visitor* counter = NULL;
component = makeComposite();
dumper = New_Visitor(DUMP);
counter = New_Visitor(COUNT);
printf("****************************\n");
component->accept(component ,dumper);
component->accept(component ,counter);
printf("****************************\n");
counter->Print(counter);
Delete_Visitor(dumper);
Delete_Visitor(counter);
return 0;
}
|