diff --git a/SConstruct b/SConstruct index fca9ccb..35b515c 100644 --- a/SConstruct +++ b/SConstruct @@ -21,7 +21,7 @@ target = "{}{}".format( # tweak this if you want to use different folders, or more folders, to store your source code in. env.Append(CPPPATH=["src/"]) -sources = [Glob('src/*.cpp'), Glob('src/vfs/*.cpp'), 'src/sqlite/sqlite3.c'] +sources = [Glob('src/*.cpp'), Glob('src/vfs/*.cpp'), Glob('src/resource/*.cpp'), 'src/sqlite/sqlite3.c'] if env["platform"] == "macos": target = "{}.{}.{}.framework/{}.{}.{}".format( @@ -40,4 +40,4 @@ else: ) library = env.SharedLibrary(target=target, source=sources) -Default(library) \ No newline at end of file +Default(library) diff --git a/demo/Main.tscn b/demo/Main.tscn index 695d889..8c247cd 100644 --- a/demo/Main.tscn +++ b/demo/Main.tscn @@ -1,7 +1,8 @@ -[gd_scene load_steps=4 format=3 uid="uid://dsba4ukrk2ymt"] +[gd_scene load_steps=5 format=3 uid="uid://dsba4ukrk2ymt"] [ext_resource type="Script" path="res://database.gd" id="1"] [ext_resource type="Script" path="res://Main.gd" id="2"] +[ext_resource type="SQLiteResource" path="res://data/test.db" id="3_onnij"] [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_45gfi"] content_margin_left = 24.0 @@ -21,6 +22,7 @@ script = ExtResource("2") [node name="Database" type="Node" parent="."] script = ExtResource("1") +db_resource = ExtResource("3_onnij") [node name="MarginContainer" type="MarginContainer" parent="."] layout_mode = 1 diff --git a/demo/database.gd b/demo/database.gd index cbd38f9..c547880 100644 --- a/demo/database.gd +++ b/demo/database.gd @@ -4,7 +4,7 @@ var db : SQLite = null const verbosity_level : int = SQLite.VERBOSE -var db_name := "res://data/test" +@export var db_resource : SQLiteResource var packaged_db_name := "res://data_to_be_packaged" var peristent_db_name := "user://my_database" var json_name := "res://data/test_backup" @@ -29,7 +29,6 @@ signal texture_received(texture) func _ready(): if OS.get_name() in ["Android", "iOS", "Web"]: copy_data_to_user() - db_name = "user://data/test" json_name = "user://data/test_backup" # Enable/disable examples here: @@ -77,7 +76,7 @@ func example_of_basic_database_querying(): table_dict["salary"] = {"data_type":"real"} db = SQLite.new() - db.path = db_name + db.path = db_resource.resource_path db.verbosity_level = verbosity_level # Open the database using the db_name found in the path variable db.open_db() @@ -249,7 +248,7 @@ func example_of_call_external_functions(): table_dict["salary"] = {"data_type":"real"} db = SQLite.new() - db.path = db_name + db.path = db_resource.resource_path db.verbosity_level = verbosity_level # Open the database using the db_name found in the path variable db.open_db() @@ -298,7 +297,7 @@ func example_of_blob_io(): var tex_data : PackedByteArray = texture.get_image().save_png_to_buffer() db = SQLite.new() - db.path = db_name + db.path = db_resource.resource_path db.verbosity_level = verbosity_level # Open the database using the db_name found in the path variable db.open_db() diff --git a/demo/project.godot b/demo/project.godot index a35a784..1dd631e 100644 --- a/demo/project.godot +++ b/demo/project.godot @@ -21,7 +21,7 @@ settings/stdout/verbose_stdout=true [editor_plugins] -enabled=PackedStringArray() +enabled=PackedStringArray("res://addons/godot-sqlite/plugin.cfg") [rendering] diff --git a/src/register_types.cpp b/src/register_types.cpp index 9601f4b..2907639 100644 --- a/src/register_types.cpp +++ b/src/register_types.cpp @@ -2,26 +2,54 @@ #include +#include #include #include #include #include "gdsqlite.h" +#include "resource/resource_loader_sqlite.h" +#include "resource/resource_sqlite.h" using namespace godot; +static Ref sqlite_loader; +const char *DEFAULT_DB_NAME = "filesystem/import/sqlite/default_extension"; + void initialize_sqlite_module(ModuleInitializationLevel p_level) { if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) { return; } - ClassDB::register_class(); + GDREGISTER_CLASS(SQLite); + GDREGISTER_CLASS(ResourceFormatLoaderSQLite); + GDREGISTER_CLASS(SQLiteResource); + + sqlite_loader.instantiate(); + ResourceLoader::get_singleton()->add_resource_format_loader(sqlite_loader); + PackedStringArray array; + array.push_back("db"); + + ProjectSettings *project_settings = ProjectSettings::get_singleton(); + + if (!project_settings->has_setting(DEFAULT_DB_NAME)) { + project_settings->set(DEFAULT_DB_NAME, ""); + } + + Dictionary property_info; + property_info["name"] = DEFAULT_DB_NAME; + property_info["type"] = godot::Variant::Type::STRING; + + project_settings->add_property_info(property_info); + project_settings->set_initial_value(DEFAULT_DB_NAME, "db"); } void uninitialize_sqlite_module(ModuleInitializationLevel p_level) { if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) { return; } + ResourceLoader::get_singleton()->remove_resource_format_loader(sqlite_loader); + sqlite_loader.unref(); } extern "C" { diff --git a/src/resource/resource_loader_sqlite.cpp b/src/resource/resource_loader_sqlite.cpp new file mode 100644 index 0000000..b3cbc9d --- /dev/null +++ b/src/resource/resource_loader_sqlite.cpp @@ -0,0 +1,26 @@ +#include "resource_loader_sqlite.h" +#include "resource_sqlite.h" +#include + +using namespace godot; + +Variant ResourceFormatLoaderSQLite::_load(const String &p_path, const String &original_path, bool use_sub_threads, int32_t cache_mode) const { + Ref sqlite_model = memnew(SQLiteResource); + sqlite_model->set_file(p_path); + return sqlite_model; +} +PackedStringArray ResourceFormatLoaderSQLite::_get_recognized_extensions() const { + return ProjectSettings::get_singleton()->get("filesystem/import/sqlite/default_extension"); +} +bool ResourceFormatLoaderSQLite::_handles_type(const StringName &type) const { + return ClassDB::is_parent_class(type, "SQLiteResource"); +} +String ResourceFormatLoaderSQLite::_get_resource_type(const String &p_path) const { + String el = p_path.get_extension().to_lower(); + for (String element : (PackedStringArray)ProjectSettings::get_singleton()->get("filesystem/import/sqlite/default_extension")) { + if (el == element) { + return "SQLiteResource"; + } + } + return ""; +} diff --git a/src/resource/resource_loader_sqlite.h b/src/resource/resource_loader_sqlite.h new file mode 100644 index 0000000..71d73b0 --- /dev/null +++ b/src/resource/resource_loader_sqlite.h @@ -0,0 +1,21 @@ +#ifndef SQLITE_LOADER_SQLITE_H +#define SQLITE_LOADER_SQLITE_H + +#include +#include + +using namespace godot; + +class ResourceFormatLoaderSQLite : public ResourceFormatLoader { + GDCLASS(ResourceFormatLoaderSQLite, ResourceFormatLoader); + +protected: + static void _bind_methods() {} + +public: + virtual Variant _load(const String &path, const String &original_path, bool use_sub_threads, int32_t cache_mode) const override; + virtual PackedStringArray _get_recognized_extensions() const override; + virtual bool _handles_type(const StringName &type) const override; + virtual String _get_resource_type(const String &p_path) const override; +}; +#endif // SQLITE_LOADER_SQLITE_H diff --git a/src/resource/resource_sqlite.cpp b/src/resource/resource_sqlite.cpp new file mode 100644 index 0000000..d22ef0c --- /dev/null +++ b/src/resource/resource_sqlite.cpp @@ -0,0 +1,13 @@ +#include "resource_sqlite.h" +#include + +#include + +void SQLiteResource::set_file(const String &p_file) { + file = p_file; + emit_changed(); +} + +String SQLiteResource::get_file() { + return file; +} diff --git a/src/resource/resource_sqlite.h b/src/resource/resource_sqlite.h new file mode 100644 index 0000000..356a0e7 --- /dev/null +++ b/src/resource/resource_sqlite.h @@ -0,0 +1,19 @@ +#ifndef SQLITE_RESOURCE_H +#define SQLITE_RESOURCE_H + +#include + +using namespace godot; + +class SQLiteResource : public Resource { + GDCLASS(SQLiteResource, Resource); + +protected: + static void _bind_methods() {} + String file; + +public: + void set_file(const String &p_file); + String get_file(); +}; +#endif // SQLITE_RESOURCE_H