Menu

[13a134]: / src / ui_tcltk.h  Maximize  Restore  History

Download this file

248 lines (208 with data), 8.2 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
/*
# Copyright (C) 2015 Fulvio Benini
* This file is part of Scid (Shane's Chess Information Database).
*
* Scid is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation.
*
* Scid is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Scid. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef SCID_UI_TCLTK_H
#define SCID_UI_TCLTK_H
#include "timer.h"
#include <tcl.h>
#include <sstream>
#include <limits>
namespace UI_impl {
typedef int UI_res_t;
typedef ClientData UI_extra_t;
typedef Tcl_Interp* UI_handle_t;
inline int initTclTk (UI_handle_t ti);
inline int Main (int argc, char* argv[], void (*exit) (void*)) {
Tcl_FindExecutable(argv[0]);
Tcl_CreateExitHandler(exit, 0);
bool search_tcl = (argc == 1) ? true : false;
if (argc > 1 && argc < 10) {
char* ext = strrchr (argv[1], '.');
if (ext != 0 && strlen(ext) == 4 && std::string(".tcl") != ext) {
search_tcl = true;
}
}
if (search_tcl) {
char sourceFileName [1024] = {0};
strncpy(sourceFileName, Tcl_GetNameOfExecutable(), 1000);
char* dirname = strrchr(sourceFileName, '/');
if (dirname == 0) dirname = sourceFileName;
else dirname += 1;
strcpy (dirname, "tcl/start.tcl");
if (0 != Tcl_Access(sourceFileName, 4)) {
strcpy (dirname, "../tcl/start.tcl");
}
char* newArgv[10] = { argv[0], sourceFileName };
std::copy(argv + 1, argv + argc, newArgv + 2);
Tcl_Main(argc + 1, newArgv, UI_impl::initTclTk);
} else {
Tcl_Main (argc, argv, UI_impl::initTclTk);
}
return 0;
}
class tcl_Progress : public ProgressImp {
UI_handle_t ti_;
Timer timer_;
public:
tcl_Progress(UI_handle_t ti) : ti_(ti) {}
virtual ~tcl_Progress() {}
virtual bool report(uint done, uint total) {
uint64_t elapsed = timer_.MilliSecs();
uint64_t estimated = (done == 0) ? 0 : elapsed * total / done;
std::ostringstream tmp;
tmp << "::progressCallBack";
tmp << " " << done << " " << total << " " << elapsed / 1000 << " " << estimated / 1000;
return TCL_OK == Tcl_EvalEx(ti_, tmp.str().c_str(), -1, 0);
}
};
class tcl_ProgressPosMask : public ProgressImp {
UI_handle_t ti_;
public:
tcl_ProgressPosMask(UI_handle_t ti) : ti_(ti) {}
virtual ~tcl_ProgressPosMask() {}
virtual bool report(uint done, uint total) {
return TCL_OK == Tcl_EvalEx(ti_, "::windows::gamelist::PosMaskProgress", -1, 0);
}
};
inline Progress CreateProgress(UI_handle_t data) {
int err = Tcl_EvalEx(data, "::progressCallBack init", -1, 0);
if (err != TCL_OK) return Progress();
return Progress(new UI_impl::tcl_Progress(data));
}
inline Progress CreateProgressPosMask(UI_handle_t data) {
return Progress(new UI_impl::tcl_ProgressPosMask(data));
}
class List {
Tcl_Obj** list_;
int i_;
Tcl_Obj* stackBuf_[6];
friend Tcl_Obj* ObjMaker(const List&);
public:
explicit List(size_t max_size)
: list_(stackBuf_), i_(0) {
const size_t stackBuf_size = sizeof(stackBuf_)/sizeof(stackBuf_[0]);
if (max_size > stackBuf_size) {
list_ = new Tcl_Obj*[max_size];
}
}
~List() {
clear();
if (list_ != stackBuf_) delete [] list_;
}
void clear() {
for (int i=0; i < i_; i++) Tcl_DecrRefCount(list_[i]);
i_ = 0;
}
void push_back(Tcl_Obj* value) {
ASSERT(value != 0);
list_[i_++] = value;
}
template <typename T>
void push_back(const T& value);
};
inline Tcl_Obj* ObjMaker(bool v) {
return Tcl_NewBooleanObj(v);
}
inline Tcl_Obj* ObjMaker(int v) {
return Tcl_NewIntObj(v);
}
inline Tcl_Obj* ObjMaker(unsigned int v) {
ASSERT(v <= static_cast<unsigned int>(std::numeric_limits<int>::max()));
return Tcl_NewIntObj(static_cast<int>(v));
}
inline Tcl_Obj* ObjMaker(unsigned long v) {
ASSERT(v <= static_cast<unsigned long>(std::numeric_limits<int>::max()));
return Tcl_NewIntObj(static_cast<int>(v));
}
#ifdef CPP11_SUPPORT
inline Tcl_Obj* ObjMaker(unsigned long long v) {
ASSERT(v <= static_cast<unsigned long long>(std::numeric_limits<int>::max()));
return Tcl_NewIntObj(static_cast<int>(v));
}
#endif
inline Tcl_Obj* ObjMaker(double v) {
return Tcl_NewDoubleObj(v);
}
inline Tcl_Obj* ObjMaker(const char* s) {
return Tcl_NewStringObj(s, -1);
}
inline Tcl_Obj* ObjMaker(const std::string& s) {
return Tcl_NewStringObj(s.c_str(), s.length());
}
inline Tcl_Obj* ObjMaker(const List& v) {
Tcl_Obj* res = Tcl_NewListObj(v.i_, v.list_);
const_cast<List&>(v).i_ = 0;
return res;
}
template <typename T>
inline void List::push_back(const T& value) {
push_back(ObjMaker(value));
}
inline UI_res_t ResultHelper(UI_handle_t ti, errorT res) {
if (res == OK) return TCL_OK;
Tcl_SetObjErrorCode(ti, Tcl_NewIntObj(res));
return TCL_ERROR;
}
inline UI_res_t Result(UI_handle_t ti, errorT res) {
Tcl_ResetResult(ti);
return UI_impl::ResultHelper(ti, res);
}
template <typename T>
inline UI_res_t Result(UI_handle_t ti, errorT res, const T& value) {
Tcl_SetObjResult(ti, UI_impl::ObjMaker(value));
return UI_impl::ResultHelper(ti, res);
}
} //End of UI_impl namespace
//TODO:
//Duplicate declarations (already in ui.h)
UI_impl::UI_res_t str_is_prefix (UI_impl::UI_extra_t, UI_impl::UI_handle_t, int argc, const char ** argv);
UI_impl::UI_res_t str_prefix_len (UI_impl::UI_extra_t, UI_impl::UI_handle_t, int argc, const char ** argv);
UI_impl::UI_res_t sc_base (UI_impl::UI_extra_t, UI_impl::UI_handle_t, int argc, const char ** argv);
UI_impl::UI_res_t sc_book (UI_impl::UI_extra_t, UI_impl::UI_handle_t, int argc, const char ** argv);
UI_impl::UI_res_t sc_clipbase (UI_impl::UI_extra_t, UI_impl::UI_handle_t, int argc, const char ** argv);
UI_impl::UI_res_t sc_eco (UI_impl::UI_extra_t, UI_impl::UI_handle_t, int argc, const char ** argv);
UI_impl::UI_res_t sc_filter (UI_impl::UI_extra_t, UI_impl::UI_handle_t, int argc, const char ** argv);
UI_impl::UI_res_t sc_game (UI_impl::UI_extra_t, UI_impl::UI_handle_t, int argc, const char ** argv);
UI_impl::UI_res_t sc_info (UI_impl::UI_extra_t, UI_impl::UI_handle_t, int argc, const char ** argv);
UI_impl::UI_res_t sc_move (UI_impl::UI_extra_t, UI_impl::UI_handle_t, int argc, const char ** argv);
UI_impl::UI_res_t sc_name (UI_impl::UI_extra_t, UI_impl::UI_handle_t, int argc, const char ** argv);
UI_impl::UI_res_t sc_report (UI_impl::UI_extra_t, UI_impl::UI_handle_t, int argc, const char ** argv);
UI_impl::UI_res_t sc_pos (UI_impl::UI_extra_t, UI_impl::UI_handle_t, int argc, const char ** argv);
UI_impl::UI_res_t sc_search (UI_impl::UI_extra_t, UI_impl::UI_handle_t, int argc, const char ** argv);
UI_impl::UI_res_t sc_tree (UI_impl::UI_extra_t, UI_impl::UI_handle_t, int argc, const char ** argv);
UI_impl::UI_res_t sc_var (UI_impl::UI_extra_t, UI_impl::UI_handle_t, int argc, const char ** argv);
inline int UI_impl::initTclTk (UI_handle_t ti)
{
if (Tcl_Init (ti) == TCL_ERROR) { return TCL_ERROR; }
Tcl_CreateCommand(ti, "strIsPrefix" , str_is_prefix , 0, NULL);
Tcl_CreateCommand(ti, "strPrefixLen", str_prefix_len, 0, NULL);
Tcl_CreateCommand(ti, "sc_base" , sc_base , 0, NULL);
Tcl_CreateCommand(ti, "sc_book" , sc_book , 0, NULL);
Tcl_CreateCommand(ti, "sc_clipbase" , sc_clipbase , 0, NULL);
Tcl_CreateCommand(ti, "sc_eco" , sc_eco , 0, NULL);
Tcl_CreateCommand(ti, "sc_filter" , sc_filter , 0, NULL);
Tcl_CreateCommand(ti, "sc_game" , sc_game , 0, NULL);
Tcl_CreateCommand(ti, "sc_info" , sc_info , 0, NULL);
Tcl_CreateCommand(ti, "sc_move" , sc_move , 0, NULL);
Tcl_CreateCommand(ti, "sc_name" , sc_name , 0, NULL);
Tcl_CreateCommand(ti, "sc_report" , sc_report , 0, NULL);
Tcl_CreateCommand(ti, "sc_pos" , sc_pos , 0, NULL);
Tcl_CreateCommand(ti, "sc_search" , sc_search , 0, NULL);
Tcl_CreateCommand(ti, "sc_tree" , sc_tree , 0, NULL);
Tcl_CreateCommand(ti, "sc_var" , sc_var , 0, NULL);
return TCL_OK;
}
#endif