mirror of
https://github.com/mattrberry/crab.git
synced 2025-01-30 20:34:45 +01:00
Change config to method-call implementation
This commit is contained in:
parent
644493b96c
commit
1e0dc878dd
8 changed files with 68 additions and 119 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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?('.')
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue