Aktuelle Zeit: 18.02.2020 09:08

Alle Zeiten sind UTC + 1 Stunde [ Sommerzeit ]




Ein neues Thema erstellen Auf das Thema antworten  [ 11 Beiträge ]  Gehe zu Seite 1, 2  Nächste
Autor Nachricht
 Betreff des Beitrags: YAED - Yet another Event Dispatcher
BeitragVerfasst: 08.06.2010 17:59 
Offline
Benutzeravatar

Registriert: 28.07.2005 00:54
Wohnort: /home/Blackskyliner/
YAED - Yet Another Event Dispatcher

Beschreibung:
Angefangen hat das ganze Projekt damit, das ich ein Thread-Safe Messaging System basteln wollte, um z.B. veränderungen an Gadgets aus Thread heraus anzeigen zu können.
Da man Gadgets nur aus dem erstellenden Thread heraus behandeln soll, habe ich mir gedacht, dann mach ich mir halt eine Liste, wo einzelne Nachrichten gespeichert werden.
Diese werden z.B. in einem Child-Thread zu der Liste hinzugefügt um dann entsprechend im Main-Thread verarbeitet zu werden.

Als dieses System fertig war, hab ich mir gedach, man kann auf diesem System aufbauend auch einen FunktionsDispatcher basteln, so wie man das von anderen Sprachen her kennt.
Also habe ich angefangen die dispatcher.pbi zu schreiben, welche letztendlich eine Funktion entsprechnd in einem anderen Thread ausführen lassen kann.
z.B. eine Funktion die im 1. Fenster was vom Mainthread erstellt wurde, Gadgets neu anordnen soll auf Knopfdruck eines Gadgets aus einem Fenster das in einem Child-Thread erzeugt wurde.

Als das alles fertig war, dachte ich mir, da diese Funktionalität (in meiner Sichtweise) sehr auf ein Event-Driven System hinweist, dachte ich mir: "Fehlt ja nurnoch ein Gadget EventSystem"
Dies habe ich dann als nächstes geschrieben.

Letztendlich kann man nun mit diesen 3 Libarys wunderbar ein Event-Driven User Interface zusammen basteln. (Alla VistualStudio)

Außerdem kann dieses System auch mit mehreren Fenstern umgehen, da man dann nur ein eigenen EventMessage Loop definieren muss (ID-Technisch) und entsprechend aufrufen.
Das tolle an diesem System istaußerdem das alle Gadgets, die via EventGadget() verwaltet werden sofort benutzt werden können.

Hier der entsprechende Quellcode der einzelnen Includes und am Ende das Beispiel

multiDatatype.pbi
Code:
; Multitype datatype for easy usage multiple datatypes
; like parameter for function arrays @see(threadMessaging.pbi)

; License: MIT-License
; Copyright (c) 2010 Blackskyliner
;
; Permission is hereby granted, free of charge, To any person
; obtaining a copy of this software And associated documentation
; files (the "Software"), To deal in the software without
; restriction, including without limitation the rights To use,
; copy, modify, merge, publish, distribute, sublicense, And/or sell
; copies of the software, And To permit persons To whom the
; software is furnished To do so, subject To the following
; conditions:
;
; the above copyright notice And this Permission notice shall be
; included in all copies Or substantial portions of the software.
;
; the software is PROVIDED "AS IS", without WARRANTY of any KIND,
; EXPRESS Or IMPLIED, including BUT Not LIMITED To the WARRANTIES
; of MERCHANTABILITY, FITNESS For a PARTICULAR PURPOSE And
; NONINFRINGEMENT. in NO event shall the AUTHORS Or copyright
; holders be LIABLE For any CLAIM, DAMAGES Or OTHER LIABILITY,
; WHETHER in AN ACTION of CONTRACT, TORT Or OTHERWISE, ARISING
; FROM, OUT of Or in CONNECTION With the software Or the use Or
; OTHER DEALINGS in the software.

Structure t_multiDatatype
   type.l ; #PB_Integer, #PB_String, ...
   StructureUnion
      integer.i
      long.l
      double.d
      
      float.f
      quad.q
      
      byte.b
      ascii.a
      character.c
      word.w
      unicode.u
      
      *pointer
   EndStructureUnion
   string.s
EndStructure

Structure t_multiDatatypeArrayArgument
  Index.t_multiDatatype[0]
EndStructure

Procedure createLongMessage(*temp.t_multiDatatype, dataVar.l)
   *temp\long = dataVar
   *temp\type = #PB_Long
EndProcedure

Procedure createDoubleMessage(*temp.t_multiDatatype, dataVar.d)
   *temp\double = dataVar
   *temp\type = #PB_Double
EndProcedure

Procedure createIntegerMessage(*temp.t_multiDatatype, dataVar.i)
   *temp\integer = dataVar
   *temp\type = #PB_Integer
EndProcedure

Procedure createFloatMessage(*temp.t_multiDatatype, dataVar.f)
   *temp\float = dataVar
   *temp\type = #PB_Float
EndProcedure

Procedure createQuadMessage(*temp.t_multiDatatype, dataVar.q)
   *temp\quad = dataVar
   *temp\type = #PB_Quad
EndProcedure

Procedure createAsciiMessage(*temp.t_multiDatatype, dataVar.a)
   *temp\ascii = dataVar
   *temp\type = #PB_Ascii
EndProcedure

Procedure createWordMessage(*temp.t_multiDatatype, dataVar.w)
   *temp\word = dataVar
   *temp\type = #PB_Word
EndProcedure

Procedure createCharacterMessage(*temp.t_multiDatatype, dataVar.c)
   *temp\character = dataVar
   *temp\type = #PB_Character
EndProcedure

Procedure createStringMessage(*temp.t_multiDatatype, dataVar.s)
   *temp\string = dataVar
   *temp\type = #PB_String
EndProcedure

Procedure createByteMessage(*temp.t_multiDatatype, dataVar.b)
   *temp\byte = dataVar
   *temp\type = #PB_Byte
EndProcedure

Procedure createPointerMessage(*temp.t_multiDatatype, *dataVar)
    *temp\pointer = *dataVar
    *temp\type = #PB_Function
EndProcedure

Procedure createUnicodeMessage(*temp.t_multiDatatype, dataVar.u)
   *temp\unicode = dataVar
   *temp\type = #PB_Unicode
EndProcedure


memory.pbi
Code:
; Memory Wrapper
; Overview over allocated data

; Needs: No dependencies

; Note:
; As of Purebasic 4.50 x86 while running a linux machine with activated Purfier
; there will be an IMA (debugger) when returning allocated memory while having a string as
; a procedure parameter. @see(http://forums.purebasic.com/german/viewtopic.php?f=20&t=22630)

; License: MIT-License
; Copyright (c) 2010 Blackskyliner
;
; Permission is hereby granted, free of charge, To any person
; obtaining a copy of this software And associated documentation
; files (the "Software"), To deal in the software without
; restriction, including without limitation the rights To use,
; copy, modify, merge, publish, distribute, sublicense, And/or sell
; copies of the software, And To permit persons To whom the
; software is furnished To do so, subject To the following
; conditions:
;
; the above copyright notice And this Permission notice shall be
; included in all copies Or substantial portions of the software.
;
; the software is PROVIDED "AS IS", without WARRANTY of any KIND,
; EXPRESS Or IMPLIED, including BUT Not LIMITED To the WARRANTIES
; of MERCHANTABILITY, FITNESS For a PARTICULAR PURPOSE And
; NONINFRINGEMENT. in NO event shall the AUTHORS Or copyright
; holders be LIABLE For any CLAIM, DAMAGES Or OTHER LIABILITY,
; WHETHER in AN ACTION of CONTRACT, TORT Or OTHERWISE, ARISING
; FROM, OUT of Or in CONNECTION With the software Or the use Or
; OTHER DEALINGS in the software.

Global _AllocatedCounter.l = 0
Global _AllocatedCounterMutex.l = CreateMutex()

Procedure _AllocateMemoryWrapper(Size.l, File.s, Line.l)
   Debug File+"["+Str(Line)+"]: Memory allocated."
   LockMutex(_AllocatedCounterMutex);>
      _AllocatedCounter = _AllocatedCounter + 1
   UnlockMutex(_AllocatedCounterMutex);<
   ProcedureReturn AllocateMemory(Size)
EndProcedure

Procedure _FreeMemoryWrapper(address.i, File.s, Line.l)
   Debug File+"["+Str(Line)+"]: Memory freed."
   LockMutex(_AllocatedCounterMutex);>
      _AllocatedCounter = _AllocatedCounter - 1
   UnlockMutex(_AllocatedCounterMutex);<
   FreeMemory(address)
EndProcedure

Macro AllocateMemory_(Size)
   _AllocateMemoryWrapper(Size, #PB_Compiler_File, #PB_Compiler_Line)
EndMacro

Macro FreeMemory_(address)
   _FreeMemoryWrapper(address, #PB_Compiler_File, #PB_Compiler_Line)
EndMacro

Macro ShowAllocatedMemoryCount()
   LockMutex(_AllocatedCounterMutex);>
      Debug _AllocatedCounter
   UnlockMutex(_AllocatedCounterMutex);<
EndMacro


threadMessaging.pbi
Code:
; Thread Messaging Library
; Multithread-Safe

; Needs:    multiDatatype.pbi
;         memory.pbi

; License: MIT-License
; Copyright (c) 2010 Blackskyliner
;
; Permission is hereby granted, free of charge, To any person
; obtaining a copy of this software And associated documentation
; files (the "Software"), To deal in the software without
; restriction, including without limitation the rights To use,
; copy, modify, merge, publish, distribute, sublicense, And/or sell
; copies of the software, And To permit persons To whom the
; software is furnished To do so, subject To the following
; conditions:
;
; the above copyright notice And this Permission notice shall be
; included in all copies Or substantial portions of the software.
;
; the software is PROVIDED "AS IS", without WARRANTY of any KIND,
; EXPRESS Or IMPLIED, including BUT Not LIMITED To the WARRANTIES
; of MERCHANTABILITY, FITNESS For a PARTICULAR PURPOSE And
; NONINFRINGEMENT. in NO event shall the AUTHORS Or copyright
; holders be LIABLE For any CLAIM, DAMAGES Or OTHER LIABILITY,
; WHETHER in AN ACTION of CONTRACT, TORT Or OTHERWISE, ARISING
; FROM, OUT of Or in CONNECTION With the software Or the use Or
; OTHER DEALINGS in the software.

XIncludeFile "multiDatatype.pbi"
XIncludeFile "memory.pbi"

Structure t_message
   ; The Event that needs to be proccessed
   ; This one defines which data are in *eventData
   eventCode.i
   
   ; The Data itself. (Dynamically allocated)
   ; You need to free them manually...
   *eventData
   
   ; To differ the diffrent peek methods
   ; use of #PB_ Types
   dataType.i
   
   ; #TRUE if it needs to be freed (autmotatically)
   needToBeFreed.i
   
   ; Should it be deleted after Called?
   ; Manly for Eventsystems which want to register permanent callbacks
   permanent.l
   
   ; So we can use GetMessage() in a while loop
   ; #True if called
   ; #False if needs to be called
   wasCalled.l
EndStructure

Prototype MessageCallbackProc(*message.t_message)

Structure t_MessageCallback
   *funcPointer.MessageCallbackProc
   messagEventID.l
   
   ; For easy unregistering...
   ; Like t_message.wasCalled
   wasChecked.l
EndStructure

; Global List and thread mutex
; to ensure threadsafety.
Global NewList ThreadEventMessageList.t_message()
Global ThreadEventMessageMutex.i = CreateMutex()
Global NewList ThreadEventMessageCallbackList.t_MessageCallback()
Global ThreadEventMessageCallbackMutex.i = CreateMutex()

; Inserts the given data in the event stack
Procedure CreateMessage(code.l, *eventData.l, dataType.l, dynamic.l = #True, permanent.l = #False)
   Protected Index.l = -1 ; old index to restore
   LockMutex(ThreadEventMessageMutex) ;>
      Index = ListIndex(ThreadEventMessageList())
      LastElement(ThreadEventMessageList())
      AddElement(ThreadEventMessageList())
      ThreadEventMessageList()\dataType = dataType;
      ThreadEventMessageList()\eventCode = code;
      ThreadEventMessageList()\eventData = *eventData;
      ThreadEventMessageList()\needToBeFreed = dynamic
      ThreadEventMessageList()\permanent = permanent
      If Index <> -1
         SelectElement(ThreadEventMessageList(), Index)
      EndIf
   UnlockMutex(ThreadEventMessageMutex) ;<
EndProcedure

; Get the top element of the event stack
Procedure GetMessages(*temp.t_message)
   Protected retVar.b = #False
   LockMutex(ThreadEventMessageMutex) ;>
      If FirstElement(ThreadEventMessageList()) <> 0
         While ThreadEventMessageList()\wasCalled
            If NextElement(ThreadEventMessageList()) = 0
               UnlockMutex(ThreadEventMessageMutex)
               ProcedureReturn #False
            EndIf
         Wend
         
         *temp\dataType = ThreadEventMessageList()\dataType
         *temp\eventCode = ThreadEventMessageList()\eventCode
         *temp\eventData = ThreadEventMessageList()\eventData
         *temp\needToBeFreed = ThreadEventMessageList()\needToBeFreed
         *temp\permanent = ThreadEventMessageList()\permanent
         
         ThreadEventMessageList()\wasCalled = #True
         retVar = #True
         
      EndIf
   UnlockMutex(ThreadEventMessageMutex) ;<
   
   ProcedureReturn retVar
EndProcedure

Procedure DeleteMessage(*message.t_message)
   ;CallDebugger
   If *message\needToBeFreed = #True
      FreeMemory_(*message\eventData); free the dynamic data
   EndIf
   ; The other data is automatically freed.
EndProcedure

Procedure registerMessageEventCallback(eventID.l, *callback)
   LockMutex(ThreadEventMessageCallbackMutex);>
      LastElement(ThreadEventMessageCallbackList())
      AddElement(ThreadEventMessageCallbackList())
      ThreadEventMessageCallbackList()\funcPointer = *callback
      ThreadEventMessageCallbackList()\messagEventID = eventID
   UnlockMutex(ThreadEventMessageCallbackMutex);<
EndProcedure

Procedure MessageEvent(eventID.l)
   Protected temp.t_message
   Protected calledOnce.l = #False
   
   While GetMessages(@temp)
      calledOnce = #False
      
      LockMutex(ThreadEventMessageCallbackMutex);>
         ResetList(ThreadEventMessageCallbackList())
         While NextElement(ThreadEventMessageCallbackList())
            If ThreadEventMessageCallbackList()\messagEventID = eventID
               ThreadEventMessageCallbackList()\funcPointer(temp)
               calledOnce = #True
            EndIf
         Wend
      UnlockMutex(ThreadEventMessageCallbackMutex);<
      
      ;CallDebugger
      If calledOnce And ThreadEventMessageList()\permanent = #False
         LockMutex(ThreadEventMessageMutex);>
            DeleteElement(ThreadEventMessageList())
         UnlockMutex(ThreadEventMessageMutex);<
         
         ; Done with the Message so free the dynamically allocated message data
         DeleteMessage(@temp)
      EndIf
      
   Wend
   
   ; Reset wasCalled
   LockMutex(ThreadEventMessageMutex);>
      ResetList(ThreadEventMessageList())
      While NextElement(ThreadEventMessageList())
         ThreadEventMessageList()\wasCalled = #False   
      Wend
   UnlockMutex(ThreadEventMessageMutex);<
EndProcedure

; If #PB_Any and FuncPointer = #Null, all Callbacks will be deleted
; If only #PB_Any and FuncPointer is Valid, all Callbacks to this function will be deleted
; If eventID is specified but the FuncPointer is #Null, all Callbacks to this EventId will be deleted
Procedure unregisterMessageEventCallback(eventID.l, *callback)
   Protected temp.t_message
   Protected calledOnce.l = #False
   
   LockMutex(ThreadEventMessageCallbackMutex);>
      While FirstElement(ThreadEventMessageCallbackList())
         While ThreadEventMessageCallbackList()\wasChecked
            If NextElement(ThreadEventMessageCallbackList()) = 0
               
               ResetList(ThreadEventMessageCallbackList())
               While NextElement(ThreadEventMessageCallbackList())
                  ThreadEventMessageCallbackList()\wasChecked = #False   
               Wend
               UnlockMutex(ThreadEventMessageCallbackMutex)
               ProcedureReturn
            EndIf
         Wend
         
         ThreadEventMessageCallbackList()\wasChecked = #True
         If eventID = #PB_Any Or eventID = ThreadEventMessageCallbackList()\messagEventID
            If *callback = #Null Or *callback = ThreadEventMessageCallbackList()\funcPointer               
               DeleteElement(ThreadEventMessageCallbackList())
            EndIf
         EndIf
      Wend
   UnlockMutex(ThreadEventMessageCallbackMutex);<
EndProcedure


dispatcher.pbi
Code:
; Function Dispatcher Library

; Needs:    threadMessaging.pbi

; License: MIT-License
; Copyright (c) 2010 Blackskyliner
;
; Permission is hereby granted, free of charge, To any person
; obtaining a copy of this software And associated documentation
; files (the "Software"), To deal in the software without
; restriction, including without limitation the rights To use,
; copy, modify, merge, publish, distribute, sublicense, And/or sell
; copies of the software, And To permit persons To whom the
; software is furnished To do so, subject To the following
; conditions:
;
; the above copyright notice And this Permission notice shall be
; included in all copies Or substantial portions of the software.
;
; the software is PROVIDED "AS IS", without WARRANTY of any KIND,
; EXPRESS Or IMPLIED, including BUT Not LIMITED To the WARRANTIES
; of MERCHANTABILITY, FITNESS For a PARTICULAR PURPOSE And
; NONINFRINGEMENT. in NO event shall the AUTHORS Or copyright
; holders be LIABLE For any CLAIM, DAMAGES Or OTHER LIABILITY,
; WHETHER in AN ACTION of CONTRACT, TORT Or OTHERWISE, ARISING
; FROM, OUT of Or in CONNECTION With the software Or the use Or
; OTHER DEALINGS in the software.

XIncludeFile "threadMessaging.pbi"

Enumeration   
   #Message_DispatchedFunction
   
   #Message_CustomInternMAX
EndEnumeration


Prototype DispatchProc(Array Param.t_multiDatatype(1))

Structure t_dispatch
   *func.DispatchProc
   Array Param.t_multiDatatype(10)
EndStructure

Procedure dispatchProcedure(*func.DispatchProc, Array Param.t_multiDatatype(1))
   Protected *temp.t_dispatch = AllocateMemory(SizeOf(t_dispatch))
   InitializeStructure(*temp, t_dispatch)
   
   *temp\func = *func;
   CopyArray(Param(), *temp\Param())
   
   CreateMessage(#Message_DispatchedFunction, *temp, #PB_Function)
EndProcedure

Procedure callDispatchedProcedure(*message.t_message)
   Protected temp.t_dispatch;
   
   If *message\dataType = #PB_Function
      CopyMemory(*message\eventData, @temp, SizeOf(t_dispatch))
      temp\func(temp\Param())
   Else
      Debug "Dispatched Datatype Error!!!"
   EndIf   
EndProcedure


gadgetEventHandler.pbi
Code:
; Gadget Event Handler Library

; Needs:    threadMessaging.pbi
;         memory.pbi

; License: MIT-License
; Copyright (c) 2010 Blackskyliner
;
; Permission is hereby granted, free of charge, To any person
; obtaining a copy of this software And associated documentation
; files (the "Software"), To deal in the software without
; restriction, including without limitation the rights To use,
; copy, modify, merge, publish, distribute, sublicense, And/or sell
; copies of the software, And To permit persons To whom the
; software is furnished To do so, subject To the following
; conditions:
;
; the above copyright notice And this Permission notice shall be
; included in all copies Or substantial portions of the software.
;
; the software is PROVIDED "AS IS", without WARRANTY of any KIND,
; EXPRESS Or IMPLIED, including BUT Not LIMITED To the WARRANTIES
; of MERCHANTABILITY, FITNESS For a PARTICULAR PURPOSE And
; NONINFRINGEMENT. in NO event shall the AUTHORS Or copyright
; holders be LIABLE For any CLAIM, DAMAGES Or OTHER LIABILITY,
; WHETHER in AN ACTION of CONTRACT, TORT Or OTHERWISE, ARISING
; FROM, OUT of Or in CONNECTION With the software Or the use Or
; OTHER DEALINGS in the software.

XIncludeFile "threadMessaging.pbi"
XIncludeFile "memory.pbi"

#GadgetMessage = $0F

Prototype gadgetCallbackFunc(gadgetID.l, event.l)

Structure t_gadgetElement
   gadgetID.l
   event.l
   *func.gadgetCallbackFunc
EndStructure

Procedure registerGadgetCallback(eventHandleLoop.l, gadgetID.l, event.l, *callback.gadgetCallbackFunc)
   Protected *temp.t_gadgetElement = AllocateMemory_(SizeOf(t_gadgetElement))
   
   *temp\event = event
   *temp\func = *callback
   *temp\gadgetID = gadgetID
   
   CreateMessage(eventHandleLoop, *temp, #GadgetMessage, #True, #True)
EndProcedure


Procedure unregisterGadgetCallback(eventHandleLoop.l, gadgetID.l, event.l, *callback.gadgetCallbackFunc)
   Protected temp.t_message
   Protected temp2.t_gadgetElement
   
   ; Dirty... could lead to double executing...
   LockMutex(ThreadEventMessageMutex) ;>
      ResetList(ThreadEventMessageList())
      While NextElement(ThreadEventMessageList())
         ThreadEventMessageList()\wasCalled = #False   
      Wend
   UnlockMutex(ThreadEventMessageMutex) ;<
   
   ; Also dity becaus use of "intern" threadMessaging functions...
   While GetMessages(@temp)
      If temp\eventCode = eventHandleLoop Or eventHandleLoop = #PB_Any
         If temp\dataType = #GadgetMessage
            CopyMemory(temp\eventData, @temp2, SizeOf(t_gadgetElement))
            If temp2\event = event Or event = #PB_Any
               If temp2\gadgetID = gadgetID Or gadgetID = #PB_Any
                  If temp2\func = *callback Or *callback = #Null
                     LockMutex(ThreadEventMessageMutex) ;>
                        DeleteElement(ThreadEventMessageList())
                     UnlockMutex(ThreadEventMessageMutex) ;<
                     DeleteMessage(@temp)
                  EndIf
               EndIf
            EndIf
         EndIf
      EndIf
   Wend
EndProcedure

Procedure handleGadgetCallbacks(*message.t_message)
   Protected temp.t_gadgetElement
   Protected GadgetEventID.l = EventGadget()
   CopyMemory(*message\eventData, @temp, SizeOf(t_gadgetElement))
   
   If temp\gadgetID = GadgetEventID
      If EventType() = temp\event
         temp\func(temp\gadgetID, temp\event)
      EndIf
   EndIf
EndProcedure


example.pb
Code:
; Example for the usage of:
;    - Thread Messaging Library
;   - Function Dispatcher Library
;   - Gadget Event Handler Library

; Needs:    multiDatatype.pbi
;      threadMessaging.pbi
;      dispatcher.pbi
;      gadgetEventHandler.pbi
;      memory.pbi

; License: MIT-License
; Copyright (c) 2010 Blackskyliner
;
; Permission is hereby granted, free of charge, To any person
; obtaining a copy of this software And associated documentation
; files (the "Software"), To deal in the software without
; restriction, including without limitation the rights To use,
; copy, modify, merge, publish, distribute, sublicense, And/or sell
; copies of the software, And To permit persons To whom the
; software is furnished To do so, subject To the following
; conditions:
;
; the above copyright notice And this Permission notice shall be
; included in all copies Or substantial portions of the software.
;
; the software is PROVIDED "AS IS", without WARRANTY of any KIND,
; EXPRESS Or IMPLIED, including BUT Not LIMITED To the WARRANTIES
; of MERCHANTABILITY, FITNESS For a PARTICULAR PURPOSE And
; NONINFRINGEMENT. in NO event shall the AUTHORS Or copyright
; holders be LIABLE For any CLAIM, DAMAGES Or OTHER LIABILITY,
; WHETHER in AN ACTION of CONTRACT, TORT Or OTHERWISE, ARISING
; FROM, OUT of Or in CONNECTION With the software Or the use Or
; OTHER DEALINGS in the software.

EnableExplicit

XIncludeFile "memory.pbi"
XIncludeFile "multiDatatype.pbi"
XIncludeFile "threadMessaging.pbi"
XIncludeFile "dispatcher.pbi"
XIncludeFile "gadgetEventHandler.pbi"

; Custom Messages
Enumeration #Message_CustomInternMAX
   #Message_AddElement
   #Message_DelElement
   
   #Message_CustomMAX
EndEnumeration

Enumeration
   #EventMessageLoop_MainWindow   
   #GadgetEventhandleLoop
EndEnumeration

Procedure DispatchMe(Array Param.t_multiDatatype(1))
   If Param(0)\type = #PB_Long
      ;Debug Param(0)\long
   Else
      ; Statt Debug, OnError Libary nutzen
      Debug "Invalid Type: Long expected!"
   EndIf
EndProcedure

Procedure ThreadedProcedure(dummy)
   Protected *eventDataBuffer;
   Protected str$
   Protected length.l
   Protected i.l, n.l
   
   ; Dispatch a function to do whatever in the mainThread...
   Dim params.t_multiDatatype(10)
   createLongMessage(params(0), 1000)
   dispatchProcedure(@DispatchMe(), params())
   
   
   ;Some test messages
   For i = 0 To 1
      str$ = "Das ist ein Test."
      length = Len(str$)
      
      *eventDataBuffer = AllocateMemory_((length+1)*SizeOf(str$))
      PokeS(*eventDataBuffer, str$)
      CreateMessage(#Message_AddElement, *eventDataBuffer, #PB_String)
      
      str$ = "Und noch einer, weils so schön ist :P."
      length = Len(str$)
      
      ; Länge + Nullbyte * Size of one character
      *eventDataBuffer = AllocateMemory_((length+1)*SizeOf(str$))
      PokeS(*eventDataBuffer, str$)
      CreateMessage(#Message_AddElement, *eventDataBuffer, #PB_String)
      
      CreateMessage(#Message_AddElement, @"", #PB_String, #False)
   Next i
EndProcedure
 
; Proccess each message
Procedure MessageCallback(*message.t_message)
   Select *message\eventCode
      Case #Message_AddElement   
         If *message\dataType = #PB_String
            AddGadgetItem(0,-1,PeekS(*message\eventData))
         EndIf
         
      Case #Message_DispatchedFunction
         ; Maybe do some stuff to stored data and then call the Proc.
         callDispatchedProcedure(*message)
      Default
         Debug "Unknown Event..."
   EndSelect
EndProcedure

CreateThread(@ThreadedProcedure(), #Null)

Procedure deleteButton_OnClick(gadgetID.l, event.l)
   RemoveGadgetItem(0, GetGadgetState(0))
   
   unregisterGadgetCallback(#GadgetEventhandleLoop, 1, #PB_EventType_LeftClick, @deleteButton_OnClick())
EndProcedure

Procedure exitButton_OnClick(gadgetID.l, event.l)
   End ; Dirty, because some dynamic data will not be freed...
EndProcedure

; Register one Callback function for the EventDispatcher
; Every registered function will get the EventMessagem
; one after another. (But only those which are for their ID)
registerMessageEventCallback(#EventMessageLoop_MainWindow,@MessageCallback())
registerMessageEventCallback(#GadgetEventhandleLoop, @handleGadgetCallbacks())

OpenWindow(0,0,0,300,200,"Test App")
ListViewGadget(0,0,0,300,175)
ButtonGadget(1, 0,175,150,25, "Delete Selected")
ButtonGadget(2, 150,175,150,25, "Exit App")


registerGadgetCallback(#GadgetEventhandleLoop, 1, #PB_EventType_LeftClick, @deleteButton_OnClick())
registerGadgetCallback(#GadgetEventhandleLoop, 2, #PB_EventType_LeftClick, @exitButton_OnClick())
Define event.l

Repeat
   ; EventDispatcher
   MessageEvent(#EventMessageLoop_MainWindow)
   event = WaitWindowEvent(5)
   
   Select event
      Case #PB_Event_Gadget
         MessageEvent(#GadgetEventhandleLoop)
   EndSelect
Until event = #PB_Event_CloseWindow

unregisterGadgetCallback(#PB_Any, #PB_Any, #PB_Any, #Null)
unregisterMessageEventCallback(#PB_Any, #Null)

ShowAllocatedMemoryCount()



Kritik erwünscht :)

MFG
Blackskyliner

_________________
Keine meiner Antworten ist endgültig, es kann passieren, dass ich den so eben geposteten Beitrag noch mehrmals ändere, um Doppelposts zu umgehen.
_________________
Purebasic Windows 7 x64 & Linux (Ubuntu 10.04LTS) 4.50[x64|x86] Nutzer
_________________
Projekte: YAED - Yet another Event Dispatcher


Zuletzt geändert von Blackskyliner am 10.06.2010 01:01, insgesamt 5-mal geändert.

Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: YAED - Yet another Event Dispatcher
BeitragVerfasst: 08.06.2010 18:02 
Offline
Kommando SG1
Benutzeravatar

Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Was ist das ?
Eine kleine Beschreibung in Worten wäre nicht schlecht, möchte nicht alles aus dem Code ziehen.
Danke :allright:

_________________
Bild
 
BildBildBild


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: YAED - Yet another Event Dispatcher
BeitragVerfasst: 08.06.2010 18:05 
Offline
Benutzeravatar

Registriert: 14.08.2007 15:41
Wohnort: Lelbach
Blackskyliner hat geschrieben:
Copyright by Blackskyliner

Blackskyliner hat geschrieben:
Lizenz: Keine, jeder kann es nutzen so wie er will und wo er will

Das widerspricht sich etwas...entweder/oder, da musst du dich schon entscheiden!

Du meinst wohl: "written by Blackskyliner" :D

_________________
- alles was ich hier im Forum sage/schreibe ist lediglich meine Meinung und keine Tatsachenbehauptung
- unkommentierter Quellcode = unqualifizierter Müll


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: YAED - Yet another Event Dispatcher
BeitragVerfasst: 08.06.2010 18:38 
Offline
Benutzeravatar

Registriert: 27.10.2004 12:25
Soviel ich weiss, hast du in Deutschland eh immer das Urheberrecht auf ein Werk und kannst dies auch nicht übertragen.
Was du aber wie im obigen Falle tun kannst, ist die Nutzungsrechte eingeschränkt oder uneingeschränkt abtreten (oder im Falle einer kommerziellen Software diese eingeschränkt gegen Bezahlung vergeben).

Zitat:
Lizenz: Keine, jeder kann es nutzen so wie er will und wo er will

Würde ich mir von Anfang an abgewöhnen, da du so bei Schadensersatzansprüchen anderer gelackmeiert bist.

Nutze eine offizielle Lizenz die deine Absicht der Übertragung der Nutzungsrechte gesichert wiedergibt:
http://www.opensource.org/licenses/bsd-license.php
http://www.opensource.org/licenses/mit-license.php

_________________
Hier gibts die OOP Option für PureBasic.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: YAED - Yet another Event Dispatcher
BeitragVerfasst: 09.06.2010 19:29 
Offline
Benutzeravatar

Registriert: 28.07.2005 00:54
Wohnort: /home/Blackskyliner/
Hab mal den Hauptpost geupdated auf die aktuellste Version.


Hab deine zwei Beiträge entfernt
RSBasic

_________________
Keine meiner Antworten ist endgültig, es kann passieren, dass ich den so eben geposteten Beitrag noch mehrmals ändere, um Doppelposts zu umgehen.
_________________
Purebasic Windows 7 x64 & Linux (Ubuntu 10.04LTS) 4.50[x64|x86] Nutzer
_________________
Projekte: YAED - Yet another Event Dispatcher


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: YAED - Yet another Event Dispatcher
BeitragVerfasst: 09.06.2010 19:42 
Offline
Benutzeravatar

Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9
Blackskyliner hat geschrieben:
- deleted -

Blackskyliner hat geschrieben:
- deleted -


Blackskyliner hat geschrieben:
sorry für den doppel/dreifach post...

kleiner Tipp: solange niemand auf Deine Postings geantwortet hat,
kannst Du diese selber mit dem "Beitrag löschen" - Button in der
unteren rechten Ecke entfernen.

Grüße ... Kiffi

_________________
Schrödingers Smiley :):


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: YAED - Yet another Event Dispatcher
BeitragVerfasst: 09.06.2010 19:45 
Offline
Benutzeravatar

Registriert: 28.07.2005 00:54
Wohnort: /home/Blackskyliner/
Sorry, hab ich nicht gesehen... Werds mir fürs nächste mal merken, danke für den Tipp :allright:
Alltägliches übersieht man schnell mal ;)

_________________
Keine meiner Antworten ist endgültig, es kann passieren, dass ich den so eben geposteten Beitrag noch mehrmals ändere, um Doppelposts zu umgehen.
_________________
Purebasic Windows 7 x64 & Linux (Ubuntu 10.04LTS) 4.50[x64|x86] Nutzer
_________________
Projekte: YAED - Yet another Event Dispatcher


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: YAED - Yet another Event Dispatcher
BeitragVerfasst: 09.06.2010 19:54 
Offline
Benutzeravatar

Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9
was mir noch fehlt, ist ein Beispiel, das die Stärken Deines
Systems besser hervorhebt. Momentan ist Dein Sample ja
eher unspektakulär.

Ich habe mal testweise die 5000 in Deiner Testmessage-
Schleife wieder einkommentiert, um zu sehen, wie sich
die GUI hierbei verhält.
Code:
   ;Some test messages
   For i = 0 To 10 ;5000
      str$ = "Das ist ein Test."
      [...]


allerdings bekomme ich dann sofort einen IMA in folgender Zeile:
Code:
      CreateMessage(#Message_AddElement, *eventDataBuffer, #PB_String)


Grüße ... Kiffi

_________________
Schrödingers Smiley :):


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: YAED - Yet another Event Dispatcher
BeitragVerfasst: 09.06.2010 19:59 
Offline
Benutzeravatar

Registriert: 28.07.2005 00:54
Wohnort: /home/Blackskyliner/
Threadsafe in den Compiler-Optionen auf on?

Bei mir klappt das mit den 5000 Einträgen...

_________________
Keine meiner Antworten ist endgültig, es kann passieren, dass ich den so eben geposteten Beitrag noch mehrmals ändere, um Doppelposts zu umgehen.
_________________
Purebasic Windows 7 x64 & Linux (Ubuntu 10.04LTS) 4.50[x64|x86] Nutzer
_________________
Projekte: YAED - Yet another Event Dispatcher


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: YAED - Yet another Event Dispatcher
BeitragVerfasst: 09.06.2010 20:05 
Offline
Benutzeravatar

Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9
Blackskyliner hat geschrieben:
Threadsafe in den Compiler-Optionen auf on?

gnaaa! Jetzt funktioniert's <)

nix für ungut ... Kiffi

_________________
Schrödingers Smiley :):


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 11 Beiträge ]  Gehe zu Seite 1, 2  Nächste

Alle Zeiten sind UTC + 1 Stunde [ Sommerzeit ]


Wer ist online?

Mitglieder in diesem Forum: Lord und 4 Gäste


Sie dürfen keine neuen Themen in diesem Forum erstellen.
Sie dürfen keine Antworten zu Themen in diesem Forum erstellen.
Sie dürfen Ihre Beiträge in diesem Forum nicht ändern.
Sie dürfen Ihre Beiträge in diesem Forum nicht löschen.

Suche nach:
Gehe zu:  

 


Powered by phpBB © 2008 phpBB Group | Deutsche Übersetzung durch phpBB.de
subSilver+ theme by Canver Software, sponsor Sanal Modifiye