179 lines
6.4 KiB
C++
179 lines
6.4 KiB
C++
#include "property.hpp"
|
|
|
|
#include <cppbase/logger.hpp>
|
|
|
|
#include <ikarus/objects/properties/property_type.h>
|
|
|
|
#include <objects/properties/property_source.hpp>
|
|
#include <persistence/function_context.hpp>
|
|
#include <persistence/project.hpp>
|
|
#include <sys/stat.h>
|
|
#include <values/value.hpp>
|
|
|
|
IkarusProperty::IkarusProperty(IkarusProject * project, IkarusId id, Data data):
|
|
IkarusObject{project, id},
|
|
_data{data} {}
|
|
|
|
IkarusProperty::Data & IkarusProperty::get_data() {
|
|
return _data;
|
|
}
|
|
|
|
IkarusProperty::Data const & IkarusProperty::get_data() const {
|
|
return _data;
|
|
}
|
|
|
|
cppbase::Result<IkarusPropertyType, sqlitecpp::SingleQueryError> IkarusProperty::get_property_type(IkarusProject * project, IkarusId id) {
|
|
LOG_DEBUG("fetching unboxed property type");
|
|
|
|
LOG_VERBOSE("project={};property={}", project->get_path().c_str(), id);
|
|
|
|
auto * ctx = project->get_function_context();
|
|
|
|
VTRY(
|
|
auto const type,
|
|
project->get_db()->query_one<int>("SELECT `type` FROM `properties` WHERE `id` = ?", id).on_error([ctx](auto const & err) {
|
|
ctx->set_error(
|
|
fmt::format("failed to fetch unboxed property type: {}", err),
|
|
true,
|
|
IkarusErrorInfo_Source_SubSystem,
|
|
IkarusErrorInfo_Type_SubSystem_Database
|
|
);
|
|
})
|
|
);
|
|
|
|
return cppbase::ok(static_cast<IkarusPropertyType>(type));
|
|
}
|
|
|
|
IKA_API void ikarus_property_delete(IkarusProperty * property) {
|
|
LOG_INFO("deleting property");
|
|
|
|
LOG_VERBOSE("project={};property={}", property->project->get_path().c_str(), property->id);
|
|
|
|
auto * ctx = property->project->get_function_context();
|
|
|
|
TRYRV(, property->project->get_db()->execute("DELETE FROM `objects` WHERE `id` = ?", property->id).on_error([ctx](auto const & err) {
|
|
ctx->set_error(
|
|
fmt::format("failed to delete property from objects table: {}", err),
|
|
true,
|
|
IkarusErrorInfo_Source_SubSystem,
|
|
IkarusErrorInfo_Type_SubSystem_Database
|
|
);
|
|
}));
|
|
|
|
LOG_VERBOSE("property was successfully deleted from database, freeing");
|
|
|
|
property->project->uncache(property);
|
|
|
|
LOG_VERBOSE("successfully deleted property");
|
|
}
|
|
|
|
IkarusPropertyType ikarus_property_get_type(IkarusProperty const * property) {
|
|
LOG_VERBOSE("fetching property type");
|
|
|
|
return IkarusProperty::get_property_type(property->project, property->id).unwrap_value_or(IkarusPropertyType_Toggle);
|
|
}
|
|
|
|
IkarusPropertySource const * ikarus_property_get_source(IkarusProperty const * property) {
|
|
LOG_VERBOSE("fetching property source");
|
|
|
|
LOG_VERBOSE("project={};property={}", property->project->get_path().c_str(), property->id);
|
|
|
|
auto * ctx = property->project->get_function_context();
|
|
|
|
VTRYRV(
|
|
auto const source,
|
|
nullptr,
|
|
property->project->get_db()
|
|
->query_one<int>("SELECT `source` FROM `properties` WHERE `id` = ?", property->id)
|
|
.on_error([ctx](auto const & err) {
|
|
ctx->set_error(
|
|
fmt::format("failed to fetch property's source: {}", err),
|
|
true,
|
|
IkarusErrorInfo_Source_SubSystem,
|
|
IkarusErrorInfo_Type_SubSystem_Database
|
|
);
|
|
})
|
|
);
|
|
|
|
switch (ikarus_id_get_object_type(source)) {
|
|
case IkarusObjectType_Blueprint: return new IkarusPropertySource{property->project->get_blueprint(source)};
|
|
case IkarusObjectType_Entity: return new IkarusPropertySource{property->project->get_entity(source)};
|
|
default: {
|
|
ctx->set_error(
|
|
fmt::format("PropertySource is neither blueprint nor entity"),
|
|
true,
|
|
IkarusErrorInfo_Source_LibIkarus,
|
|
IkarusErrorInfo_Type_LibIkarus_InvalidState
|
|
);
|
|
|
|
return nullptr;
|
|
}
|
|
}
|
|
}
|
|
|
|
IkarusValue * ikarus_property_get_default_value(IkarusProperty const * property) {
|
|
LOG_VERBOSE("fetching property default value");
|
|
|
|
LOG_VERBOSE("project={};property={}", property->project->get_path().c_str(), property->id);
|
|
|
|
auto * ctx = property->project->get_function_context();
|
|
|
|
VTRYRV(
|
|
auto const value,
|
|
nullptr,
|
|
property->project->get_db()
|
|
->query_one<int>("SELECT `default_value` FROM `properties` WHERE `id` = ?", property->id)
|
|
.on_error([ctx](auto const & err) {
|
|
ctx->set_error(
|
|
fmt::format("failed to fetch property's default value: {}", err),
|
|
true,
|
|
IkarusErrorInfo_Source_SubSystem,
|
|
IkarusErrorInfo_Type_SubSystem_Database
|
|
);
|
|
})
|
|
);
|
|
|
|
return IkarusValue::from_json(value).unwrap_value_or(nullptr);
|
|
}
|
|
|
|
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
|
|
) {
|
|
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->get_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
|
|
) {
|
|
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->get_data()
|
|
);
|
|
}
|
|
|
|
IkarusObject * ikarus_property_to_object(IkarusProperty * property) {
|
|
return static_cast<IkarusObject *>(property);
|
|
}
|
|
|
|
IkarusObject const * ikarus_property_to_object_const(IkarusProperty const * property) {
|
|
return static_cast<IkarusObject const *>(property);
|
|
}
|