Module: Lich::Common
- Includes:
- GtkIdleRetention, GtkMainLoopGuards, GtkTimeoutRetention
- Defined in:
- documented/games.rb,
documented/common/gtk.rb,
documented/common/hmr.rb,
documented/common/log.rb,
documented/common/vars.rb,
documented/global_defs.rb,
documented/common/spell.rb,
documented/common/buffer.rb,
documented/common/script.rb,
documented/common/account.rb,
documented/common/gameobj.rb,
documented/common/pipe_io.rb,
documented/attributes/char.rb,
documented/common/db_store.rb,
documented/common/postload.rb,
documented/common/settings.rb,
documented/common/throttle.rb,
documented/common/uservars.rb,
documented/common/watchfor.rb,
documented/common/front-end.rb,
documented/common/front-end.rb,
documented/common/gui/state.rb,
documented/common/gui_login.rb,
documented/common/watchable.rb,
documented/common/xmlparser.rb,
documented/common/arg_parser.rb,
documented/common/gameloader.rb,
documented/common/map/map_dr.rb,
documented/common/map/map_gs.rb,
documented/common/setup_files.rb,
documented/common/limitedarray.rb,
documented/common/map/map_base.rb,
documented/common/script_death.rb,
documented/common/sharedbuffer.rb,
documented/common/shutdown_log.rb,
documented/common/upstreamhook.rb,
documented/common/xml_entities.rb,
documented/common/feature_flags.rb,
documented/common/gui/utilities.rb,
documented/common/hook_registry.rb,
documented/common/downstreamhook.rb,
documented/common/gui/components.rb,
documented/common/gui/theme_utils.rb,
documented/common/ruby_executable.rb,
documented/common/shutdown_intent.rb,
documented/common/credential_scrub.rb,
documented/common/frontend_locator.rb,
documented/common/orderly_shutdown.rb,
documented/common/process_launcher.rb,
documented/common/session_launcher.rb,
documented/common/socket_read_hook.rb,
documented/common/frontend_launcher.rb,
documented/common/gui/accessibility.rb,
documented/common/gui/conversion_ui.rb,
documented/common/session_lifecycle.rb,
documented/common/shutdown_watchdog.rb,
documented/common/authentication/cli.rb,
documented/common/authentication/gui.rb,
documented/common/bind_host_resolver.rb,
documented/common/cli/cli_conversion.rb,
documented/common/gui/game_selection.rb,
documented/common/saga_launch_policy.rb,
documented/common/saga_managed_login.rb,
documented/common/socketconfigurator.rb,
documented/common/gui/account_manager.rb,
documented/common/gui/login_tab_utils.rb,
documented/common/gui/password_change.rb,
documented/common/gui/password_cipher.rb,
documented/common/gui/saved_login_tab.rb,
documented/common/gui/window_settings.rb,
documented/common/reusable_tcp_server.rb,
documented/common/gui/manual_login_tab.rb,
documented/common/gui/password_manager.rb,
documented/common/gui/tab_communicator.rb,
documented/common/settings_transformer.rb,
documented/common/shutdown_coordinator.rb,
documented/common/class_exts/stringproc.rb,
documented/common/cli/cli_orchestration.rb,
documented/common/gui/favorites_manager.rb,
documented/common/gui/frontend_selector.rb,
documented/common/gui/parameter_objects.rb,
documented/common/saga_managed_launcher.rb,
documented/common/settings/charsettings.rb,
documented/common/settings/gamesettings.rb,
documented/common/shutdown_script_drain.rb,
documented/common/authentication/eaccess.rb,
documented/common/creature/creature_base.rb,
documented/common/gui/account_manager_ui.rb,
documented/common/client_input_dispatcher.rb,
documented/common/settings/path_navigator.rb,
documented/common/settings/settings_proxy.rb,
documented/dragonrealms/drinfomon/startup.rb,
documented/common/cli/cli_options_registry.rb,
documented/common/cli/active_sessions_query.rb,
documented/common/settings/database_adapter.rb,
documented/common/authentication/entry_store.rb,
documented/common/authentication/launch_data.rb,
documented/common/detachable_client_registry.rb,
documented/common/gui/encryption_mode_change.rb,
documented/common/gui/master_password_change.rb,
documented/common/gui/master_password_prompt.rb,
documented/common/settings/instance_settings.rb,
documented/common/settings/sessions_settings.rb,
documented/common/shutdown_result_predicates.rb,
documented/common/authentication/cli_password.rb,
documented/common/gui/master_password_manager.rb,
documented/common/authentication/authenticator.rb,
documented/common/authentication/login_helpers.rb,
documented/common/best_effort_shutdown_cleanup.rb,
documented/common/class_exts/synchronizedsocket.rb,
documented/common/gui/master_password_prompt_ui.rb,
documented/common/cli/cli_encryption_mode_change.rb,
documented/common/gui/windows_credential_manager.rb,
documented/common/settings/session_database_adapter.rb
Overview
Namespace for Lich 5 shared internal utilities and adapters.
Defined Under Namespace
Modules: Account, Authentication, BestEffortShutdownCleanup, BindHostResolver, Buffer, CLI, CharSettings, ClientInputDispatcher, CreatureBase, CredentialScrub, DB_Store, FeatureFlags, Frontend, FrontendLauncher, GUI, GameLoader, GameSettings, GtkIdleRetention, GtkMainLoopGuards, GtkSignalHandlerRetention, GtkTimeoutRetention, HMR, HookRegistry, InstanceSettings, Log, MapBase, OrderlyShutdown, PostLoad, ProcessLauncher, ReusableTCPServer, RubyExecutable, SagaLaunchPolicy, SagaManagedLauncher, SagaManagedLogin, ScriptDeath, SessionLauncher, SessionLifecycle, SessionsSettings, Settings, SettingsTransformer, ShutdownCoordinator, ShutdownIntent, ShutdownLog, ShutdownResultPredicates, ShutdownScriptDrain, ShutdownWatchdog, SocketConfigurator, UserVars, Vars, Watchable, XmlEntities Classes: ArgParser, Char, DatabaseAdapter, DetachableClientRegistry, DownstreamHook, ExecScript, FrontendLocator, GameObj, LimitedArray, LruIndex, Map, MinHeap, PathNavigator, PipeIO, Room, RoomObj, Script, Scripting, SessionDatabaseAdapter, SettingsProxy, SetupFiles, SharedBuffer, SocketReadHook, Spell, StringProc, SynchronizedSocket, TagList, Throttle, UpstreamHook, Watchfor, WizardScript, XMLParser
Constant Summary collapse
- CORE_GET_SETTINGS =
true- CORE_SCRIPT_LOADER =
true- CORE_PARSE_ARGS =
true- CORE_AUTOSTART =
true- TRUSTED_SCRIPT_BINDING =
A proc that returns a trusted script binding context.
proc { _script }
- CORE_ARGPARSER =
true- CORE_SETUPFILES =
true- CORE_MAP_OVERRIDES =
true- CORE_DR_STARTUP =
true
Class Method Summary collapse
-
.allow_gtk_main_quit { ... } ⇒ Object
Temporarily allows a core-owned Gtk.main_quit call to bypass script guards.
-
.cleanup_gtk! ⇒ Boolean
Destroys retained GTK receivers and releases retained Ruby callbacks.
-
.clear_gtk_retention_registries ⇒ void
Clears retained GTK callback registries.
-
.gtk_guard_context ⇒ String
Returns log context for GTK guard messages.
-
.gtk_idle_callbacks ⇒ Hash{Integer => Proc}
Returns the retained GLib idle callback registry.
-
.gtk_main_loop_running? ⇒ Boolean
Returns true when the shared GTK main loop is currently running.
-
.gtk_signal_handlers ⇒ Hash
Returns the retained GTK signal handler registry.
-
.gtk_timeout_callbacks ⇒ Hash{Integer => Proc}
Returns the retained GLib timeout callback registry.
-
.quit_gtk_main_loop ⇒ Object?
Requests a GTK main-loop shutdown through the guarded core escape hatch.
-
.release_gtk_signal_handlers(receiver) ⇒ Object?
Releases retained signal handlers for a GTK receiver.
-
.shutdown_gtk! ⇒ Object?
Performs core-owned GTK shutdown before Ruby process exit.
-
.shutdown_gtk_before_exit(timeout: 2.0, direct: false) ⇒ void
Runs core GTK teardown before process exit, so Ruby's finalizer is not left to dispose surviving widget wrappers in an unsafe order (which disposes native objects out of order and segfaults).
-
.with_gtk_registry_lock { ... } ⇒ Object
Synchronizes access to GTK callback retention registries.
Instance Method Summary collapse
-
#_script ⇒ Binding
Creates a new script binding context.
-
#gui_login ⇒ Object
Provides graphical login functionality for the Lich application.
Methods included from GtkTimeoutRetention
Methods included from GtkIdleRetention
Methods included from GtkMainLoopGuards
#lich_main_quit, #main, #main_quit
Class Method Details
.allow_gtk_main_quit { ... } ⇒ Object
Temporarily allows a core-owned Gtk.main_quit call to bypass script guards.
104 105 106 107 108 109 110 |
# File 'documented/common/gtk.rb', line 104 def self.allow_gtk_main_quit previous = Thread.current[:lich_allow_gtk_main_quit] Thread.current[:lich_allow_gtk_main_quit] = true yield ensure Thread.current[:lich_allow_gtk_main_quit] = previous end |
.cleanup_gtk! ⇒ Boolean
Destroys retained GTK receivers and releases retained Ruby callbacks.
ruby-gnome will otherwise release surviving widget wrappers during Ruby finalization, which can dispose native GTK objects in an unsafe order. This may run after Gtk.main has returned, so it must not stop the GTK main loop itself.
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'documented/common/gtk.rb', line 70 def self.cleanup_gtk! retained_receivers = with_gtk_registry_lock { gtk_signal_handlers.keys.dup } callbacks_retained = with_gtk_registry_lock do gtk_timeout_callbacks.any? || gtk_idle_callbacks.any? end return false if retained_receivers.empty? && !callbacks_retained retained_receivers.each do |receiver| next unless receiver.respond_to?(:destroy) next if receiver.respond_to?(:destroyed?) && receiver.destroyed? begin receiver.destroy rescue StandardError => e Lich.log "warning: Failed to destroy GTK receiver during shutdown: #{e.class}: #{e.}" end end clear_gtk_retention_registries true end |
.clear_gtk_retention_registries ⇒ void
This method returns an undefined value.
Clears retained GTK callback registries.
This is used by core shutdown paths to avoid leaving Ruby-side callback references alive until interpreter finalization.
54 55 56 57 58 59 60 |
# File 'documented/common/gtk.rb', line 54 def self.clear_gtk_retention_registries with_gtk_registry_lock do gtk_signal_handlers.clear gtk_timeout_callbacks.clear gtk_idle_callbacks.clear end end |
.gtk_guard_context ⇒ String
Returns log context for GTK guard messages.
Prefers the currently running script name when available so blocked GTK loop operations can be traced back to the offending script.
218 219 220 221 222 223 |
# File 'documented/common/gtk.rb', line 218 def self.gtk_guard_context script_name = Script.current&.name if defined?(Script) && Script.respond_to?(:current) script_name && !script_name.to_s.empty? ? "script=#{script_name}" : 'context=unknown' rescue StandardError 'context=unknown' end |
.gtk_idle_callbacks ⇒ Hash{Integer => Proc}
Returns the retained GLib idle callback registry.
36 37 38 |
# File 'documented/common/gtk.rb', line 36 def self.gtk_idle_callbacks @gtk_idle_callbacks end |
.gtk_main_loop_running? ⇒ Boolean
Returns true when the shared GTK main loop is currently running.
Used to decide whether core teardown can be handed to the GTK thread via
#shutdown_gtk_before_exit. A false return means the queue cannot be
serviced; only the terminal lich.rbw backstop may run direct teardown.
128 129 130 131 132 |
# File 'documented/common/gtk.rb', line 128 def self.gtk_main_loop_running? return false unless defined?(Gtk) && Gtk.respond_to?(:main_level) Gtk.main_level.to_i > 0 end |
.gtk_signal_handlers ⇒ Hash
Returns the retained GTK signal handler registry.
The hash compares keys by object identity so each widget wrapper keeps its own retained callback list even if different objects compare equal.
22 23 24 |
# File 'documented/common/gtk.rb', line 22 def self.gtk_signal_handlers @gtk_signal_handlers end |
.gtk_timeout_callbacks ⇒ Hash{Integer => Proc}
Returns the retained GLib timeout callback registry.
29 30 31 |
# File 'documented/common/gtk.rb', line 29 def self.gtk_timeout_callbacks @gtk_timeout_callbacks end |
.quit_gtk_main_loop ⇒ Object?
Requests a GTK main-loop shutdown through the guarded core escape hatch.
115 116 117 118 119 |
# File 'documented/common/gtk.rb', line 115 def self.quit_gtk_main_loop return unless defined?(Gtk) return Gtk.lich_main_quit if Gtk.respond_to?(:lich_main_quit) return Gtk.main_quit if Gtk.respond_to?(:main_quit) end |
.release_gtk_signal_handlers(receiver) ⇒ Object?
Releases retained signal handlers for a GTK receiver.
44 45 46 |
# File 'documented/common/gtk.rb', line 44 def self.release_gtk_signal_handlers(receiver) with_gtk_registry_lock { gtk_signal_handlers.delete(receiver) } end |
.shutdown_gtk! ⇒ Object?
Performs core-owned GTK shutdown before Ruby process exit.
95 96 97 98 |
# File 'documented/common/gtk.rb', line 95 def self.shutdown_gtk! cleanup_gtk! Gtk.lich_main_quit if defined?(Gtk) && Gtk.respond_to?(:lich_main_quit) end |
.shutdown_gtk_before_exit(timeout: 2.0, direct: false) ⇒ void
This method returns an undefined value.
Runs core GTK teardown before process exit, so Ruby's finalizer is not left to dispose surviving widget wrappers in an unsafe order (which disposes native objects out of order and segfaults).
Dispatch depends on the GTK main loop state and caller context:
- Loop running (the launcher and the main game loop, which call this
from a thread other than the GTK thread): the teardown is queued onto the
GTK thread and this method blocks on a bounded barrier until it completes.
#shutdown_gtk! also quits the loop, so this both destroys the widgets
and unwinds
Gtk.main. - Loop not running: a queued block would never be serviced. Ordinary
callers clear retained Ruby references only. The terminal
lich.rbwbackstop passesdirect: trueafterGtk.mainreturns on the GTK thread; only that path destroys surviving widgets directly in place. Gtk.main has already returned there, so it must not call Gtk.main_quit.
If GTK is unavailable, the queue cannot be serviced, the work cannot be
queued, or it does not finish within timeout, the retention registries are
cleared directly so Ruby-side callback references are not left alive until
interpreter finalization.
160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 |
# File 'documented/common/gtk.rb', line 160 def self.shutdown_gtk_before_exit(timeout: 2.0, direct: false) return clear_gtk_retention_registries unless defined?(Gtk) unless gtk_main_loop_running? if direct begin cleanup_gtk! rescue StandardError => e Lich.log "warning: Failed to run direct GTK shutdown before exit: #{e.class}: #{e.}" clear_gtk_retention_registries end else clear_gtk_retention_registries end return end shutdown_complete = Queue.new queued = begin Gtk.queue do begin shutdown_gtk! ensure shutdown_complete << true end end rescue StandardError => e Lich.log "warning: Failed to queue GTK shutdown before exit: #{e.class}: #{e.}" nil end unless queued clear_gtk_retention_registries return end deadline = Process.clock_gettime(Process::CLOCK_MONOTONIC) + timeout loop do begin shutdown_complete.pop(true) return rescue ThreadError break if Process.clock_gettime(Process::CLOCK_MONOTONIC) >= deadline sleep 0.01 end end Lich.log 'warning: GTK shutdown queue did not complete before exit' clear_gtk_retention_registries end |
.with_gtk_registry_lock { ... } ⇒ Object
Synchronizes access to GTK callback retention registries.
12 13 14 |
# File 'documented/common/gtk.rb', line 12 def self.with_gtk_registry_lock @gtk_registries_mutex.synchronize { yield } end |
Instance Method Details
#_script ⇒ Binding
Creates a new script binding context.
18 19 20 |
# File 'documented/common/script.rb', line 18 def _script Proc.new {}.binding end |
#gui_login ⇒ Object
Provides graphical login functionality for the Lich application
This module contains the main entry point for the GUI login system and coordinates the interaction between saved and manual login tabs. It also provides account management functionality. Enhanced with cross-tab communication for data synchronization and targeted refresh capability for post-conversion scenarios.
37 38 39 40 41 42 43 44 45 46 |
# File 'documented/common/gui_login.rb', line 37 def gui_login initialize_login_state setup_gui_window wait_until { @done } save_entry_data_if_needed return_launch_data_or_exit end |