Lua и немного многозадачности - PullRequest
2 голосов
/ 04 июня 2010

Я работаю над небольшим проектом для iPad, и я просто хочу запустить скрипт, который остановится после определенных вызовов функций, а затем разрешить мне возобновить сценарий с того же места позже. На самом деле, я делаю «потоки» только по очереди в очереди, так что на самом деле это только многозадачность между 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. С BAD_MEMORY_ACCESS или lua_resume иногда возвращает ошибку времени выполнения. (Я не знаю, как проверить, в чем заключается ошибка, поэтому, если бы вы могли помочь мне с этим, я бы тоже это оценил) Может кто-нибудь там сказать мне, что я делаю здесь неправильно?

1 Ответ

3 голосов
/ 04 июня 2010

Хорошо, я не понимаю этого на 100%, но я верю, что это как-то связано с тем, что я вызывал doFileThreaded из другого исполняемого скрипта lua. Казалось бы, хотя lua_State отличается от того факта, что я вызвал luaL_loadfile из функции, которая уже была вызвана Lua, это все равно каким-то образом вызывало «попытку уступить через границу вызова метаметода / C» * *

Мое решение состояло в том, чтобы сохранить имена файлов, которые я хотел запустить как строки, в массив, а затем вызвать lua_newthread в doThread.

- (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;

    }

}

}

Ух это было настоящей болью для отладки. НО ЭТО РАБОТАЕТ !!!!!

...