Class: Demiurge::DSL::ActionItemBuilder

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

Overview

ActionItemBuilder is the parent class of all Builder classes except the TopLevelBuilder. It's used for a block of the World File DSL.

Since:

  • 0.0.1

Direct Known Subclasses

AgentBuilder, LocationBuilder, ZoneBuilder

Constant Summary

[ "state", "type", "no_build" ]

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, engine, options = {}) ⇒ void

Initialize a DSL Builder block to configure some sort of ActionItem.

Parameters:

  • name (String)

    The name to be registered with the Engine

  • engine (Demiurge::Engine)

    The engine that will include this item

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

    Options for how the DSL block acts

Options Hash (options):

  • state (Hash)

    The initial state Hash to create the item with

  • type (String)

    The item type to create

  • no_build (Boolean)

    If true, don't create and register a new StateItem with the Engine

Since:

  • 0.0.1



234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
# File 'lib/demiurge/dsl.rb', line 234

def initialize(name, engine, options = {})
  check_options(options, LEGAL_OPTIONS)
  @name = name
  @engine = engine
  @state = options["state"] || {}
  @position = nil
  @display = nil # This is display-specific information that gets passed to the display library

  unless options["type"]
    raise "You must pass a type when initializing a builder!"
  end
  unless options["no_build"]
    @built_item = ::Demiurge::StateItem.from_name_type(@engine, options["type"], @name, @state)
    @engine.register_state_item(@built_item)
  end
  nil
end

Instance Attribute Details

#built_itemStateItem (readonly)

Returns The item built by this builder

Returns:

  • (StateItem)

    The item built by this builder

Since:

  • 0.0.1



212
213
214
# File 'lib/demiurge/dsl.rb', line 212

def built_item
  @built_item
end

Instance Method Details

#__state_internalHash

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

If the DSL block sets state on the Builder object, this allows it to get to the internal Hash object rather than a wrapper. This should only be used internally to the DSL, not by others.

Returns:

  • (Hash)

    The state Hash

See Also:

Since:

  • 0.0.1



261
262
263
# File 'lib/demiurge/dsl.rb', line 261

def __state_internal
  @built_item.state
end

#define_action(action_name, options = {}) {|...| ... } ⇒ void

This method returns an undefined value.

If you want to define an action for later calling, or to set options on an action that was defined as part of another handler, you can call define_action to make that happen.

every_X_ticks("burp", 15) { engine.item_by_name("sooper sekrit").ruby_only_burp_action }
define_action("burp", "engine_code" => true, "busy" => 7)

Examples:

Make an every_X_ticks action also keep the agent busy and run as Engine code

Parameters:

  • action_name (String)

    The action name to declare or modify

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

    Options for this action

Options Hash (options):

  • busy (Integer)

    How many ticks an agent should remain busy for after taking this action

  • engine_code (Boolean)

    If true, use the EngineBlockRunner instead of a normal runner for this code; usually a bad idea

  • tags (Array<String>)

    Tags that the action can be queried by later - useful for tagging player or agent actions, or admin-only actions

Yields:

  • (...)

    Actions receive whatever arguments their later caller supplies

Yield Returns:

  • (void)

Since:

  • 0.0.1



410
411
412
413
414
415
416
# File 'lib/demiurge/dsl.rb', line 410

def define_action(action_name, options = {}, &block)
  legal_options = [ "busy", "engine_code", "tags" ]
  illegal_keys = options.keys - legal_options
  raise("Illegal keys #{illegal_keys.inspect} passed to define_action of #{action_name.inspect}!") unless illegal_keys.empty?;
  register_built_action({ "name" => action_name, "block" => block }.merge(options))
  nil
end

#display { ... } ⇒ void

This method returns an undefined value.

Pass a block through that is intended for the display library to use later. If no display library is used, this is a no-op.

Yields:

  • [] The block will be called by the display library, in a display-library-specific context, or not at all

Since:

  • 0.0.1



328
329
330
331
332
333
334
# File 'lib/demiurge/dsl.rb', line 328

def display(&block)
  # Need to figure out how to pass this through to the Display
  # library.  By design, the simulation/state part of Demiurge
  # ignores this completely.
  @built_item.register_actions("$display" => { "name" => "$display", "block" => block })
  nil
end

#every_X_ticks(action_name, t) {|...| ... } ⇒ void

This method returns an undefined value.

Perform the given action every so many ticks. This will set up the necessary state entries to cause the action to occur each time that many ticks pass. The given action name is attached to the given block (if any.) The named action can be modified using define_action if you want to set extra settings like engine_code or busy for the action in question. If no block is given, you should use define_action to create the action in question, or it will have no definition and cause errors.

Parameters:

  • action_name (String)

    The action name for this item to use repeatedly

  • t (Integer)

    The number of ticks that pass between actions

Yields:

  • (...)

    Called when the action is performed with any arguments supplied by the caller

Yield Returns:

  • (void)

Since:

  • 0.0.1



304
305
306
307
308
309
310
# File 'lib/demiurge/dsl.rb', line 304

def every_X_ticks(action_name, t, &block)
  raise("Must provide a positive number for how many ticks, not #{t.inspect}!") unless t.is_a?(Numeric) && t >= 0.0
  @built_item.state["everies"] ||= []
  @built_item.state["everies"] << { "action" => action_name, "every" => t, "counter" => 0 }
  @built_item.register_actions(action_name => { "name" => action_name, "block" => block })
  nil
end

#on_intention(caught_action, action_to_run) {|Intention| ... } ⇒ void Also known as: on_action

This method returns an undefined value.

The specified action will be called for Intentions using the appropriate action. This is used to modify or cancel an Intention before it runs.

Parameters:

  • caught_action (String)

    The action type of the Intention being caught, or "all" for all intentions

  • action_to_run (String)

    The action name of the new intercepting action

Yields:

  • (Intention)

    Receives the Intention when these Intentions occur

Since:

  • 0.0.1



379
380
381
382
383
384
385
# File 'lib/demiurge/dsl.rb', line 379

def on_intention(caught_action, action_to_run, &block)
  @built_item.state["on_action_handlers"] ||= {}
  raise "Already have an on_action (offer) handler for action #{caught_action}! Failing!" if @built_item.state["on_action_handlers"][caught_action]
  @built_item.state["on_action_handlers"][caught_action] = action_to_run
  register_built_action("name" => action_to_run, "block" => block)
  nil
end

#on_notification(event, action_name, options = {}) {|Hash| ... } ⇒ void Also known as: on

TODO:

Figure out timing of the subscription - right now it will use the item's location midway through parsing the DSL!

This method returns an undefined value.

The specified action will be called for notifications of the appropriate type.

Parameters:

  • event (String)

    The name of the notification to subscribe to

  • action_name (String)

    The action name of the new action

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

    Additional specifications about what/how to subscribe

Options Hash (options):

  • location (String, :all)

    The location name to subscribe for - defaults to this item's location

  • zone (String, :all)

    The zone name to subscribe for - defaults to this item's zone

  • actor (String, :all)

    The acting item name to subscribe for - defaults to any item

Yields:

  • (Hash)

    Receives notification hashes when these notifications occur

Since:

  • 0.0.1



349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
# File 'lib/demiurge/dsl.rb', line 349

def on_notification(event, action_name, options = {}, &block)
  @built_item.state["on_handlers"] ||= {}
  @built_item.state["on_handlers"][event] = action_name
  register_built_action("name" => action_name, "block" => block)

  location = options[:location] || options["location"] || @built_item.location
  zone = options[:zone] || options["zone"] || location.zone_name || @built_item.zone_name
  item = options[:actor] || options["actor"] || :all

  @engine.subscribe_to_notifications type: event, zone: zone, location: location, actor: item do |notification|
    # To keep this statedump-safe, need to look up the item again
    # every time. @built_item isn't guaranteed to last.
    @engine.item_by_name(@name).run_action(action_name, notification)
  end
  nil
end

#position(pos) ⇒ void

This method returns an undefined value.

Set the position of the built object.

Parameters:

  • pos (String)

    The new position string for this built object.

Since:

  • 0.0.1



317
318
319
320
# File 'lib/demiurge/dsl.rb', line 317

def position(pos)
  @built_item.state["position"] = pos
  nil
end

#stateDemiurge::ActionItemInternal::ActionItemStateWrapper

Get the state, or at least a wrapper object to it, for DSL usage.

Returns:

Since:

  • 0.0.1



269
270
271
# File 'lib/demiurge/dsl.rb', line 269

def state
  @wrapper ||= ::Demiurge::ActionItemInternal::ActionItemStateWrapper.new(self)
end