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