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 collapse

@@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



429
430
431
432
# File 'lib/demiurge/dsl.rb', line 429

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



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

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



496
497
498
499
# File 'lib/demiurge/dsl.rb', line 496

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



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

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



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

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