Skip to content

Commit b142e47

Browse files
committed
Cache emulator paths
1 parent 03a98e6 commit b142e47

File tree

6 files changed

+94
-70
lines changed

6 files changed

+94
-70
lines changed

scenes/config/settings/emulator/EmulatorEditor.gd

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,16 @@ func set_curr_emulator(_curr_emulator: Dictionary):
2626
n_logo.text = "<click to add>" if not n_logo.icon else ""
2727
n_name.text = curr_emulator["name"]
2828
n_fullname.text = curr_emulator["fullname"]
29-
n_path.text = RetroHubGenericEmulator.find_and_substitute_str(curr_emulator["binpath"], {})
29+
n_path.text = RetroHubGenericEmulator.find_path(curr_emulator, "binpath", {})
3030
n_command.text = curr_emulator["command"]
3131

3232
func save() -> Dictionary:
3333
curr_emulator["fullname"] = n_fullname.text
3434
curr_emulator["binpath"] = n_path.text
3535
curr_emulator["command"] = n_command.text
3636

37+
RetroHubConfig.set_emulator_path(curr_emulator["name"], "binpath", n_path.text)
38+
3739
return curr_emulator
3840

3941
func reset():

scenes/config/settings/emulator/RetroArchEmulatorEditor.gd

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,11 @@ func set_curr_emulator(_curr_emulator: Dictionary):
3535
n_logo.text = "<click to add>" if not n_logo.icon else ""
3636
n_name.text = curr_emulator["name"]
3737
n_fullname.text = curr_emulator["fullname"]
38-
n_path.text = RetroHubGenericEmulator.find_and_substitute_str(curr_emulator["binpath"], {})
38+
n_path.text = RetroHubGenericEmulator.find_path(curr_emulator, "binpath", {})
3939
n_core_path.text = RetroHubRetroArchEmulator.get_custom_core_path()
4040
if n_core_path.text.is_empty():
41-
n_core_path.text = RetroHubGenericEmulator.find_and_substitute_str(
42-
curr_emulator["corepath"],
41+
n_core_path.text = RetroHubGenericEmulator.find_path(
42+
curr_emulator, "corepath",
4343
{"binpath": n_path.text}
4444
)
4545
n_command.text = curr_emulator["command"]
@@ -69,6 +69,9 @@ func save() -> Dictionary:
6969

7070
curr_emulator["cores"] = cores.duplicate(true)
7171

72+
RetroHubConfig.set_emulator_path("retroarch", "binpath", n_path.text)
73+
RetroHubConfig.set_emulator_path("retroarch", "corepath", n_core_path.text)
74+
7275
return curr_emulator
7376

7477
func reset():

scenes/popups/first_time/EmulatorsSection.gd

Lines changed: 14 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ signal advance_section
77
@onready var n_emulator_info_tab := %EmulatorInfoTab
88

99
var icon_cache := {}
10-
var emulator_cache := {}
1110

1211
func _ready():
1312
n_systems.get_popup().max_size.y = RetroHubUI.max_popupmenu_height + 50
@@ -39,7 +38,6 @@ func set_systems():
3938
else:
4039
n_systems.add_icon_item(preload("res://assets/icons/failure.svg"), system["fullname"])
4140
n_systems.set_item_metadata(n_systems.get_item_count()-1, false)
42-
emulator_cache.clear()
4341

4442
func handle_emulator_info(system_raw: Dictionary) -> bool:
4543
var system_emulators : Array = system_raw["emulator"]
@@ -52,38 +50,18 @@ func handle_emulator_info(system_raw: Dictionary) -> bool:
5250
var emulator : Dictionary = emulators["retroarch"]
5351
parent.add_child(retroarch_info)
5452

55-
if not emulator_cache.has("retroarch"):
56-
emulator_cache["retroarch"] = {}
57-
5853
# Test for binpath first
59-
var binpaths
60-
if emulator_cache["retroarch"].has("binpaths"):
61-
binpaths = emulator_cache["retroarch"]["binpaths"]
62-
else:
63-
binpaths = emulator["binpath"]
64-
emulator_cache["retroarch"]["binpaths"] = binpaths
65-
var binpath : String
66-
if emulator_cache["retroarch"].has("binpath"):
67-
binpath = emulator_cache["retroarch"]["binpath"]
68-
else:
69-
binpath = FileUtils.test_for_valid_path(binpaths)
70-
emulator_cache["retroarch"]["binpath"] = binpath
54+
var binpath := RetroHubRetroArchEmulator.find_path(emulator, "binpath", {})
7155
if not binpath.is_empty():
7256
retroarch_info.set_path_found(true, binpath)
7357
# Then test for cores
7458
var required_cores : Array = system_emulator["retroarch"]
75-
var corespath : String
76-
if emulator_cache["retroarch"].has("corespath"):
77-
corespath = emulator_cache["retroarch"]["corespath"]
78-
else:
79-
corespath = RetroHubRetroArchEmulator.get_custom_core_path()
80-
if corespath.is_empty():
81-
corespath = JSONUtils.format_string_with_substitutes(FileUtils.test_for_valid_path(emulator["corepath"]) , {"binpath": binpath})
82-
if corespath.is_empty():
83-
retroarch_info.set_core_found(false, "Could not find any cores inside:\n" + convert_list_to_string(emulator["corepath"]))
84-
emulator_cache["retroarch"]["corespath"] = corespath
85-
continue
86-
emulator_cache["retroarch"]["corespath"] = corespath
59+
var corespath := RetroHubRetroArchEmulator.get_custom_core_path()
60+
if corespath.is_empty():
61+
corespath = JSONUtils.format_string_with_substitutes(FileUtils.test_for_valid_path(emulator["corepath"]) , {"binpath": binpath})
62+
if corespath.is_empty():
63+
retroarch_info.set_core_found(false, "Could not find any cores inside:\n" + convert_list_to_string(emulator["corepath"]))
64+
continue
8765
var cores : Array = emulator["cores"]
8866
var avail_cores := []
8967
for req_core in required_cores:
@@ -94,9 +72,12 @@ func handle_emulator_info(system_raw: Dictionary) -> bool:
9472
retroarch_info.set_core_found(false, "No default config for cores:\n" + convert_list_to_string(required_cores))
9573
continue
9674
var corepaths := []
75+
var corepath := ""
9776
for core in avail_cores:
77+
corepath = RetroHubRetroArchEmulator.find_core_path(core["name"], emulator, corespath)
78+
if not corepath.is_empty():
79+
break
9880
corepaths.push_back(corespath.path_join(core["file"]))
99-
var corepath := FileUtils.test_for_valid_path(corepaths)
10081
if not corepath.is_empty():
10182
for core in avail_cores:
10283
if core["file"] == corepath.get_file():
@@ -106,7 +87,7 @@ func handle_emulator_info(system_raw: Dictionary) -> bool:
10687
retroarch_info.set_core_found(false, convert_list_to_string(corepaths))
10788
continue
10889
else:
109-
retroarch_info.set_path_found(false, convert_list_to_string(binpaths))
90+
retroarch_info.set_path_found(false, convert_list_to_string(emulator["binpath"]))
11091
continue
11192

11293
elif emulators.has(system_emulator):
@@ -115,36 +96,19 @@ func handle_emulator_info(system_raw: Dictionary) -> bool:
11596
var emulator : Dictionary = emulators[system_emulator]
11697
parent.add_child(generic_info)
11798

118-
if not emulator_cache.has(emulator["name"]):
119-
emulator_cache[emulator["name"]] = {}
120-
12199
generic_info.set_name(emulator["fullname"])
122100
if not icon_cache.has(system_emulator):
123101
icon_cache[system_emulator] = load("res://assets/emulators/%s.png" % system_emulator)
124102
generic_info.set_logo(icon_cache[system_emulator])
125103

126104
# Test for binpath first
127-
var binpaths
128-
if emulator_cache[emulator["name"]].has("binpaths"):
129-
binpaths = emulator_cache[emulator["name"]]["binpaths"]
130-
else:
131-
binpaths = emulator["binpath"]
132-
emulator_cache[emulator["name"]]["binpaths"] = binpaths
133-
var binpath : String
134-
if emulator_cache[emulator["name"]].has("binpath"):
135-
binpath = emulator_cache[emulator["name"]]["binpath"]
136-
else:
137-
binpath = FileUtils.test_for_valid_path(binpaths)
138-
emulator_cache[emulator["name"]]["binpath"] = binpath
105+
var binpath := RetroHubGenericEmulator.find_path(emulator, "binpath", {})
139106
if not binpath.is_empty():
140107
found = true
141108
generic_info.set_found(true, binpath)
142109
continue
143-
elif binpaths is Array:
144-
generic_info.set_found(false, convert_list_to_string(binpaths))
145-
continue
146110
else:
147-
generic_info.set_found(false, binpaths)
111+
generic_info.set_found(false, convert_list_to_string(emulator["binpath"]))
148112
continue
149113
return found
150114

source/Config.gd

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ var systems : Dictionary
2121
var _systems_raw : Dictionary
2222
var _system_renames : Dictionary
2323
var emulators_map : Dictionary
24+
var emulators_paths : Dictionary
25+
var _should_save := false
2426

2527
var _is_sc := false
2628

@@ -96,6 +98,8 @@ func load_emulators():
9698
emulators_map[child["name"]].merge(child, true)
9799
emulators_map[child["name"]]["#modified"] = true
98100
JSONUtils.make_system_specific(emulators_map, FileUtils.get_os_string())
101+
# Load emulator paths
102+
emulators_paths = JSONUtils.load_json_file(get_emulator_paths_file())
99103

100104
func set_system_renaming():
101105
for system_name in config.system_names:
@@ -585,8 +589,12 @@ func bootstrap_config_dir():
585589
push_error("Error when creating directory " + path)
586590

587591
# Bootstrap system specific configs
588-
for filename in ["emulators.json", "systems.json"]:
589-
var filepath_out := get_config_dir() + "/rh_" + (filename as String)
592+
for filename in [
593+
"rh_emulators.json",
594+
"rh_systems.json",
595+
"_emulator_paths.json"
596+
]:
597+
var filepath_out := get_config_dir() + "/" + (filename as String)
590598
var file := FileAccess.open(filepath_out, FileAccess.WRITE)
591599
if not file:
592600
push_error("Error when opening file " + filepath_out + " for saving")
@@ -601,6 +609,9 @@ func save_config():
601609
if config.save_config_to_path(get_config_file()):
602610
push_error("Error when saving config to " + get_config_file())
603611
save_theme_config()
612+
if _should_save:
613+
_should_save = false
614+
JSONUtils.save_json_file(emulators_paths, get_emulator_paths_file())
604615

605616
func _restore_keys(dict: Dictionary, keys: Array):
606617
for key in keys:
@@ -718,6 +729,25 @@ func _determine_sc_mode():
718729
if FileAccess.file_exists(exe_path + "/._sc_") or FileAccess.file_exists(exe_path + "/_sc_"):
719730
_is_sc = true
720731

732+
func get_emulator_path(emulator_name: String, key: String) -> String:
733+
if emulators_paths.has(emulator_name) and emulators_paths[emulator_name].has(key):
734+
return emulators_paths[emulator_name][key]
735+
return ""
736+
737+
func set_emulator_path(emulator_name: String, key: String, value: String) -> void:
738+
if value.is_empty():
739+
if emulators_paths.has(emulator_name):
740+
emulators_paths[emulator_name].erase(key)
741+
if emulators_paths[emulator_name].is_empty():
742+
emulators_paths.erase(emulator_name)
743+
_should_save = true
744+
return
745+
746+
if not emulators_paths.has(emulator_name):
747+
emulators_paths[emulator_name] = {}
748+
emulators_paths[emulator_name][key] = value
749+
_should_save = true
750+
721751
func get_config_dir() -> String:
722752
var path : String
723753
if _is_sc:
@@ -744,6 +774,9 @@ func get_systems_file() -> String:
744774
func get_emulators_file() -> String:
745775
return "res://base_config/emulators.json"
746776

777+
func get_emulator_paths_file() -> String:
778+
return get_config_dir() + "/_emulator_paths.json"
779+
747780
func get_custom_systems_file() -> String:
748781
return get_config_dir() + "/rh_systems.json"
749782

source/emulators/GenericEmulator.gd

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,24 @@ var _substitutes := {}
88
func _init(emulator_raw : Dictionary, game_data : RetroHubGameData):
99
_substitutes["rompath"] = game_data.path
1010
_substitutes["romfolder"] = game_data.path.get_base_dir()
11-
var binpath := RetroHubGenericEmulator.find_and_substitute_str(emulator_raw["binpath"], _substitutes)
11+
var binpath := RetroHubGenericEmulator.find_path(emulator_raw, "binpath", _substitutes)
1212
if not binpath.is_empty():
1313
_substitutes["binpath"] = binpath
1414
command = RetroHubGenericEmulator.substitute_str(emulator_raw["command"], _substitutes)
1515
else:
1616
print("Could not find binpath for emulator \"%s\"" % emulator_raw["name"])
1717

18-
static func find_and_substitute_str(paths, substitutes: Dictionary) -> String:
18+
static func find_path(emulator_def: Dictionary, key: String, substitutes: Dictionary) -> String:
19+
var path := RetroHubConfig.get_emulator_path(emulator_def["name"], key)
20+
if not path.is_empty() and FileAccess.file_exists(path):
21+
return path
22+
var paths = emulator_def[key]
1923
if paths is Array:
20-
return substitute_str(FileUtils.test_for_valid_path(paths), substitutes)
21-
return substitute_str(FileUtils.expand_path(paths), substitutes)
24+
path = substitute_str(FileUtils.test_for_valid_path(paths), substitutes)
25+
else:
26+
path = substitute_str(FileUtils.expand_path(paths), substitutes)
27+
RetroHubConfig.set_emulator_path(emulator_def["name"], key, path)
28+
return path
2229

2330
static func substitute_str(path, substitutes: Dictionary) -> String:
2431
return JSONUtils.format_string_with_substitutes(path, substitutes)

source/emulators/RetroarchEmulator.gd

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ extends RetroHubGenericEmulator
22
class_name RetroHubRetroArchEmulator
33

44
static func get_custom_core_path() -> String:
5+
var corepath := RetroHubConfig.get_emulator_path("retroarch", "corepath")
6+
if not corepath.is_empty():
7+
return corepath
8+
59
var config_file := get_config_path()
610
if config_file:
711
var file := FileAccess.open(config_file + "/retroarch.cfg", FileAccess.READ)
@@ -10,7 +14,9 @@ static func get_custom_core_path() -> String:
1014
var line := file.get_line()
1115
if "libretro_directory" in line:
1216
var path := line.get_slice("=", 1).replace("\"", "").replace("'", "").strip_edges()
13-
return FileUtils.expand_path(path)
17+
path = FileUtils.expand_path(path)
18+
RetroHubConfig.set_emulator_path("retroarch", "corepath", path)
19+
return path
1420
return ""
1521
return ""
1622

@@ -20,7 +26,7 @@ static func get_config_path() -> String:
2026
# RetroArch on Windows works as a "portable" installation. Config is located beside main files.
2127
# Try to find a valid binpath.
2228
var emulator : Dictionary = RetroHubConfig.emulators_map["retroarch"]
23-
var binpath := RetroHubRetroArchEmulator.find_and_substitute_str(emulator["binpath"], {})
29+
var binpath := RetroHubRetroArchEmulator.find_path(emulator, "binpath", {})
2430
return binpath
2531
FileUtils.OS_ID.LINUX:
2632
# RetroArch uses either XDG_CONFIG_HOME or HOME.
@@ -38,25 +44,34 @@ static func get_config_path() -> String:
3844
_:
3945
return ""
4046

47+
static func find_core_path(core_key: String, emulator_def: Dictionary, corepath: String) -> String:
48+
var path_key := "core_" + core_key
49+
var path := RetroHubConfig.get_emulator_path("retroarch", path_key)
50+
if not path.is_empty() and FileAccess.file_exists(corepath.path_join(path)):
51+
return path
52+
for core_info in emulator_def["cores"]:
53+
if core_info["name"] == core_key:
54+
var core_file : String = core_info["file"]
55+
var core_file_path : String = corepath.path_join(core_file)
56+
RetroHubConfig.set_emulator_path("retroarch", path_key, core_file)
57+
if FileAccess.file_exists(core_file_path):
58+
return core_file
59+
return ""
60+
4161
func _init(emulator_raw : Dictionary, game_data : RetroHubGameData, system_cores : Array):
4262
super(emulator_raw, game_data)
4363
var corepath := RetroHubRetroArchEmulator.get_custom_core_path()
4464
if corepath.is_empty():
45-
corepath = RetroHubRetroArchEmulator.find_and_substitute_str(emulator_raw["corepath"], _substitutes)
65+
corepath = RetroHubRetroArchEmulator.find_path(emulator_raw, "corepath", _substitutes)
4666
var corefile : String
4767
_substitutes["corepath"] = corepath
4868
for core_name in system_cores:
49-
for core_info in emulator_raw["cores"]:
50-
if core_info["name"] == core_name:
51-
var core_file_path : String = corepath.path_join(core_info["file"])
52-
if FileAccess.file_exists(core_file_path):
53-
corefile = core_info["file"]
54-
_substitutes["corefile"] = corefile
55-
break
69+
corefile = RetroHubRetroArchEmulator.find_core_path(core_name, emulator_raw, corepath)
5670
if not corefile.is_empty():
5771
break
5872

5973
if not corefile.is_empty():
74+
_substitutes["corefile"] = corefile
6075
command = RetroHubRetroArchEmulator.substitute_str(command, _substitutes)
6176
else:
6277
print("Could not find valid core file for emulator \"%s\"" % game_data.system.name)

0 commit comments

Comments
 (0)