Jump to content


Photo

LUA Script - coroutine.sleep

LUA

    3 replies to this topic

    #1 Etamame

    Etamame

      Newbie

    • Members
    • Pip
    • 2 posts

      Posted 04 September 2015 - 07:40 PM

      I have been playing around with some scripting in LUA but ran into a problem. I want to sleep the script (i.e. to allow for a spell to be cast..etc.) and thought I would use coroutine.sleep to do this. However it doesn't appear that the interpreter ever comes back to the script, likely because its unloaded when it yields.  Is there another method for doing this?

       

      As an example the following script:

       

      print(1)

      coroutine.sleep(2)

      print(2)

       

      It seems like it should print 1 on the console and then 2 seconds later print 2, but in reality it prints 1 and then never does anything.  Is there a way to fix this, or another way to put a pause in a script?

       

       



      #2 Iryoku

      Iryoku

        Advanced Member

      • Windower Staff
      • 488 posts

        Posted 05 September 2015 - 01:31 AM

        This is a limitation of the way scripts are currently implemented; yielding from a script in any way effectively blocks the rest of the script from running. I hope to fix this in the next major release, but in the mean time there really isn't any way to do this that doesn't involve splitting the script into two parts or converting it to an addon.



        #3 Etamame

        Etamame

          Newbie

        • Members
        • Pip
        • 2 posts

          Posted 05 September 2015 - 01:58 AM

          The weird thing is that if you yield implicitly it will still work, but the sleep causes the script to exit. The following works just fine and will execute to completion.

           

          print(1)

          coroutine.yield()

          print(2)

           

          This will print 1 and 2 to the console. I also noticed that it doesn't see that you can register an event handler in a script. Looks like I'll be working on converting my script to an add-on sooner than I had expected.



          #4 Iryoku

          Iryoku

            Advanced Member

          • Windower Staff
          • 488 posts

            Posted 05 September 2015 - 09:32 AM

            The fact that coroutine.yield() happens to work shouldn't be relied upon. It's a race condition. Both addons and scripts run in isolated threads, yielding returns control back to the scheduler which notifies the calling function (in this case the script loader) that excecution has stopped, and then schedules the coroutine to be resumed at a later time. Depending on the timing this opens a small window for the script loader to send a request to the scheduler to stop, and once that happens the lua interpreter is torn down. I think, due to another quirk with how unloading happens, that execution will always continue after the first call to coroutine.yield(), but after that it's up to the whims of the OS. The fact that it works once is definitely an implementation detail that is subject to change at any time.

             

            Making yield and sleep work correctly in scripts requires fairly drastic changes to the way they are run. To understand why, it may help to know that when scripts were first implemented, sleep had yet to be implemented, and it was not possible to yield from scripts or from the global scope in an addon at all (doing so caused a runtime error). The only reason you can call either function now without error, is because the addon framework (which scripts are implemented on top of) was modified so that yielding from global scope worked.

             

            Also yes, while events can be registered in scripts (they're implemented on top of the addon framework after all), the events will never be called because the script gets unloaded before they ever get a chance to run.







            Also tagged with one or more of these keywords: LUA

            1 user(s) are reading this topic

            0 members, 1 guests, 0 anonymous users