Solved Pausing a While Loop with Schedulers

Discussion in 'Spigot Plugin Development' started by DanielVip3, Jun 13, 2018.

  1. I'm so stupid that I can't figure out how to "pause" while loops with Schedulers.
    I have a while loop that loops for every character in a text file.
    If the character is a note, it should play it. Else, if the character is "PAUSE[number]", like "PAUSE60", it should pause for 60 seconds. The problem is that... yeah, I can actually play notes.
    But I can't pause the loop for 60 seconds.
    In my code, "i" means the string itself, and "isNote" is a boolean that before checked if the code is a note, is a pause or a change of instrument. If it's not a note, it returns false.
    Code (Java):

    // all this code is in a "while (inputFile.hasNextLine())"

    // i is the character/string in the text file

    /* isNote is the check, to see if the character/string is a note(if it's C, D, E, F, G, A, B... isNote is true, else if it's
    * PAUSE[number] it's false. I added the other check(indexOf != -1), because isNote can be false even without a
    pause.)*/


                    // checking if it's a note. Obviously, a pause isn't a note
                    if (isNote) {
                        player.getWorld().playSound(loc, instrument, 1f, pitch);
                    } else {
                        // checking if it's a pause
                        if (i.indexOf("PAUSE") != -1) {
                            // replacing words in the string and getting the time, in ticks, of the pause
                            String clean = i.replaceAll("\\D+", "");
                            long pause = Long.parseLong(clean);

                            // there I'm trying to wait for "pause" ticks in the foor loop. I mean, if pause ticks are 80, it should wait for 80 ticks and then go to "continue" and continue the loop.
                            BukkitTask wait = new BukkitRunnable() {
                                @Override
                                public void run() {
                                }
                            }.runTaskTimer(Bukkit.getServer().getPluginManager().getPlugin("MoNoteblocks"), pause, 1L);
                            // but the problem is that the BukkitRunnable is ran, but the code doesn't wait till it's end.
                            continue;
                        }
                    }
     
    I can't understand how to do it. I tried with the Scheduler, but obviously the while doesn't wait the end of the scheduler to continue.
    I also tried with an Asynchronous Scheduler, but it's the same thing.
    My idea is to block the loop for some ticks and then continue it.
    Would that be possible?
     
    #1 DanielVip3, Jun 13, 2018
    Last edited: Jun 13, 2018
  2. You can pause the current Thread with
    Code (Java):
    Thread.sleep(millis);
    But if you are on the main thread, the entire server will be paused for the given time.
    You could parse your file on an asynchronous Thread, and execute the Spigot functions synchronously by doing something like this:
    Code (Java):
    Bukkit.getScheduler().callSyncMethod(pluginInstance, () -> {
        //...
    }
    Note that the passed function will not execute until the next server tick. If you were about to use packets, there would be no need to send them synchronously (it could be possible that playsound also works asynchronously, you might want to try this out).
     
    • Agree Agree x 2
  3. I'm not in the main thread, I'm in an event thread(I guess they're different threads), so I think it will work. I thought that it blocked the main thread event if it wasn't in it, but I'm so stupid and didn't think about it. I'll let you know if it works. Thank you.
     
    #3 DanielVip3, Jun 13, 2018
    Last edited: Jun 13, 2018
  4. Events are usually called synchronously, so saying that you are not in "the main method", but in a "listener method" is nonsense.
     
  5. Oh, my bad, I read it wrong. I mean that I'm in a Listener class and so I think that I'm not in the main thread(I guess that events are not passed to ta secondary thread)
     
    #5 DanielVip3, Jun 13, 2018
    Last edited: Jun 13, 2018
  6. ... Events are called in the main thread (not all though, e.g. AsyncPlayerChatEvent). You have no understanding of what a thread is and what they do. But I'm quite sure that you will figure that out yourself pretty soon anyways.
    From your statements I can also conclude you don't have very much Java knowledge either, so I suggests you might want to watch some tutorials, as reading is not so popular anymore, I guess.

    If you are more the interactive type, I think learnjavaonline.org or codecademy might be your choice.
     
  7. create a runnable class that ticks however often you want, use long timestamps when you want to pause, when the scheduled timer ticks, check if enough time has passed. if it has, then it should run the code you want
     
  8. I already know what a thread is xD I can't simply understand how spigot/bukkit threads works. I know that the event is called in the main thread, but I don't know if them are then passed to a secondary thread.
    What do you mean by "from your statements"? Lol. I think that they're good. I don't know what's my error, so if you can, notice me about it.
    By the way, I think that the community should stop saying "learn Java" everytime, also when people misunderstands things.
    And also, even if I know what a thread is an how to use it, I don't know how it works in JVM(I came, mainly, from C++ and Python), so I'll try to learn how they works in Java(I saw a lot of differences between threads in different languages).

    Nice idea. Now I will test both the ideas, and I'll see what works better.

    Thank you both.

    EDIT:
    It worked perfectly(I mean the second option). Thank you.
     
    #8 DanielVip3, Jun 13, 2018
    Last edited: Jun 13, 2018

Share This Page