2014-06-14 7 views
0

JRuby에서 Artemis entity system framework을 사용하려고합니다. 여기에 내가 JRuby를 변환하려고 자바 코드이다 : 나는 실행하면JRuby에서 Artemis ESF 사용

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() 메소드가 열 번 호출됩니다.

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() 

출력은 다음과 같습니다 : 여기 내 JRuby를 코드

in system constructor 

그래서 ConsoleOutputSystem 생성자가 호출되는하지만 ConsoleOutputSystem.process(). @ world.initialize와 @ world.java_send를 모두 사용하려고 시도했다 : 초기화하고 출력은 동일하다. 내가 시도한 또 다른 것은 java_signature 'protected void process (Entity)'를 ConsoleOutputSystem.process() 메소드에 추가하는 것이다.

Artemis 패키지의 다른 여러 클래스에는 initialize()라는 보호 된 메서드가 있지만 내 문제와 관련이 있는지 확실하지 않습니다. 내가 질문을 게시 이후

[편집]

나는 약간의 진전을했습니다. @ world.java_send : 초기화 작업을하고 올바른 메소드가 호출됩니다. 작동하지 않는 것은 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 

있는 유일한 방법은 선행 [위치 인스턴스를 생성하고 Aspect.getAspectForAll()에 해당 클래스를 통과했다 :

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

는 작동 코드입니다 그러나 그것은 kludge llike 느낌 :

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 

, 내 문제는 위치 클래스의 인스턴스를 생성하지 않고 org.jruby.proxy.com.artemis.Component $ Proxy0에 도착하는 방법은?

는 [수정 2]

Namek의 대답 덕분에 여기에서 작동하는 코드입니다.

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

그래서 난 자바 클래스로 얻을 수있는 JRuby를 클래스의 인스턴스를 만들 필요가 없습니다 사용하여 현재 문제가 여기에 설명처럼

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() 
+0

일부 쓸모없는 매개 변수가 있도록 시스템의 생성자를 정의하려고 할 수 있습니다. 그런 식으로 생성자를 initialize() 메서드와 혼동해서는 안됩니다. – Namek

+0

@Nemek 의견에 감사드립니다. 나는 이것이 더 이상 메소드 이름 충돌이라고 생각하지 않는다. 나는 더 많은 정보를 가지고 질문을 편집 할 것이다. –

+0

흥미 롭습니다. 앞으로 봐 : – Namek

답변

1

이 보인다 : http://jira.codehaus.org/browse/JRUBY-672

이 같은 자바 클래스를 얻으려고 :

Position.java_proxy_class.java_class

+0

고마워, 작동! 오프닝 포스트를 현재 코드로 업데이트하겠습니다. –

+0

좋습니다! ... 특히 JRuby를 사용한 적이 없기 때문에. – Namek