Creating multiple instances of a class that work simultaneously

Discussion in 'Plugin Development' started by CrispyCookie, Apr 8, 2015.

Thread Status:
Not open for further replies.
  1. Offline

    CrispyCookie

    Hello,
    I'm sure this has been answered before, but my search terms were probably too unspecific.

    I have a class with methods that are used to generate a building. It uses Bukkit Schedulers so the building rises up slowly.

    Now when I want to use the method when a building is already in progress, everything is messed up.
    I think it's because it's the same instace of the class.

    It's called like
    Code:
    BuildingClass.startBuilding(location);
    How can I rise up up multiple buildings at the same time without writing a second, a third... class?
     
  2. Online

    timtower Administrator Administrator Moderator

  3. Offline

    CrispyCookie

    How is that done? If I call methods from another class I have to make the methods static.
     
  4. @CrispyCookie Like @timtower said, you need to create an instance of the class instead of using static methods (I seriously wouldn't recommend static unless it's your last choice...). You can create a new instance of a class by doing:
    Code:
    ClassName name = new ClassName();
    Put any constructor arguments in the parenthesis. Creating a new instance of a class will work with methods, but will NOT work with things such as ArrayLists.
    The way that you would call methods would be:
    Code:
    name.callMethod();
    Anyway, hoped this helped. :)
     
  5. Offline

    CrispyCookie

    Oh man, whole plugin is written with static methods ^^ Will try it. Will those instances remain in the memory "forever" or how does java know they're not used anymore?
     
    Last edited: Apr 8, 2015
  6. Online

    timtower Administrator Administrator Moderator

    @CrispyCookie Please don't use static, use Constructors and pass instances instead.
    Java knows when they are out of scope if they are local variables.
    But when you make lists then you need to do some cleaning yourself.
     
  7. Offline

    CrispyCookie

    Question:

    I use something like this in another part of the plugin to apply a temporary night vision:
    Code:
        public static void blindPeople(Location l, int halfradius){
       
            //final List<Player> NightvisionPeople =new ArrayList<Player>();
       
            Player[] list = Bukkit.getOnlinePlayers();
       
            for(final Player p : list){
                p.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS,20,1));
                if (p.hasPotionEffect(PotionEffectType.NIGHT_VISION)){
                    hadNightvision = true;
                }
                else{
                    p.addPotionEffect(new PotionEffect(PotionEffectType.NIGHT_VISION,300,1));
                    hadNightvision = false;
                }
           
           
                Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable(){
                    public void run() {
                        if (hadNightvision == false){
                            p.removePotionEffect(PotionEffectType.NIGHT_VISION);
                        }
    
                        }
                        }, 20L);
           
            }
       
        }
    
    (This is so complicated because the night vision should last only a few seconds but if the remaining time is under 10s it will start to flash)

    So my question is:
    Do I have to clean something afterwards if I start using instances instead of static methods? :D


    ______________________

    Problem:

    And now I have a new problem: I use a scheduler that cancels itself.
    So until now I had in the class constructor:
    Code:
    static int taskID;
    And later in a static method:
    Code:
    taskID  = Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, new Runnable(){
    
    ...
    
    Bukkit.getScheduler().cancelTask(taskID);
    Because the cancel was in an else-statement and could only be executed when the first loop had ended, there was no warning that taskID couldn't be initialized.

    And now (since I moved to non-static methods) the last line to cancel the task says that taskID must be final. So I make it final in the constructor:
    Code:
    final int taskID;
    Now the cancel line says I should -"> Initialize the variable" which leads to:
    Code:
    final int taskID = 0;
    But now the line "taskID = Bukkit.getScheduler().scheduleSyncRepeatingTask" says I should "-> remove final modifier of taskID".

    This is an infinite loop of errors, I'm confused. Can anybody help me? I'll give more details if it wasn't clear enough.

    My current workaround for the problem is a delayed task that predicts when the repeating task will need to be cancelled. But I would be happy if I didn't have to use the workaround.
     
    Last edited: Apr 8, 2015
  8. Offline

    mythbusterma

    @CrispyCookie

    That method looks like it could be what would be considered a "utility" method.

    From what I can see, it doesn't require any instance variables of the class it's contained within (nor any others that would reasonably be considered within the scope) so that method should stay static, and be put somewhere with other utility functions.

    As a rule of thumb in Java, if you don't obtain resources (e.g. open a file, connect to a server or database, etc.) you don't need to clean up after yourself. That's what the garbage collector is for.

    Also, it's not a "scheduler" it's a "Runnable" or "BukkitRunnable" that you're using.

    As for solving the issue with that, make the class extend BukkitRunnable instead of implement Runnable, and have it invoke BukkitRunnable#cancel() on itself.
     
  9. Offline

    fireblast709

  10. Offline

    CrispyCookie

    Yes, I should probably deepen my knowlegde of Java :)

    @mythbusterma
    So I would create a separate class to extend the Runnable and then just use "this.cancel()"?

    Concerning your suggestion to make a static utility method:
    Don't I have to use instances of the class that has a delayed task in it? Because it could be called while it's in action which would mess up the variables.
     
Thread Status:
Not open for further replies.

Share This Page