Replace godot_db_manager plugin with native DB, port lod plugin
godot_db_manager was incompatible with Godot 4 (used WindowDialog, Tabs, PopupPanel which were all removed). Replace with a minimal Database.gd that parses the same ahog.json format and exposes the same surface API (get_table_by_name, get_data_at_row_idx, edit_data, save_db, etc.) used by the M* model classes — no changes needed in MBase/MScene/MLevel/MSetting. Also port the lod plugin: fix class_name syntax (Godot 4 uses @icon separately from class_name extends) and Particles -> GPUParticles3D. Rewrite Global.gd async scene loading: the convert-3to4 tool mapped load_interactive -> load_threaded_request but those have different APIs (stage count, poll vs. status enum). Reimplement using the new load_threaded_get_status / load_threaded_get pair. Clean project.godot: drop the old _global_script_classes table (Godot 4 uses inline class_name declarations), remove gddb_* autoloads, and remove the godot_db_manager entry from editor_plugins. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+135
-34
@@ -1,47 +1,148 @@
|
||||
extends Node
|
||||
|
||||
func initialize():
|
||||
var database_manager = load(gddb_constants.c_addon_main_path + "core/db_man.gd").new()
|
||||
var db_id = database_manager.load_database(save_database_in())
|
||||
|
||||
check_invalid_type(db_id)
|
||||
check_invalid_version(db_id)
|
||||
|
||||
return database_manager.get_db_by_id(db_id)
|
||||
# Lightweight replacement for the godot_db_manager plugin (incompatible with
|
||||
# Godot 4). Keeps the ahog.json format used by the rest of the project and
|
||||
# exposes the same surface API the M* model classes expect:
|
||||
#
|
||||
# Global.database.get_table_by_name(name) -> Table
|
||||
# Global.database.save_db()
|
||||
# table.get_data_at_row_idx(row_id) -> [Cell, Cell, ...]
|
||||
# table.edit_data(prop_id, row_id, value)
|
||||
# table.m_rows_count
|
||||
# table.get_data_by_prop_name_and_data(prop_name, value) -> Array
|
||||
# table.get_dictionary_by_prop_name_and_data(prop_name, value) -> Array[Dict]
|
||||
# cell.get_data() -> String
|
||||
|
||||
func check_invalid_type(db_id):
|
||||
if db_id == gddb_types.e_db_invalid_file:
|
||||
print("[Database#check_invalid_type] Error invalid database file !")
|
||||
OS.set_exit_code(1)
|
||||
class Cell:
|
||||
var _value
|
||||
func _init(value):
|
||||
_value = value
|
||||
func get_data():
|
||||
return _value
|
||||
|
||||
func check_invalid_version(db_id):
|
||||
if db_id == gddb_types.e_db_invalid_ver:
|
||||
print("[Database#check_invalid_version] Error invalid database version !")
|
||||
OS.set_exit_code(1)
|
||||
class Table:
|
||||
var name: String
|
||||
var props: Array
|
||||
var data: Array
|
||||
var m_rows_count: int
|
||||
|
||||
func save_database_in():
|
||||
func _init(table_dict: Dictionary):
|
||||
name = table_dict["table_name"]
|
||||
props = table_dict["props"]
|
||||
data = table_dict["data"]
|
||||
m_rows_count = data.size() / max(1, props.size())
|
||||
|
||||
func _col_count() -> int:
|
||||
return props.size()
|
||||
|
||||
func _find_prop_idx(prop_name: String) -> int:
|
||||
for i in range(props.size()):
|
||||
if props[i]["name"] == prop_name:
|
||||
return i
|
||||
return -1
|
||||
|
||||
func get_data_at_row_idx(row_idx: int) -> Array:
|
||||
var start = row_idx * _col_count()
|
||||
var cells = []
|
||||
for i in range(_col_count()):
|
||||
cells.append(Cell.new(data[start + i]))
|
||||
return cells
|
||||
|
||||
func edit_data(prop_id: int, row_id: int, value) -> void:
|
||||
data[row_id * _col_count() + prop_id] = str(value)
|
||||
|
||||
func get_data_by_prop_name_and_data(prop_name: String, value) -> Array:
|
||||
var prop_idx = _find_prop_idx(prop_name)
|
||||
var matches = []
|
||||
if prop_idx == -1:
|
||||
return matches
|
||||
for row in range(m_rows_count):
|
||||
if data[row * _col_count() + prop_idx] == str(value):
|
||||
matches.append(row)
|
||||
return matches
|
||||
|
||||
func get_dictionary_by_prop_name_and_data(prop_name: String, value) -> Array:
|
||||
var prop_idx = _find_prop_idx(prop_name)
|
||||
var results = []
|
||||
if prop_idx == -1:
|
||||
return results
|
||||
for row in range(m_rows_count):
|
||||
if data[row * _col_count() + prop_idx] == str(value):
|
||||
var d = {}
|
||||
for i in range(_col_count()):
|
||||
d[props[i]["name"]] = data[row * _col_count() + i]
|
||||
results.append(d)
|
||||
return results
|
||||
|
||||
func to_dict() -> Dictionary:
|
||||
return {
|
||||
"table_name": name,
|
||||
"props": props,
|
||||
"data": data,
|
||||
}
|
||||
|
||||
class DB:
|
||||
var version: String
|
||||
var db_name: String
|
||||
var tables: Dictionary = {}
|
||||
var _path: String
|
||||
|
||||
func _init(path: String):
|
||||
_path = path
|
||||
var f = FileAccess.open(path, FileAccess.READ)
|
||||
if f == null:
|
||||
push_error("[Database] Cannot open " + path)
|
||||
return
|
||||
var raw = f.get_as_text()
|
||||
f.close()
|
||||
var doc = JSON.parse_string(raw)
|
||||
if doc == null:
|
||||
push_error("[Database] Invalid JSON in " + path)
|
||||
return
|
||||
version = doc.get("GDDB_ver", "")
|
||||
db_name = doc.get("db_name", "")
|
||||
for t in doc.get("tables", []):
|
||||
var table = Table.new(t)
|
||||
tables[table.name] = table
|
||||
|
||||
func get_table_by_name(name: String):
|
||||
return tables.get(name)
|
||||
|
||||
func save_db() -> void:
|
||||
var doc = {
|
||||
"GDDB_ver": version,
|
||||
"db_name": db_name,
|
||||
"tables": [],
|
||||
}
|
||||
for tname in tables:
|
||||
doc["tables"].append(tables[tname].to_dict())
|
||||
var f = FileAccess.open(_path, FileAccess.WRITE)
|
||||
if f == null:
|
||||
push_error("[Database] Cannot write " + _path)
|
||||
return
|
||||
f.store_string(JSON.stringify(doc))
|
||||
f.close()
|
||||
|
||||
func initialize() -> DB:
|
||||
return DB.new(save_database_in())
|
||||
|
||||
func save_database_in() -> String:
|
||||
if OS.get_name() == "Android":
|
||||
copy_database()
|
||||
return android_path()
|
||||
else:
|
||||
return normal_path()
|
||||
return normal_path()
|
||||
|
||||
func android_path():
|
||||
func android_path() -> String:
|
||||
return "user://database.json"
|
||||
|
||||
func normal_path():
|
||||
func normal_path() -> String:
|
||||
return "res://db/ahog.json"
|
||||
|
||||
func copy_database():
|
||||
var database_copy = File.new()
|
||||
|
||||
if !database_copy.file_exists(android_path()):
|
||||
var database_file = File.new()
|
||||
|
||||
database_file.open(normal_path(), File.READ)
|
||||
database_copy.open(android_path(), File.WRITE)
|
||||
database_copy.store_string(database_file.get_as_text())
|
||||
database_copy.close()
|
||||
|
||||
database_file.close()
|
||||
|
||||
func copy_database() -> void:
|
||||
if FileAccess.file_exists(android_path()):
|
||||
return
|
||||
var src = FileAccess.open(normal_path(), FileAccess.READ)
|
||||
var dst = FileAccess.open(android_path(), FileAccess.WRITE)
|
||||
dst.store_string(src.get_as_text())
|
||||
dst.close()
|
||||
src.close()
|
||||
|
||||
Reference in New Issue
Block a user