brians | 343bc11 | 2013-02-10 01:53:46 +0000 | [diff] [blame^] | 1 | class 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 |
| 48 | Schwarz counter to construct and destruct the #{@name} queue. |
| 49 | Must be constructed before &#{@name} is constructed so that #{@name}_ptr |
| 50 | is valid so we can store a reference to the object. |
| 51 | COMMENT_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 |
| 84 | Create a reference to the new object in the pointer. Since we have already |
| 85 | created the initializer |
| 86 | COMMENT_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 |
| 103 | end |
| 104 | |