From 190014a3e5b0eb5c22ddeec2135cd9458a6b8f5e Mon Sep 17 00:00:00 2001 From: ValKmjolnir Date: Mon, 23 May 2022 20:23:20 +0800 Subject: [PATCH] :bug: fix bug that gc cannot mark values in coroutine & add maketimer_sim.nas update props_sim.nas update auto_crash.nas --- nasal_gc.h | 18 ++++----- test/auto_crash.nas | 20 ++++++++-- test/calc.nas | 1 + test/maketimer_sim.nas | 87 ++++++++++++++++++++++++++++++++++++++++++ test/md5compare.nas | 1 + test/props_sim.nas | 41 +++++++++----------- test/snake.nas | 18 ++++++--- 7 files changed, 147 insertions(+), 39 deletions(-) create mode 100644 test/maketimer_sim.nas diff --git a/nasal_gc.h b/nasal_gc.h index 3e84c31..4746d8d 100644 --- a/nasal_gc.h +++ b/nasal_gc.h @@ -514,15 +514,15 @@ void nasal_gc::mark() { std::queue bfs; - // this make sure values on main stack can be scanned - if(!coroutine) - { - for(nasal_ref* i=stack;i<=top;++i) - bfs.push(*i); - bfs.push(funcr); - bfs.push(upvalr); - } - else + // scan coroutine process stack when coroutine ptr is not null + // scan main process stack when coroutine ptr is null + // this scan process must execute because when running coroutine, + // the nasal_co related to it will not update it's context until the coroutine suspends or exits. + for(nasal_ref* i=stack;i<=top;++i) + bfs.push(*i); + bfs.push(funcr); + bfs.push(upvalr); + if(coroutine) // scan main process stack { for(nasal_ref* i=main_ctx.stack;i<=main_ctx.top;++i) bfs.push(*i); diff --git a/test/auto_crash.nas b/test/auto_crash.nas index 9f08195..545c13c 100644 --- a/test/auto_crash.nas +++ b/test/auto_crash.nas @@ -1,5 +1,7 @@ # Road check and auto pilot by ValKmjolnir -import("test/props_sim.nas"); +import("./test/maketimer_sim.nas"); +import("./test/props_sim.nas"); + var dt=0.01; var intergral=0; var derivative=0; @@ -67,6 +69,12 @@ var road_check_func = func(){ props.getNode("/", 1).setValue("/controls/flight/rudder",Kp*error*error+Ki*intergral+Kd*derivative); else props.getNode("/", 1).setValue("/controls/flight/rudder",0); + + # for simulation test, in fg these three lines are deleted + println(" rudder :",props.getNode("/controls/flight/rudder",1).getValue()); + println(" dt :",dt,'\tintergral :',intergral,'\tderivative :',derivative); + println(" prev-err :",previous_error,'\terror :',error); + previous_error=error; } }; @@ -77,11 +85,17 @@ var toggle_auto_pilot = func(){ { intergral=0; road_check_timer.start(); - props.getNode("/sim/messages/copilot",1).setValue("ze dong sheng teaan see tong yee tse yung. Auto Sheng Teaan System Activated!"); + props.getNode("/sim/messages/copilot",1).setValue('/',"ze dong sheng teaan see tong yee tse yung. Auto Sheng Teaan System Activated!"); } else { road_check_timer.stop(); - props.getNode("/sim/messages/copilot",1).setValue("ze dong sheng teaan see tong yee guan bee. Auto Sheng Teaan System is off."); + props.getNode("/sim/messages/copilot",1).setValue('/',"ze dong sheng teaan see tong yee guan bee. Auto Sheng Teaan System is off."); } } + +# this is used to simulate the running process in fg +# when using in fg, delete these lines below +toggle_auto_pilot(); +road_check_timer.restart(1); +simulation(); \ No newline at end of file diff --git a/test/calc.nas b/test/calc.nas index 4156d4b..86a1d1a 100644 --- a/test/calc.nas +++ b/test/calc.nas @@ -48,6 +48,7 @@ var testfile=[ "test/lexer.nas ", "test/life.nas ", "test/loop.nas ", + "test/maketimer_sim.nas", "test/mandel.nas ", "test/mandelbrot.nas ", "test/md5.nas ", diff --git a/test/maketimer_sim.nas b/test/maketimer_sim.nas new file mode 100644 index 0000000..a843905 --- /dev/null +++ b/test/maketimer_sim.nas @@ -0,0 +1,87 @@ + +var process=nil; +var task={}; +var event={}; + +var add_event=func(name,interval,function){ + event[name]=coroutine.create(func{ + unix.sleep(interval); + println("[event] ",name); + function(); + }); +} + +var add_task=func(name,interval,function){ + + task[name]=coroutine.create(func{ + while(1){ + unix.sleep(interval); + println("[task] ",name); + function(); + coroutine.yield(); + } + }); +} + +var remove_task=func(name){ + if(contains(task,name)) + delete(task,name); +} + +var remove_event=func(name){ + if(contains(event,name)) + delete(event,name); +} + +var maketimer=func(interval,function){ + var name="nasal-timer-"; + var res={ + start:func{ + if(me.isRunning) + return; + me.isRunning=1; + if(me.singleShot){ + add_event(name,interval,function); + }else{ + add_task(name,interval,function); + } + }, + stop:func{ + if(me.isRunning){ + remove_task(name); + me.isRunning=0; + } + }, + restart:func(itv){ + interval=itv; + me.stop(); + me.start(); + }, + singleShot:0, + isRunning:0, + simulatedTime:0 + }; + name~=id(res); + return res; +} + +var simulation=func(){ + var running=1; + while(running){ + running=0; + foreach(var i;keys(task)){ + if(coroutine.resume(task[i])!=nil){ + running=1; + }else{ + remove_task(i); + } + } + foreach(var i;keys(event)){ + if(coroutine.resume(event[i])!=nil){ + running=1; + }else{ + remove_event(i); + } + } + } +} diff --git a/test/md5compare.nas b/test/md5compare.nas index 9d69efa..1db3841 100644 --- a/test/md5compare.nas +++ b/test/md5compare.nas @@ -79,6 +79,7 @@ var filechecksum=func(){ "./test/lexer.nas ", "./test/life.nas ", "./test/loop.nas ", + "./test/maketimer_sim.nas", "./test/mandel.nas ", "./test/mandelbrot.nas ", "./test/md5.nas ", diff --git a/test/props_sim.nas b/test/props_sim.nas index d804899..29b9d41 100644 --- a/test/props_sim.nas +++ b/test/props_sim.nas @@ -1,25 +1,7 @@ var geodinfo=func(lat,lon){ - return {}; -} -var maketimer=func(interval,function){ - return { - isRunning:0, - start:func(){ - me.isRunning=1; - while(1){ - unix.sleep(interval); - function(); - } - }, - stop:func(){ - me.isRunning=0; - }, - restart:func(interval){ - - }, - singleShot:0, - simulatedTime:0 - }; + return [nil,{ + names:["Road","Freeway"] + }]; } var props= @@ -175,5 +157,20 @@ props.getNode('/test/in',0).setValue('/','true'); props.getNode('/test/in',1).setValue('/','false'); props.getNode('/test/in',2).setValue('/','welcome aboard,need help? use help->tutorial'); props.getNode('/test/in',3).setValue('/',2147483648); + +props.getNode("/sim",1).addChild("messages"); +props.getNode("/sim/messages",1).addChild("copilot"); +props.getNode("/position",1).addChild("latitude-deg"); +props.getNode("/position",1).addChild("longitude-deg"); +props.getNode("/orientation",1).addChild("heading-deg"); +props.getNode("/controls",1).addChild("flight"); +props.getNode("/controls/flight",1).addChild("rudder"); + +props.getNode("/sim/messages/copilot",1).setValue('/',"nothing"); +props.getNode("/position/latitude-deg",1).setValue('/',90); +props.getNode("/position/longitude-deg",1).setValue('/',90); +props.getNode("/orientation/heading-deg",1).setValue('/',90); +props.getNode("/controls/flight/rudder",1).setValue('/',0.114); props.globals.debug(); -println(props.getNode('/test/in',3).getPath()); \ No newline at end of file + +println("-----------------------------------"); diff --git a/test/snake.nas b/test/snake.nas index a925e6b..266f114 100644 --- a/test/snake.nas +++ b/test/snake.nas @@ -165,8 +165,7 @@ var game=func(x,y){ gameover=2; }, move:func(c){ - if(c=='w' or c=='a' or c=='s' or c=='d') - move=c; + move=c; }, gameover:func(){ return gameover; @@ -174,6 +173,15 @@ var game=func(x,y){ } } +var co=coroutine.create(func(){ + var t=maketimestamp(); + while(1){ + t.stamp(); + while(t.elapsedMSec()<20); + coroutine.yield(); + } +}); + var main=func(){ if(os.platform()=="windows") system("chcp 65001"); @@ -184,7 +192,7 @@ var main=func(){ print("\rpress any key to start..."); libkey.getch(); print("\r \r"); - var counter=12; + var counter=20; while(1){ var ch=libkey.nonblock(); if(ch!=nil){ @@ -197,15 +205,15 @@ var main=func(){ } g.move(chr(ch)); } - unix.sleep(0.02); counter-=1; - if(counter==0){ + if(!counter){ counter=20; g.next(); if(g.gameover()) break; g.print(); } + coroutine.resume(co); } println(g.gameover()<=1?"game over.":"you win!");