implement blueprint functionality & streamline API
Signed-off-by: Folling <mail@folling.io>
This commit is contained in:
parent
a2b5c573b2
commit
d3e93b6a72
9 changed files with 175 additions and 229 deletions
135
src/objects/blueprint.cpp
Normal file
135
src/objects/blueprint.cpp
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
#include "blueprint.hpp"
|
||||
|
||||
#include <cppbase/logger.hpp>
|
||||
#include <cppbase/result.hpp>
|
||||
#include <cppbase/strings.hpp>
|
||||
|
||||
#include <ikarus/objects/blueprint.h>
|
||||
#include <ikarus/objects/entity.h>
|
||||
#include <ikarus/objects/object_type.h>
|
||||
|
||||
#include <id.hpp>
|
||||
#include <objects/entity.hpp>
|
||||
#include <objects/property.hpp>
|
||||
#include <persistence/project.hpp>
|
||||
|
||||
IkarusBlueprint * ikarus_blueprint_create(struct IkarusProject * project, char const * name) {
|
||||
LOG_INFO("creating new blueprint");
|
||||
|
||||
if (project == nullptr) {
|
||||
LOG_ERROR("project is nullptr");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
LOG_VERBOSE("project={}; name={}", project->path.c_str(), name);
|
||||
|
||||
if (name == nullptr) {
|
||||
LOG_ERROR("name is nullptr");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (cppbase::is_empty_or_blank(name)) {
|
||||
LOG_ERROR("name is empty or blank");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
VTRYRV(auto id, nullptr, project->db->transact([name](auto * db) -> cppbase::Result<IkarusId, sqlitecpp::TransactionError> {
|
||||
LOG_VERBOSE("creating blueprint in objects table");
|
||||
|
||||
TRY(db->execute(
|
||||
"INSERT INTO `objects` (`object_type`, `name`) VALUES(?, ?);", static_cast<int>(IkarusObjectType_Blueprint), name
|
||||
));
|
||||
|
||||
auto id = db->last_insert_rowid();
|
||||
|
||||
LOG_VERBOSE("blueprint is {}", id);
|
||||
|
||||
LOG_VERBOSE("inserting blueprint into blueprints table");
|
||||
|
||||
TRY(db->execute("INSERT INTO `blueprints`(`id`) VALUES(?);", id));
|
||||
|
||||
return cppbase::ok(id);
|
||||
}));
|
||||
|
||||
LOG_VERBOSE("successfully created blueprint");
|
||||
|
||||
return new IkarusBlueprint{project, id};
|
||||
}
|
||||
|
||||
void ikarus_blueprint_delete(IkarusBlueprint * blueprint) {
|
||||
LOG_INFO("deleting blueprint");
|
||||
|
||||
if (blueprint == nullptr) {
|
||||
LOG_ERROR("blueprint is nullptr");
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_VERBOSE("blueprint={}", blueprint->id);
|
||||
|
||||
if (auto res = blueprint->project->db->execute("DELETE FROM `objects` WHERE `id` = ?", blueprint->id); res.is_err()) {
|
||||
LOG_ERROR("failed to delete blueprint {} from objects table: {}", blueprint->id, res.unwrap_error());
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_VERBOSE("blueprint was successfully deleted from database, freeing pointer");
|
||||
|
||||
delete blueprint;
|
||||
|
||||
LOG_VERBOSE("successfully deleted blueprint");
|
||||
}
|
||||
|
||||
size_t ikarus_blueprint_get_property_count(IkarusBlueprint const * blueprint) {
|
||||
LOG_VERBOSE("fetching blueprint property count");
|
||||
|
||||
if (blueprint == nullptr) {
|
||||
LOG_ERROR("blueprint is nullptr");
|
||||
return 0;
|
||||
}
|
||||
|
||||
LOG_VERBOSE("blueprint={}", blueprint->id);
|
||||
|
||||
VTRYRV(
|
||||
auto count,
|
||||
0,
|
||||
blueprint->project->db->query_one<int>(
|
||||
"SELECT COUNT(*) FROM `blueprint_properties` WHERE `blueprint_id` = ?;", blueprint->id
|
||||
)
|
||||
);
|
||||
|
||||
return static_cast<size_t>(count);
|
||||
}
|
||||
|
||||
void ikarus_blueprint_get_properties(
|
||||
IkarusBlueprint const * blueprint, struct IkarusProperty ** properties_out, size_t properties_out_size
|
||||
) {
|
||||
LOG_VERBOSE("fetching blueprint properties");
|
||||
|
||||
if (blueprint == nullptr) {
|
||||
LOG_ERROR("blueprint is nullptr");
|
||||
return;
|
||||
}
|
||||
|
||||
if (properties_out == nullptr) {
|
||||
LOG_ERROR("properties_out is nullptr");
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_VERBOSE("blueprint={}; properties_out_size={}", blueprint->id, properties_out_size);
|
||||
|
||||
IkarusId ids[properties_out_size];
|
||||
|
||||
if (auto res = blueprint->project->db->query_many_buffered<IkarusId>(
|
||||
"SELECT `id` FROM `properties` WHERE `source` = ?", static_cast<IkarusId *>(ids), properties_out_size, blueprint->id
|
||||
);
|
||||
res.is_err()) {
|
||||
LOG_ERROR("failed to fetch blueprint property ids: {}", res.unwrap_error());
|
||||
return;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < properties_out_size; ++i) {
|
||||
/// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
||||
properties_out[i] = new IkarusProperty{blueprint->project, ids[i]};
|
||||
}
|
||||
|
||||
LOG_VERBOSE("successfully fetched blueprint properties");
|
||||
}
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
#pragma once
|
||||
|
||||
#include <id.hpp>
|
||||
#include <objects/object.hpp>
|
||||
|
||||
/// \private
|
||||
struct IkarusBlueprint {
|
||||
struct IkarusProject * project;
|
||||
IkarusId id;
|
||||
struct IkarusBlueprint : public IkarusObject {
|
||||
inline IkarusBlueprint(struct IkarusProject * project, IkarusId id):
|
||||
IkarusObject{project, id} {}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,9 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include <id.hpp>
|
||||
#include <objects/object.hpp>
|
||||
|
||||
/// \private
|
||||
struct IkarusEntity {
|
||||
struct IkarusProject * project;
|
||||
IkarusId id;
|
||||
};
|
||||
struct IkarusEntity : public IkarusObject {};
|
||||
|
|
|
|||
|
|
@ -2,12 +2,13 @@
|
|||
|
||||
#include <variant>
|
||||
|
||||
#include <objects/blueprint.hpp>
|
||||
#include <objects/entity.hpp>
|
||||
#include <objects/property.hpp>
|
||||
#include <id.hpp>
|
||||
|
||||
union IkarusObject {
|
||||
IkarusBlueprint blueprint;
|
||||
IkarusEntity entity;
|
||||
IkarusProperty property;
|
||||
struct IkarusObject {
|
||||
struct IkarusProject * project;
|
||||
IkarusId id;
|
||||
|
||||
inline IkarusObject(struct IkarusProject * project, IkarusId id):
|
||||
project{project},
|
||||
id{id} {}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
#pragma once
|
||||
|
||||
#include <id.hpp>
|
||||
#include <objects/object.hpp>
|
||||
|
||||
/// \private
|
||||
struct IkarusProperty {
|
||||
struct IkarusProject * project;
|
||||
IkarusId id;
|
||||
struct IkarusProperty : public IkarusObject {
|
||||
inline IkarusProperty(struct IkarusProject * project, IkarusId id):
|
||||
IkarusObject{project, id} {}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -2,8 +2,7 @@ CREATE TABLE `objects`
|
|||
(
|
||||
`do_not_access_rowid_alias` INTEGER PRIMARY KEY,
|
||||
`object_type` INT NOT NULL,
|
||||
`id` INT GENERATED ALWAYS AS (`do_not_access_rowid_alias` | (`object_type` << 56)
|
||||
) VIRTUAL,
|
||||
`id` INT GENERATED ALWAYS AS (`do_not_access_rowid_alias` | (`object_type` << 56)) VIRTUAL,
|
||||
`name` TEXT NOT NULL,
|
||||
`information` TEXT NOT NULL
|
||||
) STRICT;
|
||||
|
|
@ -47,6 +46,7 @@ CREATE TABLE `entity_blueprints`
|
|||
|
||||
PRIMARY KEY (`entity`),
|
||||
UNIQUE (`entity`, `blueprint`),
|
||||
FOREIGN KEY (`entity`) REFERENCES `entities` (`id`) ON DELETE CASCADE,
|
||||
FOREIGN KEY (`blueprint`) REFERENCES `blueprints` (`id`) ON DELETE CASCADE
|
||||
) WITHOUT ROWID, STRICT;
|
||||
|
||||
|
|
@ -58,12 +58,15 @@ CREATE TABLE `properties`
|
|||
`type` INT NOT NULL,
|
||||
`default_value` TEXT NOT NULL,
|
||||
`settings` TEXT NOT NULL,
|
||||
`source` INT NOT NULL,
|
||||
|
||||
PRIMARY KEY (`id`),
|
||||
FOREIGN KEY (`id`) REFERENCES `objects` (`id`) ON DELETE CASCADE
|
||||
FOREIGN KEY (`id`) REFERENCES `objects` (`id`) ON DELETE CASCADE,
|
||||
FOREIGN KEY (`source`) REFERENCES `objects` (`id`) ON DELETE CASCADE
|
||||
) WITHOUT ROWID, STRICT;
|
||||
|
||||
CREATE INDEX `properties_type` ON `properties` (`type`);
|
||||
CREATE INDEX `properties_source` ON `properties` (`source`);
|
||||
|
||||
CREATE
|
||||
VIRTUAL TABLE `property_default_value_fts` USING fts5
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue