Change config to method-call implementation

This commit is contained in:
Matthew Berry 2022-01-08 09:59:53 -08:00
parent 644493b96c
commit 1e0dc878dd
8 changed files with 68 additions and 119 deletions

View file

@ -9,15 +9,34 @@ File.touch(CONFIG_FILE)
class Config
include YAML::Serializable
property explorer_dir : String?
property keybindings : Hash(LibSDL::Keycode, Input)?
property recents : Array(String)?
property gba : GBA?
property gbc : GBC?
property explorer_dir : Path = Path[Dir.current]
property keybindings : Hash(LibSDL::Keycode, Input) = {
LibSDL::Keycode::E => Input::UP,
LibSDL::Keycode::D => Input::DOWN,
LibSDL::Keycode::S => Input::LEFT,
LibSDL::Keycode::F => Input::RIGHT,
LibSDL::Keycode::K => Input::A,
LibSDL::Keycode::J => Input::B,
LibSDL::Keycode::L => Input::SELECT,
LibSDL::Keycode::SEMICOLON => Input::START,
LibSDL::Keycode::W => Input::L,
LibSDL::Keycode::R => Input::R,
}
property recents : Array(String) = [] of String
property gba : GBA = GBA.new
property gbc : GBC = GBC.new
def self.new : Config
Config.from_yaml(File.read(CONFIG_FILE))
end
def commit : Nil
File.write(CONFIG_FILE, to_yaml)
end
class GBA
include YAML::Serializable
property bios : String?
property bios : String = "bios.bin"
def initialize
end
@ -31,76 +50,3 @@ class Config
end
end
end
private def config : Config
Config.from_yaml(File.read(CONFIG_FILE))
end
private def write(& : Config ->)
new_config = config
yield new_config
File.write(CONFIG_FILE, new_config.to_yaml)
end
private def write_gba(& : Config::GBA ->)
new_gba = config.gba || Config::GBA.new
yield new_gba
write { |config| config.gba = new_gba }
end
private def write_gbc(& : Config::GBC ->)
new_gbc = config.gbc || Config::GBC.new
yield new_gbc
write { |config| config.gbc = new_gbc }
end
def explorer_dir : String
config.explorer_dir || Dir.current
end
def set_explorer_dir(dir : String) : Nil
write { |config| config.explorer_dir = dir }
end
def keybindings : Hash(LibSDL::Keycode, Input)
config.keybindings || {
LibSDL::Keycode::E => Input::UP,
LibSDL::Keycode::D => Input::DOWN,
LibSDL::Keycode::S => Input::LEFT,
LibSDL::Keycode::F => Input::RIGHT,
LibSDL::Keycode::K => Input::A,
LibSDL::Keycode::J => Input::B,
LibSDL::Keycode::L => Input::SELECT,
LibSDL::Keycode::SEMICOLON => Input::START,
LibSDL::Keycode::W => Input::L,
LibSDL::Keycode::R => Input::R,
}
end
def set_keybindings(keybindings : Hash(LibSDL::Keycode, Input)) : Nil
write { |config| config.keybindings = keybindings }
end
def recents : Array(String)
config.recents || [] of String
end
def set_recents(recents : Array(String)) : Nil
write { |config| config.recents = recents }
end
def gbc_bios : String?
config.gbc.try(&.bios)
end
def set_gbc_bios(bios : String) : Nil
write_gbc { |gbc| gbc.bios = bios }
end
def gba_bios : String
config.gba.try(&.bios) || "bios.bin"
end
def set_gba_bios(bios : String) : Nil
write_gba { |gba| gba.bios = bios }
end

View file

@ -1,9 +1,10 @@
abstract class Frontend
def self.new(bios : String?, rom : String?, headless = false)
config = Config.new
if headless
HeadlessFrontend.new(bios, rom)
HeadlessFrontend.new(config, bios, rom)
else
SDLOpenGLImGuiFrontend.new(bios, rom)
SDLOpenGLImGuiFrontend.new(config, bios, rom)
end
end
@ -13,12 +14,11 @@ abstract class Frontend
return StubbedController.new unless rom
extension = rom.rpartition('.')[2]
if GBController.extensions.includes? extension
controller = GBController.new(bios, rom)
GBController.new(@config, bios, rom)
elsif GBAController.extensions.includes? extension
controller = GBAController.new(bios, rom)
GBAController.new(@config, bios, rom)
else
abort "Unsupported file extension: #{extension}"
end
controller
end
end

View file

@ -1,4 +1,5 @@
class GBController < Controller
@config : Config
getter emu : GB::GB
class_getter extensions : Array(String) = ["gb", "gbc"]
class_getter vertex_shader : String = "identity.vert"
@ -7,8 +8,8 @@ class GBController < Controller
getter width : Int32 = 160
getter height : Int32 = 144
def initialize(bios : String?, rom : String)
@emu = GB::GB.new(bios || gbc_bios, rom, true, false)
def initialize(@config : Config, bios : String?, rom : String)
@emu = GB::GB.new(bios || @config.gbc.bios, rom, true, false)
@emu.post_init
end

View file

@ -1,4 +1,5 @@
class GBAController < Controller
@config : Config
getter emu : GBA::GBA
class_getter extensions : Array(String) = ["gba"]
class_getter vertex_shader : String = "identity.vert"
@ -10,8 +11,8 @@ class GBAController < Controller
@debug_window = false
@scheduler_window = false
def initialize(bios : String?, rom : String)
@emu = GBA::GBA.new(bios || gba_bios, rom)
def initialize(@config : Config, bios : String?, rom : String)
@emu = GBA::GBA.new(bios || @config.gba.bios, rom)
@emu.post_init
end

View file

@ -1,7 +1,8 @@
class HeadlessFrontend < Frontend
@config : Config
@controller : Controller
def initialize(bios : String?, rom : String?)
def initialize(@config : Config, bios : String?, rom : String?)
@controller = init_controller(bios, rom.not_nil!)
end

View file

@ -12,6 +12,7 @@ class SDLOpenGLImGuiFrontend < Frontend
ROM_EXTENSIONS = CONTROLLERS.reduce([] of String) { |acc, controller| acc + controller.extensions }
SHADERS = Path["#{__DIR__}/shaders"]
@config : Config
@controller : Controller
@window : SDL::Window
@ -30,7 +31,6 @@ class SDLOpenGLImGuiFrontend < Frontend
@last_sdl_timestamp = 0_u32
@enable_overlay = false
@pause = false
@recents : Array(String) = recents
@scale = 3
@fullscreen = false
@ -39,7 +39,7 @@ class SDLOpenGLImGuiFrontend < Frontend
@game_texture : UInt32 = 0
@crab_texture : UInt32 = 0
def initialize(bios : String?, rom : String?)
def initialize(@config : Config, bios : String?, rom : String?)
SDL.init(SDL::Init::VIDEO | SDL::Init::AUDIO | SDL::Init::JOYSTICK)
LibSDL.joystick_open 0
at_exit { SDL.quit }
@ -70,8 +70,8 @@ class SDLOpenGLImGuiFrontend < Frontend
@io = setup_imgui
pause(true) if stubbed?
@file_explorer = ImGui::FileExplorer.new
@keybindings = ImGui::Keybindings.new
@file_explorer = ImGui::FileExplorer.new @config
@keybindings = ImGui::Keybindings.new @config
end
def run : NoReturn
@ -121,10 +121,10 @@ class SDLOpenGLImGuiFrontend < Frontend
@controller = init_controller(nil, rom)
@file_explorer.clear_selection
@recents.delete(rom)
@recents.insert(0, rom)
@recents.pop(@recents.size - 8) if @recents.size > 8
set_recents @recents
@config.recents.delete(rom)
@config.recents.insert(0, rom)
@config.recents.pop(@config.recents.size - 8) if @config.recents.size > 8
@config.commit
LibSDL.set_window_size(@window, @controller.window_width * @scale, @controller.window_height * @scale)
LibSDL.set_window_position(@window, LibSDL::WindowPosition::CENTERED, LibSDL::WindowPosition::CENTERED)
@ -136,12 +136,13 @@ class SDLOpenGLImGuiFrontend < Frontend
private def load_new_bios(bios : String) : Nil
if @controller.class == GBController
set_gbc_bios(bios)
@config.gbc.bios = bios
elsif @controller.class == GBAController
set_gba_bios(bios)
@config.gba.bios = bios
else
abort "Internal error: Cannot set bios #{bios} for controller #{@controller}"
end
@config.commit
@file_explorer.clear_selection
end
@ -218,14 +219,14 @@ class SDLOpenGLImGuiFrontend < Frontend
if ImGui.begin_menu "File"
open_rom_selection = ImGui.menu_item "Open ROM"
open_bios_selection = ImGui.menu_item "Select BIOS" unless stubbed?
if ImGui.begin_menu "Recent", @recents.size > 0
@recents.each do |recent|
if ImGui.begin_menu "Recent", @config.recents.size > 0
@config.recents.each do |recent|
load_new_rom(recent) if ImGui.menu_item recent
end
ImGui.separator
if ImGui.menu_item "Clear"
@recents.clear
set_recents @recents
@config.recents.clear
@config.commit
end
ImGui.end_menu
end

View file

@ -1,6 +1,6 @@
module ImGui
class FileExplorer
@path : Path
@config : Config
@matched_entries = [] of Entry
@selected_entry_idx = 0
@match_hidden = false
@ -13,7 +13,7 @@ module ImGui
getter selection : Tuple(Path, Symbol)? = nil
def initialize(@path = Path[explorer_dir].expand(home: true))
def initialize(@config : Config)
gather_entries
end
@ -23,7 +23,7 @@ module ImGui
center = ImGui.get_main_viewport.get_center
ImGui.set_next_window_pos(center, ImGui::ImGuiCond::Appearing, ImGui::ImVec2.new(0.5, 0.5))
if ImGui.begin_popup_modal(name.to_s, flags: ImGui::ImGuiWindowFlags::AlwaysAutoResize)
parts = @path.parts
parts = @config.explorer_dir.parts
parts.each_with_index do |part, idx|
ImGui.same_line unless idx == 0
change_dir "../" * (parts.size - idx - 1) if ImGui.button(part)
@ -76,20 +76,20 @@ module ImGui
end
private def open_file(name : Symbol) : Nil
@selection = {(@path / @matched_entries[@selected_entry_idx][:name]).normalize, name}
@selection = {(@config.explorer_dir / @matched_entries[@selected_entry_idx][:name]).normalize, name}
close
set_explorer_dir @path.to_s
end
private def change_dir(name : String) : Nil
@path = (@path / name).normalize
@config.explorer_dir = (@config.explorer_dir / name).normalize
@config.commit
gather_entries
end
private def gather_entries : Nil
@matched_entries.clear
Dir.each_child(@path) do |name|
is_file = !Dir.exists?(@path / name)
Dir.each_child(@config.explorer_dir) do |name|
is_file = !Dir.exists?(@config.explorer_dir / name)
rpart = name.rpartition('.')
extension = rpart[2] unless rpart[1].size == 0
hidden = name.starts_with?('.')

View file

@ -3,16 +3,15 @@ module ImGui
POPUP_NAME = "Keybindings"
BUTTON_SIZE = ImGui::ImVec2.new(32, 0)
@config : Config
@open = false
@selection : Input? = nil
@keycodes : Hash(LibSDL::Keycode, Input)
@editing_keycodes : Hash(LibSDL::Keycode, Input) = {} of LibSDL::Keycode => Input
delegate :[]?, to: @keycodes
delegate :[]?, to: @config.keybindings
def initialize
@keycodes = keybindings
overwrite_hash(@editing_keycodes, @keycodes)
def initialize(@config : Config)
overwrite_hash(@editing_keycodes, @config.keybindings)
end
def open? : Bool
@ -36,7 +35,7 @@ module ImGui
def render(open_popup : Bool) : Nil
@open ||= open_popup
if open_popup
overwrite_hash(@editing_keycodes, @keycodes)
overwrite_hash(@editing_keycodes, @config.keybindings)
ImGui.open_popup(POPUP_NAME)
end
center = ImGui.get_main_viewport.get_center
@ -70,8 +69,8 @@ module ImGui
end
private def apply : Nil
overwrite_hash(@keycodes, @editing_keycodes)
set_keybindings @keycodes
overwrite_hash(@config.keybindings, @editing_keycodes)
@config.commit
close
end