【问题标题】:for loop keeps gettging caught in an infinite loopfor循环不断陷入无限循环
【发布时间】:2015-05-09 03:14:55
【问题描述】:

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

但是,每当我尝试加载多个声音时,getALBuffer 方法中的 for 循环就会陷入无限循环。我认为我没有更改任何我复制/粘贴的代码。 i 类型为 Iterator 的调用 i.next() 似乎总是返回 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 陷入无限循环!

【问题讨论】:

  • 您是否尝试过在 for 循环中增加迭代器而不是 count 变量?
  • @fingaz 哦,呵呵!哇,这是 OpenAL 官方网站自己的教程上的错误!感谢您指出这一点!
  • 刚刚发布作为答案。可以的话点个赞吧!

标签: java infinite-loop openal


【解决方案1】:

这样增加迭代器:

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

【讨论】:

  • 你不是说 i.next() 吗?
  • 糟糕!那是我的 c++ 出来了。谢谢@AmirAfghani
【解决方案2】:

解决方案是,即使迭代器的元素数量随着添加的波形数据文件的增加而增加,for 循环永远不会增加到迭代器的不同元素。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多