Class: Archipelago::Treasure::Dubloon

Inherits:
Object
  • Object
show all
Defined in:
lib/archipelago/treasure.rb

Overview

A proxy to something in the chest.

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(key, chest, transaction, chest_id) ⇒ Dubloon

Initialize us with knowledge of our chest, the key to our target in the chest, the known public_methods of our target and any transaction we are associated with.



133
134
135
136
137
138
# File 'lib/archipelago/treasure.rb', line 133

def initialize(key, chest, transaction, chest_id)
  @key = key
  @chest = chest
  @transaction = transaction
  @chest_id = chest_id
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(meth, *args, &block) ⇒ Object

Call meth with args and block on our target if it responds to it.



198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
# File 'lib/archipelago/treasure.rb', line 198

def method_missing(meth, *args, &block)
  begin
    return @chest.call_instance_method(@key, meth, @transaction, *args, &block)
  rescue DRb::DRbConnError => e
    if defined?(Archipelago::Disco::MC)
      possible_replacements = Archipelago::Disco::MC.lookup(Archipelago::Disco::Query.new({:service_id => @chest_id}))
      raise e if possible_replacements.empty?
      
      @chest = possible_replacements[@chest_id][:service]
      CHEST_BY_SERVICE_ID[@chest_id] = @chest
      
      retry
    else
      raise e
    end
  end
end

Class Method Details

._load(s) ⇒ Object

Load some instance variables and replace @chest if we know that it actually is not correct.



154
155
156
157
158
159
160
161
# File 'lib/archipelago/treasure.rb', line 154

def self._load(s)
  key, chest, transaction, chest_id = Marshal.load(s)
  if CHEST_BY_SERVICE_ID.include?(chest_id)
    chest = CHEST_BY_SERVICE_ID[chest_id]
  end

  return self.new(key, chest, transaction, chest_id)
end

Instance Method Details

#==(o) ⇒ Object

If o is a Dubloon, will return true if it has the same Dubloon#object_id.

Otherwise will defer to Dubloon#method_missing.



122
123
124
125
126
127
# File 'lib/archipelago/treasure.rb', line 122

def ==(o)
  if Dubloon === o
    return true if self.object_id == o.object_id
  end
  return self.method_missing(:==, o)
end

#_dump(dummy_levels) ⇒ Object

A more or less normal dump of all our instance variables.



142
143
144
145
146
147
148
149
# File 'lib/archipelago/treasure.rb', line 142

def _dump(dummy_levels)
  Marshal.dump([
                @key, 
                @chest, 
                @transaction, 
                @chest_id
               ])
end

#assert_transaction(transaction) ⇒ Object

Raises exception if the given transaction is not the same as our own.



174
175
176
# File 'lib/archipelago/treasure.rb', line 174

def assert_transaction(transaction)
  raise UnknownTransactionException.new(self, transaction) unless transaction == @transaction
end

#eql?(o) ⇒ Boolean

Defers to Dubloon#==.

Returns:

  • (Boolean)


114
115
116
# File 'lib/archipelago/treasure.rb', line 114

def eql?(o)
  self.==(o)
end

#hashObject

This Dubloon will always have the same hash, based on object_id.



108
109
110
# File 'lib/archipelago/treasure.rb', line 108

def hash
  self.object_id.hash
end

#join(transaction) ⇒ Object

Return a clone of myself that is joined to the transaction.



166
167
168
169
# File 'lib/archipelago/treasure.rb', line 166

def join(transaction)
  @chest.join!(transaction) if transaction
  return Dubloon.new(@key, @chest, transaction, @chest_id)
end

#object_idObject

This Dubloon will always have the same object_id, based on



181
182
183
184
185
# File 'lib/archipelago/treasure.rb', line 181

def object_id
  id = "#{@chest_id}:#{@key}"
  id << ":#{@transaction.transaction_id}" if @transaction
  return id
end

#respond_to?(meth) ⇒ Boolean

Does our target respond to meth?

Returns:

  • (Boolean)


189
190
191
192
193
# File 'lib/archipelago/treasure.rb', line 189

def respond_to?(meth)
  # This one will be called far too often, and it seems safe to ignore it.
  return false if meth == :marshal_dump
  return super(meth) || self.method_missing(:respond_to?, meth)
end