lib/game_machine/protobuf/generate.rb in game_machine-0.0.11 vs lib/game_machine/protobuf/generate.rb in game_machine-1.0.2

- old
+ new

@@ -1,9 +1,10 @@ require 'java' require 'pathname' require 'erb' require 'fileutils' +require 'active_support/inflector' java_import java.lang.System java_import com.dyuproject.protostuff.compiler.CachingProtoLoader java_import java.io.FileNotFoundException java_import com.dyuproject.protostuff.parser.ProtoUtil @@ -15,44 +16,139 @@ attr_reader :app_root def initialize(app_root) @app_root = app_root end + def java_root + ENV['JAVA_ROOT'] + end + def self.compile(path) loader = CachingProtoLoader.new file = java.io.File.new(path) ProtoUtil.parseProto(file) end def erb_template - File.join(app_root,'java','component.erb') + File.join(java_root,'component.erb') end + def model_template + File.join(java_root,'model.erb') + end + + def model_src + File.join(java_root,'src','main','java','com', 'game_machine','orm','models') + end + def java_src - File.join(app_root,'java','src','main','java','GameMachine', 'Messages') + File.join(java_root,'src','main','java','GameMachine', 'Messages') end def config_path File.join(app_root,'config') end - def write_components(proto) + def write_components(proto,persistent_messages) messages = proto.getMessages.reject {|message| message.getName == 'Components'} FileUtils.mkdir_p(java_src) + FileUtils.mkdir_p(model_src) + message_names = proto.getMessages.map {|m| m.get_name} + messages_index = proto.getMessages.each_with_object({}) {|v,res| res[v.getName] = v} + proto.getMessages.each do |message| + message_fields = [] + message.get_fields.each do |field| + if message_names.include?(field.getJavaType.to_s) && !field.is_repeated + message_fields << field.get_java_type.to_s + end + end + unless message_fields.empty? + #puts "#{message.getName} #{message_fields.inspect}" + end + klass = message.getName + persistent = persistent_messages.include?(klass) #puts "Message: #{message.getName}" - out = ERB.new(File.read(erb_template),nil,'-').result(binding) + out = ERB.new(File.read(erb_template),0,'>').result(binding) + out = out.gsub(/^(\s*\r\n){2,}/,"\r\n") src_file = File.join(java_src,"#{message.getName}.java") File.open(src_file,'w') {|f| f.write out} + + if persistent + out = ERB.new(File.read(model_template),0,'<>').result(binding) + out = out.gsub(/^(\s*\r\n){2,}/,"\r\n") + out = out.gsub(/^(\s*\n){2,}/,"\n") + src_file = File.join(model_src,"#{message.getName}.java") + File.open(src_file,'w') {|f| f.write out} + end #message.getFields.each do |field| + # puts field.default_value_set # puts field.getJavaType # puts field.toString #end end end + def sql_column_name(klass,field) + "#{klass.underscore}_#{field.name.underscore}" + end + + def sql_field(klass,field,dbtype,force_null=false) + if dbtype == 'mysql' + txt = case field.getJavaType.to_s + when 'boolean' + "`#{sql_column_name(klass,field)}` tinyint(4)" + when 'double' + "`#{sql_column_name(klass,field)}` double" + when 'float' + "`#{sql_column_name(klass,field)}` float" + when 'long' + "`#{sql_column_name(klass,field)}` int(11)" + when 'int' + "`#{sql_column_name(klass,field)}` int(11)" + when 'String' + "`#{sql_column_name(klass,field)}` varchar(128)" + end + elsif dbtype == 'postgres' + txt = case field.getJavaType.to_s + when 'boolean' + "#{sql_column_name(klass,field)} integer" + when 'double' + "#{sql_column_name(klass,field)} double precision" + when 'float' + "#{sql_column_name(klass,field)} double precision" + when 'long' + "#{sql_column_name(klass,field)} integer" + when 'int' + "#{sql_column_name(klass,field)} integer" + when 'String' + "#{sql_column_name(klass,field)} character varying(128)" + end + end + + return nil if txt.nil? + + if force_null + return "#{txt} DEFAULT NULL," + end + + if field.is_required + txt = "#{txt} NOT NULL," + else + txt = "#{txt} DEFAULT NULL," + end + end + + def simple_value?(field) + if ['boolean','double','float','long','int','String'].include?(field.getJavaType.to_s) + true + else + false + end + end + def get_type(field) if field.getJavaType.to_s == 'int' return 'Integer' elsif ['boolean','double','float','long'].include?(field.getJavaType.to_s) return field.getJavaType.to_s.clone.capitalize @@ -68,21 +164,27 @@ def classname(name) name.slice(0,1).capitalize + name.slice(1..-1) end def generate + FileUtils.rm Dir.glob(File.join(java_src,'*.java')) game_protofile = File.join(config_path,'game_messages.proto') protofile = File.join(config_path,'messages.proto') if File.exists?(game_protofile) game_messages = File.read(game_protofile) + game_messages = game_messages.gsub('local_persistent_message','message') + game_messages = game_messages.gsub('local_message','message') + game_messages = game_messages.gsub('persistent_message','message') gm = Protobuf::GameMessages.new(game_protofile) + persistent_messages = gm.persistent_messages entity_fields = gm.create_entity_fields game_entity_fields = entity_fields.join("\n") else game_messages = '' game_entity_fields = '' + persistent_messages = [] end messages = File.read(protofile) combined_messages = messages.sub('//GAME_MESSAGES',game_messages) combined_messages = combined_messages.sub('//GAME_ENTITY_MESSAGES',game_entity_fields) @@ -100,10 +202,10 @@ # This just stops generating code when it hits an error, but does not # throw an exception proto = self.class.compile(combined_messages_protofile) - write_components(proto) + write_components(proto,persistent_messages) #FileUtils.rm(combined_messages_protofile) combined_messages end end end