Seite 1 von 1

Starttimer-Funktion von PBOSL

Verfasst: 29.09.2005 17:27
von felix
Hallo,
ich benutze in meinen programm für die Abfrage einer Datenübertragung die Funktion StartTimer aus der PBOSL Lib. Ich habe bei den Codeschnippseln, nur einen teil gepostet, da es sonst zuviel würde.

Code: Alles auswählen

StartTimer(0,33000,@bilduebertragen())
In der Routine bilduebertragen, wird die Variable Counter alle 30 sekunden um den Wert 1 erhöht. Die Variable Counter habe ich zuvor als
Global definiert.

Code: Alles auswählen

Global result.b,anzbildka1.f,anzbildka2.f,anzbildka3.f,anzbildka4.f,counter.f
result.b=-99
anzbildka1.f=0
anzbildka2.f=0
anzbildka3.f=0
anzbildka4.f=0
counter.f=0

Procedure bilduebertragen()
  
  counter=counter+1
  
  ; Kamera1 übertragen und verschieben
EndProcedure
In der hauptschleife (da wo auch die Buttons und menus abgefragt werden), frage ich den Counter ab. Sobald die Variable Counter=10 ist soll was ausgeführt werden.

Code: Alles auswählen

Open_Window_0()

SetGadgetState(#CheckBox_0,1)
SetGadgetState(#CheckBox_1,1)
SetGadgetState(#CheckBox_2,0)
SetGadgetState(#CheckBox_3,0)

StartTimer(0,10000,@bilduebertragen())

Repeat
Event= WaitWindowEvent()
WindowID = EventWindowID()
GadgetID = EventGadgetID()
EventType = EventType()

If counter=10
    AddGadgetItem(#Listview_0,-1,"Counter = 10")
    ueberpruefung()
    counter=0
EndIf

Until Event = #PB_Event_CloseWindow Or quit =1
EndTimer(0)
End
jedoch wird die Abfrage nicht korrekt ausgeführt.

Entweder er zählt die Variable Counter gar nicht hoch, oder er überspringt die if abfrage einfach. Die Counter Variable stand zugar schon bei 95.

Was mache ich falsch bei der Abfrage oder ist das ein Fehler von der PBOSL oder PB ?

mfg

Stefan

Re: Starttimer funktion von PBOSL

Verfasst: 29.09.2005 17:44
von Kiffi
felix hat geschrieben:Was mache ich falsch bei der Abfrage [...]?
der Denkfehler liegt in dieser Zeile:

Code: Alles auswählen

Event= WaitWindowEvent() 
hier wird solange gewartet, bis Dein Fenster ein Ereignis bekommt
(Fenster bewegen, vergrössern/verkleinern, mit der Maus drüberfahren,
Knöpsche drücken, etc.). Wenn's also ohne Interaktion irgendwo auf
Deinem Bildschirm vor sich hingammelt, dann wird Dein Programm bis
zum Sankt Nimmerleinstag in dieser Zeile herumstehen. Aus diesem
Grund wird die If Counter - Zeile auch nur bei Fenster-Events
durchgeführt. Da kann der Counter auch schon mal bei 95 stehen, weil Du
95 mal ein Bild hochgeladen hast, aber nur einmal mit der Maus über Dein
Fenster gehuscht bist.

Kommst Du mit diesen Infos erstmal weiter?

Grüße ... Kiffi

Verfasst: 29.09.2005 20:04
von felix
danke für die Hilfe, da hätte ich auch selbst drauf kommen können, zudem ich ja noch den Text für den Thread aus dem Source kopiert habe. :oops:

Verfasst: 30.09.2005 11:15
von felix
ich habe nun das WaitWindowEvent in WindowEvent geändert und die Prgrammausführung mit Delay(1) verzögert.
Geht das so ? Den mich verwirren etwas die Threads über Delay und im "Handbuch" die Aussage das die CPU-Auslastung steigt. Ich konnte auf meinen Rechner nichts festellen das nun das Tool mehr CPU braucht, oder ist das von PC zu PC unterschiedlich ?

Verfasst: 30.09.2005 11:52
von Kiffi
felix hat geschrieben:ich habe nun das WaitWindowEvent in WindowEvent geändert und die Prgrammausführung mit Delay(1) verzögert.
Geht das so ?
jepp, das ist so richtig.

Wenn Du folgende Schleife hast:

Code: Alles auswählen

Repeat

  myEvent = WindowEvent()

  TuDies()
  TuDas()

  If myEvent
    Select myEvent
      Case ...
    EndSelect
  EndIf

Until ...
dann wird diese immer und immer wieder ausgeführt (unabhängig davon,
ob Dein Fenster ein Event bekommt oder nicht). Das hat den Vorteil, dass
[c]TuDies()[/c] und [c]TuDas()[/c] auch ausgeführt werden.

Aber!

Es hat auch den Nachteil, dass Dein Programm so gut wie alle
Prozessorzeit für sich in Anspruch nimmt. Da bleibt für die anderen
Applikationen, die evtl. parallel zu Deiner laufen, nicht mehr allzuviel
Rechenzeit übrig.

Um das zu verhindern, musst Du in die Repeat-Until-Schleife an geeigneter
Stelle ein [c]Delay(DeineDelayZeit)[/c] einbauen.

Hiermit gibt Dein Programm für die Dauer '[c]DeineDelayZeit[/c]' (Angabe
in Millisekunden) dem Prozessor Gelegenheit, sich um die anderen
Aufgaben zu kümmern.

Code: Alles auswählen

Repeat

  myEvent = WindowEvent()

  TuDies()
  TuDas()

  If myEvent
    Select myEvent
      Case ...
    EndSelect
  EndIf

  Delay(1)

Until ...
Es gibt noch eine andere Möglichkeit, Deinen Counter zu überprüfen und
gleichzeitig dabei WaitWindowEvent() zu verwenden. Das kann man mit
sogenannten Callbacks machen. Diese Technik ist aber eigentlich eher was
für fortgeschrittene Programmierer. Wenn Du Dich dem gewachsen fühlst,
dann können wir Dir sicherlich auch weiterhelfen.

Grüße ... Kiffi

Verfasst: 30.09.2005 16:27
von felix
ja das mit callbacks würde mich schon interessieren und ich denke wenns Ordentlich erklärt ist wird es auch ein PureBasic Newbie begreifen.

Im forum steht zwar einiges drüber, aber alles hab ich nicht verstanden. Wenn Du zeit hast könntest bitte mal schreiben wie das geht.

Danke.

Stefan
[/quote]

Verfasst: 30.09.2005 17:12
von ts-soft
Du könntest versuchen es so zu lösen (ohne Callback):

Code: Alles auswählen

Procedure TuDies()
  ; bla
EndProcedure

Procedure TuDas()
  ; blablah
EndProcedure

If OpenWindow(0, #CW_USEDEFAULT, #CW_USEDEFAULT, 640, 480, #PB_Window_SystemMenu, "Test")
  SetTimer_(WindowID(0), 0, 100, 0) ; Timer 0 alle 100 ms ohne Callback
  Repeat

    myEvent = WaitWindowEvent()
   Select myEvent
    Case #WM_TIMER
      TuDies()
      TuDas()
    Case ...
  EndSelect
 

  Until ... 
EndIf
KillTimer_(WindowID(0), 0)
Das Timerereignis ist so zwar nicht 100% zuverlässig, sollte aber für die meisten Dinge genügen

Verfasst: 01.10.2005 10:16
von felix
Das Timerereignis ist so zwar nicht 100% zuverlässig, sollte aber für die meisten Dinge genügen
ich habe es ausprobiert und es geht. :D
Danke für den Tipp. :allright:
Nur was meinst Du mit nicht zuverlässig ? Passen die sekunden nicht oder fällt der Timer evtl. aus?

Ich brauche für die Funktion den Timer ca. alle 30sec und da ist es egal ob er in 25sec kommt oder in 35.

Des weiteren wäre es aber trotzdem schön wenn einer von euch Profis mal die Callback Funktion beschreiben würde.

mfg
Stefan

Verfasst: 01.10.2005 14:18
von ts-soft
felix hat geschrieben:Nur was meinst Du mit nicht zuverlässig ? Passen die sekunden nicht oder fällt der Timer evtl. aus?
In der originallen PB Ereignisschleife, könnte bei hoher Auslastung schon mal ein Timerereignis verpennt werden, da diese mit niedrigerer Priorität von Windows gehändelt werden. Bei nur einem Timer sollte dies aber nicht passieren.

Wenn Du die PBOSL-Timer Funktion verwendest, mit übergabe der Adresse, ist dies bereits eine Callbackfunktion. Kannste auch den von mir geposteten Source ändern, wobei die letzte 0 durch die Proceduradresse auszutauschen ist.
Zum WindowsCallback, also dem Callback eines Hauptfensters findeste viele Beispiele im CodeArchiv.