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
|
#include <iostream>
#include <string>
#include <boost/signals2.hpp>
using namespace boost::signals2;
struct Query;
struct Game
{
signal<void(Query&)> queries;
};
struct Query
{
std::string creature_name;
enum Argument { attack, defense } argument;
int result;
};
class Creature
{
public:
std::string name;
Creature(Game& game, std::string name, int attack, int defense)
:game{game}, name{name}, attack{attack}, defense{defense}
{
}
friend std::ostream& operator<<(std::ostream& os, const Creature& creature)
{
os << creature.name << std::endl;
os << creature.get_attack() << ", " << creature.defense << std::endl;
return os;
}
int get_attack() const
{
Query q{ name, Query::Argument::attack, attack };
game.queries(q);
return q.result;
}
private:
Game& game;
int attack, defense;
};
class CreatureModifier
{
Game& game;
Creature& creature;
public:
CreatureModifier(Game& game, Creature& creature)
: game{game}, creature{creature} { }
};
class DoubleAttackModifier : public CreatureModifier
{
connection conn;
public:
DoubleAttackModifier(Game& game, Creature& creature)
: CreatureModifier(game, creature)
{
conn = game.queries.connect([&](Query& q) {
if(q.creature_name == creature.name &&
q.argument == Query::Argument::attack)
q.result *= 2;
});
}
~DoubleAttackModifier() { conn.disconnect(); }
};
int main()
{
Game game;
Creature goblin{game, "Strong Goblin", 2, 2};
std::cout << goblin << std::endl;
{
DoubleAttackModifier dam{game, goblin};
std::cout << goblin << std::endl;
}
std::cout << goblin << std::endl;
}
|