Class: Demiurge::DSL::TopLevelBuilder

Inherits:
Object
  • Object
show all
Defined in:
lib/demiurge/dsl.rb

Overview

This is the top-level DSL Builder class, for parsing the top syntactic level of the World Files.

Since:

  • 0.0.1

Constant Summary

@@types =

This is the private structure of type names that are registered with the Demiurge World File DSL

Since:

  • 0.0.1

{}

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ TopLevelBuilder

Constructor for a new set of World Files and their top-level state.

Since:

  • 0.0.1



427
428
429
430
# File 'lib/demiurge/dsl.rb', line 427

def initialize(options = {})
  @zones = []
  @engine = options["engine"] || ::Demiurge::Engine.new(types: @@types, state: [])
end

Class Method Details

.register_type(name, klass) ⇒ Object

It's hard to figure out where and how to register types and plugins for the World File format. By their nature, they need to be in place before an Engine exists, so that's not the right place. If they didn't exist before engines, we'd somehow need to register them with each engine as it was created. Since Engines keep track of that, that's exactly the same problem we're trying to solve, just for the Engine builder. And it seems like "register this plugin with Demiurge World Files" is more of a process-global operation than a per-Engine operation. So these wind up in awkward spots.

Since:

  • 0.0.1



483
484
485
486
487
488
489
# File 'lib/demiurge/dsl.rb', line 483

def self.register_type(name, klass)
  if @@types[name.to_s]
    raise("Attempting to re-register type #{name.inspect} with a different class!") unless @@types[name.to_s] == klass
  else
    @@types[name.to_s] = klass
  end
end

Instance Method Details

#built_engineObject

Return the built Engine, but first call the .finished_init callback. This will make sure that cached and duplicated data structures are properly filled in.

Since:

  • 0.0.1



494
495
496
497
# File 'lib/demiurge/dsl.rb', line 494

def built_engine
  @engine.finished_init
  @engine
end

#inert(item_name, options = {}) ⇒ void

This method returns an undefined value.

For now, this just declares an InertStateItem for a given name. It doesn't change the behavior at all. It just keeps that item name from being "orphaned" state that doesn't correspond to any state item.

Later, this may be a way to describe how important or transitory state is - is it reset like a zone? Completely transient? Cleared per reboot?

Parameters:

  • item_name (String)

    The item name for scoping the state in the Engine

  • options (Hash) (defaults to: {})

    Options about the InertStateItem

Options Hash (options):

  • zone (String)

    The zone this InertStateItem considers itself to be in, defaults to "admin"

  • state (Hash)

    The initial state Hash

  • type (String)

    The object type to instantiate, if not InertStateItem

Since:

  • 0.0.1



448
449
450
451
452
453
454
455
# File 'lib/demiurge/dsl.rb', line 448

def inert(item_name, options = {})
  zone_name = options["zone"] || "admin"
  state = options["state"] || {}
  state.merge! "zone" => zone_name, "home_zone" => zone_name
  inert_item = ::Demiurge::StateItem.from_name_type(@engine, options["type"] || "InertStateItem", item_name, state)
  @engine.register_state_item(inert_item)
  nil
end

#zone(name, options = {}, &block) ⇒ Object

Start a new Zone block, using a ZoneBuilder.

Since:

  • 0.0.1



458
459
460
461
462
463
464
465
466
467
468
469
470
471
# File 'lib/demiurge/dsl.rb', line 458

def zone(name, options = {}, &block)
  if @zones.any? { |z| z.name == name }
    # Reopening an existing zone
    builder = ZoneBuilder.new(name, @engine, options.merge("existing" => @zones.detect { |z| z.name == name }))
  else
    builder = ZoneBuilder.new(name, @engine, options)
  end

  builder.instance_eval(&block)
  new_zone = builder.built_item

  @zones |= [ new_zone ] if new_zone  # Add if not already present
  nil
end