blob: db4e1afe8615ad6b1dbaa641073e176e66e76873 [file] [log] [blame]
brians343bc112013-02-10 01:53:46 +00001class Target::QueueDec < Target::Node
2 attr_accessor :name,:loc
3 def initialize(type,name)
4 @type,@name = type,name
5 end
6 def msg_hash()
7 return @type.msg_hash
8 end
brians343bc112013-02-10 01:53:46 +00009 def full_message_name(cpp_tree)
10 type = cpp_tree.get(@type)
11 return @type.loc.to_cpp_id(type.name)
12 end
13 def full_ptr_name(cpp_tree)
14 return "::aos::SafeScopedMessagePtr< #{full_message_name(cpp_tree)}>"
15 end
16 def full_builder_name(cpp_tree)
17 return "::aos::MessageBuilder< #{full_message_name(cpp_tree)}>"
18 end
19 def full_type_name(cpp_tree)
20 return "::aos::Queue< #{full_message_name(cpp_tree)}>"
21 end
22 def type_name(cpp_tree,queue_type = "::aos::Queue")
23 type = cpp_tree.get(@type)
24 if(@type.loc == @loc) #use relative name
25 return "#{queue_type}<#{type.name}>"
26 else #use full name
27 return "#{queue_type}< #{@type.loc.to_cpp_id(type.name)}>"
28 end
29 end
30 def create_usage(cpp_tree)
31 "#{type_name(cpp_tree)} #{@name}"
32 end
33 def create(cpp_tree)
34 namespace = cpp_tree.get(@loc)
35 type = cpp_tree.get(@type)
36 cpp_tree.set(self,self)
37 type_name = type_name(cpp_tree)
38 full_type_name = full_type_name(cpp_tree)
39 namespace.add_cc("static #{type_name} *#{@name}_ptr")
40 counter = "#{@name}_counter"
41 namespace.add_cc("static int #{counter}")
42
43 str = <<COMMENT_END
44Schwarz counter to construct and destruct the #{@name} queue.
45Must be constructed before &#{@name} is constructed so that #{@name}_ptr
46is valid so we can store a reference to the object.
47COMMENT_END
48 str.split(/\n/).each do |str_sec|
49 namespace.class_comment(str_sec)
50 end
51 init_class = namespace.add_class("InitializerFor_" + @name)
52
53 init_class.add_cc_comment(
54 "The counter is initialized at load-time, i.e., before any of the static",
55 "objects are initialized.")
56
57
58 cons = CPP::Constructor.new(init_class)
59 init_class.add_member(:public,cons)
60 cons.suite << if_stmt = CPP::If.new("0 == #{counter}++")
brians343bc112013-02-10 01:53:46 +000061
62 cons_call = CPP::FuncCall.new("new #{type_name}")
63 cons_call.args.push(@loc.queue_name(@name).inspect)
64 if_stmt.suite << CPP::Assign.new("#{@name}_ptr",cons_call)
brians343bc112013-02-10 01:53:46 +000065
66
67 destruct = CPP::Destructor.new(init_class)
68 init_class.add_member(:public,destruct)
69 destruct.suite << if_stmt = CPP::If.new("0 == --#{counter}")
brians343bc112013-02-10 01:53:46 +000070 if_stmt.suite << "delete #{@name}_ptr"
71 if_stmt.suite << CPP::Assign.new("#{@name}_ptr","NULL")
72
73 init_class.static = true
74 init_class.dec = @name + "_initializer";
75
76 str = <<COMMENT_END
77Create a reference to the new object in the pointer. Since we have already
78created the initializer
79COMMENT_END
Brian Silverman04fdc232014-02-12 14:51:11 -080080 str.split(/\n/).map{|str_sec| CPP::Comment.new(str_sec)}.each do |comment|
81 namespace.add(comment)
82 end
83 namespace.add("static UNUSED_VARIABLE #{type_name} &#{@name}" +
84 " = #{@name}_initializer.get()")
brians343bc112013-02-10 01:53:46 +000085
86 get = init_class.def_func(full_type_name,"get")
87 get.pre_func_types = "&"
88 get.suite << CPP::Return.new("*#{@name}_ptr")
89
90 end
91end
92