In der Gui Timer mit Millisecs-Aufruf?
Übersicht BlitzMax, BlitzMax NG Allgemein
funkheldBetreff: In der Gui Timer mit Millisecs-Aufruf? |
Fr, März 16, 2018 11:32 Antworten mit Zitat |
|
---|---|---|
Hallo, guten Tag.
Ich habe eine Gui , wo 2 Funktionen regelmäßig mit einem Timer "erstertimer " und "zweitertimer"aufgerufen werden. Gibt es für die Gui bitte eine andere Möglichkeit? Wenn ja, welche bitte. Danke. Gruss Code: [AUSKLAPPEN] Local ersterTimer:Int = MilliSecs() Local ZweiterTimer:Int = MilliSecs() CreateTimer(60) While WaitEvent() If MilliSecs() - erstertimer >= 300 Then erstertimer = MilliSecs() fnSend("d,0") EndIf If MilliSecs() - ZweiterTimer >= 50 Then ZweiterTimer = MilliSecs() fnRecv() EndIf Select EventID() Case EVENT_GADGETSELECT Case EVENT_GADGETACTION Select EventSource() Case stage fnSend("stage,0") Case slidertv sdelta=EventData() sdelta=sdelta/10 fnSend("throttle,"+Int(sdelta)+"."+Int((sdelta-Int(sdelta)) * 10.0)) Case killer SetGadgetText text_g, "" text="" Case text_send countLines= TextAreaLen(text_g,TEXTAREA_LINES) For i = 0 To countLines line = TextAreaText(text_g, i, 1, TEXTAREA_LINES) fnSend(line) Delay(50) Next End Select Case EVENT_TIMERTICK Case EVENT_GADGETPAINT Flip Case EVENT_MOUSEDOWN Case EVENT_MOUSEMOVE Case EVENT_MOUSEUP Case EVENT_WINDOWCLOSE End End Select Wend Function fnSend(MSG:String) cliSocket.Send(MSG, Len(MSG)) End Function Function fnRecv() If(cliSocket.ReadAvail() = 0) Return strTmp = "" While(cliSocket.ReadAvail() > 0) fnFlushBuf(bufData, bufSize) anzahl=cliSocket.Recv(bufData, bufSize) strTmp:+String.FromCString(bufData) Local Einzeln$[]=strtmp.Split(":") SetGadgetText( str_alti,Einzeln$[1] ) SetGadgetText( str_apoa,Einzeln$[2] ) SetGadgetText( str_peri,Einzeln$[3] ) SetGadgetText( str_velo,Einzeln$[4] ) Wend End Function |
||
Mathias-Kwiatkowski |
Fr, März 16, 2018 11:39 Antworten mit Zitat |
|
---|---|---|
ich frage mich warum du da überhaupt ein timer anwendest
wahrscheinlich wegen den zeit leeks Code: [AUSKLAPPEN] Function UpdateTCP:Object(data:Object)
Client:TServer = TServer(data) If Client Then Repeat 'hier TCP_NODELAY entfang und senden rein Delay 1 Forever EndIf End Function Local ServerTCP:TTCPStream Global TCP:TThread = CreateThread(UpdateTCP, ServerTCP) stell bm auf multithread um und pack senden und empfangen in einer funktion. dann kannst du eine lsite machen wo ankommende nachrichten sind bitte bedenke das immer wenn auf die liste zugegriffen wird ( hinzufügen oder entfernen) gelockt werden muss. Code: [AUSKLAPPEN] Global ClientMutex:TMutex = CreateMutex()
LockMutex ClientMutex list.addlast a:String UnlockMutex ClientMutex du greifst einmal in deinem "haupt programm" auf die liste zu um nachrichten abzufangen und einaml im updatetcp thread "zweites programm" ... daher locken wenn etwas in liste rein kommt oder raus genomm wird. schon brauchst du kein timer und hast keine leeks. mit erstes und zweites programm ist im programm die deiferenzierung von threads gemeint. |
||
Skype: Anarchie1984
http://projektworks.de/maxbase/ Icq - Erneuert am 21.08.2017 Yahoo - Erneuert am 21.08.2017 |
funkheld |
Fr, März 16, 2018 12:10 Antworten mit Zitat |
|
---|---|---|
Danke für die Info.
Habe ich aber nicht ganz verstanden. Es soll nur alle 300ms gesendet werden. Das empfangen wird wohl besser sein wie du es beschrieben hast. Danke. Gruss |
||
Mathias-Kwiatkowski |
Fr, März 16, 2018 12:59 Antworten mit Zitat |
|
---|---|---|
dann bau im 2. thread ein delay 300 anstelle eine 1 an wenn du kein timer nehmen willst, wüsste aber nich aus welchem grund du kein timmer willst... | ||
Skype: Anarchie1984
http://projektworks.de/maxbase/ Icq - Erneuert am 21.08.2017 Yahoo - Erneuert am 21.08.2017 |
funkheld |
Fr, März 16, 2018 14:32 Antworten mit Zitat |
|
---|---|---|
Ich dachte das meine beiden Timer in irgendeiner Weise das Event-Window-System in der Schleife durcheinander würfeln. Wenn dem so nicht ist, lasse ich die beiden Timer drin.
Wie und wann wird eigentlich dieses aufgerufen in der Schleife: Case EVENT_TIMERTICK fnRecv() -------------------------------------------------------- Timer ticked. Event source contains timer object ??? --------------------------------------------------------- Funktionieren tut es auch. Hat das damit zu tun : CreateTimer(60) ? Code: [AUSKLAPPEN] Strict Import MaxGUI.Drivers Include "utils.bmx" Global text:String,text1:String,line:String Global x1:Int,x2:Int,x3:Int,x4:Int,x5:Int Global countLines:Int,i:Int,anzahl:Int Global sdelta:Float Local remotePort = 5000 Local remoteIp = HostIp("127.0.0.1") Global cliSocket:TSocket = CreateTCPSocket() ConnectSocket(cliSocket, remoteIp, remotePort) Global bufSize = 1024 Global bufData:Byte[] = New Byte[bufSize] Global strTmp:String Global Window:TGadget=CreateWindow("krpc",20,20,400,500) Global stage:TGadget=CreateButton("stage",10,10,60,25,Window) Global killer:TGadget=CreateButton("cls",220,200,60,25,Window) Global text_send:TGadget=CreateButton("senden",220,230,60,25,Window) Global b_plus:TGadget=CreateButton("thr+",80,10,35,25,Window) Global b_minus:TGadget=CreateButton("trt-",80,40,35,25,Window) Global str_throttle:TGadget =CreateTextField(120,10,30,22,window) Global text_g:TGadget = CreateTextArea( 10, 200, 200,200, window ) Global str_alti:TGadget =CreateTextField(210,10,120,22,window) Global str_apoa:TGadget =CreateTextField(210,40,120,22,window) Global str_peri:TGadget =CreateTextField(210,70,120,22,window) Global str_velo:TGadget =CreateTextField(210,100,120,22,window) ActivateGadget str_alti ActivateGadget str_apoa ActivateGadget str_peri ActivateGadget str_velo Local ersterTimer:Int = MilliSecs() sdelta=0.0 SetGadgetText( str_throttle,Int(sdelta)+"."+Int((sdelta-Int(sdelta)) * 10.0) ) CreateTimer(60) While WaitEvent() If MilliSecs() - erstertimer >= 200 Then erstertimer = MilliSecs() fnSend("d,0") EndIf Select EventID() Case EVENT_GADGETSELECT Case EVENT_GADGETACTION Select EventSource() Case stage fnSend("stage,0") Case b_plus sdelta=sdelta+0.1 If sdelta > 1.0 Then sdelta=1.0 fnSend("throttle,"+sdelta) SetGadgetText( str_throttle,Int(sdelta)+"."+Int((sdelta-Int(sdelta)) * 10.0) ) Delay(100) Case b_minus sdelta=sdelta-0.1 If sdelta < 0.0 Then sdelta=0.0 fnSend("throttle,"+sdelta) SetGadgetText( str_throttle,Int(sdelta)+"."+Int((sdelta-Int(sdelta)) * 10.0) ) Delay(100) Case killer SetGadgetText text_g, "" text="" Case text_send countLines= TextAreaLen(text_g,TEXTAREA_LINES) For i = 0 To countLines line = TextAreaText(text_g, i, 1, TEXTAREA_LINES) fnSend(line) Delay(50) Next End Select Case EVENT_TIMERTICK fnRecv() Local Einzeln$[]=strtmp.Split(":") SetGadgetText( str_alti,Einzeln$[1] ) SetGadgetText( str_apoa,Einzeln$[2] ) SetGadgetText( str_peri,Einzeln$[3] ) SetGadgetText( str_velo,Einzeln$[4] ) Case EVENT_GADGETPAINT Flip Case EVENT_MOUSEDOWN Case EVENT_MOUSEMOVE Case EVENT_MOUSEUP Case EVENT_WINDOWCLOSE End Case EVENT_APPTERMINATE End End Select Wend Function fnSend(MSG:String) cliSocket.Send(MSG, Len(MSG)) End Function Function fnRecv() If(cliSocket.ReadAvail() = 0) Return strTmp = "" While(cliSocket.ReadAvail() > 0) fnFlushBuf(bufData, bufSize) anzahl=cliSocket.Recv(bufData, bufSize) strTmp:+String.FromCString(bufData) Wend End Function Danke. Gruss |
||
Mathias-Kwiatkowski |
Fr, März 16, 2018 15:37 Antworten mit Zitat |
|
---|---|---|
Zitat: Ich dachte das meine beiden Timer in irgendeiner Weise das Event-Window-System in der Schleife durcheinander würfeln. Wenn dem so nicht ist, lasse ich die beiden Timer drin.
dem ist auch so, würde ich denken man kann ja das senden alle 300 ms verzögern das abfragen aber ausserhalb packen also if millisecs()timer=>300 then sende endif so das als senden, und das impfanken, läuft ja eig so ab das du erst mal schaust gibts auf dem port daten wenn ja lese sie aus, daher würde ich dafür kein timer setzen. macht auch kein sinn eigentlich und nun zu deiner gui frage... ich bau meine gui so auf Code: [AUSKLAPPEN] CreateTimer(60)
Local Timer:Int = MilliSecs() Repeat Local TmpGadget:TGadget 'Hier kommt der andere komplette code rein If Timer >= XXX Then Timer=MilliSecs() 'Mach das was nach X sek gemacht werden soll End If Select WaitEvent() Case EVENT_GADGETSELECT tmpGadget = TGadget(EventSource()) 'Nur GUI Case EVENT_GADGETACTION tmpGadget = TGadget(EventSource()) 'Nur GUI Case EVENT_TIMERTICK 'Nur Canvas der gui redrawen lasen Case EVENT_GADGETPAINT tmpGadget = TGadget(EventSource()) 'Nur GUI canvas draw Case EVENT_MOUSEDOWN tmpGadget = TGadget(EventSource()) 'Nur GUI mouse down wenn kein eneablepolled gesetzt Case EVENT_MOUSEMOVE tmpGadget = TGadget(EventSource()) 'Nur GUI mouse canvas move wenn kein polled gesetzt Case EVENT_MOUSEUP 'Nur GUI mouse up (not Press) wenn kein polled gesetzt Case EVENT_WINDOWCLOSE tmpGadget = TGadget(EventSource()) 'Nur GUI Case EVENT_MENUACTION TmpGadget = TGadget(EventSource()) 'nur gui End Select Forever ich glaube das wenn du createtimer(60) angibst das Case EVENT_TIMERTICK 60 mal in einer sekunde aufgerufen wird (wenn möglich ) da ich da redraw canvas mache gibt dies die fps meines canvas her. |
||
Skype: Anarchie1984
http://projektworks.de/maxbase/ Icq - Erneuert am 21.08.2017 Yahoo - Erneuert am 21.08.2017 |
funkheld |
Fr, März 16, 2018 17:59 Antworten mit Zitat |
|
---|---|---|
Danke für die Antwort.
Was bedeutet das bitte in der Case und ist das Notwendig ? TmpGadget = TGadget(EventSource()) Gruss |
||
Mathias-Kwiatkowski |
Fr, März 16, 2018 18:46 Antworten mit Zitat |
|
---|---|---|
also case wird mit select angewand
z.b. Code: [AUSKLAPPEN] Local A:Int=2
Select A Case 1 Print "1" Case 2 Print "2" End Select Ergebniss wäre das du eine 2 ausgegeben wirst, select ersetzt halt IF wenn du so willst... Code: [AUSKLAPPEN] Local TmpGadget:TGadget
ist die declaration Code: [AUSKLAPPEN] Case EVENT_WINDOWCLOSE
tmpGadget = TGadget(EventSource()) hier könnte ich nun abfragen auf welchem fenster das X symbol angewand wurde (du kannst ja mehrere gui fenster erstellen und jedes anders behandeln.) nun könnte ich abfragen Code: [AUSKLAPPEN] If tmpGadget = DasErstellteFenster Then End
hier hast du ein bsp Code: [AUSKLAPPEN] SuperStrict
Import maxgui.drivers CreateTimer(60) Local Win1:TGadget = CreateWindow("Fenster 1", 0, 0, 200, 200, Desktop(), WINDOW_TITLEBAR) Local Win2:TGadget = CreateWindow("Fenster 2", 100, 100, 200, 200, Desktop(), WINDOW_TITLEBAR) Repeat Local TmpGadget:TGadget Select WaitEvent() Case EVENT_WINDOWCLOSE TmpGadget = TGadget(EventSource()) If TmpGadget = Win1 Then End If TmpGadget = Win2 Then FreeGadget Win2 End Select Forever |
||
Skype: Anarchie1984
http://projektworks.de/maxbase/ Icq - Erneuert am 21.08.2017 Yahoo - Erneuert am 21.08.2017 |
funkheld |
Fr, März 16, 2018 18:58 Antworten mit Zitat |
|
---|---|---|
Danke , habe ich jetzt verstanden.
Gruss |
||
Midimaster |
Sa, März 17, 2018 10:40 Antworten mit Zitat |
|
---|---|---|
Also, wenn ihr eine MaxGui basierte App schreiben wollt, sollte sie eigentlich ohne klassische Repeat/Forever-Scheife realisiert werden.
Das Fenster wird vorab mit Menüs, Symbolleisten, etc gebaut (MDI). Anschließend wird die Kontrolle komplett an das Betriebssystem abgegeben und nur noch wenn Events auftauchen die eigene App gerufen. Damit der eigene Screen (Canvas) immer wieder mal gemalt wird wird der EVENT_TIMERTICK mit einem CreateTimer() aktiviert. In der TimerTickt() wird dann die Canvas gemalt und auch rhythmische Aufgaben wie Millisecs()-Timer abgearbeitet. Hier mal eine Programmstart, wie er bei mir immer abläuft: BlitzMax: [AUSKLAPPEN]
Ich habe mal mit Brucey über das Thema gesprochen und der macht die Hauptschleife nochmal ganz anders. Das sieht dann fast schon so aus wie bei einer Monkey-App. BlitzMax: [AUSKLAPPEN] CreateTimer 120 |
||
Gewinner des BCC #53 mit "Gitarrist vs Fussballer" http://www.midimaster.de/downl...ssball.exe |
Mathias-Kwiatkowski |
Sa, März 17, 2018 13:05 Antworten mit Zitat |
|
---|---|---|
es ist völlig legitim repeat / forever zu nutzen, wenn man z.b. keine reine gui oberfläche programmiert
Code: [AUSKLAPPEN] Repeat
Local TmpGadget:TGadget Select WaitEvent() Case EVENT_WINDOWCLOSE TmpGadget = TGadget(EventSource()) If TmpGadget = Win1 Then End If TmpGadget = Win2 Then FreeGadget Win2 End Select Forever funktioniert 1a es gibt auch keine speicher leeks oder sonstiges, habe so zahlreiche dinge schon realisiert. z.b. chat , editor für meine spiele ect. so wie es Brucey macht habe ich es auch schon einigemale gemacht aber es gab nun kein vorteil bzw nachteil. (abgesehen davon sollte es für funkheld übersichtlich sein, das er es nachvolziehen kann) ich habe einfach kleine examples für funkheld erstellt um ihn die befehle zu zeigen bzw zu erklärren was sie tun, ich weiß ja nich was er programmieren will. aber einiges erschient ein wenig kurrios. z.b. send oder empfangstimer ect, das sind so dinge die ich anders angehe als er, das habe ich letzendes auch beschrieben, auch die gui sortierung er wusste ja nich was select ist oder für was es steht. EVENT_TIMERTICK - CreateTimer() habe ich ihm ebenfalls erklärrt. oder stimmt meine aussage hingegen dessen nicht? wie gesagt ich weiß nicht was funkheld dort programmiert. |
||
Skype: Anarchie1984
http://projektworks.de/maxbase/ Icq - Erneuert am 21.08.2017 Yahoo - Erneuert am 21.08.2017 |
Midimaster |
Sa, März 17, 2018 15:18 Antworten mit Zitat |
|
---|---|---|
nein-nein... alles gut so.
ich wollte Funkheld nur eine reine, vollständige GUI Startup liefern. Von der aus kann man praktisch jedes Projekt beginnen. Für die Millisecs()-Geschichten genügt es zeitlich, sie in der TimerTickt()-Funktion zu verwalten. Der kommt ja i.d.R alle 16msec Ohne Repeat/Forever wird die eigene App halt wirklich nur noch im EVENT-Fall gerufen oder eben alle 16msec wegen des EVENT_TIMER. Das Brucey-Modell war nicht für Funkheld, sondern zur allgemeinen Kenntnisnahme bestimmt. Die meisten werden es eher nicht gewoht sein, einen App-Start derart korrekt zu progammieren. Ich hatte mal ein Problem mit Hooks und tieferen GUI-Ereignissen. Da hat Brucey mir mit dieser Variante eine stabilere App gezeigt. |
||
Gewinner des BCC #53 mit "Gitarrist vs Fussballer" http://www.midimaster.de/downl...ssball.exe |
funkheld |
Sa, März 17, 2018 20:06 Antworten mit Zitat |
|
---|---|---|
Hallo. streitet euch nicht.
Vielen Dank an euch die mir geholfen haben. Ich habe alles aufgenommen und werde es bei mir einbauen. Zu der Frage, was programmiert er eigentlich? Ich Empfange regelmäßig Daten vom Server und schicke regelmäßig Daten dort hin. Die Daten die bei mir ankommen sollen noch Grafisch dargestellt werden. Ich wusste nicht, wie man eine Gui mit Event/Select/Timer aufbaut um Konflikte in der Gui beim Ablauf zu vermeiden. Danke. Gruss |
||
funkheld |
Sa, März 17, 2018 20:13 Antworten mit Zitat |
|
---|---|---|
Zitat: ....rhythmische Aufgaben wie Millisecs()-Timer abgearbeitet. Kann man diese beiden Timer irgendwie in einer Case mit einbauen oder müssen die als Function außerhalb liegen um sie dann aufzurufen? Code: [AUSKLAPPEN] If MilliSecs() - erstertimer >= 200 Then erstertimer = MilliSecs() fnSend("d,0") EndIf If MilliSecs() - ZweiterTimer >= 50 Then ZweiterTimer = MilliSecs() If cliSocket.ReadAvail() > 0 Then strTmp = "" While(cliSocket.ReadAvail() > 0) fnFlushBuf(bufData, bufSize) anzahl=cliSocket.Recv(bufData, bufSize) strTmp:+String.FromCString(bufData) Local Einzeln$[]=strtmp.Split(":") SetGadgetText( str_alti,Einzeln$[1] ) SetGadgetText( str_apoa,Einzeln$[2] ) SetGadgetText( str_peri,Einzeln$[3] ) SetGadgetText( str_velo,Einzeln$[4] ) Wend EndIf EndIf Code: [AUSKLAPPEN] Strict Import MaxGUI.Drivers Include "utils.bmx" Global text:String,text1:String,line:String Global x1:Int,x2:Int,x3:Int,x4:Int,x5:Int Global countLines:Int,i:Int,anzahl:Int Global sdelta:Float Local remotePort = 5000 Local remoteIp = HostIp("127.0.0.1") Global cliSocket:TSocket = CreateTCPSocket() ConnectSocket(cliSocket, remoteIp, remotePort) Global bufSize = 1024 Global bufData:Byte[] = New Byte[bufSize] Global strTmp:String Global Window:TGadget=CreateWindow("krpc",20,20,400,500) Global stage:TGadget=CreateButton("stage",10,10,60,25,Window) Global killer:TGadget=CreateButton("cls",220,200,60,25,Window) Global text_send:TGadget=CreateButton("senden",220,230,60,25,Window) Global b_plus:TGadget=CreateButton("thr+",80,10,35,25,Window) Global b_minus:TGadget=CreateButton("trt-",80,40,35,25,Window) Global str_throttle:TGadget =CreateTextField(120,10,30,22,window) Global text_g:TGadget = CreateTextArea( 10, 200, 200,200, window ) Global str_alti:TGadget =CreateTextField(210,10,120,22,window) Global str_apoa:TGadget =CreateTextField(210,40,120,22,window) Global str_peri:TGadget =CreateTextField(210,70,120,22,window) Global str_velo:TGadget =CreateTextField(210,100,120,22,window) ActivateGadget str_alti ActivateGadget str_apoa ActivateGadget str_peri ActivateGadget str_velo Local ersterTimer:Int = MilliSecs() Local ZweiterTimer:Int = MilliSecs() sdelta=0.0 SetGadgetText( str_throttle,Int(sdelta)+"."+Int((sdelta-Int(sdelta)) * 10.0) ) CreateTimer(60) While WaitEvent() Select EventID() Case EVENT_GADGETSELECT Case EVENT_GADGETACTION Select EventSource() Case stage fnSend("stage,0") Case b_plus sdelta=sdelta+0.1 If sdelta > 1.0 Then sdelta=1.0 fnSend("throttle,"+sdelta) SetGadgetText( str_throttle,Int(sdelta)+"."+Int((sdelta-Int(sdelta)) * 10.0) ) Delay(100) Case b_minus sdelta=sdelta-0.1 If sdelta < 0.0 Then sdelta=0.0 fnSend("throttle,"+sdelta) SetGadgetText( str_throttle,Int(sdelta)+"."+Int((sdelta-Int(sdelta)) * 10.0) ) Delay(100) Case killer SetGadgetText text_g, "" text="" Case text_send countLines= TextAreaLen(text_g,TEXTAREA_LINES) For i = 0 To countLines line = TextAreaText(text_g, i, 1, TEXTAREA_LINES) fnSend(line) Delay(50) Next End Select Case EVENT_TIMERTICK Case EVENT_GADGETPAINT Flip Case EVENT_MOUSEDOWN Case EVENT_MOUSEMOVE Case EVENT_MOUSEUP Case EVENT_WINDOWCLOSE End Case EVENT_APPTERMINATE End Case EVENT_MENUACTION End Select Wend Function fnSend(MSG:String) cliSocket.Send(MSG, Len(MSG)) End Function Danke. Gruss |
||
Mathias-Kwiatkowski |
Sa, März 17, 2018 22:05 Antworten mit Zitat |
|
---|---|---|
du kannst es hier unter einfügen -> Case EVENT_TIMERTICK
oder du arbeitest eben mit repeat forever und packst es in der schleife. wie du es willst ist deine programm architektur. ich mache sowas anders, komplett anders ähnliche wie brucy es meistert, hab ich mir seit monkey so angewohnt. |
||
Skype: Anarchie1984
http://projektworks.de/maxbase/ Icq - Erneuert am 21.08.2017 Yahoo - Erneuert am 21.08.2017 |
funkheld |
So, März 18, 2018 12:50 Antworten mit Zitat |
|
---|---|---|
Zitat: komplett anders ... Dein Beispiel würde mich auch einmal bitte interessieren. Danke. Gruss |
||
Übersicht BlitzMax, BlitzMax NG Allgemein
Powered by phpBB © 2001 - 2006, phpBB Group