I'm pretty new to lua coding. In my intro page I want to load a different image every 0,5 second while a background music is playing. Here is my code (non working):
function carica_indice()
im=math.random(1,4)
schermataMenu=display.newImage(immagine[im],W,H)
volte=volte+1
end
function menuprincipale()
media.playSound( "sigla1.mp3" )
immagine={"firstscreen.png","firstscreen1.png","firstscreen2.png","firstscreen3.png","firstscreen4.png","firstscreen5.png"}
schermataMenuGroup=display.newGroup()
while volte<32 do
schermataMenu=display.newImage(immagine[im],W,H)
timer.performWithDelay(500,carica_indice())
end
end
timer.performWithDelay(500,carica_indice())
here you are actually calling the function by using those parentheses.
Pass the function as an argument like this:
timer.performWithDelay(500, carica_indice)
timers don't actually stop your code from executing so the while loop will continue to add a lot of timers before the first 32 would fire.
I'm guessing volte is some sort of limit? for that you can ask the timer to repeat a number of iterations instead of the while loop like this:
changeBkg = timer.performWithDelay(500, carica_indice, 32)
you can cancel the timers now, when the user hits play by:
timer.cancel(changeBkg)
Related
Note: This is a copy of a question asked here
Hi
I am completely new to EPS8266 and Lua (but not to programming - my first CPU was an 8080...)
Using a nodemcu HUZZA from adafruit
Anyway I am testing some timer stuff and running into this:
tmr.alarm(0, 500, 1, function()
print("I'm here")
tmr.stop(0)
end)
Without the stop, the loop keeps printing, with it the tmr.stop(0) stops. ... so far so good.
But if I want to start the timer again like:
tmr.alarm(0, 500, 1, function()
print("I'm here")
tmr.stop(0)
-- do some stuff
tmr.start(0)
end)
I get an error: PANIC: unprotected error in call to Lua API...
The documentation says that the tmr is still registered when stop is called.
A call to tmr.state(0) does the same. Only tmr.stop(0) seems to works as expected.
Thanks for your thoughts.
The documentation says to no longer use static timers
Static timers are deprecated and will be removed later. Use the OO API initiated with tmr.create().
If you want complete control over when the functions in the timer callback are executed you need a ALARM_SEMI instance upon which you call start whenever needed. It'll fire exactly once for every time you call start on it.
local mytimer = tmr.create()
mytimer:register(500, tmr.ALARM_SEMI, function() print("I'm here") end)
-- do stuff here
-- then whenever needed trigger the timer
mytimer:start()
Note that mytimer is not unregistered and not garbage collected.
Based on the documentation, you need to use tmr.ALARM_SEMI as your alarm mode.
ALARM_SEMI is described by the documentation as:
tmr.ALARM_SEMI manually repeating alarm (call tmr.start() to
restart)
tmr.ALARM_SEMI is equal to 2. Based on that, this should work:
tmr.alarm(0, 500, 2, function()
print("I'm here")
tmr.stop(0)
-- do some stuff
tmr.start(0)
end)
So like i have mainloop and many other functions but i cant call them because of there is infinitive loop how can i make them so i can call the functions.
local socket = require("socket")
local function sleep(sec)
socket.select(nil, nil, sec)
end
coroutine.wrap(function()
while true do
sleep(1)
end
end)()
print("bob") -- like here
like in code it doesn't print bob because there is loop is way avoid that i tried using corountines but they didnt work
Normally I would suggest using non-blocking commands, but I'm not certain what socket.select is doing. It appears you are misusing it as a blocking timer.
ok, Im almost completely new to lua and computercraft but I have alot of creativity. I'm trying to write code that will reprint a variable every second. here is what I have so far:
display = "Loading..."
While true do
sleep(1)
term.clear()
term.setCursorPos(1,1)
print (display)
end
sleep(3)
display = "hello"
I want to use it to render a 2d game, the "display" variable would change often and thus why i want it to be updated every second.
It does indeed refresh every second when I run the code but for some reason I cant seem to get the "display" variable to change after 3 seconds to test it.
What am I doing wrong?
while true is an infinite loop. The script never reaches sleep(3).
Perhaps you want to replace while true with for i=1,3.
I am not experienced in Lua, but this might be a solution: answer on SO
In the UI thread, run:
while ((status=lua_resume(L_coroutine, 0)) == LUA_YIELD) {
semaphore_wait(); /* whatever the appropriate C# call is */
}
"Wait for response" should look something like:
while not results[my_result] do
coroutine.yield()
end
The "incoming message" function should look like the following in Lua:
results[cur_result]=parsed_message
I'm trying to create a while true do loop, that reacts to clicks, using os.pullEvent, and also updates a monitor.
Problem being, it only updates the screen when I press one of the on screen buttons, and I've found out that's because pullEvent stops the script, until an event is fired.
Is it possible to make it so pullEvent doesn't stop me updating the monitor?
function getClick()
event,side,x,y = os.pullEvent("monitor_touch")
button.checkxy(x,y)
end
local tmp = 0;
while true do
button.label(2, 2, "Test "..tmp)
button.screen()
tmp++
getClick()
end
You can easily use the parallel api to run both codes essentially at the same time. How it works is it runs them in sequence until it hits something that uses os.pullEvent and then swaps over and does the other side, and if both stop at something that does os.pullEvent then it keeps swapping between until one yields and continues from there.
local function getClick()
local event,side,x,y = os.pullEvent("monitor_touch")
buttoncheckxy(x,y)
end
local tmp = 0
local function makeButtons()
while true do
button.label(2,2,"Test "..tmp)
button.screen()
tmp++
sleep(0)
end
end
parallel.waitForAny(getClick,makeButtons)
Now if you notice, first thing, I've made your while loop into a function and added a sleep inside it, so that it yields and allows the program to swap. At the end you see parallel.waitForAny() which runs the two functions that are specified and when one of them finishes, which in this case whenever you click on a button, then it ends. Notice however inside the arguments that I'm not calling the functions, I'm just passing them.
I don't have computercraft handy right now or look up the functions but i know that you can use the function os.startTimer(t) that will cause an event in t seconds (I think it is seconds)
usage:
update_rate = 1
local _timer = os.startTimer(update_rate)
while true do
local event = os.pullEvent()
if event == _timer then
--updte_screen()
_timer = os.startTimer(update_rate)
elseif event == --some oter events you want to take action for
--action()
end
end
note: the code is not tested and I didn't use computercraft in quite a while so pleas correct me if i did a mistake.
I have a problem which i suppose must be very common and most of you would have faced it.
I have written a program in lua, say main.lua which on receiving key event should modify the coordinates and display the geometry figure.
This lua code calls reg.c, where it kind of registers.
Now in reg.c i have a function engine which receives the key pressed and passes it to the lua function responsible for key handling.
But by the time key event comes, lua code is done with the registration and exits, thus the call from engine() becomes illegal memory access leading to segmentation fault.
Also i suppose we can't have lua call hanging in reg function, and call engine function from somewhere else.
Then what should be the solution, please guide me through this.
#jacob: here is the prototype of what i am trying to achieve:
function key_handler() //this function will get the latest key pressed from some other function
{
draw.image();
draw.geometry();
...
...
while(1)
{
//draw Points until some condition goes wrong
}
}
Now, once entered into key_handler, while he is busy drawing the points unless and until the failing condition occurs, i am unable to receive key pressed till that time.
I hope this explanation is much simpler and have made my point, and will help others to understand the problem.
I am really sorry, but i am not good at expressing or making others understand.
One more thing, i ahve followed the C syntax to explain, however this is completely implemented in lua
Your code snippet is still largely non-informative (ideally one should be able to just run your code in a stock Lua interpreter and see your problem). If you're describing a Lua problem, use Lua code to describe it.
However I'm beginning to see where you want to go.
The thing you need to could do is have a coroutine that's called in your key handler, which passes an argument back to your handler:
function isContinue() --just to simulate whatever function you use getting keypresses.
-- in whatever framework you're using there will probably be a function key_pressed or the like.
print('Initialize checking function')
while true do
print('Continue looping?')
local ans = io.read():match('[yY]')
local action
if not ans then
print('Do what instead?')
action = io.read()
if action:match('kill') then -- abort keychecker.
break
end
end
coroutine.yield(ans,action)
end
print('finalizing isContinue')
return nil,'STOP' -- important to tell key_handler to quit too, else it'll be calling a dead coroutine.
end
function key_handler()
local coro = coroutine.create(isContinue)
local stat,cont,action
while true do
print'Draw point'
stat,cont,action = coroutine.resume(coro)
if not stat then
print('Coroutine errored:',cont)
elseif not cont then
print('isContinue interrupted keyhandler')
print("We'll "..action.." instead.")
break
end
end
print('finalizing key_handler')
end
key_handler()
-- type something containing y or Y to continue, all else aborts.
-- when aborting, you get asked what to do instead of continuing,
--- with "kill" being a special case.
This should be self explanatory. You should probably take a good look at Programming in Lua, chapter 9: Coroutines.
The big difficulty (well, if you're not accustomed to collaborative threading) is that a coroutine should yield itself: it's not the calling function that's in charge of returning control.
Hope this helps you.