157 lines
4.3 KiB
GDScript
157 lines
4.3 KiB
GDScript
@tool
|
|
extends EditorPlugin
|
|
|
|
const ADDONS_PATH := "res://addons/"
|
|
const PLUGIN_CONFIG_DIR := "plugins/plugin_refresher"
|
|
const PLUGIN_CONFIG := "settings.cfg"
|
|
const PLUGIN_NAME := "Godot Plugin Refresher"
|
|
const SETTINGS := "settings"
|
|
const SETTING_RECENT := "recently_used"
|
|
const Refresher := preload("plugin_refresher.gd")
|
|
|
|
var plugin_config := ConfigFile.new()
|
|
var refresher: Refresher = null
|
|
|
|
|
|
func _enter_tree() -> void:
|
|
refresher = preload("plugin_refresher.tscn").instantiate() as Refresher
|
|
add_control_to_container(CONTAINER_TOOLBAR, refresher)
|
|
|
|
# Watch whether any plugin is changed, added or removed on the filesystem
|
|
var efs := EditorInterface.get_resource_filesystem()
|
|
efs.filesystem_changed.connect(_on_filesystem_changed)
|
|
|
|
refresher.request_refresh_plugin.connect(_on_request_refresh_plugin)
|
|
refresher.confirm_refresh_plugin.connect(_on_confirm_refresh_plugin)
|
|
|
|
_reload_plugins_list()
|
|
_load_settings()
|
|
|
|
|
|
func _exit_tree() -> void:
|
|
remove_control_from_container(CONTAINER_TOOLBAR, refresher)
|
|
refresher.free()
|
|
|
|
|
|
func _reload_plugins_list() -> void:
|
|
var cfg_paths: Array[String] = []
|
|
var plugins := {}
|
|
var display_names_map := {} # full path to display name
|
|
|
|
find_cfgs(ADDONS_PATH, cfg_paths)
|
|
|
|
for cfg_path in cfg_paths:
|
|
var plugin_cfg := ConfigFile.new()
|
|
var err := plugin_cfg.load(cfg_path)
|
|
if err:
|
|
push_error("ERROR LOADING PLUGIN FILE: %s" % err)
|
|
else:
|
|
var plugin_name := plugin_cfg.get_value("plugin", "name")
|
|
if plugin_name != PLUGIN_NAME:
|
|
var addon_dir_name = cfg_path.split("addons/")[-1].split("/plugin.cfg")[0]
|
|
plugins[addon_dir_name] = [plugin_name, cfg_path]
|
|
|
|
# This will be an array of the addon/* directory names.
|
|
var plugin_dirs: Array[String] = []
|
|
plugin_dirs.assign(plugins.keys()) # typed array "casting"
|
|
|
|
var plugin_names: Array[String] = []
|
|
plugin_names.assign(plugin_dirs.map(func(k): return plugins[k][0]))
|
|
|
|
for plugin_dirname in plugin_dirs:
|
|
var plugin_name = plugins[plugin_dirname][0]
|
|
var display_name = plugin_name if plugin_names.count(plugin_name) == 1 else "%s (%s)" % [plugin_name, plugin_dirname]
|
|
display_names_map[plugins[plugin_dirname][1]] = display_name
|
|
|
|
refresher.update_items([plugins, display_names_map])
|
|
|
|
|
|
func find_cfgs(dir_path: String, cfgs: Array):
|
|
var dir := DirAccess.open(dir_path)
|
|
var cfg_path := dir_path.path_join("plugin.cfg")
|
|
|
|
if dir.file_exists(cfg_path):
|
|
cfgs.append(cfg_path)
|
|
return
|
|
|
|
if dir:
|
|
dir.list_dir_begin()
|
|
var file_name := dir.get_next()
|
|
while file_name != "":
|
|
if dir.current_is_dir():
|
|
find_cfgs(dir_path.path_join(file_name), cfgs)
|
|
file_name = dir.get_next()
|
|
|
|
|
|
func _load_settings() -> void:
|
|
var path := get_settings_path()
|
|
|
|
if not FileAccess.file_exists(path):
|
|
# Create new if running for the first time
|
|
var config := ConfigFile.new()
|
|
DirAccess.make_dir_recursive_absolute(path.get_base_dir())
|
|
config.save(path)
|
|
else:
|
|
plugin_config.load(path)
|
|
|
|
|
|
func _save_settings() -> void:
|
|
plugin_config.save(get_settings_path())
|
|
|
|
|
|
func get_settings_path() -> String:
|
|
var editor_paths := EditorInterface.get_editor_paths()
|
|
var dir := editor_paths.get_project_settings_dir()
|
|
|
|
var home := dir.path_join(PLUGIN_CONFIG_DIR)
|
|
var path := home.path_join(PLUGIN_CONFIG)
|
|
|
|
return path
|
|
|
|
|
|
func _on_filesystem_changed() -> void:
|
|
if refresher:
|
|
_reload_plugins_list()
|
|
var recent = get_recent_plugin()
|
|
if recent:
|
|
refresher.select_plugin(recent)
|
|
|
|
|
|
func get_recent_plugin() -> String:
|
|
if not plugin_config.has_section_key(SETTINGS, SETTING_RECENT):
|
|
return "" # not saved yet
|
|
|
|
var recent = str(plugin_config.get_value(SETTINGS, SETTING_RECENT))
|
|
return recent
|
|
|
|
|
|
func _on_request_refresh_plugin(p_path: String) -> void:
|
|
assert(not p_path.is_empty())
|
|
|
|
var disabled := not EditorInterface.is_plugin_enabled(p_path)
|
|
if disabled:
|
|
refresher.show_warning(p_path)
|
|
else:
|
|
refresh_plugin(p_path)
|
|
|
|
|
|
func _on_confirm_refresh_plugin(p_path: String) -> void:
|
|
refresh_plugin(p_path)
|
|
|
|
|
|
func get_plugin_path() -> String:
|
|
return get_script().resource_path.get_base_dir()
|
|
|
|
|
|
func refresh_plugin(p_path: String) -> void:
|
|
print("Refreshing plugin: ", p_path)
|
|
|
|
var enabled := EditorInterface.is_plugin_enabled(p_path)
|
|
if enabled: # can only disable an active plugin
|
|
EditorInterface.set_plugin_enabled(p_path, false)
|
|
|
|
EditorInterface.set_plugin_enabled(p_path, true)
|
|
|
|
plugin_config.set_value(SETTINGS, SETTING_RECENT, p_path)
|
|
_save_settings()
|