GL Studio C++ Runtime API
util.h
Go to the documentation of this file.
1 /*! \file
2  \brief Generally useful defines, macros, enumerations and function
3  prototypes.
4 
5  \par Copyright Information
6 
7  Copyright (c) 2017 by The DiSTI Corporation.<br>
8  11301 Corporate Blvd; Suite 100<br>
9  Orlando, Florida 32817<br>
10  USA<br>
11  <br>
12  All rights reserved.<br>
13 
14  This Software contains proprietary trade secrets of DiSTI and may not be
15 reproduced, in whole or part, in any form, or by any means of electronic,
16 mechanical, or otherwise, without the written permission of DiSTI. Said
17 permission may be derived through the purchase of applicable DiSTI product
18 licenses which detail the distribution rights of this content and any
19 Derivative Works based on this or other copyrighted DiSTI Software.
20 
21  NO WARRANTY. THE SOFTWARE IS PROVIDED "AS-IS," WITHOUT WARRANTY OF ANY KIND,
22 AND ANY USE OF THIS SOFTWARE PRODUCT IS AT YOUR OWN RISK. TO THE MAXIMUM EXTENT
23 PERMITTED BY APPLICABLE LAW, DISTI AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES
24 AND CONDITIONS, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
25 IMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY AND/OR FITNESS FOR A
26 PARTICULAR PURPOSE, TITLE, AND NON-INFRINGEMENT, WITH REGARD TO THE SOFTWARE.
27 
28  LIMITATION OF LIABILITY. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW,
29 IN NO EVENT SHALL DISTI OR ITS SUPPLIERS BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
30 INDIRECT, OR CONSEQUENTIAL DAMAGES WHATSOEVER (INCLUDING, WITHOUT LIMITATION,
31 DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS
32 INFORMATION, OR ANY OTHER PECUNIARY LOSS) ARISING OUT OF THE USE OF OR
33 INABILITY TO USE THE SOFTWARE, EVEN IF DISTI HAS BEEN ADVISED OF THE POSSIBILITY
34 OF SUCH DAMAGES. DISTI'S ENTIRE LIABILITY AND YOUR EXCLUSIVE REMEDY SHALL NOT
35 EXCEED FIVE DOLLARS (US$5.00).
36 
37  The aforementioned terms and restrictions are governed by the laws of the
38 State of Florida and the United States of America.
39 
40 */
41 
42 #ifndef INCLUDED_GLS_RUNTIME_UTIL_H
43 #define INCLUDED_GLS_RUNTIME_UTIL_H
44 
45 #include "gls_include.h"
46 
47 #ifdef WIN32
48 # include <direct.h>
49 #else
50 # include <unistd.h>
51 #endif
52 
53 #include "disti_assert.h"
54 #include "dynamic_array.h"
55 #include "gls_cpp_lang_support.h"
56 #include "gls_matrix_affine.h"
57 #include "scoped_ptr.h"
58 #include "unhide_globals.h"
59 #include "vertex.h"
60 
61 #include <algorithm>
62 #include <cmath>
63 #include <iostream>
64 #include <sstream>
65 #include <string>
66 #include <typeinfo>
67 #include <vector>
68 
69 #if defined( QNX )
70 # include <stdio.h>
71 #else
72 # include <cstdio>
73 #endif
74 
75 #if defined( LINUX ) || defined( __VXWORKS__ ) || defined( __APPLE__ ) || defined( QNX )
76 # include <strings.h>
77 #endif
78 
79 #ifdef ANDROID
80 # include <android/asset_manager.h>
81 #endif
82 
83 #if defined( _MSC_VER )
84  // Hide std template warnings
85 # pragma warning( disable : 4786 )
86 #endif
87 
88 const int DIALOG_MAX_DIRECTORY_LENGTH = 1024; // Limited by FLTK FileBrowser
89 
90 class Fl_Window;
91 
92 // Wrap code that should only be compiled in debug in GLS_DEBUG_CODE()
93 #if defined( GLS_DEBUG ) || !defined( NDEBUG )
94 # define GLS_DEBUG_CODE( x ) x
95 #else
96 # define GLS_DEBUG_CODE( x )
97 #endif
98 
99 namespace disti
100 {
101 class Vertex;
102 class DisplayObject;
103 class DisplayFrame;
104 
105 #ifndef TRUE
106 # define TRUE 1
107 #endif
108 
109 #ifndef FALSE
110 # define FALSE 0
111 #endif
112 
113 #ifdef WIN32
114 inline int strcasecmp( const char* const x, const char* const y )
115 {
116  return _stricmp( x, y );
117 }
118 #endif
119 
120 /** Used to generate inline textures. The writing and reading of the lines need to know the length. */
122 
123 /* Used for parsing lines of clear text */
124 const char* const PARSER_CLEARSTRING_DELIMETER_START = "#$STRING_START$#";
125 const char* const PARSER_CLEARSTRING_DELIMETER_END = "#$STRING_END$#";
126 
127 const double HIT_TOLERANCE = 5.0;
128 
129 /** Determines if x is included in the range x1 to x2 */
130 template<class X, class X1, class X2>
131 bool BETWEEN( const X& x, const X1& x1, const X2& x2 )
132 {
133  return ( x >= x1 && x <= x2 )
134  || ( x >= x2 && x <= x1 );
135 }
136 
137 /** Determines if the argument is negative */
138 template<class X>
139 bool IS_NEGATIVE( const X& x ) { return std::fabs( x ) > 0.0001 ? ( x < 0.0 ) : 0; }
140 
141 /** Determines if the argument is positive */
142 template<class X>
143 bool IS_POSITIVE( const X& x ) { return std::fabs( x ) > 0.0001 ? ( x > 0.0 ) : 0; }
144 
145 /** Determines if the argument is small (< 1e-1) */
146 template<class X>
147 bool CloseToZero( const X x, const X threshold = X( 1e-1 ) )
148 {
149  return std::fabs( x ) < threshold;
150 }
151 
152 /** Determines if the argument is extremely small (< 10E-4) */
153 template<class X>
154 bool VeryCloseToZero( X x ) { return CloseToZero( x, X( 0.0001 ) ); }
155 
156 /** Determines if the argument is very small (< 10E-3) */
157 template<class X>
158 bool IsNearZero( X x ) { return CloseToZero( x, X( 0.001 ) ); }
159 
160 /** \deprecated Renamed to IsNearZero(). */
161 template<class X>
162 bool IS_ZERO( X x ) { return IsNearZero( x ); }
163 
164 #ifndef MIN
165  /// Determines which argument is smaller
166  /// \deprecated Use disti::Min() instead.
167 # define MIN( A, B ) ( ( A ) < ( B ) ? ( A ) : ( B ) )
168 #endif
169 
170 #ifndef MAX
171  /// Determines which argument is larger
172  /// \deprecated Use disti::Min() instead.
173 # define MAX( A, B ) ( ( A ) > ( B ) ? ( A ) : ( B ) )
174 #endif
175 
176 /** Use for determining the current OpenGL version available in the current
177  * runtime environment.
178  * It may not be valid until called after a valid rendering context has been assigned.
179  */
180 GLS_EXPORT float OpenGLVersion();
181 
182 GLS_EXPORT bool gltIsExtSupported( const char* extension );
183 
184 // Additional #defines
185 //From glext.h Available at http://oss.sgi.com/projects/ogl-sample/registry/ */
186 #ifndef GLES
187 # define GLSTUDIO_CLAMP_TO_EDGE ( OpenGLVersion() >= 1.2f ? 0x812F : GL_CLAMP )
188 #else
189 # define GLSTUDIO_CLAMP_TO_EDGE GL_CLAMP_TO_EDGE
190 #endif
191 
192 /** GL Studio color defines */
193 // \enum color enumerations for use with GlsDefinedColor methods
195 {
196  GLS_COLOR_WHITE,
197  GLS_COLOR_CYAN,
198  GLS_COLOR_RED,
199  GLS_COLOR_AMBER,
200  GLS_COLOR_GREEN,
201  GLS_COLOR_YELLOW,
202  GLS_COLOR_MAGENTA,
203  GLS_COLOR_BLACK,
204  GLS_COLOR_BLUE,
205  GLS_COLOR_MAX
206 };
207 
208 /** Predefined colors (see \sa GlsDefinedColorEnum for the values). Use \sa GlsDefinedColor() for a range-checked version. */
209 GLS_EXPORT extern unsigned char glsDefinedColors[ GLS_COLOR_MAX ][ 4 ];
210 
211 /** Gets a predefined color in \sa GlsDefinedColorEnum.
212  * \param index of defined color
213  * \return an unsigned char array of the specified index
214  */
215 inline unsigned char* GlsDefinedColor( GlsDefinedColorEnum index )
216 {
217  if( ( index < 0 ) || ( index >= GLS_COLOR_MAX ) )
218  return glsDefinedColors[ 0 ];
219  else
220  return glsDefinedColors[ index ];
221 }
222 /** Allows the user to change the predefined colors */
224  unsigned char red,
225  unsigned char green,
226  unsigned char blue,
227  unsigned char alpha )
228 {
229  if( ( index >= 0 ) && ( index < GLS_COLOR_MAX ) )
230  {
231  glsDefinedColors[ index ][ 0 ] = red;
232  glsDefinedColors[ index ][ 1 ] = green;
233  glsDefinedColors[ index ][ 2 ] = blue;
234  glsDefinedColors[ index ][ 3 ] = alpha;
235  }
236 }
237 
238 //---------------------------------------------------------------------------
239 /**
240  * Return whether two numbers are "equal" to eachother taking into account
241  * a certain precision. You can use this method on any numeric types and
242  * even mix types as the parameters. Eg. you can compare integers with
243  * floating point types or compare floats and doubles without casting.
244  *
245  * \param x first number to use in the comparison which determines the range
246  * \param y number to check if within the range determined by x and precision
247  * \param precision number that is added to and subtracted from x to
248  * determine the range to check y against.
249  */
250 template<class T1, class T2>
251 bool Equal( T1 x, T2 y, float precision = 0.001f )
252 {
253  return ( x - precision ) <= y && y <= ( x + precision );
254 }
255 
256 //---------------------------------------------------------------------------
257 /**
258  * Return the minimum of two objects. The class T must have the < operator
259  * defined.
260  */
261 template<class T>
262 const T& Min( const T& x, const T& y )
263 {
264  return x < y ? x : y;
265 }
266 
267 //---------------------------------------------------------------------------
268 /**
269  * Return the maximum of two objects. The class T must have the < operator
270  * defined.
271  */
272 template<class T>
273 const T& Max( const T& x, const T& y )
274 {
275  return x < y ? y : x;
276 }
277 
278 //---------------------------------------------------------------------------
279 /**
280  * Return the minimum of two objects determined by a predicate.
281  * If pr(x, y) is true, x is returned else y.
282  */
283 template<class T, class Pred>
284 const T& Min( const T& x, const T& y, Pred pr )
285 {
286  return pr( x, y ) ? x : y;
287 }
288 
289 //---------------------------------------------------------------------------
290 /**
291  * Return the maximum of two objects determined by a predicate.
292  * If pr(x, y) is true, y is returned else x.
293  */
294 template<class T, class Pred>
295 const T& Max( const T& x, const T& y, Pred pr )
296 {
297  return pr( x, y ) ? y : x;
298 }
299 
300 /** \brief Class to contain current OpenGL view, projection and draw matrices */
302 {
303 private:
304  bool _needsDelete;
305 
306 public:
307  int* viewMatrix;
308  GlsMatrixType* projMatrix;
309  GlsMatrixType* modelMatrix;
310 
311  /** Default constructor
312  * Keeps everything NULL */
313  GLS_EXPORT OpenGLMatrices();
314 
315  /** Copy constructor
316  * Pointers are copied as-is, copies of the
317  * data are NOT made. */
318  GLS_EXPORT OpenGLMatrices( const OpenGLMatrices& src );
319 
320  /** Another constructor.
321  * Pointers are copied as-is, copies of the
322  * data are NOT made. */
323  GLS_EXPORT OpenGLMatrices( int* view,
324  GlsMatrixType* proj,
325  GlsMatrixType* model );
326 
327  /** Destructor */
328  GLS_EXPORT ~OpenGLMatrices();
329 
330  /** Retrieves the current OpenGL Matrices from the
331  * OpenGL Subsystem */
332  GLS_EXPORT void GetCurrent();
333 };
334 
335 /** Stack class that uses DynamicArray */
336 template<class T, bool TypeIsSimple>
338 {
339 private:
341 
342 public:
343  unsigned int size() { return array.Count(); }
344 
345  void push( const T& item )
346  {
347  array[ array.Count() ] = item;
348  }
349 
350  T& top()
351  {
352  // This returns garbage if size < 1
353  return array[ array.Count() - 1 ];
354  }
355 
356  void pop()
357  {
358  if( array.Count() > 0 )
359  {
360  array.Count( array.Count() - 1 );
361  }
362  }
363 };
364 
365 /** Find a transformation that will convert to a new coordinate
366  * system defined by the given origin and basis vectors (i,j,k).
367  * \note The new i,j,k vectors are in respect to the current origin.
368  * (i.e. for transformation that moves the origin
369  * along the x axis by 5 units you should pass in
370  * (Vector(5,0,0), Vector(1,0,0), Vector(0,1,0) , Vector(0,0,1))
371  * NOT (Vector(5,0,0), Vector(6,0,0), Vector(5,1,0) , Vector(5,0,1))
372  * Template argument is either double or float.
373  * \param new_origin Vector to the new coordinate system origin.
374  * \param new_i Vector parallel to the new x-axis with magnitude equal to one unit in the new coordinate system.
375  * \param new_j Vector parallel to the new y-axis with magnitude equal to one unit in the new coordinate system.
376  * \param new_k Vector parallel to the new z-axis with magnitude equal to one unit in the new coordinate system.
377  *
378  * \returns transformation matrix to the new coordinate system
379  */
380 template<class T>
381 GlsMatrixAffine<T> FindCoordinateTransformation( const Vector& new_origin, const Vector& new_i, const Vector& new_j, const Vector& new_k )
382 {
383  GlsMatrixAffine<T> transform;
384  GlsMatrixAffine<T> rotation_scaling;
385 
386  // First translate to the new origin
387 
388  transform.Translate( -new_origin );
389 
390  // Build a matrix taking the standard basis vectors to the new basis vectors
391 
392  rotation_scaling( 0, 0 ) = new_i.x;
393  rotation_scaling( 0, 1 ) = new_j.x;
394  rotation_scaling( 0, 2 ) = new_k.x;
395  rotation_scaling( 1, 0 ) = new_i.y;
396  rotation_scaling( 1, 1 ) = new_j.y;
397  rotation_scaling( 1, 2 ) = new_k.y;
398  rotation_scaling( 2, 0 ) = new_i.z;
399  rotation_scaling( 2, 1 ) = new_j.z;
400  rotation_scaling( 2, 2 ) = new_k.z;
401 
402  // Invert because we want the new basis vectors to become the standard basis vectors
403  rotation_scaling.Invert();
404 
405  // Combine the translation and rotation to produce the complete transformation
406  return rotation_scaling * transform;
407 }
408 
409 template<class T>
410 void FindCoordinateTransformation( const Vector& new_origin, const Vector& new_i, const Vector& new_j, const Vector& new_k, GlsMatrixAffine<T>& result )
411 {
412  GlsMatrixAffine<T> transform;
413  GlsMatrixAffine<T> rotation_scaling;
414 
415  // First translate to the new origin
416 
417  transform.Translate( -new_origin );
418 
419  // Build a matrix taking the standard basis vectors to the new basis vectors
420 
421  rotation_scaling( 0, 0 ) = new_i.x;
422  rotation_scaling( 0, 1 ) = new_j.x;
423  rotation_scaling( 0, 2 ) = new_k.x;
424  rotation_scaling( 1, 0 ) = new_i.y;
425  rotation_scaling( 1, 1 ) = new_j.y;
426  rotation_scaling( 1, 2 ) = new_k.y;
427  rotation_scaling( 2, 0 ) = new_i.z;
428  rotation_scaling( 2, 1 ) = new_j.z;
429  rotation_scaling( 2, 2 ) = new_k.z;
430 
431  // Invert because we want the new basis vectors to become the standard basis vectors
432  rotation_scaling.Invert();
433 
434  // Combine the translation and rotation to produce the complete transformation
435  result = rotation_scaling * transform;
436 }
437 
438 /** Gets the transformation from one DisplayObject's object coordinates to another's
439  * Note: This method uses a screen-space transformation (DisplayObject::ModelMatrix). This requires that the two objects have been PreDrawn with the same view, but they do not need to be part of the same object heirarchy.
440  * Use GetObjectCoordinatesTransform unless GetObjectCoordinatesTransformSameView is required.
441  *
442  * \sa GetObjectCoordinatesTransform
443  *
444  * \param from The DisplayObject to start at
445  * \param to The DisplayObject to end at
446  * \param outTransform Out parameter - If the function returns true, this will contain the resulting transformation.
447  * \returns true on success, false if there was an error
448  */
449 GLS_EXPORT bool GetObjectCoordinatesTransformSameView( DisplayObject* from, DisplayObject* to, GlsMatrixType* outTransform );
450 
451 /** Gets the transformation from one DisplayObject's object coordinates to another's (if possible)
452  * This is the preferred method for determining the coordinate space relationship between two objects that have DynamicTransforms applied.
453  * Note: This method requires that the two objects are part of the same object heirarchy.
454  * Consider using GetObjectCoordinatesTransformSameView if your situation does not meet this requirement.
455  *
456  * \code
457  * // Example: Move objB to be in the same location as objA (including all DynamicTransforms)
458  * // Change Location of objB so that it's RotationPoint aligns with the RotationPoint of objA
459  * GlsMatrixType transform;
460  * if( GetObjectCoordinatesTransform( objA, objB, &transform ) )
461  * {
462  * Vector objA_rotationPoint_transformed = transform * (objA->Location() + objA->RotationPoint());
463  * objB->Location( objA_rotationPoint_transformed - objB->RotationPoint() );
464  * }
465  * else
466  * {
467  * // Error: objects are not in the same heirarchy
468  * }
469  * \endcode
470  *
471  * \sa GetObjectCoordinatesTransform
472  *
473  * \param from The DisplayObject to start at
474  * \param to The DisplayObject to end at
475  * \param outTransform Out parameter - If the function returns true, this will contain the resulting transformation.
476  * \returns true on success, false if the objects are not in the same heirarchy.
477  */
478 GLS_EXPORT bool GetObjectCoordinatesTransform( DisplayObject* from, DisplayObject* to, GlsMatrixType* outTransform );
479 
480 /** Test if the given points are not colinear (they are not in a line)
481  * \return true if the points are not colinear
482  * \return false if the points are colinear
483  */
484 GLS_EXPORT bool NotColinear( const Vector& a, const Vector& b, const Vector& c );
485 
486 /** Search the given Vertex array for the first three non-colinear vertices.
487  * \param arraySize The size of vertex_array
488  * \param array The Vertex array
489  * \param index1 variable to receive 1st array index
490  * \param index2 variable to receive 2nd array index
491  * \param index3 variable to receive 3rd array index
492  * \param isVectorArray true if array points to a Vector array, false if it
493  * points to a Vertex array
494  *
495  * \return true If the vertices were found
496  * \returns false If there are not three non-colinear vertices in the array
497  * if this occurs, the index values are undefined
498  */
499 GLS_EXPORT bool FindNonColinearVertices( int arraySize, Vector array[],
500  int& index1, int& index2, int& index3,
501  bool isVectorArray = true );
502 
503 /** Vertex version of FindNonColinearVertices */
504 inline bool FindNonColinearVertices( int arraySize, Vertex array[], int& index1, int& index2, int& index3 )
505 {
506  return FindNonColinearVertices( arraySize, array, index1, index2, index3, false );
507 }
508 
509 /** Recalculate the texture points of a given DisplayObject
510  * based on its valid texture coordinates
511  *
512  * \return true On success
513  * \return false If the texture points could not be calculated.
514  * (The object doesn't have three non-colinear vertices or doesn't have texture coordinates.)
515  */
516 GLS_EXPORT bool CalculateTexPointsFromTexCoords( DisplayObject* object );
517 
518 /** Encodes a string such that if it contains newlines, it will be wrapped with the "#$STRING_START$#" and "#$STRING_END$#" delimiters.
519  * \param dest Destination string
520  * \param src Source string
521  * \param dest_str_length Size of the destination buffer
522  * \return The length of the encoded string.
523  */
524 GLS_EXPORT int EncodeString( char* dest, const char* src, const int dest_str_length );
525 
526 /** Encodes a std::string such that there are no whitespace characters in the string
527  * \param src Source string
528  * \return The encoded string
529  */
530 GLS_EXPORT std::string EncodeString( const std::string& src );
531 
532 /** Returns a minimum length for a call to EncodeString.
533  * This is based on the clear text delimeters
534  */
535 GLS_EXPORT int EncodedStringMinLength();
536 
537 /** Encodes a string using C language encoding
538  * \param dest Destination string
539  * \param src Source string
540  * \param dest_str_length Size of the destination buffer
541  * \return The length of the encoded string
542  */
543 GLS_EXPORT int C_EncodeString( char* dest, const char* src, const int dest_str_length );
544 
545 /** Returns and encoded std::string using C language encoding
546  * \param src Source string
547  * \return The encoded string
548  */
549 GLS_EXPORT std::string C_EncodeString( const std::string& src );
550 
551 /** Decodes a string that was encoded using EncodeString
552  * \param dest Destination string
553  * \param src Source string
554  * \param dest_str_length Size of the destination buffer
555  * \return The length of the encoded string
556  */
557 GLS_EXPORT int DecodeString( char* dest, const char* src, const int dest_str_length );
558 
559 /** Decodes a std::string that was encoded using EncodeString
560  * \param src Encoded Source string
561  * \return The decoded string
562  */
563 GLS_EXPORT std::string DecodeString( const std::string& src );
564 
565 /** The InlinePixmap structure */
566 typedef struct
567 {
568  int width;
569  int height;
570  int comprSize;
571  unsigned char* pixels;
572 } InlinePixmap;
573 
574 GLS_EXPORT char* MakeRelativePath( const char* originalPath, const char* relativePath );
575 GLS_EXPORT void ConvertBackslashToSlash( char* str );
576 GLS_EXPORT void ConvertBackslashToSlash( std::string& str );
577 
578 /** Determines if the given value falls in any of the ranges passed in.
579  * range_check(int number_of_ranges, double test_value,
580  * int index_0,double range_0_min,double range_0_max,
581  *
582  * ...
583  *
584  * int index_n,double range_n_min,double range_n_max);
585  *
586  * For example, to return 1 for values 0-10 and 2 for values 10-20:
587  *
588  * index = range_check(2,val,
589  * 1, 0.0, 10.0,
590  * 2, 10.0, 20.0);
591  */
592 
593 GLS_EXPORT int range_check( int num, double val, ... );
594 
595 /** Attempts to open the given file. Pops up an error message box if the
596  * attempt fails
597  * \param filename The name of the file to open
598  * \param flags fopen style file arguments (e.g. "r")
599  * \param f Contains file pointer on success
600  * \return True if the operation was successful
601  */
602 GLS_EXPORT int Safe_fopen( const char* filename, char* flags, FILE** f );
603 /** Stream version */
604 GLS_EXPORT int Safe_fopen( const char* filename, char* flags, std::fstream& outstr );
605 
606 #ifdef ANDROID
607 /** Sets if assets should be loaded directly from the apk (default true).
608  * This only affects Android builds.
609  * \param enableDirectAssetLoading true to allow assets to be loaded directly from the apk
610  * false to force assets to be read from the resource directory (\see SetResourcePath)
611  * \post HasAssetExtension returns false for all filetypes if direct asset loading was disabled
612  */
613 GLS_EXPORT void EnableDirectAssetLoading( bool enableDirectAssetLoading );
614 
615 /** Returns if the filetype is one that can be loaded directly from the apk assets.
616  * This only affects Android builds.
617  * \param filename The filename with extension to check
618  * \return True if the filetype can be loaded directly from the apk assets,
619  * False if the file is loaded from internal or external storage
620  */
621 GLS_EXPORT bool HasAssetExtension( const char* filename );
622 
623 /** Returns if the file exists in the apk assets.
624  * This only affects Android builds.
625  * \param filename The name of the file
626  * \return True if the file is an asset that can be opened.
627  * Returns false if no asset exists with filename or the pointer to the AAssetManager, set with SetAssetManager, is null.
628  */
629 GLS_EXPORT bool AssetExists( const char* filename );
630 
631 /** Sets the Android Asset Manager to use.
632  * When the assetManager is null, apk assets cannot be loaded.
633  * This only affects Android builds.
634  * \param assetManager The pointer to the AAssetManager
635  */
636 GLS_EXPORT void SetAssetManager( AAssetManager* assetManager );
637 #endif
638 
639 #if defined( ANDROID ) || defined( __APPLE__ ) || ( defined( LINUX ) && defined( GLES ) ) || defined( QNX ) || defined( INTEGRITY )
640 /** Prepends the resource path to a file name.
641  * \param[in] filename_ The name of the file
642  * \return string containing ResourcePath+filename_, with OS specific path.
643  * On Android, apk asset files are not prepended with a path.
644  */
645 GLS_EXPORT std::string ResolvePath( const char* filename_ );
646 
647 /** Sets the path for locating resource files.
648  * On Android, this is the location where resources outside of apk assets are found.
649  * \param resourcePath The path where application resources will be found
650  */
651 GLS_EXPORT void SetResourcePath( const char* resourcePath );
652 
653 /** Attempts to open the given file. Prepends the filename with the path from SetResourcePath
654  * for non-absolute paths.
655  * On Android, filenames that match an apk asset are opened. Opened assets should be closed
656  * with fclose to free resources, not with the Android Asset Manager close function (AAsset_close)
657  * \param filename The name of the file to open
658  * \param flags fopen style file arguments (e.g. "r")
659  * \pre On Android, Asset Manager != NULL, set with SetAssetManager, when opening an apk asset
660  * \return FILE pointer or NULL otherwise
661  */
662 GLS_EXPORT FILE* gls_fopen( const char* filename, const char* flags );
663 #else
664 /** Pushes a resource search path onto the stack. The CWD is always
665  * implicitly searched first. The resource search paths are local to
666  * the calling thread only. This function should be called from the same
667  * thread as the resources are loaded from.
668  * \param resourcePath The directory path to add to the search paths
669  */
670 GLS_EXPORT void PushResourcePath( const char* resourcePath );
671 
672 /** Remove the first search path from the stack. The resource search paths
673  * are local to the calling thread only. This function should be called from
674  * the same thread as the matching PushResourcePath.
675  */
676 GLS_EXPORT void PopResourcePath();
677 
678 /** Pushes a function that can locate resources. The Resources finders are applied after the resource paths are searched
679  * \param finder The function that can locate resources to add to the search paths
680  */
681 GLS_EXPORT void PushResourceFinder( std::string ( *finder )( const std::string& ) );
682 
683 /** Resolves the given path searching the resource path list. The
684  * CWD is always implicity searched first.
685  * \param path The relative path to resolve
686  */
687 GLS_EXPORT std::string ResolvePath( const char* path );
688 
689 // helper method taking a std::string
690 inline std::string ResolvePath( const std::string& path )
691 {
692  return ResolvePath( path.c_str() );
693 }
694 
695 /** Attempts to open the given file. Relative file paths
696  * are resolved using ResolvePath.
697  * \param filename The name of the file to open
698  * \param flags fopen style file arguments (e.g. "r")
699  * \return FILE pointer or NULL otherwise
700  */
701 GLS_EXPORT FILE* gls_fopen( const char* filename, const char* flags );
702 #endif
703 
704 #ifdef __APPLE__
705 /** \return a string indicating the location of a specific file in the default resource bundle.
706  * This method is designed for runtime platforms that have a pre-defined bundle
707  * location that is not immediately known to the application until runtime.
708  * in iOS, this returns the path to the main application bundle with the file name appended.
709  * \param fileName A string referring to the file without a path.
710  */
711 GLS_EXPORT std::string GetAbsolutePathAndFileNameInDefaultResourceBundle( const char* fileName );
712 #endif
713 
714 /** Prepends the resource path to a file name.
715  * \param[in] fileName The name of the file
716  * \return string containing ResourcePath + fileName, with OS specific path.
717  * On Android, apk asset files are not prepended with a path.
718  */
719 GLS_EXPORT std::string ResolveRuntimeResourcePath( const char* fileName );
720 
721 /** \return true if the file exists, false otherwise
722  * \param filename The filename to check
723  */
724 GLS_EXPORT bool FileExists( const char* filename );
725 GLS_EXPORT bool FileExists( const std::string& filename );
726 
727 /** \return true if the file exists and is a directory, false otherwise
728  * \param filename The filename to check
729  */
730 GLS_EXPORT bool IsDirectory( const char* filename );
731 GLS_EXPORT bool IsDirectory( const std::string& filename );
732 
733 /** \return The file extension for a filepath
734  * \param filepath Filepath to get extension from
735  */
736 GLS_EXPORT std::string FileExtension( const std::string& filepath );
737 
738 /** \return The filename from a file path by stripping off anything to the left of a slash
739  * \param filepath
740  */
741 GLS_EXPORT std::string FileName( const std::string& filepath );
742 
743 /** \return a string containing the path portion of a filename
744  * by stripping off everything to the right of the rightmost slash
745  * \param filepath A string containing a file with a path
746  */
747 GLS_EXPORT std::string FilePath( const std::string& filepath );
748 
749 /** \return a pointer to the string containing the path portion of a filename
750  * by stripping off everything to the right of the rightmost slash
751  * \param name A string containing a file with a path
752  * \warning If this function is called more than once all previous values WILL CHANGE to contain the newest value
753  * \deprecated Use FilePath instead
754  */
755 GLS_EXPORT const char* GetFilePath( const char* name );
756 
757 /** \return The filename from a file path by stripping off anything to the left of a slash
758  * \param name A string containing just the file name without a path
759  * \warning If this function is called more than once all previous values WILL CHANGE to contain the newest value
760  * \deprecated Use FileName instead
761  */
762 GLS_EXPORT char* GetFileName( const char* name );
763 
764 /** Appends a trailing slash to a path string, if one isn't there already
765  * \param s File path
766  */
767 GLS_EXPORT void AppendTrailingSlash( char* s );
768 
769 /** Appends a trailing slash to a path string, if one isn't there already
770  * \param s File path
771  */
772 GLS_EXPORT void AppendTrailingSlash( std::string& s );
773 
774 /** Convert a directory path to have the correct OS
775  * slashes /, or \. Also make sure that the path ends in a \, or /.
776  * So you always have the form <name 1>\\<name 2>...<name n>\\\, or <name 1>/<name 2>...<name n>/
777  * \param path A path to convert
778  * \return a "new-ed" string which may be longer than the original.
779  * It is the calling functions responsibility to free the memory.
780  */
781 GLS_EXPORT char* PathToOS( const char* path );
782 
783 /** \return The file extension for a filename
784  * \param filename Filename to get extension from
785  * No longer allocates memory, you can let the returned string
786  * be colected as it falls out of scope
787  */
788 GLS_EXPORT std::string GetExtension( const std::string& filename );
789 
790 /** Gets the file name from a filename with path
791  * It does not allocate new memory, but rather just returns
792  * a pointer inside the original string
793  */
794 GLS_EXPORT const char* GetBaseName( const char* path );
795 
796 /** \return Pointer to a position within the given \a path where the filename starts.
797  * \deprecated This function is not const-correct. Prefer the const-correct version.
798  * \sa GetBaseName( const char* )
799  */
800 GLS_EXPORT char* GetBaseName( char* path );
801 
802 /** Removes and double slashes from a path.
803  * It will look for the specified type of slash.
804  * It will modify path, but since it can only shrink,
805  * no allocation is done.
806  * \param path The path to operate on.
807  * \param slash The type of slash to search for.
808  */
809 GLS_EXPORT void RemoveDoubleSlashes( char* path, char slash = '/' );
810 
811 /** Remove possible extra spaces the user might enter in the server name input field.
812  * \param entry String to be manupulated.
813  */
814 GLS_EXPORT void RemoveSpaces( std::string& entry );
815 
816 /** \return The minimum angular distance between angle1 and angle2 in degrees
817  * \param angle1 First angle
818  * \param angle2 Second angle
819  */
820 GLS_EXPORT float AngularDistanceDeg( float angle1, float angle2 );
821 
822 /** \return The minimum angular distance between angle1 and angle2 in radians
823  * \param angle1 First angle
824  * \param angle2 Second angle
825  */
826 GLS_EXPORT float AngularDistanceRad( float angle1, float angle2 );
827 
828 GLS_EXPORT bool ContainsNonBlank( const std::string& val );
829 
830 GLS_EXPORT bool GetNoSpaces( FILE* f, char* result, int maxLen );
831 GLS_EXPORT bool GetToEnd( std::istream& instr, std::string& result, bool decode );
832 GLS_EXPORT bool GetVertex( std::istream& instr, Vertex* vert, bool getColor );
833 
834 /** Searches the specified binary file for the specified tag, and adds what immediatly follows the tag to the nameList.
835  * Returns true if at least one is found, false otherwise.
836  */
837 GLS_EXPORT bool GetComponentClassNames( const char* dllFileName, DynamicArray<std::string, false>& nameList, const char* createClassTag = "CreateComponent_" );
838 
839 /** Opens the DLL and attempts to run GlsDefaultClassName(), if found.
840  * Returns an empty string if not found. */
841 GLS_EXPORT std::string GetDefaultComponentClassName( const char* dllFileName );
842 
843 /** Returns the qualified instance name of an object that is
844  * contained within given DisplayFrame. (e.g "cockpit.altimeter.needle")
845  * Note that names are only added for each DisplayFrame (not every Group)
846  * and the name of the topFrame is not included in the qualified name.
847  * \param topFrame The frame in which the qualification will make sense.
848  * \param obj The object which is a direct child or located somewhere below topFrame.
849  * \returns The qualified instance name or an empty string if the qualified
850  * instance name could not be determined. */
851 GLS_EXPORT std::string GetQualifiedInstanceName( const DisplayFrame* topFrame, const DisplayObject* obj );
852 
853 #if !defined( GLES ) || defined( GLES_ANGLE )
854 GLS_EXPORT bool OpenFileDialog( Fl_Window* win, char* filePath, unsigned int filePathSize,
855  char* directory = NULL, const char* filterStr = NULL,
856  const char* defaultExt = NULL, const char* title = NULL,
857  bool multiSelect = false, bool createFile = false,
858  bool fileMustExist = false, bool pathMustExist = false,
859  bool noChangeDirectory = false );
860 
861 GLS_EXPORT bool SaveFileDialog( Fl_Window* win, char* filePath, unsigned int filePathSize,
862  char* directory = NULL, const char* filterStr = NULL,
863  const char* defaultExt = NULL, const char* title = NULL,
864  bool createFile = false,
865  bool fileMustExist = false, bool pathMustExist = false,
866  bool noChangeDirectory = false );
867 #endif
868 GLS_EXPORT void CheckGLError( void );
869 
870 //---------------------------------------------------------------------------
871 /**
872  * Returns a string which is the uppercase version of the passed parameter.
873  *
874  * \param str original string to convert to Uppercase
875  *
876  * \return a string copy of the original but in all caps.
877  */
878 GLS_EXPORT std::string Uppercase( const std::string& str );
879 
880 GLS_EXPORT std::string ReplaceEnvironmentVariables( const char* originalPath );
881 
882 /** A singleton used for accessing the command line arguments in generated code */
884 {
885  bool _silentMode; /** Whether or not the app should run in silent mode */
886 
887 public:
888  GLS_EXPORT glsCommandLine( void );
889  GLS_EXPORT void ReadCommandLine( int argc, char** argv );
890  GLS_EXPORT void Usage();
891 
892  int _argc;
893  char** _argv;
894 
895  bool SilentMode( void ) { return _silentMode; }
896 
897  static GLS_EXPORT glsCommandLine* Instance();
898  static glsCommandLine* _instance;
899 };
900 
901 /** Used to make interface information visible to the user at design time*/
903 {
904 protected:
905  char* _code; // e.g. "DynamicRotate("
906  char* _usage; // e.g. "void DynamicRotate(float angle, int axis)"
907  char* _comment; // e.g. "Sets dynamic rotation in degrees for the specified axis"
908 public:
909  // Default constructor
910  GLS_EXPORT InterfaceDescriptionClass();
911  // Copy constructor
912  GLS_EXPORT InterfaceDescriptionClass( const InterfaceDescriptionClass& source );
913  // Destructor
914  GLS_EXPORT ~InterfaceDescriptionClass();
915  // Copy operator
916  GLS_EXPORT InterfaceDescriptionClass( const char* code, const char* usage, const char* comment );
917 
918  GLS_EXPORT void operator=( const InterfaceDescriptionClass& source );
919  GLS_EXPORT void Code( const char* );
920  GLS_EXPORT const char* Code() const;
921  GLS_EXPORT void Usage( const char* );
922  GLS_EXPORT const char* Usage() const;
923  GLS_EXPORT void Comment( const char* );
924  GLS_EXPORT const char* Comment() const;
925 };
927 
928 /** Base class for GlsMultiVal template
929  */
931 {
932 public:
933  virtual ~GlsMultiValBase() {}
934 
935  //These are used to avoid template problems with VC6.0
936  typedef std::ostream ostreamType;
937  typedef std::istream istreamType;
938 
939  virtual void StreamOut( ostreamType& outstr ) const = 0;
940  virtual void StreamIn( istreamType& instr ) = 0;
941 };
942 
943 /** GlsMultiVal is used to effectivly create a structure containing up
944  * to 10 values of varying types. An instance of the class is capable
945  * of streaming itself to and from a text stream. The individual values
946  * will be separated by spaces when written and read from the stream.
947  * The types have to follow some rules:
948  * - They must themselves have the << and >> stream operators defined.
949  * - operator>> must read all data written by operator<< and must not consume spaces or other characters that follow it
950  * - They must have a default constructor
951  * - They must have a copy constructor
952  * - They shall not be void* (it is used for determining the end of the desired types).
953  * - If a GlsPropString is used, there must be only one, and it *must* be the
954  * last entry in the GlsMultiVal instance.
955  * - A GlsPropStringQuoted will work in any position.
956  * This is intended primarily for the GL Studio end user to use as a Class Property type.
957  */
958 template<class T1,
959  class T2 = void*,
960  class T3 = void*,
961  class T4 = void*,
962  class T5 = void*,
963  class T6 = void*,
964  class T7 = void*,
965  class T8 = void*,
966  class T9 = void*,
967  class T10 = void*>
969 {
970  int _numVals;
971  void CalcNumVals()
972  {
973  _numVals = 1;
974  if( typeid( T2 ) != typeid( void* ) )
975  _numVals++;
976  else
977  return;
978  if( typeid( T3 ) != typeid( void* ) )
979  _numVals++;
980  else
981  return;
982  if( typeid( T4 ) != typeid( void* ) )
983  _numVals++;
984  else
985  return;
986  if( typeid( T5 ) != typeid( void* ) )
987  _numVals++;
988  else
989  return;
990  if( typeid( T6 ) != typeid( void* ) )
991  _numVals++;
992  else
993  return;
994  if( typeid( T7 ) != typeid( void* ) )
995  _numVals++;
996  else
997  return;
998  if( typeid( T8 ) != typeid( void* ) )
999  _numVals++;
1000  else
1001  return;
1002  if( typeid( T9 ) != typeid( void* ) )
1003  _numVals++;
1004  else
1005  return;
1006  if( typeid( T10 ) != typeid( void* ) )
1007  _numVals++;
1008  else
1009  return;
1010  }
1011 
1012 public:
1013  T1 _val1;
1014  T2 _val2;
1015  T3 _val3;
1016  T4 _val4;
1017  T5 _val5;
1018  T6 _val6;
1019  T7 _val7;
1020  T8 _val8;
1021  T9 _val9;
1022  T10 _val10;
1023 
1024  /** Default constructor.
1025  * The _val member types must have default constructors.
1026  */
1028  {
1029  CalcNumVals();
1030  }
1031 
1032  /** Copy constructor.
1033  * This GlsMultiVal will copy values from the src GlsMultiVal.
1034  * \param src GlsMultiVal object to use for initialization.
1035  * \return
1036  */
1037  GlsMultiVal( const GlsMultiVal& src )
1038  : _val1( src._val1 )
1039  , _val2( src._val2 )
1040  , _val3( src._val3 )
1041  , _val4( src._val4 )
1042  , _val5( src._val5 )
1043  , _val6( src._val6 )
1044  , _val7( src._val7 )
1045  , _val8( src._val8 )
1046  , _val9( src._val9 )
1047  , _val10( src._val10 )
1048  {
1049  CalcNumVals();
1050  }
1051  /** Full constructor. Creates a GlsMultiVal object with the provided data.
1052  * \param val1 First value to use for intialization of type T1.
1053  * \param val2 First value to use for intialization of type T2.
1054  * \param val3 First value to use for intialization of type T3.
1055  * \param val4 First value to use for intialization of type T4.
1056  * \param val5 First value to use for intialization of type T5.
1057  * \param val6 First value to use for intialization of type T6.
1058  * \param val7 First value to use for intialization of type T7.
1059  * \param val8 First value to use for intialization of type T8.
1060  * \param val9 First value to use for intialization of type T9.
1061  * \param val10 First value to use for intialization of type T10.
1062  * \return
1063  */
1065  const T1& val1,
1066  const T2& val2 = T2(),
1067  const T3& val3 = T3(),
1068  const T4& val4 = T4(),
1069  const T5& val5 = T5(),
1070  const T6& val6 = T6(),
1071  const T7& val7 = T7(),
1072  const T8& val8 = T8(),
1073  const T9& val9 = T9(),
1074  const T10& val10 = T10() )
1075  : _val1( val1 )
1076  , _val2( val2 )
1077  , _val3( val3 )
1078  , _val4( val4 )
1079  , _val5( val5 )
1080  , _val6( val6 )
1081  , _val7( val7 )
1082  , _val8( val8 )
1083  , _val9( val9 )
1084  , _val10( val10 )
1085  {
1086  CalcNumVals();
1087  }
1088 
1089  /** Compares two multival objects for equality */
1090  virtual bool operator==( const GlsMultiVal& val ) const
1091  {
1092  bool rval = true;
1093  // Only compare the number of used values.
1094  switch( _numVals )
1095  {
1096  // No breaks is intentional
1097  case 10: rval &= ( _val10 == val._val10 );
1098  case 9: rval &= ( _val9 == val._val9 );
1099  case 8: rval &= ( _val8 == val._val8 );
1100  case 7: rval &= ( _val7 == val._val7 );
1101  case 6: rval &= ( _val6 == val._val6 );
1102  case 5: rval &= ( _val5 == val._val5 );
1103  case 4: rval &= ( _val4 == val._val4 );
1104  case 3: rval &= ( _val3 == val._val3 );
1105  case 2: rval &= ( _val2 == val._val2 );
1106  case 1:
1107  rval &= ( _val1 == val._val1 );
1108  break;
1109  default:
1110  rval = false;
1111  }
1112  return rval;
1113  }
1114 
1115  /** Inverse of equality */
1116  virtual bool operator!=( const GlsMultiVal& val ) const
1117  {
1118  return !( *this == val );
1119  }
1120 
1121  /** StreamOut(). This function serializes itself into the provided stream object.
1122  * \param outstr This is the object used by the GlsMultiVal class to serialize itself onto.
1123  * \return
1124  */
1125  virtual void StreamOut( ostreamType& outstr ) const
1126  {
1127  outstr << _val1;
1128  if( _numVals >= 2 )
1129  outstr << " " << _val2;
1130  if( _numVals >= 3 )
1131  outstr << " " << _val3;
1132  if( _numVals >= 4 )
1133  outstr << " " << _val4;
1134  if( _numVals >= 5 )
1135  outstr << " " << _val5;
1136  if( _numVals >= 6 )
1137  outstr << " " << _val6;
1138  if( _numVals >= 7 )
1139  outstr << " " << _val7;
1140  if( _numVals >= 8 )
1141  outstr << " " << _val8;
1142  if( _numVals >= 9 )
1143  outstr << " " << _val9;
1144  if( _numVals >= 10 )
1145  outstr << " " << _val10;
1146  }
1147 
1148  /** StreamIn(). Uses the provided istream object to populate the current GlsMultiVal object
1149  * \param instr This is the stream object used by the GlsMultiVal instance to populate itself.
1150  * \return
1151  */
1152  virtual void StreamIn( istreamType& instr )
1153  {
1154  instr >> _val1;
1155  if( _numVals >= 2 )
1156  {
1157  instr.get(); // The separating space
1158  instr >> _val2;
1159  }
1160  if( _numVals >= 3 )
1161  {
1162  instr.get();
1163  instr >> _val3;
1164  }
1165  if( _numVals >= 4 )
1166  {
1167  instr.get();
1168  instr >> _val4;
1169  }
1170  if( _numVals >= 5 )
1171  {
1172  instr.get();
1173  instr >> _val5;
1174  }
1175  if( _numVals >= 6 )
1176  {
1177  instr.get();
1178  instr >> _val6;
1179  }
1180  if( _numVals >= 7 )
1181  {
1182  instr.get();
1183  instr >> _val7;
1184  }
1185  if( _numVals >= 8 )
1186  {
1187  instr.get();
1188  instr >> _val8;
1189  }
1190  if( _numVals >= 9 )
1191  {
1192  instr.get();
1193  instr >> _val9;
1194  }
1195  if( _numVals >= 10 )
1196  {
1197  instr.get();
1198  instr >> _val10;
1199  }
1200  }
1201 };
1202 
1203 GLS_EXPORT std::ostream& operator<<( std::ostream& outstr, const GlsMultiValBase& multiVal );
1204 GLS_EXPORT std::istream& operator>>( std::istream& instr, GlsMultiValBase& multiVal );
1205 
1206 /** GlsPropString is designed to be used as a string in GL Studio Class Properties.
1207  * It writes itself out as a single line, and will read in up to the next newline.
1208  * It will attempt to convert itself to and from std::strings.
1209  * If it is used in a GlsMultiVal, there must be only one, and it *must* be the
1210  * last entry in the GlsMultiVal instance.
1211  * See GlsPropStringQuoted for more usefulness in GlsMultiVal.
1212  */
1214 {
1215 public:
1216  std::string _string;
1217 
1218  /** Default constructor Creates an empty GlsPropString. */
1220  : _string( "" )
1221  {
1222  }
1223  /** Create a new GlsPropString using the provided std string.
1224  * \param str std::string to use to create the GlsPropString
1225  * \return
1226  */
1227  GlsPropString( const std::string& str )
1228  : _string( str )
1229  {
1230  }
1231 
1232  /** Create a new GlsPropString using the provided c-style string.
1233  * \param str c-style string to use to create the GlsPropString.
1234  * \return
1235  */
1236  GlsPropString( const char* str )
1237  : _string( str ? str : "" )
1238  {
1239  }
1240 
1241  operator std::string() const
1242  {
1243  return _string;
1244  }
1245 
1246  /** Get the string value for this object.
1247  * \return std::string containing the string value for this object.
1248  */
1249  std::string& String()
1250  {
1251  return _string;
1252  }
1253 
1254  /** Checks lexicographic equality of the two arguments */
1255  friend inline bool operator==( const GlsPropString& str1, const GlsPropString& str2 )
1256  {
1257  return str1._string == str2._string;
1258  }
1259 
1260  /** Checks lexicographic inequality of the two arguments */
1261  friend inline bool operator!=( const GlsPropString& str1, const GlsPropString& str2 )
1262  {
1263  return !( str1 == str2 );
1264  }
1265 };
1266 
1267 inline std::ostream& operator<<( std::ostream& outstr, const GlsPropString& str )
1268 {
1269  outstr << disti::C_EncodeString( str._string );
1270  return outstr;
1271 }
1272 inline std::istream& operator>>( std::istream& instr, GlsPropString& str )
1273 {
1274  std::string temp;
1275  disti::GetToEnd( instr, temp, false );
1276  str._string = disti::DecodeString( temp );
1277 
1278  return instr;
1279 }
1280 /** GlsPropStringQuoted is designed to be used as a string in GL Studio Class Properties.
1281  * It writes itself out as a single line surrounded with quotes (""), and will read in up to the next un-escaped quote.
1282  * It will attempt to convert itself to and from std::strings.
1283  * Use of GlsPropStringQuoted is preferred over GlsPropString for use in a GlsMultiVal.
1284  */
1286 {
1287 public:
1288  std::string _string;
1289 
1290  /** Default constructor, create an empty GlsPropStringQuoted object. */
1292  {
1293  }
1294  /** Constructor, create a new GlsPropStringQuoted object using the provided std::string object
1295  * \param str std::string object to use to create the GlsPropStringQuoted object
1296  * \return
1297  */
1298  GlsPropStringQuoted( const std::string& str )
1299  : _string( str )
1300  {
1301  }
1302  /** Constructor, create a new GlsPropStringQuoted object using the provided c-style string
1303  * \param str c-style string to use to create the GlsPropStringQuoted object
1304  * \return
1305  */
1306  GlsPropStringQuoted( const char* str )
1307  : _string( str )
1308  {
1309  }
1310 
1311  operator std::string() const
1312  {
1313  return _string;
1314  }
1315 
1316  std::string& String()
1317  {
1318  return _string;
1319  }
1320 
1321  bool operator==( const GlsPropStringQuoted& str ) const
1322  {
1323  return str._string == _string;
1324  }
1325 };
1326 
1327 inline std::ostream& operator<<( std::ostream& outstr, const GlsPropStringQuoted& str )
1328 {
1329  outstr << '\"' << disti::C_EncodeString( str._string ) << '\"';
1330  return outstr;
1331 }
1332 
1333 inline std::istream& operator>>( std::istream& instr, GlsPropStringQuoted& str )
1334 {
1335  std::string temp;
1336  str._string = "";
1337 
1338  // The next character should be a quote.
1339  // If it is not, we will attempt to do something useful anyway.
1340  if( instr.peek() != '\"' )
1341  {
1342  disti::GetToEnd( instr, temp, false );
1343  }
1344  else // Starts with quote
1345  {
1346  // Go ahead and consume the quote
1347  instr.get();
1348 
1349  int lastChar = 0;
1350  int currChar = 0;
1351  // Loop until we find an un-escaped quote or we run out of stream.
1352  while( instr.good() )
1353  {
1354  lastChar = currChar;
1355  currChar = instr.get();
1356  if( currChar != -1 )
1357  {
1358  if( currChar == '\"' && lastChar != '\\' )
1359  break; // We found the trailing quote
1360  temp += (char)currChar;
1361  }
1362  }
1363  }
1364 
1365  str._string = disti::DecodeString( temp );
1366 
1367  return instr;
1368 }
1369 
1370 #ifndef WIN32
1371 void SpawnBrowser( const char* url );
1372 #endif
1373 
1374 /** Call this to check for the availability of a DiSTI conrolled license.
1375  * It does not hold the license. It only checks it out and checks it back in.
1376  * \param licenseGroupName A name for what this license allows. i.e. "GL Studio Runtime".
1377  * \param feature The specific feature that will be checked out.
1378  * \param version The specific version that will be checked out.
1379  * \param quiet When true, no popup will occur upon missing license.
1380  */
1381 GLS_EXPORT bool CheckDistiLicense( const char* licenseGroupName, const char* feature, const char* version, bool quiet );
1382 
1383 /** This will set the m parameter to an orthographic projection.
1384  * The current value of m is ignored.
1385  * This does NOT make any OpenGL calls.
1386  */
1387 GLS_EXPORT void GlsGetOrtho( GlsMatrixType& m,
1388  double left,
1389  double right,
1390  double bottom,
1391  double top,
1392  double zNear,
1393  double zFar );
1394 
1395 /** This will set the m parameter to a perspective projection.
1396  * The current value of m is ignored
1397  * This does NOT make any OpenGL calls.
1398  */
1399 GLS_EXPORT void GlsGetPerspective( GlsMatrixType& m,
1400  double fovy,
1401  double aspect,
1402  double zNear,
1403  double zFar );
1404 
1405 // using a namespace to help avoid collisions with user code. Future functionality should prefer to go here
1406 namespace Util
1407 {
1408  ////////////////////////////////////////////////////////////////////////////////
1409  /// Clamps a value to the range [min, max]
1410  /// \param val The value to clamp
1411  /// \param min The minimum value in the range
1412  /// \param max The maximum value in the range
1413  ////////////////////////////////////////////////////////////////////////////////
1414  template<class T>
1415  T Clamp( const T& val, const T& min, const T& max )
1416  {
1417  return std::min( max, std::max( min, val ) );
1418  }
1419 
1420  ////////////////////////////////////////////////////////////////////////////////
1421  /// Split a string and add to existing vector of elements with delimeters removed.
1422  /// \param s The string to split
1423  /// \param delim The delimiter to split the string on.
1424  /// \param elems The vector of elements to append each split string to.
1425  /// \param maxElems The maximum number of elements to split. Remaining elements
1426  /// are appended unsplit as the last value. If 0, it does not
1427  /// have a maximum.
1428  /// \note Adapted from http://stackoverflow.com/questions/236129/split-a-string-in-c
1429  ////////////////////////////////////////////////////////////////////////////////
1430  inline void Split( const std::string& s, const char delim, std::vector<std::string>& elems, const std::size_t maxElems = 0 )
1431  {
1432  std::istringstream ss( s );
1433  std::string item;
1434  while( std::getline( ss, item, delim ) )
1435  {
1436  elems.push_back( DISTI_RVAL_MOVE( item ) );
1437  if( elems.size() == maxElems )
1438  {
1439  break;
1440  }
1441  }
1442  if( elems.size() == maxElems && ss.good() && maxElems > 0 )
1443  {
1444  std::string remainder;
1445  std::getline( ss, remainder, '\0' );
1446  elems.back() += delim + remainder;
1447  }
1448  }
1449 
1450  ////////////////////////////////////////////////////////////////////////////////
1451  /// Split a string return a vector of the elements with delimeters removed.
1452  /// \param s The string to split
1453  /// \param delim The delimiter to split the string on.
1454  /// \param maxElems The maximum number of elements to split. Remaining elements
1455  /// are appended unsplit as the last value. If 0, it does not
1456  /// have a maximum.
1457  /// \return The vector of split elements.
1458  /// \note Adapted from http://stackoverflow.com/questions/236129/split-a-string-in-c
1459  ////////////////////////////////////////////////////////////////////////////////
1460  inline std::vector<std::string> Split( const std::string& s, const char delim, const std::size_t maxElems = 0 )
1461  {
1462  std::vector<std::string> elems;
1463  Split( s, delim, elems, maxElems );
1464  return elems;
1465  }
1466 
1467  /// Passing null to std::string is not well-defined. Create a string safely.
1468  inline std::string MakeString( const char* const cStr )
1469  {
1470  return ( cStr ? cStr : "" );
1471  }
1472 } // namespace Util
1473 
1474 ///////////////////////////////////////////////////////////////////////////////////////////////////
1475 // Forward declarations for globals managed by GlsGlobals.
1476 class GlsFontMan;
1477 class IGlsStateManager;
1478 class List_c;
1479 class Mutex;
1480 class TextureLoaderList;
1481 
1482 /// Hold global objects so we can control order of destruction.
1484 {
1485 public:
1486  /// Singleton instance
1487  GLS_EXPORT static GlsGlobals& Instance();
1488 
1489  /// Gets the image list. \sa GetImageListMutex()
1490  GLS_EXPORT List_c& GetImageList();
1491 
1492  /// Gets the mutex for protecting the image list. \sa GetImageList()
1493  GLS_EXPORT Mutex& GetImageListMutex();
1494 
1495  /// Gets the global font manager.
1496  GLS_EXPORT GlsFontMan& GetFontMan();
1497 
1498  /// Gets the global state manager instance
1499  GLS_EXPORT IGlsStateManager& GetStateManager();
1500 
1501  /// Gets the global list of texture loaders
1502  GLS_EXPORT TextureLoaderList& GetTextureLoaders();
1503 
1504 private:
1505  // Order of objects is important here since they are destroyed in the reverse order listed
1506  ScopedPtr<List_c> _imageList;
1507  ScopedPtr<Mutex> _imageListMutex;
1508  ScopedPtr<GlsFontMan> _fontMan;
1509  ScopedPtr<IGlsStateManager> _stateManager;
1510  ScopedPtr<TextureLoaderList> _textureLoaders;
1511 
1512  GlsGlobals();
1513  GlsGlobals( const GlsGlobals& ) DISTI_SPECIAL_MEM_FUN_DELETE;
1514  void operator=( const GlsGlobals& ) DISTI_SPECIAL_MEM_FUN_DELETE;
1515 };
1516 
1517 } // namespace disti
1518 
1519 // Our own local versions of a few glu methods to avoid needing to include the GL Utility library
1520 GLS_EXPORT void glsPerspective( double fovy, double aspect, double zNear, double zFar );
1521 
1522 #ifdef MATRIX_TYPE_FLOAT
1523 GLS_EXPORT bool glsProject( double objx, double objy, double objz,
1524  const float modelMatrix[ 16 ],
1525  const float projMatrix[ 16 ],
1526  const int viewport[ 4 ],
1527  double* winx, double* winy, double* winz );
1528 
1529 GLS_EXPORT bool glsUnProject( double winx, double winy, double winz,
1530  const float modelMatrix[ 16 ],
1531  const float projMatrix[ 16 ],
1532  const int viewport[ 4 ],
1533  double* objx, double* objy, double* objz );
1534 # else
1535 GLS_EXPORT bool glsProject( double objx, double objy, double objz,
1536  const double modelMatrix[ 16 ],
1537  const double projMatrix[ 16 ],
1538  const int viewport[ 4 ],
1539  double* winx, double* winy, double* winz );
1540 
1541 GLS_EXPORT bool glsUnProject( double winx, double winy, double winz,
1542  const double modelMatrix[ 16 ],
1543  const double projMatrix[ 16 ],
1544  const int viewport[ 4 ],
1545  double* objx, double* objy, double* objz );
1546 # endif
1547 
1548 #endif
The DistiUnhideGlobalsDummyClass class.
const T & Min(const T &x, const T &y)
Definition: util.h:262
int EncodedStringMinLength()
GlsPropStringQuoted(const std::string &str)
Definition: util.h:1298
virtual void StreamOut(ostreamType &outstr) const
Definition: util.h:1125
std::string GetExtension(const std::string &filename)
Definition: vertex.h:409
GlsDefinedColorEnum
Definition: util.h:194
bool IS_NEGATIVE(const X &x)
Definition: util.h:139
const int INLINE_TEXTURE_LINE_LENGTH
Definition: util.h:121
Definition: util.h:1285
std::string & String()
Definition: util.h:1249
std::string FileExtension(const std::string &filepath)
void GlsGetPerspective(GlsMatrixType &m, double fovy, double aspect, double zNear, double zFar)
GlsPropString(const char *str)
Definition: util.h:1236
unsigned char glsDefinedColors[GLS_COLOR_MAX][4]
bool IsNearZero(X x)
Definition: util.h:158
virtual bool operator!=(const GlsMultiVal &val) const
Definition: util.h:1116
Definition: dynamic_array.h:62
The disti::DynamicArray class. A templated array of objects capable of dynamically growing...
Class to contain current OpenGL view, projection and draw matrices.
Definition: util.h:301
std::string FileName(const std::string &filepath)
const char * GetBaseName(const char *path)
bool VeryCloseToZero(X x)
Definition: util.h:154
int EncodeString(char *dest, const char *src, const int dest_str_length)
The GlsMatrixAffine class.
Definition: util.h:883
void AppendTrailingSlash(char *s)
Definition: util.h:968
GlsFontMan & GetFontMan()
Gets the global font manager.
void RemoveDoubleSlashes(char *path, char slash= '/')
Definition: texture_loader.h:55
bool CheckDistiLicense(const char *licenseGroupName, const char *feature, const char *version, bool quiet)
std::string GetQualifiedInstanceName(const DisplayFrame *topFrame, const DisplayObject *obj)
Hold global objects so we can control order of destruction.
Definition: util.h:1483
std::string GetDefaultComponentClassName(const char *dllFileName)
Definition: util.h:930
bool BETWEEN(const X &x, const X1 &x1, const X2 &x2)
Definition: util.h:131
GlsMultiVal()
Definition: util.h:1027
char * PathToOS(const char *path)
bool IS_ZERO(X x)
Definition: util.h:162
Definition: gls_state_manager_interface.h:67
void RemoveSpaces(std::string &entry)
float OpenGLVersion()
Definition: util.h:337
const T & Max(const T &x, const T &y)
Definition: util.h:273
virtual bool operator==(const GlsMultiVal &val) const
Definition: util.h:1090
GlsPropStringQuoted(const char *str)
Definition: util.h:1306
A file for all GL Studio files to include.
Mutex & GetImageListMutex()
Gets the mutex for protecting the image list.
int range_check(int num, double val,...)
std::ostream & operator<<(std::ostream &outstr, const AttributeName &name)
Defines the stream out operator.
bool GetObjectCoordinatesTransformSameView(DisplayObject *from, DisplayObject *to, GlsMatrixType *outTransform)
float AngularDistanceRad(float angle1, float angle2)
std::string Uppercase(const std::string &str)
void ChangeGlsDefinedColor(GlsDefinedColorEnum index, unsigned char red, unsigned char green, unsigned char blue, unsigned char alpha)
Definition: util.h:223
Definition: scoped_ptr.h:53
GlsPropString()
Definition: util.h:1219
void PopResourcePath()
VertexNoColor Vector
Definition: gls_font_base.h:66
GlsMatrixAffine< T > FindCoordinateTransformation(const Vector &new_origin, const Vector &new_i, const Vector &new_j, const Vector &new_k)
Definition: util.h:381
bool FindNonColinearVertices(int arraySize, Vector array[], int &index1, int &index2, int &index3, bool isVectorArray=true)
Definition: util.h:1213
bool GetObjectCoordinatesTransform(DisplayObject *from, DisplayObject *to, GlsMatrixType *outTransform)
int DecodeString(char *dest, const char *src, const int dest_str_length)
bool GetComponentClassNames(const char *dllFileName, DynamicArray< std::string, false > &nameList, const char *createClassTag="CreateComponent_")
void Count(const unsigned int count)
Definition: dynamic_array.h:115
bool CalculateTexPointsFromTexCoords(DisplayObject *object)
TextureLoaderList & GetTextureLoaders()
Gets the global list of texture loaders.
Definition: gls_mutex.h:52
friend bool operator!=(const GlsPropString &str1, const GlsPropString &str2)
Definition: util.h:1261
Definition: util.h:566
The disti::Vertex class. A class for manipulating 3D vertices.
GlsMultiVal(const GlsMultiVal &src)
Definition: util.h:1037
void PushResourcePath(const char *resourcePath)
IGlsStateManager & GetStateManager()
Gets the global state manager instance.
void Translate(Type x, Type y, Type z)
Definition: gls_matrix_affine.h:196
bool FileExists(const char *filename)
int C_EncodeString(char *dest, const char *src, const int dest_str_length)
static GlsGlobals & Instance()
Singleton instance.
virtual void StreamIn(istreamType &instr)
Definition: util.h:1152
GlsMultiVal(const T1 &val1, const T2 &val2=T2(), const T3 &val3=T3(), const T4 &val4=T4(), const T5 &val5=T5(), const T6 &val6=T6(), const T7 &val7=T7(), const T8 &val8=T8(), const T9 &val9=T9(), const T10 &val10=T10())
Definition: util.h:1064
FILE * gls_fopen(const char *filename, const char *flags)
bool IsDirectory(const char *filename)
float AngularDistanceDeg(float angle1, float angle2)
std::string FilePath(const std::string &filepath)
Definition: gls_font_man.h:59
bool Equal(T1 x, T2 y, float precision=0.001f)
Definition: util.h:251
char * GetFileName(const char *name)
List_c & GetImageList()
Gets the image list.
bool NotColinear(const Vector &a, const Vector &b, const Vector &c)
const char * GetFilePath(const char *name)
Definition: vertex.h:84
std::string ResolveRuntimeResourcePath(const char *fileName)
void PushResourceFinder(std::string(*finder)(const std::string &))
A smart pointer with unique ownership – poor man's std::unique_ptr.
std::string ResolvePath(const char *path)
bool CloseToZero(const X x, const X threshold=X(1e-1))
Definition: util.h:147
friend bool operator==(const GlsPropString &str1, const GlsPropString &str2)
Definition: util.h:1255
Contains the DistiAssert macro.
Definition: util.h:902
Macros and helper code to determine what subset of C++11/14/17 is available.
void GlsGetOrtho(GlsMatrixType &m, double left, double right, double bottom, double top, double zNear, double zFar)
GlsPropString(const std::string &str)
Definition: util.h:1227
int Safe_fopen(const char *filename, char *flags, FILE **f)
unsigned char * GlsDefinedColor(GlsDefinedColorEnum index)
Definition: util.h:215
Definition: bmpimage.h:46
Definition: list.h:134
GlsPropStringQuoted()
Definition: util.h:1291
bool IS_POSITIVE(const X &x)
Definition: util.h:143