Class: PirateGame::Client

Inherits:
Shuttlecraft
  • Object
show all
Defined in:
lib/pirate_game/client.rb

Constant Summary collapse

STATES =
[:select_game, :pub, :stage, :end]

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(opts = {}) ⇒ Client

Returns a new instance of Client.



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/pirate_game/client.rb', line 38

def initialize(opts={})
  opts[:protocol] ||= PirateGame::Protocol.default

  super(opts.merge({:verbose => true}))

  set_state :select_game

  @bridge          = nil
  @command_start   = nil
  @command_thread  = nil
  @completion_time = PirateGame::Boot.config["action_duration"]
  @current_action  = nil
  @log_book        = PirateGame::LogBook.new

  @slop_bucket = {}
end

Instance Attribute Details

#bridgeObject (readonly)

Returns the value of attribute bridge.



9
10
11
# File 'lib/pirate_game/client.rb', line 9

def bridge
  @bridge
end

#command_startObject (readonly)

The time the last command was issued



24
25
26
# File 'lib/pirate_game/client.rb', line 24

def command_start
  @command_start
end

#completion_timeObject

Returns the value of attribute completion_time.



26
27
28
# File 'lib/pirate_game/client.rb', line 26

def completion_time
  @completion_time
end

#current_actionObject (readonly)

The command the client is waiting for



31
32
33
# File 'lib/pirate_game/client.rb', line 31

def current_action
  @current_action
end

#log_bookObject (readonly)

Log of messages sent



14
15
16
# File 'lib/pirate_game/client.rb', line 14

def log_book
  @log_book
end

#slop_bucketObject (readonly)

Bucket for data being sent from game master



36
37
38
# File 'lib/pirate_game/client.rb', line 36

def slop_bucket
  @slop_bucket
end

#stateObject (readonly)

The state of the client. See STATES.



19
20
21
# File 'lib/pirate_game/client.rb', line 19

def state
  @state
end

Class Method Details

.default_nameObject



55
56
57
# File 'lib/pirate_game/client.rb', line 55

def self.default_name
  "Blackbeard"
end

Instance Method Details

#action_time_leftObject



59
60
61
62
63
# File 'lib/pirate_game/client.rb', line 59

def action_time_left
  return 0 unless waiting?

  @command_start - Time.now + @completion_time
end

#broadcast(msg) ⇒ Object



125
126
127
# File 'lib/pirate_game/client.rb', line 125

def broadcast(msg)
  each_client {|remote| remote.say(msg, @name) }
end

#clicked(button) ⇒ Object



71
72
73
74
75
# File 'lib/pirate_game/client.rb', line 71

def clicked button
  renewer = Rinda::SimpleRenewer.new @completion_time

  @mothership.write [:button, button, Time.now.to_i, DRb.uri], renewer
end

#end_game(data) ⇒ Object



106
107
108
109
110
# File 'lib/pirate_game/client.rb', line 106

def end_game data
  set_state :end

  @slop_bucket[:end_game] = data
end

#issue_command(item = nil) ⇒ Object



77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/pirate_game/client.rb', line 77

def issue_command item=nil
  item ||= @bridge.sample_item if @bridge

  return unless item

  @command_thread = Thread.new do
    wait_for_action item
  end

  Thread.pass until @command_start # this should be a proper barrier

  @current_action = "#{PirateCommand.action} the #{item}"
end

#perform_action(item, time, from) ⇒ Object

Sends action message to Game Master indicating that action has been successfully performed



119
120
121
122
123
# File 'lib/pirate_game/client.rb', line 119

def perform_action item, time, from
  if @mothership
    @mothership.write [:action, item, time, from]
  end
end

#registerObject



91
92
93
94
# File 'lib/pirate_game/client.rb', line 91

def register
  set_state :pub
  super
end

#renewerObject



133
134
135
# File 'lib/pirate_game/client.rb', line 133

def renewer
  PirateGame::TimeoutRenewer.new @completion_time
end

#return_to_pubObject



101
102
103
104
# File 'lib/pirate_game/client.rb', line 101

def return_to_pub
  @bridge = nil
  set_state :pub
end

#say(msg, name) ⇒ Object



129
130
131
# File 'lib/pirate_game/client.rb', line 129

def say(msg, name)
  @log_book.add msg, name || 'unknown'
end

#set_state(state) ⇒ Object

Raises:

  • (RuntimeError)


65
66
67
68
69
# File 'lib/pirate_game/client.rb', line 65

def set_state state
  raise RuntimeError, "invalid state #{state}" unless STATES.include? state

  @state = state
end

#start_stage(bridge, all_items) ⇒ Object



96
97
98
99
# File 'lib/pirate_game/client.rb', line 96

def start_stage(bridge, all_items)
  @bridge = PirateGame::Bridge.new(bridge, all_items)
  set_state :stage
end

#teammatesObject



112
113
114
# File 'lib/pirate_game/client.rb', line 112

def teammates
  registered_services.collect{|name,_| name}
end

#wait_for_action(item) ⇒ Object



137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# File 'lib/pirate_game/client.rb', line 137

def wait_for_action item
  @command_start = Time.now
  now = @command_start.to_i

  Thread.pass

  from = nil

  Timeout.timeout @completion_time do
    _, _, _, from =
      @mothership.read [:button, item, (now...now + 30), nil], renewer
  end

  perform_action item, Time.now, from

rescue Rinda::RequestExpiredError, Timeout::Error
ensure
  @command_thread = nil
  @command_start  = nil
  @current_action = nil
end

#waiting?Boolean

Returns:

  • (Boolean)


159
160
161
# File 'lib/pirate_game/client.rb', line 159

def waiting?
  @command_thread and @command_thread.alive? and @command_start
end