libsdl class 消耗所有 JVM(阻止代码执行)

libsdl class consumes all JVM (blocks the execution of code)

我使用图形库 libsdl(C SDL 与 Java 的绑定)以及多代理库 Jade。

我有一个创建 GUI class 的代理,该 GUI class 使用 libsdl 创建,创建后,不再执行代理的代码。事实上,唯一 运行ning 是 GUI class.

为什么?

有人知道如何解决吗?我希望 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();
    }
}

我想我找到了答案。对于那些感兴趣的人:Jade 中的每个代理都在自己的线程中运行。因此,为了让 Display(创建 GUI 的代理)继续执行,我必须将 GUI 从他身上分离出来。我这样做的方法是让 GUI 也成为代理。因此,从我通过调用其构造函数创建 GUI 的那一刻起,它会启动一个新线程并允许 Display 在该指令之后保持 运行。

所以答案是:使 GUI 成为代理。

public class GUI extends Agent
{
    ...
}