1 
2 /*
3 A* -------------------------------------------------------------------
4 B* This file contains source code for the PyMOL computer program
5 C* copyright 1998-2000 by Warren Lyford Delano of DeLano Scientific.
6 D* -------------------------------------------------------------------
7 E* It is unlawful to modify or remove this copyright notice.
8 F* -------------------------------------------------------------------
9 G* Please see the accompanying LICENSE file for further information.
10 H* -------------------------------------------------------------------
11 I* Additional authors of this source file include:
12 -*
13 -*
14 -*
15 Z* -------------------------------------------------------------------
16 */
17 #ifndef _H_Setting
18 #define _H_Setting
19 
20 #include <vector>
21 #include <string>
22 
23 #include"os_python.h"
24 #include"PyMOLGlobals.h"
25 #include"OVOneToOne.h"
26 
27 typedef char SettingName[255];
28 
29 /*
30  * Setting record for atom/astate/bond/bstate level settings
31  */
32 typedef struct {
33   int setting_id;
34   union {
35     int int_;
36     float float_;
37     float float3_[3];
38   } value;
39   int next;                     /* for per-atom setting lists & memory management */
40 } SettingUniqueEntry;
41 
42 struct _CSettingUnique {
43   OVOneToOne *id2offset;
44   OVOneToOne *old2new;
45   SettingUniqueEntry *entry;
46   int n_alloc, next_free;
47 };
48 
49 /*
50  * Setting record for global/object/ostate level settings
51  */
52 struct SettingRec {
53   union {
54     int int_;
55     float float_;
56     float float3_[3];
57     std::string * str_;
58   };
59 
60   bool defined;
61   bool changed;
62 
63 private:
setChangedSettingRec64   void setChanged() {
65     defined = true;
66     changed = true;
67   }
68 
69 public:
set_iSettingRec70   void set_i(int value) {
71     int_ = value;
72     setChanged();
73   }
74 
set_fSettingRec75   void set_f(float value) {
76     float_ = value;
77     setChanged();
78   }
79 
set_3fSettingRec80   void set_3f(float v0, float v1, float v2) {
81     float3_[0] = v0;
82     float3_[1] = v1;
83     float3_[2] = v2;
84     setChanged();
85   }
86 
set_3fSettingRec87   void set_3f(const float * value) {
88     set_3f(value[0], value[1], value[2]);
89   }
90 
set_sSettingRec91   void set_s(const char * value) {
92     if (!str_) {
93       str_ = new std::string(value);
94     } else {
95       str_->assign(value);
96     }
97     setChanged();
98   }
99 
delete_sSettingRec100   void delete_s() {
101     if (str_) {
102       delete str_;
103       str_ = NULL;
104     }
105   }
106 };
107 
108 struct _CSetting {
109   PyMOLGlobals *G;
110   ov_size size;
111   SettingRec *info;
112 };
113 
114 #define cSetting_tuple      -1 // for get_setting_tuple
115 #define cSetting_blank       0
116 #define cSetting_boolean     1
117 #define cSetting_int         2
118 #define cSetting_float       3
119 #define cSetting_float3      4
120 #define cSetting_color       5
121 #define cSetting_string      6
122 
123 
124 /* Atomic Settings */
125 
126 void SettingUniqueDetachChain(PyMOLGlobals * G, int index);
127 
128 /* New API
129  * NOTE: get commands are not range-checked, so be careful
130  * in contrast, set commands expand the current list
131  */
132 
133 int SettingUniqueSetTypedValue(PyMOLGlobals * G, int unique_id, int setting_id,
134 			       int setting_type, const void *value);
135 
136 /*
137  * bool overload
138  */
139 inline
SettingUniqueSetTypedValue(PyMOLGlobals * G,int unique_id,int setting_id,int setting_type,const bool * value)140 int SettingUniqueSetTypedValue(PyMOLGlobals * G, int unique_id, int setting_id,
141 			       int setting_type, const bool *value) {
142   int i = *value;
143   return SettingUniqueSetTypedValue(G, unique_id, setting_id, setting_type, &i);
144 }
145 
146 bool SettingUniqueUnset(PyMOLGlobals * G, int unique_id, int setting_id);
147 
148 #ifndef _PYMOL_NOPY
149 bool SettingUniqueSetPyObject(PyMOLGlobals * G, int unique_id, int setting_id, PyObject *value);
150 #endif
151 
152 int SettingUniqueCheck(PyMOLGlobals * G, int unique_id, int setting_id);
153 PyObject *SettingUniqueGetPyObject(PyMOLGlobals * G, int unique_id, int index);
154 
155 void SettingUniqueResetAll(PyMOLGlobals * G);
156 PyObject *SettingUniqueAsPyList(PyMOLGlobals * G);
157 int SettingUniqueFromPyList(PyMOLGlobals * G, PyObject * list, int partial_restore);
158 int SettingUniqueConvertOldSessionID(PyMOLGlobals * G, int old_unique_id);
159 
160 int SettingUniqueCopyAll(PyMOLGlobals * G, int src_unique_id, int dst_unique_id);
161 void SettingInitGlobal(PyMOLGlobals * G, int alloc, int reset_gui, int use_default);
162 void SettingStoreDefault(PyMOLGlobals * G);
163 void SettingPurgeDefault(PyMOLGlobals * G);
164 
165 void SettingFreeGlobal(PyMOLGlobals * G);
166 
167 CSetting *SettingNew(PyMOLGlobals * G);
168 void SettingFreeP(CSetting * I);
169 void SettingInit(PyMOLGlobals * G, CSetting * I);
170 void SettingPurge(CSetting * I);
171 void SettingCheckHandle(PyMOLGlobals * G, CSetting ** handle);
172 
173 #define SettingSet_b SettingSet_i
174 int SettingSet_i(CSetting * I, int index, int value);
175 int SettingSet_f(CSetting * I, int index, float value);
176 int SettingSet_s(CSetting * I, int index, const char *value);
177 int SettingSet_3fv(CSetting * I, int index, const float *value);
178 
179 int SettingGetTextValue(PyMOLGlobals * G, const CSetting * set1, const CSetting * set2, int index,
180                         char *buffer);
181 const char * SettingGetTextPtr(PyMOLGlobals * G, const CSetting * set1, const CSetting * set2,
182                                int index, char *buffer);
183 
184 int SettingUnset(CSetting * I, int index);
185 
186 void SettingRestoreDefault(CSetting * I, int index, const CSetting * src=NULL);
187 
188 bool SettingIsDefaultZero(int index);
189 
190 int SettingGetType(int index);
SettingGetType(PyMOLGlobals *,int index)191 inline int SettingGetType(PyMOLGlobals *, int index) {
192   return SettingGetType(index);
193 }
194 
195 template <typename V> inline int SettingGetType();
196 template <> inline int SettingGetType<bool>()           { return cSetting_boolean; }
197 template <> inline int SettingGetType<int>()            { return cSetting_int; }
198 template <> inline int SettingGetType<float>()          { return cSetting_float; }
199 template <> inline int SettingGetType<const float*>()   { return cSetting_float3; }
200 template <> inline int SettingGetType<float*>()         { return cSetting_float3; }
201 template <> inline int SettingGetType<const char*>()    { return cSetting_string; }
202 template <> inline int SettingGetType<char*>()          { return cSetting_string; }
203 
204 #define SettingSetGlobal_b SettingSet<bool>
205 #define SettingSetGlobal_i SettingSet<int>
206 #define SettingSetGlobal_s SettingSet<const char *>
207 #define SettingSetGlobal_f SettingSet<float>
208 
209 int SettingSetSmart_i(PyMOLGlobals * G, CSetting * set1, CSetting * set2, int index,
210                       int value);
211 
212 int SettingSet_color(CSetting * I, int index, const char *value);
213 
214 int SettingSetFromString(PyMOLGlobals * G, CSetting * I, int index, const char *st);
215 int SettingStringToTypedValue(PyMOLGlobals * G, int index, const char *st, int *type,
216                               int *value);
217 
218 #ifndef _PYMOL_NOPY
219 int SettingSetFromTuple(PyMOLGlobals * G, CSetting * I, int index, PyObject * tuple);
220 PyObject *SettingGetPyObject(PyMOLGlobals * G, const CSetting * set1, const CSetting * set2, int index);
221 PyObject *SettingGetTuple(PyMOLGlobals * G, const CSetting * set1, const CSetting * set2, int index);       /* (type,(value,)) */
222 PyObject *SettingGetSettingIndices();
223 PyObject *SettingUniqueGetIndicesAsPyList(PyMOLGlobals * G, int unique_id);
224 #endif
225 
226 std::vector<int> SettingGetUpdateList(PyMOLGlobals * G, const char * name="", int state=0);
227 
228 void SettingGenerateSideEffects(PyMOLGlobals * G, int index, const char *sele, int state, int quiet);
229 
230 int SettingGetIndex(PyMOLGlobals * G, const char *name);
231 int SettingGetName(PyMOLGlobals * G, int index, SettingName name);
232 const char * SettingGetName(int index);
233 
234 PyObject *SettingAsPyList(CSetting * I, bool incl_blacklisted=false);
235 int SettingFromPyList(CSetting * I, PyObject * list);
236 
237 int SettingSetGlobalsFromPyList(PyMOLGlobals * G, PyObject * list);
238 PyObject *SettingGetGlobalsAsPyList(PyMOLGlobals * G);
239 
240 
241 CSetting *SettingNewFromPyList(PyMOLGlobals * G, PyObject * list);
242 
243 int SettingCheckFontID(PyMOLGlobals * G, CSetting * set1, CSetting * set2, int font_id);
244 
245 // The following defines the enum with all cSetting_<settingname> indices
246 #include "SettingInfo.h"
247 
248 #define cStereo_default              0  /* stereo_mode=0 only used for startup */
249 #define cStereo_quadbuffer           1
250 #define cStereo_crosseye             2
251 #define cStereo_walleye              3
252 #define cStereo_geowall              4
253 #define cStereo_sidebyside           5
254 #define cStereo_stencil_by_row       6
255 #define cStereo_stencil_by_column    7
256 #define cStereo_stencil_checkerboard 8
257 #define cStereo_stencil_custom       9  /* for hardware developers to use */
258 #define cStereo_anaglyph            10
259 #define cStereo_dynamic             11  /* dynamic polarization */
260 #define cStereo_clone_dynamic       12
261 #define cStereo_openvr              13
262 
263 /*
264  * State index iterator which iterates either over a single state (state >= 0),
265  * the current state (state == -2), or all states (state == -1). Takes
266  * static singletons into account. Zero iterations if state >= nstate.
267  *
268  * StateIterator iter(G, I->Setting, state, I->NState);
269  * while(iter.next()) {
270  *   printf("in state %d\n", iter.state);
271  * }
272  */
273 class StateIterator {
274   int end;
275 
276 public:
277   int state;
278 
279   StateIterator(PyMOLGlobals * G, CSetting * set, int state_, int nstate);
280   StateIterator(struct CObject* obj, int state_);
281 
next()282   bool next() {
283     return (++state < end);
284   };
285 };
286 
287 /*
288  * Setting levels (global, object, ...)
289  */
290 
291 enum {
292   cSettingLevel_unused = 0,
293   cSettingLevel_global,
294   cSettingLevel_object,
295   cSettingLevel_ostate,
296   cSettingLevel_atom,
297   cSettingLevel_astate,
298   cSettingLevel_bond,
299   cSettingLevel_bstate
300 };
301 
302 // Setting level info table
303 extern const struct SettingLevelInfoType {
304   // name of this level, for feedback
305   const char * name;
306   // bitmask of valid (sub-)levels
307   unsigned char mask;
308 } SettingLevelInfo[];
309 
310 const char * SettingLevelGetName(PyMOLGlobals * G, int index);
311 bool SettingLevelCheckMask(PyMOLGlobals * G, int index, unsigned char mask);
312 bool SettingLevelCheck(PyMOLGlobals * G, int index, unsigned char level);
313 
314 bool CPyMOLInitSetting(OVLexicon * Lex, OVOneToOne * Setting);
315 extern "C" OVreturn_word get_setting_id(CPyMOL * I, const char *setting);
316 
317 /*
318  * Overloaded setters for templatted programming
319  */
320 
SettingSet(CSetting * s,int i,bool v)321 inline void SettingSet(CSetting * s, int i, bool v)         { SettingSet_b(s, i, v); }
SettingSet(CSetting * s,int i,int v)322 inline void SettingSet(CSetting * s, int i, int v)          { SettingSet_i(s, i, v); }
SettingSet(CSetting * s,int i,long int v)323 inline void SettingSet(CSetting * s, int i, long int v)     { SettingSet_i(s, i, v); }
SettingSet(CSetting * s,int i,float v)324 inline void SettingSet(CSetting * s, int i, float v)        { SettingSet_f(s, i, v); }
SettingSet(CSetting * s,int i,const char * v)325 inline void SettingSet(CSetting * s, int i, const char *v)  { SettingSet_s(s, i, v); }
SettingSet(CSetting * s,int i,const float * v)326 inline void SettingSet(CSetting * s, int i, const float *v) { SettingSet_3fv(s, i, v); }
327 
328 template <typename V>
SettingUniqueSet(PyMOLGlobals * G,int uid,int index,V value)329 void SettingUniqueSet(PyMOLGlobals * G, int uid, int index, V value) {
330   SettingUniqueSetTypedValue(G, uid, index, SettingGetType<V>(), &value);
331 }
332 
SettingSet(PyMOLGlobals * G,CSetting ** handle,int index,V value)333 template <typename V> void SettingSet(PyMOLGlobals * G, CSetting ** handle, int index, V value) {
334   SettingCheckHandle(G, handle);
335   SettingSet(*handle, index, value);
336 }
337 
338 // global setting
SettingSet(PyMOLGlobals * G,int index,V value)339 template <typename V> bool SettingSet(PyMOLGlobals * G, int index, V value) {
340   SettingSet(G->Setting, index, value);
341   return true;
342 }
343 
344 // light setting array
345 extern int light_setting_indices[];
346 
347 /*
348  * Getters for templatted programming
349  */
350 
351 const CSetting * _SettingGetFirstDefined(int index,
352     PyMOLGlobals * G,
353     const CSetting * set1,
354     const CSetting * set2);
355 
356 template <typename V> V SettingGet(int index, const CSetting *);
SettingGet(PyMOLGlobals * G,const CSetting * set1,const CSetting * set2,int index)357 template <typename V> V SettingGet(PyMOLGlobals * G,
358     const CSetting * set1,
359     const CSetting * set2, int index) {
360   return SettingGet<V>(index, _SettingGetFirstDefined(index, G, set1, set2));
361 }
SettingGet(PyMOLGlobals * G,int index)362 template <typename V> V SettingGet(PyMOLGlobals * G, int index) {
363   return SettingGet<V>(index, G->Setting);
364 }
365 
366 /*
367  * Get setting value if it's defined in the given set, and assign value to
368  * `out` variable and return true. Otherwise return false and leave `out`
369  * untouched.
370  */
371 template <typename V>
SettingGetIfDefined(const CSetting * s,int index,V * out)372 bool SettingGetIfDefined(const CSetting * s, int index, V * out) {
373   if (s && s->info[index].defined) {
374     *out = SettingGet<V>(index, s);
375     return true;
376   }
377   return false;
378 }
379 
380 /**
381  * Return setting value if it's defined in the given set, or `default_` otherwise.
382  */
383 template <typename V>
SettingGetWD(const CSetting * s,int index,V default_)384 V SettingGetWD(const CSetting* s, int index, V default_) {
385   V out;
386   if (SettingGetIfDefined<V>(s, index, &out))
387     return out;
388   return default_;
389 }
390 
391 #define SettingGet_b            SettingGet<bool>
392 #define SettingGet_i            SettingGet<int>
393 #define SettingGet_color        SettingGet<int>
394 #define SettingGet_f            SettingGet<float>
395 #define SettingGet_s            SettingGet<const char *>
396 #define SettingGet_3fv          SettingGet<const float *>
397 
398 #define SettingGetGlobal_b      SettingGet<bool>
399 #define SettingGetGlobal_i      SettingGet<int>
400 #define SettingGetGlobal_color  SettingGet<int>
401 #define SettingGetGlobal_f      SettingGet<float>
402 #define SettingGetGlobal_s      SettingGet<const char *>
403 #define SettingGetGlobal_3fv    SettingGet<const float *>
404 
405 #define SettingGetIfDefined_b(G, s, i, o) SettingGetIfDefined(s, i, o)
406 #define SettingGetIfDefined_i(G, s, i, o) SettingGetIfDefined(s, i, o)
407 
408 /*
409  * templatted unique settings
410  */
411 
412 bool SettingUniqueGetTypedValuePtr(PyMOLGlobals * G, int unique_id, int index,
413     int setting_type, void * out);
414 
415 /*
416  * bool overload
417  */
418 inline
SettingUniqueGetTypedValuePtr(PyMOLGlobals * G,int unique_id,int index,int setting_type,bool * out)419 bool SettingUniqueGetTypedValuePtr(PyMOLGlobals * G, int unique_id, int index,
420     int setting_type, bool * out) {
421   int i = *out;
422   bool r = SettingUniqueGetTypedValuePtr(G, unique_id, index, setting_type, &i);
423   *out = i;
424   return r;
425 }
426 
427 /*
428  * `SettingGetIfDefined` equivalent for unique settings.
429  */
430 template <typename V>
SettingUniqueGetIfDefined(PyMOLGlobals * G,int unique_id,int index,V * out)431 bool SettingUniqueGetIfDefined(PyMOLGlobals * G, int unique_id, int index, V * out) {
432   return SettingUniqueGetTypedValuePtr(G, unique_id, index,
433       SettingGetType<V>(), out);
434 }
435 
436 #endif
437