Minsky
minskyTCLObj.h
Go to the documentation of this file.
1 /*
2  @copyright Steve Keen 2016
3  @author Russell Standish
4  This file is part of Minsky.
5 
6  Minsky is free software: you can redistribute it and/or modify it
7  under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  Minsky is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with Minsky. If not, see <http://www.gnu.org/licenses/>.
18 */
19 
22 
23 // Lazy instantiated pattern to avoid the indeterminate initialisation
24 // ordering problem of C++ (See Stroustrup 4th edition ยง15.4.1)
25 
26 #ifndef MINSKYTCLOBJ_H
27 #define MINSKYTCLOBJ_H
28 #include "minskyTCL.h"
29 #include <string>
30 
31 namespace minsky
32 {
33  inline string to_string(CONST84 char* x) {return x;}
34  inline string to_string(Tcl_Obj* x) {return Tcl_GetString(x);}
35 
36  // a hook for recording when the minsky model's state changes
37  template <class AV>
38  void member_entry_hook(int argc, AV argv)
39  {
40  string argv0=to_string(argv[0]);
41  MinskyTCL& m=static_cast<MinskyTCL&>(minsky());
42  if (argv0.find("godleyWindow")==0)
43  {
44  if (argv0.find(".undo")!=std::string::npos) return; // do not record undo in history
45  if (argv0.find(".keyRelease")!=std::string::npos) return;
46  // support undo/redo in a Godley edit window
47  auto i=argv0.find('.');
48  if (i==std::string::npos) i=argv0.length();
49  auto t=dynamic_cast<member_entry_base*>(getCommandData(argv0.substr(0,i)));
50  if (!t || (!t->is_const && (!t->is_setterGetter || argc>1)))
51  if (auto gtw=t->memberPtrCasted<GodleyTableWindow>())
52  gtw->pushHistory();
53  return;
54  }
55 
56  if (m.commandHook(argv0,argc-1) && m.eventRecord.get() && argv0!="minsky.startRecording")
57  {
58  for (int i=0; i<argc; ++i)
59  (*m.eventRecord) << "{"<<to_string(argv[i]) <<"} ";
60  (*m.eventRecord)<<endl;
61  }
62 
63  if (m.rebuildTCLcommands)
64  {
65  TCL_obj(minskyTCL_obj(), "minsky", m);
66  m.rebuildTCLcommands=false;
67  }
68  }
69 
70  inline TCL_obj_t& minskyTCL_obj()
71  {
72  static TCL_obj_t t;
73  static int dum=(
74  t.member_entry_hook=member_entry_hook<CONST84 char**>,
75  t.member_entry_thook=member_entry_hook<Tcl_Obj* const *>,
76  1);
77  return t;
78  }
79 
80 }
81 
82 #endif
std::unique_ptr< std::ostream > eventRecord
Definition: minskyTCL.h:50
bool pushHistory()
push current model state onto history if it differs from previous
Definition: minsky.cc:1265
bool commandHook(const std::string &command, unsigned nargs)
Executed after each interpreter command to maintain undo/redo stack, edited flag, autosaving etc...
Definition: minsky.cc:1326
Creation and access to the minskyTCL_obj object, which has code to record whenever Minsky&#39;s state cha...
Definition: constMap.h:22
void member_entry_hook(int argc, AV argv)
Definition: minskyTCLObj.h:38
bool rebuildTCLcommands
Definition: minskyTCL.h:45
ecolab::TCL_obj_t & minskyTCL_obj()
a TCL_obj_t that provides a hook for detecting model edits
Definition: minskyTCLObj.h:70
cmd_data * getCommandData(const string &name)
Definition: minskyTCL.cc:62
string to_string(CONST84 char *x)
Definition: minskyTCLObj.h:33
Minsky & minsky()
global minsky object
Definition: minskyTCL.cc:51