2

私は iPad 用の小さなプロジェクトに取り組んでおり、特定の関数呼び出しの後に停止するスクリプトを実行し、後で同じ場所からスクリプトを再開できるようにしたいだけです。実際、キューで一度に 1 つずつ「スレッド」を実行するだけなので、実際には iPhone OS と Lua の間のマルチタスクのみです。

static int yield__ (lua_State *L) {
//NSLog(@"Do Yield");
return lua_yield(L, 0);
}

//This function adds a script to my queue
- (void) doFileThreaded:(NSString*)filename {

NSString* path = [[NSBundle mainBundle] pathForResource:filename ofType:nil];
const char* file = [path UTF8String];

lua_State* newThread = lua_newthread(luaState);

//Load the file for execution
if ( luaL_loadfile(newThread,file) != 0 ) {
    return;
}   
//Add file to the queue
[threads addObject:[NSValue valueWithPointer:newThread]];
}

//This Function Executes the queued threads one at a time removing them when they've finished
- (void) doThreads {

lua_State* thread = NULL;

while ( threads.count > 0 ) {

    thread = (lua_State*)[[threads objectAtIndex:0] pointerValue];

    //Resume will run a thread until it yeilds execution
    switch ( lua_resume(thread, 0) ) {
        case LUA_YIELD:
            //NSLog(@"Recieved Yield");
            return;

        case 0:
            NSLog(@"Removing Thread");
            [threads removeObjectAtIndex:0];
            thread = NULL;
            break;
        default:
            NSLog(@"Error Executing Threaded Script!");
            [threads removeObjectAtIndex:0];
            break;

    }

}

}

Luaコードの場合:

function wait (seconds)

  time = os.time() + seconds;
  print("Waiting " .. os.time() .. " to " .. time);
  while ( time > os.time() ) do
    yield(); --I have written my own yield function
  end

end

print("Entered Toad Behavior");

yield();

print("Point 1");

yield();

print("point 3");

wait(1);

print("point 4");

wait(2);

print("point 5");

このコードは、lua で待機する 2 番目の呼び出しでクラッシュします。BAD_MEMORY_ACCESS または lua_resume を使用すると、実行時エラーが返されることがあります。(エラーが何であるかを確認する方法がわからないので、それを手伝っていただければ幸いです)ここで私が間違っていることを誰か教えてもらえますか?

4

1 に答える 1

3

わかりました、100% 理解できませんが、別の実行中の lua スクリプトから doFileThreaded を呼び出していたことに関係があると思います。lua_State は異なっていても、Lua によって既に呼び出されていた関数から luaL_loadfile を呼び出したという事実は、これが何らかの形で「メタメソッド/C 呼び出しの境界を越えて譲歩しようとする試み」を引き起こしているように思われます。

私の解決策は、実行したいファイルの名前を文字列として配列に保存し、doThread で lua_newthread を呼び出すことでした。

- (void) doFileThreaded:(NSString*)filename {

NSString* path = [[NSBundle mainBundle] pathForResource:filename ofType:nil];

//Add to queue
[threads addObject:path];
}

- (void) doThreads {

//Will run through the threads in the order they've been queued.
//Cooperative Multitasking

while ( threads.count > 0 ) {

    //If there is no thread start one
    if ( threadState == NULL ) {

        threadState = lua_newthread(luaState);

        const char* file = [[threads objectAtIndex:0] UTF8String];

        if ( luaL_loadfile(threadState,file) != 0 ) {
            NSLog(@"%s\n", lua_tostring(threadState,-1));
            [threads removeObjectAtIndex:0];
            threadState = NULL;
            return;
        }

        //Return because we don't want to resume the file right away
        //return;

    }

    //Resume will run a thread until it yeilds execution
    switch ( lua_resume(threadState, 0) ) {
        case LUA_YIELD:
            return;

        case 0:
            //New Thread
            NSLog(@"Thread Returned");
            threadState = NULL;
            [threads removeObjectAtIndex:0];
            break;

        case LUA_ERRMEM:
            NSLog(@"LUA_ERRMEM");
            NSLog(@"%s\n", lua_tostring(threadState,-1));
            [threads removeObjectAtIndex:0];
            break;

        case LUA_ERRERR:
            NSLog(@"LUA_ERRERR: error while running the error handler function");
            NSLog(@"%s\n", lua_tostring(threadState,-1));
            [threads removeObjectAtIndex:0];
            break;

        case LUA_ERRRUN:
            NSLog(@"LUA_ERRRUN: a runtime error.");
            NSLog(@"%s\n", lua_tostring(threadState,-1));
            [threads removeObjectAtIndex:0];
            break;

        default:
            NSLog(@"Error Executing Threaded Script!");
            NSLog(@"%s\n", lua_tostring(threadState,-1));
            [threads removeObjectAtIndex:0];
            break;

    }

}

}

デバッグするのは本当に大変でしたしかし、それは機能します!!!!!

于 2010-06-04T07:36:22.780 に答える