comfpile-old/lib/comfpile/core.rb

141 lines
No EOL
3.9 KiB
Ruby

require_relative 'artefact_engine.rb'
module Comfpile
class Core
attr_reader :processing_stack
def initialize()
@artefact_engines = []
@artefact_prio_counter = 0
# Artefacts are arranged in a double-hash.
# First query is stage, second filename.
@artefacts = {}
# Stack-style processing queue for item processing
@processing_stack = []
end
def find_artefact(stage, file = :none)
@artefacts.dig(stage, file)
end
# Create or find a new artefact.
#
# This will first see if a given artefact matching
# the stage and target descriptions already exists, and
# will return it, if found. Otherwise it will
# consult all given artefact crafting engines to
# see if a new artefact can be created, which will be returned.
#
# If no artefact can be made, nil is returned
#
# @param [Symbol, String] stage State that shall be created (e.g. :parsed, :compiled, etc.)
# @param [String] file File or other target that shall be looked at (e.g. "main.cpp")
#
# @return [Comfpile::Artefact, nil] Found or created artefact, or nil if nothing could be done
#
def craft_artefact(stage, file = :none)
artefact = find_artefact(stage, file)
return artefact unless artefact.nil?
@artefact_engines.each do |engine|
artefact = engine.craft stage, file
if artefact
@artefacts[stage] ||= {}
@artefacts[stage][file] = artefact
@processing_stack.push artefact
return artefact
end
end
nil
end
def add_artefact(stage, file = :none, engine: nil, artefact_class: Comfpile::Artefact)
return unless find_artefact(stage, file).nil?
a = Artefact.new(self, engine, stage, file);
@artefacts[stage] ||= {}
@artefacts[stage][file] = a
yield(a) if block_given?
nil
end
# @yieldparam [Comfpile::ArtefactEngine] Engine that was newly created
def add_artefact_engine(engine_class = Comfpile::ArtefactEngine, **options)
new_engine = if(engine_class.is_a? Comfpile::ArtefactEngine)
engine_class
else
engine = engine_class.new(self,
subpriority: @artefact_prio_counter, **options)
@artefact_prio_counter += 1
engine
end
yield(new_engine) if block_given?
@artefact_engines << new_engine
@artefact_engines.sort!
new_engine
end
def processing_stack_prune()
loop do
return if @processing_stack.empty?
if @processing_stack[-1].completed?
@processing_stack.pop
else
break
end
end
nil
end
def processing_stack_find_next()
i = 0
@processing_stack.reverse_each do |a|
i += 1
if a.waiting?
puts "DBG - Found item after #{i} checks"
return a
end
end
nil
end
def execute_step
return if @processing_stack.empty?
puts "Got #{@processing_stack.length} items..."
processing_stack_prune
artefact = processing_stack_find_next
return nil if artefact.nil?
puts "Processing artefact #{artefact.stage} #{artefact.target}"
begin
artefact.execute_step
rescue ArtefactExecSkipError
end
nil
end
end
end