Seite 1 von 2
Event aussetzen?
Verfasst: 16.08.2010 18:44
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
Re: Event aussetzen?
Verfasst: 16.08.2010 19:06
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+
Re: Event aussetzen?
Verfasst: 16.08.2010 19:14
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.
Re: Event aussetzen?
Verfasst: 16.08.2010 19:20
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
Re: Event aussetzen?
Verfasst: 16.08.2010 19:24
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).
Re: Event aussetzen?
Verfasst: 16.08.2010 19:55
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.
Re: Event aussetzen?
Verfasst: 16.08.2010 20:52
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
Re: Event aussetzen?
Verfasst: 16.08.2010 21:40
von Jilocasin
Okay ich muss zugeben, ich habe keinen blassen Schimmer, was du versuchst zu erreichen
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.

Re: Event aussetzen?
Verfasst: 16.08.2010 21:47
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.
Re: Event aussetzen?
Verfasst: 16.08.2010 22:27
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