Skip to content

Commit

Permalink
Implement event-hooked enchantment framework
Browse files Browse the repository at this point in the history
  • Loading branch information
Peter Shih committed Apr 17, 2017
1 parent 4dff00f commit ab6ab60
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 17 deletions.
2 changes: 1 addition & 1 deletion include/FlowControl/Manipulators/BoardManipulator-impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ namespace FlowControl
state::CardRef card_ref = state_.AddCard(GenerateCard(std::move(new_data), player));

state_.GetMutableCard(card_ref).GetMutableEnchantmentHandler()
.AfterCopied(FlowControl::Manipulate(state_, flow_context_));
.AfterCopied(FlowControl::Manipulate(state_, flow_context_), card_ref);

return card_ref;
}
Expand Down
26 changes: 15 additions & 11 deletions include/FlowControl/enchantment/Enchantments.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@ namespace FlowControl
class Enchantments
{
public:
using IdentifierType = Utils::CloneableContainers::RemovableVectorIdentifier;

typedef void(*ApplyFunctor)(state::Cards::EnchantableStates &);
typedef void(*RegisterEventFunctor)(FlowControl::Manipulate &);
typedef void(*RegisterEventFunctor)(FlowControl::Manipulate &, state::CardRef, IdentifierType);

struct AuraEnchantment {
ApplyFunctor apply_functor;
Expand All @@ -36,15 +38,15 @@ namespace FlowControl
};
struct EventHookedEnchantment {
bool Apply(state::State const& state, state::Cards::EnchantableStates & stats) const { apply_functor(stats); return true; }
void RegisterEvent(FlowControl::Manipulate & manipulate) const { register_functor(manipulate); }
void RegisterEvent(FlowControl::Manipulate & manipulate, state::CardRef card_ref, IdentifierType id) const {
register_functor(manipulate, card_ref, id);
}

ApplyFunctor apply_functor;
RegisterEventFunctor register_functor;
};
using EnchantmentType = std::variant<NormalEnchantment, AuraEnchantment, EventHookedEnchantment>;

typedef Utils::CloneableContainers::RemovableVector<EnchantmentType> ContainerType;
using IdentifierType = ContainerType::Identifier;

class NormalEnchantmentUpdateDecider {
public:
Expand Down Expand Up @@ -80,13 +82,14 @@ namespace FlowControl
}

template <typename EnchantmentType>
typename IdentifierType PushBackEventHookedEnchantment()
typename IdentifierType PushBackEventHookedEnchantment(FlowControl::Manipulate & manipulate, state::CardRef card_ref)
{
EnchantmentType item;
need_update_ = true;
assert(item.apply_functor);
assert(item.register_functor);
return enchantments_.PushBack(EventHookedEnchantment{ item.apply_functor, item.register_functor });
IdentifierType id = enchantments_.PushBack(EventHookedEnchantment{ item.apply_functor, item.register_functor });
item.register_functor(manipulate, card_ref, id);
}

void Remove(IdentifierType id)
Expand All @@ -101,13 +104,13 @@ namespace FlowControl
enchantments_.Clear();
}

void AfterCopied(FlowControl::Manipulate & manipulate)
void AfterCopied(FlowControl::Manipulate & manipulate, state::CardRef card_ref)
{
need_update_ = true;
enchantments_.IterateAll([&](IdentifierType id, EnchantmentType& enchantment) -> bool {
struct OpFunctor {
OpFunctor(FlowControl::Manipulate & manipulate, ContainerType & enchantments, IdentifierType id)
: manipulate_(manipulate), enchantments_(enchantments), id_(id)
OpFunctor(FlowControl::Manipulate & manipulate, state::CardRef card_ref, ContainerType & enchantments, IdentifierType id)
: manipulate_(manipulate), card_ref_(card_ref), enchantments_(enchantments), id_(id)
{}

void operator()(NormalEnchantment const& arg) {
Expand All @@ -118,15 +121,16 @@ namespace FlowControl
enchantments_.Remove(id_);
}
void operator()(EventHookedEnchantment const& arg) {
arg.RegisterEvent(manipulate_);
arg.RegisterEvent(manipulate_, card_ref_, id_);
}

FlowControl::Manipulate & manipulate_;
state::CardRef card_ref_;
ContainerType & enchantments_;
IdentifierType id_;
};

std::visit(OpFunctor(manipulate, enchantments_, id), enchantment);
std::visit(OpFunctor(manipulate, card_ref, enchantments_, id), enchantment);
return true;
});
}
Expand Down
5 changes: 4 additions & 1 deletion include/FlowControl/enchantment/Handler.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,14 @@ namespace FlowControl
template <typename EnchantmentType> auto PushBackAuraEnchantment(state::State const& state) {
return enchantments.PushBackAuraEnchantment<EnchantmentType>();
}
template <typename EnchantmentType> auto PushBackEventHookedEnchantment(FlowControl::Manipulate & manipulate, state::CardRef card_ref) {
return enchantments.PushBackEventHookedEnchantment<EnchantmentType>(manipulate, card_ref);
}

bool Exists(TieredEnchantments::IdentifierType id) const { return enchantments.Exists(id); }

void Clear() { enchantments.Clear(); }
void AfterCopied(FlowControl::Manipulate & manipulate) { enchantments.AfterCopied(manipulate); }
void AfterCopied(FlowControl::Manipulate & manipulate, state::CardRef card_ref) { enchantments.AfterCopied(manipulate, card_ref); }
void Remove(TieredEnchantments::IdentifierType id) { return enchantments.Remove(id); }

void Update(state::State & state, FlowContext & flow_context, state::CardRef card_ref, bool allow_hp_reduce);
Expand Down
14 changes: 10 additions & 4 deletions include/FlowControl/enchantment/TieredEnchantments.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@ namespace FlowControl
GetEnchantments<EnchantmentType::normal_tier>().PushBackNormalEnchantment<EnchantmentType>(state);
}

template <typename EnchantmentType>
void PushBackEventHookedEnchantment(FlowControl::Manipulate & manipulate, state::CardRef card_ref)
{
GetEnchantments<EnchantmentType::normal_tier>().PushBackEventHookedEnchantment<EnchantmentType>(manipulate, card_ref);
}

void Remove(IdentifierType id)
{
switch (id.tier) {
Expand Down Expand Up @@ -71,11 +77,11 @@ namespace FlowControl
tier3_.Clear();
}

void AfterCopied(FlowControl::Manipulate & manipulate)
void AfterCopied(FlowControl::Manipulate & manipulate, state::CardRef card_ref)
{
tier1_.AfterCopied(manipulate);
tier2_.AfterCopied(manipulate);
tier3_.AfterCopied(manipulate);
tier1_.AfterCopied(manipulate, card_ref);
tier2_.AfterCopied(manipulate, card_ref);
tier3_.AfterCopied(manipulate, card_ref);
}

void ApplyAll(state::State const& state, state::Cards::EnchantableStates & stats)
Expand Down

0 comments on commit ab6ab60

Please sign in to comment.