class AutoC::Module::EntityContainer::AutoC::Module::EntityContainer::Module::State::AutoC::Module::EntityContainer::AutoC::Module::EntityContainer::Module::State::Module::StreamFile::AutoC::Module::EntityContainer::AutoC::Module::EntityContainer::Module::State::AutoC::Module::EntityContainer::AutoC::Module::EntityContainer::Module::State::Module::StreamFile::Module::Header::AutoC::Module::EntityContainer::AutoC::Module::EntityContainer::Module::State::AutoC::Module::EntityContainer::AutoC::Module::EntityContainer::Module::State::Module::StreamFile::AutoC::Module::EntityContainer::AutoC::Module::EntityContainer::Module::State::AutoC::Module::EntityContainer::AutoC::Module::EntityContainer::Module::State::Module::StreamFile::Module::Header::Module::Source

Attributes

complexity[R]
index[R]
module[R]

Public Class Methods

new(m, index) click to toggle source
# File lib/autoc/module.rb, line 262
def initialize(m, index)
  @module = m
  @complexity = 0
  @index = index
end

Public Instance Methods

<<(entity) click to toggle source
Calls superclass method AutoC::Module::EntityContainer#<<
# File lib/autoc/module.rb, line 268
def <<(entity)
  @complexity += entity.complexity unless entities.include?(entity)
  super
end
file_name(= self.module.source_count < 2 ? " click to toggle source
# File lib/autoc/module.rb, line 260
  def file_name = self.module.source_count < 2 ? "#{self.module.name}_auto.c" : "#{self.module.name}_auto#{index}.c"

  def initialize(m, index)
    @module = m
    @complexity = 0
    @index = index
  end

  def <<(entity)
    @complexity += entity.complexity unless entities.include?(entity)
    super
  end

private

  def render_contents(stream)
    render_prologue(stream)
    total_entities = ::Set.new
    entities.each { |e| total_entities.merge(e.total_references) }
    total_entities.to_a.sort.each { |e| e.forward_declarations.each { |x| stream << x } }
    entities.to_a.sort.each { |e| e.implementation.each { |x| stream << x } }
  end

  def render_prologue(stream)
    stream << %{
      #{Module::CAP}
      #include "#{self.module.header.file_name}"
    }
  end

  def stream = @stream ||= Module::StreamFile.new(file_name+'~', 'wt')

end # Source


module Entity

  include ::Comparable

  # A set of the entity's immediate references which, unlike dependencies, do not enforce the entities relative ordering
  def references = @references ||= ReferenceSet.new

  # Return the entire entity's reference set staring with self
  def total_references = @total_references ||= collect_references(::Set.new)

  # A set of the entity's immediate dependencies which enforce the entities relative ordering
  def dependencies = @dependencies ||= DependencySet.new(self)

  # Return the entire entity's dependency set staring with self
  def total_dependencies = @total_dependencies ||= collect_dependencies(::Set.new)

  protected def collect_references(set)
    unless set.include?(self)
      set << self
      references.each { |x| x.collect_references(set) }
    end
    set
  end

  protected def collect_dependencies(set)
    unless set.include?(self)
      set << self
      dependencies.each { |x| x.collect_dependencies(set) }
    end
    set
  end

  def <=>(other) = position <=> other.position

  # Compute the entity's relative position with respect to its dependencies
  def position = @position ||= begin
    p = 0
    # This code goes into infinite recursion on circular dependency
    # which must be resolved manually with Entity#references
    total_dependencies.each do |d|
      unless equal?(d)
        dp = d.position
        p = dp if p < dp # p <- max(p, dp)
      end
    end
    p + 1 # Arrange entity to follow all its dependencies
  end

  def complexity = forward_declarations.complexity + implementation.complexity # Interface part is not considered as it is shared across the sources

  def interface
    @interface ||= begin
      render_interface(stream = Module::Builder.new)
      stream
    end
  end

  def forward_declarations
    @forward_declarations ||= begin
      render_forward_declarations(stream = Module::Builder.new)
      stream
    end
  end

  def implementation
    @implementation ||= begin
      render_implementation(stream = Module::Builder.new)
      stream
    end
  end

private

  ### Overridable rendering methods

  def render_interface(stream) = nil

  def render_forward_declarations(stream) = nil

  def render_implementation(stream) = nil

end # Entity


Entity::ReferenceSet = ::Set


# @private
class Entity::DependencySet < ::Set

  def initialize(entity)
    super()
    @entity = entity
  end

  def <<(x)
    @entity.references << x # Each dependency is also registered as a reference
    super
  end

end # DependencySet


# Helper class to represent plain C side code block
class Code

  include Entity

  def initialize(interface: nil, implementation: nil, definitions: nil)
    @interface_ = interface
    @definitions_ = definitions
    @implementation_ = implementation
  end

  def inspect = "... <#{self.class}>"

private

  def render_interface(stream)
    stream << @interface_ unless @interface_.nil?
  end

  def render_implementation(stream)
    stream << @implementation_ unless @implementation_.nil?
  end

  def render_forward_declarations(stream)
    stream << @definitions_ unless @definitions_.nil?
  end

end # Code


# Helper class to inject a system-wide header into the C side interface part of the module
class SystemHeader < AutoC::Code
  def initialize(
render_contents(stream) click to toggle source
# File lib/autoc/module.rb, line 275
def render_contents(stream)
  render_prologue(stream)
  total_entities = ::Set.new
  entities.each { |e| total_entities.merge(e.total_references) }
  total_entities.to_a.sort.each { |e| e.forward_declarations.each { |x| stream << x } }
  entities.to_a.sort.each { |e| e.implementation.each { |x| stream << x } }
end
render_prologue(stream) click to toggle source
# File lib/autoc/module.rb, line 283
def render_prologue(stream)
  stream << %{
    #{Module::CAP}
    #include "#{self.module.header.file_name}"
  }
end
stream(= @stream ||= Module::StreamFile.new(file_name+'~', 'wt')) click to toggle source
# File lib/autoc/module.rb, line 290
  def stream = @stream ||= Module::StreamFile.new(file_name+'~', 'wt')

end