Class: RedShift::World

Inherits:
Object show all
Includes:
CShadow, Enumerable
Defined in:
lib/redshift/syntax.rb,
lib/redshift/world.rb,
lib/redshift/target/c/world-gen.rb,
lib/redshift/mixins/zeno-debugger.rb,
lib/redshift/target/c/component-gen.rb

Overview

Register the given block to be called for this world just before it is first run. The block is called with the world as self. Any number of blocks can be registered.

Defined Under Namespace

Modules: ZenoDebugger Classes: ComponentList

Constant Summary collapse

CV_CACHE_SIZE =

Initial size for the constant value cache.

64
64
PORT_CACHE_SIZE =

Initial size for the port cache.

64
@@count =
0

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize {|_self| ... } ⇒ World

Can override the options using assignments in the block. Note that clock_start should not be assigned after the block.

Yields:

  • (_self)

Yield Parameters:



97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/redshift/world.rb', line 97

def initialize # :yields: world
  dv_vars = %w{
    curr_A curr_P curr_CR curr_S next_S curr_T
    active_E prev_active_E awake prev_awake
    strict_sleep inert diff_list
  }
  dv_vars.each do |var|
    send "#{var}=", DVector[]
  end
  
  self.queue_sleep = {}
  @components = ComponentList.new  \
    awake, prev_awake, curr_T, strict_sleep, inert # _not_ diff_list

  options = default_options

  @name             = options[:name]
  @time_unit        = options[:time_unit]
  self.time_step    = options[:time_step]
  self.zeno_limit   = options[:zeno_limit]
  self.clock_start  = options[:clock_start]
  self.clock_finish = options[:clock_finish]
  self.input_depth_limit =
                      options[:input_depth_limit]
  self.alg_depth_limit =
                      options[:alg_depth_limit]
  
  self.step_count = 0
  
  @@count += 1

  do_defaults
  yield self if block_given?
  
  self.base_step_count = 0
  self.base_clock = clock_start
end

Class Attribute Details

.subclassesObject (readonly)

World is not included in subclasses. This returns nil when called on subs.



61
62
63
# File 'lib/redshift/world.rb', line 61

def subclasses
  @subclasses
end

Instance Attribute Details

#componentsObject (readonly)

Returns the value of attribute components.



73
74
75
# File 'lib/redshift/world.rb', line 73

def components
  @components
end

#nameObject

Returns the value of attribute name.



90
91
92
# File 'lib/redshift/world.rb', line 90

def name
  @name
end

#time_unitObject

Returns the value of attribute time_unit.



90
91
92
# File 'lib/redshift/world.rb', line 90

def time_unit
  @time_unit
end

Class Method Details

.defaults(&block) ⇒ Object Also known as: default

Register the given block to be called for instances of this class of World as they are instantiated (before the block passed to #new is called). The registered code is inherited by subclasses of this World class. The block is called with the world as self. Any number of blocks can be registered. (There are no per-world defaults. Use the #new block instead.)



11
12
13
# File 'lib/redshift/syntax.rb', line 11

def World.defaults(&block)
  (@defaults_procs ||= []) << block if block
end

.do_defaults(instance) ⇒ Object



140
141
142
143
144
145
146
147
# File 'lib/redshift/world.rb', line 140

def self.do_defaults instance
  superclass.do_defaults instance if superclass.respond_to? :do_defaults
  if @defaults_procs
    @defaults_procs.each do |pr|
      instance.instance_eval(&pr)
    end
  end
end

.do_setup(instance) ⇒ Object



160
161
162
163
164
165
166
167
# File 'lib/redshift/world.rb', line 160

def self.do_setup instance
  superclass.do_setup instance if superclass.respond_to? :do_setup
  if @setup_procs
    @setup_procs.each do |pr|
      instance.instance_eval(&pr)
    end
  end
end

.inherited(sub) ⇒ Object



63
64
65
# File 'lib/redshift/world.rb', line 63

def inherited(sub)
  World.subclasses << sub
end

.new(*args, &block) ⇒ Object

Redefines World#new so that a library commit happens first.



149
150
151
152
# File 'lib/redshift/target/c/world-gen.rb', line 149

def self.new(*args, &block)
  RedShift.require_target     # redefines World.new
  new(*args, &block)          # which is what this line calls
end

.open(filename) ⇒ Object



288
289
290
291
292
293
294
295
296
297
298
299
300
301
# File 'lib/redshift/world.rb', line 288

def World.open filename
  RedShift.require_target
  commit
  
  world = nil
  store = PStore.new filename
  store.transaction do
    if store.root? 'world'
      world = store['world']
      yield store if block_given?
    end
  end
  world
end

.setup(&block) ⇒ Object

Register the given block to be called for instances of this class of World just before they are first run. The registered code is inherited by subclasses of this World class. The block is called with the world as self. Any number of blocks can be registered.



22
23
24
# File 'lib/redshift/syntax.rb', line 22

def World.setup(&block)
  (@setup_procs ||= []) << block if block
end

Instance Method Details

#create(component_class) ⇒ Object



169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
# File 'lib/redshift/world.rb', line 169

def create(component_class)
  component = 
    if block_given?
      component_class.new(self) {|c| yield c}
    else
      component_class.new(self)
    end
  
  unless component.is_a? Component # Component is abstract
    raise TypeError, "#{component.class} is not a Component class"
  end
  
  awake << component if component.world == self
  component
end

#default_optionsObject



75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/redshift/world.rb', line 75

def default_options
  {
    :name         =>  "#{self.class}_#{@@count}",
    :time_unit    =>  "second",
    :time_step    =>  0.1,
    :zeno_limit   =>  100,
    :clock_start  =>  0.0,
    :clock_finish =>  Infinity,
    :input_depth_limit => 100,
    :alg_depth_limit => 100
  }
end

#each(&b) ⇒ Object



247
248
249
# File 'lib/redshift/world.rb', line 247

def each(&b)
  @components.each(&b)
end

#evolve(time = 1.0, &block) ⇒ Object



229
230
231
# File 'lib/redshift/world.rb', line 229

def evolve(time = 1.0, &block)
  run((time.to_f/time_step).round, &block)
end

#garbage_collectObject

is this a good idea? tests?



239
240
241
242
243
244
245
# File 'lib/redshift/world.rb', line 239

def garbage_collect
  self.components.clear
  GC.start
  ObjectSpace.each_object(Component) do |c|
    components << c if c.world == self
  end
end

#include?(component) ⇒ Boolean Also known as: member?

Returns:

  • (Boolean)


255
256
257
# File 'lib/redshift/world.rb', line 255

def include? component
  component.world == self
end

#inspectObject



260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
# File 'lib/redshift/world.rb', line 260

def inspect
  if @started
    digits = -Math.log10(time_step).floor
    digits = 0 if digits < 0

    data = []
    data << "%d step%s" % [step_count, ("s" if step_count != 1)]
    data << "%.#{digits}f #{@time_unit}%s" % [clock, ("s" if clock != 1)]
    data << "%d component%s" % [size, ("s" if size != 1)]
    data << "discrete step = #{discrete_step}" ## only if in step_discrete?
  else
    data = ["not started. Do 'run 0' to setup, or 'run n' to run."]
  end

  str = [name, data.join("; ")].join(": ")
  "<#{str}>"
end

#remove(c) ⇒ Object

is this a good idea? tests? #add ?



186
187
188
189
190
191
192
193
# File 'lib/redshift/world.rb', line 186

def remove c
  if components.summands.any? {|list| list.delete(c)}
    raise unless c.world == self
    c.__set__world(nil)
  else
    raise "Tried to remove #{c} from #{self}, but its world is #{c.world}."
  end
end

#run(*args, &block) ⇒ Object



224
225
226
227
# File 'lib/redshift/world.rb', line 224

def run(*args, &block)
  ## warn "World#run is deprecated -- use #step or #evolve"
  step(*args, &block)
end

#running?Boolean

Returns:

  • (Boolean)


93
# File 'lib/redshift/world.rb', line 93

def running?; @running; end

#save(filename = @name) ⇒ Object



278
279
280
281
282
283
284
285
286
# File 'lib/redshift/world.rb', line 278

def save filename = @name
  raise "Can't save world during its run method." if @running
  File.delete(filename) rescue SystemCallError
  store = PStore.new filename
  store.transaction do
    store['world'] = self
    yield store if block_given?
  end
end

#setup(&block) ⇒ Object



30
31
32
# File 'lib/redshift/syntax.rb', line 30

def setup(&block)
  (@setup_procs ||= []) << block if block
end

#sizeObject



251
252
253
# File 'lib/redshift/world.rb', line 251

def size
  @components.size
end

#started?Boolean

Returns:

  • (Boolean)


92
# File 'lib/redshift/world.rb', line 92

def started?; @started; end

#step(steps = 1) ⇒ Object

All evolution methods untimately call step, which can be overridden. After each step, yields to block. It is the block’s responsibility to step_discrete at this point after changing any vars.



198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
# File 'lib/redshift/world.rb', line 198

def step(steps = 1)
  @running = true
  
  unless @started
    do_setup
    @started = true
  end
  
  step_discrete
  steps.to_i.times do
    break if clock > clock_finish
    self.step_count += 1
    step_continuous
    step_discrete
    @running = false
    yield self if block_given?
    @running = true
  end
  
  self
  
ensure
  @running = false
  ## how to continue stepping after an exception?
end

#step_zenoObject

Default implementation is to raise RedShift::ZenoError.



234
235
236
# File 'lib/redshift/world.rb', line 234

def step_zeno
  raise RedShift::ZenoError, "Exceeded zeno limit of #{zeno_limit}."
end