#ifndef __PT_H__ #define __PT_H__ typedef unsigned short lc_t; #define LC_INIT(s) s = 0; // LC_INIT #define LC_RESUME(s) switch(s) { case 0: // LC_RESUME #define LC_SET(s) s = __LINE__; case __LINE__: // LC_SET line #define LC_END(s) } // LC_END struct pt { lc_t lc; }; #define PT_WAITING 0 #define PT_YIELDED 1 #define PT_EXITED 2 #define PT_ENDED 3 #define PT_INIT(pt) LC_INIT((pt)->lc) // INIT #define PT_THREAD(name_args) char name_args // THREAD #define PT_BEGIN(pt) { char PT_YIELD_FLAG = 1; LC_RESUME((pt)->lc) // BEGIN #define PT_END(pt) LC_END((pt)->lc); \ PT_YIELD_FLAG = 0; \ PT_INIT(pt); return PT_ENDED; } // END #define PT_WAIT_UNTIL(pt, condition) \ do { \ LC_SET((pt)->lc); \ if(!(condition)) { \ return PT_WAITING; \ } \ } while(0) // WAIT_UNTIL #define PT_WAIT_WHILE(pt, cond) \ PT_WAIT_UNTIL((pt), !(cond)) // WAIT_WHILE #define PT_WAIT_THREAD(pt, thread) \ PT_WAIT_WHILE((pt), PT_SCHEDULE(thread)) // WAIT_THREAD #define PT_SPAWN(pt, child, thread) \ do { \ PT_INIT((child)); \ PT_WAIT_THREAD((pt), (thread)); \ } while(0) // SPAWN #define PT_RESTART(pt) \ do { \ PT_INIT(pt); \ return PT_WAITING; \ } while(0) // RESTART #define PT_EXIT(pt) \ do { \ PT_INIT(pt); \ return PT_EXITED; \ } while(0) // EXIT #define PT_SCHEDULE(f) ((f) < PT_EXITED) // SCHEDULE #define PT_YIELD(pt) \ do { \ PT_YIELD_FLAG = 0; \ LC_SET((pt)->lc); \ if(PT_YIELD_FLAG == 0) { \ return PT_YIELDED; \ } \ } while(0) // YIELD #define PT_YIELD_UNTIL(pt, cond) \ do { \ PT_YIELD_FLAG = 0; \ LC_SET((pt)->lc); \ if((PT_YIELD_FLAG == 0) || !(cond)) { \ return PT_YIELDED; \ } \ } while(0) // YIELD_UNTIL // checked for n calls in a thread : seems OK #define PT_DELAY(pt, ms) \ do { \ static unsigned long _PTTTL_ ; \ _PTTTL_ = millis() + (unsigned int)(ms); \ PT_WAIT_UNTIL((pt), (millis() > _PTTTL_)); \ } while(0) // DELAY #define PT_SYNC(pt, mark, ms) \ do { \ PT_WAIT_UNTIL((pt), (millis() - (mark) > (ms) )); \ } while(0) // SYNC #endif /* __PT_H__ */