#include <stdio.h>
#include <process.h>
#include <windows.h>
#include <string>
class IAnimalActionObserver
{
public:
IAnimalActionObserver(){}
virtual ~IAnimalActionObserver(){}
virtual void OnAnimalEat() = 0;
};
class Animal
{
public:
Animal()
: observer_(NULL)
{
_beginthreadex(NULL, 0, ThreadFun, this, 0, NULL);
}
virtual ~Animal(){}
virtual void RegsiterActionObserver(IAnimalActionObserver* observer)
{
observer_ = observer;
}
virtual void DeregsiterActionObserver()
{
observer_ = NULL;
}
private:
static unsigned int _stdcall ThreadFun(void* args)
{
(static_cast<Animal*>(args))->ThreadLoop();
return 0;
}
void ThreadLoop()
{
while (true)
{
if (observer_)
{
observer_->OnAnimalEat();
}
Sleep(2 * 1000);
}
}
private:
IAnimalActionObserver* observer_;
};
class Cat
: public IAnimalActionObserver
{
struct CatInfo
{
CatInfo():eat_count_(0){}
int eat_count_;
std::string str_msg_;
};
public:
Cat()
{
InitializeCriticalSection(&cs_);
_beginthreadex(NULL, 0, ThreadFun1, this, 0, NULL);
_beginthreadex(NULL, 0, ThreadFun2, this, 0, NULL);
}
virtual ~Cat()
{
}
virtual void OnAnimalEat()
{
printf("cat eat a fish.\n");
EatFinish();
}
private:
static unsigned int _stdcall ThreadFun1(void* args)
{
(static_cast<Cat*>(args))->ThreadLoop1();
return 0;
}
void ThreadLoop1()
{
while (true)
{
animal_.RegsiterActionObserver(this);
Sleep(2 * 1000);
animal_.DeregsiterActionObserver();
msg_.str_msg_ = "cat eating fish\n";
msg_.eat_count_++;
if (msg_.eat_count_ >= 5)
{
break;
}
}
}
static unsigned int _stdcall ThreadFun2(void* args)
{
(static_cast<Cat*>(args))->ThreadLoop2();
return 0;
}
void ThreadLoop2()
{
while (true)
{
EnterCriticalSection(&cs_);
if (msg_.eat_count_ >= 5)
{
msg_.str_msg_ = "cat eat finish\n";
EatFinish();
break;
}
LeaveCriticalSection(&cs_);
}
}
void EatFinish()
{
EnterCriticalSection(&cs_);
if (msg_.eat_count_ >= 5)
{
printf(msg_.str_msg_.c_str());
msg_.eat_count_ = 0;
msg_.str_msg_.empty();
animal_.DeregsiterActionObserver();
}
LeaveCriticalSection(&cs_);
}
private:
Animal animal_;
CRITICAL_SECTION cs_;
CatInfo msg_;
};
int main()
{
Cat cat_;
while (1)
{
Sleep(1000);
}
return 0;
}