Lua Wait/Sleep functionality and Bmax Delay

BlitzMax Forums/BlitzMax Programming/Lua Wait/Sleep functionality and Bmax Delay

juankprada(Posted 2013) [#1]
I am trying to integrate Lua into my Bmax engine. So far I am able to call Lua functions from Bmax and viceverse. I can show messages on screen and move the camera and the player from the scripts.

So my problem is with the implementation of a Wait/Sleep command that will actually delay the execution of the next Lua line.

the problem I have is that I found out that Lua doesnt have such functionallity and I can only think about calling a Bmax function that will execute a Delay(n). The problem with that approach is that it will actually delay my Engine execution so if for example I do this in my Lua script:




The ShowMessage (the way is implemented in my engine) will actually add a message to a FIFO Queue and not draw anything on screen until the next game loop, only then, the update method of the engine will iterate over this message queue and show the first message in line.

So if I set that Wait(2000) right after the showMessage line, the "Message 1" will actually be shown after 2000 millisecs have passed, which is not the desired effect.

For clarity. The desired effect should be as follow:

1. "Message 1" is shown on screen
2. 2 seconds delayd before...
3. "Message 2" is shown on screen

Do you guys have any idea on how to make this work the way it should?

Thank you


GW(Posted 2013) [#2]
you should fully flesh out your event pump to handle any kind of command and make the problem trivial.

pseudo code
 --lua
 addevent(SHOWMESSAGE,"Message 1")
 addevent(PAUSE,2000)
 addevent(SHOWMESSAGE,"Message 2")



juankprada(Posted 2013) [#3]
I'm not sure If what I understood is what you really meant.

So I should handle all events as a Queue? and in the update method of the engine, call each one in order (one after the previous one has finished) right?


GW(Posted 2013) [#4]
I'm suggesting that your message queue should also handle commands[events].
An event would contain a type(showmessage, pause, move enemy etc), and any relevant data needed to handle the event.
a 'showmessage' event would need to hold the string to show, a 'pause' event would need to contain the length to pause, etc

more pseudo code:
EventQueue:TList

Type Event
	Field typ%
	Field dataI:Int[4]		'// hold integer data
	Field dataF:Float[4]	'// hold float data
	Field dataS:String[4]	'// hold string data
End Type

Function handle_events()
	'// grab the top event
	Local e:event = Event(EventQueue.First())
	Select e.typ
		Case SHOWMESSAGE
			Print(e.dataS[0])
			EventQueue.removeFirst()
			Return
			
		Case PAUSE
			If gametimer > e.dataI[0] Then
				EventQueue.removeFirst()		'// done with pausing
				Return
			Else
				'// do nothing. This event is still on top	
			EndIf
		Case MOVEENEMY
			Local nme = GetEnemy(e.datai[0])
			nme.x :+ e.dataF[0]
			nme.y :+ e.dataF[1]
			
	End Select		
End Function

Function CreateEvent_ShowMessage(msg:String)
	Local e:Event = New Event
	e.typ = SHOWMESSAGE
	e.dataS[0] = msg
	EventQueue.addlast(e)
End Function


Function CreateEvent_Pause(pausetime%)
	Local e:Event = New Event
	e.typ = PAUSE
	e.dataI[0] = gametimer + pausetime
	EventQueue.addlast(e)
End Function

Function CreateEvent_MoveEnemy(EnemyID%, X#,Y#)
	Local e:Event = New Event
	e.typ = MOVEENEMY
	e.dataI[0] = EnemyID
	e.dataF[0] = X
	e.dataF[1] = Y
	EventQueue.addlast(e)
End Function

The create_event functions could be called from lua. the handle_events function would be called every frame of your game internally.


Derron(Posted 2013) [#5]
Although I did not want to answer to your question (your prior one - with a big pot of my source code - was left unanswered to you, so I moved you imaginary to the group of "only taker").

Instead of a full-blown-event-system - which makes things more harder to code (not really "dynamically" adding functions and handlers to lua by just exposing them...).

While not give the "ShowMessage" a Delay?
So the BlitzMax-Function is
Function ShowMessage(msg, delay)

Another option is to wrap your commands in a Delay-Function. Within BlitzMax that Delay-Function then is the only one needed being connected to an EventSystem.
So insteat of using a expandable-system like GW's suggestion you use your normal EventQueue (many have them for easier connection between ingameGUI and logic, - I use it for nearly everything not "directly commanded").

These EventQueue just has to recognize delays - or given Executiontimestamps.

Using reflection you can delay nearly every function your engine provides (and you can integrate your lua exposing ...so lua cannot call everything :D).


Suggestion: If you do not intent to have further situations of delaying things: Just add the delay param to ShowMessage, that function has a "showMessages"-stack connected with timers...


Now to the WHY: Why does your do,sleep,do not work in lua
Imagine that the lua script gets called by your engine... and then the engine is waiting for the script to end. Now that end is delayed by "sleep" so the script's execution just takes "sleep"-time longer.
It is no "run and forget" - else you won't have to call certain lua functions during updateloops (or update events or ...).


bye
Ron


juankprada(Posted 2013) [#6]
Thanks for your answers. Both of you have given me enough to keep on with the development. Although I think I need to think a little bit harder on the Events system to adjust it to the rest of the engine.