1 //////////////////////////////////////////////////////////////////////// 2 // 3 // Copyright (C) 2013-2021 The Octave Project Developers 4 // 5 // See the file COPYRIGHT.md in the top-level directory of this 6 // distribution or <https://octave.org/copyright/>. 7 // 8 // This file is part of Octave. 9 // 10 // Octave is free software: you can redistribute it and/or modify it 11 // under the terms of the GNU General Public License as published by 12 // the Free Software Foundation, either version 3 of the License, or 13 // (at your option) any later version. 14 // 15 // Octave is distributed in the hope that it will be useful, but 16 // WITHOUT ANY WARRANTY; without even the implied warranty of 17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 // GNU General Public License for more details. 19 // 20 // You should have received a copy of the GNU General Public License 21 // along with Octave; see the file COPYING. If not, see 22 // <https://www.gnu.org/licenses/>. 23 // 24 //////////////////////////////////////////////////////////////////////// 25 26 #if ! defined (octave_hook_fcn_h) 27 #define octave_hook_fcn_h 1 28 29 #include "octave-config.h" 30 31 #include <string> 32 33 #include "ovl.h" 34 #include "ov.h" 35 #include "ov-fcn-handle.h" 36 #include "variables.h" 37 38 class 39 base_hook_function 40 { 41 public: 42 43 friend class hook_function; 44 base_hook_function(void)45 base_hook_function (void) : count (1) { } 46 base_hook_function(const base_hook_function &)47 base_hook_function (const base_hook_function&) : count (1) { } 48 49 virtual ~base_hook_function (void) = default; 50 id(void)51 virtual std::string id (void) const { return ""; } 52 is_valid(void)53 virtual bool is_valid (void) const { return false; } 54 eval(const octave_value_list &)55 virtual void eval (const octave_value_list&) { } 56 57 protected: 58 59 std::size_t count; 60 }; 61 62 class 63 hook_function 64 { 65 public: 66 hook_function(void)67 hook_function (void) 68 { 69 static base_hook_function nil_rep; 70 rep = &nil_rep; 71 rep->count++; 72 } 73 74 hook_function (const octave_value& f, 75 const octave_value& d = octave_value ()); 76 ~hook_function(void)77 ~hook_function (void) 78 { 79 if (--rep->count == 0) 80 delete rep; 81 } 82 hook_function(const hook_function & hf)83 hook_function (const hook_function& hf) 84 : rep (hf.rep) 85 { 86 rep->count++; 87 } 88 89 hook_function& operator = (const hook_function& hf) 90 { 91 if (rep != hf.rep) 92 { 93 if (--rep->count == 0) 94 delete rep; 95 96 rep = hf.rep; 97 rep->count++; 98 } 99 100 return *this; 101 } 102 id(void)103 std::string id (void) const { return rep->id (); } 104 is_valid(void)105 bool is_valid (void) const { return rep->is_valid (); } 106 eval(const octave_value_list & initial_args)107 void eval (const octave_value_list& initial_args) 108 { 109 rep->eval (initial_args); 110 } 111 112 private: 113 114 base_hook_function *rep; 115 }; 116 117 class 118 named_hook_function : public base_hook_function 119 { 120 public: 121 named_hook_function(const std::string & n,const octave_value & d)122 named_hook_function (const std::string& n, const octave_value& d) 123 : name (n), data (d) 124 { } 125 126 void eval (const octave_value_list& initial_args); 127 id(void)128 std::string id (void) const { return name; } 129 is_valid(void)130 bool is_valid (void) const { return is_valid_function (name); } 131 132 private: 133 134 std::string name; 135 136 octave_value data; 137 }; 138 139 class 140 fcn_handle_hook_function : public base_hook_function 141 { 142 public: 143 fcn_handle_hook_function(const octave_value & fh_arg,const octave_value & d)144 fcn_handle_hook_function (const octave_value& fh_arg, const octave_value& d) 145 : ident (), valid (false), fcn_handle (fh_arg), data (d) 146 { 147 octave_fcn_handle *fh = fcn_handle.fcn_handle_value (true); 148 149 if (fh) 150 { 151 valid = true; 152 153 std::ostringstream buf; 154 buf << fh; 155 ident = fh->fcn_name () + ':' + buf.str (); 156 } 157 } 158 159 void eval (const octave_value_list& initial_args); 160 id(void)161 std::string id (void) const { return ident; } 162 is_valid(void)163 bool is_valid (void) const { return valid; } 164 165 private: 166 167 std::string ident; 168 169 bool valid; 170 171 octave_value fcn_handle; 172 173 octave_value data; 174 }; 175 176 class 177 hook_function_list 178 { 179 public: 180 181 typedef std::map<std::string, hook_function> map_type; 182 183 typedef map_type::iterator iterator; 184 typedef map_type::const_iterator const_iterator; 185 hook_function_list(void)186 hook_function_list (void) : fcn_map () { } 187 188 ~hook_function_list (void) = default; 189 hook_function_list(const hook_function_list & lst)190 hook_function_list (const hook_function_list& lst) 191 : fcn_map (lst.fcn_map) 192 { } 193 194 hook_function_list& operator = (const hook_function_list& lst) 195 { 196 if (&lst != this) 197 fcn_map = lst.fcn_map; 198 199 return *this; 200 } 201 empty(void)202 bool empty (void) const { return fcn_map.empty (); } 203 clear(void)204 void clear (void) { fcn_map.clear (); } 205 insert(const std::string & id,const hook_function & f)206 void insert (const std::string& id, const hook_function& f) 207 { 208 fcn_map[id] = f; 209 } 210 find(const std::string & id)211 iterator find (const std::string& id) 212 { 213 return fcn_map.find (id); 214 } 215 find(const std::string & id)216 const_iterator find (const std::string& id) const 217 { 218 return fcn_map.find (id); 219 } 220 end(void)221 iterator end (void) { return fcn_map.end (); } 222 end(void)223 const_iterator end (void) const { return fcn_map.end (); } 224 erase(iterator p)225 void erase (iterator p) { fcn_map.erase (p); } 226 227 void run (const octave_value_list& initial_args = octave_value_list ()) 228 { 229 auto p = fcn_map.begin (); 230 231 while (p != fcn_map.end ()) 232 { 233 std::string hook_fcn_id = p->first; 234 hook_function hook_fcn = p->second; 235 236 auto q = p++; 237 238 if (hook_fcn.is_valid ()) 239 hook_fcn.eval (initial_args); 240 else 241 fcn_map.erase (q); 242 } 243 } 244 245 private: 246 247 map_type fcn_map; 248 }; 249 250 #endif 251