Class: Lich::Gemstone::Combat::AsyncProcessor
- Inherits:
-
Object
- Object
- Lich::Gemstone::Combat::AsyncProcessor
- Defined in:
- documented/gemstone/combat/async_processor.rb
Overview
Single-threaded async combat processor that handles combat chunks in arrival order.
Chunks are enqueued via #process_async from the game stream thread (O(1), non-blocking) and consumed sequentially by a dedicated worker thread. This guarantees that status updates, UCS changes, and damage events are processed in order, and ensures creature instances are only mutated from one thread.
The worker thread is automatically respawned if it dies (e.g., when the parent script exits), since it can be spawned from a script thread but must survive the script's lifetime to process events from the downstream hook.
Instance Method Summary collapse
-
#initialize(_max_threads = 1) ⇒ AsyncProcessor
constructor
max_threads retained for call-site compatibility; processing is intentionally single-threaded to preserve event ordering.
-
#process_async(chunk) ⇒ Object
Enqueue a chunk; O(1), never blocks the game stream.
-
#shutdown ⇒ Object
Drain remaining work and stop the worker.
-
#stats ⇒ Hash
Returns the current state of the async processor.
Constructor Details
#initialize(_max_threads = 1) ⇒ AsyncProcessor
max_threads retained for call-site compatibility; processing is intentionally single-threaded to preserve event ordering.
37 38 39 40 41 42 43 |
# File 'documented/gemstone/combat/async_processor.rb', line 37 def initialize(_max_threads = 1) @queue = Queue.new @processing = false @chunks_processed = 0 @spawn_mutex = Mutex.new ensure_worker end |
Instance Method Details
#process_async(chunk) ⇒ Object
Enqueue a chunk; O(1), never blocks the game stream.
Also revives the worker if it died: a worker spawned from a script context (enable! via autostart/;e) belongs to that script's thread group and is killed when the script exits. process_async runs on the downstream-hook (game) thread, so a worker respawned here survives script death.
52 53 54 55 56 57 |
# File 'documented/gemstone/combat/async_processor.rb', line 52 def process_async(chunk) return if chunk.empty? @queue.push(chunk) ensure_worker nil end |
#shutdown ⇒ Object
Drain remaining work and stop the worker.
60 61 62 63 64 65 66 67 68 69 70 |
# File 'documented/gemstone/combat/async_processor.rb', line 60 def shutdown respond "[Combat] Waiting for #{@queue.size} queued chunks..." if Tracker.debug?(:verbose) @queue.push(:shutdown) @worker.join # Force GC after shutdown to help with memory fragmentation. # Compaction is routed through Lich::Util::GtkCompaction, which # keeps it safe to use alongside gtk3. GC.start Lich::Util::GtkCompaction.safe_compact! end |
#stats ⇒ Hash
Returns the current state of the async processor.
81 82 83 84 85 86 87 88 |
# File 'documented/gemstone/combat/async_processor.rb', line 81 def stats { active: @processing ? 1 : 0, queued: @queue.size, total: @chunks_processed, worker_alive: !@worker.nil? && @worker.alive? } end |