2012-11-16 9 views
6

Jaki jest cel przekazywania argumentów lua_resume i lua_yield?Lua: lua_resume i lua_yield argument celów

Rozumiem, że przy pierwszym wywołaniu lua_resume argumenty są przekazywane do funkcji lua, która jest wznawiana. To ma sens. Oczekuję jednak, że wszystkie kolejne wywołania lua_resume "zaktualizują" argumenty w funkcji coroutine. Jednak tak nie jest.

Jaki jest cel przekazywania argumentów lua_resume dla lua_yield do zwrócenia? Czy funkcja lua działająca pod coroutine ma dostęp do argumentów przekazywanych przez lua_resume?

Odpowiedz

10

Co powiedział Nicol. Nadal można zachować wartości od pierwszego resume rozmowy, jeśli chcesz:

do 
    local firstcall 
    function willyield(a) 
    firstcall = a 
    while a do 
     print(a, firstcall) 
     a = coroutine.yield() 
    end 
    end 
end 

local coro = coroutine.create(willyield) 
coroutine.resume(coro, 1) 
coroutine.resume(coro, 10) 
coroutine.resume(coro, 100) 
coroutine.resume(coro) 

wypisze

1 1 
10 1 
100 1 
+0

Czuję, że to nie odpowiada na pytanie.OP dotyczył/C API/funkcji lua_resume() i lua_yield(), które mają inną semantykę niż standardowa biblioteka 'coroutine.resume()', itp. (Na przykład, lua_resume ma trzy argumenty - dwa z nich to lua_State ...) – BadZen

+0

Myślę, że odpowiada na pytanie o cel przekazywania parametrów i daje przykład, który można łatwo wypróbować przy pomocy interpretera Lua. W rzeczywistości, OP powiedział tak samo w swoim komentarzu w odpowiedzi Nicola. Zawsze możesz podać własną odpowiedź, jeśli uważasz, że masz lepszą. –

+0

Istnieje duża różnica między obiektem coroutine w bibliotekach (które na przykład enkapsuluje lua_State) a używaniem API C. Nie mam lepszej odpowiedzi, więc otworzyłem kolejne pytanie z pytaniem o C API. Odpowiedź Nichola i twoje tutaj mówią o korupcyjnym obiekcie bibliotecznym. Istnieje około 100 linii kodu, które implementują to pod względem lua_ * API. Nie jest to oczywiste, a dokumentacja jest krótka. – BadZen

5

Lua nie może magicznie podać oryginalnych argumentów nowych wartości. Mogą nie być już na stosie, w zależności od optymalizacji. Co więcej, nie ma żadnego wskazania, gdzie kod był, gdy się uległ, więc może nie być już w stanie zobaczyć tych argumentów. Na przykład, jeśli coroutine nazwie funkcję, ta nowa funkcja nie może zobaczyć argumentów przekazanych do starego.

coroutine.yield() zwraca argumenty przekazane do wywołania resume, które kontynuują coroutine, dzięki czemu strona wywołania yield może obsługiwać parametry zgodnie z oczekiwaniami. Pozwala to kodowi powracającemu na komunikowanie się z określonym kodem wykonującym plonowanie. yield() przekazuje swoje argumenty jako wartości zwracane z resume, a resume przekazuje swoje argumenty jako wartości zwracane do yield. To ustanawia ścieżkę komunikacji.

Nie można tego zrobić w żaden inny sposób. Z pewnością nie przez modyfikowanie argumentów, które mogą być niewidoczne z witryny yield. Jest prosty, elegancki i ma sens.

Uważa się także za wyjątkowo niegrzecznego, gdy chodzi o wsłuchiwanie się w czyjeś wartości. Zwłaszcza funkcja już działająca. Pamiętaj: argumenty są po prostu zmiennymi lokalnymi wypełnionymi wartościami. Użytkownik nie powinien oczekiwać zmiany zawartości tych zmiennych, chyba że sam je zmieni. W końcu są to zmienne local. Można je zmieniać tylko lokalnie; stąd nazwa.

+0

Dzięki! Aby wyjaśnić, po uruchomieniu coroutine lokalne wartości nie mogą być modyfikowane zewnętrznie? Założę się, że będę musiał przekazać do wnętrza coroutine przez zmienne globalne? Na przykład mogę mieć liczbę "obiektów pobliskich" w grze, w której zawodnik musi wiedzieć, ile innych obiektów znajduje się w odległości. Aby to zrobić, musiałbym mieć globalny, aby przechowywać liczbę pobliskich obiektów? Miałem nadzieję, że mogę docenić wartość Coroutine tuż przed moim powrotem, aby uniknąć porządkowania przestrzeni nazw za pomocą globaliów. – RandyGaul

+0

Wartości można modyfikować; wystarczy przypisać wynik wywołania coroutine.yield() do tej samej zmiennej, którą przekazałeś jako parametr pierwotnie. Popatrz na moją odpowiedź na przykład. –

+0

@RandyGaul: "* po uruchomieniu coroutine lokalne wartości nie mogą być modyfikowane zewnętrznie *" Zmienne 'local 'nie mogą być modyfikowane zewnętrznie * period *; Coroutines nie są specjalne. Jeśli chcesz przekazać ten numer, przekaż go jako parametry do 'wznowienia' i odbierz je jako wartość zwracaną z' yield'. Jak już wspomniałem, to jest interfejs komunikacyjny, który posiadasz. –