From ed0764b9eaf53630940a20c3d9a14d6899e11608 Mon Sep 17 00:00:00 2001 From: SoraKatadzuma Date: Fri, 28 Aug 2026 10:37:43 -0500 Subject: [PATCH] Runtime type information --- include/malunal/type.h | 211 ++++++++++++++++++++++++++++++++ include/malunal/types/bool.h | 38 ------ include/malunal/types/error.h | 3 +- include/malunal/types/integer.h | 158 ------------------------ include/malunal/types/object.h | 112 ++++++++++------- include/malunal/types/rtti.h | 161 ++++++++++++++++++++++++ include/malunal/types/string.h | 37 ------ include/malunal/types/uuid.h | 3 +- source/object.c | 76 ++++++++++++ 9 files changed, 518 insertions(+), 281 deletions(-) delete mode 100644 include/malunal/types/bool.h delete mode 100644 include/malunal/types/integer.h create mode 100644 include/malunal/types/rtti.h delete mode 100644 include/malunal/types/string.h diff --git a/include/malunal/type.h b/include/malunal/type.h index 123cbb6..af880b3 100644 --- a/include/malunal/type.h +++ b/include/malunal/type.h @@ -36,6 +36,27 @@ #define null ((malunal_mptr_t)0) #endif /* null */ +/** + * @def true + * @brief Defines the value of the boolean true. + * @details This is here just in case it is not defined anywhere else, to make + * boolean usage easier. + */ +#ifndef true +#define true 1 +#endif /* true */ + +/** + * @def false + * @brief Defines the value of the boolean false. + * @details This is here just in case it is not defined anywhere else, to make + * boolean usage easier. + */ +#ifndef false +#define false 0 +#endif /* false */ + + /** * @brief Our own definition of @c void. * @details This is provided, like all of the types in this header, to meet @@ -60,5 +81,195 @@ typedef void* malunal_mptr_t; */ typedef const void* malunal_iptr_t; +/** + * @brief Our own definition of @c bool. + * @details This is provided, like all of the types in this header, to meet + * modern standards and to exist specifically to match how we name + * many of our other types. + */ +typedef _Bool malunal_bool_t; + +/** + * @brief Our own definition of @c char. + * @details This is provided, like all of the types in this header, to meet + * modern standards and to exist specifically to match how we name + * many of our other types. + */ +typedef char malunal_char_t; + +/** + * @brief Our own definition of a mutable string. + * @details This is provided, like all of the types in this header, to meet + * modern standards and to exist specifically to match how we name + * many of our other types. + */ +typedef char* malunal_str_t; + +/** + * @brief Our own definition of a immutable string. + * @details This is provided, like all of the types in this header, to meet + * modern standards and to exist specifically to match how we name + * many of our other types. + */ +typedef const char* malunal_cstr_t; + +/** + * @brief Our own definition of an 8-bit signed integer. + * @details This is provided, like all of the types in this header, to meet + * modern standards and to exist specifically to match how we name + * many of our other types. + */ +typedef signed char malunal_int8_t; + +/** + * @brief Our own definition of an 16-bit signed integer. + * @details This is provided, like all of the types in this header, to meet + * modern standards and to exist specifically to match how we name + * many of our other types. + */ +typedef signed short malunal_int16_t; + +/** + * @brief Our own definition of an 32-bit signed integer. + * @details This is provided, like all of the types in this header, to meet + * modern standards and to exist specifically to match how we name + * many of our other types. + */ +typedef signed int malunal_int32_t; + +/** + * @brief Our own definition of an 8-bit unsigned integer. + * @details This is provided, like all of the types in this header, to meet + * modern standards and to exist specifically to match how we name + * many of our other types. + */ +typedef unsigned char malunal_uint8_t; + +/** + * @brief Our own definition of an 16-bit unsigned integer. + * @details This is provided, like all of the types in this header, to meet + * modern standards and to exist specifically to match how we name + * many of our other types. + */ +typedef unsigned short malunal_uint16_t; + +/** + * @brief Our own definition of an 32-bit unsigned integer. + * @details This is provided, like all of the types in this header, to meet + * modern standards and to exist specifically to match how we name + * many of our other types. + */ +typedef unsigned int malunal_uint32_t; + + +/** + * @typedef malunal_int64_t + * @brief Our own definition of an 64-bit signed integer. + * @details This is provided, like all of the types in this header, to meet + * modern standards and to exist specifically to match how we name + * many of our other types. + */ +/** + * @typedef malunal_uint64_t + * @brief Our own definition of an 64-bit unsigned integer. + * @details This is provided, like all of the types in this header, to meet + * modern standards and to exist specifically to match how we name + * many of our other types. + */ +#if defined(_MSC_VER) +typedef signed __int64 malunal_int64_t; +typedef unsigned __int64 malunal_uint64_t; +#else +typedef signed long long malunal_int64_t; +typedef unsigned long long malunal_uint64_t; +#endif /* Compiler specific. */ + + +/** + * @typedef malunal_ptrdiff_t + * @brief Our own definition of an 64-bit pointer difference. + * @details This is provided, like all of the types in this header, to meet + * modern standards and to exist specifically to match how we name + * many of our other types. + */ +/** + * @typedef malunal_intptr_t + * @brief Our own definition of an 64-bit signed integer pointer. + * @details This is provided, like all of the types in this header, to meet + * modern standards and to exist specifically to match how we name + * many of our other types. + */ +/** + * @typedef malunal_size_t + * @brief Our own definition of an 64-bit unsigned integer. + * @details This is provided, like all of the types in this header, to meet + * modern standards and to exist specifically to match how we name + * many of our other types. + */ +/** + * @typedef malunal_uintptr_t + * @brief Our own definition of an 64-bit unsigned integer pointer. + * @details This is provided, like all of the types in this header, to meet + * modern standards and to exist specifically to match how we name + * many of our other types. + */ +#if MALUNAL_POINTER_SIZE == 8 +typedef malunal_int64_t malunal_ptrdiff_t; +typedef malunal_int64_t malunal_intptr_t; +typedef malunal_uint64_t malunal_size_t; +typedef malunal_uint64_t malunal_uintptr_t; +#elif MALUNAL_POINTER_SIZE == 4 +typedef malunal_int32_t malunal_ptrdiff_t; +typedef malunal_int32_t malunal_intptr_t; +typedef malunal_uint32_t malunal_size_t; +typedef malunal_uint32_t malunal_uintptr_t; +#else +# error "Unsupported pointer size" +#endif + + +_Static_assert( + sizeof(malunal_int8_t) == 1, + "malunal_int8_t must be 1 byte" +); + +_Static_assert( + sizeof(malunal_int16_t) == 2, + "malunal_int16_t must be 2 bytes" +); + +_Static_assert( + sizeof(malunal_int32_t) == 4, + "malunal_int32_t must be 4 bytes" +); + +_Static_assert( + sizeof(malunal_int64_t) == 8, + "malunal_int64_t must be 8 bytes" +); + +_Static_assert( + sizeof(malunal_size_t) == sizeof(void*), + "malunal_size_t must match pointer width" +); + +_Static_assert( + sizeof(malunal_uintptr_t) == sizeof(void*), + "malunal_uintptr_t must match pointer width" +); + +/** + * @def define_struct + * @brief Defines a structure and its pointer types. + * @details This simplifies the way we typically define our structures, in which + * we define the structure itself and type definitions for the mutable + * and immutable pointers to that structure. + * @param name The name of the structure. + */ +#define define_struct(name) \ + typedef struct name name##_t; \ + typedef name##_t* name##_mptr_t; \ + typedef const name##_t* name##_iptr_t; \ + struct name #endif /* MALUNAL_TYPES_HEADER */ diff --git a/include/malunal/types/bool.h b/include/malunal/types/bool.h deleted file mode 100644 index 7924fdf..0000000 --- a/include/malunal/types/bool.h +++ /dev/null @@ -1,38 +0,0 @@ -/** - * @file bool.h - * @brief Contains the definition of a boolean type and its possible values. - * @author John Christman (sorakatadzuma@gmail.com) - * @copyright Malunal Studios, LLC. - */ -#ifndef MALUNAL_TYPES_BOOL_HEADER -#define MALUNAL_TYPES_BOOL_HEADER - -/** - * @def true - * @brief Defines the value of the boolean true. - * @details This is here just in case it is not defined anywhere else, to make - * boolean usage easier. - */ -#ifndef true -#define true 1 -#endif /* true */ - -/** - * @def false - * @brief Defines the value of the boolean false. - * @details This is here just in case it is not defined anywhere else, to make - * boolean usage easier. - */ -#ifndef false -#define false 0 -#endif /* false */ - -/** - * @brief Our own definition of @c bool. - * @details This is provided, like all of the types in this header, to meet - * modern standards and to exist specifically to match how we name - * many of our other types. - */ -typedef _Bool malunal_bool_t; - -#endif /* MALUNAL_TYPES_BOOL_HEADER */ diff --git a/include/malunal/types/error.h b/include/malunal/types/error.h index 8aa6a81..01c94d7 100644 --- a/include/malunal/types/error.h +++ b/include/malunal/types/error.h @@ -5,8 +5,7 @@ * @author John Christman (sorakatadzuma@gmail.com) * @copyright Malunal Studios, LLC. */ -#include "integer.h" -#include "string.h" +#include "../type.h" #ifndef MALUNAL_TYPES_ERROR_HEADER #define MALUNAL_TYPES_ERROR_HEADER diff --git a/include/malunal/types/integer.h b/include/malunal/types/integer.h deleted file mode 100644 index 4a05691..0000000 --- a/include/malunal/types/integer.h +++ /dev/null @@ -1,158 +0,0 @@ -/** - * @file int.h - * @brief Contains all of the integer related type definitions. - * @author John Christman (sorakatadzuma@gmail.com) - * @copyright Malunal Studios, LLC. - */ -#include "../type.h" - -#ifndef MALUNAL_TYPES_INT_HEADER -#define MALUNAL_TYPES_INT_HEADER - - -/** - * @brief Our own definition of an 8-bit signed integer. - * @details This is provided, like all of the types in this header, to meet - * modern standards and to exist specifically to match how we name - * many of our other types. - */ -typedef signed char malunal_int8_t; - -/** - * @brief Our own definition of an 16-bit signed integer. - * @details This is provided, like all of the types in this header, to meet - * modern standards and to exist specifically to match how we name - * many of our other types. - */ -typedef signed short malunal_int16_t; - -/** - * @brief Our own definition of an 32-bit signed integer. - * @details This is provided, like all of the types in this header, to meet - * modern standards and to exist specifically to match how we name - * many of our other types. - */ -typedef signed int malunal_int32_t; - -/** - * @brief Our own definition of an 8-bit unsigned integer. - * @details This is provided, like all of the types in this header, to meet - * modern standards and to exist specifically to match how we name - * many of our other types. - */ -typedef unsigned char malunal_uint8_t; - -/** - * @brief Our own definition of an 16-bit unsigned integer. - * @details This is provided, like all of the types in this header, to meet - * modern standards and to exist specifically to match how we name - * many of our other types. - */ -typedef unsigned short malunal_uint16_t; - -/** - * @brief Our own definition of an 32-bit unsigned integer. - * @details This is provided, like all of the types in this header, to meet - * modern standards and to exist specifically to match how we name - * many of our other types. - */ -typedef unsigned int malunal_uint32_t; - - -/** - * @typedef malunal_int64_t - * @brief Our own definition of an 64-bit signed integer. - * @details This is provided, like all of the types in this header, to meet - * modern standards and to exist specifically to match how we name - * many of our other types. - */ -/** - * @typedef malunal_uint64_t - * @brief Our own definition of an 64-bit unsigned integer. - * @details This is provided, like all of the types in this header, to meet - * modern standards and to exist specifically to match how we name - * many of our other types. - */ -#if defined(_MSC_VER) -typedef signed __int64 malunal_int64_t; -typedef unsigned __int64 malunal_uint64_t; -#else -typedef signed long long malunal_int64_t; -typedef unsigned long long malunal_uint64_t; -#endif /* Compiler specific. */ - - -/** - * @typedef malunal_ptrdiff_t - * @brief Our own definition of an 64-bit pointer difference. - * @details This is provided, like all of the types in this header, to meet - * modern standards and to exist specifically to match how we name - * many of our other types. - */ -/** - * @typedef malunal_intptr_t - * @brief Our own definition of an 64-bit signed integer pointer. - * @details This is provided, like all of the types in this header, to meet - * modern standards and to exist specifically to match how we name - * many of our other types. - */ -/** - * @typedef malunal_size_t - * @brief Our own definition of an 64-bit unsigned integer. - * @details This is provided, like all of the types in this header, to meet - * modern standards and to exist specifically to match how we name - * many of our other types. - */ -/** - * @typedef malunal_uintptr_t - * @brief Our own definition of an 64-bit unsigned integer pointer. - * @details This is provided, like all of the types in this header, to meet - * modern standards and to exist specifically to match how we name - * many of our other types. - */ -#if MALUNAL_POINTER_SIZE == 8 -typedef malunal_int64_t malunal_ptrdiff_t; -typedef malunal_int64_t malunal_intptr_t; -typedef malunal_uint64_t malunal_size_t; -typedef malunal_uint64_t malunal_uintptr_t; -#elif MALUNAL_POINTER_SIZE == 4 -typedef malunal_int32_t malunal_ptrdiff_t; -typedef malunal_int32_t malunal_intptr_t; -typedef malunal_uint32_t malunal_size_t; -typedef malunal_uint32_t malunal_uintptr_t; -#else -# error "Unsupported pointer size" -#endif - - -_Static_assert( - sizeof(malunal_int8_t) == 1, - "malunal_int8_t must be 1 byte" -); - -_Static_assert( - sizeof(malunal_int16_t) == 2, - "malunal_int16_t must be 2 bytes" -); - -_Static_assert( - sizeof(malunal_int32_t) == 4, - "malunal_int32_t must be 4 bytes" -); - -_Static_assert( - sizeof(malunal_int64_t) == 8, - "malunal_int64_t must be 8 bytes" -); - -_Static_assert( - sizeof(malunal_size_t) == sizeof(void*), - "malunal_size_t must match pointer width" -); - -_Static_assert( - sizeof(malunal_uintptr_t) == sizeof(void*), - "malunal_uintptr_t must match pointer width" -); - -#endif /* MALUNAL_TYPES_INT_HEADER */ diff --git a/include/malunal/types/object.h b/include/malunal/types/object.h index 43113d0..839b868 100644 --- a/include/malunal/types/object.h +++ b/include/malunal/types/object.h @@ -1,12 +1,12 @@ /** * @file object.h - * @brief Contains the definition of the virtual function table for the object - * interface and the object interface itself. + * @brief Contains the definition of the virtual function table for the + * @c object interface and the @c object interface itself. * @author John Christman (sorakatadzuma@gmail.com) * @copyright Malunal Studios, LLC. */ #include "error.h" -#include "uuid.h" +#include "rtti.h" #ifndef MALUNAL_TYPES_OBJECT_HEADER #define MALUNAL_TYPES_OBJECT_HEADER @@ -21,57 +21,33 @@ const uuid_t UUID_OBJECT_T; /** - * @brief Defines the object virtual function table. - * @details Implementing classes of the object interface are expected to provide - * valid pointers to these functions that are implementation specific. + * @brief Imports an external constant for the error domain of @c object_t. + * @details This is needed to detect from what domain an error has come from, + * so that error codes can mean different things based on its domain. */ -typedef struct { - /** - * @brief A pointer to a function which can will attempt to cast the given - * type specified by the @c uuid pointer, placing the address of the - * casted type into the @c out parameter, and indicating any error in - * the return value. - * @param self A pointer to the object to be scrutinized. - * @param uuid A pointer to The UUID of the interface or class from which - * @c self inherits. - * @param out A pointer to the location where a pointer to the base type that - * the @c uuid represents will be stored. - * @returns An error code if the object could not be casted. - */ - error_t(*const cast)(malunal_mptr_t self, uuid_iptr_t uuid, malunal_mptr_t* out); +extern +const error_domain_t +ERROR_DOMAIN_OBJECT_T; - /** - * @brief A pointer to a function which can retain a reference on the given - * generic object, returning the current number of references. - * @param self A pointer to the object that will be reference counted. - * @returns The number of references attached to the object after retaining a - * new reference. - */ - malunal_uint32_t(*const retain)(malunal_mptr_t self); - - /** - * @brief A pointer to a function which can release a reference on the given - * generic object, returning the current number of references. - * @param self A pointer to the object that will be reference counted. - * @returns The number of reference still attached to the object after releasing - * an old reference. - */ - malunal_uint32_t(*const release)(malunal_mptr_t self); -} object_vtable_t; /** * @brief Defines the object interface object. * @details Since this is only an interface, it only contains a pointer to the - * virtual table for itself. Other object which implement this, may - * come with member variables. + * runtime type information for itself. Other objects which implement + * this interface, should be able to provide its runtime type + * information through this pointer. */ typedef struct { /** - * @brief A pointer to an immutable object virtual function table. - * @details Contains function pointers to the object specific functions that - * make this object function as one. + * @brief The runtime type information for this object. + * @details Designed to provide information about the functional capabilities + * of this object from the perspective of the concrete type. Runtime + * type information provides the concrete type UUID, the size of the + * object, its interfaces, and its properties. This makes it possible + * to introspectively look at the object if all that is provided to a + * function is an @c object_t pointer. */ - const object_vtable_t* vtable; + rtti_iptr_t rtti; } object_t; /** @@ -88,4 +64,52 @@ typedef object_t* object_mptr_t; */ typedef const object_t* object_iptr_t; + +/** + * @brief A set of errors which an object itself may produce. + * @details These are very generic and designed for the object functions and the + * possible outputs from it. If an object function receives a null + * object or output pointer there are error codes for that. Likewise, + * if the object could not find a requested interface or property, + * there are error codes for that as well. + */ +typedef enum { + OBJECT_ERROR_NULL_OBJECT, + OBJECT_ERROR_NULL_OUTPUT, + OBJECT_ERROR_NOT_MY_INTERFACE, + OBJECT_ERROR_NOT_MY_PROPERTY +} object_error_t; + + +/** + * @brief Queries the object for the interface defined by @c iid. + * @param obj The object to query for the interface. + * @param iid The type UUID of the interface to query for. + * @param intf A pointer to where to store the interface information. + * @returns An error code if the object or the output is null or if the interface + * could not be found. + */ +error_t +object_query_interface( + object_iptr_t obj, + uuid_iptr_t iid, + rtti_intf_mptr_t intf +); + +/** + * @brief Queries the object for the property defined by @c name. + * @param obj The object to query for the property. + * @param name The name of the property to query. + * @param prop A pointer to where to store the property information. + * @returns An error code if the object or the output is null or if the property + * could not be found. + */ +error_t +object_query_property( + object_iptr_t obj, + malunal_cstr_t name, + rtti_prop_mptr_t prop +); + + #endif /* MALUNAL_TYPES_OBJECT_HEADER */ diff --git a/include/malunal/types/rtti.h b/include/malunal/types/rtti.h new file mode 100644 index 0000000..c90a938 --- /dev/null +++ b/include/malunal/types/rtti.h @@ -0,0 +1,161 @@ +/** + * @file rtti.h + * @brief Contains the definition of the runtime type information structures. + * @author John Christman (sorakatadzuma@gmail.com) + * @copyright Malunal Studios, LLC. + */ +#include "uuid.h" + +#ifndef MALUNAL_TYPES_RTTI_HEADER +#define MALUNAL_TYPES_RTTI_HEADER + +/** + * @brief Defines a runtime type information interface entry. + * @details This represents an entry into the runtime type information structure + * specifically for the interface of an object. A pointer to the type + * UUID and virtual function table is the fields that it provides. The + * combination of those fields makes is possible to query an interface + * from the given object. + */ +typedef struct { + /** + * @brief A pointer to the interface UUID. + * @details This is provided such that querying an interface is quicker and + * can be generic; that implementations do not need to specify the + * mapping of their inteface virtual function tables. + */ + uuid_iptr_t iid; + + /** + * @brief A pointer to the virtual function table of the interface. + * @details This is the provided value when an interface is queried from an + * object successfully. + */ + malunal_iptr_t vtable; +} rtti_intf_t; + +/** + * @brief A pointer to a mutable runtime type information interface entry. + * @details This is provided to simplify type declarations for functions + * requiring runtime type information interface entries that are meant + * to be mutable. + */ +typedef rtti_intf_t* rtti_intf_mptr_t; + +/** + * @brief A pointer to an immutable runtime type information interface entry. + * @details This is provided to simplify type declarations for functions + * requiring runtime type informaiton interface entries that are meant + * to be immutable. + */ +typedef const rtti_intf_t* rtti_intf_iptr_t; + + +/** + * @brief Defines a runtime type information property entry. + * @details This represents an entry into the runtime type information structure + * specifically for the properties of an object. A pointer to the name + * of the property and its own runtime type information is provided. + * The combination of those fields make it possible to query a property + * from the given object as if there was readonly reflection. + */ +typedef struct { + /** + * @brief The name of the property. + * @details This, like the interface UUID, make it possible to query the + * property of the object. + */ + malunal_cstr_t name; + + /** + * @brief The runtime type information of the property. + * @details The runtime type information of the property makes it possible to + * support a type of readonly reflection of the object. The object + * interface provides a function for obtaining the mutable value of + * the property. + */ + malunal_iptr_t rtti; +} rtti_prop_t; + +/** + * @brief A pointer to a mutable runtime type information property entry. + * @details This is provided to simplify type declarations for functions + * requiring runtime type information property entries that are meant + * to be mutable. + */ +typedef rtti_prop_t* rtti_prop_mptr_t; + +/** + * @brief A pointer to an immutable runtime type information property entry. + * @details This is provided to simplify type declarations for functions + * requiring runtime type information property entries that are meant + * to be immutable. + */ +typedef const rtti_prop_t* rtti_prop_iptr_t; + + +/** + * @brief Defines a runtime type information structure. + * @details The runtime type information structure is provided on an object in + * order to well define what type an object is, how large it is, its + * interfaces, and its properties. This is useful when performing type + * identification and checking, as well as object casting. + */ +typedef struct { + /** + * @brief The class UUID of the object. + * @details This is a concrete type UUID. It distinguishes each object by + * their type such that two objects cannot be cast to each other. + */ + uuid_iptr_t clsid; + + /** + * @brief The stride of this object. + * @details + */ + malunal_size_t stride; + + /** + * @brief A pointer to the interface entries of this runtime type information. + * @details This contains the UUIDs and virtual function tables of all the + * interfaces that the current object implements. + */ + rtti_intf_iptr_t pIntfs; + + /** + * @brief A pointer to the property entries of this runtime type information. + * @details This contains the name and runtime type information of all the + * properties that the current object has. + */ + rtti_prop_iptr_t pProps; + + /** + * @brief The number of interface entries in this runtime type information. + * @details This is provided to allow the interfaces to be iterated during the + * querying operation. + */ + malunal_size_t nIntfs; + + /** + * @brief The number of property entries in this runtime type information. + * @details This is provided to allow the properties to be iterated during the + * querying operation and for obtaining the value of a property. + */ + malunal_size_t nProps; +} rtti_t; + +/** + * @brief A pointer to a mutable runtime type information. + * @details This is provided to simplify type declarations for functions + * requiring runtime type information that are meant to be mutable. + */ +typedef rtti_t* rtti_mptr_t; + +/** + * @brief A pointer to an immutable runtime type information. + * @details This is provided to simplify type declarations for functions + * requiring runtime type information that are meant to be immutable. + */ +typedef const rtti_t* rtti_iptr_t; + +#endif /* MALUNAL_TYPES_RTTI_HEADER */ diff --git a/include/malunal/types/string.h b/include/malunal/types/string.h deleted file mode 100644 index d6b6404..0000000 --- a/include/malunal/types/string.h +++ /dev/null @@ -1,37 +0,0 @@ -/** - * @file string.h - * @brief Contains the definitions of character and string types. - * @author John Christman (sorakatadzuma@gmail.com) - * @copyright Malunal Studios, LLC. - */ -#include "../type.h" - -// TODO: add support for wide characters. -#ifndef MALUNAL_TYPES_STRING_HEADER -#define MALUNAL_TYPES_STRING_HEADER - -/** - * @brief Our own definition of @c char. - * @details This is provided, like all of the types in this header, to meet - * modern standards and to exist specifically to match how we name - * many of our other types. - */ -typedef char malunal_char_t; - -/** - * @brief Our own definition of a mutable string. - * @details This is provided, like all of the types in this header, to meet - * modern standards and to exist specifically to match how we name - * many of our other types. - */ -typedef char* malunal_str_t; - -/** - * @brief Our own definition of a immutable string. - * @details This is provided, like all of the types in this header, to meet - * modern standards and to exist specifically to match how we name - * many of our other types. - */ -typedef const char* malunal_cstr_t; - -#endif /* MALUNAL_TYPES_STRING_HEADER */ diff --git a/include/malunal/types/uuid.h b/include/malunal/types/uuid.h index e5353a3..3abd9b6 100644 --- a/include/malunal/types/uuid.h +++ b/include/malunal/types/uuid.h @@ -4,8 +4,7 @@ * @author John Christman (sorakatadzuma@gmail.com) * @copyright Malunal Studios, LLC. */ -#include "bool.h" -#include "integer.h" +#include "../type.h" #ifndef MALUNAL_TYPES_UUID_HEADER #define MALUNAL_TYPES_UUID_HEADER diff --git a/source/object.c b/source/object.c index 7547434..6b24e69 100644 --- a/source/object.c +++ b/source/object.c @@ -1,3 +1,4 @@ +#include #include "malunal/types/object.h" @@ -12,3 +13,78 @@ const uuid_t UUID_OBJECT_T = { 0x6C, 0x9C, 0x3A } }; + + +error_t +object_query_interface( + object_iptr_t obj, + uuid_iptr_t iid, + rtti_intf_mptr_t intf +) { + if (obj == null) + return (error_t) { + .domain = &ERROR_DOMAIN_OBJECT_T, + .code = OBJECT_ERROR_NULL_OBJECT + }; + + if (intf == null) + return (error_t) { + .domain = &ERROR_DOMAIN_OBJECT_T, + .code = OBJECT_ERROR_NULL_OUTPUT + }; + + malunal_size_t index; + rtti_intf_mptr_t entry; + for (index = 0; index < obj->rtti->nIntfs; index++) { + entry = &obj->rtti->pIntfs[index]; + if (uuid_equals(iid, entry->iid)) { + intf->iid = entry->iid; + intf->vtable = entry->vtable; + return NO_ERROR; + } + } + + intf->iid = null; + intf->vtable = null; + return (error_t) { + .domain = &ERROR_DOMAIN_OBJECT_T, + .code = OBJECT_ERROR_NOT_MY_INTERFACE + }; +} + +error_t +object_query_property( + object_iptr_t obj, + malunal_cstr_t name, + rtti_prop_mptr_t prop +) { + if (obj == null) + return (error_t) { + .domain = &ERROR_DOMAIN_OBJECT_T, + .code = OBJECT_ERROR_NOT_MY_INTERFACE + }; + + if (prop == null) + return (error_t) { + .domain = &ERROR_DOMAIN_OBJECT_T, + .code = OBJECT_ERROR_NULL_OUTPUT + }; + + malunal_size_t index; + rtti_prop_mptr_t entry; + for (index = 0; index < obj->rtti->nProps; index++) { + entry = &obj->rtti->pProps[index]; + if (strcmp(name, entry->name) == 0) { + prop->name = entry->name; + prop->rtti = entry->rtti; + return NO_ERROR; + } + } + + prop->name = null; + prop->rtti = null; + return (error_t) { + .domain = &ERROR_DOMAIN_OBJECT_T, + .code = OBJECT_ERROR_NOT_MY_PROPERTY + }; +}