blob: 8c3bd51469873a63421b6b46ab4019cff0972c79 [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
9 def java_type_name(cpp_tree)
10 type = cpp_tree.get(@type)
11 return "#{type.name}Queue"
12 end
13 def full_message_name(cpp_tree)
14 type = cpp_tree.get(@type)
15 return @type.loc.to_cpp_id(type.name)
16 end
17 def full_ptr_name(cpp_tree)
18 return "::aos::SafeScopedMessagePtr< #{full_message_name(cpp_tree)}>"
19 end
20 def full_builder_name(cpp_tree)
21 return "::aos::MessageBuilder< #{full_message_name(cpp_tree)}>"
22 end
23 def full_type_name(cpp_tree)
24 return "::aos::Queue< #{full_message_name(cpp_tree)}>"
25 end
26 def type_name(cpp_tree,queue_type = "::aos::Queue")
27 type = cpp_tree.get(@type)
28 if(@type.loc == @loc) #use relative name
29 return "#{queue_type}<#{type.name}>"
30 else #use full name
31 return "#{queue_type}< #{@type.loc.to_cpp_id(type.name)}>"
32 end
33 end
34 def create_usage(cpp_tree)
35 "#{type_name(cpp_tree)} #{@name}"
36 end
37 def create(cpp_tree)
38 namespace = cpp_tree.get(@loc)
39 type = cpp_tree.get(@type)
40 cpp_tree.set(self,self)
41 type_name = type_name(cpp_tree)
42 full_type_name = full_type_name(cpp_tree)
43 namespace.add_cc("static #{type_name} *#{@name}_ptr")
44 counter = "#{@name}_counter"
45 namespace.add_cc("static int #{counter}")
46
47 str = <<COMMENT_END
48Schwarz counter to construct and destruct the #{@name} queue.
49Must be constructed before &#{@name} is constructed so that #{@name}_ptr
50is valid so we can store a reference to the object.
51COMMENT_END
52 str.split(/\n/).each do |str_sec|
53 namespace.class_comment(str_sec)
54 end
55 init_class = namespace.add_class("InitializerFor_" + @name)
56
57 init_class.add_cc_comment(
58 "The counter is initialized at load-time, i.e., before any of the static",
59 "objects are initialized.")
60
61
62 cons = CPP::Constructor.new(init_class)
63 init_class.add_member(:public,cons)
64 cons.suite << if_stmt = CPP::If.new("0 == #{counter}++")
65 if_stmt.suite << "printf(#{"making a #{@name} queue!\n".inspect})"
66
67 cons_call = CPP::FuncCall.new("new #{type_name}")
68 cons_call.args.push(@loc.queue_name(@name).inspect)
69 if_stmt.suite << CPP::Assign.new("#{@name}_ptr",cons_call)
70 if_stmt.else_suite << CPP::FuncCall.build("printf","already made a #{@name}\n".inspect)
71
72
73 destruct = CPP::Destructor.new(init_class)
74 init_class.add_member(:public,destruct)
75 destruct.suite << if_stmt = CPP::If.new("0 == --#{counter}")
76 if_stmt.suite << "printf(#{"deleting a #{@name}!! :) !!\n".inspect})"
77 if_stmt.suite << "delete #{@name}_ptr"
78 if_stmt.suite << CPP::Assign.new("#{@name}_ptr","NULL")
79
80 init_class.static = true
81 init_class.dec = @name + "_initializer";
82
83 str = <<COMMENT_END
84Create a reference to the new object in the pointer. Since we have already
85created the initializer
86COMMENT_END
87 comments = str.split(/\n/).map{|str_sec| CPP::Comment.new(str_sec)}
88 comments << "static UNUSED_VARIABLE #{type_name} &#{@name} = " +
89 "#{@name}_initializer.get()"
90 namespace.add_post_swig("%immutable #{@name}_initializer")
91 java_type_name = java_type_name(cpp_tree)
92 namespace.add_post_swig(CPP::SwigPragma.new("java", "modulecode", CPP::Suite.new(["public static final #{java_type_name} #{@name} = get#{@name.capitalize}_initializer().get()"])))
93
94 ifdef_statement = CPP::IfnDef.new(CPP::Suite.new(comments))
95 ifdef_statement.name = "SWIG"
96 namespace.add(ifdef_statement)
97
98 get = init_class.def_func(full_type_name,"get")
99 get.pre_func_types = "&"
100 get.suite << CPP::Return.new("*#{@name}_ptr")
101
102 end
103end
104