blob: 031c0335c62a75196068be349e0e3ab112f0cf1b [file] [log] [blame]
class Target::QueueDec < Target::Node
attr_accessor :name,:loc
def initialize(type,name)
@type,@name = type,name
end
def msg_hash()
return @type.msg_hash
end
def full_message_name(cpp_tree)
type = cpp_tree.get(@type)
return @type.loc.to_cpp_id(type.name)
end
def full_builder_name(cpp_tree)
return "::aos::MessageBuilder< #{full_message_name(cpp_tree)}>"
end
def full_type_name(cpp_tree)
return "::aos::Queue< #{full_message_name(cpp_tree)}>"
end
def type_name(cpp_tree,queue_type = "::aos::Queue")
type = cpp_tree.get(@type)
if(@type.loc == @loc) #use relative name
return "#{queue_type}<#{type.name}>"
else #use full name
return "#{queue_type}< #{@type.loc.to_cpp_id(type.name)}>"
end
end
def create_usage(cpp_tree)
"#{type_name(cpp_tree)} #{@name}"
end
def create(cpp_tree)
namespace = cpp_tree.get(@loc)
type = cpp_tree.get(@type)
cpp_tree.set(self,self)
type_name = type_name(cpp_tree)
full_type_name = full_type_name(cpp_tree)
namespace.add_cc("static #{type_name} *#{@name}_ptr")
counter = "#{@name}_counter"
namespace.add_cc("static int #{counter}")
str = <<COMMENT_END
Schwarz counter to construct and destruct the #{@name} queue.
Must be constructed before &#{@name} is constructed so that #{@name}_ptr
is valid so we can store a reference to the object.
COMMENT_END
str.split(/\n/).each do |str_sec|
namespace.class_comment(str_sec)
end
init_class = namespace.add_class("InitializerFor_" + @name)
init_class.add_cc_comment(
"The counter is initialized at load-time, i.e., before any of the static",
"objects are initialized.")
cons = CPP::Constructor.new(init_class)
init_class.add_member(:public,cons)
cons.suite << if_stmt = CPP::If.new("0 == #{counter}++")
cons_call = CPP::FuncCall.new("new #{type_name}")
cons_call.args.push(@loc.queue_name(@name).inspect)
if_stmt.suite << CPP::Assign.new("#{@name}_ptr",cons_call)
destruct = CPP::Destructor.new(init_class)
init_class.add_member(:public,destruct)
destruct.suite << if_stmt = CPP::If.new("0 == --#{counter}")
if_stmt.suite << "delete #{@name}_ptr"
if_stmt.suite << CPP::Assign.new("#{@name}_ptr","NULL")
init_class.static = true
init_class.dec = @name + "_initializer";
str = <<COMMENT_END
Create a reference to the new object in the pointer. Since we have already
created the initializer
COMMENT_END
str.split(/\n/).map{|str_sec| CPP::Comment.new(str_sec)}.each do |comment|
namespace.add(comment)
end
namespace.add("static UNUSED_VARIABLE #{type_name} &#{@name}" +
" = #{@name}_initializer.get()")
get = init_class.def_func(full_type_name,"get")
get.pre_func_types = "&"
get.suite << CPP::Return.new("*#{@name}_ptr")
end
end