# frozen_string_literal: true require 'georuby' require 'sequel' require 'sequel-postgis-georuby' require 'singleton' require 'concurrent-ruby' module TacScribe class Cache include Singleton include GeoRuby::SimpleFeatures @@cache = Concurrent::Hash.new attr_accessor :reference_latitude, :reference_longitude def data @@cache end def write_object(object) if reference_latitude != 0 || reference_longitude != 0 localize_position(object) end id = object[:object_id] object[:id] = id cache_object = @@cache[id] object[:position] = set_position(object, cache_object) %i[object_id latitude longitude color country].each do |key| object.delete(key) end if object[:coalition] object[:coalition] = case object[:coalition] when 'Allies' 0 when 'Enemies' 1 else 2 end end if cache_object object[:heading] = calculate_heading(cache_object, object) cache_object.merge!(object) else object[:heading] = -1 cache_object = object end if !cache_object.key?(:altitude) || !cache_object[:altitude] cache_object[:altitude] = 0 end if !cache_object.key?(:coalition) || !cache_object[:coalition] cache_object[:coalition] = 2 end cache_object[:pilot] = nil unless cache_object.key?(:pilot) cache_object[:group] = nil unless cache_object.key?(:group) cache_object[:deleted] = false unless cache_object.key?(:deleted) cache_object[:updated_at] = Time.now @@cache[id] = cache_object end def delete_object(id) @@cache[id][:deleted] = true if @@cache[id] end def clear @@cache.clear end private def localize_position(object) if reference_latitude && object.key?(:latitude) object[:latitude] = reference_latitude + object[:latitude] end if reference_longitude && object.key?(:longitude) object[:longitude] = reference_longitude + object[:longitude] end end def set_position(object, cache_object) longitude = if object.key?(:longitude) object[:longitude] else cache_object[:position].y end latitude = if object.key?(:latitude) object[:latitude] else cache_object[:position].x end Point.from_x_y(longitude, latitude) end def calculate_heading(cache_object, object) return cache_object[:heading] if cache_object[:position] == object[:position] begin cache_object[:position].bearing_to(object[:position]).to_i rescue Math::DomainError => e puts 'Could not calculate heading: ' + e.message puts 'Old Position: ' + cache_object[:position].inspect puts 'New Position: ' + object[:position].inspect end end end end