Module: Lich::Common::Vars

Defined in:
documented/common/vars.rb

Constant Summary collapse

@@vars =
Hash.new
@@md5 =
nil
@@load_state =
LoadState::UNLOADED
@@load =

Proc that loads variables from database on first access

proc {
  Lich.db_mutex.synchronize {
    if @@load_state == LoadState::UNLOADED
      @@load_state = LoadState::LOADING
      begin
        h = Lich.db.get_first_value(
          'SELECT hash FROM uservars WHERE scope=?;',
          ["#{XMLData.game}:#{XMLData.name}".encode('UTF-8')]
        )
      rescue SQLite3::BusyException
        sleep 0.1
        retry
      end
       if h
        begin
          hash = Marshal.load(h)
          # Normalize all keys to strings during load
          hash.each { |k, v| @@vars[normalize_key(k)] = v }
          @@md5 = Digest::MD5.hexdigest(hash.to_s)
        rescue StandardError => e
          respond "--- Lich: error: #{e}"
          respond e.backtrace[0..2]
        end
      end
      @@load_state = LoadState::LOADED
    end
  }
  nil
}
@@save =

Proc that saves variables to database if modified

proc {
  Lich.db_mutex.synchronize {
    if @@load_state == LoadState::LOADED
      current_md5 = Digest::MD5.hexdigest(@@vars.to_s)
      if current_md5 != @@md5
        @@md5 = current_md5
        blob = SQLite3::Blob.new(Marshal.dump(@@vars))
        begin
          Lich.db.execute(
            'INSERT OR REPLACE INTO uservars(scope,hash) VALUES(?,?);',
            ["#{XMLData.game}:#{XMLData.name}".encode('UTF-8'), blob]
          )
        rescue SQLite3::BusyException
          sleep 0.1
          retry
        end
      end
    end
  }
  nil
}

Class Method Summary collapse

Class Method Details

.[](name) ⇒ Object?

Retrieves the value associated with the given name.

Parameters:

  • name (Object) —

    the name of the variable to retrieve

Returns:

  • (Object, nil) —

    the value associated with the name, or nil if not found



95
96
97
98
# File 'documented/common/vars.rb', line 95

def self.[](name)
  @@load.call unless @@load_state == LoadState::LOADED
  @@vars[normalize_key(name)]
end

.[]=(name, val) ⇒ void

This method returns an undefined value.

Sets the value for the given name.

Parameters:

  • name (Object) —

    the name of the variable to set

  • val (Object, nil) —

    the value to assign, or nil to delete the variable



105
106
107
108
109
110
111
112
113
# File 'documented/common/vars.rb', line 105

def self.[]=(name, val)
  @@load.call unless @@load_state == LoadState::LOADED
  key = normalize_key(name)
  if val.nil?
    @@vars.delete(key)
  else
    @@vars[key] = val
  end
end

.list ⇒ Hash

Returns a duplicate of the current variables.

Returns:

  • (Hash) —

    a duplicate of the current variables



118
119
120
121
# File 'documented/common/vars.rb', line 118

def self.list
  @@load.call unless @@load_state == LoadState::LOADED
  @@vars.dup
end

.method_missing(method_name, *args) ⇒ Object?

Handles method calls that do not have a direct implementation.

Parameters:

  • method_name (Symbol) —

    the name of the method being called

  • args (Array) —

    the arguments passed to the method

Returns:

  • (Object, nil) —

    the value associated with the method call, or nil if not found



135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
# File 'documented/common/vars.rb', line 135

def self.method_missing(method_name, *args)
  @@load.call unless @@load_state == LoadState::LOADED

  # Handle []= called through method_missing
  if method_name == :[]= && args.length == 2
    key = normalize_key(args[0])
    if args[1].nil?
      @@vars.delete(key)
    else
      @@vars[key] = args[1]
    end
  # Handle [] called through method_missing
  elsif method_name == :[] && args.length == 1
    @@vars[normalize_key(args[0])]
  # Handle setter methods (e.g., foo=)
  elsif method_name.to_s.end_with?('=')
    key = normalize_key(method_name.to_s.chop)
    if args[0].nil?
      @@vars.delete(key)
    else
      @@vars[key] = args[0]
    end
  # Handle getter methods
  else
    @@vars[normalize_key(method_name.to_s)]
  end
end

.normalize_key(key) ⇒ String

Normalizes the given key to a string.

Parameters:

  • key (Object) —

    the key to normalize

Returns:

  • (String) —

    the normalized key as a string



19
20
21
# File 'documented/common/vars.rb', line 19

def self.normalize_key(key)
  key.to_s
end

.respond_to_missing?(method_name, _include_private = false) ⇒ Boolean

Determines if the object responds to the given method name.

Parameters:

  • method_name (Symbol) —

    the name of the method

  • _include_private (Boolean) (defaults to: false) —

    whether to include private methods in the check

Returns:

  • (Boolean) —

    true if the method exists, false otherwise



168
169
170
171
172
173
174
175
176
177
178
# File 'documented/common/vars.rb', line 168

def self.respond_to_missing?(method_name, _include_private = false)
  method_str = method_name.to_s

  # Allow bracket operators
  return true if method_name == :[] || method_name == :[]=

  # Allow valid Ruby method names (with or without trailing =)
  # Valid: starts with letter or underscore, contains letters/digits/underscores
  # and optionally ends with = for setters
  method_str.match?(/\A[a-zA-Z_][a-zA-Z0-9_]*=?\z/)
end

.save ⇒ void

This method returns an undefined value.

Saves the current variables to the database if modified.



126
127
128
# File 'documented/common/vars.rb', line 126

def self.save
  @@save.call
end