Enhance threadsafety of Hooks and improve generally
[clinton/bobotpp.git] / source / BotInterp.H
index 85644aa..4329ee4 100644 (file)
@@ -1,6 +1,6 @@
 // BotInterp.H  -*- C++ -*-
 // Copyright (c) 1998 Etienne BERNARD
-// Copyright (C) 2002 Clinton Ebadi
+// Copyright (C) 2002,2005,2008 Clinton Ebadi
 
 // This program is free software; you can redistribute it and/or modify
 // it under the terms of the GNU General Public License as published by
@@ -14,7 +14,8 @@
 
 // You should have received a copy of the GNU General Public License
 // along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+// 02110-1301, USA.
 
 #ifndef BOTINTERP_H
 #define BOTINTERP_H
 #ifdef USESCRIPTS
 
 #include <ctime>
+#include <functional>
+#include <list>
+#include <map>
+#include <string>
+
 #include <libguile.h>
+
+#include "BotThreading.H"
 #include "String.H"
+#include "Utils.H"
 
 class Bot;
 
@@ -36,53 +45,27 @@ struct Hook {
   int priority;
   bool fallthru;
 
-  String regex_str;
-  String name;
+  std::string regex_str;
+  std::string name;
   SCM regex;
   SCM function;
 
-  Hook(int t, String rs, SCM r, SCM f, int p, bool ft, String n="DEFAULT")
+  Hook(int t, std::string rs, SCM r, SCM f, int p, bool ft, std::string n="DEFAULT")
     : type(t), priority (p), fallthru (ft), regex_str(rs), 
       name (n), regex(r), function(f)  { }
 
-  bool operator< (const Hook &h) const
-  {
-    if (priority < h.priority)
-      {
-       return true;
-      }
-    else if (priority > h.priority)
-      {
-       return false;
-      }
-    else if (fallthru && h.fallthru)
-      {
-       return false;
-      }
-    else if (fallthru && !h.fallthru)
-      {
-       return false;
-      }
-    else if (!fallthru && h.fallthru)
-      {
-       return true;
-      }
-    else
-      {
-       // NOTE: This should never be reached
-       return false;
-      }
-  }
+  bool operator< (const Hook & h) const;
 
   enum {
     ACTION, NICKNAME, SIGNOFF, CTCP, CTCP_REPLY,
-    DISCONNECT, FLOOD, INVITE, JOIN, KICK, LEAVE,
-    MODE, MESSAGE, NAMES, NOTICE, PUBLIC,
+    DISCONNECT, FLOOD, INVITE, JOIN, KICK, MODE, 
+    MESSAGE, NAMES, NOTICE, PART, PUBLIC,
     PUBLIC_NOTICE, RAW, TIMER, TOPIC,
     // send hooks
     SEND_ACTION, SEND_CTCP, SEND_PUBLIC, SEND_MESSAGE,
+    SEND_WHO, SEND_WHOIS,
     // DCC hooks
-    DCC_CHAT_BEGIN, DCC_CHAT_MESSAGE
+    DCC_CHAT_BEGIN, DCC_CHAT_END, DCC_CHAT_MESSAGE
   };  
 };
 
@@ -93,15 +76,29 @@ struct Timer {
 
   Timer(int c, std::time_t t, SCM f)
     : count(c), when(t), function(f) { }
+
+  bool operator< (const Timer & other) const
+  { return when < other.when; }
 };
 
 class BotInterp {
+  typedef std::list<Timer *> TimerList;
+  typedef std::list<Hook *> HookList;
+  typedef std::map<int, HookList, std::less<int> > HookMap;
+  
   Bot * bot;
   SCM logPort;
-  std::map<int, std::list<Hook *>, std::less<int> > hooksMap;
-  std::list<Timer *> timersList;
   int counter;
 
+  HookMap hooks;
+  TimerList timers;
+
+  Utils::IndirectPred<Timer, std::less<Timer> > timer_sort_p;
+  Utils::IndirectPred<Hook, std::less<Hook> > hook_sort_p;
+
+  BotMutex hook_mutex;
+  BotMutex timer_mutex; // NOTE: recursive lock
+
 public:
   BotInterp(Bot *, String);
 
@@ -110,8 +107,8 @@ public:
   void Execute(String);
   void LoadScript(String);
 
-  bool AddHook(int, SCM, SCM, int, bool, String);
-  bool RunHooks(int, String, SCM);
+  bool AddHook(int, SCM, SCM, int, bool, std::string);
+  bool RunHooks(int, std::string, SCM);
 
   SCM AddTimer(int, SCM);
   bool DelTimer(SCM);