------------------------------------------------------------------------------ -- AGAR CORE LIBRARY -- -- A G A R . O B J E C T -- -- B o d y -- -- -- -- Copyright (c) 2018-2023, Julien Nadeau Carriere (vedge@csoft.net) -- -- Copyright (c) 2010, coreland (mark@coreland.ath.cx) -- -- -- -- Permission to use, copy, modify, and/or distribute this software for any -- -- purpose with or without fee is hereby granted, provided that the above -- -- copyright notice and this permission notice appear in all copies. -- -- -- -- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -- -- WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -- -- MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -- -- ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -- -- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -- -- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -- -- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -- ------------------------------------------------------------------------------ with Agar.Error; package body Agar.Object is use Interfaces.C; use Agar.Event; function New_Object (Parent : in Object_Access; Name : in String; Class : in Class_Not_Null_Access) return Object_Access is Ch_Name : aliased C.char_array := C.To_C(Name); begin return AG_ObjectNew (Parent => Parent.all'Address, Name => CS.To_Chars_Ptr(Ch_Name'Unchecked_Access), Class => Class); end; function New_Object (Parent : in Object_Access; Class : in Class_Not_Null_Access) return Object_Access is begin return AG_ObjectNew (Parent => Parent.all'Address, Name => CS.Null_Ptr, Class => Class); end; function New_Object (Class : in Class_Not_Null_Access) return Object_Access is begin return AG_ObjectNew (Parent => System.Null_Address, Name => CS.Null_Ptr, Class => Class); end; procedure Init_Object (Object : in Object_Not_Null_Access; Class : in Class_Not_Null_Access; Static : in Boolean := False; Name_On_Attach : in Boolean := False) is C_Flags : C.unsigned := 0; begin AG_ObjectInit (Object, Class); C_Flags := Object.Flags; if Static then C_Flags := C_Flags or OBJECT_STATIC; end if; if Name_On_Attach then C_Flags := C_Flags or OBJECT_NAME_ON_ATTACH; end if; Object.Flags := C_Flags; end; procedure Attach (Parent : in Object_Access; Child : in Object_not_null_Access) is begin AG_ObjectAttach (Parent => Parent, Child => Child); end; function Find (Root : in Object_Not_Null_Access; Path : in String) return Object_Access is Ch_Path : aliased C.char_array := C.To_C(Path); begin return AG_ObjectFindS (Root => Root, Path => CS.To_Chars_Ptr(Ch_Path'Unchecked_Access)); end; function Find_Parent (Object : in Object_Not_Null_Access; Name : in String; Class : in String) return Object_Access is Ch_Name : aliased C.char_array := C.To_C(Name); Ch_Class : aliased C.char_array := C.To_C(Class); begin return AG_ObjectFindParent (Object => Object, Name => CS.To_Chars_Ptr(Ch_Name'Unchecked_Access), Class => CS.To_Chars_Ptr(Ch_Class'Unchecked_Access)); end; function Find_Child (Parent : in Object_Not_Null_Access; Name : in String) return Object_Access is Ch_Name : aliased C.char_array := C.To_C(Name); begin return AG_ObjectFindChild (Parent => Parent, Name => CS.To_Chars_Ptr(Ch_Name'Unchecked_Access)); end; function Get_Name (Object : in Object_Not_Null_Access) return String is Ch_Name : aliased C.char_array (0 .. C.size_t(HIER_MAX)); Result : C.int; begin Result := AG_ObjectCopyName (Object => Object, Buffer => Ch_Name'Address, Size => Ch_Name'Length); if Integer(Result) /= 0 then raise Program_Error with Agar.Error.Get_Error; end if; return C.To_Ada(Ch_Name); end; procedure Set_Name (Object : in Object_Not_Null_Access; Name : in String) is Ch_Name : aliased C.char_array := C.To_C(Name); begin AG_ObjectSetNameS (Object => Object, Name => CS.To_Chars_Ptr(Ch_Name'Unchecked_Access)); end; function Generate_Name (Object : in Object_Not_Null_Access; Class : in Class_Not_Null_Access) return String is Ch_Name : aliased C.char_array (0 .. C.size_t(NAME_MAX)); begin AG_ObjectGenName (Object => Object, Class => Class, Buffer => Ch_Name'Address, Size => Ch_Name'Length); return C.To_Ada(Ch_Name); end; function Generate_Name (Object : in Object_Not_Null_Access; Prefix : in String) return String is Ch_Name : aliased C.char_array (0 .. C.size_t(NAME_MAX)); Ch_Prefix : aliased C.char_array := C.To_C(Prefix); begin AG_ObjectGenNamePfx (Object => Object, Prefix => CS.To_Chars_Ptr(Ch_Prefix'Unchecked_Access), Buffer => Ch_Name'Address, Size => Ch_Name'Length); return C.To_Ada(Ch_Name); end; procedure Register_Namespace (Name : in String; Prefix : in String; URL : in String) is Ch_Name : aliased C.char_array := C.To_C(Name); Ch_Prefix : aliased C.char_array := C.To_C(Prefix); Ch_URL : aliased C.char_array := C.To_C(URL); begin AG_RegisterNamespace (Name => CS.To_Chars_Ptr(Ch_Name'Unchecked_Access), Prefix => CS.To_Chars_Ptr(Ch_Prefix'Unchecked_Access), URL => CS.To_Chars_Ptr(Ch_URL'Unchecked_Access)); end; procedure Unregister_Namespace (Name : in String) is Ch_Name : aliased C.char_array := C.To_C(Name); begin AG_UnregisterNamespace(CS.To_Chars_Ptr(Ch_Name'Unchecked_Access)); end; function Create_Class (Hierarchy : in String; Object_Size : in Natural; Class_Size : in Natural; Major : in Natural := 1; Minor : in Natural := 0; Init_Func : in Init_Func_Access := null; Reset_Func : in Reset_Func_Access := null; Destroy_Func : in Destroy_Func_Access := null; Load_Func : in Load_Func_Access := null; Save_Func : in Save_Func_Access := null; Edit_Func : in Edit_Func_Access := null) return Class_Not_Null_Access is Ch_Hierarchy : aliased C.char_array := C.To_C(Hierarchy); Class : Class_Access; begin Class := AG_CreateClass (Hierarchy => CS.To_Chars_Ptr(Ch_Hierarchy'Unchecked_Access), Object_Size => AG_Size(Object_Size / System.Storage_Unit), Class_Size => AG_Size(Class_Size / System.Storage_Unit), Major => C.unsigned(Major), Minor => C.unsigned(Minor)); if Class = null then raise Program_Error with Agar.Error.Get_Error; end if; if Init_Func /= null then AG_ClassSetInit (Class, Init_Func); end if; if Reset_Func /= null then AG_ClassSetReset (Class, Reset_Func); end if; if Destroy_Func /= null then AG_ClassSetDestroy (Class, Destroy_Func); end if; if Load_Func /= null then AG_ClassSetLoad (Class, Load_Func); end if; if Save_Func /= null then AG_ClassSetSave (Class, Save_Func); end if; if Edit_Func /= null then AG_ClassSetEdit (Class, Edit_Func); end if; return Class; end Create_Class; procedure Class_Set_Init (Class : in Class_Not_Null_Access; Init_Func : in Init_Func_Access) is begin AG_ClassSetInit(Class, Init_Func); end; function Class_Set_Init (Class : in Class_Not_Null_Access; Init_Func : in Init_Func_Access) return Init_Func_Access is begin return AG_ClassSetInit(Class, Init_Func); end; procedure Class_Set_Reset (Class : in Class_Not_Null_Access; Reset_Func : in Reset_Func_Access) is begin AG_ClassSetReset(Class, Reset_Func); end; function Class_Set_Reset (Class : in Class_Not_Null_Access; Reset_Func : in Reset_Func_Access) return Reset_Func_Access is begin return AG_ClassSetReset(Class, Reset_Func); end; procedure Class_Set_Destroy (Class : in Class_Not_Null_Access; Destroy_Func : in Destroy_Func_Access) is begin AG_ClassSetDestroy(Class, Destroy_Func); end; function Class_Set_Destroy (Class : in Class_Not_Null_Access; Destroy_Func : in Destroy_Func_Access) return Destroy_Func_Access is begin return AG_ClassSetDestroy(Class, Destroy_Func); end; procedure Class_Set_Load (Class : in Class_Not_Null_Access; Load_Func : in Load_Func_Access) is begin AG_ClassSetLoad(Class, Load_Func); end; function Class_Set_Load (Class : in Class_Not_Null_Access; Load_Func : in Load_Func_Access) return Load_Func_Access is begin return AG_ClassSetLoad(Class, Load_Func); end; procedure Class_Set_Save (Class : in Class_Not_Null_Access; Save_Func : in Save_Func_Access) is begin AG_ClassSetSave(Class, Save_Func); end; function Class_Set_Save (Class : in Class_Not_Null_Access; Save_Func : in Save_Func_Access) return Save_Func_Access is begin return AG_ClassSetSave(Class, Save_Func); end; procedure Class_Set_Edit (Class : in Class_Not_Null_Access; Edit_Func : in Edit_Func_Access) is begin AG_ClassSetEdit(Class, Edit_Func); end; function Class_Set_Edit (Class : in Class_Not_Null_Access; Edit_Func : in Edit_Func_Access) return Edit_Func_Access is begin return AG_ClassSetEdit(Class, Edit_Func); end; function Lookup_Class (Class : in String) return Class_Access is Ch_Class : aliased C.char_array := C.To_C(Class); begin return AG_LookupClass (Class => CS.To_Chars_Ptr(Ch_Class'Unchecked_Access)); end; function Load_Class (Class : in String) return Class_Access is Ch_Class : aliased C.char_array := C.To_C(Class); begin return AG_LoadClass (Class => CS.To_Chars_Ptr(Ch_Class'Unchecked_Access)); end; procedure Register_Module_Directory (Path : in String) is Ch_Path : aliased C.char_array := C.To_C(Path); begin AG_RegisterModuleDirectory (Path => CS.To_Chars_Ptr(Ch_Path'Unchecked_Access)); end; procedure Unregister_Module_Directory (Path : in String) is Ch_Path : aliased C.char_array := C.To_C(Path); begin AG_UnregisterModuleDirectory (Path => CS.To_Chars_Ptr(Ch_Path'Unchecked_Access)); end; function Is_Of_Class (Object : in Object_Not_Null_Access; Pattern : in String) return Boolean is Ch_Pattern : aliased C.char_array := C.To_C(Pattern); begin return AG_OfClass (Object => Object, Pattern => CS.To_Chars_Ptr(Ch_Pattern'Unchecked_Access)) = 1; end; function Is_A (Object : in Object_Not_Null_Access; Pattern : in String) return Boolean is Ch_Pattern : aliased C.char_array := C.To_C(Pattern); begin return AG_OfClass (Object => Object, Pattern => CS.To_Chars_Ptr(Ch_Pattern'Unchecked_Access)) = 1; end; ------------------- -- Serialization -- ------------------- function Load (Object : in Object_Not_Null_Access) return Boolean is begin return AG_ObjectLoad(Object) = 0; end; function Load (Object : in Object_Not_Null_Access; File : in String) return Boolean is Ch_File : aliased C.char_array := C.To_C(File); begin return AG_ObjectLoadFromFile (Object => Object, File => CS.To_Chars_Ptr(Ch_File'Unchecked_Access)) = 0; end; function Load_Data (Object : in Object_Not_Null_Access) return Boolean is begin return AG_ObjectLoadData(Object) = 0; end; function Load_Data (Object : in Object_Not_Null_Access; File : in String) return Boolean is Ch_File : aliased C.char_array := C.To_C(File); begin return AG_ObjectLoadDataFromFile (Object => Object, File => CS.To_Chars_Ptr(Ch_File'Unchecked_Access)) = 0; end; function Load_Generic (Object : in Object_Not_Null_Access) return Boolean is begin return AG_ObjectLoadGeneric(Object) = 0; end; function Load_Generic (Object : in Object_Not_Null_Access; File : in String) return Boolean is Ch_File : aliased C.char_array := C.To_C(File); begin return AG_ObjectLoadGenericFromFile (Object => Object, File => CS.To_Chars_Ptr(Ch_File'Unchecked_Access)) = 0; end; function Save (Object : in Object_Not_Null_Access) return Boolean is begin return AG_ObjectSave(Object) = 0; end; function Save (Object : in Object_Not_Null_Access; File : in String) return Boolean is Ch_File : aliased C.char_array := C.To_C(File); begin return AG_ObjectSaveToFile (Object => Object, File => CS.To_Chars_Ptr(Ch_File'Unchecked_Access)) = 0; end; function Save_All (Object : in Object_Not_Null_Access) return Boolean is begin return AG_ObjectSaveAll(Object) = 0; end; function Serialize (Object : in Object_Not_Null_Access; Source : in DS.Data_Source_Not_Null_Access) return Boolean is begin return AG_ObjectSerialize(Object, Source) = 0; end; function Unserialize (Object : in Object_Not_Null_Access; Source : in DS.Data_Source_Not_Null_Access) return Boolean is begin return AG_ObjectUnserialize(Object, Source) = 0; end; function Read_Header (Source : in DS.Data_Source_Not_Null_Access; Header : in Header_Access) return Boolean is begin return AG_ObjectReadHeader (Source, Header) = 0; end; ------------ -- Events -- ------------ function Set_Event (Object : in Object_Not_Null_Access; Event : in String; Func : in Event_Func_Access; Async : in Boolean := False; Propagate : in Boolean := False) return Event_Not_Null_Access is Ch_Event : aliased C.char_array := C.To_C(Event); Result : constant Event_Not_Null_Access := AG_SetEvent (Object => Object, Event => CS.To_Chars_Ptr(Ch_Event'Unchecked_Access), Func => Func, Format => CS.Null_Ptr); begin -- TODO Async, Propagate return (Result); end; procedure Set_Event (Object : in Object_Not_Null_Access; Event : in String; Func : in Event_Func_Access; Async : in Boolean := False; Propagate : in Boolean := False) is Ch_Event : aliased C.char_array := C.To_C(Event); begin AG_SetEvent (Object => Object, Event => CS.To_Chars_Ptr(Ch_Event'Unchecked_Access), Func => Func, Format => CS.Null_Ptr); end; function Add_Event (Object : in Object_Not_Null_Access; Event : in String; Func : in Event_Func_Access; Async : in Boolean := False; Propagate : in Boolean := False) return Event_Not_Null_Access is Ch_Event : aliased C.char_array := C.To_C(Event); Result : constant Event_Not_Null_Access := AG_AddEvent (Object => Object, Event => CS.To_Chars_Ptr(Ch_Event'Unchecked_Access), Func => Func, Format => CS.Null_Ptr); begin return (Result); end; procedure Add_Event (Object : in Object_Not_Null_Access; Event : in String; Func : in Event_Func_Access; Async : in Boolean := False; Propagate : in Boolean := False) is Ch_Event : aliased C.char_array := C.To_C(Event); begin AG_AddEvent (Object => Object, Event => CS.To_Chars_Ptr(Ch_Event'Unchecked_Access), Func => Func, Format => CS.Null_Ptr); end; procedure Post_Event (Object : in Object_Not_Null_Access; Event : in String) is Ch_Event : aliased C.char_array := C.To_C(Event); begin AG_PostEvent (Object => Object, Event => CS.To_Chars_Ptr(Ch_Event'Unchecked_Access), Format => CS.Null_Ptr); end; procedure Post_Event (Object : in Object_Not_Null_Access; Event : in Event_Not_Null_Access) is begin AG_PostEventByPtr (Object => Object, Event => Event, Format => CS.Null_Ptr); end; procedure Debug (Object : in Object_Access; Message : in String) is Ch_Format : aliased C.char_array := C.To_C("%s"); Ch_Message : aliased C.char_array := C.To_C(Message); begin AG_Debug (Object => Object, Format => CS.To_Chars_Ptr(Ch_Format'Unchecked_Access), Message => CS.To_Chars_Ptr(Ch_Message'Unchecked_Access)); end; ------------ -- Timers -- ------------ function Add_Timer (Object : in Object_Access; Timer : in TMR.Timer_not_null_Access; Interval : in Interfaces.Unsigned_32; Func : in TMR.Timer_Callback) return Boolean is begin return 0 = AG_AddTimer (Object => Object, Timer => Timer, Interval => Interval, Func => Func, Flags => 0, Format => CS.Null_Ptr); end; function Add_Timer (Object : in Object_Access; Interval : in Interfaces.Unsigned_32; Func : in TMR.Timer_Callback) return TMR.Timer_Access is begin return AG_AddTimerAuto (Object => Object, Interval => Interval, Func => Func, Format => CS.Null_Ptr); end; --------------- -- Variables -- --------------- function Defined (Object : in Object_not_null_Access; Variable : in String) return Boolean is Ch_Name : aliased C.char_array := C.To_C(Variable); Result : C.int; begin Lock(Object); Result := AG_Defined (Object => Object, Name => CS.To_Chars_Ptr(Ch_Name'Unchecked_Access)); Unlock(Object); return Result = 1; end; -- -- Compare two variables with no dereference. Discrete types are compared -- by value. Strings are compared case-sensitively. Reference types are -- compared by their pointer value. -- function "=" (Left, Right : in Variable_not_null_Access) return Boolean is begin return 0 = AG_CompareVariables (Left, Right); end; end Agar.Object;