Back to index

texmacs  1.0.7.15
list_observer.cpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : list_observer.cpp
00004 * DESCRIPTION: Attach several observers to trees
00005 * COPYRIGHT  : (C) 2005  Joris van der Hoeven
00006 *******************************************************************************
00007 * An inverse path observer maintains the inverse path of the position
00008 * of the corresponding tree with respect to the global meta-tree.
00009 *******************************************************************************
00010 * This software falls under the GNU general public license version 3 or later.
00011 * It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
00012 * in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
00013 ******************************************************************************/
00014 
00015 #include "modification.hpp"
00016 #include "blackbox.hpp"
00017 
00018 #define DETACHED (-5)
00019 
00020 /******************************************************************************
00021 * Definition of the list_observer_rep class
00022 ******************************************************************************/
00023 
00024 class list_observer_rep: public observer_rep {
00025   observer o1;
00026   observer o2;
00027 
00028 public:
00029   list_observer_rep (observer o1b, observer o2b): o1 (o1b), o2 (o2b) {}
00030   int get_type () { return OBSERVER_LIST; }
00031   tm_ostream& print (tm_ostream& out) {
00032     if (!is_nil (o1)) o1->print (out);
00033     if (!is_nil (o2)) o2->print (out);
00034     return out; }
00035 
00036   void announce (tree& ref, modification mod);
00037   void done     (tree& ref, modification mod);
00038   void touched  (tree& ref, path p);
00039 
00040   void notify_assign      (tree& ref, tree t);
00041   void notify_insert      (tree& ref, int pos, int nr);
00042   void notify_remove      (tree& ref, int pos, int nr);
00043   void notify_split       (tree& ref, int pos, tree prev);
00044   void notify_var_split   (tree& ref, tree t1, tree t2);
00045   void notify_join        (tree& ref, int pos, tree next);
00046   void notify_var_join    (tree& ref, tree t, int offset);
00047   void notify_assign_node (tree& ref, tree_label op);
00048   void notify_insert_node (tree& ref, int pos);
00049   void notify_remove_node (tree& ref, int pos);
00050   void notify_set_cursor  (tree& ref, int pos, tree data);
00051   void notify_detach      (tree& ref, tree closest, bool right);
00052 
00053   bool get_ip (path& ip);
00054   bool set_ip (path ip);
00055   bool get_position (tree& t, int& index);
00056   bool set_position (tree t, int index);
00057   observer& get_child (int which);
00058   list<observer> get_tree_pointers ();
00059   bool get_tree (tree& t);
00060   bool get_contents (int kind, blackbox& bb);
00061   bool set_highlight (int lan, int col, int start, int end);
00062   bool get_highlight (int lan, array<int>& cols);
00063 };
00064 
00065 /******************************************************************************
00066 * Call back routines for announcements
00067 ******************************************************************************/
00068 
00069 void
00070 list_observer_rep::announce (tree& ref, modification mod) {
00071   if (!is_nil (o1)) o1->announce (ref, mod);
00072   if (!is_nil (o2)) o2->announce (ref, mod);
00073 }
00074 
00075 void
00076 list_observer_rep::done (tree& ref, modification mod) {
00077   if (!is_nil (o1)) o1->done (ref, mod);
00078   if (!is_nil (o2)) o2->done (ref, mod);
00079 }
00080 
00081 void
00082 list_observer_rep::touched (tree& ref, path p) {
00083   if (!is_nil (o1)) o1->touched (ref, p);
00084   if (!is_nil (o2)) o2->touched (ref, p);
00085 }
00086 
00087 /******************************************************************************
00088 * Call back routines for modifications
00089 ******************************************************************************/
00090 
00091 void
00092 list_observer_rep::notify_assign (tree& ref, tree t) {
00093   if (!is_nil (o1)) o1->notify_assign (ref, t);
00094   if (!is_nil (o2)) o2->notify_assign (ref, t);
00095 }
00096 
00097 void
00098 list_observer_rep::notify_insert (tree& ref, int pos, int nr) {
00099   if (!is_nil (o1)) o1->notify_insert (ref, pos, nr);
00100   if (!is_nil (o2)) o2->notify_insert (ref, pos, nr);
00101 }
00102 
00103 void
00104 list_observer_rep::notify_remove (tree& ref, int pos, int nr) {
00105   if (!is_nil (o1)) o1->notify_remove (ref, pos, nr);
00106   if (!is_nil (o2)) o2->notify_remove (ref, pos, nr);
00107 }
00108 
00109 void
00110 list_observer_rep::notify_split (tree& ref, int pos, tree prev) {
00111   if (!is_nil (o1)) o1->notify_split (ref, pos, prev);
00112   if (!is_nil (o2)) o2->notify_split (ref, pos, prev);
00113 }
00114 
00115 void
00116 list_observer_rep::notify_var_split (tree& ref, tree t1, tree t2) {
00117   if (!is_nil (o1)) o1->notify_var_split (ref, t1, t2);
00118   if (!is_nil (o2)) o2->notify_var_split (ref, t1, t2);
00119 }
00120 
00121 void
00122 list_observer_rep::notify_join (tree& ref, int pos, tree next) {
00123   if (!is_nil (o1)) o1->notify_join (ref, pos, next);
00124   if (!is_nil (o2)) o2->notify_join (ref, pos, next);
00125 }
00126 
00127 void
00128 list_observer_rep::notify_var_join (tree& ref, tree t, int offset) {
00129   if (!is_nil (o1)) o1->notify_var_join (ref, t, offset);
00130   if (!is_nil (o2)) o2->notify_var_join (ref, t, offset);
00131 }
00132 
00133 void
00134 list_observer_rep::notify_assign_node (tree& ref, tree_label op) {
00135   if (!is_nil (o1)) o1->notify_assign_node (ref, op);
00136   if (!is_nil (o2)) o2->notify_assign_node (ref, op);
00137 }
00138 
00139 void
00140 list_observer_rep::notify_insert_node (tree& ref, int pos) {
00141   if (!is_nil (o1)) o1->notify_insert_node (ref, pos);
00142   if (!is_nil (o2)) o2->notify_insert_node (ref, pos);
00143 }
00144 
00145 void
00146 list_observer_rep::notify_remove_node (tree& ref, int pos) {
00147   if (!is_nil (o1)) o1->notify_remove_node (ref, pos);
00148   if (!is_nil (o2)) o2->notify_remove_node (ref, pos);
00149 }
00150 
00151 void
00152 list_observer_rep::notify_set_cursor (tree& ref, int pos, tree data) {
00153   if (!is_nil (o1)) o1->notify_set_cursor (ref, pos, data);
00154   if (!is_nil (o2)) o2->notify_set_cursor (ref, pos, data);
00155 }
00156 
00157 void
00158 list_observer_rep::notify_detach (tree& ref, tree closest, bool right) {
00159   if (!is_nil (o1)) o1->notify_detach (ref, closest, right);
00160   if (!is_nil (o2)) o2->notify_detach (ref, closest, right);
00161 }
00162 
00163 /******************************************************************************
00164 * Further methods for special types of observers
00165 ******************************************************************************/
00166 
00167 bool
00168 list_observer_rep::get_ip (path& ip) {
00169   return (!is_nil (o1) && o1->get_ip (ip)) |
00170          (!is_nil (o2) && o2->get_ip (ip));
00171 }
00172 
00173 bool
00174 list_observer_rep::set_ip (path ip) {
00175   return (!is_nil (o1) && o1->set_ip (ip)) |
00176          (!is_nil (o2) && o2->set_ip (ip));
00177 }
00178 
00179 bool
00180 list_observer_rep::get_position (tree& t, int& index) {
00181   return (!is_nil (o1) && o1->get_position (t, index)) |
00182          (!is_nil (o2) && o2->get_position (t, index));
00183 }
00184 
00185 bool
00186 list_observer_rep::set_position (tree t, int index) {
00187   return (!is_nil (o1) && o1->set_position (t, index)) |
00188          (!is_nil (o2) && o2->set_position (t, index));
00189 }
00190 
00191 observer&
00192 list_observer_rep::get_child (int which) {
00193   if (which == 0) return o1;
00194   else return o2;
00195 }
00196 
00197 list<observer>
00198 list_observer_rep::get_tree_pointers () {
00199   list<observer> l;
00200   if (!is_nil (o1)) l= l * o1->get_tree_pointers ();
00201   if (!is_nil (o2)) l= l * o2->get_tree_pointers ();
00202   return l;
00203 }
00204 
00205 bool
00206 list_observer_rep::get_tree (tree& t) {
00207   return (!is_nil (o1) && o1->get_tree (t)) |
00208          (!is_nil (o2) && o2->get_tree (t));
00209 }
00210 
00211 bool
00212 list_observer_rep::get_contents (int kind, blackbox& bb) {
00213   return (!is_nil (o1) && o1->get_contents (kind, bb)) |
00214          (!is_nil (o2) && o2->get_contents (kind, bb));
00215 }
00216 
00217 bool
00218 list_observer_rep::set_highlight (int lan, int col, int start, int end) {
00219   return (!is_nil (o1) && o1->set_highlight (lan, col, start, end)) |
00220          (!is_nil (o2) && o2->set_highlight (lan, col, start, end));
00221 }
00222 
00223 bool
00224 list_observer_rep::get_highlight (int lan, array<int>& cols) {
00225   return (!is_nil (o1) && o1->get_highlight (lan, cols)) |
00226          (!is_nil (o2) && o2->get_highlight (lan, cols));
00227 }
00228 
00229 /******************************************************************************
00230 * Creation of list observers
00231 ******************************************************************************/
00232 
00233 observer
00234 list_observer (observer o1, observer o2) {
00235   if (is_nil (o1)) return o2;
00236   if (is_nil (o2)) return o1;
00237   return tm_new<list_observer_rep> (o1, o2);
00238 }
00239 
00240 void
00241 insert_observer (observer& o, observer what) {
00242   o= list_observer (o, what);
00243 }
00244 
00245 void
00246 remove_observer (observer& o, observer what) {
00247   if (is_nil (o)) return;
00248   else if (o == what) o= nil_observer;
00249   else {
00250     remove_observer (o->get_child (0), what);
00251     remove_observer (o->get_child (1), what);
00252   }
00253 }
00254 
00255 void
00256 clean_observers (observer& o) {
00257   if (is_nil (o)) return;
00258   if (o->get_type () == OBSERVER_IP) return;
00259   if (o->get_type () == OBSERVER_LIST) {
00260     clean_observers (o->get_child (0));
00261     clean_observers (o->get_child (1));
00262     if (is_nil (o->get_child (0))) o= o->get_child (1);
00263     else if (is_nil (o->get_child (1))) o= o->get_child (0);
00264   }
00265   else o= nil_observer;
00266 }
00267 
00268 void
00269 attach_observer (tree& ref, observer o) {
00270   insert_observer (ref->obs, o);
00271 }
00272 
00273 void
00274 detach_observer (tree& ref, observer o) {
00275   remove_observer (ref->obs, o);
00276 }
00277 
00278 void
00279 clean_observers (tree& ref) {
00280   clean_observers (ref->obs);
00281 }