Update all deprecated/discouraged Guile calls
[clinton/bobotpp.git] / source / BotInterp.C
CommitLineData
cb21075d 1// BotInterp.C -*- C++ -*-
2// Copyright (c) 1998 Etienne BERNARD
46af1667 3// Copyright (C) 2002,2005,2008 Clinton Ebadi
cb21075d 4
5// This program is free software; you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation; either version 2 of the License, or
8// (at your option) any later version.
9
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14
15// You should have received a copy of the GNU General Public License
16// along with this program; if not, write to the Free Software
ae97d6ec 17// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18// 02110-1301, USA.
cb21075d 19
20#ifdef HAVE_CONFIG_H
21#include "config.h"
22#endif
23
24#include "Utils.H"
25#include "Bot.H"
26#include "BotInterp.H"
27
28#ifdef USESCRIPTS
29
30#include <libguile.h>
31extern "C"
32{
33#include <libguile/regex-posix.h>
34}
35
36BotInterp::BotInterp(Bot *b, String fn)
37 : bot(b), counter(0)
38{
db098a03 39 logPort = scm_open_file (Utils::str2scm (fn),
40 Utils::str2scm ("a"));
41
cb21075d 42 scm_gc_protect_object(logPort);
43}
44
45void
46BotInterp::Execute(String command)
47{
48 Interp::Execute(bot, command);
49}
50
51void
52BotInterp::LoadScript(String filename)
53{
54 Interp::LoadScript(bot, filename);
55}
56
d56bdd22 57SCM
58BotInterp::ScriptLog()
cb21075d 59{
d56bdd22 60 return logPort;
cb21075d 61}
62
be3612f3 63namespace
64{
65 bool hptr_lt (const Hook* h, const Hook* h1)
66 // Hook Pointer less than
67 // Used to sort the Hooks list
68 { return *h < *h1; }
69}
70
cb21075d 71bool
fd7440f1 72BotInterp::AddHook(int hooktype, SCM regex, SCM function, int pri, bool fall,
73 String name) {
cb21075d 74 if (scm_string_p(regex) == SCM_BOOL_F)
75 return false;
a6339323 76 String rx = Utils::to_upper (Utils::scm2str (regex));
46af1667 77 // fixme: really ought to use scm_c_module_lookup with bot module
78 SCM r = scm_make_regexp (regex,
79 scm_list_n (scm_variable_ref (scm_c_lookup ("regexp/icase")),
80 SCM_UNDEFINED));
cb21075d 81 scm_gc_protect_object(r);
82 scm_gc_protect_object(function);
83 // First, we check if an hook doesn't exist yet
84 std::list<Hook *>::iterator it = hooksMap[hooktype].begin();
85 std::list<Hook *>::iterator it2 = hooksMap[hooktype].end();
be3612f3 86
cb21075d 87 for ( ; it != it2; ++it)
88 // It exists, we replace it.
fd7440f1 89 if ((*it)->regex_str == rx && (*it)->name == name) {
cb21075d 90 scm_gc_unprotect_object((*it)->function);
91 scm_gc_unprotect_object (r);
92 (*it)->function = function;
93 (*it)->priority = pri;
94 (*it)->fallthru = fall;
be3612f3 95 hooksMap[hooktype].sort (hptr_lt);
cb21075d 96 return true;
97 }
98 // It does not exist, we create it
99 hooksMap[hooktype].push_back (new Hook(hooktype, rx, r,
fd7440f1 100 function, pri, fall, name));
be3612f3 101 hooksMap[hooktype].sort (hptr_lt);
cb21075d 102 return true;
103}
104
105bool
106BotInterp::RunHooks(int hooktype, String match, SCM args)
107{
108 SCM result;
ad529fde 109 // We want to execute higher priority hooks first, so we start at
110 // the end of the list instead of the beggining
111 std::list<Hook *>::reverse_iterator it = hooksMap[hooktype].rbegin();
112 std::list<Hook *>::reverse_iterator it2 = hooksMap[hooktype].rend();
cb21075d 113 wrapper_data wd;
114 wd.args = args;
115 for ( ; it != it2; ++it) {
a6339323 116 if (scm_regexp_exec((*it)->regex, Utils::str2scm (match),
cb21075d 117 SCM_UNDEFINED, SCM_UNDEFINED) != SCM_BOOL_F)
118 {
119 wd.func = (*it)->function;
d56bdd22 120 result = scm_internal_catch(SCM_BOOL_T,
ae97d6ec 121 (scm_t_catch_body)
122 Interp::LazyApplyWrapper,
d56bdd22 123 static_cast<void *> (&wd),
ae97d6ec 124 (scm_t_catch_handler) Interp::EmptyHandler, 0);
cb21075d 125 if (! (*it)->fallthru)
126 break;
127 }
128 }
129 return true;
130}
131
132SCM
133BotInterp::AddTimer(int delay, SCM function)
134{
135 int when = time(NULL) + delay;
136 int c = ++counter;
137 scm_gc_protect_object(function);
138 Timer *t = new Timer(c, when, function);
139 timersList.push_back(t);
46af1667 140 return scm_from_int (c);
cb21075d 141}
142
143bool
144BotInterp::DelTimer(SCM timer)
145{
46af1667 146 int count = scm_to_int (timer);
cb21075d 147 std::list<Timer *>::iterator it = timersList.begin();
148 std::list<Timer *>::iterator it2 = timersList.end();
149
150 for ( ; it != it2; ++it) {
151 if ((*it)->count == count) {
152 scm_gc_unprotect_object((*it)->function);
153 delete (*it);
154 timersList.erase(it);
155 return true;
156 }
157 }
158 return false;
159}
160
161bool
162BotInterp::RunTimers(int now)
163{
164 std::list<Timer *>::iterator it = timersList.begin();
165 std::list<Timer *>::iterator it2 = timersList.end();
166 std::list<Timer *>::iterator it3;
cf8ea873 167
cb21075d 168 struct wrapper_data wd;
46af1667 169 wd.args = scm_list_n (SCM_UNDEFINED);
cb21075d 170
171 while (it != it2) {
172 if ((*it)->when <= now) {
173 wd.func = (*it)->function;
d56bdd22 174 scm_internal_catch(SCM_BOOL_T,
ae97d6ec 175 (scm_t_catch_body) Interp::LazyApplyWrapper, (void *)&wd,
176 (scm_t_catch_handler) Interp::EmptyHandler, 0);
cb21075d 177 scm_gc_unprotect_object(wd.func);
178 it3 = it;
179 ++it3;
180 delete (*it);
181 timersList.erase(it);
182 it = it3;
183 } else {
184 ++it;
185 }
186 }
187 return true;
188}
189
190#endif