require "rubylib/tcp_pack.rb"
require "rubylib/tcp_client.rb"


#_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
# * TCP Server类
#-------------------------------------------------------------------------------------------------------
#
#     
#_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
class GameTCPServer < FSServer

	#_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
	# * Scheduler 定時任務
	#-------------------------------------------------------------------------------------------------------
	#_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
	class Scheduler
		
		attr_reader :sid
		attr_reader :server
		attr_reader :execute_proc
		def initialize()
		end
		#_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		# * 計時器啟動
		#-------------------------------------------------------------------------------------------------------
		#  
		#_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		def start(server, dt, times, execute_proc)

			@execute_proc = execute_proc.to_s
			@server = server

			@sid = @server.scheduler(dt.to_f, times, @execute_proc)
		end
		def stop
			if(@server != nil)
				@server.unscheduler_update(@sid)
				@sid = 0
				@server = nil
			end
		end
		
	end
  
  # 所有客户端
  attr_reader :clients
  attr_reader :byte_order
	attr_reader :schedulers

	#_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
	# * server 初始化
	#-------------------------------------------------------------------------------------------------------
	#  @server_name
	#_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
  def initialize(server_name)
     super(server_name)
     @clients = {}
     @byte_order = 0
     @start_proc = nil
		 @schedulers = {}
  end

	#_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
	# * 開始一個定時任務
	#-------------------------------------------------------------------------------------------------------
	#     @dt     dt (float) 間隔
	#     @times  循環次數 -1 unlimit
	#     @proc   每次執行的回調方法  从 proc -> method  测试证明 call_method  比 proc.call 效率快
	#_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
	def scheduler_update(dt, times, method_sym)
		scheduler = Scheduler.new()
		scheduler.start(self, dt, times, method_sym)
		@schedulers[scheduler.sid] = scheduler
		scheduler.sid
	end

	def stop_scheduler(sid)
		if @schedulers.has_key?(sid)
			unscheduler(sid)
			@schedulers.delete(sid)
		end
	end


	#_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
  # * 开始服务
  #-------------------------------------------------------------------------------------------------------
  #     @ip     ip地址
  #     @port   端口
  #     @proc   开始后的回调
  #_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
  def start_server(ip, port, &proc)
      super(ip, port, T_TCP);
      @start_proc = proc;
  end
  

  @@_start_time = Time.now.to_i;
  @@_times = 0;
  #_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
  # * 收到包的时候的回调
  #-------------------------------------------------------------------------------------------------------
  #     @node_id    这个从哪个节点过来的
  #     @pack       pack
  #_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
  def on_handle_pack(node_id, pack)
      @@_times += 1
			now = Time.now.to_i;
      if(now - @@_start_time > 0)
          # print "#{self.name} handle packs #{@@_times}/#{now - @@_start_time}s \n"
          @@_start_time = now
          @@_times = 0
      end
  end
  
  #_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
  # * 当服务完成开启的回调
  #-------------------------------------------------------------------------------------------------------
  #
  #
  #_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
  def on_start()
      if(@start_proc != nil)
          @start_proc.call(self);
      end
  end
  
  #_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
  # * 当有新连接进来的时候
  #-------------------------------------------------------------------------------------------------------
  #     @node_id    新连接的节点ID
  #
  #_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
  def on_connect_node(node_id)
      # p "#{self.name} new connect node_id:#{node_id}, say'it hello ";
      @clients[node_id] = on_create_new_client.new(self, node_id);
  end
  
  #_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
  # * 当有连接关闭的时候
  #-------------------------------------------------------------------------------------------------------
  #     @node_id    关闭掉的节点ID
  #
  #_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
  def on_shutdown_node(node_id)
	    @clients[node_id].on_shutdown
      @clients.delete(node_id)
      # p "#{self.name} shutdown connect #{node_id}";
  end
 
  
  #_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
  # * 向指定节点发送包
  #-------------------------------------------------------------------------------------------------------
  #     @node_id	目标节点ID
	#     @pack    要发送的包
  #_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/n_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
  def send_pack_to(node_id, pack)
		if(@clients[node_id] != nil)
			@clients[node_id].send_pack(pack);
			return true
		end
#		raise("#{self.name} send_pack_to target_id(#{node_id}) is NULL clients id => #{@clients.keys}  pack_type => #{pack.pack_type}")
		return false
  end


	#_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
	# * 创建新client
	#-------------------------------------------------------------------------------------------------------
	#
	#_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/n_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
	def on_create_new_client
		TCPClient
	end

end
