HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
AP_Interface.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: AP_Interface.h ( SI Library, C++)
7  *
8  * COMMENTS:
9  */
10 
11 #ifndef __AP_Interface__
12 #define __AP_Interface__
13 
14 #include "SI_API.h"
15 #include <stdio.h>
16 
17 #include <UI/UI_Object.h>
18 
19 #include <UT/UT_Error.h>
20 #include <UT/UT_Signal.h>
21 #include <UT/UT_ValArray.h>
22 #include <UT/UT_String.h>
23 #include <UT/UT_WorkBuffer.h>
24 #include <UT/UT_SharedPtr.h>
25 #include <UT/UT_UniquePtr.h>
26 
27 #include <utility>
28 
29 class UT_Url;
30 
31 class AP_Interface;
32 class UI_Value;
33 class UI_Manager;
34 template<typename T> class UT_SymbolMap;
35 class UI_Feel;
36 class UI_KeyDelegate;
39 class UI_Window;
43 
44 // Forward declare this to avoid pulling in LM_Manager.h
45 // which will break SI_OSXDialogs.mm
46 enum LM_SaveAppReason : int;
47 
48 /// Base class for interfaces.
49 /// This class' main responsibility is to maintain hash tables of named
50 /// UI_Feel "object symbol" and UI_Value "value symbol" items.
51 class SI_API AP_Interface : public UI_Object {
52 public:
53  AP_Interface();
54 
55  /// Construct with given name and predefined value names with corresponding
56  /// interests. The actual values are not created until wireInteface() is
57  /// called. Typically, initApplication() is first called to create the
58  /// the values and then wireInterface() is called afterwards to attach the
59  /// methods to the corresponding values.
60  AP_Interface(const char *myname,
61  const char *const *names,
62  UI_EventMethod const *methods);
63 
64  ~AP_Interface() override;
65 
66  const char *className() const override;
67 
68  /// Return the name passed in the constructor
69  const UT_String &getName() const { return myName; }
70 
71  /// Attach values names to the methods passed in the constructor.
72  /// The actual UI_Value's are typically created by calling
73  /// initApplication() first. If the values do not exist yet, then they are
74  /// automatically created into uims (if not nullptr), else they will
75  /// created in this object.
76  ///
77  /// This method also calls processKeyBindingProxyRequests().
78  void wireInterface(UI_Manager *uims);
79 
80  // Removes interests from all the value names passed in the constructor.
81  void unwireInterface(UI_Manager *uims);
82 
83  /// Turns a .ui file into UI gadgets. If quiet is true, no errors or
84  /// warnings are printed.
85  bool readUIFile(const char *ui_filename,
86  bool quiet = false);
87 
88  /// Create new preference file given its base name using standard rules
89  /// (eg. in $HOME/houdiniX.Y). This may return nullptr if a .nosave file is
90  /// found.
91  static FILE *createPreferenceFile(const char *filename);
92 
93  /// Read the given preference file given its base name using standard
94  /// rules. The values will be initialized according to the parsed file into
95  /// this object.
96  bool readPreferenceFile(const char *pref_filename,
97  bool quiet = false);
98 
99  /// Set the named value symbol to the corresponding pointer. If warn is
100  /// true, then a warning will be issued if the name already exists as an
101  /// object or key delegate symbol, or if the value symbol name already
102  /// previously existed.
103  void setValueSymbol(const char *symbol, UI_Value *value,
104  bool warn = true);
105 
106  /// Find the UI_Value for the given named value symbol
107  UI_Value *findValueSymbol(const char *symbol) const;
108 
109  /// Get the UI_Value for the given named value symbol, creating it if it
110  /// doesn't exist yet. If 'create' is false, then getValueSymbol() is the
111  /// same as findValueSymbol().
112  UI_Value *getValueSymbol(const char *symbol, int create = 1);
113 
114  /// Returns all the Symbol/UI_Value's pairs from the ValueSymbol table
115  /// return array will contain nullptr values if its symbol doesn't exist.
116  int getValueSymbols(UT_StringArray &symbols,
118 
119  /// Set the named object symbol to the corresponding pointer. If warn is
120  /// true, then a warning will be issued if the name already exists as a
121  /// value or key delegate symbol, or if the object symbol name already
122  /// previously existed.
123  void setObjectSymbol(const char *symbol, UI_Object *who,
124  int warn = 1);
125 
126  /// Find the UI_Object for the given object symbol name. Returns nullptr if
127  /// it doesn't exist.
128  UI_Object *getObjectSymbol(const char *symbol) const;
129 
130  /// Find the UI_Feel for the given object symbol name. Returns nullptr if
131  /// it doesn't exist. This is equivalent to findObject<UI_Feel*>(symbol).
132  UI_Feel *getFeelSymbol(const char *symbol) const;
133 
134  /// Find the UI_Feel for the given value pointer. Returns nullptr if
135  /// it doesn't exist.
136  UI_Feel *findValueFeel( UI_Value * value) const;
137 
138  /// Returns all the Symbol/UI_Feel's pairs from the FeelSymbol table
139  /// return array will contain nullptr values if its symbol doesn't exist.
140  int getFeelSymbols(UT_StringArray &symbols,
141  UT_Array<UI_Feel *> &feels) const;
142 
143  /// Set the named key delegate symbol to the corresponding pointer. If warn
144  /// is true, then a warning will be issued if the name already exists as an
145  /// object or value symbol, or if the key delegate symbol name already
146  /// previously existed.
147  void setKeyDelegateSymbol(const char *symbol,
148  UI_KeyDelegateSPtr delegate,
149  bool warn = true);
150 
151  /// Returns whether the current key delegate symbol is defined.
152  bool hasKeyDelegateSymbol(const char *symbol) const;
153 
154  /// Find the UI_KeyDelegate for the given named key delegate symbol.
155  UI_KeyDelegateSPtr findKeyDelegateSymbol(const char *symbol) const;
156 
157  /// Get the UI_KeyDelegate for the given named key delegate symbol,
158  /// creating it if it doesn't exist yet. If 'create' is false, then
159  /// getKeyDelegateSymbol() is the same as findKeyDelegateSymbol().
160  UI_KeyDelegateSPtr getKeyDelegateSymbol(const char *symbol,
161  int create = 1);
162 
163  /// Delete the entry for the given object symbol name
164  void removeObjectSymbol(const char *symbol);
165 
166  /// Delete the entry for the given value symbol name
167  void removeValueSymbol(const char *symbol);
168 
169  /// Find the pointer for the given object symbol name, dynamically casted
170  /// to the given template type.
171  template<typename T>
172  T *findObject(const char *name) const
173  {
174  return dynamic_cast<T *>(getObjectSymbol(name));
175  }
176 
177  /// Find the pointer for the given value symbol name, dynamically casted
178  /// to the given template type.
179  template<typename T>
180  T *findValue(const char *name) const
181  {
182  return dynamic_cast<T *>(findValueSymbol(name));
183  }
184 
185  /// This class maintains a table of requests to assign some feels as
186  /// binding proxies for other feels.
187  ///
188  /// Such requests often originate during the parsing of .ui files that
189  /// occurs in subclass initApplication() overrides. These requests are
190  /// identified by a name, and the order in which the source and references
191  /// are registered does not matter.
192  ///
193  /// The pointers to the feels are only temporarily stored until a call to
194  /// processKeyBindingProxyRequests() occurs. At the moment this occurs as
195  /// part of the wireInterface() method.
196  /// @{
197  void setKeyBindingProxySrc(const char *symbol, UI_Feel *src,
198  bool warn = true);
199  void addKeyBindingProxyRef(const char *symbol, UI_Feel *ref,
200  bool warn = true);
201  /// @}
202 
203  /// Initialize this object. This method is intended to be overriden by
204  /// subclasses since the base class implementation is empty. The subclass
205  /// typically calls readUIFile() here to create the interface which
206  /// populates the object and value symbols.
207  virtual void initApplication(UI_Manager *uims,
208  int argc,
209  const char **argv);
210 
211  // The outputUsage() method should simply output the usage text to
212  // the standard error stream.
213  // The application is terminated after invoking this method.
214  virtual void outputUsage(int argc, const char **argv) const;
215 
216  /// Resets this object by calling unwireInterface() and then destroying all
217  /// objects and values.
218  void resetApplication();
219 
220  void handleEvent(UI_Event *event) override;
221 
222  // These are methods which are called only if the APP is "the"
223  // registered main application in the program. By default, they
224  // do nothing.
225  virtual int saveAppData(const char *filename); // ret 1 on success
226  virtual int loadAppState(); // Allows app to load context
227  virtual int saveAppState(); // Allows app to save context
228  virtual void saveOnCoreDump(); // To do stuff when...yikes!
229  virtual bool getCoreDumpFileName(UT_WorkBuffer &name);
230 
231  // Utility methods for managing the common ui.pref file
232  // Load the UI pref file; should be used by Main.C only.
233  bool loadUIInitPrefs();
234  // Save the current UI state to the pref file. The layout level is
235  // the desired level to be saved.
236  void saveUIInitPrefs(
237  const char * layout_level,
238  fpreal uiscale,
239  int playbarui);
240  // Restore UI prefs from file. Similar to load but does not explicitly
241  // set the layout level, which can only be done by Main.C; so this method
242  // is used everywhere else to load the prefs from file.
243  bool restoreUIInitPrefs();
244 
245  /// Menu items and their mapping for file chooser style preference.
246  static const std::pair<const char *, int> theFileChooserStyleMap[];
247 
248  // Helper methods to convert enums to labels, and vice versa.
249  static int mapStrToInt(const char *label,
250  const std::pair<const char *, int> *map);
251  static const char * mapIntToStr(int index,
252  const std::pair<const char *, int> *map);
253 
254  // If a function key is pressed and a script is attached to it,
255  // this will return the script.
256  //
257  bool getFunctionKeyScript(int key, UI_Event *event,
258  UT_String &script);
259 
260  // These static methods will get/set the exit code that the UI application
261  // will exit with. The default exit code is 0. Note that these methods
262  // are implemented in AP_Main.C.
263  static void setAppExitCode(int exit_code);
264  static int getAppExitCode();
265 
266  /// Returns @c true if the application is exiting.
267  static bool isAppExiting();
268 
269  // Returns the desktop specified by the -desktop argument.
270  // Returns nullptr if no such argument was specified.
271  static const char *getStartupDesktop();
272 
273  // Helper class for being able to call the private installSignalHandlers().
274  class InstallSignalHandlersHelper;
275 
276 protected:
277  static void setTheMainApplication(AP_Interface *app);
278  static AP_Interface *getMainApplication() { return theMainApplication; }
279  static void clearTheMainApplication();
280 
282  const char * const *myValueNames;
284 
285  UI_NamedValueMap *getValueTable() const { return myValueTable; }
286  UI_NamedObjectMap *getObjectTable() const { return myObjectTable; }
287 
288  // Processes any registered binding proxy requests. After this call
289  // the key binding proxy request table will be cleared.
290  void processKeyBindingProxyRequests();
291 
292  // Updates the given UI_Window object using the -geometry or pref file
293  static void loadWindowGeometry(
294  UI_Window *window,
295  bool default_maximized,
296  bool use_pref);
297 
298  // Returns true if the -geometry arg was parsed out and false otherwise.
299  // NOTE: The values are returned in pixels!
300  static bool getWindowGeometry(int &width, int &height,
301  int &left, int &bottom,
302  bool &maximized,
303  bool use_pref);
304  static bool getSaveWindowGeoPref();
305  static void saveWindowGeoPref();
306  static bool loadWindowGeoPref(
307  int &w, int &h, int &left, int &bottom,
308  bool &maximized);
309 
310 private:
311  class si_CrashHandler;
312  friend class si_CrashHandler;
313 
314  // WARNING: The installSignalHandlers() method calls UTgetInterrupt(), so
315  // should not be called before the call to UTsetInterrupt().
316  static void installSignalHandlers();
317  static void getSignalList(UT_Array<int> &signals);
318 
319  void assignUIInitPrefs();
320 
321  static const char *mainApplicationName();
322 
323  static void createCrashLog(UTsignalHandlerArg sig_arg,
324  const char *appname, const char *filename);
325  static void terminateSignalHandler(UTsignalHandlerArg sig_arg);
326  static bool coredumpHandler(UTsignalHandlerArg sig_arg);
327  static void coreDumpChaser(UTsignalHandlerArg sig_arg);
328  static void installCallbacks();
329  static void powerFailHandlerSignalHandler(UTsignalHandlerArg);
330  static void powerFailHandler(
331  LM_SaveAppReason reason,
332  UT_String &saved_file_name,
333  const UT_StringRef &details);
334  static void terminationWarning(uint nseconds);
335 
336  static AP_Interface *theMainApplication;
337 
338  class ProxyRequest
339  {
340  public:
341  ProxyRequest() : myTarget(nullptr) {}
342 
343  UI_Feel *myTarget;
344  UT_Array<UI_Feel *> myReferences;
345  };
346  typedef UT_SymbolMap<ProxyRequest> NamedProxyRequestMap;
347 
348 private:
349  UI_NamedValueMap *myValueTable;
350  UI_NamedObjectMap *myObjectTable;
351  UI_NamedKeyDelegateMap *myKeyDelegateTable;
352  NamedProxyRequestMap *myKeyBindingProxyRequestTable;
353 };
354 
355 
356 /// Base class for bootstrapping code for executable applications, with
357 /// the main UI implemented by an AP_Interface.
358 ///
359 /// Instances are created as static objects so that the constructor runs
360 /// during static initialization before the main() function in AP_Main.C.
361 ///
362 /// The createApplication() method will be called on any existing bootstrap
363 /// objects during the execution of main() to allocate an AP_Interface that
364 /// main() will initialize and wire, and finally destroy before terminating.
366 {
367 public:
368  AP_Bootstrap();
369  virtual ~AP_Bootstrap();
370 
371  virtual AP_InterfaceUPtr createApplication() = 0;
372 
373 protected:
374  //
375  // Set the application to run in the fore or background. This MUST
376  // be called from a static constructor (i.e. before main is run).
377  //
378  static void setAppForeground();
379 };
380 
381 
382 // A convenience template for a trivial bootstrapper subclass that creates
383 // an application with a trivial constructor.
384 template <typename APP_T>
386 {
387 public:
389  { return UTmakeUnique<APP_T>(); }
390 };
391 
392 extern void APregister (AP_Interface *app);
393 extern void APderegister(AP_Interface *app);
394 
395 extern void APregister (AP_Bootstrap *bootstrap);
396 extern void APderegister(AP_Bootstrap *bootstrap);
397 
398 // These template functions allow you to get & cast to the appropriate
399 // object/value type in one step, ie:
400 //
401 // UI_Button *button = UIgetObject<UI_Button>(this, "button.gad");
402 // UI_StringList *menu = UIgetValue<UI_StringList>(this, "rmb.menu");
403 
404 template<class ObjectClass> inline
405 ObjectClass *SIgetObject(const AP_Interface *app, const char *name)
406 {
407  return dynamic_cast<ObjectClass *>(app->getObjectSymbol(name));
408 }
409 
410 template<class ValueClass> inline
411 ValueClass *SIgetValue(const AP_Interface *app, const char *name)
412 {
413  return dynamic_cast<ValueClass *>(app->findValueSymbol(name));
414 }
415 
416 #endif
typedef int(APIENTRYP RE_PFNGLXSWAPINTERVALSGIPROC)(int)
ValueClass * SIgetValue(const AP_Interface *app, const char *name)
Definition: AP_Interface.h:411
GT_API const UT_StringHolder filename
GLuint GLsizei const GLchar * label
Definition: glcorearb.h:2545
T * findValue(const char *name) const
Definition: AP_Interface.h:180
#define SI_API
Definition: SI_API.h:10
GLint left
Definition: glcorearb.h:2005
GLsizei const GLfloat * value
Definition: glcorearb.h:824
AP_InterfaceUPtr createApplication() override
Definition: AP_Interface.h:388
void APregister(AP_Interface *app)
UT_SymbolMap< UI_Value * > UI_NamedValueMap
Definition: AP_Interface.h:39
std::unique_ptr< T, Deleter > UT_UniquePtr
A smart pointer for unique ownership of dynamically allocated objects.
Definition: UT_UniquePtr.h:39
struct _cl_event * event
Definition: glcorearb.h:2961
virtual void handleEvent(UI_Event *event)
GLint GLsizei GLsizei height
Definition: glcorearb.h:103
GLint ref
Definition: glcorearb.h:124
std::shared_ptr< T > UT_SharedPtr
Wrapper around std::shared_ptr.
Definition: UT_SharedPtr.h:36
const UT_String & getName() const
Return the name passed in the constructor.
Definition: AP_Interface.h:69
UT_UniquePtr< AP_Interface > AP_InterfaceUPtr
Definition: AP_Interface.h:38
static AP_Interface * getMainApplication()
Definition: AP_Interface.h:278
const char *const * myValueNames
Definition: AP_Interface.h:282
Definition: UT_Url.h:26
UI_EventMethod const * myMethods
Definition: AP_Interface.h:283
GLuint const GLchar * name
Definition: glcorearb.h:786
GLint GLint bottom
Definition: glcorearb.h:2005
UT_SymbolMap< UI_Object * > UI_NamedObjectMap
Definition: AP_Interface.h:41
UI_NamedObjectMap * getObjectTable() const
Definition: AP_Interface.h:286
UI_Object * getObjectSymbol(const char *symbol) const
GLfloat GLfloat GLfloat GLfloat h
Definition: glcorearb.h:2002
GLenum GLsizei GLsizei GLint * values
Definition: glcorearb.h:1602
fpreal64 fpreal
Definition: SYS_Types.h:278
T * findObject(const char *name) const
Definition: AP_Interface.h:172
GLuint index
Definition: glcorearb.h:786
void(UI_Object::* UI_EventMethod)(UI_Event *)
Definition: UI_Object.h:36
virtual const char * className() const
Definition: UI_Object.h:87
GLint GLsizei width
Definition: glcorearb.h:103
UT_String myName
Definition: AP_Interface.h:281
GLubyte GLubyte GLubyte GLubyte w
Definition: glcorearb.h:857
UI_Value * findValueSymbol(const char *symbol) const
Find the UI_Value for the given named value symbol.
UT_SymbolMap< UI_KeyDelegateSPtr > UI_NamedKeyDelegateMap
Definition: AP_Interface.h:42
unsigned int uint
Definition: SYS_Types.h:45
void APderegister(AP_Interface *app)
UI_NamedValueMap * getValueTable() const
Definition: AP_Interface.h:285
GLenum src
Definition: glcorearb.h:1793
UT_SharedPtr< UI_KeyDelegate > UI_KeyDelegateSPtr
Definition: AP_Interface.h:37
ObjectClass * SIgetObject(const AP_Interface *app, const char *name)
Definition: AP_Interface.h:405