Starttimer-Funktion von PBOSL

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
felix
Beiträge: 32
Registriert: 24.10.2004 07:56
Wohnort: Giengen/Brenz
Kontaktdaten:

Starttimer-Funktion von PBOSL

Beitrag 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
Benutzeravatar
Kiffi
Beiträge: 10714
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Re: Starttimer funktion von PBOSL

Beitrag 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
a²+b²=mc²
Benutzeravatar
felix
Beiträge: 32
Registriert: 24.10.2004 07:56
Wohnort: Giengen/Brenz
Kontaktdaten:

Beitrag 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:
Benutzeravatar
felix
Beiträge: 32
Registriert: 24.10.2004 07:56
Wohnort: Giengen/Brenz
Kontaktdaten:

Beitrag 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 ?
Benutzeravatar
Kiffi
Beiträge: 10714
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Beitrag 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
a²+b²=mc²
Benutzeravatar
felix
Beiträge: 32
Registriert: 24.10.2004 07:56
Wohnort: Giengen/Brenz
Kontaktdaten:

Beitrag 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]
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 »

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
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
felix
Beiträge: 32
Registriert: 24.10.2004 07:56
Wohnort: Giengen/Brenz
Kontaktdaten:

Beitrag 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
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 »

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.
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
Antworten