Skip to content

Instantly share code, notes, and snippets.

@kyle-go
Last active December 15, 2015 11:49
Show Gist options
  • Save kyle-go/5256042 to your computer and use it in GitHub Desktop.
Save kyle-go/5256042 to your computer and use it in GitHub Desktop.
c++ mvc.h v2 complie with vs2010
#ifndef MVC_H_
#define MVC_H_
#include <set>
#include <memory>
#include <functional>
template <typename T>
class observer
{
public:
typedef std::function<bool(const T&)> CBF;
virtual const T calc() const = 0;
void ApplyModel(const T& d) const
{
callback_(d);
}
protected:
observer(typename CBF callback):callback_(callback){};
private:
typename CBF callback_;
};
template <typename T>
class model_proxy
{
public:
model_proxy(){};
~model_proxy()
{
for (auto it=std::begin(observer_); it!=std::end(observer_); it++)
delete *it;
}
void add_observer(observer<T>*o)
{
//cannot find o
if (observer_.find(o) == observer_.end()) {
observer_.insert(o);
fresh(T());
}
}
void remove_observer(observer<T>* o)
{
observer_.erase(o);
}
void fresh(T)
{
auto it = observer_.begin();
if (it != std::end(observer_)) {
const T d = (*it)->calc();
for (;it!=observer_.end(); it++)
(*it)->ApplyModel(d);
}
}
private:
//disable copy
model_proxy(const model_proxy&);
void operator=(const model_proxy&);
std::set<observer<T>*> observer_;
};
#endif //MVC_H_
#include <memory>
#include <string>
#include <functional>
#include <windows.h>
#include <stdio.h>
#include "mvc.h"
class GameModel
{
public:
static std::shared_ptr<GameModel> SingleInstance() {
static std::shared_ptr<GameModel> p(new GameModel);
return p;
}
void add_observer(observer<int>*o)
{
model_int_.add_observer(o);
}
void add_observer(observer<std::string>*o)
{
model_string_.add_observer(o);
}
void remove_observer(observer<int>*o)
{
model_int_.remove_observer(o);
}
void remove_observer(observer<std::string>*o)
{
model_string_.remove_observer(o);
}
void fresh(int)
{
model_int_.fresh(int());
}
void fresh(std::string)
{
model_string_.fresh(std::string());
}
void fresh()
{
fresh(int());
fresh(std::string());
}
//some other public functions...
private:
//some data...
//...
//make sure this class is a single instance.
GameModel(){};
GameModel(const GameModel&);
void operator=(const GameModel&);
model_proxy<int> model_int_;
model_proxy<std::string> model_string_;
};
class GameObserverInt : public observer<int>
{
public:
static GameObserverInt* factory(CBF c)
{
return new GameObserverInt(c);
}
virtual const int calc() const
{
auto gameModel = GameModel::SingleInstance();
//do some calc with model...
//...
return 9;
}
private:
GameObserverInt(CBF callback):observer(callback){}
};
class GameObserverString : public observer<std::string>
{
public:
static GameObserverString* factory(CBF c)
{
return new GameObserverString(c);
}
virtual const std::string calc() const
{
auto gameModel = GameModel::SingleInstance();
//do some calc with model..
//...
return "hello~";
}
private:
GameObserverString(CBF callback):observer(callback){}
};
//this is a callback function
bool cb_function_int(const int& i)
{
printf("this is cb_function<int>, i=%d\n", i);
return true;
}
//this is a callback function
bool cb_function_string(const std::string& i)
{
printf("this is cb_function<std::string>, i=%s\n", i.c_str());
return true;
}
int main()
{
std::shared_ptr<GameModel> gm = GameModel::SingleInstance();
GameObserverInt* gi = GameObserverInt::factory(cb_function_int);
GameObserverString* gs = GameObserverString::factory(cb_function_string);
gm->add_observer(gi);
gm->add_observer(gs);
gm->fresh(int());
//gm->fresh(std::string());
gm->fresh();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment