1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
|
#include <iostream>
#include <vector>
#include <memory>
template<typename D>
class dataModifier;
template<typename D>
class dataSharer{
private:
std::shared_ptr<dataModifier<D> > dataMod_;
protected:
void share(D data){
dataMod_->share(data);
}
virtual void sync(){} //override to sync newly connected dataSharer
public:
dataSharer(){
dataMod_=std::make_shared<dataModifier<D> >(*this);
}
virtual ~dataSharer(){}
void connect(dataSharer<D>& other){
dataMod_=other.dataMod_;
dataMod_->addSharer(*this);
sync();
}
virtual void modify(D data)=0;
};
template<typename D>
class dataModifier{
private:
std::vector<dataSharer<D>* > dataSharers_;
public:
dataModifier(dataSharer<D>& ds){
addSharer(ds);
}
void addSharer(dataSharer<D>& ds){
dataSharers_.push_back(&ds);
}
void share(D& data){
for(auto& a: dataSharers_){
a->modify(data);
}
}
};
struct vector2{
float x;
float y;
};
struct generic{
vector2 position;
vector2 scale;
vector2 origin;
};
struct physics{
vector2 velocity;
};
class component: public dataSharer<generic>, public dataSharer<physics>{
private:
using dataSharer<generic>::share;
using dataSharer<physics>::share;
generic generic_;
physics physics_;
virtual void modify(generic g){
generic_=g;
std::cout<<"setting generic data:\n";
std::cout<<"position: ("<<generic_.position.x<<", "<<generic_.position.y<<")\n";
std::cout<<"scale: ("<<generic_.scale.x<<", "<<generic_.scale.y<<")\n";
std::cout<<"origin: ("<<generic_.origin.x<<", "<<generic_.origin.y<<")\n";
}
virtual void modify(physics p){
physics_=p;
std::cout<<"setting physical data:\n";
std::cout<<"velocity: ("<<physics_.velocity.x<<", "<<physics_.velocity.y<<")\n";
}
virtual void sync(){
share(generic_);
share(physics_);
}
public:
using dataSharer<generic>::connect;
using dataSharer<physics>::connect;
component(generic g=generic{{0,0},{0,0},{0,0}}, physics p=physics{{0,0}}){
physics_=p;
generic_=g;
}
component(component& other): dataSharer<generic>::dataSharer(),dataSharer<physics>::dataSharer() {
physics_=other.physics_;
generic_=other.generic_;
}
component& operator =(component& other){
share(other.generic_);
share(other.physics_);
return *this;
}
void setPosition(vector2 position){
generic_.position=position;
share(generic_);
}
void setVelocity(vector2 velocity){
physics_.velocity=velocity;
share(physics_);
}
};
int main(){
component c1(generic{{8,7},{4,2},{5,4}}, physics{{0,2}});
component c2;
c1.connect(static_cast<dataSharer<generic>&>(c2)); //c1 now shares generic data with c2
c1.connect(static_cast<dataSharer<physics>&>(c2)); //c1 now shares physical data with c2
c2.setPosition(vector2{12,9}); //applied to c1 & c2
component c3(c2); //members copied to c3, but does not share data with c1 & c2
c3.setPosition(vector2{88,21}); //only applies to c3
c2=c3; //applies c3 modification to c1 & c2
return 0;
}
|