Class: Demiurge::Intention

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

Overview

An Intention is an unresolved event. Some part of the simulated world "wishes" to take an action. This need not be a sentient being - any change to the world should occur with an Intention then being resolved into changes in state and events -- or not. It's also possible for an intention to resolve to nothing at all. For instance, an intention to move in an impossible direction could simply resolve with no movement, no state change and no event.

Intentions go through verification, resolution and eventually notification.

Intentions are not, in general, serializable. They normally persist for only a single tick. To persist an intention for most StateItems, consider persisting action names instead.

For more details about Intention, see CONCEPTS.

Since:

  • 0.0.1

Instance Method Summary collapse

Constructor Details

#initialize(engine) ⇒ Intention

Subclasses of intention can require all sorts of constructor arguments to specify what the intention is. But the engine should always be supplied.

Parameters:

Since:

  • 0.0.1



28
29
30
31
32
# File 'lib/demiurge/intention.rb', line 28

def initialize(engine)
  @cancelled = false
  @engine = engine
  @intention_id = engine.get_intention_id
end

Instance Method Details

#allowed?Boolean

This method allows child classes of Intention to check whether they should happen at all. If this method returns false, the intention will self-cancel without sending a notification and quietly not occur. The method exists primarily to allow "illegal" intentions like walking through a wall or drinking nonexistent water to quietly not happen without the rest of the simulation responding to them in any way.

Returns:

  • (Boolean)

    If this method returns false, the Intention will quietly self-cancel before the offer phase.

Since:

  • 0.0.1



116
117
118
# File 'lib/demiurge/intention.rb', line 116

def allowed?
  raise "Unimplemented 'allowed?' for intention: #{self.inspect}!"
end

#applyvoid

This method returns an undefined value.

This method tells the Intention that it has successfully occurred and it should modify StateItems accordingly. Normally this will only be called after #allowed? and #offer have completed, and other items have had a chance to modify or cancel this Intention.

Since:

  • 0.0.1



128
129
130
# File 'lib/demiurge/intention.rb', line 128

def apply
  raise "Unimplemented 'apply' for intention: #{self.inspect}!"
end

#apply_notificationvoid

This method returns an undefined value.

Intentions should send an apply notice when they are successfully applied. #apply_notification can be overridden by child classes to send more specific information.

Since:

  • 0.2.0



88
89
90
91
92
93
94
95
96
97
# File 'lib/demiurge/intention.rb', line 88

def apply_notification
  @engine.send_notification({
                              :id => @intention_id,
                              :intention_type => self.class.to_s,
                              :info => @cancelled_info
                            },
                            type: Demiurge::Notifications::IntentionApplied, zone: "admin", location: nil, actor: nil,
                            include_context: true)
  nil
end

#cancel(reason, info = {}) ⇒ void

This method returns an undefined value.

This cancels the intention, and gives the reason for the cancellation.

Parameters:

  • reason (String)

    A human-readable reason this action was cancelled

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

    A String-keyed Hash of additional information about the cancellation

Since:

  • 0.0.1



41
42
43
44
45
46
47
48
# File 'lib/demiurge/intention.rb', line 41

def cancel(reason, info = {})
  @cancelled = true
  @cancelled_by = caller(1, 1)
  @cancelled_reason = reason
  @cancelled_info = info
  cancel_notification
  nil
end

#cancel_notificationvoid

This method returns an undefined value.

Most intentions will send a cancellation notice when they are cancelled. By default, this will include who cancelled the intention and why.

If the cancellation info Hash includes "silent" with a true value, by default no notification will be sent out. This is to avoid an avalache of notifications for common cancelled intentions that happen nearly every tick. Examples include an agent's action queue being empty so it cancels its intention. These are normal operation and nobody is likely to need notification every tick that they didn't ask to do anything so they didn't.

#cancel_notification can be overridden by child classes for more specific cancel notifications.

Since:

  • 0.0.1



68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/demiurge/intention.rb', line 68

def cancel_notification
  return if @cancelled_info && @cancelled_info["silent"]
  @engine.send_notification({
                              :reason => @cancelled_reason,
                              :by => @cancelled_by,
                              :id => @intention_id,
                              :intention_type => self.class.to_s,
                              :info => @cancelled_info
                            },
                            type: Demiurge::Notifications::IntentionCancelled, zone: "admin", location: nil, actor: nil,
                            include_context: true)
  nil
end

#cancelled?Boolean

This returns whether this intention has been cancelled.

Returns:

  • (Boolean)

    Whether the notification is cancelled.

Since:

  • 0.0.1



102
103
104
# File 'lib/demiurge/intention.rb', line 102

def cancelled?
  @cancelled
end

#offervoid

Note:

This method changed signature in 0.2.0 to stop taking an intention ID.

This method returns an undefined value.

When an Intention is "offered", that means appropriate other entities have a chance to modify or cancel the intention. For instance, a movement action in a room should be offered to that room, which may trigger a special action (e.g. trap) or change the destination of the action (e.g. exits, slippery ice, spinning spaces.)

See Also:

Since:

  • 0.0.1



143
144
145
# File 'lib/demiurge/intention.rb', line 143

def offer
  raise "Unimplemented 'offer' for intention: #{self.inspect}!"
end

#try_applyvoid

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.

Note:

This method changed signature in 0.2.0 to stop taking an intention ID.

This method returns an undefined value.

This is a normally-private part of the Tick cycle. It checks the #allowed? and #offer phases for this one specific Intention.

Since:

  • 0.0.1



154
155
156
157
158
159
160
161
162
# File 'lib/demiurge/intention.rb', line 154

def try_apply
  return unless allowed?
  offer
  return if cancelled? # Notification should already have been sent out
  apply
  return if cancelled? # Notification should already have been sent out
  apply_notification
  nil
end