Author Topic: [Java] ChatQueue  (Read 4298 times)

0 Members and 1 Guest are viewing this topic.

Offline Camel

  • Hero Member
  • *****
  • Posts: 1703
    • View Profile
    • BNU Bot
[Java] ChatQueue
« on: September 23, 2007, 05:56:31 pm »
Here's the ChatQueue class from my bot. If flood protection (boolean fp) is enabled, enqueue() will throw the string in a linked list, and the thread will come around and pick a Connection to send the text on. If fp is disabled, then it will send text immediately in round-robin order.

http://bnubot.googlecode.com/svn/trunk/BNUBot/src/net/bnubot/core/ChatQueue.java
/**
 * This file is distributed under the GPL
 * $Id$
 */

package net.bnubot.core;

import java.util.Iterator;
import java.util.LinkedList;


public class ChatQueue extends Thread {
   private LinkedList<Connection> cons = new LinkedList<Connection>();
   private LinkedList<String> queue = new LinkedList<String>();
   private int lastCon = 0;
   
   public ChatQueue() {
      super(ChatQueue.class.getSimpleName());
      setDaemon(true);
   }
   
   public boolean add(Connection c) {
      synchronized(cons) {
         return cons.add(c);
      }
   }
   
   public boolean enqueue(String text, boolean fp) {
      if(fp) synchronized(queue) {
         return queue.add(text);
      }
      if(lastCon >= cons.size())
         lastCon = 0;
      cons.get(lastCon++).sendChatNow(text);
      return true;
   }
   
   public void run() {
      //TODO: flag condition for when there's a /kick or /ban but no ops are connected
      while(true) {
         // If there's text in the queue to send
         if(queue.size() > 0) {
            // Iterate through the connecitons
            Iterator<Connection> it = cons.iterator();
            while(it.hasNext()) {
               Connection con = it.next();
               // Check if the con can send text now
               if(con.canSendChat()) {
                  if(!con.isOp()) {
                     //Find a string we can send
                     int queueIndex;
                     findSendableText: for(queueIndex = 0; queueIndex < queue.size(); queueIndex++) {
                        String text = queue.get(queueIndex);
                        
                        // Check if ops is required
                        try {
                           if(text.charAt(0) == '/') {
                              String cmd = text.substring(1);
                              int i = cmd.indexOf(' ');
                              if(i != -1) {
                                 cmd = cmd.substring(0, i).toLowerCase();
                                 
                                 if(cmd.equals("kick")
                                 || cmd.equals("ban"))
                                    continue findSendableText;
                              }
                           }
                        } catch(Exception e) {}

                        // Write the text out
                        con.sendChatNow(queue.remove(queueIndex));
                     }
                  } else {
                     // Write the text out
                     con.sendChatNow(queue.remove());
                  }
                  
                  // If the queue is empty, stop
                  if(queue.size() == 0)
                     break;
               }
            }
            
         }
         
         yield();
         try { sleep(10); } catch(Exception e) {}
      }
   }
}

<Camel> i said what what
<Blaze> in the butt
<Camel> you want to do it in my butt?
<Blaze> in my butt
<Camel> let's do it in the butt
<Blaze> Okay!

Offline iago

  • Leader
  • Administrator
  • Hero Member
  • *****
  • Posts: 17914
  • Fnord.
    • View Profile
    • SkullSecurity
Re: [Java] ChatQueue
« Reply #1 on: September 24, 2007, 10:44:50 am »

         try { sleep(10); } catch(Exception e) {}

One of my least favorite things that Java forces you to do. Damn Java!

Offline Camel

  • Hero Member
  • *****
  • Posts: 1703
    • View Profile
    • BNU Bot
Re: [Java] ChatQueue
« Reply #2 on: September 24, 2007, 12:12:01 pm »
Agreed; it's nice that it informs you whether it succeeded, but it could accomplish the same by returning a boolean. The way I see it, exceptions have two purposes: to provide details about the error, and to provide a stack trace. Since InterruptedExceptions or whatever they're using are not useful for either case, they shouldn't exist.

<Camel> i said what what
<Blaze> in the butt
<Camel> you want to do it in my butt?
<Blaze> in my butt
<Camel> let's do it in the butt
<Blaze> Okay!

Offline Chavo

  • x86
  • Hero Member
  • *****
  • Posts: 2219
  • no u
    • View Profile
    • Chavoland
Re: [Java] ChatQueue
« Reply #3 on: September 24, 2007, 05:13:44 pm »
a boolean wouldn't be as useful in the case that you have another thread waking your sleeping thread and want to send a message or control (it could be necessary to differentiate between a timeout and a forced wakeup)

Offline Camel

  • Hero Member
  • *****
  • Posts: 1703
    • View Profile
    • BNU Bot
Re: [Java] ChatQueue
« Reply #4 on: September 24, 2007, 07:25:18 pm »
a boolean wouldn't be as useful in the case that you have another thread waking your sleeping thread and want to send a message or control (it could be necessary to differentiate between a timeout and a forced wakeup)

Booleans have two states: true, and false.

There are only two conditions for sleep() to stop blocking: timeout, and forced wakeup.

What's confusing about that?

<Camel> i said what what
<Blaze> in the butt
<Camel> you want to do it in my butt?
<Blaze> in my butt
<Camel> let's do it in the butt
<Blaze> Okay!

Offline Chavo

  • x86
  • Hero Member
  • *****
  • Posts: 2219
  • no u
    • View Profile
    • Chavoland
Re: [Java] ChatQueue
« Reply #5 on: September 24, 2007, 10:17:17 pm »
Two conditions aren't sufficient to describe all possible circumstances that might cause a thread to wakeup.  If true is a normal timeout return and false describes any unintended interrupt, you would have to do significant extra work to find out what caused the unintended interrupt.  What's wrong with throwing an exception to find the cause of an error/non-timeout interrupt?

Don't get me wrong, I'm not a big fan of the syntax either but I can't think of anything better :)

Offline Camel

  • Hero Member
  • *****
  • Posts: 1703
    • View Profile
    • BNU Bot
Re: [Java] ChatQueue
« Reply #6 on: September 24, 2007, 11:41:06 pm »
I can't think of any condition where the program should care why sleep() failed.

<Camel> i said what what
<Blaze> in the butt
<Camel> you want to do it in my butt?
<Blaze> in my butt
<Camel> let's do it in the butt
<Blaze> Okay!

Offline iago

  • Leader
  • Administrator
  • Hero Member
  • *****
  • Posts: 17914
  • Fnord.
    • View Profile
    • SkullSecurity
Re: [Java] ChatQueue
« Reply #7 on: September 25, 2007, 10:06:16 am »
I can't think of any condition where the program should care why sleep() failed.
I can see rare reasons why it might care, but it can be handled on a case-by-case basis depending on what needs to happen.