Last active
March 21, 2019 07:16
-
-
Save acgetchell/7d396f78104d7dc6d81bbd2ec0847cdb to your computer and use it in GitHub Desktop.
Command Pattern
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <string> | |
#include <memory> | |
#include <vector> | |
#include <functional> | |
struct A { | |
explicit A() : sum{15} {} | |
std::vector<int> data{1,2,3,4,5}; | |
void update_sum() { | |
auto new_sum = 0; | |
for (auto const& item : data) { | |
new_sum += item; | |
} | |
sum = new_sum; | |
} | |
int sum; | |
friend std::ostream& operator<<(std::ostream& os, A const& result); | |
}; | |
std::ostream& operator<<(std::ostream& os, A const& result) | |
{ | |
for (auto& item : result.data) { | |
os << item << " "; | |
} | |
os << " sums to " << result.sum; | |
return os; | |
} | |
template <typename ManifoldType, | |
typename FunctionType=std::function<ManifoldType(ManifoldType&)>> | |
class Command | |
{ | |
public: | |
explicit Command(ManifoldType& manifold) | |
: manifold_{std::make_unique<ManifoldType>(manifold)} | |
{} | |
/// @return A reference to the manifold | |
ManifoldType const& get_manifold() const { return *manifold_; } | |
/// Push a move onto the move queue | |
void enqueue(FunctionType move) { moves_.emplace_back(move); } | |
/// Execute move | |
void execute() | |
{ | |
auto move = moves_.back(); | |
move(*manifold_); | |
} | |
/// The results | |
[[nodiscard]] auto& get_results() { return *manifold_; } | |
private: | |
std::unique_ptr<ManifoldType> manifold_; | |
std::vector<FunctionType> moves_; | |
}; | |
A f(A& a){ | |
for (auto& item : a.data) { | |
item *= 2; | |
} | |
return a; | |
} | |
A g(A& a){ | |
for (auto& item : a.data) { | |
item *= 4; | |
} | |
return a; | |
} | |
int main() | |
{ | |
A a; | |
Command<A> command{a}; | |
auto func{f}; | |
command.enqueue(func); | |
command.execute(); | |
auto b = command.get_results(); | |
std::cout << "The original is " << a << "\n"; | |
b.update_sum(); | |
std::cout << "The result is " << b << "\n"; | |
A c; | |
Command<A> command2{c}; | |
auto func2 = [](auto& a) -> A { | |
return g(a); | |
}; | |
command2.enqueue(func2); | |
std::cout << "The original is " << command2.get_manifold() << "\n"; | |
command2.execute(); | |
c = command2.get_results(); | |
// Don't update yet | |
std::cout << "The un-updated result is " << c << "\n"; | |
c.update_sum(); | |
std::cout << "After update: " << c << "\n"; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment