Timer Callback... wie gehts?

Für allgemeine Fragen zur Programmierung mit PureBasic.
Benutzeravatar
edel
Beiträge: 3667
Registriert: 28.07.2005 12:39
Computerausstattung: GameBoy
Kontaktdaten:

Beitrag von edel »

hab heute morgen auch mal was geschrieben , bin dann nur eingeschlafen.

Code: Alles auswählen



#USER_TIMER_MINIMUM = 10

Global Color.l

Procedure CCOlOR(hwnd,uMsg,idEvent,dwTime)
  Color = Random($FFFFFF)
EndProcedure

Procedure CText2(hwnd,uMsg,idEvent,dwTime)
  Static dir1.l, dir0.l
  Static x.l
  Static y.l
  
  If dir1 : x - 1         : Else    : x + 1 : EndIf 
  If x > 700 : dir1.l = 1 : ElseIf    x < 0 :  dir1 = 0 : EndIf 
  If dir0 : y - 1         : Else    : y + 1 : EndIf 
  If y > 580 : dir0 = 1   : ElseIf    y < 0 : dir0 = 0 : EndIf
  
  StartDrawing(ScreenOutput())
  DrawingMode(4)
  DrawText(x,y,"TimerID = " + Str(idEvent),$0000FF,Color)
  StopDrawing()
  
EndProcedure

Procedure CText1(hwnd,uMsg,idEvent,dwTime)
  Static dir1.l = 1, dir0.l
  Static x.l = 300
  Static y.l = 430
  
  If dir1 : x - 1         : Else    : x + 1 : EndIf 
  If x > 700 : dir1.l = 1 : ElseIf    x < 0 :  dir1 = 0 : EndIf 
  If dir0 : y - 1         : Else    : y + 1 : EndIf 
  If y > 580 : dir0 = 1   : ElseIf    y < 0 : dir0 = 0 : EndIf
  
  StartDrawing(ScreenOutput()) 
  DrawText(x,y,"TimerID = " + Str(idEvent),$FFFFFF,Color)
  StopDrawing()
  
EndProcedure

InitSprite()
InitKeyboard()

OpenScreen(800,600,32,"")

t1 = SetTimer_(0,0,#USER_TIMER_MINIMUM,@CText1())
t2 = SetTimer_(0,0,#USER_TIMER_MINIMUM,@CText2())
t3 = SetTimer_(0,0,1000,@CCOlOR())

Repeat
  ExamineKeyboard() 
  ClearScreen(Color) 

  FlipBuffers() 
Until KeyboardReleased(#PB_Key_Escape)

killtimer_(0,t1)
killtimer_(0,t2)
killtimer_(0,t3)

Code: Alles auswählen

InitSprite()

#timerid = 0

hwnd = OpenWindow(0,0,0,200,200,"")
OpenWindowedScreen(hwnd,0,0,200,200,0,0,0)

SetTimer_(hwnd,#timerid,200,0)

Repeat
  event = WaitWindowEvent(30) 
  
  If event = #WM_TIMER 
    Color = Random($FFFFFF)
  EndIf
  
  ClearScreen(Color)
  FlipBuffers() 
  
Until event = #WM_CLOSE 
  
killtimer_(hwnd,#timerid)
Das mit dem 'return 0' ist natuerlich Bloedsinn, das was Windows
erwartet steht auf MSDN bei den Events unter 'Return Value' .
Benutzeravatar
inc.
Beiträge: 348
Registriert: 27.10.2004 12:25

Beitrag von inc. »

Ich hatte auch mal mit jenen hWindow basierten Timer rumexperementiert um framegenau Videos abzuspielen. Resultat war/ist, dass wenn man mit der Maus die Fenstertitelleiste festhält, der Timer für eine gewisse Zeit stoppt (1/2 Sek ca.).

Die (für mich erst gefundene) Lösung war der Windows MultimediaTimer (für anderes als Video bestimmt auch gut nutzbar):
http://msdn.microsoft.com/library/defau ... timers.asp

Viell. triffts nicht exact dieses Topic hier, aber ist bestimmt einen Blick wert.
Diese Timer haben eine eigene Callback Prozedur und sind unabhängig vom Fenster.
Hier gibts die OOP Option für PureBasic.
Benutzeravatar
mk-soft
Beiträge: 3846
Registriert: 24.11.2004 13:12
Wohnort: Germany

Beitrag von mk-soft »

Unter 250ms ist das Programm bei mir nicht Taktgenau

Celeron 1800MHz

Code: Alles auswählen

; VOID CALLBACK TimerProc(
; 
;     HWND  hwnd,	// handle of window For timer messages 
;     UINT  uMsg,	// WM_TIMER message
;     UINT  idEvent,	// timer identifier
;     DWORD  dwTime 	// current system time
 
Procedure TimerProc(hwnd, uMsg, idEvent, dwTime)

  Debug Str(dwTime)
  Delay(50)
  ProcedureReturn 0
EndProcedure


If OpenWindow(0,0,0,400,300, "Timer")

  idEvent = SetTimer_(WindowID(0), 1, 250, @TimerProc())
  Debug idEvent
  Repeat
    event = WaitWindowEvent()
  Until event = #PB_Event_CloseWindow
  
  KillTimer_(WindowID(0), idEvent)

EndIf
FF :wink:
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

>> Unter 250ms ist das Programm bei mir nicht Taktgenau
Wie denn auch, bei Delay(50) :freak:
abgesehen vom Debugger.
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
mk-soft
Beiträge: 3846
Registriert: 24.11.2004 13:12
Wohnort: Germany

Beitrag von mk-soft »

@ts-soft
auch ohne delay und ohne debugger wird es nicht besser.
Wie gesagt. Windows ist kein Echtzeitbetriebssystem.

FF :wink:
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Benutzeravatar
MVXA
Beiträge: 3823
Registriert: 11.09.2004 00:45
Wohnort: Bremen, Deutschland
Kontaktdaten:

Beitrag von MVXA »

Wenn man auf hohe Prozessor auslastungen steht, könnte ich hier mit
einer Delay Procedure helfen, die den Quarz Timer im PC nutzt, um
möglichst genaue Wartezeiten zu erreichen.
Bild
Benutzeravatar
nco2k
Beiträge: 892
Registriert: 08.09.2004 23:13

Beitrag von nco2k »

@mk-soft
GetTickCount_() und Sleep_() sind zu ungenau, da braucht man sich auch nicht wundern. deswegen benützt man timeBeginPeriod_(1) um dem ganzen, etwas entgegenwirken zu können.

oder man verwendet gleich QueryPerformanceCounter_(). afaik gibt es nichts genaueres, damit liegst du im nanosekunden bereich und kannst es leicht auf millisekunden hochrechnen. :wink:

timeGetTime_() in verbindung mit timeBeginPeriod_(1) ist aber für die meisten aufgaben mehr als ausreichend. um einiges besser als der GetTickCount_() schrott.

eine sehr nützliche infopage zum thema: http://www.geisswerks.com/ryan/FAQS/timing.html

c ya,
nco2k
~|__/
..o.o.. <--- This is Einkaufswagen. Copy Einkaufswagen into your signature to help him on his way to world domination.
Antworten