Seite 1 von 3

Timer Callback... wie gehts?

Verfasst: 07.09.2006 04:26
von Kaeru Gaman
Hi Leute,

ich hab noch nie mit Callbacks gearbeitet, wird wohl langsam zeit.

ich würde gern ne Game-aktualisierungs-schleife in nen timer-callback packen,
um ihn von der grafik schleife, die sich nach der framerate richtet, unabhängig zu machen.
(windowed-screen, also win-oberfläche)

könntet ihr mir n kurzes code-snippet posten, wie so ein call back mindestens aussehen muss?

und ich hab noch fragen....

- ist der timer genau genug, um die routine alle 20 oder sogar nur 10 ms aufzurufen?
- läuft der parallel oder ausschließlich? also, muss ich mittels flag sicherstellen,
dass nur eine instanz der callback-routine zur zeit laufen kann,
oder ist das grundsätzlich ausgeschlossen?

danke im voraus.

Verfasst: 07.09.2006 08:51
von #NULL

Verfasst: 07.09.2006 09:28
von AND51
Danke! Dank dem Turoial habe ich Callbacks weitestgehend verstanden.
Aber wie der eine schon fragte: Warum soll das abarbeiten der Events in einem Callback besser sein?

Ah, genau: Vieleicht, weil man mit Hilfe von Callbacks die Hauptschleife überflüssig machen kann, wärehnd man den restlichen Code, der hinter den Knöpfen, Hebeln, und Slidern steckt auch in Proceduren verbannt? OK. Aber was soll dann daran besser sein, die Performanz?

Verfasst: 07.09.2006 09:38
von nco2k
@#Null
Hroudtwolf hat geschrieben:"Der Rückgabewert #PB_ProcessPureBasicEvents sollte nur zurückgegeben werden wenn kein Ereignis vom Callback verarbeitet wurde.
Nachdem ein Ereignis vom Callback verarbeitet wurde sollte stets ProcedureReturn 0 zurückgegeben werden."
bitte wie?

wenn ich ProcedureReturn 0 verwende, verhindere ich ja damit (sofern es windows erlaubt) dass die message überhaupt vom system verarbeitet wird:

Code: Alles auswählen

Procedure WndProc(hWnd, uMsg, wParam, lParam)
  If uMsg = #WM_SYSKEYDOWN And wParam = #VK_MENU
    ;ProcedureReturn 0
  EndIf
  ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure

If OpenWindow(0, 0, 0, 200, 200, "Test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  SetWindowCallback(@WndProc())
  While WaitWindowEvent() <> #PB_Event_CloseWindow : Wend
EndIf : End
1.) drücke die linke alt taste
2.) lasse die linke alt taste los
3.) drücke die pfeiltaste unten

du wirst sehen, dass das sysmenu aufpopt, wenn du aber ProcedureReturn 0 auskommentierst, wird das nicht mehr gehen. die alt taste wurde dann praktisch nie gedrückt.

@Kaeru Gaman
hilft dir dieses beispiel von ts-soft weiter?

Code: Alles auswählen

If OpenWindow(0, #PB_Ignore, 0, 200, 200, "Test")

  SetTimer_(WindowID(0), 0, 5000, 0)
  
  Repeat
    Select WaitWindowEvent()
      
      Case #PB_Event_CloseWindow
        Break
        
      Case #WM_TIMER
        Debug "Schon wieder 5 Sekunden um"
    
    EndSelect
  ForEver
EndIf

KillTimer_(WindowID(0), 0)
edit: in den callback verpackt:

Code: Alles auswählen

Procedure WndProc(hWnd, uMsg, wParam, lParam)
  If uMsg = #WM_TIMER
    Debug "Schon wieder 2 Sekunden um"
  EndIf
  ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure

If OpenWindow(0, 0, 0, 200, 200, "Test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  SetWindowCallback(@WndProc())
  SetTimer_(WindowID(0), 0, 2000, 0)
  While WaitWindowEvent() <> #PB_Event_CloseWindow : Wend
EndIf : End
c ya,
nco2k

Verfasst: 07.09.2006 12:41
von Kaeru Gaman
@nco2k

danke für dein mini-beispiel.

jetzt fehler noch die antworten auf meine zusatzfragen:
wie siehts mit dem timing und möglichen überschneidungen aus.


btw:
wolfs artikel hättest du dort kritisieren können, wo es hingehört: in der lounge selber.
ich finde das nicht sehr gelungen, das hier zu machen.

Verfasst: 07.09.2006 13:01
von Kiffi
<OT>
Kaeru Gaman hat geschrieben:wolfs artikel hättest du dort kritisieren können, wo es hingehört: in der lounge selber.
ich finde das nicht sehr gelungen, das hier zu machen.
ohne jetzt hier wieder eine endlose Diskussion lostreten zu wollen möchte ich
dennoch anmerken, dass auch in der Lounge Kritik an Produkten von
Board'lern geübt wurde / wird (im speziellen Fall: Meine MSXML-Lib sei zu
kompliziert), ohne dass Du mit einem ähnlichen Kommentar darauf reagiert
hast.

</OT>

Grüße ... Kiffi

Verfasst: 07.09.2006 13:06
von Kaeru Gaman
> ohne jetzt hier wieder eine endlose Diskussion lostreten zu wollen

schwierig


> ohne dass Du mit einem ähnlichen Kommentar darauf reagiert
hast.

hab ich garnicht gesehen.

aber: deine Lib ist eine Lib, und kein tutorial in einem thread.

Verfasst: 07.09.2006 13:14
von Kiffi
Kaeru Gaman hat geschrieben:hab ich garnicht gesehen.
ist Dir wahrscheinlich entfallen. Du hast Dich an diesem Thread beteiligt.
Kaeru Gaman hat geschrieben:aber: deine Lib ist eine Lib, und kein tutorial in einem thread.
das sehe ich in Hinsicht auf den Ort, wo die Kritik ausgeübt werden soll, als
irrelevant an.

Egal: Ist ja auch OK, dass Du nco2k drauf hinweist, dass seine Kritik in der
Lounge besser aufgehoben ist. Wäre aber auch nett, wenn Du in der Lounge
genauso umgekehrt verfahren würdest. :allright:

Grüße ... Kiffi

Verfasst: 07.09.2006 13:17
von Kaeru Gaman
> Wäre aber auch nett, wenn Du in der Lounge genauso umgekehrt verfahren würdest.

ich werde mich bemühen.
schließlich hast du recht mit diesem hinweis. :wink:


Send(#BACK_TO_TOPIC)

wie ist das nun mit einem Timer-Callback alle 10 oder 20 millisekunden?

Verfasst: 07.09.2006 14:41
von Kaeru Gaman
durch #NULL auf den Lounge-thread hingewiesen hab ich auch dort gefragt.
ich hoffe, dass wird nicht zusehr als "parallelfrage" angesehen.

inzwischen sind meine fragen beantwortet, endgültig auch durch einen kleinen test meinerseits:

http://www.purebasic-lounge.de/viewtopi ... 7894#37894

Code: Alles auswählen

Global Timer_Active.l

Procedure WndProc(hWnd, uMsg, wParam, lParam) 
  If uMsg = #WM_TIMER 
    If Timer_Active = 0
      Timer_Active = 1

      Debug "** timer-call execution started"
      Delay(1000)
      Debug "** timer-call execution ended"
      
      Timer_Active = 0
    Else
      Debug "timer-call blocked"
    EndIf
  EndIf 
  ProcedureReturn #PB_ProcessPureBasicEvents 
EndProcedure 

If OpenWindow(0, 0, 0, 200, 200, "Test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) 

  SetWindowCallback(@WndProc()) 
  SetTimer_(WindowID(0), 0, 200, 0) 

  While WaitWindowEvent() <> #PB_Event_CloseWindow : Wend 
EndIf

End
die meldung "timer-call blocked" erscheint nie, somit wird eine callback-routine nur einmal zur zeit aufgerufen.