OSDN Git Service

Forgot to add them at r338
authorbeatles <beatles@b8c68f68-1e22-0410-b08e-880e1f8202b4>
Wed, 29 Jul 2009 13:53:03 +0000 (13:53 +0000)
committerbeatles <beatles@b8c68f68-1e22-0410-b08e-880e1f8202b4>
Wed, 29 Jul 2009 13:53:03 +0000 (13:53 +0000)
shogi_server/buoy.rb [new file with mode: 0644]
shogi_server/config.rb [new file with mode: 0644]
test/mock_game.rb [new file with mode: 0644]
test/mock_log_message.rb [new file with mode: 0644]

diff --git a/shogi_server/buoy.rb b/shogi_server/buoy.rb
new file mode 100644 (file)
index 0000000..7008ff1
--- /dev/null
@@ -0,0 +1,129 @@
+require 'shogi_server/config'
+require 'shogi_server/game'
+require 'yaml'
+require 'yaml/store'
+
+module ShogiServer
+
+  class BuoyGame
+    attr_reader :game_name
+    attr_reader :moves
+    attr_reader :owner
+    attr_reader :count
+
+    def initialize(game_name, moves, owner, count)
+      raise "owner name is required" if owner && !owner.instance_of?(String)
+      @game_name, @moves, @owner, @count = game_name, moves, owner, count
+    end
+
+    def decrement_count
+      @count -= 1
+    end
+
+    def ==(rhs)
+      return (@game_name == rhs.game_name && 
+              @moves == rhs.moves &&
+              @owner == rhs.owner &&
+              @count == rhs.count)
+    end
+  end
+
+  class NilBuoyGame < BuoyGame
+    def initialize
+      super(nil, nil, nil, 0)
+    end
+  end
+
+  class Buoy
+
+    # "buoy_hoge-900-0"
+    #
+    def Buoy.game_name?(str)
+      return /^buoy_.*\-\d+\-\d+$/.match(str) ? true : false
+    end
+
+    def initialize(conf = {})
+      @conf = $config || Config.new
+      @conf.merge!(conf, true)
+      filename = @conf[:buoy, :filename] || File.join(@conf[:topdir], "buoy.yaml")
+      @db = YAML::Store.new(filename)
+      @db.transaction do
+      end
+    end
+
+    def is_new_game?(game_name)
+      @db.transaction(true) do
+        return !@db.root?(game_name)
+      end
+    end
+
+    def add_game(buoy_game)
+      @db.transaction do
+        if @db.root?(buoy_game.game_name)
+          # error
+        else
+          hash = {'moves' => buoy_game.moves,
+                  'owner' => buoy_game.owner,
+                  'count' => buoy_game.count}
+          @db[buoy_game.game_name] = hash
+        end
+      end
+    end
+
+    def update_game(buoy_game)
+      @db.transaction do
+        if @db.root?(buoy_game.game_name)
+          hash = {'moves' => buoy_game.moves,
+                  'owner' => buoy_game.owner,
+                  'count' => buoy_game.count}
+          @db[buoy_game.game_name] = hash
+        else
+          # error
+        end
+      end
+    end
+
+    def delete_game(buoy_game)
+      @db.transaction do
+        @db.delete(buoy_game.game_name)
+      end
+    end
+
+    def get_game(game_name)
+      @db.transaction(true) do
+        hash = @db[game_name]
+        if hash
+          moves = hash['moves']
+          owner = hash['owner']
+          count = hash['count'].to_i
+          return BuoyGame.new(game_name, moves, owner, count)
+        else
+          return NilBuoyGame.new
+        end
+      end
+    end
+  end
+
+
+  # Observer obserers GameResult of a buoy game
+  #
+  class BuoyObserver
+    def update(game_result)
+      game_name = game_result.game.game_name
+      unless game_result.instance_of?(GameResultWin)
+        log_message "#{game_name} was not valid. It will be retried"
+        return
+      end
+      buoy = Buoy.new
+      buoy_game = buoy.get_game(game_name)
+      buoy_game.decrement_count
+      if buoy_game.count < 1
+        buoy.delete_game buoy_game
+        log_message "#{game_name} has finished."
+      else
+        buoy.update_game buoy_game
+        log_message "#{game_name} remains #{buoy_game.count} slots."
+      end
+    end
+  end
+end # module ShogiServer
diff --git a/shogi_server/config.rb b/shogi_server/config.rb
new file mode 100644 (file)
index 0000000..288a00e
--- /dev/null
@@ -0,0 +1,162 @@
+#--
+# Copyright (c) 2006-2009 by Craig P Jolicoeur <cpjolicoeur at gmail dot com>
+# Copyright (C) 2009 Daigo Moriwaki <daigo at debian dot org>
+# 
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+# 
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+# 
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#++
+
+#
+# This code was copied from cerberus[1] and modified.
+# [1] http://rubyforge.org/projects/cerberus
+#
+
+require 'erb'
+
+class Hash
+  def deep_merge!(second)
+    second.each_pair do |k,v|
+      if self[k].is_a?(Hash) && second[k].is_a?(Hash)
+        self[k].deep_merge!(second[k])
+      else
+        self[k] = second[k]
+      end
+    end
+  end
+end
+
+class HashWithIndifferentAccess < Hash
+  def initialize(constructor = {})
+    if constructor.is_a?(Hash)
+      super()
+      update(constructor)
+    else
+      super(constructor)
+    end
+  end
+  def default(key)
+    self[key.to_s] if key.is_a?(Symbol)
+  end  
+
+  alias_method :regular_writer, :[]= unless method_defined?(:regular_writer)
+  alias_method :regular_update, :update unless method_defined?(:regular_update)
+  
+  def []=(key, value)
+    regular_writer(convert_key(key), convert_value(value))
+  end
+
+  def update(other_hash)
+    other_hash.each_pair { |key, value| regular_writer(convert_key(key), convert_value(value)) }
+    self
+  end
+  
+  alias_method :merge!, :update
+
+  def key?(key)
+    super(convert_key(key))
+  end
+
+  alias_method :include?, :key?
+  alias_method :has_key?, :key?
+  alias_method :member?, :key?
+
+  def fetch(key, *extras)
+    super(convert_key(key), *extras)
+  end
+
+  def values_at(*indices)
+    indices.collect {|key| self[convert_key(key)]}
+  end
+
+  def dup
+    HashWithIndifferentAccess.new(self)
+  end
+  
+  def merge(hash)
+    self.dup.update(hash)
+  end
+
+  def delete(key)
+    super(convert_key(key))
+  end
+    
+  protected
+    def convert_key(key)
+      key.kind_of?(Symbol) ? key.to_s : key
+    end
+    def convert_value(value)
+      value.is_a?(Hash) ? HashWithIndifferentAccess.new(value) : value
+    end
+end
+
+
+module ShogiServer
+  class Config
+    FILENAME = 'shogi-server.yaml'
+
+    def initialize(options = {})
+      @config = HashWithIndifferentAccess.new
+      
+      if options.is_a?(Hash)
+        options[:topdir] ||= $topdir if $topdir
+        options[:topdir] ||= options["topdir"] if options["topdir"]
+      end
+
+      if options[:topdir] && File.exist?(File.join(options[:topdir], FILENAME))
+        merge!(YAML.load(ERB.new(IO.read(File.join(options[:topdir], FILENAME)).result)))
+      end
+
+      merge!(options)
+    end
+
+    def [](*path)
+      c = @config
+      path.each{|p|
+        c = c[p]
+        return if c.nil?
+      }
+      c
+    end
+
+    def merge!(hash, overwrite = true)
+      return unless hash && !hash.empty?
+      if overwrite
+        @config.deep_merge!(hash)
+      else
+        d = HashWithIndifferentAccess.new(hash)
+        d.deep_merge!(@config)
+        @config = d
+      end
+    end
+
+    def inspect
+      @config.inspect
+    end
+
+    private
+    def symbolize_hash(hash)
+      hash.each_pair{|k,v|
+        if v === Hash
+          hash[k] = HashWithIndifferentAccess.new(symbolize_hash(v))
+        end
+      }
+    end
+  end
+end # module ShogiServer
diff --git a/test/mock_game.rb b/test/mock_game.rb
new file mode 100644 (file)
index 0000000..b18ab20
--- /dev/null
@@ -0,0 +1,60 @@
+class MockGame
+  attr_accessor :finish_flag
+  attr_reader :log
+  attr_accessor :prepared_expire
+  attr_accessor :rejected
+  attr_accessor :is_startable_status
+  attr_accessor :started
+  attr_accessor :game_id
+  attr_accessor :game_name
+
+  def initialize
+    @finish_flag     = false
+    @log             = []
+    @prepared_expire = false
+    @rejected        = false
+    @is_startable_status = false
+    @started             = false
+    @game_id         = "dummy_game_id"
+    @game_name       = "mock_game_name"
+    @monitoron_called = false
+    @monitoroff_called = false
+  end
+
+  def handle_one_move(move, player)
+    return @finish_flag
+  end
+
+  def log_game(str)
+    @log << str
+  end
+
+  def prepared_expire?
+    return @prepared_expire
+  end
+
+  def reject(str)
+    @rejected = true
+  end
+
+  def is_startable_status?
+    return @is_startable_status
+  end
+
+  def start
+    @started = true
+  end
+
+  def show
+    return "dummy_game_show"
+  end
+
+  def monitoron(player)
+    @monitoron_called = true
+  end
+
+  def monitoroff(player)
+    @monitoroff_called = true
+  end
+end
+
diff --git a/test/mock_log_message.rb b/test/mock_log_message.rb
new file mode 100644 (file)
index 0000000..e2e1e1d
--- /dev/null
@@ -0,0 +1,17 @@
+def log_info(str)
+  $stderr.puts str
+end
+
+def log_message(str)
+  $stderr.puts str
+end
+
+def log_warning(str)
+  $stderr.puts str
+end
+
+def log_error(str)
+  $stderr.puts str
+end
+
+