Changes between Initial Version and Version 1 of Tutorial6SingleUseTimerTasks

Jul 31, 2007 4:21:08 PM (12 years ago)

Initial version


  • Tutorial6SingleUseTimerTasks

    v1 v1  
     2^This tutorial has been copied with the approval of D1st0rt from [ D1st0rt's website].^ 
     4= Tutorial 6: Single-Use TimerTasks = 
     5''Written by D1st0rt @ Saturday, 25 February 2006''[[BR]] 
     6''Last updated: Saturday, 25 February 2006'' 
     8This is the first of two tutorials to demonstrate the use of TimerTasks. In this one we will be dealing with Single-Use TimerTasks, meaning tasks that execute only once some time in the future. TWCore provides an easy way to manage these TimerTasks through the BotAction class, which I will attempt to illustrate in this tutorial with our good friend mybot. Our mybot module welcomes players whenever they enter the arena, but we only want it to greet players that have entered the arena for the first time in the last 10 minutes. Since parts of the mybot module stay the same, I'm only going to show changed sections of code in this tutorial. 
     12//Removed some of the older comments to make the code cleaner 
     13//now that you should know the reasoning behind it all 
     14package twcore.bots.twbot; 
     16import java.util.HashSet; 
     17import java.util.Vector; 
     18import java.util.TimerTask; 
     19import twcore.core.*; 
     21public class twbotmybot extends TWBotExtension 
     23    /** Keeps track of the recent players to enter */ 
     24    private HashSet<String> recentPlayers; 
     25    /** Holds onto all of the current tasks running */ 
     26    private Vector<RemovePlayer> activeTasks; 
     27    /** Module Help message */ 
     28    private final String[] helpMsg = { 
     29        "[mybot]", 
     30        "!welcome - welcomes people" 
     31    }; 
     33    /** 
     34     * Creates a new instance of the mybot module 
     35     */ 
     36    public twbotmybot() 
     37    { 
     38        recentPlayers = new HashSet<String>(); 
     39        activeTasks = new Vector<RemovePlayer>(); 
     40    } 
     42    /** 
     43     * Stops any running tasks so the module can be unloaded. 
     44     */ 
     45    public void cancel() 
     46    { 
     47        for(RemovePlayer task : activeTasks) 
     48            task.cancel(); 
     49    }  
     52There are some new imports for this module, being the `HashSet` and `Vector` data structures from the `java.util` package. These will allow us to easily store some of the dynamic data we need for this module. I also added the `TimerTask` import for obvious reasons. In the constructor, I instantiated my HashSet and Vector. Because they are objects and not primitive types like an `int` or a `char`, they must be created before they can be used. The `cancel` method is important to have in a module because if you do not cancel all of your tasks they will keep running even after the module is unloaded, which can have some undesired effects. 
     56    /** 
     57     * Event: PlayerEntered 
     58     * Called when a player enters the arena 
     59     * If the player enters the arena for the first time in the past 10 minutes, 
     60     * welcome them to the arena. 
     61     */ 
     62    public void handleEvent(PlayerEntered event) 
     63    { 
     64        String name = event.getPlayerName(); 
     65        if(!recentPlayers.contains(name)) 
     66        { 
     67            m_botAction.sendPrivateMessage(name,"Welcome!"); 
     68            recentPlayers.add(name); 
     69            RemovePlayer task = new RemovePlayer(name); 
     70            activeTasks.add(task); 
     71            m_botAction.scheduleTask(task, 600000); 
     72        } 
     73    }   
     76Here is our new and improved `PlayerEntered` event handling. Once we get the player's name, we check to see if they have been in the arena in the last 10 minutes by whether they are contained in our set of recent players. If they aren't, we need to welcome them, add them to our recent players, and start a task to remove them from the recent players set after 10 minutes. We don't do anything if they are in the recent player set because that means they previously entered the arena less than 10 minutes ago. 
     80    /** 
     81     * This class represents a task to remove a player from the list of 
     82     * players recently entering the arena after 10 minutes 
     83     */ 
     84    private class RemovePlayer extends TimerTask 
     85    { 
     86        /** The name of the player */ 
     87        private String name; 
     89        /** 
     90         * Creates a new instance of the RemovePlayer task 
     91         * @param name the name of the player 
     92         */ 
     93        public RemovePlayer(String name) 
     94        { 
     95   = name; 
     96        } 
     98        /** 
     99         * Execute this task: remove the player from the recent players list 
     100         */ 
     101        public void run() 
     102        { 
     103            recentPlayers.remove(name); 
     104            activeTasks.remove(this); 
     105        } 
     106    } 
     110Whenever you want to use a TimerTask, having a task to execute is usually fairly important. We put our class `RemovePlayer` that `extends TimerTask` inside of our module class so that it can access the recent player set, and we make it `private` so that no other class has access to it. When we create a new `RemovePlayer` task, we specify the name of the player we want to remove when the task executes. The `run` method is what is called when it is time for the task to do it's thing. In this case, it removes the player from the recent players and removes this task from the list of active tasks. Because a `TimerTask` runs on a separate thread from the bot, it is a good idea to use the `Vector` class to store tasks over the `ArrayList class` because the latter is not thread-safe. 
     112[wiki:Tutorial5TWBotExtensionBasics Previous Tutorial] | [wiki:Tutorial7RepeatingTimerTasks Next Tutorial]