------art_2193_32568951.1142620392843
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

I've attached a library, GalaxyLoader, that parses a DSL for "world
builders". There's a brief example of the DSL following, and an
example world attached. The library also adds a class method
Galaxy.load to your Galaxy class. With this library, loading a galaxy
is as simple as:

  require 'galaxy_loader'
  galaxy = Galaxy.load('sample.glx')
  # do stuff with the galaxy...

The DSL is fairly simple. A galaxy can have many sectors, possibly
within regions:

  galaxy {
    region("Federation Space") {
      sector(1) { ... }
      sector(2) { ... }
    }

    region("Klingon Space") {
      sector(3) { ... }
      sector(4) { ... }
    }

    sector(5) { ... }
    sector(6) { ... }
  }

A sector can have planets, stations and neighbors:

  galaxy {
    sector(1) {
      planet "Earth"
      station "Alpha"
      neighbors 2, 3
    }
    sector(2) {
      station "Beta"
      neighbors 1, 3
    }

    sector(3) {
      neighbors 1, 2
    }
  }

And that's all there is to it! I tried to make the GalaxyLoader class
as consistent as possible, so it should be fairly easy to add further
attributes to planets and stations by following the pattern of the
existing methods.

Enjoy!

Jacob Fugal

------art_2193_32568951.1142620392843
Content-Type: application/octet-stream; name=galaxy_loader.rb
Content-Transfer-Encoding: 7bit
X-Attachment-Id: f_ekwtx01d
Content-Disposition: attachment; filename="galaxy_loader.rb"

require 'galaxy'
require 'sector'
require 'planet'
require 'station'

class GalaxyLoader
  class InvalidContext < Exception; end

  def initialize
    @context_stack  ]
    @sectors  ]
    @neighbors  }
  end

  def execute(definition)
    instance_eval(definition)
  end

  private
  def galaxy(&block)
    raise InvalidContext, "galaxy allowed only in root context" unless context nil
    with(:galaxy Galaxy.instance) do
      instance_eval(&block) if block
      resolve_neighbors
    end
  end

  def region(name, &block)
    raise InvalidContext, "region allowed only in galaxy context" unless context :galaxy
    with(:region name) do
      instance_eval(&block) if block
    end
  end

  def sector(name, &block)
    raise InvalidContext, "sector allowed only in galaxy or region context" unless context :galaxy or context :region
    with(:sector Sector.new(name, @region)) do
      instance_eval(&block) if block
      @sectors[name]  sector
      @galaxy.add_sector(@sector)
    end
  end

  def planet(name, &block)
    raise InvalidContext, "planet allowed only in sector context" unless context :sector
    with(:planet Planet.new(@sector, name)) do
      instance_eval(&block) if block
      @sector.add_planet(@planet)
    end
  end

  def station(name, &block)
    raise InvalidContext, "station allowed only in sector context" unless context :sector
    with(:station Station.new(@sector, name)) do
      instance_eval(&block) if block
      @sector.add_station(@station)
    end
  end

  def neighbors(*sectors)
    raise InvalidContext, "neighbors allowed only in sector context" unless context :sector
    @neighbors[@sector]  ectors
  end

  def with(context)
    name  ontext.keys.first
    value  ontext[name]
    instance_eval("@#{name}  alue")
    @context_stack << name
    yield
    @context_stack.pop
    instance_eval("@#{name}  il")
  end

  def context
    @context_stack.last
  end

  def resolve_neighbors
    @neighbors.each do |sector,neighbors|
      neighbors.each do |name|
        neighbor  sectors[name]
        sector.link(neighbor)
      end
    end
  end
end

def Galaxy.load(filename)
  GalaxyLoader.new.execute(File.read(filename))
  Galaxy.instance
end












------art_2193_32568951.1142620392843
Content-Type: application/octet-stream; name=sample.glx
Content-Transfer-Encoding: 7bit
X-Attachment-Id: f_ekwuoos3
Content-Disposition: attachment; filename="sample.glx"

galaxy {
  region("Federation Space") {
    sector(1) {
      planet "Earth"
      station "Alpha"
      neighbors 2, 3, 4
    }

    sector(2) {
      neighbors 1, 3, 4, 8
    }

    sector(3) {
      neighbors 1, 2, 5, 12
    }

    sector(4) {
      neighbors 1, 2, 3, 16
    }
  }

  region("Klingon Space") {
    sector(5) {
      planet "Kronos"
      station "Beta"
      neighbors 6, 7, 8
    }

    sector(6) {
      neighbors 5, 7, 8, 15
    }

    sector(7) {
      station "Gamma"
      neighbors 5, 6, 8, 10
    }

    sector(8) {
      neighbors 2, 5, 6, 7
    }
  }

  region("Romulan Space") {
    sector(9) {
      planet "Romulus"
      planet "Remus"
      neighbors 10, 11, 12
    }

    sector(10) {
      neighbors 7, 9, 11, 12
    }

    sector(11) {
      station "Delta"
      neighbors 9, 10, 12, 14
    }

    sector(12) {
      neighbors 3, 9, 10, 11
    }
  }

  region("Ferengi Space") {
    sector(13) {
      planet "Ferenginar"
      station "Epsilon"
      neighbors 14, 15, 16
    }

    sector(14) {
      neighbors 11, 13, 15, 16
    }

    sector(15) {
      station "Zeta"
      neighbors 6, 13, 14, 16
    }

    sector(16) {
      neighbors 4, 13, 14, 15
    }
  }
}

------art_2193_32568951.1142620392843--