I want to show a message every 5 secounds, but how?
EDIT: I found it out:
Code: Select all
Dim As Integer laserding
Do
If buttons=1 And laserding<=Timer-1 Then
laserding=Timer
End If
Loop
Code: Select all
Dim As Integer laserding
Do
If buttons=1 And laserding<=Timer-1 Then
laserding=Timer
End If
Loop
Code: Select all
' align timing at a 5 second multiple to see delay in fractional part
Dim As Double next_time = 5 * Int(Timer / 5)
Do ' this is your main loop
' do what you want here
If Timer > next_time Then ' test if times up
next_time += 5 ' schedule next message in 5 seconds
Print "Message time is"; Timer, " Next at "; next_time
End If
Sleep 10 ' release time to the system
Loop Until Inkey <> "" ' press any key to exit
Code: Select all
Dim Shared terminate As Integer = 0
Sub mythread (Byval param As Any Ptr)
' align timing at a 5 second multiple to see delay in fractional part
Dim As Double next_time = 5 * Int(Timer / 5)
Do
If Timer > next_time Then ' test if times up
next_time += 5 ' schedule next message in 5 seconds
Print "Message time is"; Timer, " Next at "; next_time
End If
Sleep 100 ' release time to the system
Loop Until terminate = 1
End Sub
Dim thread As Any Ptr
thread = ThreadCreate(@mythread, 0)
sleep 60000 ' wait 1 minute or press any key to exit
terminate=1
ThreadWait (thread)
Code: Select all
SUB mythread (BYVAL param AS ANY PTR)
' align timing at a 5 second multiple to see delay in fractional part
VAR next_time = TIMER
WHILE *CAST(INTEGER PTR, param)
IF TIMER > next_time THEN ' test if times up
next_time += 5 ' schedule next message in 5 seconds
PRINT "Message time is"; TIMER, " Next at "; next_time
END IF
SLEEP 100 ' release time to the system
WEND
END SUB
' ***** main *****
VAR thread_run = 1
VAR thread = THREADCREATE(@mythread, @thread_run)
SLEEP 60000 ' wait 1 minute or press any key to exit
thread_run = 0
THREADWAIT(thread)
Code: Select all
SUB mythread (BYVAL param AS ANY PTR)
VAR next_time = CAST(DOUBLE PTR, param)
DO
IF TIMER > *next_time THEN ' test if times up
*next_time += 5 ' schedule next message in 5 seconds
PRINT "Message time is"; TIMER, " Next at "; *next_time
END IF
SLEEP 100 ' release time to the system
LOOP UNTIL *next_time = 0
END SUB
' ***** main *****
VAR thread_time = TIMER
VAR thread = THREADCREATE(@mythread, @thread_time)
SLEEP 60000 ' wait 1 minute or press any key to exit
thread_time = 0
THREADWAIT(thread)
Code: Select all
Dim As Double msgtimer = Timer
Do
If( (Timer - msgtimer) >= 5) Then
Print "hello!"
msgtimer = Timer
End If
Sleep 10
Loop Until InKey = Chr(27)
This is risky!fxm wrote:But let's purist to the end:
- delete the comment that is no more appropriate
- output the next time value and not its pointer.Code: Select all
SUB mythread (BYVAL param AS ANY PTR) VAR next_time = CAST(DOUBLE PTR, param) DO IF TIMER > *next_time THEN ' test if times up *next_time += 5 ' schedule next message in 5 seconds PRINT "Message time is"; TIMER, " Next at "; *next_time END IF SLEEP 100 ' release time to the system LOOP UNTIL *next_time = 0 END SUB ' ***** main ***** VAR thread_time = TIMER VAR thread = THREADCREATE(@mythread, @thread_time) SLEEP 60000 ' wait 1 minute or press any key to exit thread_time = 0 THREADWAIT(thread)
Code: Select all
Dim As Double msgtimer = Timer
Do
If( (Timer - msgtimer) >= 5) Then
Print "hello!", Timer
msgtimer = Timer ' slips due to response latency
End If
Sleep 10
Loop Until Inkey = Chr(27)
Code: Select all
Dim As Double msgtimer = Timer
Do
If( (Timer - msgtimer) >= 5) Then
Print "hello!", Timer
msgtimer = msgtimer + 5 ' avoids latency slip
End If
Sleep 10
Loop Until Inkey = Chr(27)
Code: Select all
' modified to reduce cyclic variation of latency
Dim As Double next_time = 5 * Int(Timer / 5)
Do ' this is your main loop
' do what you want here
If Timer > next_time Then ' test if time is up
next_time += 5 ' schedule next message in 5 seconds
Print "Message time is"; Timer, " Next at "; next_time
End If
If (next_time - Timer) > .012 Then Sleep 10 ' release time to the system
Loop Until Inkey <> "" ' press any key to exit
I also thought the general case of passing a pointer as a parameter untyped (ANY) and then applying the right cast.TJF wrote:This is risky!
The linesand
- *next_time += 5
may get executed at the same time, or better saying it starts with the first line, executes the second and goes back again to the first. In this case the thread won't stop.
- thread_time = 0
(As a developer you can test this 1000 times and won't find any problem. But be sure, users need just a few minutes to find this bug.)
Sorry, passing a pointer doesn't solve the problem. The linefxm wrote:I also thought the general case of passing a pointer as a parameter untyped (ANY) and then applying the right cast.TJF wrote:This is risky!
The linesand
- *next_time += 5
may get executed at the same time, or better saying it starts with the first line, executes the second and goes back again to the first. In this case the thread won't stop.
- thread_time = 0
(As a developer you can test this 1000 times and won't find any problem. But be sure, users need just a few minutes to find this bug.)
Code: Select all
TYPE UDT_thread
thread_time AS TYPEOF(TIMER)
thread_terminate AS BYTE
END TYPE
SUB mythread (BYVAL param AS ANY PTR)
VAR pt = CAST(UDT_thread PTR, param)
DO
IF TIMER > pt->thread_time THEN ' test if times up
pt->thread_time += 5 ' schedule next message in 5 seconds
PRINT "Message time is"; TIMER, " Next at "; pt->thread_time
END IF
SLEEP 100 ' release time to the system
LOOP UNTIL pt->thread_terminate = 1
END SUB
' ***** main *****
VAR thread_cmd = NEW UDT_thread(TIMER, 0)
VAR thread = THREADCREATE(@mythread, thread_cmd)
SLEEP 60000 ' wait 1 minute or press any key to exit
thread_cmd->thread_terminate = 1
THREADWAIT(thread)
DELETE(thread_cmd)
Yes, another save solution.fxm wrote:Code: Select all
TYPE UDT_thread thread_time AS TYPEOF(TIMER) thread_terminate AS BYTE END TYPE SUB mythread (BYVAL param AS ANY PTR) VAR pt = CAST(UDT_thread PTR, param) DO IF TIMER > pt->thread_time THEN ' test if times up pt->thread_time += 5 ' schedule next message in 5 seconds PRINT "Message time is"; TIMER, " Next at "; pt->thread_time END IF SLEEP 100 ' release time to the system LOOP UNTIL pt->thread_terminate = 1 END SUB ' ***** main ***** VAR thread_cmd = NEW UDT_thread Thread_cmd->thread_terminate = 0 Thread_cmd->thread_time = TIMER VAR thread = THREADCREATE(@mythread, Thread_cmd) SLEEP 60000 ' wait 1 minute or press any key to exit Thread_cmd->thread_terminate = 1 THREADWAIT(thread) DELETE(Thread_cmd)
Code: Select all
TYPE UDT_thread
AS TYPEOF(TIMER) thread_time = TIMER
AS BYTE thread_terminate = 0
END TYPE
SUB mythread (BYVAL param AS ANY PTR)
WITH *CAST(UDT_thread PTR, param)
DO
IF TIMER > .thread_time THEN ' test if times up
.thread_time += 5 ' schedule next message in 5 seconds
PRINT "Message time is"; TIMER, " Next at "; .thread_time
END IF
SLEEP 100 ' release time to the system
LOOP UNTIL .thread_terminate
END WITH
END SUB
' ***** main *****
VAR thread_cmd = NEW UDT_thread
VAR thread = THREADCREATE(@mythread, Thread_cmd)
SLEEP 60000 ' wait 1 minute or press any key to exit
Thread_cmd->thread_terminate = 1
THREADWAIT(thread)
DELETE(thread_cmd)
Code: Select all
TYPE UDT_thread
AS TYPEOF(TIMER) thread_time
AS BYTE thread_terminate
END TYPE
SUB mythread (BYVAL param AS UDT_thread PTR)
WITH *param
DO
IF TIMER > .thread_time THEN ' test if times up
.thread_time += 5 ' schedule next message in 5 seconds
PRINT "Message time is"; TIMER, " Next at "; .thread_time
END IF
SLEEP 100 ' release time to the system
LOOP UNTIL .thread_terminate
END WITH
END SUB
' ***** main *****
VAR thread_cmd = NEW UDT_thread(TIMER, 0)
VAR thread = THREADCREATE(@mythread, Thread_cmd)
SLEEP 60000 ' wait 1 minute or press any key to exit
Thread_cmd->thread_terminate = 1
THREADWAIT(thread)
DELETE(thread_cmd)
Code: Select all
TYPE Timer_Output
DECLARE CONSTRUCTOR(BYVAL S AS SINGLE)
DECLARE DESTRUCTOR()
Private:
DECLARE STATIC SUB thread_sub(BYVAL P AS ANY PTR)
AS TYPEOF(TIMER) time_ = TIMER
AS BYTE terminate = 0
AS ANY PTR thread
AS SINGLE inc
END TYPE
CONSTRUCTOR Timer_Output(BYVAL S AS SINGLE)
inc = IIF(S > 0.5, S, .5) ' less than .5 doesn't make sense
thread = THREADCREATE(@thread_sub, @THIS)
END CONSTRUCTOR
DESTRUCTOR Timer_Output()
terminate = 1
THREADWAIT(thread)
END DESTRUCTOR
SUB Timer_Output.thread_sub(BYVAL param AS ANY PTR) STATIC
WITH *CAST(Timer_Output PTR, param)
DO
IF TIMER > .time_ THEN ' test if times up
.time_ += .inc ' schedule next message
PRINT "Message time is"; TIMER, " Next at "; .time_
END IF
SLEEP 100 ' release time to the system
LOOP UNTIL .terminate
END WITH
END SUB
' ***** main *****
VAR out_thread = NEW Timer_Output(2) ' start the output, 2 sec delay
SLEEP 60000 ' wait 1 minute or press any key to exit
DELETE(out_thread) ' stop the output