-
-
Save OvermindDL1/e72f67f42df565a5ba9a 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
namespace detail { | |
class coroutine_ref; | |
} | |
class coroutine | |
{ | |
public: | |
coroutine() : value_(0) {} | |
bool is_child() const { return value_ < 0; } | |
bool is_parent() const { return !is_child(); } | |
bool is_complete() const { return value_ == -1; } | |
void reset() { value_ = 0; } | |
private: | |
friend class detail::coroutine_ref; | |
int value_; | |
}; | |
namespace detail { | |
class coroutine_ref | |
{ | |
public: | |
coroutine_ref(coroutine& c) : value_(c.value_), modified_(false) {} | |
coroutine_ref(coroutine* c) : value_(c->value_), modified_(false) {} | |
~coroutine_ref() { if (!modified_) value_ = -1; } | |
operator int() const { return value_; } | |
int& operator=(int v) { modified_ = true; return value_ = v; } | |
private: | |
void operator=(const coroutine_ref&); | |
int& value_; | |
bool modified_; | |
}; | |
} | |
#define CORO_REENTER(c) \ | |
switch (::detail::coroutine_ref _coro_value = c) \ | |
case -1: if (_coro_value) \ | |
{ \ | |
goto terminate_coroutine; \ | |
terminate_coroutine: \ | |
_coro_value = -1; \ | |
goto bail_out_of_coroutine; \ | |
bail_out_of_coroutine: \ | |
break; \ | |
} \ | |
else case 0: | |
#define CORO_YIELD_IMPL(n) \ | |
for (_coro_value = (n);;) \ | |
if (_coro_value == 0) \ | |
{ \ | |
case (n): ; \ | |
break; \ | |
} \ | |
else \ | |
switch (_coro_value ? 0 : 1) \ | |
for (;;) \ | |
case -1: if (_coro_value) \ | |
goto terminate_coroutine; \ | |
else for (;;) \ | |
case 1: if (_coro_value) \ | |
goto bail_out_of_coroutine; \ | |
else case 0: | |
#define CORO_FORK_IMPL(n) \ | |
for (_coro_value = -(n);; _coro_value = (n)) \ | |
if (_coro_value == (n)) \ | |
{ \ | |
case -(n): ; \ | |
break; \ | |
} \ | |
else | |
#define CORO_YIELD CORO_YIELD_IMPL(__LINE__) | |
#define CORO_FORK CORO_FORK_IMPL(__LINE__) | |
#define reenter(c) CORO_REENTER(c) | |
#define yield CORO_YIELD | |
#define fork CORO_FORK | |
const int Red = 9; | |
const int Green = 10; | |
const int Blue = 11; | |
struct colorfader : coroutine { | |
const int pin; | |
const int skip; | |
int i; | |
colorfader(int pin_, int skip_) : pin(pin_), skip(skip_) {} | |
void operator()() { reenter(this) { | |
while(true) { | |
for(i=0;i<=255;i+=skip) yield analogWrite(pin, 255-i); | |
for(i=0;i<=255;i+=skip) yield analogWrite(pin, i); | |
} | |
}} | |
}; | |
colorfader fadered(Red, 1); | |
colorfader fadegreen(Green, 2); | |
colorfader fadeblue(Blue, 3); | |
void setup(){ | |
} | |
void loop() { | |
fadered(); | |
fadegreen(); | |
fadeblue(); | |
delay(40); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment