From 8bea1648a3ddcf044b7c292fddd8ab52f175c1e2 Mon Sep 17 00:00:00 2001 From: Jeffrey Phillips Freeman <the@jeffreyfreeman.me> Date: Wed, 6 May 2020 19:59:05 -0400 Subject: [PATCH] Actions are now handled through a priority queue. --- lib/aethyr/core/components/manager.rb | 31 ++++++++++++++++++++++++-- lib/aethyr/core/connection/server.rb | 3 +++ lib/aethyr/core/util/priority_queue.rb | 2 ++ 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/lib/aethyr/core/components/manager.rb b/lib/aethyr/core/components/manager.rb index 2bac117..4120397 100644 --- a/lib/aethyr/core/components/manager.rb +++ b/lib/aethyr/core/components/manager.rb @@ -5,6 +5,7 @@ require 'aethyr/core/errors' require 'aethyr/core/objects/info/calendar' require 'aethyr/core/registry' require 'aethyr/core/util/publisher' +require 'aethyr/core/util/priority_queue' require 'set' #The Manager class uses the wisper to recieve commands from objects, which @@ -22,9 +23,12 @@ class Manager < Publisher #a Manager object in an external script. def initialize(objects = nil) Aethyr::Extend::HandlerRegistry.handle(self) + @soft_restart = false @storage = StorageMachine.new @uptime = Time.new.to_i + @future_actions = PriorityQueue.new + @pending_actions = PriorityQueue.new unless objects @cancelled_events = Set.new @@ -43,8 +47,26 @@ class Manager < Publisher end end - def submit_action action - action.action + def submit_action( action, priority: 0, wait: nil ) + if wait.nil? || wait <= 0 + @pending_actions.push(action, priority) + else + activate_when = Manager::epoch_now + wait + @future_actions.push({:action => action, :priority => priority}, activate_when) + end + end + + def pop_action + # first check for any future actions ready to become active + when_next = @future_actions.min_priority + while when_next && when_next < Manager::epoch_now do + future_next = @future_actions.pop_min + @pending_actions.push(future_next[:action], future_next[:priority]) + when_next = @future_actions.min_priority + end + + #return and pop whatever the next thing in the queue is. + return @pending_actions.pop_min end #Checks if a game object ID exists already, to avoid conflicts. @@ -427,4 +449,9 @@ class Manager < Publisher def to_s "The Manager" end + + private + def self.epoch_now + return DateTime.now.strftime('%s') + end end diff --git a/lib/aethyr/core/connection/server.rb b/lib/aethyr/core/connection/server.rb index 7c330bc..0326d2f 100644 --- a/lib/aethyr/core/connection/server.rb +++ b/lib/aethyr/core/connection/server.rb @@ -74,6 +74,9 @@ module Aethyr end end + next_action = $manager.pop_action + next_action.action unless next_action.nil? + # TODO this is a hack to fix a bug from calling resizeterm #check if global refresh is needed need_refresh = false diff --git a/lib/aethyr/core/util/priority_queue.rb b/lib/aethyr/core/util/priority_queue.rb index 2cd83bc..19bce22 100644 --- a/lib/aethyr/core/util/priority_queue.rb +++ b/lib/aethyr/core/util/priority_queue.rb @@ -405,6 +405,8 @@ class PriorityQueue delete_min[0] rescue nil end + alias pop_min delete_min_return_key + # call-seq: # delete_min_return_priority -> priority # -- GitLab