#include "property.hpp" #include #include #include #include #include #include #include #include IkarusProperty::IkarusProperty(IkarusProject * project, IkarusId id, Data data): IkarusObject{project, id}, data{data} {} IKA_API void ikarus_property_delete(IkarusProperty * property, IkarusErrorData * error_out) { IKARUS_FAIL_IF_NULL(property, ); IKARUS_FAIL_IF_OBJECT_MISSING(property, ); IKARUS_TRYRV_OR_FAIL( , "unable to delete property: {}", IkarusErrorInfo_Database_QueryFailed, property->project->db->execute("DELETE FROM `objects` WHERE `id` = ?", property->id) ); property->project->uncache(property); } IkarusProject * ikarus_property_get_project(IkarusProperty const * property, IkarusErrorData * error_out) { return ikarus::util::object_get_project(property, error_out); } char const * ikarus_property_get_name(IkarusProperty const * property, IkarusErrorData * error_out) { return ikarus::util::object_get_name(property, error_out); } void ikarus_property_set_name(IkarusProperty * property, char const * name, IkarusErrorData * error_out) { ikarus::util::object_set_name(property, name, error_out); } IkarusPropertyType ikarus_property_get_type(IkarusProperty const * property, IkarusErrorData * error_out) { IKARUS_FAIL_IF_NULL(property, IkarusPropertyType_Toggle); IKARUS_FAIL_IF_OBJECT_MISSING(property, IkarusPropertyType_Toggle); IKARUS_VTRYRV_OR_FAIL( auto const ret, IkarusPropertyType_Toggle, "unable to fetch property type from database: {}", IkarusErrorInfo_Database_QueryFailed, property->project->db->query_one("SELECT `type` FROM `properties` WHERE `id` = ?", property->id) ); return static_cast(ret); } IkarusPropertyScope const * ikarus_property_get_scope(IkarusProperty const * property, IkarusErrorData * error_out) { IKARUS_FAIL_IF_NULL(property, nullptr); IKARUS_FAIL_IF_OBJECT_MISSING(property, nullptr); IKARUS_VTRYRV_OR_FAIL( auto const source, nullptr, "unable to fetch property source from database: {}", IkarusErrorInfo_Database_QueryFailed, property->project->db->query_one("SELECT `source` FROM `properties` WHERE `id` = ?", property->id) ); switch (ikarus_id_get_object_type(source)) { case IkarusObjectType_Blueprint: return new IkarusPropertyScope{property->project->get_blueprint(source)}; case IkarusObjectType_Entity: return new IkarusPropertyScope{property->project->get_entity(source)}; default: IKARUS_FAIL( nullptr, fmt::format("invalid property source type: {}", ikarus_object_type_to_string(ikarus_id_get_object_type(source))), IkarusErrorInfo_LibIkarus_InvalidState ); } } IkarusValue * ikarus_property_get_default_value(IkarusProperty const * property, IkarusErrorData * error_out) { IKARUS_FAIL_IF_NULL(property, nullptr); IKARUS_FAIL_IF_OBJECT_MISSING(property, nullptr); return fetch_value_from_db(property->project, error_out, "SELECT `default_value` FROM `properties` WHERE `id` = ?", property->id); } void ikarus_property_visit( IkarusProperty * property, void (*toggle_property_visitor)(struct IkarusToggleProperty *, void *), void (*number_property_visitor)(struct IkarusNumberProperty *, void *), void (*text_property_visitor)(struct IkarusTextProperty *, void *), void * data, IkarusErrorData * error_out ) { IKARUS_FAIL_IF_NULL(property, ); IKARUS_FAIL_IF_OBJECT_MISSING(property, ); std::visit( cppbase::overloaded{ [toggle_property_visitor, data](IkarusToggleProperty * property) { toggle_property_visitor(property, data); }, [number_property_visitor, data](IkarusNumberProperty * property) { number_property_visitor(property, data); }, [text_property_visitor, data](IkarusTextProperty * property) { text_property_visitor(property, data); } }, property->data ); } void ikarus_property_visit_const( IkarusProperty const * property, void (*toggle_property_visitor)(struct IkarusToggleProperty const *, void *), void (*number_property_visitor)(struct IkarusNumberProperty const *, void *), void (*text_property_visitor)(struct IkarusTextProperty const *, void *), void * data, IkarusErrorData * error_out ) { IKARUS_FAIL_IF_NULL(property, ); IKARUS_FAIL_IF_OBJECT_MISSING(property, ); std::visit( cppbase::overloaded{ [toggle_property_visitor, data](IkarusToggleProperty const * property) { toggle_property_visitor(property, data); }, [number_property_visitor, data](IkarusNumberProperty const * property) { number_property_visitor(property, data); }, [text_property_visitor, data](IkarusTextProperty const * property) { text_property_visitor(property, data); } }, property->data ); } // No existence checks here for performance reasons. All methods on IkarusObject perform this check anyway. IkarusObject * ikarus_property_to_object(IkarusProperty * property) { return static_cast(property); } IkarusObject const * ikarus_property_to_object_const(IkarusProperty const * property) { return static_cast(property); }