0

JRubyのArtemis エンティティ システム フレームワークを使用しようとしています。JRuby に変換しようとしている Java コードは次のとおりです。

import com.artemis.Aspect;
import com.artemis.Component;
import com.artemis.Entity;
import com.artemis.World;
import com.artemis.systems.EntityProcessingSystem;

public class MyGame {

    private World world;

    public MyGame() {
        world = new World();

        Entity e = world.createEntity();
        e.addComponent(new Position());
        e.addToWorld();

        world.setSystem(new ConsoleOutputSystem());
        world.initialize();
        for(int i = 0; i < 10; i++) {
            world.setDelta(60);
            world.process();
        }
    }

    public static void main(String[] args) {
        new MyGame();
    }
}

class Position extends Component {

    public int x;
    public int y;

    public Position() {
        this.x = 0;
        this.y = 0;
    }
}

class ConsoleOutputSystem extends EntityProcessingSystem {

    public ConsoleOutputSystem() {
        super(Aspect.getAspectForAll(Position.class));
        System.out.println("In system constructor");
    }

    @Override
    protected void process(Entity entity) {
        System.out.println("processing");
        System.out.println(entity.getUuid());
    }

}

これを実行すると、出力は次のようになります。

In system constructor
processing
9e8a24a8-b778-4926-b305-5a426a2f0ce1
processing
...

ConsoleOutputSystem.process() メソッドは 10 回呼び出されます。ここに私のJRubyコードがあります:

require 'artemis.jar'

java_import com.artemis.Entity
java_import com.artemis.World
java_import com.artemis.Component
java_import com.artemis.Aspect
java_import com.artemis.systems.EntityProcessingSystem

class MyGame 

  attr_reader :world

  def initialize

    @world = World.new()
    e = @world.create_entity()
    e.add_component(Position.new())
    e.add_to_world()
    @world.set_system(ConsoleOutputSystem.new())
    #@world.initialize
    @world.java_send :initialize
    10.times do
      @world.set_delta(60)
      @world.process()
    end
  end

end

class Position < Component

    attr_accessor :x, :y

    def initialize ()
        @x = 0
        @y = 0
    end

end

class ConsoleOutputSystem < EntityProcessingSystem

    def initialize()
      puts 'in system constructor'
      super(Aspect.get_aspect_for_all(Position))
    end

    java_signature 'protected void process(Entity)'
    def process(entity)
      puts 'process'
      puts entity.getUuid
    end

end


MyGame.new()

出力は次のとおりです。

in system constructor

したがって、ConsoleOutputSystem コンストラクターは呼び出されますが、ConsoleOutputSystem.process() は呼び出されません。@world.initialize と @world.java_send :initialize の両方を使用しようとしましたが、出力は同じです。私が試したもう 1 つのことは、java_signature 'protected void process(Entity)' を ConsoleOutputSystem.process() メソッドに追加することです。

Artemis パッケージの他のいくつかのクラスには、initialize() という名前の保護メソッドがありますが、それが私の問題に関連しているかどうかはわかりません。

[編集]

質問を投稿してから、私はいくつかの進歩を遂げました。@world.java_send :initialize が機能し、正しいメソッドが呼び出されます。うまくいかないのは Aspect.get_aspect_for_all() です。Java Aspect.getAspectForAll() では、

Class<? extends Component> , Class<? extends Component>[]

引数として。JRuby では、これらのどちらも Aspect.getAspectForAll() の引数として機能しません。

Position
Position.class
Position.java_class
Position.java_proxy_class

機能する唯一の方法は、最初に Position インスタンスを作成し、そのクラスを Aspect.getAspectForAll() に渡すことでした。

@position_class = Position.new().getClass()

動作するコードは次のとおりですが、おかしな感じがします。

require 'artemis.jar'

java_import com.artemis.Entity
java_import com.artemis.World
java_import com.artemis.Component
java_import com.artemis.ComponentType
java_import com.artemis.ComponentMapper
java_import com.artemis.Aspect
java_import com.artemis.systems.EntityProcessingSystem

class MyGame 

  attr_reader :world

  def initialize

    @world = World.new()

    e = @world.create_entity()
    e.add_component(Position.new())
    e.add_component(Velocity.new())
    e.add_to_world()

    @world.set_system(ConsoleOutputSystem.new(@world))
    @world.java_send :initialize


    5.times do
      @world.set_delta(60)
      @world.process
    end

  end

end

class Position < Component

    attr_accessor :x, :y

    def initialize ()
        @x = rand(100)
        @y = rand(100)
    end

end

class Velocity < Component

  attr_accessor :v

  def initialize()
    @v = 1.43
  end

end

class ConsoleOutputSystem < EntityProcessingSystem

  attr_accessor :position_class, :velocity_class

    def initialize(world)

      @position_class = Position.new().getClass()
      @velocity_class = Velocity.new().getClass()

      puts "@position_class: #{@position_class}"
      puts "Position: #{Position}"
      puts "Position.class: #{Position.class}"
      puts "Position.java_class: #{Position.java_class}"
      puts "Position.java_proxy_class: #{Position.java_proxy_class}"

      super(Aspect.get_aspect_for_all(@position_class, @velocity_class))

    end

    def process(entity)

      puts 'process'
      puts entity.getUuid

      position = entity.get_component(@position_class)
      velocity = entity.get_component(@velocity_class)

      position.x += 1
      position.y += 1
      velocity.v += 1

      puts position.x
      puts position.y
      puts velocity.v
      puts '----------'

    end

end

game = MyGame.new()

の出力

puts "@position_class: #{@position_class}"
puts "Position: #{Position}"
puts "Position.class: #{Position.class}"
puts "Position.java_class: #{Position.java_class}"
puts "Position.java_proxy_class: #{Position.java_proxy_class}"

は:

@position_class: org.jruby.proxy.com.artemis.Component$Proxy0
Position: Position
Position.class: Class
Position.java_class: com.artemis.Component
Position.java_proxy_class: org.jruby.javasupport.proxy.JavaProxyClass

では、私の問題は、Position クラスのインスタンスを作成せずに org.jruby.proxy.com.artemis.Component$Proxy0 にアクセスする方法ですか?

[編集2]

Namek's answer のおかげで、動作するコードがここにあります。それは使用しています

@position_class = Position.java_proxy_class.java_class
@velocity_class = Velocity.java_proxy_class.java_class

そのため、JRuby クラスのインスタンスを作成してその Java クラスにアクセスする必要はありません。

require 'artemis.jar'

java_import com.artemis.Entity
java_import com.artemis.World
java_import com.artemis.Component
java_import com.artemis.ComponentType
java_import com.artemis.ComponentMapper
java_import com.artemis.Aspect
java_import com.artemis.systems.EntityProcessingSystem


class MyGame 

  attr_reader :world

  def initialize

    @world = World.new()

    e = @world.create_entity()
    e.add_component(Position.new())
    e.add_component(Velocity.new())
    e.add_to_world()

    @world.set_system(ConsoleOutputSystem.new(@world))
    @world.java_send :initialize


    5.times do
      @world.set_delta(60)
      @world.process
    end

  end

end


class Position < Component

    attr_accessor :x, :y

    def initialize ()
        @x = rand(100)
        @y = rand(100)
    end

end


class Velocity < Component

  attr_accessor :v

  def initialize()
    @v = 1.43
  end

end


class ConsoleOutputSystem < EntityProcessingSystem

  attr_accessor :position_class, :velocity_class

    def initialize(world)

      @position_class = Position.java_proxy_class.java_class
      @velocity_class = Velocity.java_proxy_class.java_class

      super(Aspect.get_aspect_for_all(@position_class, @velocity_class))

    end

    def process(entity)

      puts 'process'
      puts entity.getUuid

      position = entity.get_component(@position_class)
      velocity = entity.get_component(@velocity_class)

      position.x += 1
      position.y += 1
      velocity.v += 1

      puts position.x
      puts position.y
      puts velocity.v
      puts '----------'

    end

end


game = MyGame.new()
4

1 に答える 1

1

あなたの現在の問題はここで議論されているようです: http://jira.codehaus.org/browse/JRUBY-672

次のように Java クラスを取得してみてください。

Position.java_proxy_class.java_class

于 2014-08-31T13:54:20.717 に答える