Page 1 of 1

Object Managment (+ example)

Posted: Tue Jun 20, 2006 7:32 pm
by Dr. Dri
This code makes possible to use internal PB object functions. This is particularly useful for userlibs. When you register an "Object" list, you can add static and dynamic (#PB_Any) elements.

include this file and you can call the functions

Code: Select all

Import #PB_Compiler_Home + "Compilers/ObjectManager.lib"
  Object_GetOrAllocateID (Objects, Object.l) As "_PB_Object_GetOrAllocateID@8"
  Object_GetObject       (Objects, Object.l) As "_PB_Object_GetObject@8"
  Object_IsObject        (Objects, Object.l) As "_PB_Object_IsObject@8"
  Object_EnumerateAll    (Objects, ObjectEnumerateAllCallback, *VoidData) As "_PB_Object_EnumerateAll@12"
  Object_EnumerateStart  (Objects) As "_PB_Object_EnumerateStart@4"
  Object_EnumerateNext   (Objects, *object.Long) As "_PB_Object_EnumerateNext@8"
  Object_EnumerateAbort  (Objects) As "_PB_Object_EnumerateAbort@4"
  Object_FreeID          (Objects, Object.l) As "_PB_Object_FreeID@8"
  Object_Init            (StructureSize.l, IncrementStep.l, ObjectFreeFunction) As "_PB_Object_Init@12"
  Object_GetThreadMemory (MemoryID.l) As "_PB_Object_GetThreadMemory@4"
  Object_InitThreadMemory(Size.l, InitFunction, EndFunction) As "_PB_Object_InitThreadMemory@12"
EndImport
I made a small example, i hope it's not too complicated...

Code: Select all

IncludeFile "Object.pbi"

;la structure qui contient les
;informations sur les timers
Structure Timer
  Event.l
  Window.l
  Elapse.l
EndStructure

;il faut que ce soit global ^^
;ou alors shared dans chaque fonction
Global TimerObjects

;la fonction la plus importante, sans elle
;pas d'objets statiques/dynamiques
Procedure.l FreeTimer(Timer.l)
  Protected Free.l = #False, *Timer.Timer
  
  If Timer <> #PB_Any And Object_IsObject(TimerObjects, Timer)
    *Timer = Object_GetObject(TimerObjects, Timer)
  EndIf
  
  If *Timer And IsWindow(*Timer\Window)
    Free = KillTimer_(WindowID(*Timer\Window), *Timer\Event)
    Object_Free(TimerObjects, Timer)
  EndIf
  
  ProcedureReturn Free
EndProcedure

;Retourne "non-zero" si le timer a été créé
;Retourne l'index du timer si Timer = #PB_Any
Procedure.l CreateTimer(Timer.l, Window.l, Event.l, Elapse.l)
  Protected Create.l = #Null, *Timer.Timer
  
  If IsWindow(Window) And Event
    FreeTimer(Timer)
    *Timer = Object_GetOrAllocate(TimerObjects, Timer)
  EndIf
  
  If *Timer
    SetTimer_(WindowID(Window), Event, Elapse, #Null)
    *Timer\Event  = Event
    *Timer\Window = Window
    *Timer\Elapse = Elapse
  EndIf
  
  If Timer = #PB_Any
    Create = *Timer
  ElseIf *Timer
    Create = *Timer\Event
  EndIf
  
  ProcedureReturn Create
EndProcedure

;trois fonctions pour meubler
Procedure.l GetTimerEvent(Timer.l)
  Protected Event.l = #PB_Any, *Timer.Timer
  
  *Timer = Object_GetObject(TimerObjects, Timer)
   
  If *Timer And IsWindow(*Timer\Window)
    Event = *Timer\Event
  EndIf
  
  ProcedureReturn Event
EndProcedure

Procedure.l GetTimerWindow(Timer.l)
  Protected Window.l = #PB_Any, *Timer.Timer
  
  *Timer = Object_GetObject(TimerObjects, Timer)
   
  If *Timer And IsWindow(*Timer\Window)
    Window = *Timer\Window
  EndIf
  
  ProcedureReturn Window
EndProcedure

Procedure.l GetTimerElapse(Timer.l)
  Protected Elapse.l = #PB_Any, *Timer.Timer
  
  *Timer = Object_GetObject(TimerObjects, Timer)
   
  If *Timer And IsWindow(*Timer\Window)
    Elapse = *Timer\Elapse
  EndIf
  
  ProcedureReturn Elapse
EndProcedure

;si on fait une lib autant
;créer les évennements qui vont avec ^^
#PB_Event_Timer = #WM_TIMER

;retourne le numéro de timer (#PB_Any s'il n'existe pas)
Procedure.l EventTimer()
  Protected Window.l, Event.l, Temp.l
  Protected Timer.l = #PB_Any, *Timer.Timer
  
  Window = EventWindow()
  Event  = EventwParam()
  
  Object_EnumerateStart(TimerObjects)
  
  While Object_EnumerateNext(TimerObjects, @Temp)
    *Timer = Object_GetObject(TimerObjects, Temp)
    
    If *Timer\Window = Window And *Timer\Event = Event
      Object_EnumerateAbort(TimerObjects)
      Timer = Temp
    EndIf
  Wend
  
  ProcedureReturn Timer
EndProcedure

;crée la liste d'objets des timers,
;je ne sais pas à quoi correspond le 2e argument
TimerObjects = Object_Init(SizeOf(Timer), 1, @FreeTimer())

;fin de la "lib"

;-------------------------------------------------------------------------------

;début du programme

Enumeration
  #Timer_A
  #Timer_C
EndEnumeration

If OpenWindow(0, 0, 0, 222, 50, "Timer", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  CreateGadgetList(WindowID(0))
  
  ButtonGadget(0, 10, 10, 200, 30, "Timer", #PB_Button_Toggle)
  
  CreateTimer(#Timer_A, 0, 6, 2000)
  CreateTimer(#Timer_C, 0, 2, 1500)
  
  Repeat
    
    Event = WaitWindowEvent()
    
    If Event = #PB_Event_Gadget
      
      If GetGadgetState(0)
        Timer = CreateTimer(#PB_Any, 0, 1, 1000)
      Else
        FreeTimer(Timer)
      EndIf
      
    ElseIf Event = #PB_Event_Timer
      
      Select EventTimer()
        Case #Timer_A
          Debug "#Timer_A"
          
        Case #Timer_C
          Debug "#Timer_C"
          
        Case Timer
          Debug "Timer"
          
      EndSelect
      
    EndIf
    
  Until Event = #PB_Event_CloseWindow
EndIf
Dri ;)

Posted: Tue Jun 20, 2006 7:35 pm
by Hroudtwolf
Very useful.
Thank you for sharing your knowledge.