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