2016-05-15 2 views
1

Я использую графическую библиотеку libsdl (привязка C SDL для Java), а также многоагентную библиотеку Jade.Класс libsdl потребляет все JVM (блокирует выполнение кода)

У меня есть агент, который создает класс GUI, созданный с помощью libsdl, и после создания код агента больше не выполняется. Фактически, единственное, что работает, - это GUI-класс.

Почему?

И кто-нибудь знает, как это исправить? Я хочу, чтобы графический интерфейс работал бок о бок с другими агентами моей программы, но, как только он загорается, он принимает все JVM для себя.

Вот соответствующие части моего кода (первый, агент):

package main; 

import java.util.HashMap; 
import java.util.Map; 

import jade.core.Agent; 
import jade.core.behaviours.TickerBehaviour; 
import sdljava.SDLException; 

public class Display extends Agent 
{ 
    private static final long serialVersionUID = 1L; 
    Map<String, Position> m_drones = new HashMap<String, Position>(); 
    GUI m_gui = null; 

    protected void setup() 
    { 
    for(int i = 0 ; i < Constants.numberDrones ; i++) 
    { 
     String name = "Drone" + Integer.toString(i); 
     Position position = getFreePosition(); 
     Object[] arguments = {i, position}; 

     try 
     { 
      this.getContainerController().createNewAgent(name, "main.Drone", arguments).start(); 
     } 
     catch(Exception exception) 
     { 
      System.out.println("Erreur : " + exception.getMessage()); 
      System.exit(-1);  
     } 

     m_drones.put(name, position); 
    } 

    try 
    { 
     m_gui = new GUI(m_drones); 
    } 
    catch (SDLException | InterruptedException e) 
    { 
     e.printStackTrace(); 
    } 

    addBehaviour(new RetrievePositions(this, Constants.retrievePositionsPeriod)); 
    addBehaviour(new UpdateGUI(this, Constants.updateGUIPeriod)); 
} 

Map<String, Position> getDrones() 
{ 
    return m_drones; 
} 

Position getFreePosition() 
{ 
    int x, y; 
    Position position = new Position(0, 0); 

    do 
    { 
     x = (int) Math.floor(Math.random() * Constants.environmentWidth) * Constants.dotSize; 
     y = (int) Math.floor(Math.random() * Constants.environmentHeight) * Constants.dotSize; 

     position.setPosition(x, y); 
    } 
    while(m_drones.containsValue(position)); 

    return position; 
    } 
} 

    class RetrievePositions extends TickerBehaviour 
    { 
     private static final long serialVersionUID = 1L; 

     Display display = (Display) this.myAgent; 
     Map<String, Position> drones = display.getDrones(); 

     public RetrievePositions(Agent agent, long period) 
     { 
      super(agent, period); 
     } 

    public void onTick() 
    { 
     System.out.println("retrievePositions"); 
    } 
} 

class UpdateGUI extends TickerBehaviour 
{ 
    private static final long serialVersionUID = 1L; 

    Display display = (Display) this.myAgent; 

    public UpdateGUI(Agent agent, long period) 
    { 
     super(agent, period); 
    } 

    protected void onTick() 
    { 
     System.out.println("updateGUI"); 
    } 
} 

и GUI:

package main; 

import java.util.HashMap; 
import java.util.Map; 

import sdljava.SDLException; 
import sdljava.SDLMain; 
import sdljava.event.SDLEvent; 
import sdljava.video.SDLRect; 
import sdljava.video.SDLSurface; 
import sdljava.video.SDLVideo; 

public class GUI 
{ 
    SDLSurface m_screen = null; 
    Map<String, SDLSurface> m_surfaces = new HashMap<String, SDLSurface>(); 
    boolean m_running = true; 

    void initSurfaces(Map<String, Position> drones) throws SDLException 
    { 
     for(Map.Entry<String, Position> entry : drones.entrySet()) 
     { 
      SDLSurface surface = SDLVideo.createRGBSurface(SDLVideo.SDL_HWSURFACE, Constants.dotSize, Constants.dotSize, 32, 0, 0, 0, 0); 
      SDLRect rect = new SDLRect(entry.getValue().getX(), entry.getValue().getY()); 
      surface.fillRect(surface.mapRGB(Constants.droneRed, Constants.droneGreen, Constants.droneBlue)); 
      surface.blitSurface(m_screen, rect); 
      m_surfaces.put(entry.getKey(), surface); 
     } 
    } 

    public GUI(Map<String, Position> drones) throws SDLException, InterruptedException 
    { 
     SDLMain.init(SDLMain.SDL_INIT_VIDEO); 
     m_screen = SDLVideo.setVideoMode(Constants.environmentWidth * Constants.dotSize, 
     Constants.environmentHeight * Constants.dotSize, 32, SDLVideo.SDL_DOUBLEBUF | SDLVideo.SDL_HWSURFACE); 
     SDLVideo.wmSetCaption("Flotte de drones en 2D", null); 

     initSurfaces(drones); 

     while(m_running) 
     { 
      SDLEvent event = SDLEvent.pollEvent(); 

      if(event instanceof SDLEvent) 
      { 
       switch (event.getType()) 
       { 
        case SDLEvent.SDL_QUIT:  
         m_running = false;  
        break; 
       } 
      } 

      m_screen.flip(); 
     } 

     freeSurfaces(); 
     SDLMain.quit(); 
    } 

    public void updateGUI(Map<String, Position> drones) throws SDLException 
    { 
     for(Map.Entry<String, Position> entry : drones.entrySet()) 
     { 
      SDLRect rect = new SDLRect(entry.getValue().getX(), entry.getValue().getY()); 
      m_surfaces.get(entry.getKey()).updateRect(rect); 
      m_surfaces.get(entry.getKey()).blitSurface(m_screen, rect); 
     } 
    } 

    void freeSurfaces() throws SDLException 
    { 
     for(Map.Entry<String, SDLSurface> entry : m_surfaces.entrySet()) 
     { 
      m_surfaces.get(entry.getKey()).freeSurface(); 
     } 

     m_screen.freeSurface(); 
    } 
} 
+0

Я думаю, что нашел ответ. Для тех, кто заинтересован: каждый агент в Jade работает в своей собственной нити. Чтобы позволить Display (агенту, создавшему GUI) продолжить его выполнение, я должен отделить GUI от него. То, как я это делаю, - это сделать GUI агентом. Поэтому с момента создания GUI, вызвав его конструктор, он запускает новый поток и позволяет Display продолжать работу после этой инструкции. Итак, ответ: сделайте GUI агентом. 'public class GUI extends Агент { ... }' –

ответ

0

Я думаю, я нашел ответ. Для тех, кто заинтересован: каждый агент в Jade работает в своей собственной нити. Чтобы позволить Display (агенту, создавшему GUI) продолжить его выполнение, я должен отделить GUI от него. То, как я это делаю, - это сделать GUI агентом. Поэтому с момента создания GUI, вызвав его конструктор, он запускает новый поток и позволяет Display продолжать работу после этой инструкции.

Итак, ответ: сделайте GUI агентом.

public class GUI extends Agent 
{ 
    ... 
}