Event aussetzen?

Fragen zu Grafik- & Soundproblemen und zur Spieleprogrammierung haben hier ihren Platz.
super_castle
Beiträge: 557
Registriert: 29.11.2005 15:05

Event aussetzen?

Beitrag von super_castle »

Wenn die "Procedure zeichne()" abgearbeitet wird, möchte ich keine Unterbrechung durch Purebasic, wenn zb die Maus bewegt wird usw.
Wie kann ich das Event für diesen Zeitpunkt ausschalten?

Gruss

Code: Alles auswählen

Global x.l,y.l,*DC.l,start_p.f,ende_p.f,diff_p.f,gehe.l

Define.l Event, EventWindow, EventGadget, EventType, EventMenu

Declare zeichne()

Enumeration
  #Window_0 
  #Button_0
EndEnumeration

Procedure zeichne()
  start_p = ElapsedMilliseconds()
  For gehe=0 To 12
    For y=10 To 90
      For x=200 To 232
        SetPixel_(*DC,x,y,$0000ff)
      Next
    Next
  Next
  ende_p = ElapsedMilliseconds()
  diff_p = ende_p-start_p
  Debug "Gesamtzeit: "+Str(diff_p)+" ms"
EndProcedure
  
InitSprite()
 
OpenWindow(#Window_0, 400, 150, 500,500, "Window_0", #PB_Window_SystemMenu|#PB_Window_SizeGadget|#PB_Window_MinimizeGadget|#PB_Window_TitleBar)

ButtonGadget(#Button_0, 10,10, 80, 25, "Zeichne")

Repeat
  Event = WaitWindowEvent()

  *DC = GetDC_(WindowID(#Window_0))          

  Select Event
    Case #PB_Event_Gadget
      EventGadget = EventGadget()
      EventType = EventType()
      
      If EventGadget = #Button_0  
        zeichne()
      EndIf

    Case #PB_Event_CloseWindow
      EventWindow = EventWindow()
      If EventWindow = #Window_0
        CloseWindow(#Window_0)
        Break
      EndIf
  EndSelect
  
  ReleaseDC_(WindowID(0), *DC) 
   
ForEver

Christian+
Beiträge: 213
Registriert: 13.07.2008 10:05
Computerausstattung: Windows 8.1 Pro
AMD Phenom II X4 955 @ 3.2 GHz
4GB RAM
NVIDIA GeForce GTX 660

Re: Event aussetzen?

Beitrag von Christian+ »

Der Quellcode läuft doch ohne Probleme. Die Procedure zeichne() wird doch gar nicht durch Pure Basic unterbrochen die Events aus der Zeit die die Procedure braucht werden solange gespeichert bis sie mit einem WindowEvent abgefragt werden was ist denn genau dein Problem ich verstehe das gerade irgendwie nicht das einzige was da stören kann ist doch dass wenn du die Events nichts abfragst und deine Procedere sehr sehr lange braucht Windows meint dein Programm hätte sich aufgehängt da die Events nicht verarbeitet werden aber das sollte bei Prozeduren zum nur was Zeichen nicht auftreten.
mfg Christian+
Windows 8.1 Pro 64Bit | AMD Phenom II X4 955 @ 3.2 GHz | 4GB RAM | NVIDIA GeForce GTX 660
Jilocasin
Beiträge: 665
Registriert: 13.05.2006 16:04
Kontaktdaten:

Re: Event aussetzen?

Beitrag von Jilocasin »

Wieso benutzt du für diesen ganzen Zeichenquark eigentlich API calls? Dafür gibt es doch extra die 2D-Drawing library.
Außerdem kann ich Christian+ nur zustimmen. Ausgelöste Events werden ohnehin solange gespeichert, bis mal (Wait-)WindowEvent() aufruft.

InitSprite() ist im Übrigen hierbei auch überflüssig und wird nur bei Screen- bzw. Spritebefehlen benutzt.
Bild
super_castle
Beiträge: 557
Registriert: 29.11.2005 15:05

Re: Event aussetzen?

Beitrag von super_castle »

Wenn ich während des Ablaufes die Maus hin und her bewege, steigt die Zeit an.
Auch habe ich immer wieder andere kleine Abweichungen der Zeit. Die bleibt nicht Constant.

Gruss
Jilocasin
Beiträge: 665
Registriert: 13.05.2006 16:04
Kontaktdaten:

Re: Event aussetzen?

Beitrag von Jilocasin »

super_castle hat geschrieben:Wenn ich während des Ablaufes die Maus hin und her bewege, steigt die Zeit an.
Hier nicht. Versuch mal dein "gehe" soweit zu erhöhen, dass es etwa eine Sekunde dauert (aussagekräftigere Zeitmessung).
Bild
Christian+
Beiträge: 213
Registriert: 13.07.2008 10:05
Computerausstattung: Windows 8.1 Pro
AMD Phenom II X4 955 @ 3.2 GHz
4GB RAM
NVIDIA GeForce GTX 660

Re: Event aussetzen?

Beitrag von Christian+ »

Also die Zeit Abweichungen kommen daher da der gleiche Code nicht immer gleich schnell läuft denn schließlich nutzen verschiedene Prozesse die gleiche CPU weshalb nicht immer die gleiche Rechenleistung (sofort) vorhanden ist. Außerdem hat ElapsedMilliseconds() ebenfalls eine gewisse Ungenauigkeit von mehreren Millisekunden darum sollte deine Zeichen Funktion wie schon geschrieben mindestens 1-2 Sekunden brauche um ordentlich vergleichen zu können da je kürzer die Funktion braucht desto mehr sich diese ganzen Abweichungen bemerkbar machen. Wenn ich deinen Code unverändert lasse und er nur einige Millisekunden braucht, braucht jeder Aufruf der Funktion bei mir minimal unterschiedlich lange egal ob ich die Maus bewege oder nicht so das sich da keine Aussage machen lässt ob sich was ändert wenn ich die Maus bewege und wenn liegt das aber sowieso an Windows das die Mausbewegung immer verarbeiten muss was zeitlich aber eigentlich völlig unbedeutend sein sollte.
Windows 8.1 Pro 64Bit | AMD Phenom II X4 955 @ 3.2 GHz | 4GB RAM | NVIDIA GeForce GTX 660
super_castle
Beiträge: 557
Registriert: 29.11.2005 15:05

Re: Event aussetzen?

Beitrag von super_castle »

Die "While ys => 0" soll solange angehalten werden, bist die Zeit "pixelz" verstrichen ist.
Aber irgendwie ist jetzt eine starke Bremse drin.
Das Pixelsetzen geht damit jetzt ganz langsam.

Ohne dieses :

gehe:
zeite=ElapsedMilliseconds()
If (zeite-zeita) < pixelz
Goto gehe
EndIf

geht es viel zu schnell, die Zeit wird also stark unterboten (ist auch gut so), mit meiner Zeitbremse tritt nicht das erhoffte ein.

Geht diese Zeitbremse nicht?



Code: Alles auswählen

Global zeita.d,zeite.d,pixelz.d

pixelz = 1.0 / 32000.0

............
.............

While ys => 0
      zeita= ElapsedMilliseconds()
      
      lauf=lauf+1
      If lauf => datlaenge
        Goto ende
      EndIf
      ys=ys-1
      farbe=PeekB(*datspeicher+lauf)
      SetPixel_(*DC,xd+xs,yd+ys,RGB(farbe,farbe,farbe))
      
      gehe:
      zeite=ElapsedMilliseconds()
      If (zeite-zeita) < pixelz
        Goto gehe
      EndIf  
    Wend
Jilocasin
Beiträge: 665
Registriert: 13.05.2006 16:04
Kontaktdaten:

Re: Event aussetzen?

Beitrag von Jilocasin »

Okay ich muss zugeben, ich habe keinen blassen Schimmer, was du versuchst zu erreichen :freak:
Wie auch immer. Wenn du versuchst die Operationen immer in einem festgelegten Zeitrahmen auszuführen, kannst du es so machen:

Code: Alles auswählen

Global zeita.d,zeite.d,pixelz.d

pixelz = 32000

.............

zeit = ElapsedMilliseconds()

While Abs(ElapsedMilliseconds() - zeit) < pixelz
  lauf = lauf + 1
  If lauf => datlaenge
    Break
  EndIf
  
  ys = ys - 1
  farbe = PeekB(*datspeicher + lauf)
  SetPixel_(*DC, xd + xs, yd + ys, RGB(farbe, farbe, farbe))
Wend
Im Allgemeinen sollte man die Verwendung von Goto absolut vermeiden, es sei denn es ist aus Performancegründen unbedingt notwendig. Dann aber auch nur mit ausreichender Assemblerkenntnis benutzen, was Stack angeht usw.
Ansonsten schleichen sich sehr gerne kleine Fehler ein, die man entweder erst gar nicht merkt, oder sich erst irgendwann scheinbar zufällig bemerkbar machen. :D
Bild
super_castle
Beiträge: 557
Registriert: 29.11.2005 15:05

Re: Event aussetzen?

Beitrag von super_castle »

Oben habe ich "zeita".
Unten "zeite".

Wenn nach dem Pixelsetzen die pixelz noch nicht verstrichen ist, muss ich es abremsen, dann erst kann der nächste y-Pixel gesetzt werden.
Jilocasin
Beiträge: 665
Registriert: 13.05.2006 16:04
Kontaktdaten:

Re: Event aussetzen?

Beitrag von Jilocasin »

Ahh jetzt versteh ichs. Naja, du hast für die Wartezeit 1/32000 Sekunde genommen, was für ElapsedMilliseconds() schon mal keinen Sinn macht, da das nur in Abständen von Millisekunden (ach na sowas?) arbeitet.

Wenn du es tatsächlich auf diese Weise machen musst, gibt es noch genauere Zeitmessungen (wohl hier im Forum unter HighResTimer zu finden), die ich aber hierfür nicht empfehlen würde.

Der folgende Code sollte zwar funktionieren, ist aber ziemlich hässlich, da er die komplette, verfügbare Prozessorleistung frisst.
Ich habe mal versucht mich bei deiner.. Namensgebung zu orientieren.

Code: Alles auswählen

Define.f pixelz, TotalTime
Define.q frequenz, zeita, zeite

pixelz = 1.0 / 32000.0

If QueryPerformanceFrequency_(@frequenz)
  While ys => 0
    QueryPerformanceCounter_(@zeita)
    
    lauf = lauf + 1
    If lauf => datlaenge
      Break
    EndIf
    ys = ys - 1
    farbe = PeekB(*datspeicher + lauf)
    SetPixel_(*DC, xd + xs, yd + ys, RGB(farbe, farbe, farbe))
    
    QueryPerformanceCounter_(@zeite)
    TotalTime = (zeite - zeita) / frequenz
    
    While TotalTime < pixelz
      QueryPerformanceCounter_(@zeite)
      TotalTime = (zeite - zeita) / frequenz
    Wend
    
    Debug "Geschätzt " + StrD(1 / (pixelz * pixelz) * TotalTime, 4) + " pro Sekunde"
  Wend
Else
  Debug "Ups.. leider keinen high-resolution performance counter gefunden"
EndIf
Bild
Antworten