Created
February 26, 2019 15:17
-
-
Save hgaiser/f9220db1979274297476adddd52cf506 to your computer and use it in GitHub Desktop.
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 "fizyr_flow.hpp" | |
void Variable::operator=(std::any v) { | |
// Copy the new value. | |
value = v; | |
// Check if we can run ops that haven't been executed yet. | |
for (auto const & op: operators) | |
if (op->inputsReady() && !op->executed()) { | |
op->_execute(); | |
} | |
// Optionally notify listeners that this value has been updated. | |
for (auto const & callback: callbacks) { callback(); } | |
}; | |
/// Simple Operator that sums all its inputs. | |
template<typename T> | |
class AddOperator: public Operator { | |
public: | |
AddOperator(std::string name): Operator(name) {} | |
virtual void createOutputs() { | |
// We create only one output. | |
outputs_.emplace_back(std::make_shared<Variable>(name_ + "/output")); | |
} | |
virtual void execute() { | |
// Sum all inputs together. | |
T sum; | |
for (auto const & input: inputs_) { | |
sum += std::any_cast<T>(input->value); | |
} | |
// Finally, set the output to the sum. | |
*outputs_[0] = sum; | |
} | |
}; | |
int main() { | |
// Create input Variables. | |
auto input_1 = std::make_shared<Variable>("input_1"); | |
auto input_2 = std::make_shared<Variable>("input_2"); | |
// Create two AddOperators. | |
auto add_output_1 = (*std::make_shared<AddOperator<int>>("simple_add_op"))({input_1, input_2})[0]; | |
auto add_output_2 = (*std::make_shared<AddOperator<int>>("second_add_op"))({add_output_1, input_1})[0]; | |
// Add a callback to print when add_output_2 has been updated. | |
add_output_2->addCallback([add_output_2] () { | |
std::cout << "Variable " << add_output_2->name << " has been set to " << std::any_cast<int>(add_output_2->value) << std::endl; | |
}); | |
// Set the values for the input, this automatically triggers Operators. | |
*input_1 = 5; | |
*input_2 = 6; | |
// Print the input and output values. | |
std::cout << std::any_cast<int>(input_1->value) << std::endl; | |
std::cout << std::any_cast<int>(input_2->value) << std::endl; | |
std::cout << std::any_cast<int>(add_output_1->value) << std::endl; | |
std::cout << std::any_cast<int>(add_output_2->value) << std::endl; | |
} |
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 <vector> | |
#include <functional> | |
#include <optional> | |
#include <any> | |
#include <memory> | |
class Operator; | |
/// Represents a piece of data in the graph. | |
class Variable { | |
public: | |
/// Callbacks are called whenever the Variable changes values. | |
using Callback = std::function<void ()>; | |
Variable(std::string name) : name{name} {} | |
/// List of Operators that this Variable is connected to. | |
std::vector<std::shared_ptr<Operator>> operators; | |
/// List of callbacks to call when this Variable changes. | |
std::vector<Callback> callbacks; | |
/// The name of the Variable. | |
std::string name; | |
/// The Value of the Variable. | |
std::any value; | |
/// Checks to see if this Variable contains data. | |
operator bool() const { return value.has_value(); }; | |
/// Updates the Variable to contain new data. | |
void operator=(std::any v); | |
/// Adds a callback which is called when this Variable is updated. | |
void addCallback(Callback callback) { | |
callbacks.push_back(callback); | |
} | |
}; | |
/// Represents an action on one or more pieces of data. | |
class Operator: public std::enable_shared_from_this<Operator> { | |
protected: | |
/// List of input Variables. | |
std::vector<std::shared_ptr<Variable>> inputs_; | |
/// List of Variables that will be set after execution. | |
std::vector<std::shared_ptr<Variable>> outputs_; | |
/// Holds the state of this Operator. | |
bool executed_ = false; | |
/// The name of this Operator. | |
std::string name_; | |
public: | |
Operator(std::string name) : name_{name} {} | |
/// Constructs the Operator, returns the output Variables. | |
std::vector<std::shared_ptr<Variable>> operator() (std::vector<std::shared_ptr<Variable>> inputs) { | |
// Simply copy the inputs. | |
inputs_ = inputs; | |
// For all inputs, add this Operator as part of their list of Operators. | |
for (auto & input: inputs) { | |
input->operators.emplace_back(shared_from_this()); | |
} | |
// Create outputs (virtual function). | |
createOutputs(); | |
return outputs_; | |
} | |
/// Check to see if all inputs have values. | |
bool inputsReady() { | |
for (auto const & input: inputs_) | |
if (!(*input)) return false; | |
return true; | |
} | |
/// Execution wrapper, sets executed_ to true. | |
void _execute() { | |
execute(); | |
executed_ = true; | |
} | |
/// Return if this Operator has already been executed. | |
bool executed() { return executed_; } | |
/// Return the name of this Operator. | |
std::string name() { return name_; }; | |
/// Function that populates the outputs_ list. | |
virtual void createOutputs() = 0; | |
/// Function that runs on the inputs_ list and puts the results in the outputs_ list. | |
virtual void execute() = 0; | |
}; | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment