class SorterBase
Attributes
player_position_map[R]
todo:remove for avoid sync errors (can't add key during iteration)
players_ids[R]
players_locker[R]
players_resources_map[R]
sort_criteria_non_players[RW]
top_size[RW]
properties
Public Class Methods
new()
click to toggle source
methods
# File lib/mrpin/core/utils/sorter_base.rb, line 46 def initialize @top_size = 100 @sort_criteria_non_players = 0 # ordered player_ids @players_ids = [] # key player_id, value - position @player_position_map = {} # key - player_id, value - player specify resource count @players_resources_map = {} @players_locker = Mutex.new end
Public Instance Methods
add_player(player, sort_criteria_value = 0)
click to toggle source
manager players
# File lib/mrpin/core/utils/sorter_base.rb, line 287 def add_player(player, sort_criteria_value = 0) @players_locker.synchronize do add_player_unsafe(player, sort_criteria_value) end end
delete_player(player)
click to toggle source
# File lib/mrpin/core/utils/sorter_base.rb, line 320 def delete_player(player) @players_locker.synchronize do player_id = player.id position_old = @player_position_map[player.id] return if position_old.nil? @players_ids.delete_at(position_old - 1) @players_resources_map.delete(player_id) @player_position_map.delete(player_id) update_player_positions(position_old, @players_ids.size) if position_old <= @top_size position_new = [@players_ids.size + 1, @top_size + 1].max resource_count_new = 0 on_player_left_from_top(player, position_old, position_new, resource_count_new) end end end
get_player_info(player_id)
click to toggle source
return {
player_id: sort_criteria: position:
}
# File lib/mrpin/core/utils/sorter_base.rb, line 226 def get_player_info(player_id) result = nil @players_locker.synchronize do return result unless @player_position_map.key?(player_id) result = get_player_info_unsafe(player_id) end result end
get_player_position_total(player)
click to toggle source
# File lib/mrpin/core/utils/sorter_base.rb, line 208 def get_player_position_total(player) result = 0 @players_locker.synchronize do result = @player_position_map[player.id] end result end
get_players_ids(position_start = 0, position_end = nil)
click to toggle source
methods for get info
# File lib/mrpin/core/utils/sorter_base.rb, line 197 def get_players_ids(position_start = 0, position_end = nil) result = nil @players_locker.synchronize do result = get_players_ids_unsafe(position_start, position_end) end result end
get_players_infos(position_start = 0, position_end = nil)
click to toggle source
return array of {
player_id: sort_criteria: position:
}
# File lib/mrpin/core/utils/sorter_base.rb, line 263 def get_players_infos(position_start = 0, position_end = nil) result = [] @players_locker.synchronize do players_ids = get_players_ids_unsafe(position_start, position_end) players_ids.each do |player_id| player_info = get_player_info_unsafe(player_id) result << player_info end end result end
init_sorter(sort_criteria_map)
click to toggle source
init sorter with start data sort_criteria_map - map with key - player_id, value - sort criteria
# File lib/mrpin/core/utils/sorter_base.rb, line 64 def init_sorter(sort_criteria_map) @players_ids = sort_criteria_map.keys.dup @players_ids.sort_by! do |id| sort_criteria_map[id] end @players_ids.reverse! @player_position_map = Hash[@players_ids.map.with_index(index_offset = 1).to_a] @players_resources_map = sort_criteria_map.dup end
try_update_position(player, sort_criteria_value)
click to toggle source
# File lib/mrpin/core/utils/sorter_base.rb, line 115 def try_update_position(player, sort_criteria_value) player_came_to_top = false player_left_from_top = false player_id = player.id if player.respond_to?(:is_player?) && !player.is_player? sort_criteria_value = @sort_criteria_non_players end @players_locker.synchronize do #add player if he doesn't exist if @player_position_map[player_id].nil? add_player_unsafe(player, sort_criteria_value) return end sort_criteria_old = @players_resources_map[player_id] return if sort_criteria_value == sort_criteria_old find_position_up = sort_criteria_value > sort_criteria_old position_old = @player_position_map[player_id] position_new = find_new_position(sort_criteria_value, position_old, find_position_up) if position_new > position_old # need because player already in top position_new -= 1 end @players_resources_map[player_id] = sort_criteria_value player_in_top = position_new <= @top_size if position_new != position_old player_came_to_top = position_old > @top_size && position_new <= @top_size player_left_from_top = position_old <= @top_size && position_new > @top_size @players_ids.delete_at(position_old - 1) @players_ids.insert(position_new - 1, player_id) update_player_positions(position_new, position_old) end if player_came_to_top on_player_came_to_top(player, position_old, position_new, sort_criteria_value) elsif player_left_from_top on_player_left_from_top(player, position_old, position_new, sort_criteria_value) elsif player_in_top #invalidate top player on_player_top_updated(player, position_old, position_new, sort_criteria_value) else #usual player, just invalidate online friends on_player_updated(player, position_old, position_new, sort_criteria_value) end end nil end
Protected Instance Methods
add_player_unsafe(player, sort_criteria_value = 0)
click to toggle source
# File lib/mrpin/core/utils/sorter_base.rb, line 294 def add_player_unsafe(player, sort_criteria_value = 0) player_id = player.id sort_criteria_value = 0 if sort_criteria_value.nil? return if @players_resources_map.empty? return unless @player_position_map[player_id].nil? index_position = @players_ids.size while index_position > 0 && sort_criteria_value > @players_resources_map[@players_ids[index_position - 1]] index_position -= 1 end @players_ids.insert(index_position, player_id) @players_resources_map[player_id] = sort_criteria_value @player_position_map[player_id] = index_position + 1 update_player_positions(index_position + 1, @players_ids.size) if index_position < @top_size on_player_came_to_top(player, nil, index_position + 1, sort_criteria_value) end end
find_new_position(resource_count, player_position_old, find_up)
click to toggle source
# File lib/mrpin/core/utils/sorter_base.rb, line 79 def find_new_position(resource_count, player_position_old, find_up) if find_up index_left = 0 index_right = player_position_old - 1 else index_left = player_position_old - 1 index_right = @players_ids.size - 1 end while index_left <= index_right median_index = (index_right + index_left) / 2 player_median_resources = @players_resources_map[@players_ids[median_index]] if resource_count > player_median_resources index_right = median_index - 1 elsif resource_count == player_median_resources index_left = median_index while resource_count == player_median_resources index_left = index_left + 1 player_median_resources = @players_resources_map[@players_ids[index_left]] end break else index_left = median_index + 1 end end index_left + 1 end
on_player_came_to_top(player, position_old, position_new, resource_count_new)
click to toggle source
# File lib/mrpin/core/utils/sorter_base.rb, line 27 def on_player_came_to_top(player, position_old, position_new, resource_count_new) #do nothing end
on_player_left_from_top(player, position_old, position_new, resource_count_new)
click to toggle source
# File lib/mrpin/core/utils/sorter_base.rb, line 32 def on_player_left_from_top(player, position_old, position_new, resource_count_new) #do nothing end
on_player_top_updated(player, position_old, position_new, resource_count_new)
click to toggle source
# File lib/mrpin/core/utils/sorter_base.rb, line 37 def on_player_top_updated(player, position_old, position_new, resource_count_new) #do nothing end
on_player_updated(player, position_old, position_new, resource_count_new)
click to toggle source
events
# File lib/mrpin/core/utils/sorter_base.rb, line 22 def on_player_updated(player, position_old, position_new, resource_count_new) #do nothing end
update_player_positions(position_new, position_old)
click to toggle source
# File lib/mrpin/core/utils/sorter_base.rb, line 178 def update_player_positions(position_new, position_old) position_start = [position_new, position_old].min position_end = [position_new, position_old].max (position_start..position_end).each do |position| player_id = @players_ids[position - 1] @player_position_map[player_id] = position end end
Private Instance Methods
get_player_info_unsafe(player_id)
click to toggle source
# File lib/mrpin/core/utils/sorter_base.rb, line 239 def get_player_info_unsafe(player_id) { player_id: player_id, position: @player_position_map[player_id], sort_criteria: @players_resources_map[player_id] } end
get_players_ids_unsafe(position_start, position_end)
click to toggle source
# File lib/mrpin/core/utils/sorter_base.rb, line 248 def get_players_ids_unsafe(position_start, position_end) position_end = position_end || (@top_size - 1) position_end = @players_ids.size if position_end < 0 result = @players_ids[position_start..position_end] end