11import std::io;
22import std::math;
3+ import std::collections::list;
34import raylib5::rl;
45import future;
56
@@ -36,7 +37,7 @@ fn any! Lerp.poll(&self, any env) @dynamic {
3637}
3738
3839fn Future lerp (float * place , float a , float b , float duration ) {
39- return @tclone (Lerp {
40+ return @clone (Lerp {
4041 .place = place ,
4142 .a = a ,
4243 .b = b ,
@@ -60,7 +61,7 @@ fn any! Parallel.poll(&urmom, any env) @dynamic {
6061}
6162
6263fn Future parallel (Future [] futures ) {
63- return @tclone (Parallel {
64+ return @clone (Parallel {
6465 .futures = futures ,
6566 });
6667}
@@ -82,33 +83,97 @@ fn any! Seq.poll(&urmom, any env) @dynamic {
8283}
8384
8485fn Future seq (Future [] futures ) {
85- return @tclone (Seq {
86+ return @clone (Seq {
8687 .futures = futures ,
8788 });
8889}
8990
91+ struct Patcher {
92+ List (<usz * >) lerp ;
93+ List (<usz * >) par ;
94+ List (<usz * >) seq ;
95+ }
96+
97+ macro @fut_type_ptr (Future * x )
98+ {
99+ usz * y = (usz * ) x ;
100+ return y + 1 ;
101+ }
102+
103+ fn void Patcher .add (& urmom , Future * f ) {
104+ switch (f .type ) {
105+ case Lerp .typeid :
106+ urmom .lerp .push (@fut_type_ptr (f ));
107+ case Parallel .typeid :
108+ urmom .par .push (@fut_type_ptr (f ));
109+ case Seq .typeid :
110+ urmom .seq .push (@fut_type_ptr (f ));
111+ default :
112+ unreachable (" unexpected type " );
113+ }
114+ }
115+
116+ macro @list_patch (list , $Type ) {
117+ for (usz i = 0 ; i < list .len (); i ++ ) {
118+ * list [i ] = (usz ) $Type .typeid ;
119+ Future * f = (Future * ) (list [i ] - 1 );
120+ $Type * ft = anycast (* f , $Type )!! ; // Some dirty trickery
121+ (void )ft ;
122+ }
123+ }
124+
125+ fn void Patcher .patch (& urmom ) {
126+ io::printfn (" Patching futures " );
127+ @list_patch (urmom .lerp , Lerp );
128+ @list_patch (urmom .par , Parallel );
129+ @list_patch (urmom .seq , Seq );
130+ }
131+
132+ fn void Patcher .clear (& urmom ) {
133+ urmom .lerp .clear ();
134+ urmom .par .clear ();
135+ urmom .seq .clear ();
136+ }
137+
90138struct State {
91139 float t1 , t2 ;
92140 bool finished ;
93141 Future anim ;
142+ Patcher patcher ;
94143}
95144
96145State * state = null ;
97146
98147fn void reset_anim ()
99148{
100- // TODO: clean up allocator::temp() here
101- state .anim = parallel (@tclone (Future [* ] {
102- // TODO: Tuck the whole @tclone(Future[*]{ ... }) under the future constructors
149+ // TODO: clean up allocator::heap() here
150+ // Leaky-leaky
151+ state .anim = parallel (@clone (Future [* ] {
152+ // TODO: Tuck the whole @clone(Future[*]{ ... }) under the future constructors
103153 // See if variadic args can be applied here
104- seq (@tclone (Future [* ] {
154+ seq (@clone (Future [* ] {
105155 lerp (& state .t1 , 0 , 1 , CYCLE_DURATION ),
106156 lerp (& state .t1 , 1 , 0 , CYCLE_DURATION / 4 ),
107157 })),
108- seq (@tclone (Future [* ] {
158+ seq (@clone (Future [* ] {
109159 lerp (& state .t2 , 0 , 1 , CYCLE_DURATION + CYCLE_DURATION / 4 ),
110160 }))
111161 }));
162+
163+ state .patcher .clear ();
164+
165+ // TODO: reflection to do this automatically or something
166+ // Maybe Future.traverse(fn void FutureTraverseFn(void *env, Future *f))?
167+
168+ state .patcher .add (& state .anim );
169+ Parallel * p = anycast (state .anim , Parallel )!! ;
170+ foreach (& s : p .futures ) {
171+ state .patcher .add (s );
172+ Seq * s1 = anycast (* s , Seq )!! ;
173+ foreach (& l : s1 .futures ) {
174+ state .patcher .add (l );
175+ }
176+ }
112177}
113178
114179fn void plug_init () @export (" plug_init " )
@@ -125,6 +190,8 @@ fn void* plug_pre_reload() @export("plug_pre_reload")
125190fn void plug_post_reload (void * old_state ) @export (" plug_post_reload " )
126191{
127192 state = old_state ;
193+
194+ state .patcher .patch ();
128195}
129196
130197fn void orbit_circle (Env env , float t , float radius , float orbit , Color color )
0 commit comments