Last active
August 29, 2015 14:03
-
-
Save tiffany352/2b66929898526b70f8df 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
/* Copyright 2014 tiffany <tiffany@stormbit.net> | |
* Licensed under zlib/libpng | |
*/ | |
#ifndef FRP_HPP | |
#define FRP_HPP | |
#include <vector> | |
#include <functional> | |
namespace SpaceGame { | |
// http://stackoverflow.com/a/7943765 | |
template <typename T> | |
struct function_traits | |
: public function_traits<decltype(&T::operator())> | |
{}; | |
template <typename ClassType, typename ReturnType, typename... Args> | |
struct function_traits<ReturnType(ClassType::*)(Args...) const> | |
{ | |
enum { arity = sizeof...(Args) }; | |
typedef ReturnType result_type; | |
template <size_t i> | |
struct arg | |
{ | |
typedef typename std::tuple_element<i, std::tuple<Args...>>::type type; | |
}; | |
}; | |
template<typename F, typename src> | |
struct Behaviour; | |
template<typename F, typename src1, typename src2> | |
struct Behaviour2; | |
template<typename T> | |
struct Variable; | |
template<typename T> | |
struct VariableSrc { | |
VariableSrc() {} | |
VariableSrc(Variable<T>* src) : src(src) {} | |
Variable<T> *src; | |
T get() | |
{ | |
return src->get(); | |
} | |
}; | |
template<typename T> | |
class Variable { | |
T val; | |
public: | |
static VariableSrc<T> Src; | |
Variable(T v) : val(v) {} | |
T get() | |
{ | |
return val; | |
} | |
void set(T v) | |
{ | |
val = v; | |
} | |
template<typename F> | |
Behaviour<F,VariableSrc<T>> lift(F func) | |
{ | |
return Behaviour<F,VariableSrc<T>> | |
(func, | |
VariableSrc<T>(this)); | |
} | |
}; | |
template<typename T> | |
struct BehaviourSrc { | |
BehaviourSrc() = default; | |
BehaviourSrc(T (*fn)(void*), void *user) : update(fn), user(user) {} | |
template<typename F, typename src> | |
BehaviourSrc(Behaviour<F,src> *self) : update(&Behaviour<F,src>::update), user(self) {} | |
void *user; | |
T (*update)(void*); | |
T get() | |
{ | |
return update(user); | |
} | |
}; | |
template<typename F, typename src> | |
struct Behaviour { | |
typedef function_traits<F> traits; | |
typedef typename traits::result_type U; | |
Behaviour(F f, src source) : func(f), source(source) {} | |
static BehaviourSrc<U> Src; | |
F func; | |
src source; | |
U get() | |
{ | |
return func(source.get()); | |
} | |
static U update(void *ptr) | |
{ | |
Behaviour<F,src> &self = *reinterpret_cast<Behaviour<F,src>*>(ptr); | |
return self.get(); | |
} | |
template<typename F2> | |
Behaviour<F2,BehaviourSrc<U>> lift(F2 func) | |
{ | |
return Behaviour<F2,BehaviourSrc<U>> | |
(func, | |
BehaviourSrc<U>(this)); | |
} | |
}; | |
template<typename F, typename src1, typename src2> | |
struct Behaviour2 { | |
typedef function_traits<F> traits; | |
typedef typename traits::result_type U; | |
Behaviour2(F f, src1 source1, src2 source2) : func(f), source1(source1), source2(source2) {} | |
static BehaviourSrc<U> Src; | |
F func; | |
src1 source1; | |
src2 source2; | |
U get() | |
{ | |
return func(source1.get(), source2.get()); | |
} | |
static U update(void *ptr) | |
{ | |
Behaviour2<F,src1,src2> &self = *reinterpret_cast<Behaviour2<F,src1,src2>*>(ptr); | |
return self.get(); | |
} | |
template<typename F2> | |
Behaviour<F2,BehaviourSrc<U>> lift(F2 func) | |
{ | |
return Behaviour<F2,BehaviourSrc<U>> | |
(func, | |
BehaviourSrc<U>(this)); | |
} | |
}; | |
template<typename F, typename B1, typename B2> | |
Behaviour2<F,decltype(B1::Src),decltype(B2::Src)> lift2(B1 &b1, B2 &b2, F func) | |
{ | |
return Behaviour2<F,decltype(B1::Src),decltype(B2::Src)> | |
(func, | |
decltype(B1::Src)(&b1), | |
decltype(B2::Src)(&b2)); | |
} | |
} | |
#endif |
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 "frp.hpp" | |
#include <cstdio> | |
using namespace SpaceGame; | |
int main() | |
{ | |
Variable<int> test(4); | |
auto test_x_2 = test.lift([](int a) -> int {return a*2;}); | |
auto test_plus_1 = test_x_2.lift([](int a) -> int {return a+1;}); | |
auto res = lift2(test_x_2, test_plus_1, [](int a, int b) -> int {return a+b;}); | |
printf("%i\n", res.get()); // 17 | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment