Gestion des objets (+ exemple)
Publié : mar. 20/juin/2006 9:36
				
				Ce code permet d'utiliser les fonctions internes de PB pour gérer des listes d'objets. C'est pratique pour ceux qui font des userlibs, il suffit d'initialiser une liste d'objets et on peut y créer des objets statiques ou dynamiques (avec  #PB_Any)
Un exemple d'utilisation, en espérant que ca aide...
Dri 
			- Liste des fonctions:
 - Object_GetOrAllocate(*Objects, Object.l)
 - Object_GetObject(*Objects, Object.l)
 - Object_IsObject(*Objects, Object.l)
 - Object_EnumerateAll(*Objects, EnumerateCallback, *VoidData)
 - Object_EnumerateStart(*Objects)
 - Object_EnumerateNext(*Objects, *ID.Long)
 - Object_EnumerateAbort(*Objects)
 - Object_Free(*Objects, Object.l)
 - Object_Init(StructureSize.l, IncrementStep.l, FreeObjectFunction)
 - Object_GetThreadMemory(MemoryID.l)
 - Object_InitThreadMemory(Size.l, InitFunction, EndFunction)
 
Code : Tout sélectionner
Prototype   ThreadFunction(Param)
Prototype.l ObjectEnumerateAllCallback(Object.l, *Element, *VoidData)
Prototype   ObjectFreeFunction(Object.l)
Structure PB_SimpleList
  *Next    .PB_SimpleList
  *Previous.PB_SimpleList
EndStructure
Structure PB_Object
  StructureSize.l
  IncrementStep.l
  ObjectsNumber.l
  *ListFirstElement.PB_SimpleList
  FreeObject.ObjectFreeFunction
  Current.l
  *CurrentElement.PB_SimpleList
CompilerIf #PB_Compiler_Thread
  IncrementShift.l
  *FirstObjectsArea.PB_SimpleList
  *LastObjectsArea .PB_SimpleList
  ObjectMutex.Critical_Section
CompilerElse
  *ObjectsArea
CompilerEndIf
  
EndStructure
Prototype   PB_Object_GetOrAllocate   (*Object.PB_Object, Object.l)
Prototype   PB_Object_GetObject       (*Object.PB_Object, Object.l)
Prototype   PB_Object_IsObject        (*Object.PB_Object, Object.l)
Prototype   PB_Object_EnumerateAll    (*Object.PB_Object, Callback.ObjectEnumerateAllCallback, *VoidData)
Prototype   PB_Object_EnumerateStart  (*Object.PB_Object)
Prototype   PB_Object_EnumerateNext   (*Object.PB_Object, *ID.Long)
Prototype   PB_Object_EnumerateAbort  (*Object.PB_Object)
Prototype   PB_Object_Free            (*Object.PB_Object, Object.l)
Prototype.l PB_Object_Init            (StructureSize.l, IncrementStep.l, FreeObject.ObjectFreeFunction)
Prototype   PB_Object_GetThreadMemory (MemoryID.l)
Prototype.l PB_Object_InitThreadMemory(Size.l, InitFunction.ThreadFunction, EndFunction.ThreadFunction)
Global Object_GetOrAllocate   .PB_Object_GetOrAllocate
Global Object_GetObject       .PB_Object_GetObject
Global Object_IsObject        .PB_Object_IsObject
Global Object_EnumerateAll    .PB_Object_EnumerateAll
Global Object_EnumerateStart  .PB_Object_EnumerateStart
Global Object_EnumerateNext   .PB_Object_EnumerateNext
Global Object_EnumerateAbort  .PB_Object_EnumerateAbort
Global Object_Free            .PB_Object_Free
Global Object_Init            .PB_Object_Init
Global Object_GetThreadMemory .PB_Object_GetThreadMemory
Global Object_InitThreadMemory.PB_Object_InitThreadMemory
!extrn _PB_Object_GetOrAllocateID@8
!extrn _PB_Object_GetObject@8
!extrn _PB_Object_IsObject@8
!extrn _PB_Object_EnumerateAll@12
!extrn _PB_Object_EnumerateStart@4
!extrn _PB_Object_EnumerateNext@8
!extrn _PB_Object_EnumerateAbort@4
!extrn _PB_Object_FreeID@8
!extrn _PB_Object_Init@12
!extrn _PB_Object_GetThreadMemory@4
!extrn _PB_Object_InitThreadMemory@12
!MOV [v_Object_GetOrAllocate]   , _PB_Object_GetOrAllocateID@8
!MOV [v_Object_GetObject]       , _PB_Object_GetObject@8
!MOV [v_Object_IsObject]        , _PB_Object_IsObject@8
!MOV [v_Object_EnumerateAll]    , _PB_Object_EnumerateAll@12
!MOV [v_Object_EnumerateStart]  , _PB_Object_EnumerateStart@4
!MOV [v_Object_EnumerateNext]   , _PB_Object_EnumerateNext@8
!MOV [v_Object_EnumerateAbort]  , _PB_Object_EnumerateAbort@4
!MOV [v_Object_Free]            , _PB_Object_FreeID@8
!MOV [v_Object_Init]            , _PB_Object_Init@12
!MOV [v_Object_GetThreadMemory] , _PB_Object_GetThreadMemory@4
!MOV [v_Object_InitThreadMemory], _PB_Object_InitThreadMemory@12Code : Tout sélectionner
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