for循环使gettging陷入无限循环

时间:2015-05-09 03:14:56

标签: java infinite-loop openal

我从本教程中复制/粘贴了OpenAL声音加载器的代码:http://wiki.lwjgl.org/wiki/OpenAL_Tutorial_6_-_Advanced_Loading_and_Error_Handles

但是,每当我尝试加载多个声音时,getALBuffer方法中的for循环就会陷入无限循环。我不认为我改变了我复制/粘贴的任何代码。调用i.next(),其中我是类型Iterator似乎总是返回true,但我不知道为什么。我会发布我的所有复制/粘贴代码,以防我在没有意识到的情况下意外更改某些内容。代码从loadALData()调用开始。

public static String getALErrorString(int err) {
      switch (err) {
        case AL_NO_ERROR:
            return "AL_NO_ERROR";
        case AL_INVALID_NAME:
            return "AL_INVALID_NAME";
        case AL_INVALID_ENUM:
            return "AL_INVALID_ENUM";
        case AL_INVALID_VALUE:
            return "AL_INVALID_VALUE";
        case AL_INVALID_OPERATION:
            return "AL_INVALID_OPERATION";
        case AL_OUT_OF_MEMORY:
            return "AL_OUT_OF_MEMORY";
        default:
            return "No such error code";
      }
}

public static String getALCErrorString(int err) {
    switch (err) {
    case ALC_NO_ERROR:
        return "AL_NO_ERROR";
    case ALC_INVALID_DEVICE:
        return "ALC_INVALID_DEVICE";
    case ALC_INVALID_CONTEXT:
        return "ALC_INVALID_CONTEXT";
    case ALC_INVALID_ENUM:
        return "ALC_INVALID_ENUM";
    case ALC_INVALID_VALUE:
        return "ALC_INVALID_VALUE";
    case ALC_OUT_OF_MEMORY:
        return "ALC_OUT_OF_MEMORY";
    default:
        return "no such error code";
    }
}

public static int loadALBuffer(String path){

    int result;
    IntBuffer buffer = BufferUtils.createIntBuffer(1);

    // Load wav data into a buffers.
    alGenBuffers(buffer);

    if ((result = alGetError()) != AL_NO_ERROR){
        throw new OpenALException(getALErrorString(result));
    }

    WaveData waveFile = LoadSound(path);

    if (waveFile != null){
        alBufferData(buffer.get(0), waveFile.format, waveFile.data, waveFile.samplerate);
        waveFile.dispose();
    }else{
        throw new RuntimeException("No such file: " + path);
    }

    // Do another error check and return.
    if ((result = alGetError()) != AL_NO_ERROR) {
        throw new OpenALException(getALErrorString(result));
    }

    return buffer.get(0);
}

/**
 * 1) Checks if file has already been loaded.
 * 2) If it has been loaded already, return the buffer id.
 * 3) If it has not been loaded, load it and return buffer id.
 */
@SuppressWarnings({ "unchecked", "rawtypes" })
public static int getLoadedALBuffer(String path) {
    int count = 0;
    for (Iterator i = loadedFiles.iterator(); i.hasNext(); count++) {
        if (i.equals(path)) {
            return ((Integer) buffers.get(count)).intValue();
        }
        //I added this if statement to catch the infinite loop
        if (count>=100000){
            System.out.println("getLoadedALBuffer was caught in an infinite loop!");
            return -1;
        }
    }

    int buffer = loadALBuffer(path);

    buffers.add(new Integer(buffer));
    loadedFiles.add(path);

    return buffer;
}

/**
 * 1) Creates a source.
 * 2) Calls 'GetLoadedALBuffer' with 'path' and uses the returned buffer id as it's sources buffer.
 * 3) Returns the source id.
 */
@SuppressWarnings("unchecked")
public static int loadALSample(String path, boolean loop) {
    IntBuffer source = BufferUtils.createIntBuffer(1);
    int buffer;
    int result;

    // Get the files buffer id (load it if necessary).
    buffer = getLoadedALBuffer(path);

    //I added this to handle infinite loop error
    if (buffer == -1){
        return -1;
    }

    // Generate a source.
    alGenSources(source);

    if ((result = alGetError()) != AL_NO_ERROR)
        throw new OpenALException(getALErrorString(result));

    // Setup the source properties.
    alSourcei(source.get(0), AL_BUFFER, buffer);
    alSourcef(source.get(0), AL_PITCH, 1.0f);
    alSourcef(source.get(0), AL_GAIN, 1.0f);
    //alSource(source.get(0), AL_POSITION, sourcePos);
    //alSource(source.get(0), AL_VELOCITY, sourceVel);
    alSourcei(source.get(0), AL_LOOPING, (loop ? AL_TRUE : AL_FALSE));

    // Save the source id.
    sources.add(new Integer(source.get(0)));

    // Return the source id.
    return source.get(0);
}

//I created this method
public static int LoadWaveFile(String name, int location, boolean loop){
    return loadALSample(getWaveFilePath(name,location), loop);
}

/**
 * 1) Releases temporary loading phase data.
 */
public static void killALLoadedData() {
    loadedFiles.clear();
}

// Source id's.
public static int busterShot;
public static int lifeGain;

public static void loadALData() {
    // Anything for your application here. No worrying about buffers.
    busterShot = LoadWaveFile("MM_Shoot", SFX_FOLDER, false);
    lifeGain = LoadWaveFile("MM_1up", SFX_FOLDER, false);

    killALLoadedData();
}

//I created these integers
public static final int MUSIC_FOLDER = 0;
public static final int SFX_FOLDER = 1;
//I created this method
public static WaveData LoadSound(String path){
    System.out.println("\nLoadSound() called!");
    WaveData sound = null;
    try {
        sound = WaveData.create(new BufferedInputStream(new FileInputStream(path)));
        System.out.println(path+((sound!=null) ? " exists!" : " does not exist!"));
    } catch (Exception e) {
        e.printStackTrace();
    }

    return sound;
}
//I created this method
public static WaveData QuickLoad(String name, int location){
    WaveData sound = LoadSound(getWaveFilePath(name, location));
    return sound;
}
//I created this Method
public static String getWaveFilePath(String name, int location){
    if (location == MUSIC_FOLDER){
        return "res/sounds/music/"+name+".wav";
    }else if(location == SFX_FOLDER){
        return "res/sounds/soundEffects/"+name+".wav";
    }

    return null;
}

编辑:当我运行此代码时,这是我的控制台输出:

LoadSound()调用!

res / sounds / soundEffects / MM_Shoot.wav存在!

getLoadedALBuffer陷入无限循环!

2 个答案:

答案 0 :(得分:2)

增加迭代器:

for(Iterator i = ... ; i.hasNext(); i.next())

答案 1 :(得分:0)

解决方案是,即使Iterator的元素数量随着添加的wave数据文件的增加而增加,for循环也不会增加到Iterator的不同元素。

这是官方lwjgl网站自带教程的编程问题!我没想到,因此我的困惑。老实说虽然我应该早点看到这个错误。我很抱歉这个愚蠢的问题!