├── debian ├── compat ├── docs ├── libcvars1.dirs ├── source │ └── format ├── libcvars1.install ├── libcvars-dev.dirs ├── rules ├── libcvars-dev.install ├── changelog ├── control └── copyright ├── examples ├── CMakeLists.txt ├── TextConsole │ ├── CMakeLists.txt │ └── TextConsoleDemo.cpp ├── Demo2 │ ├── CMakeLists.txt │ ├── Point3D.h │ ├── Pyramid.h │ ├── Point3D.cc │ ├── Pyramid.cc │ └── demo2.cc ├── GlutConsole │ ├── CMakeLists.txt │ └── GlutConsoleDemo.cpp └── FltkConsole │ ├── CMakeLists.txt │ ├── FltkCVarsDemo.cpp │ ├── GLCube.h │ └── GLHelpers.h ├── .gitignore ├── cmake_modules ├── PkgConfig.pc.in ├── FindPackage.cmake.in ├── PackageConfigVersion.cmake.in ├── FindGLUES.cmake ├── FindFREEGLUT.cmake ├── SetPlatformVars.cmake ├── PackageConfig.cmake.in ├── FindTinyXML2.cmake ├── FindGLEW.cmake ├── cmake_uninstall.cmake.in ├── FindCVARS.cmake └── install_package.cmake ├── src ├── CVar.cpp ├── config.h.in ├── TrieNode.cpp ├── Timestamp.cpp ├── CVarParse.cpp └── Trie.cpp ├── README ├── include ├── cvars │ ├── Timestamp.h │ ├── TrieNode.h │ ├── CVarVectorIO.h │ ├── glplatform.h │ ├── Trie.h │ ├── CVarMapIO.h │ └── CVar.h ├── GLConsole │ ├── GLColor.h │ ├── GLFont.h │ └── GLConsoleFunction.h ├── TextConsole │ └── TextConsoleFunction.h └── FLConsole │ └── FLConsoleFunction.h ├── package.xml ├── CMakeLists.txt └── LICENSE /debian/compat: -------------------------------------------------------------------------------- 1 | 9 2 | -------------------------------------------------------------------------------- /debian/docs: -------------------------------------------------------------------------------- 1 | README 2 | -------------------------------------------------------------------------------- /debian/libcvars1.dirs: -------------------------------------------------------------------------------- 1 | usr/lib 2 | -------------------------------------------------------------------------------- /debian/source/format: -------------------------------------------------------------------------------- 1 | 3.0 (quilt) 2 | -------------------------------------------------------------------------------- /debian/libcvars1.install: -------------------------------------------------------------------------------- 1 | usr/lib/lib*.so.* 2 | -------------------------------------------------------------------------------- /debian/libcvars-dev.dirs: -------------------------------------------------------------------------------- 1 | usr/lib 2 | usr/include 3 | -------------------------------------------------------------------------------- /examples/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | SUBDIRS( GlutConsole ) 3 | 4 | -------------------------------------------------------------------------------- /debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | include /usr/share/dpkg/default.mk 3 | 4 | %: 5 | dh $@ 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | CVars/CVarVersion.h 2 | CMakeLists.txt.user 3 | build 4 | debug 5 | abuild 6 | libs 7 | .DS_Store 8 | -------------------------------------------------------------------------------- /debian/libcvars-dev.install: -------------------------------------------------------------------------------- 1 | usr/include/* 2 | usr/lib/lib*.a 3 | usr/lib/lib*.so 4 | usr/lib/pkgconfig/* 5 | usr/share/pkgconfig/* 6 | -------------------------------------------------------------------------------- /debian/changelog: -------------------------------------------------------------------------------- 1 | cvars (2.6.0-1) unstable; urgency=low 2 | 3 | * Initial release (Closes: #1234) 4 | 5 | -- Gabe Sibley Wed, 21 Oct 2015 17:31:00 -0700 6 | -------------------------------------------------------------------------------- /examples/TextConsole/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8) 2 | INCLUDE_DIRECTORIES( ${CMAKE_SOURCE_DIR} ) 3 | ADD_EXECUTABLE( TextConsoleDemo TextConsoleDemo.cpp ) 4 | TARGET_LINK_LIBRARIES( TextConsoleDemo cvars ) 5 | 6 | -------------------------------------------------------------------------------- /cmake_modules/PkgConfig.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@CMAKE_INSTALL_PREFIX@ 2 | exec_prefix=${prefix} 3 | libdir=${exec_prefix}/lib 4 | includedir=${prefix}/include 5 | 6 | Name: @PACKAGE_PKG_NAME@ 7 | Description: @PACKAGE_DESCRIPTION@ 8 | Version: @PACKAGE_VERSION@ 9 | Cflags: 10 | Libs: -L${libdir} @PACKAGE_LIBS@ @PACKAGE_LIB_LINK@ 11 | 12 | -------------------------------------------------------------------------------- /src/CVar.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | namespace CVarUtils 5 | { 6 | 7 | struct TrieContext 8 | { 9 | TrieContext() { 10 | trie.Init(); 11 | } 12 | 13 | Trie trie; 14 | }; 15 | 16 | Trie& TrieInstance() 17 | { 18 | static TrieContext context; 19 | return context.trie; 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /examples/TextConsole/TextConsoleDemo.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************************* 2 | * 3 | * CVars demo using standard input. 4 | * 5 | *******************************************************************/ 6 | 7 | #include 8 | 9 | #include 10 | 11 | 12 | int main( int, char** ) 13 | { 14 | TextConsole Console; 15 | 16 | while(1){ 17 | int c = KbHit(); 18 | Console.ProcessKey( c ); 19 | } 20 | } 21 | 22 | -------------------------------------------------------------------------------- /examples/Demo2/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | FIND_PACKAGE( GLUT REQUIRED ) 2 | FIND_PACKAGE( GLU REQUIRED ) 3 | FIND_PACKAGE( OpenGL REQUIRED ) 4 | 5 | IF( APPLE AND OPENGL_FOUND ) 6 | ADD_DEFINITIONS( -DHAVE_APPLE_OPENGL_FRAMEWORK ) 7 | ENDIF( APPLE AND OPENGL_FOUND) 8 | 9 | INCLUDE_DIRECTORIES( ${CMAKE_SOURCE_DIR} ${GLUT_INCLUDE_DIR} ) 10 | LINK_DIRECTORIES( "../../CVars/" "../../GLConsole/" ) 11 | ADD_EXECUTABLE( GLConsoleDemo2 demo2.cc Pyramid.cc Point3D.cc ) 12 | TARGET_LINK_LIBRARIES( GLConsoleDemo2 cvars ${GLUT_LIBRARIES} ${GLU_LIBRARIES} ${OPENGL_LIBRARIES} ) 13 | 14 | 15 | -------------------------------------------------------------------------------- /cmake_modules/FindPackage.cmake.in: -------------------------------------------------------------------------------- 1 | 2 | SET( @PACKAGE_PKG_NAME@_LIBRARIES @PACKAGE_LINK_LIBS@ CACHE INTERNAL "@PACKAGE_PKG_NAME@ libraries" FORCE ) 3 | SET( @PACKAGE_PKG_NAME@_INCLUDE_DIRS @PACKAGE_INCLUDE_DIRS@ CACHE INTERNAL "@PACKAGE_PKG_NAME@ include directories" FORCE ) 4 | SET( @PACKAGE_PKG_NAME@_LIBRARY_DIRS @PACKAGE_LINK_DIRS@ CACHE INTERNAL "@PACKAGE_PKG_NAME@ library directories" FORCE ) 5 | 6 | mark_as_advanced( @PACKAGE_PKG_NAME@_LIBRARIES ) 7 | mark_as_advanced( @PACKAGE_PKG_NAME@_LIBRARY_DIRS ) 8 | mark_as_advanced( @PACKAGE_PKG_NAME@_INCLUDE_DIRS ) 9 | 10 | 11 | -------------------------------------------------------------------------------- /debian/control: -------------------------------------------------------------------------------- 1 | Source: cvars 2 | Priority: optional 3 | Maintainer: Gabe Sibley 4 | Build-Depends: debhelper (>= 9), cmake 5 | Standards-Version: 3.9.5 6 | Section: libs 7 | Homepage: http://github.com/arpg/cvars 8 | 9 | Package: libcvars 10 | Section: libdevel 11 | Architecture: any 12 | Depends: ${shlibs:Depends}, ${misc:Depends}, libtinyxml, libglew 13 | Description: Console-based run-time tweaking of C++ variables. 14 | Within CVars, GLConsole is an example that allows OpenGL developers to easily 15 | add a 'Quake-style' debugging console to their applications. GLConsole relies 16 | on CVars. 17 | 18 | -------------------------------------------------------------------------------- /examples/GlutConsole/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | FIND_PACKAGE( GLUT REQUIRED ) 2 | FIND_PACKAGE( GLEW REQUIRED ) 3 | #FIND_PACKAGE( GLU REQUIRED ) 4 | FIND_PACKAGE( OpenGL REQUIRED ) 5 | 6 | IF( APPLE AND OPENGL_FOUND ) 7 | ADD_DEFINITIONS( -DHAVE_APPLE_OPENGL_FRAMEWORK ) 8 | ENDIF( APPLE AND OPENGL_FOUND) 9 | 10 | INCLUDE_DIRECTORIES( ${CMAKE_SOURCE_DIR} ${GLUT_INCLUDE_DIR} ${GLEW_INCLUDE_DIR} ) 11 | #LINK_DIRECTORIES( "../../CVars/" "../../GLConsole/" ) 12 | ADD_EXECUTABLE( GlutConsoleDemo GlutConsoleDemo.cpp ) 13 | TARGET_LINK_LIBRARIES( GlutConsoleDemo cvars ${GLUT_LIBRARIES} ${GLU_LIBRARIES} ${OPENGL_LIBRARIES} ${GLEW_LIBRARY} ) 14 | 15 | -------------------------------------------------------------------------------- /examples/FltkConsole/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.6) 2 | 3 | # Fltk does not support 64bits on OS X yet... 4 | #SET( CMAKE_OSX_ARCHITECTURES "i386" ) 5 | 6 | FIND_PACKAGE( FLTK REQUIRED ) 7 | FIND_PACKAGE( OpenGL REQUIRED ) 8 | 9 | INCLUDE_DIRECTORIES( ${CMAKE_SOURCE_DIR} ${FLTK_INCLUDE_DIR} ) 10 | #ADD_EXECUTABLE( Test Test.cpp ) 11 | #TARGET_LINK_LIBRARIES( Test cvars ${FLTK_LIBRARIES} ${OPENGL_LIBRARIES} ) 12 | 13 | ADD_EXECUTABLE( FltkCVarsDemo FltkCVarsDemo.cpp ) 14 | TARGET_LINK_LIBRARIES( FltkCVarsDemo cvars ${FLTK_LIBRARIES} ${OPENGL_LIBRARIES} ) 15 | 16 | #MESSAGE( STATUS "FLTK_LIBRARIES ${FLTK_LIBRARIES}" ) 17 | -------------------------------------------------------------------------------- /examples/Demo2/Point3D.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef POINT3D_H__ 3 | #define POINT3D_H__ 4 | 5 | #include 6 | 7 | class Point3D 8 | { 9 | public: 10 | Point3D(float tx = 0.0f, float ty = 0.0f, float tz = 0.0f) 11 | : x(tx), y(ty), z(tz) {} 12 | ~Point3D() {} 13 | 14 | Point3D operator+(const Point3D&) const; 15 | Point3D operator*(const Point3D&) const; 16 | 17 | float x, y, z; 18 | 19 | }; 20 | 21 | // All types you wish to use with CVars must overload << and >>. 22 | std::ostream &operator<<(std::ostream &stream, Point3D &point ); 23 | std::istream &operator>>(std::istream &stream, Point3D &point ); 24 | 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /src/config.h.in: -------------------------------------------------------------------------------- 1 | #ifndef _CVARS_CONFIG_H_ 2 | #define _CVARS_CONFIG_H_ 3 | 4 | /// Version 5 | 6 | #define CVARS_MAJOR_REV @VERSION_MAJOR@ 7 | #define CVARS_MINOR_REV @VERSION_MINOR@ 8 | #define CVARS_PATCH_REV @VERSION_PATCH@ 9 | #define CVARS_VERSION_STRING "@VERSION@" 10 | 11 | /// Platform 12 | #cmakedefine _UNIX_ 13 | #cmakedefine _WIN_ 14 | #cmakedefine _OSX_ 15 | #cmakedefine _LINUX_ 16 | #cmakedefine _ANDROID_ 17 | 18 | /// Compiler 19 | #cmakedefine _GCC_ 20 | #cmakedefine _MSVC_ 21 | 22 | /// Optional Libraries 23 | #cmakedefine HAVE_APPLE_OPENGL_FRAMEWORK 24 | #cmakedefine HAVE_GLEW 25 | #cmakedefine HAVE_GLES 26 | #cmakedefine HAVE_FREEGLUT 27 | #cmakedefine HAVE_MODIFIED_OSXGLUT 28 | 29 | #endif //_CVARS_CONFIG_H_ 30 | -------------------------------------------------------------------------------- /cmake_modules/PackageConfigVersion.cmake.in: -------------------------------------------------------------------------------- 1 | set(PACKAGE_VERSION "@PACKAGE_VERSION@") 2 | 3 | # Check build type is valid 4 | if( "System:${CMAKE_SYSTEM_NAME},Android:${ANDROID},iOS:${IOS}" STREQUAL 5 | "System:@CMAKE_SYSTEM_NAME@,Android:@ANDROID@,iOS:@IOS@" ) 6 | # Check whether the requested PACKAGE_FIND_VERSION is compatible 7 | if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}") 8 | set(PACKAGE_VERSION_COMPATIBLE FALSE) 9 | else() 10 | set(PACKAGE_VERSION_COMPATIBLE TRUE) 11 | if ("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}") 12 | set(PACKAGE_VERSION_EXACT TRUE) 13 | endif() 14 | endif() 15 | else() 16 | set(PACKAGE_VERSION_COMPATIBLE FALSE) 17 | endif() 18 | -------------------------------------------------------------------------------- /examples/Demo2/Pyramid.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef PYRAMID_H__ 3 | #define PYRAMID_H__ 4 | 5 | #include "Point3D.h" 6 | 7 | class Pyramid 8 | { 9 | public: 10 | Pyramid(); 11 | ~Pyramid(); 12 | void Draw(); 13 | void Reset(); 14 | 15 | private: 16 | void glVertex( Point3D &p ); 17 | 18 | private: 19 | Point3D &mpPos; //Centre of the pyramid 20 | Point3D mpRot; //use a point to hold rotation information for each axis 21 | Point3D &mpRotDelta; //how much to change the rotation by each time 22 | Point3D &mpScale; //Scale factor for the size of the pyramid 23 | Point3D &mpP1; //the 5 points of the pyramid 24 | Point3D &mpP2; 25 | Point3D &mpP3; 26 | Point3D &mpP4; 27 | Point3D &mpP5; 28 | 29 | }; 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /cmake_modules/FindGLUES.cmake: -------------------------------------------------------------------------------- 1 | # Try to find the GLUES lib and include files 2 | # 3 | # GLUES_INCLUDE_DIR 4 | # GLUES_LIBRARIES 5 | # GLUES_FOUND 6 | 7 | FIND_PATH( GLUES_INCLUDE_DIR glues/glues.h 8 | /usr/include 9 | /usr/local/include 10 | /opt/include 11 | /opt/local/include 12 | ${CMAKE_INSTALL_PREFIX}/include 13 | ) 14 | 15 | FIND_LIBRARY( GLUES_LIBRARY glues 16 | /usr/lib64 17 | /usr/lib 18 | /usr/local/lib 19 | /opt/local/lib 20 | /opt/local/lib64 21 | ${CMAKE_INSTALL_PREFIX}/lib 22 | ) 23 | 24 | IF(GLUES_INCLUDE_DIR AND GLUES_LIBRARY) 25 | SET( GLUES_FOUND TRUE ) 26 | SET( GLUES_LIBRARIES ${GLUES_LIBRARY} ) 27 | ENDIF(GLUES_INCLUDE_DIR AND GLUES_LIBRARY) 28 | 29 | IF(GLUES_FOUND) 30 | IF(NOT GLUES_FIND_QUIETLY) 31 | MESSAGE(STATUS "Found GLUES: ${GLUES_LIBRARY}") 32 | ENDIF(NOT GLUES_FIND_QUIETLY) 33 | ELSE(GLUES_FOUND) 34 | IF(GLUES_FIND_REQUIRED) 35 | MESSAGE(FATAL_ERROR "Could not find GLUES") 36 | ENDIF(GLUES_FIND_REQUIRED) 37 | ENDIF(GLUES_FOUND) 38 | 39 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | CVars is a small C++ library that allows run-time tweaking of variables. 2 | 3 | Within CVars, GLConsole is an example that allows OpenGL developers to easily 4 | add a 'Quake-style' debugging console to their applications. GLConsole relies 5 | on CVars. 6 | 7 | A short list of features: 8 | 9 | - Any variable in your code can easily be exposed for tweaking from the console. 10 | - New object types to be easily exposed in the console (just overload << and >>) 11 | - Full and partial tab completion with suggestions and commmand history 12 | - Scrolling with shift+up/shift+down and page-up/page-down. 13 | - Printf style logging functions to send any error or status messages to the 14 | console 15 | - Custom console functions that take an arbitrary number of parameters allow 16 | the console to perform arbitrary tasks 17 | 18 | 19 | To use the GLUT interface, just include . See the demo 20 | in the Example directory to see how use GLConsole with GLUT. 21 | 22 | To use the FLTK interface, just include . See the demo 23 | in the Example directory to see how use FLConsole with FLTK. 24 | 25 | 26 | -------------------------------------------------------------------------------- /include/cvars/Timestamp.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Cross platform "CVars" functionality. 4 | 5 | This Code is covered under the LGPL. See COPYING file for the license. 6 | 7 | $Id: Timestamp.h 162 2010-02-15 19:11:05Z gsibley $ 8 | 9 | */ 10 | 11 | 12 | // cross platform timing utility 13 | #ifndef __TIMESTAMP_H__ 14 | #define __TIMESTAMP_H__ 15 | 16 | #include 17 | 18 | #ifndef WIN32 19 | # include 20 | #endif 21 | 22 | class TimeStamp 23 | { 24 | public: 25 | TimeStamp(); 26 | void Stamp(); 27 | double Elapsed(); //in seconds since last "stamp" 28 | double TotalElapsed(); //total since first stamp 29 | int ElapsedFrames(double frameTime, double factor=1.0); //given target time in millisecs per frames 30 | 31 | #ifdef _WIN_ 32 | //allow timer to be pauses in between "stamps" 33 | void Pause(); 34 | //unpause the timer... 35 | void UnPause(); 36 | #endif 37 | 38 | private: 39 | int start; 40 | 41 | #ifndef _WIN_ 42 | struct timeval prevTime, startTime; 43 | struct timezone tz; 44 | #else 45 | double prevTime, startTime; 46 | double pauseTime; 47 | bool isPaused; 48 | #endif 49 | 50 | double overflow; 51 | 52 | }; 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /cmake_modules/FindFREEGLUT.cmake: -------------------------------------------------------------------------------- 1 | # Try to find the FREEGLUT library 2 | # 3 | # FREEGLUT_INCLUDE_DIR 4 | # FREEGLUT_LIBRARY 5 | # FREEGLUT_FOUND 6 | 7 | FIND_PATH( 8 | FREEGLUT_INCLUDE_DIR GL/freeglut.h 9 | ${CMAKE_INCLUDE_PATH} 10 | $ENV{include} 11 | ${OPENGL_INCLUDE_DIR} 12 | /usr/include 13 | /usr/local/include 14 | ) 15 | 16 | SET(STORE_CMAKE_FIND_FRAMEWORK ${CMAKE_FIND_FRAMEWORK}) 17 | SET(CMAKE_FIND_FRAMEWORK NEVER) 18 | 19 | FIND_LIBRARY( 20 | FREEGLUT_LIBRARY 21 | NAMES freeglut_static freeglut glut 22 | PATH 23 | /opt/local/lib 24 | ${CMAKE_LIBRARY_PATH} 25 | $ENV{lib} 26 | /usr/lib 27 | /usr/local/lib 28 | ) 29 | 30 | SET(CMAKE_FIND_FRAMEWORK ${STORE_CMAKE_FIND_FRAMEWORK}) 31 | 32 | IF (FREEGLUT_INCLUDE_DIR AND FREEGLUT_LIBRARY) 33 | SET(FREEGLUT_FOUND TRUE) 34 | ENDIF (FREEGLUT_INCLUDE_DIR AND FREEGLUT_LIBRARY) 35 | 36 | IF (FREEGLUT_FOUND) 37 | IF (NOT FREEGLUT_FIND_QUIETLY) 38 | MESSAGE(STATUS "Found FREEGLUT: ${FREEGLUT_LIBRARY}") 39 | ENDIF (NOT FREEGLUT_FIND_QUIETLY) 40 | ELSE (FREEGLUT_FOUND) 41 | IF (FREEGLUT_FIND_REQUIRED) 42 | MESSAGE(FATAL_ERROR "Could not find FREEGLUT") 43 | ENDIF (FREEGLUT_FIND_REQUIRED) 44 | ENDIF (FREEGLUT_FOUND) 45 | -------------------------------------------------------------------------------- /debian/copyright: -------------------------------------------------------------------------------- 1 | Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ 2 | Upstream-Name: cvars 3 | Source: http://github.com/arpg/cvars 4 | 5 | Files: * 6 | Copyright: 2008-2015 Gabe Sibley 7 | 2004-2010 Michale Mendal 8 | License: LGPL-3.0+ 9 | 10 | Files: debian/* 11 | Copyright: 2015 Gabe Sibley 12 | License: LGPL-3.0+ 13 | 14 | License: LGPL-3.0+ 15 | This package is free software; you can redistribute it and/or 16 | modify it under the terms of the GNU Lesser General Public 17 | License as published by the Free Software Foundation; either 18 | version 3 of the License, or (at your option) any later version. 19 | . 20 | This package is distributed in the hope that it will be useful, 21 | but WITHOUT ANY WARRANTY; without even the implied warranty of 22 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 23 | Lesser General Public License for more details. 24 | . 25 | You should have received a copy of the GNU General Public License 26 | along with this program. If not, see . 27 | . 28 | On Debian systems, the complete text of the GNU Lesser General 29 | Public License can be found in "/usr/share/common-licenses/LGPL-3". 30 | 31 | -------------------------------------------------------------------------------- /include/cvars/TrieNode.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Cross platform "CVars" functionality. 4 | 5 | This Code is covered under the LGPL. See COPYING file for the license. 6 | 7 | $Id: TrieNode.h 162 2010-02-15 19:11:05Z gsibley $ 8 | 9 | */ 10 | 11 | 12 | #ifndef _TRIE_NODE_H__ 13 | #define _TRIE_NODE_H__ 14 | 15 | #include 16 | #include 17 | #include 18 | 19 | enum TrieNodeType 20 | { 21 | TRIE_LEAF=0, 22 | TRIE_NODE, 23 | TRIE_ROOT 24 | }; 25 | 26 | class TrieNode 27 | { 28 | public: 29 | TrieNode(); 30 | TrieNode( TrieNodeType t ); 31 | TrieNode( std::string s ); 32 | TrieNode( char c ); 33 | ~TrieNode(); //destroy all nodes 34 | 35 | TrieNode* TraverseInsert( char addchar ); 36 | TrieNode* TraverseFind( char addchar ); 37 | void PrintToVector( std::vector &vec ); 38 | void PrintNodeToVector( std::vector &vec ); 39 | 40 | void* m_pNodeData; 41 | std::list m_children; 42 | TrieNodeType m_nNodeType; 43 | 44 | // private: 45 | std::string m_sLeafText; 46 | char m_cNodeChar; 47 | }; 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /cmake_modules/SetPlatformVars.cmake: -------------------------------------------------------------------------------- 1 | ## Compiler configuration 2 | IF(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_GNUCC) 3 | SET(_GCC_ 1) 4 | ENDIF() 5 | 6 | IF(${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang") 7 | SET(_CLANG_ 1) 8 | ENDIF() 9 | 10 | IF(MSVC) 11 | SET(_MSVC_ 1) 12 | ENDIF() 13 | 14 | ## Platform configuration 15 | 16 | IF(WIN32 OR WIN64) 17 | SET(_WIN_ 1) 18 | ENDIF() 19 | 20 | IF(UNIX) 21 | SET(_UNIX_ 1) 22 | ENDIF() 23 | 24 | IF(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") 25 | SET(_OSX_ 1) 26 | ENDIF() 27 | 28 | IF(${CMAKE_SYSTEM_NAME} MATCHES "Linux") 29 | SET(_LINUX_ 1) 30 | ENDIF() 31 | 32 | IF(ANDROID) 33 | SET(_ANDROID_ 1) 34 | ENDIF() 35 | 36 | IF(IOS) 37 | SET(_APPLE_IOS_ 1) 38 | ENDIF() 39 | 40 | 41 | 42 | ## Default search paths 43 | 44 | IF(_WIN_) 45 | IF(${CMAKE_CL_64}) 46 | LIST(APPEND CMAKE_INCLUDE_PATH "c:/dev/sysroot64/usr/include") 47 | LIST(APPEND CMAKE_LIBRARY_PATH "c:/dev/sysroot64/usr/lib") 48 | LIST(APPEND CMAKE_LIBRARY_PATH "c:/dev/sysroot64/usr/bin") 49 | ELSE() 50 | LIST(APPEND CMAKE_INCLUDE_PATH "c:/dev/sysroot32/usr/include") 51 | LIST(APPEND CMAKE_LIBRARY_PATH "c:/dev/sysroot32/usr/lib") 52 | LIST(APPEND CMAKE_LIBRARY_PATH "c:/dev/sysroot32/usr/bin") 53 | ENDIF() 54 | ENDIF() 55 | -------------------------------------------------------------------------------- /cmake_modules/PackageConfig.cmake.in: -------------------------------------------------------------------------------- 1 | SET( @PACKAGE_PKG_NAME@_LIBRARIES "@PACKAGE_LINK_LIBS@" CACHE INTERNAL "@PACKAGE_PKG_NAME@ libraries" FORCE ) 2 | SET( @PACKAGE_PKG_NAME@_INCLUDE_DIRS @PACKAGE_INCLUDE_DIRS@ CACHE INTERNAL "@PACKAGE_PKG_NAME@ include directories" FORCE ) 3 | SET( @PACKAGE_PKG_NAME@_LIBRARY_DIRS @PACKAGE_LINK_DIRS@ CACHE INTERNAL "@PACKAGE_PKG_NAME@ library directories" FORCE ) 4 | 5 | mark_as_advanced( @PACKAGE_PKG_NAME@_LIBRARIES ) 6 | mark_as_advanced( @PACKAGE_PKG_NAME@_LIBRARY_DIRS ) 7 | mark_as_advanced( @PACKAGE_PKG_NAME@_INCLUDE_DIRS ) 8 | 9 | 10 | 11 | # Compute paths 12 | get_filename_component( PACKAGE_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH ) 13 | 14 | # This file, when used for INSTALLED code, does not use Targets... sigh. 15 | ## Library dependencies (contains definitions for IMPORTED targets) 16 | #if(NOT TARGET "@PACKAGE_PKG_NAME@_LIBRARIES" AND NOT "@PACKAGE_PKG_NAME@_BINARY_DIR") 17 | # include( "${PACKAGE_CMAKE_DIR}/@PACKAGE_PKG_NAME@Targets.cmake" ) 18 | # include( "${PACKAGE_CMAKE_DIR}/@PACKAGE_PKG_NAME@ConfigVersion.cmake" ) 19 | #endif() 20 | 21 | #SET(@PACKAGE_PKG_NAME@_LIBRARIES @PACKAGE_LIBRARIES@) 22 | #SET(@PACKAGE_PKG_NAME@_LIBRARY @PACKAGE_LIBRARY@) 23 | #SET(@PACKAGE_PKG_NAME@_INCLUDE_DIRS @PACKAGE_INCLUDE_DIRS@) 24 | #SET(@PACKAGE_PKG_NAME@_LINK_DIRS @PACKAGE_LINK_DIRS@) 25 | -------------------------------------------------------------------------------- /examples/Demo2/Point3D.cc: -------------------------------------------------------------------------------- 1 | #include "Point3D.h" 2 | 3 | #include 4 | #include 5 | 6 | #ifndef NAME_MAX 7 | # define NAME_MAX 1024 8 | #endif 9 | 10 | 11 | /** 12 | * Overloaded stream out for Point3D. Converts it to a string 13 | */ 14 | std::ostream &operator<<(std::ostream &stream, Point3D &point) 15 | { 16 | stream << "[ " << point.x << ", " << point.y << ", " << point.z << " ]"; 17 | return stream; 18 | } 19 | 20 | /** 21 | * Overloaded stream in for Point3D. Converts it from a string 22 | */ 23 | std::istream &operator>>(std::istream &stream, Point3D &point) 24 | { 25 | char str[NAME_MAX] = {0}; 26 | stream.readsome( str, NAME_MAX ); 27 | sscanf( str, "[ %f, %f, %f ]", &point.x, &point.y, &point.z ); 28 | 29 | return stream; 30 | } 31 | 32 | /** 33 | * add points together 34 | */ 35 | Point3D Point3D::operator+(const Point3D& that) const 36 | { 37 | Point3D result; 38 | result.x = this->x + that.x; 39 | result.y = this->y + that.y; 40 | result.z = this->z + that.z; 41 | return result; 42 | } 43 | 44 | /** 45 | * multiply points together 46 | */ 47 | Point3D Point3D::operator*(const Point3D& that) const 48 | { 49 | Point3D result; 50 | result.x = this->x * that.x; 51 | result.y = this->y * that.y; 52 | result.z = this->z * that.z; 53 | return result; 54 | } 55 | -------------------------------------------------------------------------------- /cmake_modules/FindTinyXML2.cmake: -------------------------------------------------------------------------------- 1 | # FractalImages 2 | # Copyright (C) 2012 Sven Hertle 3 | # 4 | # This program is free software; you can redistribute it and/or modify it under 5 | # the terms of the GNU General Public License as published by the Free Software 6 | # Foundation; either version 3 of the License, or (at your option) any later 7 | # version. 8 | # 9 | # This program is distributed in the hope that it will be useful, but WITHOUT ANY 10 | # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 11 | # PARTICULAR PURPOSE. See the GNU General Public License for more details. 12 | # 13 | # You should have received a copy of the GNU General Public License along with 14 | # this program; if not, see . 15 | 16 | # Find TinyXML2 17 | # 18 | # TinyXML2_FOUND True if TinyXML2 was found 19 | # TinyXML2_INCLUDE_DIR Directory with headers 20 | # TinyXML2_LIBRARIES List of libraries 21 | # 22 | 23 | find_path(TinyXML2_INCLUDE_DIR "tinyxml2.h") 24 | 25 | find_library(TinyXML2_LIBRARIES NAMES "tinyxml2") 26 | 27 | include(FindPackageHandleStandardArgs) 28 | find_package_handle_standard_args("TinyXML2" DEFAULT_MSG TinyXML2_INCLUDE_DIR TinyXML2_LIBRARIES) 29 | set(TinyXML2_FOUND ${TINYXML2_FOUND} CACHE BOOL "TinyXML2 was found or not" FORCE) 30 | 31 | mark_as_advanced(TinyXML2_INCLUDE_DIR TinyXML2_LIBRARIES) 32 | 33 | message(STATUS "TinyXML2_INCLUDE_DIR: ${TinyXML2_INCLUDE_DIR}") 34 | message(STATUS "TinyXML2_LIBRARIES: ${TinyXML2_LIBRARIES}") 35 | -------------------------------------------------------------------------------- /cmake_modules/FindGLEW.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # Try to find GLEW library and include path. 3 | # Once done this will define 4 | # 5 | # GLEW_FOUND 6 | # GLEW_INCLUDE_DIR 7 | # GLEW_LIBRARY 8 | # 9 | 10 | IF (WIN32) 11 | FIND_PATH( GLEW_INCLUDE_DIR GL/glew.h 12 | $ENV{PROGRAMFILES}/GLEW/include 13 | ${PROJECT_SOURCE_DIR}/src/nvgl/glew/include 14 | DOC "The directory where GL/glew.h resides") 15 | FIND_LIBRARY( GLEW_LIBRARY 16 | NAMES glew GLEW glew32 glew32s 17 | PATHS 18 | $ENV{PROGRAMFILES}/GLEW/lib 19 | ${PROJECT_SOURCE_DIR}/src/nvgl/glew/bin 20 | ${PROJECT_SOURCE_DIR}/src/nvgl/glew/lib 21 | DOC "The GLEW library") 22 | ELSE (WIN32) 23 | FIND_PATH( GLEW_INCLUDE_DIR GL/glew.h 24 | /usr/include 25 | /usr/local/include 26 | /sw/include 27 | /opt/local/include 28 | DOC "The directory where GL/glew.h resides") 29 | FIND_LIBRARY( GLEW_LIBRARY 30 | NAMES GLEW glew 31 | PATHS 32 | /usr/lib64 33 | /usr/lib 34 | /usr/local/lib64 35 | /usr/local/lib 36 | /sw/lib 37 | /opt/local/lib 38 | DOC "The GLEW library") 39 | ENDIF (WIN32) 40 | 41 | IF (GLEW_INCLUDE_DIR AND GLEW_LIBRARY) 42 | SET( GLEW_FOUND TRUE ) 43 | ENDIF (GLEW_INCLUDE_DIR AND GLEW_LIBRARY) 44 | 45 | IF (GLEW_FOUND) 46 | IF (NOT GLEW_FIND_QUIETLY) 47 | MESSAGE(STATUS "Found GLEW: ${GLEW_LIBRARY}") 48 | ENDIF (NOT GLEW_FIND_QUIETLY) 49 | ELSE (GLEW_FOUND) 50 | IF (GLEW_FIND_REQUIRED) 51 | MESSAGE(FATAL_ERROR "Could not find GLEW") 52 | ENDIF (GLEW_FIND_REQUIRED) 53 | ENDIF (GLEW_FOUND) 54 | -------------------------------------------------------------------------------- /cmake_modules/cmake_uninstall.cmake.in: -------------------------------------------------------------------------------- 1 | ## A simple uninstall script. 2 | ## Alternatively UNIX users can run/sudo `xargs rm < install_manifest.txt` in the build directory. 3 | 4 | set(unfile ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake) 5 | file(WRITE ${unfile} "IF(NOT EXISTS \"install_manifest.txt\")\n") 6 | file(APPEND ${unfile} "MESSAGE(\"FATAL_ERROR Cannot find \\\"install manifest\\\": install_manifest.txt\")\n") 7 | file(APPEND ${unfile} "ENDIF(NOT EXISTS \"install_manifest.txt\")\n") 8 | file(APPEND ${unfile} "FILE(READ \"install_manifest.txt\" files)\n") 9 | file(APPEND ${unfile} "STRING(REGEX REPLACE \"\\n\" \";\" files \"\${files}\")\n") 10 | file(APPEND ${unfile} "FOREACH(file \${files})\n") 11 | file(APPEND ${unfile} " MESSAGE(STATUS \"Uninstalling \\\"\${file}\\\"\")\n") 12 | file(APPEND ${unfile} " IF(EXISTS \"\${file}\")\n") 13 | file(APPEND ${unfile} " EXEC_PROGRAM(\n") 14 | file(APPEND ${unfile} " \"\${CMAKE_COMMAND}\" ARGS \"-E remove \\\"\${file}\\\"\"\n") 15 | file(APPEND ${unfile} " OUTPUT_VARIABLE rm_out\n") 16 | file(APPEND ${unfile} " RETURN_VALUE rm_retval\n") 17 | file(APPEND ${unfile} " )\n") 18 | file(APPEND ${unfile} " IF(\"\${rm_retval}\" STREQUAL 0\)\n") 19 | file(APPEND ${unfile} " ELSE(\"\${rm_retval}\" STREQUAL 0\)\n") 20 | file(APPEND ${unfile} " MESSAGE(FATAL_ERROR \"Problem when removing \\\"\${file}\\\"\")\n") 21 | file(APPEND ${unfile} " ENDIF(\"\${rm_retval}\" STREQUAL 0)\n") 22 | file(APPEND ${unfile} " ELSE(EXISTS \"\${file}\")\n") 23 | file(APPEND ${unfile} " MESSAGE(STATUS \"File \\\"\${file}\\\" does not exist. \")\n") 24 | file(APPEND ${unfile} " ENDIF(EXISTS \"\${file}\")\n") 25 | file(APPEND ${unfile} "ENDFOREACH(file)\n") 26 | 27 | -------------------------------------------------------------------------------- /cmake_modules/FindCVARS.cmake: -------------------------------------------------------------------------------- 1 | # Try to find CVars library 2 | # 3 | # This module defines 4 | # 5 | # CVARS_FOUND - system has CVars 6 | # CVARS_INCLUDE_DIR - the CVars include directories 7 | # CVARS_LIBRARIES - link these to use CVars 8 | 9 | 10 | # Be quite if already in cache. 11 | IF( CVARS_FOUND ) 12 | SET( CVARS_FIND_QUIETLY TRUE ) 13 | ENDIF( CVARS_FOUND ) 14 | 15 | # Try to find headers. 16 | FIND_PATH( _header_dir CVars/CVar.h 17 | PATHS 18 | $ENV{HOME}/include 19 | $ENV{HOME}/local/include 20 | /usr/local/include 21 | /usr/include 22 | /opt/local/include 23 | ENV CPATH 24 | ) 25 | SET( _header_dir ${_header_dir} CACHE INTERNAL "" FORCE ) 26 | 27 | 28 | IF( NOT "${_header_dir}" STREQUAL "_header_dir-NOTFOUND" ) 29 | FIND_LIBRARY( CVARS_LIBRARIES 30 | NAMES libcvars cvars 31 | PATHS 32 | $ENV{HOME}/local/lib 33 | $ENV{HOME}/lib 34 | /usr/lib 35 | /usr/local/lib 36 | ) 37 | 38 | 39 | SET( CVARS_INCLUDE_DIR ${_header_dir} CACHE PATH "" FORCE ) 40 | ENDIF() 41 | 42 | #Did we find it? 43 | IF( CVARS_LIBRARIES AND CVARS_INCLUDE_DIR ) 44 | SET( CVARS_FOUND TRUE CACHE INTERNAL "" ) 45 | ELSE() 46 | SET( CVARS_FOUND FALSE CACHE INTERNAL "" ) 47 | ENDIF() 48 | 49 | #print out status 50 | IF( CVARS_FOUND ) 51 | IF( NOT CVARS_FIND_QUIETLY ) 52 | MESSAGE(STATUS "Looking for CVars headers -- found") 53 | MESSAGE(STATUS "Looking for CVars libraries -- found") 54 | ENDIF() 55 | ELSE() 56 | IF( CVARS_FIND_REQUIRED ) 57 | MESSAGE(FATAL_ERROR "Could not find CVars library") 58 | ENDIF() 59 | ENDIF() 60 | 61 | #MARK_AS_ADVANCED( CVARS_INCLUDE_DIR ) 62 | #MARK_AS_ADVANCED( CVARS_LIBRARIES ) 63 | 64 | -------------------------------------------------------------------------------- /include/cvars/CVarVectorIO.h: -------------------------------------------------------------------------------- 1 | #ifndef _CVAR_VECTOR_IO_H_ 2 | #define _CVAR_VECTOR_IO_H_ 3 | 4 | #include 5 | #include 6 | 7 | #define VECTOR_NAME_MAX 1000 8 | 9 | namespace CVarUtils { 10 | // All types you wish to use with CVars must overload << and >> 11 | // This is a possible overloading for vectors 12 | template 13 | std::ostream &operator<<(std::ostream &stream, std::vector& vT ) { 14 | if( vT.size() == 0 ) { 15 | stream << "[ ]"; 16 | return stream; 17 | } 18 | 19 | stream << "[ " << vT[0]; 20 | for( size_t i=1; i 30 | std::istream &operator>>(std::istream &stream, std::vector& vT ) { 31 | 32 | std::string sBuf; // Have a buffer string 33 | 34 | vT.clear(); 35 | 36 | // Only works for splitting with whitespaces 37 | while( stream >> sBuf ) { 38 | if( sBuf.find( "[" ) == std::string::npos && 39 | sBuf.find( "]" ) == std::string::npos ) { 40 | 41 | T TVal; 42 | std::stringstream( sBuf ) >> TVal; 43 | std::stringstream sCheck; 44 | sCheck << TVal; 45 | if( sBuf != sCheck.str() ) { 46 | printf( "ERROR deserialising vector, ignoring \"%s\" value.\n" , 47 | sBuf.c_str() ); 48 | continue; 49 | } 50 | 51 | vT.push_back( TVal ); 52 | } 53 | } 54 | 55 | return stream; 56 | } 57 | } 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /include/cvars/glplatform.h: -------------------------------------------------------------------------------- 1 | /* This file is ported from the Pangolin project 2 | * 3 | * http://github.com/stevenlovegrove/Pangolin 4 | * 5 | * as part of the CVars project. 6 | * 7 | * Copyright (c) 2011 Steven Lovegrove, Richard Newcombe, 8 | * 2015 Christoffer Heckman 9 | * 10 | */ 11 | 12 | #ifndef CVARS_GLPLATFORM_H 13 | #define CVARS_GLPLATFORM_H 14 | 15 | ////////////////////////////////////////////////////////// 16 | // Attempt to portably include Necessary OpenGL headers 17 | ////////////////////////////////////////////////////////// 18 | 19 | #include 20 | 21 | #ifdef _WIN_ 22 | // Define maths quantities when using to match posix systems 23 | #define _USE_MATH_DEFINES 24 | 25 | // Don't define min / max macros in windows.h or other unnecessary macros 26 | #define NOMINMAX 27 | #define WIN32_LEAN_AND_MEAN 28 | #include 29 | 30 | // Undef nuisance Windows.h macros which interfere with our methods 31 | #undef LoadImage 32 | #undef near 33 | #undef far 34 | #endif 35 | 36 | #ifdef HAVE_GLEW 37 | #include 38 | #endif 39 | 40 | #ifdef HAVE_GLES 41 | #if defined(_ANDROID_) 42 | #include 43 | #ifdef HAVE_GLES_2 44 | #include 45 | #include 46 | #else 47 | #include 48 | #define GL_GLEXT_PROTOTYPES 49 | #include 50 | #endif 51 | #elif defined(_APPLE_IOS_) 52 | #include 53 | #include 54 | #endif 55 | #else 56 | #ifdef _OSX_ 57 | #include 58 | #ifdef HAVE_APPLE_OPENGL_FRAMEWORK 59 | #include 60 | #include 61 | #include 62 | #elif defined HAVE_FREEGLUT 63 | #include 64 | #else 65 | #include 66 | #include 67 | #include 68 | #endif 69 | #else 70 | #include 71 | #endif 72 | #endif // HAVE_GLES 73 | 74 | #ifdef HAVE_FREEGLUT 75 | #include 76 | #include 77 | #include 78 | #endif 79 | 80 | #endif // CVARS_GLPLATFORM_H 81 | -------------------------------------------------------------------------------- /include/GLConsole/GLColor.h: -------------------------------------------------------------------------------- 1 | #if 0 2 | /* 3 | 4 | Cross platform OpenGL console using the "CVars" functionality. 5 | 6 | This Code is covered under the LGPL. See COPYING file for the license. 7 | 8 | $Id: GLColor.h 192 2012-03-06 01:12:01Z gsibley $ 9 | 10 | */ 11 | 12 | #ifndef GLCOLOR_H__ 13 | #define GLCOLOR_H__ 14 | 15 | #include 16 | #include 17 | 18 | //////////////////////////////////////////////////////////////////////////////// 19 | struct GLColor 20 | { 21 | GLColor( 22 | float tr = 1.0f, 23 | float tg = 1.0f, 24 | float tb = 1.0f, 25 | float ta = 1.0f 26 | ) 27 | { 28 | r = tr; 29 | g = tg; 30 | b = tb; 31 | a = ta; 32 | } 33 | 34 | GLColor( 35 | int tr, 36 | int tg, 37 | int tb, 38 | int ta = 255 39 | ) 40 | { 41 | r = tr/255.0f; 42 | g = tg/255.0f; 43 | b = tb/255.0f; 44 | a = ta/255.0f; 45 | } 46 | 47 | // float fColor[4]; 48 | float fColor[0]; 49 | struct{ 50 | float r; 51 | float g; 52 | float b; 53 | float a; 54 | }; 55 | }; 56 | 57 | 58 | #ifndef NAME_MAX 59 | # define NAME_MAX 1024 60 | #endif 61 | 62 | //////////////////////////////////////////////////////////////////////////////// 63 | /// All types you wish to use with CVars must overload << and >>. 64 | inline std::ostream &operator<<(std::ostream &stream, GLColor &color) 65 | { 66 | int r = int( 255*color.r ); 67 | int g = int( 255*color.g ); 68 | int b = int( 255*color.b ); 69 | int a = int( 255*color.a ); 70 | 71 | stream << "[ " << r << ", " << g << ", " << b << ", " << a << " ]"; 72 | return stream; 73 | } 74 | 75 | //////////////////////////////////////////////////////////////////////////////// 76 | /// All types you wish to use with CVars must overload << and >>. 77 | inline std::istream &operator>>(std::istream &stream, GLColor &color) 78 | { 79 | int r=0,g=0,b=0,a=0; 80 | 81 | char str[NAME_MAX] = {0}; 82 | stream.readsome( str, NAME_MAX ); 83 | sscanf( str, "[ %d, %d, %d, %d ]", &r, &g, &b, &a ); 84 | 85 | color.r = (float)r/255.0f; 86 | color.g = (float)g/255.0f; 87 | color.b = (float)b/255.0f; 88 | color.a = (float)a/255.0f; 89 | 90 | return stream; 91 | } 92 | 93 | #endif 94 | #endif 95 | -------------------------------------------------------------------------------- /package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | cvars 4 | 2.6.0 5 | CVars is a small C++ library that allows run-time tweaking of C++ variables. 6 | 7 | 8 | 9 | 10 | Gabe Sibley 11 | 12 | 13 | 14 | 15 | 16 | LGPL 17 | 18 | 19 | 20 | 21 | 22 | http://github.com/arpg/CVars 23 | 24 | 25 | 26 | 27 | 28 | Gabe Sibley 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | catkin 43 | glut 44 | tinyxml 45 | 46 | catkin 47 | glut 48 | tinyxml 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /examples/FltkConsole/FltkCVarsDemo.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************************* 2 | * 3 | * CVars demo using FLTK. 4 | * 5 | *******************************************************************/ 6 | 7 | #include 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include "GLHelpers.h" 14 | #include "GLCube.h" 15 | 16 | #include 17 | 18 | const double g_dFPS = 1.0/20.0; 19 | 20 | /// FLTK OpenGL window. 21 | class GLWindow : public Fl_Gl_Window 22 | { 23 | /// timer callback drives animation and forces drawing at 20 hz 24 | static void Timer(void *userdata) { 25 | GLWindow *pWin = (GLWindow*)userdata; 26 | pWin->m_Cube.m_dSpin += 3.0; 27 | pWin->redraw(); 28 | Fl::repeat_timeout( g_dFPS, Timer, userdata ); 29 | } 30 | 31 | public: 32 | 33 | /// Constructor. 34 | GLWindow(int x,int y,int w,int h,const char *l=0) : Fl_Gl_Window(x,y,w,h,l) 35 | { 36 | Fl::add_timeout( g_dFPS, Timer, (void*)this ); 37 | } 38 | 39 | /// Init OpenGL 40 | void Init() 41 | { 42 | m_Cube.Init(); 43 | // OpenGL settings 44 | glShadeModel( GL_FLAT ); 45 | glEnable( GL_DEPTH_TEST ); 46 | glDepthFunc( GL_LEQUAL ); 47 | glClearColor(.5,.5,.8, 1.0); 48 | } 49 | 50 | /// Main function called by FLTK to draw the scene. 51 | void draw() { 52 | CheckForGLErrors(); 53 | 54 | // handle reshaped viewport 55 | if ( !valid() ) { 56 | ReshapeViewport( w(), h() ); 57 | } 58 | // Initialization 59 | static bool bInitialized = false; 60 | if ( !bInitialized || !context() ) { 61 | bInitialized = true; 62 | Init(); 63 | return; 64 | } 65 | 66 | // Clear 67 | glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); 68 | 69 | // Draw objects 70 | m_Cube.draw(); 71 | m_Console.draw(); 72 | 73 | CheckForGLErrors(); 74 | } 75 | 76 | /// Pass input to FLConsole. 77 | int handle( int e ) 78 | { 79 | if( context() ){ 80 | return m_Console.handle( e ); 81 | } 82 | return false; 83 | } 84 | 85 | 86 | private: 87 | GLCube m_Cube; 88 | FLConsole m_Console; 89 | }; 90 | 91 | 92 | int main( int, char** ) 93 | { 94 | GLWindow* pWin = new GLWindow( 10, 10, 640, 480, "Fltk CVars Demo" ); 95 | pWin->end(); 96 | pWin->resizable( pWin ); 97 | 98 | pWin->show(); 99 | return( Fl::run() ); 100 | } 101 | 102 | -------------------------------------------------------------------------------- /examples/FltkConsole/GLCube.h: -------------------------------------------------------------------------------- 1 | #ifndef _CUBE_H_ 2 | #define _CUBE_H_ 3 | 4 | #include // for M_PI 5 | #include 6 | 7 | #define FPS 1.0/20.0 8 | #define TEX_W 64 9 | #define TEX_H 64 10 | 11 | class GLCube 12 | { 13 | public: 14 | double m_dSpin; 15 | 16 | public: 17 | /// OpenGL stuff to do *only once* on startup. 18 | void Init(); 19 | 20 | /// Main function called by FLTK to draw the scene. 21 | void draw(); 22 | 23 | private: 24 | GLuint m_nTexID; 25 | }; 26 | 27 | 28 | 29 | inline void GLCube::Init() 30 | { 31 | // Texture Map Init 32 | GLubyte img[TEX_W][TEX_H][3]; // after glTexImage2D(), array is no longer needed 33 | for (int x=0; x 16 | #include 17 | 18 | #include 19 | 20 | class TrieNode; 21 | 22 | 23 | namespace CVarUtils { 24 | class MemoryHolder { 25 | private: 26 | struct holder { 27 | virtual ~holder() {} 28 | }; 29 | 30 | template 31 | struct obj_holder : public holder { 32 | T obj; 33 | 34 | obj_holder() 35 | : obj() {} 36 | 37 | template 38 | obj_holder( Arg1 arg1 ) 39 | : obj(arg1) {} 40 | }; 41 | 42 | std::vector owned; 43 | 44 | private: 45 | MemoryHolder(const MemoryHolder&); 46 | void operator=(const MemoryHolder&); 47 | 48 | public: 49 | MemoryHolder() {} 50 | ~MemoryHolder() { 51 | destroy_all(); 52 | } 53 | 54 | template 55 | T* create() { 56 | obj_holder* p = new obj_holder(); 57 | owned.push_back(p); 58 | return &p->obj; 59 | } 60 | 61 | template 62 | T* create(Arg1 arg1) { 63 | obj_holder* p = new obj_holder(arg1); 64 | owned.push_back(p); 65 | return &p->obj; 66 | } 67 | 68 | void destroy_all() { 69 | for( std::vector::size_type ii = 0; ii < owned.size(); ii++ ) { 70 | delete owned[ ii ]; 71 | } 72 | owned.clear(); 73 | } 74 | }; 75 | } 76 | 77 | enum CVARS_STREAM_TYPE 78 | { 79 | CVARS_XML_STREAM, 80 | CVARS_TXT_STREAM 81 | }; 82 | 83 | class Trie 84 | { 85 | public: 86 | Trie(); 87 | ~Trie(); 88 | void Init(); 89 | // add string to tree and store data at leaf 90 | void Insert( std::string s, void *data ); 91 | // finds s in the tree and returns the node (may not be a leaf) 92 | // returns null otherwise 93 | TrieNode* FindSubStr( const std::string& s ); 94 | std::vector FindListSubStr( const std::string& s ); 95 | TrieNode* Find( const std::string& s ); 96 | void* FindData( const std::string& s ); 97 | 98 | bool Exists( const std::string& s ); 99 | 100 | TrieNode* GetRoot(); 101 | void SetAcceptedSubstrings( std::vector< std::string > vAcceptedSubstrings ); 102 | bool IsNameAcceptable( const std::string& sVarName ); 103 | bool IsVerbose(); 104 | void SetVerbose( bool bVerbose ); 105 | 106 | // does an in order traversal starting at node and printing all leaves 107 | // to a list 108 | std::vector CollectAllNames( TrieNode* node ); 109 | // traverse from the supplied node and return a list of all nodes 110 | std::vector CollectAllNodes( TrieNode* node ); 111 | 112 | CVARS_STREAM_TYPE GetStreamType() { return m_StreamType; } 113 | void SetStreamType( const CVARS_STREAM_TYPE& streamType ) { m_StreamType = streamType; } 114 | 115 | // CVar 116 | int* m_pVerboseCVarNamePaddingWidth; 117 | 118 | // To avoid memory leaks, CVars should be created using the memory holder 119 | CVarUtils::MemoryHolder mem; 120 | 121 | private: 122 | TrieNode* root; 123 | std::vector< std::string > m_vAcceptedSubstrings; 124 | std::vector< std::string > m_vNotAcceptedSubstrings; 125 | std::vector< std::string > m_vCVarNames; // Keep a list of CVar names 126 | bool m_bVerbose; 127 | CVARS_STREAM_TYPE m_StreamType; 128 | }; 129 | 130 | std::ostream &operator<<(std::ostream &stream, Trie &rTrie ); 131 | std::istream &operator>>(std::istream &stream, Trie &rTrie ); 132 | 133 | 134 | #endif 135 | -------------------------------------------------------------------------------- /examples/Demo2/Pyramid.cc: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include "Pyramid.h" 5 | 6 | /** 7 | * Construct the pyramid object and initialise the CVars 8 | */ 9 | Pyramid::Pyramid() : 10 | mpPos( CVarUtils::CreateCVar( "pyramid.position", Point3D(0.0f, 0.0f, -2.0f), "Centre of the pyramid" ) ), 11 | mpRot( 0.0f, 0.0f, 0.0f), 12 | mpRotDelta( CVarUtils::CreateCVar( "pyramid.rotationDelta", Point3D(0.0f, 0.2f, 0.0f), "How quickly to rotate the pyramid on each axis" ) ), 13 | mpScale( CVarUtils::CreateCVar( "pyramid.scale", Point3D(1.0f, 1.0f, 1.0f), "The scale of the pyramid in each axis" ) ), 14 | mpP1( CVarUtils::CreateCVar( "pyramid.point.1", Point3D(0.0f, 1.0f, 0.0f), "The top point" ) ), 15 | mpP2( CVarUtils::CreateCVar( "pyramid.point.2", Point3D(-1.0f,-1.0f, 1.0f), "The front left point" ) ), 16 | mpP3( CVarUtils::CreateCVar( "pyramid.point.3", Point3D(1.0f,-1.0f, 1.0f), "The front right point" ) ), 17 | mpP4( CVarUtils::CreateCVar( "pyramid.point.4", Point3D(1.0f,-1.0f, -1.0f), "The back right point" ) ), 18 | mpP5( CVarUtils::CreateCVar( "pyramid.point.5", Point3D(-1.0f,-1.0f, -1.0f), "The back left point" ) ) 19 | { 20 | 21 | } 22 | 23 | /** 24 | * Destructor. 25 | */ 26 | Pyramid::~Pyramid() 27 | { 28 | 29 | } 30 | 31 | /** 32 | * Helper funciton to draw a point in OpenGL 33 | */ 34 | inline void Pyramid::glVertex(Point3D &p) 35 | { 36 | Point3D sp = mpScale * p; 37 | glVertex3f(sp.x, sp.y, sp.z); 38 | } 39 | 40 | 41 | /** 42 | * Call this to draw the pyramid 43 | */ 44 | void Pyramid::Draw() 45 | { 46 | glTranslatef(mpPos.x,mpPos.y,mpPos.z); // Move Left 1.5 Units And Into The Screen 6.0 47 | 48 | mpRot = mpRot + mpRotDelta; 49 | glRotatef(mpRot.x,1.0f,0.0f,0.0f); // Rotate The Pyramid On The X axis 50 | glRotatef(mpRot.y,0.0f,1.0f,0.0f); // Rotate The Pyramid On The Y axis 51 | glRotatef(mpRot.z,0.0f,0.0f,1.0f); // Rotate The Pyramid On The Z axis 52 | 53 | // draw a pyramid (in smooth coloring mode) 54 | glBegin(GL_POLYGON); // start drawing a pyramid 55 | 56 | // front face of pyramid 57 | glColor3f(1.0f,0.0f,0.0f); // Set The Color To Red 58 | glVertex( mpP1 ); // Top of triangle (front) 59 | glColor3f(0.0f,1.0f,0.0f); // Set The Color To Green 60 | glVertex(mpP2 ); // left of triangle (front) 61 | glColor3f(0.0f,0.0f,1.0f); // Set The Color To Blue 62 | glVertex( mpP3 ); // right of traingle (front) 63 | 64 | // right face of pyramid 65 | glColor3f(1.0f,0.0f,0.0f); // Red 66 | glVertex( mpP1 ); // Top Of Triangle (Right) 67 | glColor3f(0.0f,0.0f,1.0f); // Blue 68 | glVertex( mpP3 ); // Left Of Triangle (Right) 69 | glColor3f(0.0f,1.0f,0.0f); // Green 70 | glVertex( mpP4 ); // Right Of Triangle (Right) 71 | 72 | // back face of pyramid 73 | glColor3f(1.0f,0.0f,0.0f); // Red 74 | glVertex( mpP1 ); // Top Of Triangle (Back) 75 | glColor3f(0.0f,1.0f,0.0f); // Green 76 | glVertex( mpP4 ); // Left Of Triangle (Back) 77 | glColor3f(0.0f,0.0f,1.0f); // Blue 78 | glVertex( mpP5 ); // Right Of Triangle (Back) 79 | 80 | // left face of pyramid. 81 | glColor3f(1.0f,0.0f,0.0f); // Red 82 | glVertex( mpP1 ); // Top Of Triangle (Left) 83 | glColor3f(0.0f,0.0f,1.0f); // Blue 84 | glVertex( mpP5 ); // Left Of Triangle (Left) 85 | glColor3f(0.0f,1.0f,0.0f); // Green 86 | glVertex( mpP2 ); // Right Of Triangle (Left) 87 | 88 | glEnd(); // Done Drawing The Pyramid 89 | 90 | } 91 | 92 | 93 | /** 94 | * Reset the pyramid to initial conditions 95 | */ 96 | void Pyramid::Reset() 97 | { 98 | mpPos = Point3D(0.0f, 0.0f, -2.0f); 99 | mpRot = Point3D( 0.0f, 0.0f, 0.0f); 100 | mpRotDelta = Point3D( 0.0f, 0.2f, 0.0f); 101 | mpScale = Point3D(1.0f, 1.0f, 1.0f); 102 | mpP1 = Point3D(0.0f, 1.0f, 0.0f); 103 | mpP2 = Point3D(-1.0f,-1.0f, 1.0f); 104 | mpP3 = Point3D(1.0f,-1.0f, 1.0f); 105 | mpP4 = Point3D(1.0f,-1.0f, -1.0f); 106 | mpP5 = Point3D(-1.0f,-1.0f, -1.0f); 107 | } 108 | -------------------------------------------------------------------------------- /src/TrieNode.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Cross platform "CVars" functionality. 4 | 5 | This Code is covered under the LGPL. See COPYING file for the license. 6 | 7 | $Id: TrieNode.cpp 162 2010-02-15 19:11:05Z gsibley $ 8 | */ 9 | 10 | 11 | #include "cvars/TrieNode.h" 12 | #include "cvars/CVar.h" 13 | 14 | //////////////////////////////////////////////////////////////////////////////// 15 | TrieNode::TrieNode() : m_pNodeData(0), 16 | m_nNodeType(TRIE_LEAF), 17 | m_cNodeChar(0) { 18 | m_children.clear(); 19 | } 20 | 21 | //////////////////////////////////////////////////////////////////////////////// 22 | TrieNode::TrieNode( TrieNodeType t ) : m_pNodeData(0), 23 | m_nNodeType(t), 24 | m_cNodeChar(0) 25 | { 26 | m_children.clear(); 27 | } 28 | 29 | //////////////////////////////////////////////////////////////////////////////// 30 | TrieNode::TrieNode( std::string s ) : m_pNodeData(0), 31 | m_nNodeType(TRIE_LEAF), 32 | m_sLeafText(s), 33 | m_cNodeChar(0) 34 | { 35 | m_children.clear(); 36 | } 37 | 38 | //////////////////////////////////////////////////////////////////////////////// 39 | TrieNode::TrieNode( char c ) : m_pNodeData(0), 40 | m_nNodeType(TRIE_NODE), 41 | m_cNodeChar(c) 42 | { 43 | m_children.clear(); 44 | } 45 | 46 | //////////////////////////////////////////////////////////////////////////////// 47 | TrieNode::~TrieNode() 48 | { 49 | std::list::iterator it; 50 | if( m_nNodeType == TRIE_LEAF && 51 | m_pNodeData != NULL ) { 52 | //printf( "Destroying leaf node '%s'\n", m_sLeafText.c_str() ); 53 | CVarUtils::CVar* pCVar = 54 | static_cast*>(m_pNodeData); 55 | delete pCVar; 56 | } 57 | else { 58 | for( it = m_children.begin() ; it != m_children.end() ; ++it ) { 59 | delete (*it); //destructor on TrieNodes will destroy all the children 60 | } 61 | } 62 | } 63 | 64 | //////////////////////////////////////////////////////////////////////////////// 65 | // Go through this node and see if this char is a branch, if so, simply return 66 | // the corresponding child otherwise, create a node and return its child 67 | TrieNode* TrieNode::TraverseInsert( char addchar ) 68 | { 69 | std::list::iterator it; 70 | for( it = m_children.begin() ; it != m_children.end() ; ++it ) { 71 | //found child 72 | if( ((*it)->m_nNodeType == TRIE_NODE) && ((*it)->m_cNodeChar == addchar) ) { 73 | return (*it); 74 | } 75 | } 76 | 77 | TrieNode* newNode = new TrieNode( addchar ); 78 | m_children.push_back( newNode ); 79 | return newNode; 80 | } 81 | 82 | //////////////////////////////////////////////////////////////////////////////// 83 | // See if there is a child with this character, if so, return it otherwise, 84 | // return NULL. 85 | TrieNode* TrieNode::TraverseFind( char addchar ) 86 | { 87 | std::list::iterator it; 88 | for( it = m_children.begin() ; it != m_children.end() ; ++it ) { 89 | //found child 90 | if( ((*it)->m_nNodeType == TRIE_NODE) && 91 | ((*it)->m_cNodeChar == addchar) ) { 92 | return (*it); 93 | } 94 | } 95 | return NULL; 96 | } 97 | 98 | //////////////////////////////////////////////////////////////////////////////// 99 | // Recursively traverses 100 | void TrieNode::PrintToVector( std::vector &vec ) 101 | { 102 | if( m_nNodeType == TRIE_LEAF ) { 103 | vec.push_back( m_sLeafText ); 104 | } else { 105 | std::list::iterator it; 106 | for( it = m_children.begin() ; it != m_children.end() ; ++it ) { 107 | (*it)->PrintToVector( vec ); 108 | } 109 | } 110 | } 111 | 112 | //////////////////////////////////////////////////////////////////////////////// 113 | // Recursively traverses 114 | void TrieNode::PrintNodeToVector( std::vector &vec ) 115 | { 116 | if( m_nNodeType == TRIE_LEAF ) { 117 | vec.push_back( this ); 118 | } else { 119 | std::list::iterator it; 120 | for( it = m_children.begin() ; it != m_children.end() ; ++it ) { 121 | (*it)->PrintNodeToVector( vec ); 122 | } 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /src/Timestamp.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Cross platform "CVars" functionality. 4 | 5 | This Code is covered under the LGPL. See COPYING file for the license. 6 | 7 | $Id: Timestamp.cpp 162 2010-02-15 19:11:05Z gsibley $ 8 | 9 | */ 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #ifdef _WIN_ 17 | # include 18 | #endif 19 | 20 | #include 21 | 22 | TimeStamp::TimeStamp() 23 | { 24 | start = 1; 25 | overflow = 0; 26 | 27 | #ifdef _WIN_ 28 | isPaused = false; 29 | #endif 30 | } 31 | 32 | #ifndef _WIN_ 33 | void TimeStamp::Stamp() 34 | { 35 | gettimeofday(&prevTime, &tz); 36 | //overflow = 0; 37 | if(start == 1) 38 | { 39 | start = 0; 40 | startTime = prevTime; 41 | } 42 | } 43 | #endif 44 | 45 | #ifdef _WIN_ 46 | void TimeStamp::Stamp() 47 | { 48 | if(isPaused) 49 | UnPause(); 50 | 51 | LARGE_INTEGER time, freq; 52 | QueryPerformanceCounter(&time); 53 | QueryPerformanceFrequency(&freq); 54 | prevTime = (double) time.QuadPart / (double) freq.QuadPart; 55 | 56 | //overflow = 0; 57 | if(start == 1) 58 | { 59 | start = 0; 60 | startTime = prevTime; 61 | } 62 | } 63 | #endif 64 | 65 | #ifndef _WIN_ 66 | double TimeStamp::TotalElapsed() 67 | { 68 | if(start == 1) 69 | { 70 | start = 0; 71 | return 0; 72 | } 73 | 74 | //get current time 75 | struct timeval currTime; 76 | struct timezone currTz; 77 | gettimeofday(&currTime, &currTz); 78 | 79 | double t1 = (double)startTime.tv_sec + (double) startTime.tv_usec/(1000*1000); 80 | double t2 = (double)currTime.tv_sec + (double)currTime.tv_usec/(1000*1000); 81 | return t2-t1; 82 | } 83 | #endif 84 | 85 | #ifdef _WIN_ 86 | double TimeStamp::TotalElapsed() 87 | { 88 | if(start == 1) 89 | { 90 | start = 0; 91 | return 0; 92 | } 93 | 94 | //get current time 95 | LARGE_INTEGER time, freq; 96 | QueryPerformanceCounter(&time); 97 | QueryPerformanceFrequency(&freq); 98 | double currTime = (double)time.QuadPart / (double) freq.QuadPart; 99 | 100 | return currTime-startTime; 101 | } 102 | #endif 103 | 104 | #ifndef _WIN_ 105 | //returns very precise time in seconds since last "stamp" 106 | double TimeStamp::Elapsed() 107 | { 108 | if(start == 1) 109 | { 110 | start = 0; 111 | return 0; 112 | 113 | } 114 | 115 | //get current time 116 | struct timeval currTime; 117 | struct timezone currTz; 118 | gettimeofday(&currTime, &currTz); 119 | 120 | double t1 = (double)prevTime.tv_sec + (double) prevTime.tv_usec/(1000*1000); 121 | double t2 = (double)currTime.tv_sec + (double)currTime.tv_usec/(1000*1000); 122 | return t2-t1; 123 | } 124 | #endif 125 | 126 | #ifdef _WIN_ 127 | double TimeStamp::Elapsed() 128 | { 129 | if(start == 1) 130 | { 131 | start = 0; 132 | return 0; 133 | 134 | } 135 | 136 | 137 | //get current time 138 | LARGE_INTEGER time, freq; 139 | QueryPerformanceCounter(&time); 140 | QueryPerformanceFrequency(&freq); 141 | double currTime = (double)time.QuadPart / (double) freq.QuadPart; 142 | 143 | double elapsed; 144 | if(isPaused) 145 | { 146 | UnPause(); 147 | elapsed = currTime-prevTime; 148 | Pause(); 149 | } 150 | else 151 | elapsed = currTime-prevTime; 152 | 153 | return elapsed; 154 | } 155 | #endif 156 | 157 | //returns the # of frames that have elapsed since the last "stamp" 158 | //frameTime is the time per frame in milliseconds 159 | //factor is the scaling factor used to speed and slow the timer 160 | int TimeStamp::ElapsedFrames(double frameTime, double factor) 161 | { 162 | //double elapSec = Elapsed(); 163 | 164 | double total = ((Elapsed() / (frameTime/1000)) + overflow)*factor; 165 | int result = (int) total; 166 | overflow = total - result; 167 | 168 | return result; 169 | } 170 | 171 | #ifdef _WIN_ 172 | //allow timer to be pauses in between "stamps" 173 | void TimeStamp::Pause() 174 | { 175 | if(isPaused) 176 | return; 177 | 178 | //get current time 179 | LARGE_INTEGER time, freq; 180 | QueryPerformanceCounter(&time); 181 | QueryPerformanceFrequency(&freq); 182 | 183 | pauseTime = (double)time.QuadPart / (double) freq.QuadPart; 184 | isPaused = true; 185 | } 186 | 187 | //unpause the timer... 188 | void TimeStamp::UnPause() 189 | { 190 | if(!isPaused) 191 | return; 192 | 193 | //get current time 194 | LARGE_INTEGER time, freq; 195 | QueryPerformanceCounter(&time); 196 | QueryPerformanceFrequency(&freq); 197 | double currTime = (double)time.QuadPart / (double) freq.QuadPart; 198 | 199 | prevTime += currTime - pauseTime; 200 | isPaused = false; 201 | } 202 | #endif 203 | -------------------------------------------------------------------------------- /examples/Demo2/demo2.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | #include "Pyramid.h" 16 | 17 | // Single global instance so glut can get access 18 | GLConsole theConsole; 19 | 20 | Pyramid pyramid; 21 | 22 | 23 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 24 | /** 25 | * What to draw on the display 26 | */ 27 | void display() 28 | { 29 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 30 | glLoadIdentity(); 31 | glTranslatef(0,0.0f,-2.0f); 32 | 33 | pyramid.Draw(); 34 | 35 | theConsole.RenderConsole(); 36 | 37 | glutSwapBuffers(); 38 | } 39 | 40 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 41 | /** 42 | * resize the window to the desired size 43 | * @param w Window width 44 | * @param h Window height 45 | */ 46 | void reshape (int w, int h) 47 | { 48 | glViewport ( 0, 0, w, h ); 49 | glMatrixMode ( GL_PROJECTION ); 50 | glLoadIdentity ( ); 51 | 52 | if ( h == 0 ) 53 | gluPerspective ( 80, ( float ) w, 1.0, 5000.0 ); 54 | else 55 | gluPerspective ( 80, ( float ) w / ( float ) h, 1.0, 5000.0 ); 56 | 57 | glMatrixMode ( GL_MODELVIEW ); 58 | glLoadIdentity ( ); 59 | } 60 | 61 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 62 | /** 63 | * just redisplay constantly to let the console update... 64 | */ 65 | void idle() 66 | { 67 | #ifdef WIN32 68 | Sleep( 1 ); 69 | #else 70 | usleep( (int)1e4 ); 71 | #endif 72 | glutPostRedisplay(); // we have 73 | } 74 | 75 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 76 | /** 77 | * Pass keboard events to the console. 78 | * Up and down arrows to scroll through console history. 79 | * Shift+up or shift+down to scroll the console window. 80 | * Pageup or pagedown to scroll the console window as well. 81 | */ 82 | void special(int key, int, int ) 83 | { 84 | if( theConsole.IsOpen() ) 85 | { 86 | //pass all key strokes to the console 87 | theConsole.SpecialFunc( key ); 88 | } 89 | else 90 | { 91 | //do your own thing with the keys 92 | } 93 | } 94 | 95 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 96 | /** 97 | * handle incoming key events and send to console 98 | */ 99 | void keyfunc( unsigned char key, int, int ) 100 | { 101 | switch( key ) { 102 | 103 | case 27: //escape 104 | exit ( 0 ); 105 | break; 106 | 107 | case GLCONSOLE_KEY: //~ key opens console on US keyboards. 108 | //On UK keyboards it is the ` key (the one above the Tab and left of the 1 keys) 109 | theConsole.ToggleConsole(); 110 | break; 111 | 112 | default: 113 | if( theConsole.IsOpen() ) { 114 | //send keystroke to console 115 | theConsole.KeyboardFunc( key ); 116 | } 117 | else { 118 | //do your own thing with the keys 119 | } 120 | break; 121 | } 122 | } 123 | 124 | using CVarUtils::operator<<; 125 | using CVarUtils::operator>>; 126 | 127 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 128 | /** 129 | * Main. initialises GLUT and window, and some CVars then starts 130 | * the main GLUT loop. 131 | */ 132 | int main (int argc, const char * argv[]) 133 | { 134 | glutInit(&argc, (char **)argv); 135 | glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); 136 | glutInitWindowPosition (300, 50); 137 | glutInitWindowSize (800, 600); 138 | glutCreateWindow("GLConsole Demo 2"); 139 | 140 | // standard GL init 141 | glShadeModel(GL_SMOOTH); 142 | glClearColor(0.0f, 0.0f, 0.0f, 0.5f); 143 | glClearDepth(1.0f); 144 | glEnable(GL_DEPTH_TEST); 145 | glDepthFunc(GL_LEQUAL); 146 | glEnable ( GL_COLOR_MATERIAL ); 147 | glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); 148 | 149 | glutReshapeFunc (reshape); 150 | glutDisplayFunc (display); 151 | glutKeyboardFunc (keyfunc); 152 | glutSpecialFunc (special); 153 | glutIdleFunc(idle); 154 | 155 | glutMainLoop(); 156 | 157 | return 0; 158 | } 159 | -------------------------------------------------------------------------------- /include/cvars/CVarMapIO.h: -------------------------------------------------------------------------------- 1 | #ifndef _CVAR_MAP_IO_H_ 2 | #define _CVAR_MAP_IO_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | namespace CVarUtils { 11 | // All types you wish to use with CVars must overload << and >> 12 | // This is a possible overloading for maps 13 | template 14 | std::ostream &operator<<( std::ostream &stream, std::map& mMap ) { 15 | 16 | stream << std::endl; 17 | stream << CVarUtils::CVarSpc() << "\n"; 18 | for( typename std::map::iterator it = mMap.begin(); it != mMap.end(); ++it ) { 19 | CVarUtils::CVarIndent(); 20 | stream << CVarUtils::CVarSpc() << "\n"; 21 | CVarUtils::CVarIndent(); 22 | stream << CVarUtils::CVarSpc() << " " << it->first << " " << std::endl; 23 | stream << CVarUtils::CVarSpc() << " "; 24 | CVarUtils::CVarIndent(); 25 | stream << it->second; 26 | CVarUtils::CVarUnIndent(); 27 | stream << CVarUtils::CVarSpc() << "" << std::endl; 28 | CVarUtils::CVarUnIndent(); 29 | stream << CVarUtils::CVarSpc() << "" << std::endl; 30 | CVarUtils::CVarUnIndent(); 31 | } 32 | stream << CVarUtils::CVarSpc() << "" << std::endl; 33 | return stream; 34 | } 35 | 36 | template 37 | std::istream &operator>>( std::istream &stream, std::map& mMap ) { 38 | 39 | tinyxml2::XMLDocument doc; 40 | std::string s; 41 | stream >> s; 42 | doc.Parse(s.c_str()); 43 | //doc.Print( stdout ); 44 | tinyxml2::XMLNode* pCVarsNode = doc.RootElement(); 45 | 46 | if( pCVarsNode == NULL ) { 47 | std::cerr << "ERROR: Could not find a node." << std::endl; 48 | return stream; 49 | } 50 | 51 | for( tinyxml2::XMLNode* pNode = pCVarsNode->FirstChild(); 52 | pNode != NULL; 53 | pNode = pNode->NextSibling() ) { 54 | 55 | std::string sObject( pNode->Value() ); 56 | 57 | if( sObject != "Object" ) { 58 | std::cerr << "WARNING: got '" << sObject << "' value when expecting 'Object'." << std::endl; 59 | continue; 60 | } 61 | 62 | K KKey; 63 | D DData; 64 | 65 | //////////////////////////////////////////////////////// 66 | tinyxml2::XMLNode* pChild = pNode->FirstChild(); 67 | //////////////////////////////////////////////////////// 68 | if( pChild == NULL ) { 69 | std::cerr << "ERROR parsing map, could not find first child (Key) of Object." << std::endl; 70 | return stream; 71 | } 72 | else { 73 | if( std::string( pChild->Value() ) != "Key" ) { 74 | std::cerr << "ERROR parsing key in map, expecting 'Key' node, got "<< pChild->Value() << "." << std::endl; 75 | return stream; 76 | } 77 | 78 | tinyxml2::XMLNode* pKeyChild = pChild->FirstChild(); 79 | 80 | if( pKeyChild == NULL ) { 81 | std::cerr << "ERROR parsing key value in map (empty Key ?).\n" << std::endl; 82 | return stream; 83 | } 84 | std::stringstream iKeyString(pKeyChild->ToText()->Value()); 85 | iKeyString >> KKey; 86 | //std::cout << "Key value: " << pChild->FirstChild()->Value() << std::endl; 87 | } 88 | 89 | //////////////////////////////////////////////////////// 90 | pChild = pChild->NextSibling(); 91 | //////////////////////////////////////////////////////// 92 | if( pChild == NULL ) { 93 | std::cerr << "ERROR parsing map, could not find 2nd child (Data) of Object." << std::endl; 94 | return stream; 95 | } 96 | else { 97 | if( std::string( pChild->Value() ) != "Data" ) { 98 | std::cerr << "ERROR parsing key in map, expecting 'Data' node, got "<< pChild->Value() << "." << std::endl; 99 | return stream; 100 | } 101 | 102 | tinyxml2::XMLNode* pDataChild = pChild->FirstChild(); 103 | 104 | if( pDataChild == NULL ) { 105 | std::cerr << "ERROR parsing Data value in map (empty Data ?).\n" << std::endl; 106 | return stream; 107 | } 108 | std::stringstream iDataString(pDataChild->ToText()->Value()); 109 | iDataString >> DData; 110 | //std::cout << "Data value: " << pChild->FirstChild()->Value() << std::endl; 111 | } 112 | //////////////////////////////////////////////////////// 113 | //std::cout << "Found Key: " << KKey << " with data: " << DData << std::endl; 114 | 115 | mMap[ KKey ] = DData; 116 | } 117 | return stream; 118 | } 119 | } 120 | 121 | #endif 122 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required( VERSION 2.8 ) 2 | 3 | # Be sure to change these with each update 4 | SET( VERSION_MAJOR 2 ) 5 | SET( VERSION_MINOR 6 ) 6 | SET( VERSION_PATCH 0 ) 7 | SET( VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH} ) 8 | 9 | project( CVars ) 10 | 11 | # Add to module path, so we can find our cmake modules 12 | list( APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules ) 13 | include( install_package ) 14 | include( SetPlatformVars ) 15 | include( CheckCXXSourceRuns ) 16 | 17 | # Properly source GL headers. 18 | find_package(OpenGL QUIET) 19 | if(OpenGL_FOUND) 20 | list(APPEND USER_INC "${OPENGL_INCLUDE_DIR}" ) 21 | list(APPEND LINK_LIBS "${OPENGL_LIBRARIES}" ) 22 | endif(OpenGL_FOUND) 23 | 24 | find_package(GLEW QUIET) 25 | if(GLEW_FOUND) 26 | list(APPEND USER_INC "${GLEW_INCLUDE_DIR}" ) 27 | list(APPEND LINK_LIBS "${GLEW_LIBRARY}" ) 28 | set(HAVE_GLEW 1) 29 | endif() 30 | 31 | find_package(FREEGLUT QUIET) 32 | find_package(GLUT QUIET) 33 | 34 | find_package(TinyXML2 REQUIRED) 35 | list(APPEND USER_INC ${TinyXML2_INCLUDE_DIRS} ) 36 | list(APPEND LINK_LIBS ${TinyXML2_LIBRARIES} ) 37 | 38 | 39 | # Custom check for Modified OSX GLUT. 40 | if(_OSX_) 41 | set(CMAKE_REQUIRED_LIBRARIES ${GLUT_LIBRARY}) 42 | CHECK_CXX_SOURCE_RUNS("#include \n int main () {return glutGetProcAddress(\"glutScrollFunc\") ? 0 : -1;};" HAVE_MODIFIED_OSXGLUT) 43 | if(NOT HAVE_MODIFIED_OSXGLUT) 44 | message(STATUS "Install modified osxglut for smooth scroll support / pinch / zoom.") 45 | message(STATUS "(https://github.com/stevenlovegrove/osxglut)") 46 | endif() 47 | endif(_OSX_) 48 | 49 | # Prefer OSX_MODIFIED_GLUT > FREEGLUT > GLUT 50 | option(FORCE_FREEGLUT "Force use of freeglut if found." OFF) 51 | if(FREEGLUT_FOUND AND (NOT HAVE_MODIFIED_OSXGLUT OR FORCE_FREEGLUT)) 52 | set(HAVE_FREEGLUT 1) 53 | list(APPEND USER_INC ${FREEGLUT_INCLUDE_DIR} ) 54 | list(APPEND LINK_LIBS ${FREEGLUT_LIBRARY} ) 55 | elseif(GLUT_FOUND) 56 | list(APPEND USER_INC ${GLUT_INCLUDE_DIR} ) 57 | list(APPEND LINK_LIBS ${GLUT_LIBRARY} ) 58 | if(_OSX_) 59 | set(HAVE_APPLE_OPENGL_FRAMEWORK 1) 60 | list(APPEND LINK_LIBS "-framework GLUT" ) 61 | if(NOT HAVE_MODIFIED_OSXGLUT) 62 | message(STATUS "Using Apple Framework GLUT.") 63 | message(STATUS "Install Freeglut or modified osxglut for scroll support.") 64 | endif() 65 | endif() 66 | if(FREEGLUT_FOUND OR GLUT_FOUND) 67 | set(HAVE_GLUT 1) 68 | message(STATUS "Glut Found and Enabled") 69 | endif() 70 | endif() 71 | 72 | if( HAVE_GLES_2 ) 73 | # Add Pangolins backwards compat layer. 74 | list(APPEND HEADERS ${INCDIR}/gl2engine.h ) 75 | list(APPEND SOURCES ${SRCDIR}/gl2engine.cpp) 76 | endif() 77 | 78 | ############################################################################### 79 | if (COMMAND catkin_package) 80 | find_package( catkin QUIET ) 81 | catkin_package( 82 | INCLUDE_DIRS include 83 | LIBRARIES cvars 84 | CATKIN_DEPENDS 85 | DEPENDS glut 86 | ) 87 | # Install catkin package.xml 88 | install(FILES package.xml DESTINATION share/cvars) 89 | endif() 90 | 91 | 92 | 93 | # Set version values in config.h (see config.h.in) 94 | configure_file( src/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/include/cvars/config.h IMMEDIATE ) 95 | include_directories( ${CMAKE_CURRENT_BINARY_DIR}/include ) 96 | 97 | ############################################################################### 98 | # Setup compiler flags 99 | IF( NOT MSVC ) 100 | # Setup strict debugging environment. 101 | IF( "${CMAKE_BUILD_TYPE}" STREQUAL "Debug" ) 102 | SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -g -fno-strict-aliasing ") 103 | SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -g -fno-strict-aliasing ") 104 | ENDIF( "${CMAKE_BUILD_TYPE}" STREQUAL "Debug" ) 105 | ENDIF( NOT MSVC ) 106 | 107 | ############################################################################### 108 | # Build cvars library 109 | 110 | include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/include ) 111 | set( CVAR_SRCS 112 | src/CVar.cpp 113 | src/CVarParse.cpp 114 | src/Timestamp.cpp 115 | src/Trie.cpp 116 | src/TrieNode.cpp 117 | ) 118 | 119 | set( CVAR_HDRS 120 | include/cvars/config.h 121 | include/cvars/CVar.h 122 | include/cvars/CVarVectorIO.h 123 | include/cvars/CVarMapIO.h 124 | include/cvars/Timestamp.h 125 | include/cvars/Trie.h 126 | include/cvars/TrieNode.h 127 | include/cvars/glplatform.h 128 | ) 129 | 130 | add_definitions( -DTIXML_USE_STL ) 131 | 132 | ############################################################################### 133 | set( BUILD_GLCONSOLE_DEMO CACHE BOOL OFF ) 134 | if( BUILD_GLCONSOLE_DEMO ) 135 | add_subdirectory( examples ) 136 | endif() 137 | 138 | ############################################################################### 139 | # Headers for GLConsole 140 | set( GLCONSOLE_HEADERS 141 | include/GLConsole/GLFont.h 142 | include/GLConsole/GLColor.h 143 | include/GLConsole/GLConsole.h 144 | include/GLConsole/GLConsoleFunction.h 145 | ) 146 | 147 | ############################################################################### 148 | # Headers for FLConsole 149 | set( FLCONSOLE_HEADERS 150 | include/FLConsole/FLConsole.h 151 | include/FLConsole/FLConsoleFunction.h 152 | ) 153 | 154 | # include CVAR_HDRS in add_library so QtCreator will detect them. 155 | include_directories( ${USER_INC} ) 156 | add_library( cvars SHARED ${CVAR_SRCS} ${CVAR_HDRS} ${GLCONSOLE_HEADERS} ${FLCONSOLE_HEADERS} ) 157 | target_link_libraries( cvars ${LINK_LIBS} ) 158 | set_target_properties( cvars PROPERTIES VERSION "${VERSION}" SOVERSION "${VERSION}" ) 159 | 160 | 161 | ############################################################################## 162 | if(NOT COMMAND catkin_package) 163 | install_package( 164 | PKG_NAME CVars 165 | LIB_NAME cvars 166 | VERSION ${VERSION} 167 | DESCRIPTION "Library for runtime variable editing for fast prototyping." 168 | INSTALL_INCLUDE_DIR true 169 | INSTALL_GENERATED_HEADERS ${CMAKE_CURRENT_BINARY_DIR}/include/cvars/config.h 170 | DESTINATION ${CMAKE_INSTALL_PREFIX} 171 | ) 172 | endif() 173 | 174 | # make an uninstall target 175 | include(${CMAKE_MODULE_PATH}/cmake_uninstall.cmake.in) 176 | add_custom_target(uninstall 177 | COMMAND "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake") 178 | 179 | -------------------------------------------------------------------------------- /include/GLConsole/GLFont.h: -------------------------------------------------------------------------------- 1 | /* 2 | \file GLFont.h 3 | 4 | This Code is covered under the LGPL. See COPYING file for the license. 5 | 6 | $Id: GLFont.h 183 2010-07-18 15:20:20Z effer $ 7 | */ 8 | #ifndef __GL_FONT_H__ 9 | #define __GL_FONT_H__ 10 | 11 | #include 12 | 13 | #include 14 | #include 15 | 16 | #include 17 | #include 18 | #include 19 | 20 | 21 | #define MAX_TEXT_LENGTH 512 22 | 23 | /// 24 | class GLFont 25 | { 26 | friend inline bool GLFontCheckInit( GLFont* pFont ); 27 | public: 28 | GLFont() 29 | { 30 | m_nNumLists = 96; 31 | m_nCharWidth = 8; 32 | m_nCharHeight = 13; 33 | m_bInitDone = false; 34 | } 35 | ~GLFont(); 36 | 37 | // printf style function take position to print to as well 38 | // NB: coordinates start from bottom left 39 | void glPrintf(int x, int y, const char *fmt, ...); 40 | void glPrintf(int x, int y, const std::string fmt, ...){ glPrintf(x,y, fmt.c_str()); } 41 | void glPrintfFast(int x, int y, const char *fmt, ...); 42 | void glPrintfFast(int x, int y, const std::string fmt, ...){ glPrintfFast(x,y, fmt.c_str()); } 43 | 44 | unsigned int CharWidth() { return m_nCharWidth; } 45 | unsigned int CharHeight() { return m_nCharHeight; } 46 | 47 | private: 48 | unsigned int m_nCharWidth; // fixed width 49 | unsigned int m_nCharHeight; // fixed width 50 | int m_nNumLists; // number of display lists 51 | int m_nDisplayListBase; // base number for display lists 52 | bool m_bInitDone; 53 | }; 54 | 55 | //////////////////////////////////////////////////////////////////////////////// 56 | /// 57 | inline bool GLFontCheckInit( GLFont* pFont = NULL ) 58 | { 59 | // make sure glutInit has been called 60 | if( glutGet(GLUT_ELAPSED_TIME) <= 0 ){ 61 | //fprintf( stderr, "WARNING: GLFontCheckInit failed after 'glutGet(GLUT_ELAPSED_TIME) <= 0' check\n" ); 62 | return false; 63 | } 64 | 65 | static int nDisplayListBase = -1; 66 | if( !pFont->m_bInitDone ) { 67 | assert( pFont != NULL ); 68 | // GLUT bitmapped fonts... 69 | pFont->m_nDisplayListBase = glGenLists( pFont->m_nNumLists ); 70 | if( pFont->m_nDisplayListBase == 0 ) { 71 | // hmm, commented out for now because on my linux box w get here sometimes 72 | // even though glut hasn't been initialized. 73 | // fprintf( stderr, "%i", pFont->m_nNumLists ); 74 | fprintf( stderr, "GLFontCheckInit() -- out of display lists\n"); 75 | return false; 76 | } 77 | for( int nList = pFont->m_nDisplayListBase; 78 | nList < pFont->m_nDisplayListBase + pFont->m_nNumLists; nList++ ) { 79 | glNewList( nList, GL_COMPILE ); 80 | glutBitmapCharacter( GLUT_BITMAP_8_BY_13, nList+32-pFont->m_nDisplayListBase ); 81 | glEndList(); 82 | } 83 | 84 | nDisplayListBase = pFont->m_nDisplayListBase; 85 | pFont->m_bInitDone = true; 86 | return false; 87 | } 88 | else{ 89 | assert( nDisplayListBase > 0 ); 90 | pFont->m_nDisplayListBase = nDisplayListBase; 91 | } 92 | return true; 93 | } 94 | 95 | //////////////////////////////////////////////////////////////////////////////// 96 | inline GLFont::~GLFont() 97 | { 98 | if( m_bInitDone && GLFontCheckInit(this) ) { 99 | glDeleteLists( m_nDisplayListBase, m_nDisplayListBase + m_nNumLists ); 100 | } 101 | } 102 | 103 | //////////////////////////////////////////////////////////////////////////////// 104 | // printf style print function 105 | // NB: coordinates start from bottom left 106 | inline void GLFont::glPrintf(int x, int y, const char *fmt, ...) 107 | { 108 | GLFontCheckInit(this); 109 | 110 | char text[MAX_TEXT_LENGTH]; // Holds Our String 111 | va_list ap; // Pointer To List Of Arguments 112 | 113 | if( fmt == NULL ) { // If There's No Text 114 | return; // Do Nothing 115 | } 116 | 117 | va_start( ap, fmt ); // Parses The String For Variables 118 | vsnprintf( text, MAX_TEXT_LENGTH, fmt, ap ); // And Converts Symbols To Actual Numbers 119 | va_end( ap ); // Results Are Stored In Text 120 | 121 | glDisable(GL_DEPTH_TEST); //causes text not to clip with geometry 122 | //position text correctly... 123 | 124 | // This saves our transform (matrix) information and our current viewport information. 125 | glPushAttrib( GL_TRANSFORM_BIT | GL_VIEWPORT_BIT ); 126 | // Use a new projection and modelview matrix to work with. 127 | glMatrixMode( GL_PROJECTION ); 128 | glPushMatrix(); 129 | glLoadIdentity(); 130 | glMatrixMode( GL_MODELVIEW ); 131 | glPushMatrix(); 132 | glLoadIdentity(); 133 | //create a viewport at x,y, but doesnt have any width (so we end up drawing there...) 134 | glViewport( x - 1, y - 1, 0, 0 ); 135 | //This actually positions the text. 136 | glRasterPos4f( 0, 0, 0, 1 ); 137 | //undo everything 138 | glPopMatrix(); // Pop the current modelview matrix off the stack 139 | glMatrixMode( GL_PROJECTION ); // Go back into projection mode 140 | glPopMatrix(); // Pop the projection matrix off the stack 141 | glPopAttrib(); // This restores our TRANSFORM and VIEWPORT attributes 142 | 143 | //glRasterPos2f(x, y); 144 | 145 | glPushAttrib( GL_LIST_BIT ); // Pushes The Display List Bits 146 | glListBase( m_nDisplayListBase - 32 ); // Sets The Base Character to 32 147 | //glScalef( 0.5, 0.5, 0.5 ); 148 | glCallLists( strlen(text), GL_UNSIGNED_BYTE, text );// Draws The Display List Text 149 | glPopAttrib(); // Pops The Display List Bits 150 | glEnable(GL_DEPTH_TEST); 151 | } 152 | 153 | //////////////////////////////////////////////////////////////////////////////// 154 | //printf style print function 155 | //NOTE: coordinates start from bottom left 156 | //ASSUMES ORTHOGRAPHIC PROJECTION ALREADY SET UP... 157 | inline void GLFont::glPrintfFast(int x, int y, const char *fmt, ...) 158 | { 159 | GLFontCheckInit(this); 160 | 161 | char text[MAX_TEXT_LENGTH];// Holds Our String 162 | va_list ap; // Pointer To List Of Arguments 163 | 164 | if( fmt == NULL ) { // If There's No Text 165 | return; // Do Nothing 166 | } 167 | 168 | va_start( ap, fmt ); // Parses The String For Variables 169 | vsnprintf( text, MAX_TEXT_LENGTH, fmt, ap ); // And Converts Symbols To Actual Numbers 170 | va_end( ap ); // Results Are Stored In Text 171 | 172 | glDisable( GL_DEPTH_TEST ); // Causes text not to clip with geometry 173 | glRasterPos2f( x, y ); 174 | //glPushAttrib( GL_LIST_BIT ); // Pushes The Display List Bits 175 | glListBase( m_nDisplayListBase - 32 ); // Sets The Base Character to 32 176 | glCallLists( strlen(text), GL_UNSIGNED_BYTE, text ); // Draws The Display List Text 177 | //glPopAttrib(); // Pops The Display List Bits 178 | glEnable( GL_DEPTH_TEST ); 179 | } 180 | 181 | 182 | #endif 183 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | 9 | This version of the GNU Lesser General Public License incorporates 10 | the terms and conditions of version 3 of the GNU General Public 11 | License, supplemented by the additional permissions listed below. 12 | 13 | 0. Additional Definitions. 14 | 15 | As used herein, "this License" refers to version 3 of the GNU Lesser 16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU 17 | General Public License. 18 | 19 | "The Library" refers to a covered work governed by this License, 20 | other than an Application or a Combined Work as defined below. 21 | 22 | An "Application" is any work that makes use of an interface provided 23 | by the Library, but which is not otherwise based on the Library. 24 | Defining a subclass of a class defined by the Library is deemed a mode 25 | of using an interface provided by the Library. 26 | 27 | A "Combined Work" is a work produced by combining or linking an 28 | Application with the Library. The particular version of the Library 29 | with which the Combined Work was made is also called the "Linked 30 | Version". 31 | 32 | The "Minimal Corresponding Source" for a Combined Work means the 33 | Corresponding Source for the Combined Work, excluding any source code 34 | for portions of the Combined Work that, considered in isolation, are 35 | based on the Application, and not on the Linked Version. 36 | 37 | The "Corresponding Application Code" for a Combined Work means the 38 | object code and/or source code for the Application, including any data 39 | and utility programs needed for reproducing the Combined Work from the 40 | Application, but excluding the System Libraries of the Combined Work. 41 | 42 | 1. Exception to Section 3 of the GNU GPL. 43 | 44 | You may convey a covered work under sections 3 and 4 of this License 45 | without being bound by section 3 of the GNU GPL. 46 | 47 | 2. Conveying Modified Versions. 48 | 49 | If you modify a copy of the Library, and, in your modifications, a 50 | facility refers to a function or data to be supplied by an Application 51 | that uses the facility (other than as an argument passed when the 52 | facility is invoked), then you may convey a copy of the modified 53 | version: 54 | 55 | a) under this License, provided that you make a good faith effort to 56 | ensure that, in the event an Application does not supply the 57 | function or data, the facility still operates, and performs 58 | whatever part of its purpose remains meaningful, or 59 | 60 | b) under the GNU GPL, with none of the additional permissions of 61 | this License applicable to that copy. 62 | 63 | 3. Object Code Incorporating Material from Library Header Files. 64 | 65 | The object code form of an Application may incorporate material from 66 | a header file that is part of the Library. You may convey such object 67 | code under terms of your choice, provided that, if the incorporated 68 | material is not limited to numerical parameters, data structure 69 | layouts and accessors, or small macros, inline functions and templates 70 | (ten or fewer lines in length), you do both of the following: 71 | 72 | a) Give prominent notice with each copy of the object code that the 73 | Library is used in it and that the Library and its use are 74 | covered by this License. 75 | 76 | b) Accompany the object code with a copy of the GNU GPL and this license 77 | document. 78 | 79 | 4. Combined Works. 80 | 81 | You may convey a Combined Work under terms of your choice that, 82 | taken together, effectively do not restrict modification of the 83 | portions of the Library contained in the Combined Work and reverse 84 | engineering for debugging such modifications, if you also do each of 85 | the following: 86 | 87 | a) Give prominent notice with each copy of the Combined Work that 88 | the Library is used in it and that the Library and its use are 89 | covered by this License. 90 | 91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license 92 | document. 93 | 94 | c) For a Combined Work that displays copyright notices during 95 | execution, include the copyright notice for the Library among 96 | these notices, as well as a reference directing the user to the 97 | copies of the GNU GPL and this license document. 98 | 99 | d) Do one of the following: 100 | 101 | 0) Convey the Minimal Corresponding Source under the terms of this 102 | License, and the Corresponding Application Code in a form 103 | suitable for, and under terms that permit, the user to 104 | recombine or relink the Application with a modified version of 105 | the Linked Version to produce a modified Combined Work, in the 106 | manner specified by section 6 of the GNU GPL for conveying 107 | Corresponding Source. 108 | 109 | 1) Use a suitable shared library mechanism for linking with the 110 | Library. A suitable mechanism is one that (a) uses at run time 111 | a copy of the Library already present on the user's computer 112 | system, and (b) will operate properly with a modified version 113 | of the Library that is interface-compatible with the Linked 114 | Version. 115 | 116 | e) Provide Installation Information, but only if you would otherwise 117 | be required to provide such information under section 6 of the 118 | GNU GPL, and only to the extent that such information is 119 | necessary to install and execute a modified version of the 120 | Combined Work produced by recombining or relinking the 121 | Application with a modified version of the Linked Version. (If 122 | you use option 4d0, the Installation Information must accompany 123 | the Minimal Corresponding Source and Corresponding Application 124 | Code. If you use option 4d1, you must provide the Installation 125 | Information in the manner specified by section 6 of the GNU GPL 126 | for conveying Corresponding Source.) 127 | 128 | 5. Combined Libraries. 129 | 130 | You may place library facilities that are a work based on the 131 | Library side by side in a single library together with other library 132 | facilities that are not Applications and are not covered by this 133 | License, and convey such a combined library under terms of your 134 | choice, if you do both of the following: 135 | 136 | a) Accompany the combined library with a copy of the same work based 137 | on the Library, uncombined with any other library facilities, 138 | conveyed under the terms of this License. 139 | 140 | b) Give prominent notice with the combined library that part of it 141 | is a work based on the Library, and explaining where to find the 142 | accompanying uncombined form of the same work. 143 | 144 | 6. Revised Versions of the GNU Lesser General Public License. 145 | 146 | The Free Software Foundation may publish revised and/or new versions 147 | of the GNU Lesser General Public License from time to time. Such new 148 | versions will be similar in spirit to the present version, but may 149 | differ in detail to address new problems or concerns. 150 | 151 | Each version is given a distinguishing version number. If the 152 | Library as you received it specifies that a certain numbered version 153 | of the GNU Lesser General Public License "or any later version" 154 | applies to it, you have the option of following the terms and 155 | conditions either of that published version or of any later version 156 | published by the Free Software Foundation. If the Library as you 157 | received it does not specify a version number of the GNU Lesser 158 | General Public License, you may choose any version of the GNU Lesser 159 | General Public License ever published by the Free Software Foundation. 160 | 161 | If the Library as you received it specifies that a proxy can decide 162 | whether future versions of the GNU Lesser General Public License shall 163 | apply, that proxy's public statement of acceptance of any version is 164 | permanent authorization for you to choose that version for the 165 | Library. 166 | -------------------------------------------------------------------------------- /include/TextConsole/TextConsoleFunction.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | \file TextConsoleFunction.h 4 | 5 | Collection of ConsoleFunc's for TextConsole. 6 | 7 | $Id: TextConsoleFunction.h 164 2010-03-01 20:19:13Z gsibley $ 8 | */ 9 | 10 | #ifndef __TEXT_CONSOLE_FUNCTION__ 11 | #define __TEXT_CONSOLE_FUNCTION__ 12 | 13 | 14 | #include 15 | #include 16 | 17 | //////////////////////////////////////////////////////////////////////////////// 18 | /// Print the current CVars version. 19 | inline bool ConsoleVersion( std::vector* ) 20 | { 21 | printf( "CVars v%d.%d.%d", 22 | CVARS_MAJOR_REV, 23 | CVARS_MINOR_REV, 24 | CVARS_PATCH_REV ); 25 | return true; 26 | } 27 | 28 | //////////////////////////////////////////////////////////////////////////////// 29 | /// Help for functions and variables or just general help. 30 | inline bool ConsoleHelp( std::vector *vArgs ) 31 | { 32 | TextConsoleInstance* pConsole = GetConsole(); 33 | return pConsole->Help( vArgs ); 34 | } 35 | 36 | //////////////////////////////////////////////////////////////////////////////// 37 | /// Looks for the lists of substrings provided in vArgs in the CVarTrie. 38 | inline bool ConsoleFind( std::vector *vArgs ) 39 | { 40 | Trie& trie = CVarUtils::TrieInstance(); 41 | 42 | if( vArgs != NULL && vArgs->size() > 0 ) { 43 | for( size_t i=0; isize(); i++ ) { 44 | std::vector vCVarNames = trie.FindListSubStr( vArgs->at(i) ); 45 | 46 | for( size_t j=0; j *vArgs ) 60 | { 61 | std::string sFile = "cvars.xml"; 62 | std::vector< std::string > vAcceptedSubstrings; 63 | 64 | if( vArgs != NULL && vArgs->size() > 0 ) { 65 | sFile = vArgs->at( 0 ); 66 | for( size_t i=1; isize(); i++ ) { 67 | vAcceptedSubstrings.push_back( vArgs->at( i ) ); 68 | } 69 | } 70 | 71 | printf( "Saving cvars to \"%s\".", sFile.c_str() ); 72 | if( !CVarUtils::Save( sFile, vAcceptedSubstrings ) ) { 73 | printf( "Error saving file.\n" ); 74 | return false; 75 | } 76 | 77 | return true; 78 | } 79 | 80 | //////////////////////////////////////////////////////////////////////////////// 81 | /// Load CVars from a file. 82 | inline bool ConsoleLoad( std::vector *vArgs ) 83 | { 84 | TextConsoleInstance* pConsole = GetConsole(); 85 | std::string sFile = "cvars.xml"; 86 | std::vector< std::string > vAcceptedSubstrings; 87 | 88 | if( vArgs != NULL && vArgs->size() > 0 ) { 89 | sFile = vArgs->at( 0 ); 90 | for( size_t i=1; isize(); i++ ) { 91 | vAcceptedSubstrings.push_back( vArgs->at(i) ); 92 | } 93 | } 94 | printf( "Loading file \"%s\".", sFile.c_str() ); 95 | if( !CVarUtils::Load( sFile, vAcceptedSubstrings ) ) { 96 | printf( "Error: Could not load \"%s\".", sFile.c_str() ); 97 | } 98 | return true; 99 | } 100 | 101 | //////////////////////////////////////////////////////////////////////////////// 102 | /// Exits program from command line. 103 | inline bool ConsoleExit( std::vector * ) 104 | { 105 | exit( 0 ); 106 | } 107 | 108 | //////////////////////////////////////////////////////////////////////////////// 109 | /// Save the console history to a file. 110 | inline bool ConsoleHistorySave( std::vector *vArgs ) 111 | { 112 | TextConsoleInstance* pConsole = GetConsole(); 113 | if( vArgs != NULL && vArgs->size() != 0 ) { 114 | return pConsole->HistorySave( vArgs->at( 0 ) ); 115 | } 116 | else { 117 | return pConsole->HistorySave(); 118 | } 119 | } 120 | 121 | //////////////////////////////////////////////////////////////////////////////// 122 | /// Load a previously saved console history from a file. 123 | inline bool ConsoleHistoryLoad( std::vector *vArgs ) 124 | { 125 | TextConsoleInstance* pConsole = GetConsole(); 126 | if( vArgs != NULL && vArgs->size() != 0 ) { 127 | return pConsole->HistoryLoad( vArgs->at( 0 ) ); 128 | } 129 | else { 130 | return pConsole->HistoryLoad(); 131 | } 132 | } 133 | 134 | //////////////////////////////////////////////////////////////////////////////// 135 | /// clear the console history. 136 | inline bool ConsoleHistoryClear( std::vector* ) 137 | { 138 | TextConsoleInstance* pConsole = GetConsole(); 139 | pConsole->HistoryClear(); 140 | return true; 141 | } 142 | 143 | //////////////////////////////////////////////////////////////////////////////// 144 | /// Save the current script. 145 | inline bool ConsoleScriptSave( std::vector *vArgs ) 146 | { 147 | TextConsoleInstance* pConsole = GetConsole(); 148 | if( vArgs != NULL && vArgs->size() != 0 ) { 149 | return pConsole->ScriptSave( vArgs->at( 0 ) ); 150 | } 151 | else { 152 | return pConsole->ScriptSave(); 153 | } 154 | 155 | } 156 | 157 | //////////////////////////////////////////////////////////////////////////////// 158 | /// Load a script from a file. 159 | inline bool ConsoleScriptLoad( std::vector *vArgs ) 160 | { 161 | TextConsoleInstance* pConsole = GetConsole(); 162 | if( vArgs != NULL && vArgs->size() != 0 ) { 163 | return pConsole->ScriptLoad( vArgs->at( 0 ) ); 164 | } 165 | else { 166 | return pConsole->ScriptLoad(); 167 | } 168 | } 169 | 170 | //////////////////////////////////////////////////////////////////////////////// 171 | /// Start script recording 172 | inline bool ConsoleScriptRecordStart( std::vector * ) 173 | { 174 | TextConsoleInstance* pConsole = GetConsole(); 175 | pConsole->ScriptRecordStart(); 176 | return true; 177 | } 178 | 179 | //////////////////////////////////////////////////////////////////////////////// 180 | /// Stop script recording. 181 | inline bool ConsoleScriptRecordStop( std::vector * ) 182 | { 183 | TextConsoleInstance* pConsole = GetConsole(); 184 | pConsole->ScriptRecordStop(); 185 | return true; 186 | } 187 | 188 | //////////////////////////////////////////////////////////////////////////////// 189 | /// Pause script recording. 190 | inline bool ConsoleScriptRecordPause( std::vector * ) 191 | { 192 | TextConsoleInstance* pConsole = GetConsole(); 193 | pConsole->ScriptRecordPause(); 194 | return true; 195 | } 196 | 197 | //////////////////////////////////////////////////////////////////////////////// 198 | /// Show the current script. 199 | inline bool ConsoleScriptShow( std::vector * ) 200 | { 201 | TextConsoleInstance* pConsole = GetConsole(); 202 | pConsole->ScriptShow(); 203 | return true; 204 | } 205 | 206 | //////////////////////////////////////////////////////////////////////////////// 207 | /// Run the current scipt or one from the named file. 208 | inline bool ConsoleScriptRun( std::vector *vArgs ) 209 | { 210 | TextConsoleInstance* pConsole = GetConsole(); 211 | if( vArgs != NULL && vArgs->size() != 0 ) { 212 | return pConsole->ScriptRun( vArgs->at( 0 ) ); 213 | } 214 | else { 215 | return pConsole->ScriptRun(); 216 | } 217 | } 218 | 219 | //////////////////////////////////////////////////////////////////////////////// 220 | /// Save the console settings. 221 | inline bool ConsoleSettingsSave( std::vector *vArgs ) 222 | { 223 | TextConsoleInstance* pConsole = GetConsole(); 224 | if( vArgs != NULL && vArgs->size() != 0 ) { 225 | return pConsole->SettingsSave( vArgs->at( 0 ) ); 226 | } 227 | else { 228 | return pConsole->SettingsSave(); 229 | } 230 | return false; 231 | } 232 | 233 | //////////////////////////////////////////////////////////////////////////////// 234 | /// Load console settings. 235 | inline bool ConsoleSettingsLoad( std::vector *vArgs ) 236 | { 237 | TextConsoleInstance* pConsole = GetConsole(); 238 | if( vArgs != NULL && vArgs->size() != 0 ) { 239 | return pConsole->SettingsLoad( vArgs->at( 0 ) ); 240 | } 241 | else { 242 | return pConsole->SettingsLoad(); 243 | } 244 | return false; 245 | } 246 | 247 | 248 | 249 | #endif 250 | 251 | -------------------------------------------------------------------------------- /examples/FltkConsole/GLHelpers.h: -------------------------------------------------------------------------------- 1 | /* 2 | * \file GLHelpers.h 3 | * 4 | * $Id: GLHelpers.h 197 2012-03-28 17:26:27Z gsibley $ 5 | */ 6 | 7 | #ifndef _GL_HELPERS_H_ 8 | #define _GL_HELPERS_H_ 9 | 10 | #include 11 | #include 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 18 | /// If a GL error has occured, this function outputs "msg" and the 19 | // programme exits. To avoid exiting @see WarnForGLErrors. 20 | inline void CheckForGLErrors( const char * msg = NULL ) 21 | { 22 | GLenum glError = glGetError(); 23 | if( glError != GL_NO_ERROR ) { 24 | if( msg ) { 25 | fprintf( stderr, "%s\n", msg ); 26 | } 27 | fprintf( stderr, "ERROR: %s\n", (char *) gluErrorString(glError) ); 28 | exit( -1 ); 29 | } 30 | } 31 | 32 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 33 | /// If a GL error has occured, this function outputs "msg" and automatically sets 34 | // the gl error state back to normal. 35 | inline void WarnForGLErrors( const char * msg = NULL ) 36 | { 37 | GLenum glError = (GLenum)glGetError(); 38 | if( glError != GL_NO_ERROR ) { 39 | if( msg ) { 40 | fprintf( stderr, "WARNING: %s\n", msg ); 41 | } 42 | fprintf( stderr, "ERROR: %s\n", (char *) gluErrorString(glError) ); 43 | } 44 | } 45 | 46 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 47 | /// Given a particular OpenGL Format, return the appropriate number of image channels. 48 | inline unsigned int NumChannels( unsigned int nFormat ) 49 | { 50 | switch( nFormat ){ 51 | case GL_LUMINANCE: 52 | return 1; 53 | case GL_RGB: 54 | return 3; 55 | case GL_RGBA: 56 | return 4; 57 | default: 58 | fprintf( stderr, "NumChannels() - unknown format\n" ); 59 | return 0; 60 | } 61 | return 0; 62 | } 63 | 64 | //////////////////////////////////////////////////////////////////////////////////////////////////// 65 | /// Given an OpenGL Type, return the associated number of bits used. 66 | inline unsigned int BitsPerChannel( unsigned int nType ) 67 | { 68 | switch( nType ){ 69 | case GL_UNSIGNED_BYTE: 70 | case GL_BYTE: 71 | return 8; 72 | case GL_2_BYTES: 73 | case GL_SHORT: 74 | case GL_UNSIGNED_SHORT: 75 | return 16; 76 | case GL_4_BYTES: 77 | case GL_FLOAT: 78 | case GL_UNSIGNED_INT: 79 | case GL_INT: 80 | return 32; 81 | case GL_DOUBLE: 82 | return 64; 83 | case GL_3_BYTES: 84 | return 24; 85 | default: 86 | fprintf( stderr, "\nBitsPerChannel() - unknown image Type"); 87 | return 0; 88 | } 89 | return 0; 90 | } 91 | 92 | /// 1) Generate a texutre ID 93 | // 2) Bind texture to memory 94 | // 3) Load texture into memory 95 | inline unsigned int GenerateAndBindRectTextureID( 96 | const unsigned int nWidth, 97 | const unsigned int nHeight, 98 | const unsigned int nFormat, 99 | const unsigned int nType, 100 | const unsigned char* pData 101 | ) 102 | { 103 | GLuint texId; 104 | glGenTextures( 1, &texId ); 105 | glBindTexture( GL_TEXTURE_RECTANGLE_ARB, texId ); 106 | glTexImage2D( GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGB, nWidth, nHeight, 0, nFormat, nType, pData ); 107 | return texId; 108 | } 109 | 110 | 111 | /// 1) Generate a texutre ID 112 | // 2) Bind texture to memory 113 | // 3) Load texture into memory 114 | inline unsigned int GenerateAndBindTextureID( 115 | const unsigned int nWidth, 116 | const unsigned int nHeight, 117 | const unsigned int nFormat, 118 | const unsigned int nType, 119 | const unsigned char* pData 120 | ) 121 | { 122 | GLuint texId; 123 | 124 | /// Ask for an ID 125 | glGenTextures( 1, &texId ); 126 | 127 | /// Associate that ID with the next thing we upload. 128 | glBindTexture( GL_TEXTURE_2D, texId ); 129 | 130 | /// Texture Mapping Mode: 131 | // GL_DECAL: use actual texture colors 132 | // GL_MODULATE: texture colors affected by poly's color (this is the default). 133 | // glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL ); 134 | 135 | // GL_UNPACK_ALIGNMENT Specifies the alignment requirements for the start of each 136 | // pixel row in memory. 1 specifies byte-alignment. 137 | glPixelStorei( GL_UNPACK_ALIGNMENT, 1); 138 | 139 | // Actually copy the texture into opengl 140 | glTexImage2D( 141 | GL_TEXTURE_2D, // texture target 142 | 0, // mipmap level 143 | GL_RGB, // internal format 144 | nWidth, // texture widht 145 | nHeight, // texture height 146 | 0, // width of the border (0 or 1) 147 | nFormat, // pixel data format 148 | nType, // pixel data type 149 | pData // pixel data 150 | ); 151 | 152 | glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); 153 | glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); 154 | 155 | /* 156 | // 157 | glPixelStorei( GL_UNPACK_ALIGNMENT, 1 ); 158 | 159 | // 160 | glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP ); 161 | 162 | // 163 | glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP ); 164 | 165 | // 166 | glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); 167 | 168 | // 169 | glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); 170 | // glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE ); 171 | */ 172 | 173 | return texId; 174 | } 175 | 176 | //////////////////////////////////////////////////////////////////////////////////////////////////// 177 | // Change to orthographic projection (for image drawing, etc) 178 | inline void PushOrtho( const unsigned int nWidth, const unsigned int nHeight ) 179 | { 180 | // load ortho to the size of the window 181 | glPushMatrix(); 182 | glLoadIdentity(); 183 | glMatrixMode(GL_PROJECTION); 184 | glPushMatrix(); 185 | glLoadIdentity(); 186 | glOrtho(0, nWidth, nHeight, 0, -1, 1); // left, right, top, bottom, near, far 187 | glMatrixMode( GL_MODELVIEW ); 188 | } 189 | 190 | //////////////////////////////////////////////////////////////////////////////////////////////////// 191 | /// Set projection matrix 192 | inline void PopOrtho() 193 | { 194 | glMatrixMode(GL_PROJECTION); 195 | glPopMatrix(); 196 | glMatrixMode(GL_MODELVIEW); 197 | glPopMatrix(); 198 | } 199 | 200 | //////////////////////////////////////////////////////////////////////////////////////////////////// 201 | /// Set projection matrix 202 | inline void OrthoQuad( 203 | const int nWidth, //< Input: 204 | const int nHeight, //< Input: 205 | const int nTop, //< Input: 206 | const int nLeft, //< Input: 207 | const int nBottom, //< Input: 208 | const int nRight //< Input: 209 | ) 210 | { 211 | glBegin( GL_QUADS ); 212 | glTexCoord2f( 0.0, 0.0 ); glVertex3f( nLeft, nTop, 1 ); 213 | glTexCoord2f( nWidth, 0.0 ); glVertex3f( nRight, nTop, 1 ); 214 | glTexCoord2f( nWidth, nHeight ); glVertex3f( nRight, nBottom, 1 ); 215 | glTexCoord2f( 0.0, nHeight ); glVertex3f( nLeft, nBottom, 1 ); 216 | glEnd(); 217 | } 218 | 219 | //////////////////////////////////////////////////////////////////////////////////////////////////// 220 | /// set perspective view. same as gluperspective(). 221 | inline void Perspective( double fovy, double aspect, double zNear, double zFar) 222 | { 223 | double xmin, xmax, ymin, ymax; 224 | ymax = zNear * tan(fovy * M_PI / 360.0); 225 | ymin = -ymax; 226 | xmin = ymin * aspect; 227 | xmax = ymax * aspect; 228 | glFrustum(xmin, xmax, ymin, ymax, zNear, zFar); 229 | } 230 | 231 | //////////////////////////////////////////////////////////////////////////////////////////////////// 232 | /// Reshape viewport whenever window changes size. 233 | inline void ReshapeViewport( int w, int h ) 234 | { 235 | // Viewport 236 | glViewport(0, 0, w, h ); 237 | 238 | // Projection 239 | glMatrixMode(GL_PROJECTION); 240 | glLoadIdentity(); 241 | GLfloat ratio = float(w) / float(h); 242 | Perspective(30.0, 1.0*ratio, 1.0, 30.0); 243 | glTranslatef(0.0, 0.0, -8.0); 244 | 245 | // Model view 246 | glMatrixMode(GL_MODELVIEW); 247 | glLoadIdentity(); 248 | } 249 | 250 | 251 | 252 | #endif 253 | -------------------------------------------------------------------------------- /include/FLConsole/FLConsoleFunction.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | \file FLConsoleFunction.h 4 | 5 | Collection of ConsoleFunc's for FLConsole. 6 | 7 | $Id: FLConsoleFunction.h 164 2010-03-01 20:19:13Z gsibley $ 8 | */ 9 | 10 | #ifndef __FLCONSOLE_FUNCTION__ 11 | #define __FLCONSOLE_FUNCTION__ 12 | 13 | 14 | #include 15 | #include 16 | 17 | //////////////////////////////////////////////////////////////////////////////// 18 | /// Print the current CVars version. 19 | inline bool ConsoleVersion( std::vector* ) 20 | { 21 | FLConsoleInstance* pConsole = GetConsole(); 22 | pConsole->Printf( "CVars v%d.%d.%d", 23 | CVARS_MAJOR_REV, 24 | CVARS_MINOR_REV, 25 | CVARS_PATCH_REV ); 26 | return true; 27 | } 28 | 29 | //////////////////////////////////////////////////////////////////////////////// 30 | /// Help for functions and variables or just general help. 31 | inline bool ConsoleHelp( std::vector *vArgs ) 32 | { 33 | FLConsoleInstance* pConsole = GetConsole(); 34 | return pConsole->Help( vArgs ); 35 | } 36 | 37 | //////////////////////////////////////////////////////////////////////////////// 38 | /// Looks for the lists of substrings provided in vArgs in the CVarTrie. 39 | inline bool ConsoleFind( std::vector *vArgs ) 40 | { 41 | Trie& trie = CVarUtils::TrieInstance(); 42 | FLConsoleInstance* pConsole = GetConsole(); 43 | if( vArgs != NULL && vArgs->size() > 0 ) { 44 | for( size_t i=0; isize(); i++ ) { 45 | std::vector vCVarNames = trie.FindListSubStr( vArgs->at(i) ); 46 | 47 | for( size_t j=0; jPrintf( "%s", vCVarNames[j].c_str() ); 49 | } 50 | } 51 | } 52 | return true; 53 | } 54 | 55 | //////////////////////////////////////////////////////////////////////////////// 56 | /// First argument indicates the file name, the following arguments are 57 | // used to choose a subset of variables to be saved using the provided 58 | // substrings. 59 | // Last argument can be used to be verbose when saving. 60 | inline bool ConsoleSave( std::vector *vArgs ) 61 | { 62 | FLConsoleInstance* pConsole = GetConsole(); 63 | std::string sFile = "cvars.xml"; 64 | std::vector< std::string > vAcceptedSubstrings; 65 | 66 | if( vArgs != NULL && vArgs->size() > 0 ) { 67 | sFile = vArgs->at( 0 ); 68 | for( size_t i=1; isize(); i++ ) { 69 | vAcceptedSubstrings.push_back( vArgs->at( i ) ); 70 | } 71 | } 72 | 73 | pConsole->Printf( "Saving cvars to \"%s\".", sFile.c_str() ); 74 | if( !CVarUtils::Save( sFile, vAcceptedSubstrings ) ) { 75 | pConsole->PrintError( "Error saving file.\n" ); 76 | return false; 77 | } 78 | 79 | return true; 80 | } 81 | 82 | //////////////////////////////////////////////////////////////////////////////// 83 | /// Load CVars from a file. 84 | inline bool ConsoleLoad( std::vector *vArgs ) 85 | { 86 | FLConsoleInstance* pConsole = GetConsole(); 87 | std::string sFile = "cvars.xml"; 88 | std::vector< std::string > vAcceptedSubstrings; 89 | 90 | if( vArgs != NULL && vArgs->size() > 0 ) { 91 | sFile = vArgs->at( 0 ); 92 | for( size_t i=1; isize(); i++ ) { 93 | vAcceptedSubstrings.push_back( vArgs->at(i) ); 94 | } 95 | } 96 | pConsole->Printf( "Loading file \"%s\".", sFile.c_str() ); 97 | if( !CVarUtils::Load( sFile, vAcceptedSubstrings ) ) { 98 | pConsole->PrintError( "Error: Could not load \"%s\".", sFile.c_str() ); 99 | } 100 | return true; 101 | } 102 | 103 | //////////////////////////////////////////////////////////////////////////////// 104 | /// Exits program from command line. 105 | inline bool ConsoleExit( std::vector * ) 106 | { 107 | exit( 0 ); 108 | } 109 | 110 | //////////////////////////////////////////////////////////////////////////////// 111 | /// Save the console history to a file. 112 | inline bool ConsoleHistorySave( std::vector *vArgs ) 113 | { 114 | FLConsoleInstance* pConsole = GetConsole(); 115 | if( vArgs != NULL && vArgs->size() != 0 ) { 116 | return pConsole->HistorySave( vArgs->at( 0 ) ); 117 | } 118 | else { 119 | return pConsole->HistorySave(); 120 | } 121 | } 122 | 123 | //////////////////////////////////////////////////////////////////////////////// 124 | /// Load a previously saved console history from a file. 125 | inline bool ConsoleHistoryLoad( std::vector *vArgs ) 126 | { 127 | FLConsoleInstance* pConsole = GetConsole(); 128 | if( vArgs != NULL && vArgs->size() != 0 ) { 129 | return pConsole->HistoryLoad( vArgs->at( 0 ) ); 130 | } 131 | else { 132 | return pConsole->HistoryLoad(); 133 | } 134 | } 135 | 136 | //////////////////////////////////////////////////////////////////////////////// 137 | /// clear the console history. 138 | inline bool ConsoleHistoryClear( std::vector* ) 139 | { 140 | FLConsoleInstance* pConsole = GetConsole(); 141 | pConsole->HistoryClear(); 142 | return true; 143 | } 144 | 145 | //////////////////////////////////////////////////////////////////////////////// 146 | /// Save the current script. 147 | inline bool ConsoleScriptSave( std::vector *vArgs ) 148 | { 149 | FLConsoleInstance* pConsole = GetConsole(); 150 | if( vArgs != NULL && vArgs->size() != 0 ) { 151 | return pConsole->ScriptSave( vArgs->at( 0 ) ); 152 | } 153 | else { 154 | return pConsole->ScriptSave(); 155 | } 156 | 157 | } 158 | 159 | //////////////////////////////////////////////////////////////////////////////// 160 | /// Load a script from a file. 161 | inline bool ConsoleScriptLoad( std::vector *vArgs ) 162 | { 163 | FLConsoleInstance* pConsole = GetConsole(); 164 | if( vArgs != NULL && vArgs->size() != 0 ) { 165 | return pConsole->ScriptLoad( vArgs->at( 0 ) ); 166 | } 167 | else { 168 | return pConsole->ScriptLoad(); 169 | } 170 | } 171 | 172 | //////////////////////////////////////////////////////////////////////////////// 173 | /// Start script recording 174 | inline bool ConsoleScriptRecordStart( std::vector * ) 175 | { 176 | FLConsoleInstance* pConsole = GetConsole(); 177 | pConsole->ScriptRecordStart(); 178 | return true; 179 | } 180 | 181 | //////////////////////////////////////////////////////////////////////////////// 182 | /// Stop script recording. 183 | inline bool ConsoleScriptRecordStop( std::vector * ) 184 | { 185 | FLConsoleInstance* pConsole = GetConsole(); 186 | pConsole->ScriptRecordStop(); 187 | return true; 188 | } 189 | 190 | //////////////////////////////////////////////////////////////////////////////// 191 | /// Pause script recording. 192 | inline bool ConsoleScriptRecordPause( std::vector * ) 193 | { 194 | FLConsoleInstance* pConsole = GetConsole(); 195 | pConsole->ScriptRecordPause(); 196 | return true; 197 | } 198 | 199 | //////////////////////////////////////////////////////////////////////////////// 200 | /// Show the current script. 201 | inline bool ConsoleScriptShow( std::vector * ) 202 | { 203 | FLConsoleInstance* pConsole = GetConsole(); 204 | pConsole->ScriptShow(); 205 | return true; 206 | } 207 | 208 | //////////////////////////////////////////////////////////////////////////////// 209 | /// Run the current scipt or one from the named file. 210 | inline bool ConsoleScriptRun( std::vector *vArgs ) 211 | { 212 | FLConsoleInstance* pConsole = GetConsole(); 213 | if( vArgs != NULL && vArgs->size() != 0 ) { 214 | return pConsole->ScriptRun( vArgs->at( 0 ) ); 215 | } 216 | else { 217 | return pConsole->ScriptRun(); 218 | } 219 | } 220 | 221 | //////////////////////////////////////////////////////////////////////////////// 222 | /// Save the console settings. 223 | inline bool ConsoleSettingsSave( std::vector *vArgs ) 224 | { 225 | FLConsoleInstance* pConsole = GetConsole(); 226 | if( vArgs != NULL && vArgs->size() != 0 ) { 227 | return pConsole->SettingsSave( vArgs->at( 0 ) ); 228 | } 229 | else { 230 | return pConsole->SettingsSave(); 231 | } 232 | return false; 233 | } 234 | 235 | //////////////////////////////////////////////////////////////////////////////// 236 | /// Load console settings. 237 | inline bool ConsoleSettingsLoad( std::vector *vArgs ) 238 | { 239 | FLConsoleInstance* pConsole = GetConsole(); 240 | if( vArgs != NULL && vArgs->size() != 0 ) { 241 | return pConsole->SettingsLoad( vArgs->at( 0 ) ); 242 | } 243 | else { 244 | return pConsole->SettingsLoad(); 245 | } 246 | return false; 247 | } 248 | 249 | 250 | 251 | #endif 252 | 253 | -------------------------------------------------------------------------------- /include/GLConsole/GLConsoleFunction.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | \file GLConsoleFunction.h 4 | 5 | Collection of ConsoleFunc's for GLConsole. 6 | 7 | $Id: GLConsoleFunction.h 162 2010-02-15 19:11:05Z gsibley $ 8 | */ 9 | 10 | #ifndef __GL_CONSOLE_FUNCTION__ 11 | #define __GL_CONSOLE_FUNCTION__ 12 | 13 | 14 | #include 15 | #include 16 | 17 | //////////////////////////////////////////////////////////////////////////////// 18 | /** 19 | * The current console version. 20 | */ 21 | inline bool ConsoleVersion( std::vector* ) 22 | { 23 | GLConsole* pConsole = GetConsole(); 24 | pConsole->Printf( "CVars v%d.%d.%d", 25 | CVARS_MAJOR_REV, 26 | CVARS_MINOR_REV, 27 | CVARS_PATCH_REV ); 28 | return true; 29 | } 30 | 31 | //////////////////////////////////////////////////////////////////////////////// 32 | /** 33 | * Help for functions and variables or just general help. 34 | */ 35 | inline bool ConsoleHelp( std::vector *vArgs ) 36 | { 37 | GLConsole* pConsole = GetConsole(); 38 | return pConsole->Help( vArgs ); 39 | } 40 | 41 | //////////////////////////////////////////////////////////////////////////////// 42 | /** 43 | * Looks for the lists of substrings provided in vArgs in the CVarTrie. 44 | */ 45 | inline bool ConsoleFind( std::vector *vArgs ) 46 | { 47 | GLConsole* pConsole = GetConsole(); 48 | Trie& trie = CVarUtils::TrieInstance(); 49 | 50 | if( vArgs != NULL && vArgs->size() > 0 ) { 51 | for( size_t i=0; isize(); i++ ) { 52 | std::vector vCVarNames = trie.FindListSubStr( vArgs->at(i) ); 53 | 54 | for( size_t j=0; jPrintf( "%s", vCVarNames[j].c_str() ); 56 | } 57 | } 58 | } 59 | return true; 60 | } 61 | 62 | //////////////////////////////////////////////////////////////////////////////// 63 | /** 64 | * First argument indicates the file name, the following arguments are 65 | * used to choose a subset of variables to be saved using the provided 66 | * substrings. 67 | * Last argument can be used to be verbose when saving. 68 | */ 69 | inline bool ConsoleSave( std::vector *vArgs ) 70 | { 71 | GLConsole* pConsole = GetConsole(); 72 | std::string sFile = "cvars.xml"; 73 | std::vector< std::string > vAcceptedSubstrings; 74 | 75 | if( vArgs != NULL && vArgs->size() > 0 ) { 76 | sFile = vArgs->at( 0 ); 77 | for( size_t i=1; isize(); i++ ) { 78 | vAcceptedSubstrings.push_back( vArgs->at( i ) ); 79 | } 80 | } 81 | 82 | pConsole->Printf( "Saving cvars to \"%s\".", sFile.c_str() ); 83 | if( !CVarUtils::Save( sFile, vAcceptedSubstrings ) ) { 84 | pConsole->PrintError( "Error saving file.\n" ); 85 | return false; 86 | } 87 | 88 | return true; 89 | } 90 | 91 | //////////////////////////////////////////////////////////////////////////////// 92 | /** 93 | * Load CVars from a file 94 | */ 95 | inline bool ConsoleLoad( std::vector *vArgs ) 96 | { 97 | GLConsole* pConsole = GetConsole(); 98 | std::string sFile = "cvars.xml"; 99 | std::vector< std::string > vAcceptedSubstrings; 100 | 101 | if( vArgs != NULL && vArgs->size() > 0 ) { 102 | sFile = vArgs->at( 0 ); 103 | for( size_t i=1; isize(); i++ ) { 104 | vAcceptedSubstrings.push_back( vArgs->at(i) ); 105 | } 106 | } 107 | pConsole->Printf( "Loading file \"%s\".", sFile.c_str() ); 108 | if( !CVarUtils::Load( sFile, vAcceptedSubstrings ) ) { 109 | pConsole->PrintError( "Error: Could not load \"%s\".", sFile.c_str() ); 110 | } 111 | return true; 112 | } 113 | 114 | //////////////////////////////////////////////////////////////////////////////// 115 | /** 116 | * Exits program from command line 117 | */ 118 | inline bool ConsoleExit( std::vector * ) 119 | { 120 | exit( 0 ); 121 | } 122 | 123 | //////////////////////////////////////////////////////////////////////////////// 124 | /** 125 | * Save the console history to a file 126 | */ 127 | inline bool ConsoleHistorySave( std::vector *vArgs ) 128 | { 129 | GLConsole* pConsole = GetConsole(); 130 | if( vArgs != NULL && vArgs->size() != 0 ) { 131 | return pConsole->HistorySave( vArgs->at( 0 ) ); 132 | } 133 | else { 134 | return pConsole->HistorySave(); 135 | } 136 | } 137 | 138 | //////////////////////////////////////////////////////////////////////////////// 139 | /** 140 | * Load a previously saved console history from a file 141 | */ 142 | inline bool ConsoleHistoryLoad( std::vector *vArgs ) 143 | { 144 | GLConsole* pConsole = GetConsole(); 145 | if( vArgs != NULL && vArgs->size() != 0 ) { 146 | return pConsole->HistoryLoad( vArgs->at( 0 ) ); 147 | } 148 | else { 149 | return pConsole->HistoryLoad(); 150 | } 151 | } 152 | 153 | //////////////////////////////////////////////////////////////////////////////// 154 | /** 155 | * clear the console history 156 | */ 157 | inline bool ConsoleHistoryClear( std::vector* ) 158 | { 159 | GLConsole* pConsole = GetConsole(); 160 | pConsole->HistoryClear(); 161 | return true; 162 | } 163 | 164 | //////////////////////////////////////////////////////////////////////////////// 165 | /** 166 | * Save the current script 167 | */ 168 | inline bool ConsoleScriptSave( std::vector *vArgs ) 169 | { 170 | GLConsole* pConsole = GetConsole(); 171 | if( vArgs != NULL && vArgs->size() != 0 ) { 172 | return pConsole->ScriptSave( vArgs->at( 0 ) ); 173 | } 174 | else { 175 | return pConsole->ScriptSave(); 176 | } 177 | 178 | } 179 | 180 | //////////////////////////////////////////////////////////////////////////////// 181 | /** 182 | * Load a script from a file 183 | */ 184 | inline bool ConsoleScriptLoad( std::vector *vArgs ) 185 | { 186 | GLConsole* pConsole = GetConsole(); 187 | if( vArgs != NULL && vArgs->size() != 0 ) { 188 | return pConsole->ScriptLoad( vArgs->at( 0 ) ); 189 | } 190 | else { 191 | return pConsole->ScriptLoad(); 192 | } 193 | } 194 | 195 | //////////////////////////////////////////////////////////////////////////////// 196 | /** 197 | * Start script recording 198 | */ 199 | inline bool ConsoleScriptRecordStart( std::vector * ) 200 | { 201 | GLConsole* pConsole = GetConsole(); 202 | pConsole->ScriptRecordStart(); 203 | return true; 204 | } 205 | 206 | //////////////////////////////////////////////////////////////////////////////// 207 | /** 208 | * Stop script recording 209 | */ 210 | inline bool ConsoleScriptRecordStop( std::vector * ) 211 | { 212 | GLConsole* pConsole = GetConsole(); 213 | pConsole->ScriptRecordStop(); 214 | return true; 215 | } 216 | 217 | //////////////////////////////////////////////////////////////////////////////// 218 | /** 219 | * Pause script recording 220 | */ 221 | inline bool ConsoleScriptRecordPause( std::vector * ) 222 | { 223 | GLConsole* pConsole = GetConsole(); 224 | pConsole->ScriptRecordPause(); 225 | return true; 226 | } 227 | 228 | //////////////////////////////////////////////////////////////////////////////// 229 | /** 230 | * Show the current script 231 | */ 232 | inline bool ConsoleScriptShow( std::vector * ) 233 | { 234 | GLConsole* pConsole = GetConsole(); 235 | pConsole->ScriptShow(); 236 | return true; 237 | } 238 | 239 | //////////////////////////////////////////////////////////////////////////////// 240 | /** 241 | * Run the current scipt or one from the named file 242 | */ 243 | inline bool ConsoleScriptRun( std::vector *vArgs ) 244 | { 245 | GLConsole* pConsole = GetConsole(); 246 | if( vArgs != NULL && vArgs->size() != 0 ) { 247 | return pConsole->ScriptRun( vArgs->at( 0 ) ); 248 | } 249 | else { 250 | return pConsole->ScriptRun(); 251 | } 252 | } 253 | 254 | //////////////////////////////////////////////////////////////////////////////// 255 | /** 256 | * Save the console settings 257 | */ 258 | inline bool ConsoleSettingsSave( std::vector *vArgs ) 259 | { 260 | GLConsole* pConsole = GetConsole(); 261 | if( vArgs != NULL && vArgs->size() != 0 ) { 262 | return pConsole->SettingsSave( vArgs->at( 0 ) ); 263 | } 264 | else { 265 | return pConsole->SettingsSave(); 266 | } 267 | return false; 268 | } 269 | 270 | //////////////////////////////////////////////////////////////////////////////// 271 | /** 272 | * Load console settings 273 | */ 274 | inline bool ConsoleSettingsLoad( std::vector *vArgs ) 275 | { 276 | GLConsole* pConsole = GetConsole(); 277 | if( vArgs != NULL && vArgs->size() != 0 ) { 278 | return pConsole->SettingsLoad( vArgs->at( 0 ) ); 279 | } 280 | else { 281 | return pConsole->SettingsLoad(); 282 | } 283 | return false; 284 | } 285 | 286 | 287 | #endif 288 | 289 | 290 | -------------------------------------------------------------------------------- /examples/GlutConsole/GlutConsoleDemo.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************************* 2 | * 3 | * CVar and GlutConsole Demo App 1 4 | * 5 | * This demo shows the basics of how to use CVars and the GLConsole 6 | * 7 | *******************************************************************/ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | //include this header for CVars and GLConsole 20 | #include 21 | 22 | //A CVar version of std::vector 23 | #include 24 | 25 | //A CVar version of std::map 26 | #include 27 | 28 | 29 | // Single global instance so glut can get access 30 | GLConsole theConsole; 31 | 32 | using CVarUtils::operator<<; 33 | using CVarUtils::operator>>; 34 | 35 | using namespace std; 36 | 37 | //Function declarations 38 | void display(); 39 | void reshape (int w, int h); 40 | void idle(); 41 | void special(int key, int px, int py); 42 | void keyfunc( unsigned char key, int px, int py ); 43 | 44 | 45 | 46 | /** 47 | * The Main function 48 | * Set up the GLUT window and create some CVars 49 | */ 50 | int main (int argc, const char * argv[]) 51 | { 52 | //Initialise GLUT 53 | glutInit(&argc, (char **)argv); 54 | glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); 55 | glutInitWindowPosition (300, 50); 56 | glutInitWindowSize (800, 600); 57 | glutCreateWindow("GLConsole Demo"); 58 | 59 | // standard GL init 60 | glShadeModel(GL_SMOOTH); 61 | glClearColor(0.0f, 0.0f, 1.0f, 0.5f); 62 | glClearDepth(1.0f); 63 | glEnable(GL_DEPTH_TEST); 64 | glDepthFunc(GL_LEQUAL); 65 | glEnable ( GL_COLOR_MATERIAL ); 66 | glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); 67 | 68 | //register functions 69 | glutReshapeFunc (reshape); 70 | glutDisplayFunc (display); 71 | glutKeyboardFunc (keyfunc); 72 | glutSpecialFunc (special); 73 | glutIdleFunc(idle); 74 | 75 | ////// How to make some CVars ////// 76 | 77 | //CVars have a name and a default value 78 | CVarUtils::CreateCVar( "myFirstCVar", 1); 79 | //You can make groups using a dot in the name. Helps keep things tidy 80 | CVarUtils::CreateCVar( "LevelOne.myVar1 ", 2 ); 81 | CVarUtils::CreateCVar( "LevelOne.myVar2", 3 ); 82 | //You can have lots of levels 83 | CVarUtils::CreateCVar( "LevelOne.LevelTwo.another", 3.14 ); 84 | 85 | //CVars can also have a help string associated 86 | //Just type help var_name on the console 87 | CVarUtils::CreateCVar( "whatAmIFor", 47, "A test variable to teach you about help"); 88 | 89 | //To actually make these CVars useful they need effect something in your program, 90 | //so you normally create them as follows 91 | int& nTest = CVarUtils::CreateCVar( "testVar", 100, "Another test CVar" ); 92 | 93 | //nTest is now always equal the value of testVar and vice-vera as it is a reference 94 | cout << "nTest: " << nTest << endl; 95 | //This is how you get a CVar value. Note the type specification 96 | cout << "testVar: " << CVarUtils::GetCVar( "testVar" ) << endl; 97 | 98 | nTest = 200; 99 | cout << "testVar: " << CVarUtils::GetCVar( "testVar" ) << endl; 100 | 101 | //this is how to set a CVar 102 | CVarUtils::SetCVar( "testVar", 300 ); 103 | cout << "nTest: " << nTest << endl; 104 | 105 | // How to save to text 106 | CVarUtils::SetStreamType( CVARS_TXT_STREAM ); 107 | const string sOutputFile = "my_cvars.txt"; 108 | cout << "Saving cvars in text format to: " << sOutputFile << endl; 109 | CVarUtils::Save( "my_cvars.txt" ); 110 | 111 | CVarUtils::Load( "my_cvars2.txt" ); 112 | 113 | //CVars have exception handling 114 | try { 115 | cout << "Nonexistant: " << CVarUtils::GetCVar( "nonExistant" ); 116 | } 117 | catch( CVarUtils::CVarException e ){ 118 | switch( e ) { 119 | case CVarUtils::CVarNonExistant: 120 | cout << "CVar does not exist" << endl; 121 | break; 122 | default: 123 | cout << "Unknown exception." << endl; 124 | break; 125 | } 126 | } 127 | 128 | ///@TODO finish off the demo 129 | //You can also create your own types of CVar 130 | //so you are not limited to ints, doubles, floats, and strings 131 | 132 | //Included with CVars is an implementation of a CVar vector and a CVar map 133 | //These will work for vectors and maps of basics types 134 | 135 | //Have a look at demo 2 to see how to make your own types. 136 | 137 | // Create a vector of ints, this function uses the 138 | // serialising/deserialising functions from "CVars/CVarVectorIO.h" 139 | // obtained using the CVarUtils namespace 140 | CVarUtils::CreateCVar< std::vector >( "stl.vector", std::vector() ); 141 | 142 | #if 0 143 | CVarUtils::CreateCVar< std::vector >( "stl.vector", std::vector(), true, 144 | &(CVarUtils::operator<<), &(CVarUtils::operator>>) ); 145 | 146 | // Create a map of (int,string), this function uses the 147 | // serialising/deserialising functions from "CVars/CVarMapIO.h" 148 | // obtained using the CVarUtils namespace 149 | std::map mMap; 150 | mMap[0] = "zero"; 151 | mMap[1] = "one"; 152 | 153 | CVarUtils::CreateCVar >( "stl.map", mMap, true, 154 | &(CVarUtils::operator<<), &(CVarUtils::operator>>) ); 155 | #endif 156 | 157 | // print out all the CVars (with optional formatting tags -- PMWiki table tags in this case) 158 | // CVarUtils::PrintCVars( "(:cellnr:) ", "", "\n(:cell:) ","" ); 159 | 160 | glutMainLoop(); 161 | 162 | return 0; 163 | } 164 | 165 | /** 166 | * What to draw each refresh 167 | * Called by GLUT 168 | */ 169 | void display() 170 | { 171 | // This is how you register a CVar with the console, having a CVar 172 | // in an inner loop is a bad idea, however. 173 | //Hence the try/catch block 174 | 175 | float triangleSize = 1.0; 176 | try { 177 | //triangleSize is set to the default value of the CVar "triangle.size 178 | // Use this syntax to make the CVar CVar name, Default value, Help text, 179 | triangleSize = CVarUtils::CreateCVar( "triangle.size", 1.0f, "Triangle size value" ); 180 | } 181 | catch( CVarUtils::CVarException e ) { 182 | switch( e ) { 183 | case CVarUtils::CVarAlreadyCreated: 184 | //it already exists, so just assign the latest value 185 | triangleSize = CVarUtils::GetCVar( "triangle.size" ); 186 | break; 187 | default: 188 | printf( "Unknown exception" ); 189 | break; 190 | } 191 | } 192 | 193 | //set up the scene 194 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 195 | glLoadIdentity(); 196 | glTranslatef(0,0.0f,-2.0f); 197 | 198 | //draw the triangle 199 | glBegin(GL_TRIANGLES); { 200 | glColor3f(1.0f,0.0f,0.0f); 201 | glVertex3f( 0.0f, triangleSize, 0.0f); 202 | glColor3f(0.0f,triangleSize,0.0f); 203 | glVertex3f(-triangleSize,-triangleSize, 0.0f); 204 | glColor3f(0.0f,0.0f,triangleSize); 205 | glVertex3f( triangleSize,-triangleSize, 0.0f); 206 | } 207 | glEnd(); 208 | 209 | //draw the console. always call it last so it is drawn on top of everything 210 | theConsole.RenderConsole(); 211 | 212 | glutSwapBuffers(); 213 | } 214 | 215 | /** 216 | * resize the window to the desired size 217 | * @param w Window width 218 | * @param h Window height 219 | */ 220 | void reshape (int w, int h) 221 | { 222 | glViewport ( 0, 0, w, h ); 223 | glMatrixMode ( GL_PROJECTION ); 224 | glLoadIdentity ( ); 225 | 226 | if ( h == 0 ) 227 | gluPerspective ( 80, ( float ) w, 1.0, 5000.0 ); 228 | else 229 | gluPerspective ( 80, ( float ) w / ( float ) h, 1.0, 5000.0 ); 230 | 231 | glMatrixMode ( GL_MODELVIEW ); 232 | glLoadIdentity ( ); 233 | } 234 | 235 | /** 236 | * just redisplay constantly to let the console update... 237 | */ 238 | void idle() 239 | { 240 | #ifdef WIN32 241 | Sleep( 1 ); 242 | #else 243 | usleep( (int)1e4 ); 244 | #endif 245 | glutPostRedisplay(); // we have 246 | } 247 | 248 | /** 249 | * Pass keboard events to the console. 250 | * Up and down arrows to scroll through console history. 251 | * Shift+up or shift+down to scroll the console window. 252 | * Pageup or pagedown to scroll the console window as well. 253 | */ 254 | void special(int key, int, int ) 255 | { 256 | if( theConsole.IsOpen() ) 257 | { 258 | //pass all key strokes to the console 259 | theConsole.SpecialFunc( key ); 260 | } 261 | else 262 | { 263 | //do your own thing with the keys 264 | } 265 | } 266 | 267 | /** 268 | * handle incoming key events and send to console 269 | */ 270 | void keyfunc( unsigned char key, int, int ) 271 | { 272 | switch( key ) { 273 | 274 | case 27: //escape 275 | exit ( 0 ); 276 | break; 277 | 278 | case GLCONSOLE_KEY: //~ key opens console on US keyboards. 279 | //On UK keyboards it is the ` key (the one above the Tab and left of the 1 keys) 280 | theConsole.ToggleConsole(); 281 | break; 282 | 283 | default: 284 | if( theConsole.IsOpen() ) { 285 | //send keystroke to console 286 | theConsole.KeyboardFunc( key ); 287 | } 288 | else { 289 | //do your own thing with the keys 290 | } 291 | break; 292 | } 293 | } 294 | -------------------------------------------------------------------------------- /cmake_modules/install_package.cmake: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # install_package.cmake - This function will install and "export" your library 3 | # or files in such a way that they can be found using either CMake's 4 | # "FindXXX.cmake" mechanism or with pkg-config. This makes your code boradly 5 | # compatible with traditional unix best practices, and also easy to use from 6 | # other CMake projets. 7 | # 8 | # This function will create and install a ${PACKAGE}.pc pkg-config file. 9 | # Will also create a Find${PACKAGE}.cmake, which will in turn call. 10 | 11 | # 12 | # install_package - Takes a package name and the following optional named arguments: 13 | # PKG_NAME , usually the same as ${PROJECT_NAME} 14 | # LIB_NAME 15 | # VERSION 16 | # INSTALL_HEADERS
17 | # DESTINATION 18 | # INCLUDE_DIRS 19 | # LINK_LIBS 20 | # LINK_DIRS 21 | # CFLAGS 22 | # CXXFLAGS 23 | # 24 | ################################################################################ 25 | include(CMakeParseArguments) 26 | 27 | get_filename_component(modules_dir ${CMAKE_CURRENT_LIST_FILE} PATH) 28 | 29 | function(install_package) 30 | set(PACKAGE_OPTIONS "") 31 | set(PACKAGE_SINGLE_ARGS "") 32 | set( PACKAGE_MULTI_ARGS 33 | PKG_NAME 34 | LIB_NAME 35 | VERSION 36 | DESCRIPTION 37 | INSTALL_HEADERS 38 | INSTALL_GENERATED_HEADERS 39 | INSTALL_HEADER_DIRS 40 | INSTALL_INCLUDE_DIR 41 | DESTINATION 42 | INCLUDE_DIRS 43 | LINK_LIBS 44 | LINK_DIRS 45 | CFLAGS 46 | CXXFLAGS 47 | ) 48 | cmake_parse_arguments( PACKAGE 49 | "${PACKAGE_OPTIONS}" 50 | "${PACKAGE_SINGLE_ARGS}" 51 | "${PACKAGE_MULTI_ARGS}" 52 | "${ARGN}" 53 | ) 54 | 55 | # Add package to CMake package registery for use from the build tree. RISKY. 56 | option( EXPORT_${PROJECT_NAME} 57 | "Should the ${PROJECT_NAME} package be exported for use by other software" OFF ) 58 | 59 | mark_as_advanced( EXPORT_${PROJECT_NAME} ) 60 | 61 | 62 | # clean things up 63 | if( PACKAGE_LINK_DIRS ) 64 | list( REMOVE_DUPLICATES PACKAGE_LINK_DIRS ) 65 | endif() 66 | if(PACKAGE_LINK_LIBS) 67 | list( REMOVE_DUPLICATES PACKAGE_LINK_LIBS ) 68 | endif() 69 | if( PACKAGE_INCLUDE_DIRS) 70 | list( REMOVE_DUPLICATES PACKAGE_INCLUDE_DIRS ) 71 | endif() 72 | 73 | # construct Cflags arguments for pkg-config file 74 | set( PACKAGE_CFLAGS "${PACKAGE_CFLAGS} ${CMAKE_C_FLAGS}" ) 75 | foreach(var IN LISTS PACKAGE_INCLUDE_DIRS ) 76 | set( PACKAGE_CFLAGS "${PACKAGE_CFLAGS} -I${var}" ) 77 | endforeach() 78 | 79 | # now construct Libs.private arguments 80 | foreach(var IN LISTS PACKAGE_LINK_DIRS ) 81 | set( PACKAGE_LIBS "${PACKAGE_LIBS} -L${var}" ) 82 | endforeach() 83 | foreach(var IN LISTS PACKAGE_LINK_LIBS ) 84 | if( EXISTS ${var} OR ${var} MATCHES "-framework*" ) 85 | set( PACKAGE_LIBS "${PACKAGE_LIBS} ${var}" ) 86 | else() # assume it's just a -l call?? 87 | set( PACKAGE_LIBS "${PACKAGE_LIBS} -l${var}" ) 88 | endif() 89 | endforeach() 90 | 91 | # add any CXX flags user has passed in 92 | if( PACKAGE_CXXFLAGS ) 93 | set( PACKAGE_CFLAGS ${PACKAGE_CXXFLAGS} ) 94 | endif() 95 | 96 | # In case we want to install. 97 | if( NOT EXPORT_${PROJECT_NAME} ) 98 | # add "installed" library to list of required libraries to link against 99 | if( PACKAGE_LIB_NAME ) 100 | if(POLICY CMP0026) 101 | cmake_policy( SET CMP0026 OLD ) 102 | endif() 103 | get_target_property( _target_library ${PACKAGE_LIB_NAME} LOCATION ) 104 | get_filename_component( _lib ${_target_library} NAME ) 105 | list( APPEND PACKAGE_LINK_LIBS ${PACKAGE_LIB_NAME} ) 106 | endif() 107 | 108 | if( PACKAGE_INSTALL_HEADER_DIRS ) 109 | foreach(dir IN LISTS PACKAGE_INSTALL_HEADER_DIRS ) 110 | install( DIRECTORY ${dir} 111 | DESTINATION ${PACKAGE_DESTINATION}/include 112 | FILES_MATCHING PATTERN "*.h|*.hxx|*.hpp" 113 | ) 114 | endforeach() 115 | endif() 116 | 117 | # install header files 118 | if( PACKAGE_INSTALL_HEADERS ) 119 | # install( FILES ${PACKAGE_INSTALL_HEADERS} DESTINATION ${PACKAGE_DESTINATION} ) 120 | foreach(hdr IN LISTS PACKAGE_INSTALL_HEADERS ) 121 | get_filename_component( _fp ${hdr} ABSOLUTE ) 122 | file( RELATIVE_PATH _rpath ${CMAKE_BINARY_DIR} ${_fp} ) 123 | get_filename_component( _dir ${_rpath} DIRECTORY ) 124 | install( FILES ${_fp} 125 | DESTINATION ${PACKAGE_DESTINATION}/${_dir} ) 126 | endforeach() 127 | endif() 128 | if( PACKAGE_INSTALL_GENERATED_HEADERS ) 129 | foreach(hdr IN LISTS PACKAGE_INSTALL_GENERATED_HEADERS ) 130 | get_filename_component( _fp ${hdr} ABSOLUTE ) 131 | file( RELATIVE_PATH _rpath ${CMAKE_BINARY_DIR} ${_fp} ) 132 | get_filename_component( _dir ${_rpath} DIRECTORY ) 133 | install( FILES ${_fp} 134 | DESTINATION ${PACKAGE_DESTINATION}/${_dir} ) 135 | endforeach() 136 | endif() 137 | 138 | if( PACKAGE_INSTALL_INCLUDE_DIR ) 139 | install(DIRECTORY ${CMAKE_SOURCE_DIR}/include DESTINATION ${PACKAGE_DESTINATION} ) 140 | endif() 141 | 142 | # install library itself 143 | if( PACKAGE_LIB_NAME ) 144 | install( TARGETS ${PACKAGE_LIB_NAME} DESTINATION ${CMAKE_INSTALL_PREFIX}/lib ) 145 | set( PACKAGE_LIB_LINK "-l${PACKAGE_LIB_NAME}" ) 146 | endif() 147 | 148 | # build pkg-config file 149 | if( PACKAGE_PKG_NAME ) 150 | configure_file( ${modules_dir}/PkgConfig.pc.in ${PACKAGE_PKG_NAME}.pc @ONLY ) 151 | 152 | # install pkg-config file for external projects to discover this library 153 | install( FILES ${CMAKE_CURRENT_BINARY_DIR}/${PACKAGE_PKG_NAME}.pc 154 | DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/pkgconfig/ ) 155 | 156 | ####################################################### 157 | # Export library for easy inclusion from other cmake projects. APPEND allows 158 | # call to function even as subdirectory of larger project. 159 | FILE(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Targets.cmake") 160 | export( TARGETS ${LIBRARY_NAME} 161 | APPEND FILE "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Targets.cmake" ) 162 | 163 | # Version information. So find_package( XXX version ) will work. 164 | configure_file( ${CMAKE_SOURCE_DIR}/cmake_modules/PackageConfigVersion.cmake.in 165 | "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" @ONLY ) 166 | 167 | # Build tree config. So some folks can use the built package (e.g., any of our 168 | # own examples or applcations in this project. 169 | configure_file( ${CMAKE_SOURCE_DIR}/cmake_modules/PackageConfig.cmake.in 170 | ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake @ONLY ) 171 | install(FILES 172 | ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake 173 | ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Targets.cmake 174 | ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake 175 | DESTINATION 176 | lib/cmake/${PROJECT_NAME}) 177 | 178 | install( FILES ${CMAKE_CURRENT_BINARY_DIR}/Find${PACKAGE_PKG_NAME}.cmake 179 | DESTINATION ${CMAKE_INSTALL_PREFIX}/share/${PACKAGE_PKG_NAME}/ ) 180 | 181 | 182 | # # Install tree config. NB we DO NOT use this. We install using brew or 183 | # pkg-config. 184 | # set( EXPORT_LIB_INC_DIR ${LIB_INC_DIR} ) 185 | # set( EXPORT_LIB_INC_DIR "\${PROJECT_CMAKE_DIR}/${REL_INCLUDE_DIR}" ) 186 | # configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}Config.cmake.in 187 | # ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${PROJECT_NAME}Config.cmake @ONLY ) 188 | endif() 189 | 190 | # In case we want to export. 191 | elseif( EXPORT_${PROJECT_NAME} ) 192 | 193 | if( PACKAGE_LIB_NAME ) 194 | if(POLICY CMP0026) 195 | cmake_policy( SET CMP0026 OLD ) 196 | endif() 197 | get_target_property( _target_library ${PACKAGE_LIB_NAME} LOCATION ) 198 | list( APPEND PACKAGE_LINK_LIBS ${_target_library} ) 199 | endif() 200 | 201 | if( PACKAGE_INSTALL_HEADER_DIRS ) 202 | foreach(dir IN LISTS PACKAGE_INSTALL_HEADER_DIRS ) 203 | list( APPEND PACKAGE_INCLUDE_DIRS ${dir} ) 204 | endforeach() 205 | endif() 206 | 207 | #if( PACKAGE_INSTALL_HEADER_DIRS ) 208 | # foreach(dir IN LISTS PACKAGE_INSTALL_HEADER_DIRS ) 209 | # FILE( GLOB ${dir} "*.h" "*.hpp" ) 210 | # list( APPEND PACKAGE_INCLUDE_DIRS ${dir} ) 211 | # endforeach() 212 | #endif() 213 | 214 | list( APPEND PACKAGE_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/include 215 | ${CMAKE_CURRENT_BINARY_DIR}/include ) 216 | 217 | # install library itself 218 | #if( PACKAGE_LIB_NAME ) 219 | # set( PACKAGE_LIB_LINK "-l${PACKAGE_LIB_NAME}" ) 220 | #endif() 221 | ####################################################### 222 | # Export library for easy inclusion from other cmake projects. APPEND allows 223 | # call to function even as subdirectory of larger project. 224 | FILE(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Targets.cmake") 225 | export( TARGETS ${LIBRARY_NAME} 226 | APPEND FILE "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Targets.cmake" ) 227 | 228 | export( PACKAGE ${PROJECT_NAME} ) 229 | # install( EXPORT ${PROJECT_NAME}Targets DESTINATION ${CMAKECONFIG_INSTALL_DIR} ) 230 | # install(TARGETS ${LIBRARY_NAME} 231 | # EXPORT ${PROJECT_NAME}Targets DESTINATION ${CMAKE_INSTALL_PREFIX}/lib 232 | # ) 233 | 234 | # Version information. So find_package( XXX version ) will work. 235 | configure_file( ${CMAKE_SOURCE_DIR}/cmake_modules/PackageConfigVersion.cmake.in 236 | "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" @ONLY ) 237 | 238 | # Build tree config. So some folks can use the built package (e.g., any of our 239 | # own examples or applcations in this project. 240 | configure_file( ${CMAKE_SOURCE_DIR}/cmake_modules/PackageConfig.cmake.in 241 | ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake @ONLY ) 242 | 243 | # # Install tree config. NB we DO NOT use this. We install using brew or 244 | # pkg-config. 245 | # set( EXPORT_LIB_INC_DIR ${LIB_INC_DIR} ) 246 | # set( EXPORT_LIB_INC_DIR "\${PROJECT_CMAKE_DIR}/${REL_INCLUDE_DIR}" ) 247 | # configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}Config.cmake.in 248 | # ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${PROJECT_NAME}Config.cmake @ONLY ) 249 | #export( PACKAGE ${PROJECT_NAME} ) 250 | endif() 251 | 252 | 253 | # write and install a cmake "find package" for cmake projects to use. 254 | # NB: this .cmake file CANNOT refer to any source directory, only to 255 | # _installed_ files. 256 | configure_file( ${modules_dir}/FindPackage.cmake.in Find${PACKAGE_PKG_NAME}.cmake @ONLY ) 257 | 258 | endfunction() 259 | 260 | -------------------------------------------------------------------------------- /src/CVarParse.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Cross platform "CVars" functionality. 4 | 5 | This Code is covered under the LGPL. See COPYING file for the license. 6 | 7 | $Id: CVarParse.cpp 189 2011-07-26 14:29:48Z effer $ 8 | 9 | */ 10 | 11 | #include 12 | 13 | using namespace CVarUtils; 14 | 15 | #include 16 | 17 | //////////////////////////////////////////////////////////////////////////////// 18 | // remove all spaces from the front and back... 19 | std::string& _RemoveSpaces( std::string &str ) 20 | { 21 | str.erase( str.find_last_not_of( ' ' ) + 1 ); 22 | str.erase( 0, str.find_first_not_of( ' ' ) ); 23 | return str; 24 | } 25 | 26 | //////////////////////////////////////////////////////////////////////////////// 27 | namespace CVarUtils 28 | { 29 | //////////////////////////////////////////////////////////////////////////////// 30 | bool ProcessCommand( 31 | const std::string& sCommand, 32 | std::string& sResult, 33 | bool bExecute //< Input: 34 | ) 35 | { 36 | Trie& trie = TrieInstance(); 37 | 38 | TrieNode*node; 39 | bool bSuccess = true; 40 | std::string sCmd = sCommand; 41 | 42 | // remove leading and trailing spaces 43 | int pos = sCmd.find_first_not_of( " ", 0 ); 44 | if( pos >= 0 ) { 45 | sCmd = sCmd.substr( pos ); 46 | } 47 | pos = sCmd.find_last_not_of( " " ); 48 | if( pos >= 0 ) { 49 | sCmd= sCmd.substr( 0, pos+1 ); 50 | } 51 | 52 | // Simply print value if the command is just a variable 53 | if( ( node = trie.Find( sCmd ) ) ) { 54 | //execute function if this is a function cvar 55 | if( IsConsoleFunc( node ) ) { 56 | bSuccess &= ExecuteFunction( 57 | sCmd, 58 | (CVarUtils::CVar*)node->m_pNodeData, 59 | sResult, 60 | bExecute 61 | ); 62 | } 63 | else { //print value associated with this cvar 64 | sResult = GetValueAsString(node->m_pNodeData).c_str(); 65 | } 66 | } 67 | //see if it is an assignment or a function execution (with arguments) 68 | else{ 69 | int eq_pos; //get the position of the equal sign 70 | //see if this an assignment 71 | if( ( eq_pos = sCmd.find( "=" ) ) != -1 ) { 72 | std::string command, value; 73 | std::string tmp = sCmd.substr(0, eq_pos ) ; 74 | command = _RemoveSpaces( tmp ); 75 | value = sCmd.substr( eq_pos+1, sCmd.length() ); 76 | if( !value.empty() ) { 77 | value = _RemoveSpaces( value ); 78 | if( ( node = trie.Find(command) ) ) { 79 | if( bExecute ) { 80 | SetValueFromString( node->m_pNodeData, value ); 81 | } 82 | sResult = GetValueAsString(node->m_pNodeData).c_str(); 83 | } 84 | else { 85 | sResult = command + ": variable not found"; 86 | bSuccess = false; 87 | } 88 | } 89 | else { 90 | if( bExecute ) { 91 | sResult = command + ": command not found"; 92 | } 93 | bSuccess = false; 94 | } 95 | } 96 | //check if this is a function 97 | else if( ( eq_pos = sCmd.find(" ") ) != -1 ) { 98 | std::string function; 99 | std::string args; 100 | function = sCmd.substr( 0, eq_pos ); 101 | //check if this is a valid function name 102 | if( ( node = trie.Find( function ) ) && IsConsoleFunc( node ) ) { 103 | bSuccess &= ExecuteFunction( 104 | sCmd, 105 | ( CVar*)node->m_pNodeData, 106 | sResult, 107 | bExecute 108 | ); 109 | } 110 | else { 111 | if( bExecute ) { 112 | sResult = function + ": function not found"; 113 | } 114 | bSuccess = false; 115 | } 116 | } 117 | else if( !sCmd.empty() ) { 118 | if( bExecute ) { 119 | sResult = sCmd + ": command not found"; 120 | } 121 | bSuccess = false; 122 | } 123 | } 124 | if( sResult == "" && bSuccess == false ){ 125 | sResult = sCmd + ": command not found"; 126 | } 127 | return bSuccess; 128 | } 129 | 130 | 131 | //////////////////////////////////////////////////////////////////////////////// 132 | /// Parses the argument list and calls the function object associated with the 133 | // provided variable. 134 | bool ExecuteFunction( 135 | const std::string& sCommand, //< Input: 136 | CVarUtils::CVar *cvar, //< Input: 137 | std::string& , //< Output: 138 | bool bExecute //< Input: 139 | ) 140 | { 141 | std::vector argslist; 142 | std::string args; 143 | bool bSuccess = true; 144 | ConsoleFunc func = *(cvar->m_pVarData); 145 | std::string sCmd = sCommand; 146 | 147 | //extract arguments string 148 | int pos = sCmd.find( " " ); 149 | if( pos != -1 ) { 150 | args = sCmd.substr(pos+1, sCmd.length() - pos); 151 | } 152 | //parse arguments into a list of strings 153 | if( args.length() > 0 ) { 154 | while( ( pos = args.find(" ") ) != -1 ) { 155 | argslist.push_back(args.substr(0, pos)); 156 | args = args.substr(pos+1, args.length() - pos); 157 | } 158 | if( args.length() > 0 ) { 159 | argslist.push_back(args); 160 | } 161 | } 162 | 163 | if( bExecute ) { 164 | const bool res = (*func)( &argslist ); 165 | if( !res ) { 166 | bSuccess = false; 167 | } 168 | } 169 | 170 | return bSuccess; 171 | } 172 | 173 | 174 | //////////////////////////////////////////////////////////////////////////////// 175 | bool IsConsoleFunc( TrieNode *node ) 176 | { 177 | if( typeid( ConsoleFunc ).name() == ((CVar*)node->m_pNodeData)->type() ) { 178 | return true; 179 | } 180 | return false; 181 | } 182 | 183 | //////////////////////////////////////////////////////////////////////////////// 184 | bool IsConsoleFunc( const std::string sCmd ) { 185 | TrieNode* pNode = TrieInstance().Find( sCmd ); 186 | if( pNode == NULL ) { return false; } 187 | if( typeid( ConsoleFunc ).name() == ((CVar*)pNode->m_pNodeData)->type() ) { 188 | return true; 189 | } 190 | return false; 191 | } 192 | 193 | //////////////////////////////////////////////////////////////////////////////// 194 | /// Utility function. 195 | inline std::string FindLevel( std::string sString, int iMinRecurLevel ) { 196 | int level = 0; 197 | int index = sString.length(); 198 | for( unsigned int ii = 0; ii < sString.length(); ii++ ) { 199 | if( sString.c_str()[ii]=='.' ) { 200 | level ++; 201 | } 202 | if( level == iMinRecurLevel ) { 203 | index = ii+1; 204 | } 205 | } 206 | return sString.substr( 0, index ); 207 | } 208 | 209 | //////////////////////////////////////////////////////////////////////////////// 210 | inline int _FindRecursionLevel( const std::string& sCommand ) { 211 | int nLevel = 0; 212 | for( unsigned int ii = 0; ii < sCommand.length(); ii++ ) { 213 | if( sCommand.c_str()[ii] == '.' ) { 214 | nLevel++; 215 | } 216 | } 217 | return nLevel; 218 | } 219 | 220 | //////////////////////////////////////////////////////////////////////////////// 221 | /// Return whether first element is greater than the second. 222 | inline bool _StringIndexPairGreater 223 | ( const std::pair& e1, const std::pair& e2 ) { 224 | return e1.first < e2.first; 225 | } 226 | 227 | //////////////////////////////////////////////////////////////////////////////// 228 | bool TabComplete( const unsigned int nMaxNumCharactersPerLine, 229 | std::string& sCommand, 230 | std::vector& vResult 231 | ) { 232 | Trie& trie = TrieInstance(); 233 | 234 | sCommand = _RemoveSpaces( sCommand ); 235 | TrieNode* node = trie.FindSubStr( sCommand ); 236 | if( node == NULL ) { 237 | std::string sCommandStripEq = sCommand.substr( 0, sCommand.rfind( "=" ) ); 238 | sCommandStripEq = _RemoveSpaces( sCommandStripEq ); 239 | node = trie.FindSubStr( sCommandStripEq ); 240 | if( node != NULL ) { sCommand = sCommandStripEq; } 241 | } 242 | if( node == NULL ) { 243 | return false; 244 | } 245 | else if( node->m_nNodeType == TRIE_LEAF || 246 | ( node->m_children.size() == 0 ) ) { 247 | node = trie.Find( sCommand ); 248 | if( !IsConsoleFunc( node ) ) { 249 | sCommand += " = " + CVarUtils::GetValueAsString( node->m_pNodeData ); 250 | vResult.push_back( sCommand ); 251 | } 252 | } 253 | else { 254 | // Retrieve suggestions (retrieve all leaves by traversing from current node) 255 | std::vector suggest = trie.CollectAllNodes( node ); 256 | //output suggestions 257 | if( suggest.size() == 1 ) { 258 | // Is this what the use wants? Clear the left bit... 259 | sCommand = 260 | ((CVarUtils::CVar*) suggest[0]->m_pNodeData)->m_sVarName; 261 | } 262 | else if( suggest.size() > 1) { 263 | std::vector > suggest_name_index_full; 264 | std::vector > suggest_name_index_set; 265 | // Build list of names with index from suggest 266 | // Find lowest recursion level 267 | int nMinRecurLevel = 100000; 268 | for( unsigned int ii = 0; ii < suggest.size(); ii++ ) { 269 | std::string sName = ( (CVarUtils::CVar*) suggest[ii]->m_pNodeData )->m_sVarName; 270 | suggest_name_index_full.push_back( std::pair( sName, ii ) ); 271 | if( _FindRecursionLevel( sName ) < nMinRecurLevel ) { 272 | nMinRecurLevel = _FindRecursionLevel( sName ); 273 | } 274 | } 275 | // We need to know if there are many different roots for a given recursion 276 | std::set sRoots; 277 | for( unsigned int ii = 0; ii < suggest_name_index_full.size() ; ii++ ) { 278 | std::string sCurString = suggest_name_index_full[ii].first; 279 | if( _FindRecursionLevel( sCurString ) == nMinRecurLevel ) { 280 | std::string sCurLevel = FindLevel( suggest_name_index_full[ii].first, nMinRecurLevel-1 ); 281 | sRoots.insert( sCurLevel ); 282 | } 283 | } 284 | if( sRoots.size() > 1 ) { 285 | nMinRecurLevel--; 286 | } 287 | 288 | // Sort alphabetically (this is useful for later removing 289 | // duplicate name at a given level and looks nice too...) 290 | std::sort( suggest_name_index_full.begin(), suggest_name_index_full.end(), 291 | _StringIndexPairGreater ); 292 | 293 | // Remove suggestions at a higher level of recursion 294 | std::string sCurLevel = ""; 295 | int nCurLevel; 296 | for( unsigned int ii = 0; ii < suggest_name_index_full.size() ; ii++ ) { 297 | std::string sCurString = suggest_name_index_full[ii].first; 298 | nCurLevel = _FindRecursionLevel( sCurString ); 299 | if( sCurLevel.length() == 0 ) { 300 | if( nCurLevel == nMinRecurLevel ) { 301 | sCurLevel = ""; 302 | suggest_name_index_set. 303 | push_back( std::pair( sCurString,suggest_name_index_full[ii].second ) ); 304 | } 305 | else { 306 | // Add new substring at given level 307 | sCurLevel = FindLevel( sCurString, nMinRecurLevel ); 308 | suggest_name_index_set.push_back( std::pair( sCurLevel,suggest_name_index_full[ii].second ) ); 309 | } 310 | } 311 | else { 312 | if( sCurString.find( sCurLevel ) == std::string::npos ) { 313 | // Add new substring at given level 314 | sCurLevel = FindLevel( sCurString, nMinRecurLevel ); 315 | suggest_name_index_set.push_back( std::pair( sCurLevel,suggest_name_index_full[ii].second ) ); 316 | } 317 | } 318 | } 319 | 320 | // Get all commands and function separately 321 | // Print out all suggestions to the console 322 | std::string commands, functions; //collect each type separately 323 | 324 | unsigned int longest = 0; 325 | for( unsigned int ii = 0; ii < suggest_name_index_set.size(); ii++ ) { 326 | if( suggest_name_index_set[ii].first.length() > longest ) { 327 | longest = suggest_name_index_set[ii].first.length(); 328 | } 329 | } 330 | longest +=3; 331 | 332 | std::vector cmdlines; 333 | std::vector funclines; 334 | 335 | // add command lines 336 | for( unsigned int ii = 0; ii < suggest_name_index_set.size() ; ii++ ) { 337 | std::string tmp = suggest_name_index_set[ii].first; 338 | tmp.resize( longest, ' ' ); 339 | 340 | if( (commands+tmp).length() > nMaxNumCharactersPerLine ) { 341 | cmdlines.push_back( commands ); 342 | commands.clear(); 343 | } 344 | if( !IsConsoleFunc( suggest[suggest_name_index_set[ii].second] ) ) { 345 | commands += tmp; 346 | } 347 | } 348 | if( commands.length() ) cmdlines.push_back( commands ); 349 | 350 | // add function lines 351 | for( unsigned int ii = 0; ii < suggest_name_index_set.size() ; ii++ ) { 352 | std::string tmp = suggest_name_index_set[ii].first; 353 | tmp.resize( longest, ' ' ); 354 | if( (functions+tmp).length() > nMaxNumCharactersPerLine ) { 355 | funclines.push_back( functions ); 356 | functions.clear(); 357 | } 358 | if( IsConsoleFunc( suggest[suggest_name_index_set[ii].second] ) ) { 359 | functions += tmp; 360 | } 361 | } 362 | if( functions.length() ) funclines.push_back( functions ); 363 | 364 | // enter the results 365 | if( cmdlines.size() + funclines.size() > 0 ) { 366 | //EnterLogLine( " ", LINEPROP_LOG ); 367 | vResult.push_back( " " ); 368 | } 369 | for( unsigned int ii = 0; ii < cmdlines.size(); ii++ ) { 370 | //EnterLogLine( cmdlines[ii].c_str(), LINEPROP_LOG ); 371 | vResult.push_back( cmdlines[ii] ); 372 | } 373 | for( unsigned int ii = 0; ii < funclines.size(); ii++ ) { 374 | //EnterLogLine( funclines[ii].c_str(), LINEPROP_FUNCTION ); 375 | vResult.push_back( funclines[ii] ); 376 | } 377 | 378 | // Do partial completion - look for paths with one child down the trie 379 | int c = sCommand.length(); 380 | while( node->m_children.size() == 1 ) { 381 | node = node->m_children.front(); 382 | c++; 383 | } 384 | sCommand = suggest_name_index_set[0].first.substr( 0, c ); 385 | } 386 | } 387 | return true; 388 | } 389 | } 390 | 391 | -------------------------------------------------------------------------------- /src/Trie.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Cross platform "CVars" functionality. 4 | 5 | This Code is covered under the LGPL. See COPYING file for the license. 6 | 7 | $Id: Trie.cpp 162 2010-02-15 19:11:05Z gsibley $ 8 | 9 | */ 10 | 11 | // Trie data structure implementation. 12 | 13 | #include "cvars/CVar.h" 14 | #include "cvars/Trie.h" 15 | #include "cvars/TrieNode.h" 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | using namespace std; 23 | 24 | //////////////////////////////////////////////////////////////////////////////// 25 | Trie::Trie() : root( NULL ), m_bVerbose( false ), m_StreamType( CVARS_XML_STREAM ) 26 | { 27 | } 28 | 29 | //////////////////////////////////////////////////////////////////////////////// 30 | void Trie::Init() 31 | { 32 | if(!root) 33 | { 34 | root = new TrieNode( TRIE_ROOT ); 35 | 36 | std::string sVarName; 37 | 38 | ////// 39 | sVarName = "console.VerbosePaddingWidth"; 40 | CVarUtils::CVar *pCVar1 = new CVarUtils::CVar( sVarName, 30 ); 41 | m_pVerboseCVarNamePaddingWidth = pCVar1->m_pVarData; 42 | Insert( sVarName, (void *) pCVar1 ); 43 | ////// 44 | sVarName = "console.CVarIndent"; 45 | CVarUtils::CVar *pCVar2 = new CVarUtils::CVar( sVarName, 0 ); 46 | m_pVerboseCVarNamePaddingWidth = pCVar2->m_pVarData; 47 | Insert( sVarName, (void *) pCVar2 ); 48 | ////// 49 | sVarName = "console.CVarIndentIncr"; 50 | CVarUtils::CVar *pCVar3 = new CVarUtils::CVar( sVarName, 4 ); 51 | m_pVerboseCVarNamePaddingWidth = pCVar3->m_pVarData; 52 | Insert( sVarName, (void *) pCVar3 ); 53 | ////// 54 | } 55 | } 56 | 57 | //////////////////////////////////////////////////////////////////////////////// 58 | Trie::~Trie() 59 | { 60 | delete root; 61 | } 62 | 63 | //////////////////////////////////////////////////////////////////////////////// 64 | void Trie::Insert( std::string s, void *dataPtr ) 65 | { 66 | if( root == NULL ) { 67 | printf( "ERROR in Trie::Insert, root == NULL!!!!!\n" ); 68 | return; 69 | } 70 | 71 | m_vCVarNames.push_back( s ); 72 | 73 | TrieNode *traverseNode = root; 74 | for( unsigned int i = 0 ; i < s.length() ; i++ ) { 75 | traverseNode = traverseNode->TraverseInsert( s[i] ); 76 | } 77 | 78 | //add leaf node 79 | TrieNode* newNode = new TrieNode( s ); 80 | newNode->m_pNodeData = dataPtr; 81 | traverseNode->m_children.push_back(newNode); //create leaf node at end of chain 82 | } 83 | 84 | //////////////////////////////////////////////////////////////////////////////// 85 | TrieNode* Trie::Find( const std::string& s ) 86 | { 87 | TrieNode* node = FindSubStr( s ); 88 | if( node != NULL 89 | && node->m_nNodeType == TRIE_LEAF ) { 90 | return node; 91 | } 92 | return NULL; 93 | } 94 | 95 | //////////////////////////////////////////////////////////////////////////////// 96 | void* Trie::FindData( const std::string& s ) 97 | { 98 | return Find( s )->m_pNodeData; 99 | } 100 | 101 | //////////////////////////////////////////////////////////////////////////////// 102 | bool Trie::Exists( const std::string& s ) 103 | { 104 | return Find( s ) != NULL; 105 | } 106 | 107 | //////////////////////////////////////////////////////////////////////////////// 108 | TrieNode* Trie::GetRoot() { 109 | return root; 110 | } 111 | 112 | //////////////////////////////////////////////////////////////////////////////// 113 | // Finds all the CVarNames that contain s as a substring. 114 | std::vector Trie::FindListSubStr( const std::string& s ) 115 | { 116 | std::vector vCVars; 117 | for( size_t i=0; iTraverseFind( s[i] ); 142 | if( traverseNode ) { 143 | continue; 144 | } else { 145 | return NULL; 146 | } 147 | } 148 | 149 | // Look for a leaf node here and return it if no leaf node just return this 150 | // node. 151 | std::list::iterator it; 152 | for(it = traverseNode->m_children.begin() ; it != traverseNode->m_children.end() ; it++){ 153 | //found child 154 | if((*it)->m_nNodeType == TRIE_LEAF) { 155 | return (*it); 156 | } 157 | } 158 | 159 | return traverseNode; 160 | } 161 | 162 | //////////////////////////////////////////////////////////////////////////////// 163 | // Chris, please comment this guy for me. GTS 164 | void Trie::SetAcceptedSubstrings( std::vector< std::string > vFilterSubstrings ) 165 | { 166 | m_vAcceptedSubstrings.clear(); 167 | m_vNotAcceptedSubstrings.clear(); 168 | 169 | // Check if verbose should be set 170 | if( vFilterSubstrings.size() > 0 ) { 171 | if( vFilterSubstrings[ vFilterSubstrings.size()-1 ] == "true" ) { 172 | m_bVerbose = true; 173 | vFilterSubstrings.pop_back(); 174 | } 175 | else if( vFilterSubstrings[ vFilterSubstrings.size()-1 ] == "false" ) { 176 | m_bVerbose = false; 177 | vFilterSubstrings.pop_back(); 178 | } 179 | } 180 | 181 | // Split the list between acceptable and not acceptable substrings. 182 | int nAccIndex = 0; 183 | for( nAccIndex=0; nAccIndex Trie::CollectAllNames( TrieNode* node ) 240 | { 241 | std::vector res; 242 | node->PrintToVector( res ); 243 | 244 | return res; 245 | } 246 | 247 | //////////////////////////////////////////////////////////////////////////////// 248 | // Does an in order traversal starting at node and printing all leaves to a list 249 | std::vector Trie::CollectAllNodes( TrieNode* node ) 250 | { 251 | std::vector res; 252 | node->PrintNodeToVector( res ); 253 | return res; 254 | } 255 | 256 | //////////////////////////////////////////////////////////////////////////////// 257 | static std::ostream &TrieToTXT( std::ostream &stream, Trie &rTrie ) 258 | { 259 | std::vector vNodes = rTrie.CollectAllNodes( rTrie.GetRoot() ); 260 | for( size_t ii = 0; ii < vNodes.size(); ii++ ){ 261 | std::string sVal = ((CVarUtils::CVar*)vNodes[ii]->m_pNodeData)->GetValueAsString(); 262 | 263 | if( !sVal.empty() ) { 264 | std::string sCVarName = ((CVarUtils::CVar*)vNodes[ii]->m_pNodeData)->m_sVarName; 265 | if( !rTrie.IsNameAcceptable( sCVarName ) ) { 266 | if( rTrie.IsVerbose() ) { 267 | printf( "NOT saving %s (not in acceptable name list).\n", sCVarName.c_str() ); 268 | } 269 | continue; 270 | } 271 | if( !((CVarUtils::CVar*)vNodes[ii]->m_pNodeData)->m_bSerialise ) { 272 | if( rTrie.IsVerbose() ) { 273 | printf( "NOT saving %s (set as not savable at construction time).\n", sCVarName.c_str() ); 274 | } 275 | continue; 276 | } 277 | if( rTrie.IsVerbose() ) { 278 | printf( "Saving \"%-*s\" with value \"%s\".\n", *rTrie.m_pVerboseCVarNamePaddingWidth, 279 | sCVarName.c_str(), sVal.c_str() ); 280 | } 281 | stream << sCVarName << " = " << sVal << std::endl; 282 | } 283 | } 284 | return stream; 285 | } 286 | 287 | //////////////////////////////////////////////////////////////////////////////// 288 | static std::ostream &TrieToXML( std::ostream &stream, Trie &rTrie ) 289 | { 290 | std::vector vNodes = rTrie.CollectAllNodes( rTrie.GetRoot() ); 291 | stream << CVarUtils::CVarSpc() << "" << std::endl; 292 | for( size_t ii = 0; ii < vNodes.size(); ii++ ){ 293 | std::string sVal = ((CVarUtils::CVar*)vNodes[ii]->m_pNodeData)->GetValueAsString(); 294 | 295 | if( !sVal.empty() ) { 296 | std::string sCVarName = ((CVarUtils::CVar*)vNodes[ii]->m_pNodeData)->m_sVarName; 297 | if( !rTrie.IsNameAcceptable( sCVarName ) ) { 298 | if( rTrie.IsVerbose() ) { 299 | printf( "NOT saving %s (not in acceptable name list).\n", sCVarName.c_str() ); 300 | } 301 | continue; 302 | } 303 | if( !((CVarUtils::CVar*)vNodes[ii]->m_pNodeData)->m_bSerialise ) { 304 | if( rTrie.IsVerbose() ) { 305 | printf( "NOT saving %s (set as not savable at construction time).\n", sCVarName.c_str() ); 306 | } 307 | continue; 308 | } 309 | if( rTrie.IsVerbose() ) { 310 | printf( "Saving \"%-*s\" with value \"%s\".\n", *rTrie.m_pVerboseCVarNamePaddingWidth, 311 | sCVarName.c_str(), sVal.c_str() ); 312 | } 313 | CVarUtils::CVarIndent(); 314 | stream << CVarUtils::CVarSpc() << "<" << sCVarName << "> "; 315 | CVarUtils::CVarIndent(); 316 | stream << sVal; 317 | CVarUtils::CVarUnIndent(); 318 | stream << CVarUtils::CVarSpc() << "" << std::endl; 319 | CVarUtils::CVarUnIndent(); 320 | } 321 | } 322 | stream << CVarUtils::CVarSpc() << "" << std::endl; 323 | 324 | return stream; 325 | } 326 | 327 | //////////////////////////////////////////////////////////////////////////////// 328 | std::ostream &operator<<( std::ostream &stream, Trie &rTrie ) 329 | { 330 | switch( rTrie.GetStreamType() ) { 331 | case CVARS_XML_STREAM: 332 | return TrieToXML( stream, rTrie ); 333 | break; 334 | case CVARS_TXT_STREAM: 335 | return TrieToTXT( stream, rTrie ); 336 | break; 337 | default: 338 | std::cerr << "ERROR: unknown stream type" << std::endl; 339 | } 340 | return stream; 341 | } 342 | 343 | //////////////////////////////////////////////////////////////////////////////// 344 | static std::istream &XMLToTrie( std::istream &stream, Trie &rTrie ) 345 | { 346 | tinyxml2::XMLDocument doc; 347 | std::string s; 348 | stream >> s; 349 | doc.Parse(s.c_str()); 350 | 351 | tinyxml2::XMLNode* pCVarsNode = doc.RootElement(); 352 | 353 | if( pCVarsNode == NULL ) { 354 | cerr << "ERROR: Could not find node." << endl; 355 | return stream; 356 | } 357 | 358 | for( tinyxml2::XMLNode* pNode = pCVarsNode->FirstChild(); 359 | pNode != NULL; 360 | pNode = pNode->NextSibling() ) { 361 | std::string sCVarName( pNode->Value() ); 362 | 363 | if( !rTrie.Exists( sCVarName ) ) { 364 | if( rTrie.IsVerbose() ) { 365 | printf( "NOT loading %s (not in Trie).\n", sCVarName.c_str() ); 366 | } 367 | continue; 368 | } 369 | 370 | if( !rTrie.IsNameAcceptable( sCVarName ) ) { 371 | if( rTrie.IsVerbose() ) { 372 | printf( "NOT loading %s (not in acceptable name list).\n", sCVarName.c_str() ); 373 | } 374 | continue; 375 | } 376 | 377 | CVarUtils::CVar* pCVar = (CVarUtils::CVar*)rTrie.Find( sCVarName )->m_pNodeData; 378 | tinyxml2::XMLNode* pChild = pNode->FirstChild(); 379 | 380 | if( pCVar != NULL && pChild != NULL ) { 381 | std::string sCVarValue(pChild->ToText()->Value()); 382 | pCVar->SetValueFromString( sCVarValue ); 383 | 384 | if( rTrie.IsVerbose() ) { 385 | printf( "Loading \"%-*s\" with value \"%s... \".\n", *rTrie.m_pVerboseCVarNamePaddingWidth, 386 | sCVarName.c_str(), sCVarValue.substr(0,40).c_str() ); 387 | } 388 | } 389 | else { 390 | cerr << "WARNING: found a cvar in file with no value (name: " << sCVarName << ").\n" << endl; 391 | } 392 | } 393 | return stream; 394 | } 395 | 396 | //////////////////////////////////////////////////////////////////////////////// 397 | static std::string remove_spaces( std::string str ) 398 | { 399 | str.erase( str.find_last_not_of( ' ' ) + 1 ); 400 | str.erase( 0, str.find_first_not_of( ' ' ) ); 401 | return str; 402 | } 403 | 404 | //////////////////////////////////////////////////////////////////////////////// 405 | static bool get_not_comment_line( std::istream& iStream, std::string& sLineNoComment ) 406 | { 407 | std::string sLine; 408 | if( !iStream.good() ) { return false; } 409 | while( !iStream.eof() ) { 410 | getline( iStream, sLine ); 411 | sLine.erase( 0, sLine.find_first_not_of( ' ' ) ); 412 | if( sLine.empty() ) { 413 | continue; 414 | } 415 | else if( sLine[0] != '#' && sLine[0] != '/' ) { 416 | sLineNoComment = sLine; 417 | return true; 418 | } 419 | } 420 | return false; 421 | } 422 | 423 | //////////////////////////////////////////////////////////////////////////////// 424 | static bool get_name_val( const std::string& sLine, 425 | std::string& sName, 426 | std::string& sVal ) 427 | { 428 | size_t sEq = sLine.find( "=" ); 429 | if( sEq == std::string::npos || sEq == sLine.length()-1 ) { return false; } 430 | sVal = sLine; 431 | sVal.erase( 0, sEq+1 ); 432 | sVal = remove_spaces( sVal ); 433 | sName = sLine; 434 | sName.erase( sEq ); 435 | sName = remove_spaces( sName ); 436 | return true; 437 | } 438 | 439 | //////////////////////////////////////////////////////////////////////////////// 440 | static std::istream &TXTToTrie( std::istream &stream, Trie &rTrie ) 441 | { 442 | std::string sLine, sCVarName, sCVarValue; 443 | while( get_not_comment_line( stream, sLine ) ) 444 | { 445 | if( get_name_val( sLine, sCVarName, sCVarValue ) ) 446 | { 447 | if( !rTrie.Exists( sCVarName ) ) { 448 | if( rTrie.IsVerbose() ) { 449 | printf( "NOT loading %s (not in Trie).\n", sCVarName.c_str() ); 450 | } 451 | continue; 452 | } 453 | if( !rTrie.IsNameAcceptable( sCVarName ) ) { 454 | if( rTrie.IsVerbose() ) { 455 | printf( "NOT loading %s (not in acceptable name list).\n", sCVarName.c_str() ); 456 | } 457 | continue; 458 | } 459 | 460 | CVarUtils::CVar* pCVar = (CVarUtils::CVar*)rTrie.Find( sCVarName )->m_pNodeData; 461 | 462 | if( pCVar != NULL ) { 463 | pCVar->SetValueFromString( sCVarValue ); 464 | if( rTrie.IsVerbose() ) { 465 | printf( "Loading \"%-*s\" with value \"%s... \".\n", *rTrie.m_pVerboseCVarNamePaddingWidth, 466 | sCVarName.c_str(), sCVarValue.substr(0,40).c_str() ); 467 | } 468 | } 469 | else { 470 | cerr << "WARNING: found a cvar in file with no value (name: " << sCVarName << ").\n" << endl; 471 | } 472 | } 473 | } 474 | return stream; 475 | } 476 | 477 | //////////////////////////////////////////////////////////////////////////////// 478 | std::istream &operator>>( std::istream &stream, Trie &rTrie ) 479 | { 480 | switch( rTrie.GetStreamType() ) { 481 | case CVARS_XML_STREAM: 482 | return XMLToTrie( stream, rTrie ); 483 | break; 484 | case CVARS_TXT_STREAM: 485 | return TXTToTrie( stream, rTrie ); 486 | break; 487 | default: 488 | std::cerr << "ERROR: unknown stream type" << std::endl; 489 | } 490 | return stream; 491 | } 492 | -------------------------------------------------------------------------------- /include/cvars/CVar.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Cross platform "CVars" functionality. 4 | 5 | This Code is covered under the LGPL. See COPYING file for the license. 6 | 7 | $Id: CVar.h 201 2012-10-17 18:43:27Z effer $ 8 | 9 | */ 10 | 11 | 12 | //////////////////////////////////////////////////////////////////////////////// 13 | // Facilities to get and set a variable of any type from the command line uses 14 | // a Trie to store strings for easy lookup have specialized cast and assignment 15 | // operators to fascilitate little code change They can also be Serialized and 16 | // Restored on app startup and shutdown 17 | // Example: 18 | // "int height = 2;" 19 | // would be written as 20 | // "int& height = CVarUtils::CreateCVar( "height", 2);" 21 | // Saving can be done in the Console with: 22 | // save cvars.xml 23 | // or for verbose: 24 | // save cvars.xml true 25 | // or to save just the values starting by "cons" with verbose: 26 | // save cvars.xml cons true 27 | 28 | #ifndef CVAR_H__ 29 | #define CVAR_H__ 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | 40 | #include 41 | #include 42 | #include 43 | 44 | // Console functions must have the following signature 45 | typedef bool (*ConsoleFunc)( std::vector *args); 46 | 47 | namespace CVarUtils 48 | { 49 | //////////////////////////////////////////////////////////////////////////////// 50 | // A global Trie structure holds all of the variables organized by their string 51 | // name. He lives in Trie.cpp. 52 | Trie& TrieInstance(); 53 | 54 | //////////////////////////////////////////////////////////////////////////////// 55 | template 56 | class CVarRef 57 | { 58 | public: 59 | CVarRef(T* reference=0) : var(reference) {} 60 | ~CVarRef() {} 61 | T* var; 62 | }; 63 | 64 | // overload the stream operators (so operator << and >> are used on type T when using a CVarRef) 65 | template std::ostream& operator<<(std::ostream &out, const CVarRef &v) { out << *v.var; return out; } 66 | template std::istream& operator>>(std::istream &in, CVarRef &v) { in >> *v.var; return in; } 67 | 68 | inline std::ostream &operator<<(std::ostream &stream, ConsoleFunc &) 69 | { 70 | return stream; 71 | } 72 | 73 | inline std::istream &operator>>(std::istream &stream, ConsoleFunc &) 74 | { 75 | return stream; 76 | } 77 | 78 | //////////////////////////////////////////////////////////////////////////////// 79 | /// Color class: useful in practice for most consoles 80 | struct Color { 81 | Color( float tr = 1.0f, 82 | float tg = 1.0f, 83 | float tb = 1.0f, 84 | float ta = 1.0f ) { 85 | r = tr; g = tg; b = tb; a = ta; 86 | } 87 | Color( int tr, 88 | int tg, 89 | int tb, 90 | int ta = 255 91 | ) { 92 | r = tr/255.0f; g = tg/255.0f; b = tb/255.0f; a = ta/255.0f; 93 | } 94 | //float fColor[0]; 95 | struct { float r; float g; float b; float a; }; 96 | }; 97 | 98 | //////////////////////////////////////////////////////////////////////////////// 99 | /// All types you wish to use with CVars must overload << and >>. 100 | inline std::ostream &operator<<( std::ostream &stream, Color &color ) { 101 | int r = int( 255*color.r ); 102 | int g = int( 255*color.g ); 103 | int b = int( 255*color.b ); 104 | int a = int( 255*color.a ); 105 | stream << "[ " << r << ", " << g << ", " << b << ", " << a << " ]"; 106 | return stream; 107 | } 108 | 109 | //////////////////////////////////////////////////////////////////////////////// 110 | /// All types you wish to use with CVars must overload << and >>. 111 | inline std::istream &operator>>( std::istream &stream, Color &color ) { 112 | int r=0, g=0, b=0, a=0; 113 | const int CVAR_NAME_MAX = 1024; char str[CVAR_NAME_MAX] = {0}; 114 | stream.readsome( str, CVAR_NAME_MAX ); 115 | sscanf( str, "[ %d, %d, %d, %d ]", &r, &g, &b, &a ); 116 | color.r = (float)r/255.0f; 117 | color.g = (float)g/255.0f; 118 | color.b = (float)b/255.0f; 119 | color.a = (float)a/255.0f; 120 | return stream; 121 | } 122 | 123 | 124 | //////////////////////////////////////////////////////////////////////////////// 125 | // This is our generic data-to-string function, there is one instantiated for 126 | // every kind of CVar type that gets declared. To print, the CVar type merely 127 | // has to overload <<. To support reading from the console, just overload >>. 128 | template 129 | std::string CVarValueString( T *t ) 130 | { 131 | std::ostringstream oss; 132 | oss << *t; 133 | return oss.str(); 134 | } 135 | 136 | //////////////////////////////////////////////////////////////////////////////// 137 | // Each time a CVar is constructed we register it's type so we can recover the 138 | // original type after being cast about (esp. within the Trie data structure). 139 | template 140 | std::string CVarTypeString( T *t ) 141 | { 142 | std::ostringstream oss; 143 | oss << typeid( *t ).name(); 144 | return oss.str(); 145 | } 146 | 147 | //////////////////////////////////////////////////////////////////////////////// 148 | // Each time a CVar is constructed we register it's type so we can recover the 149 | // original type after being cast about (esp. within the Trie data structure). 150 | template 151 | void StringToCVarValue( T *t, const std::string &sValue ) 152 | { 153 | std::istringstream iss( sValue ); 154 | iss >> *t; 155 | } 156 | 157 | //////////////////////////////////////////////////////////////////////////////// 158 | /** These functions must be called to create a CVar, they return a reference to 159 | * the value saved. 160 | * A default parameter makes it possible to avoid this variable 161 | * from being saved. 162 | * eg. int& nGUIWidth = CVarUtils::CreateCVar( "gui.Width", 10 ); 163 | */ 164 | template T& CreateCVar( 165 | const std::string& s, 166 | T val, 167 | std::string sHelp = "No help available", 168 | std::ostream& (*pSerialisationFuncPtr)( std::ostream &, T ) = NULL, 169 | std::istream& (*pDeserialisationFuncPtr)( std::istream &, T ) = NULL 170 | ); 171 | 172 | template T& CreateGetCVar( 173 | const std::string& s, 174 | T val, 175 | std::string sHelp = "No help available", 176 | std::ostream& (*pSerialisationFuncPtr)( std::ostream &, T ) = NULL, 177 | std::istream& (*pDeserialisationFuncPtr)( std::istream &, T ) = NULL 178 | ); 179 | 180 | template T& CreateUnsavedCVar( 181 | const std::string& s, 182 | T val, 183 | const std::string& sHelp = "No help available", 184 | std::ostream& (*pSerialisationFuncPtr)( std::ostream &, T ) = NULL, 185 | std::istream& (*pDeserialisationFuncPtr)( std::istream &, T ) = NULL 186 | ); 187 | 188 | template T& CreateGetUnsavedCVar( 189 | const std::string& s, 190 | T val, 191 | const std::string& sHelp = "No help available", 192 | std::ostream& (*pSerialisationFuncPtr)( std::ostream &, T ) = NULL, 193 | std::istream& (*pDeserialisationFuncPtr)( std::istream &, T ) = NULL 194 | ); 195 | 196 | //////////////////////////////////////////////////////////////////////////////// 197 | /** These functions must be called to attach a CVar to a variable. 198 | * Use these functions if you do not want to use references to CVars (as 199 | * created with \c CreateCVar() ). 200 | * \code 201 | * int nGUIWidth = 100; // declare a variable as you usually do 202 | * AttachCVar( "gui.Wdith", &nGuiWidth ); // attach the variable 203 | * 204 | * nGUIWidth = 200; // change the variable as you usually do 205 | * \endcode 206 | */ 207 | template 208 | void AttachCVar(const std::string& s, 209 | T* ref, 210 | const std::string& sHelp = "No help available"); 211 | 212 | //////////////////////////////////////////////////////////////////////////////// 213 | /** These functions can be called to obtain a reference to a previously 214 | * created CVar. 215 | * 216 | * The exception "CVarUtils::CVarNonExistant" will be thrown if the value 217 | * does not exist. 218 | * eg. int& nGUIWidth = CVarUtils::GetCVarRef( "gui.Width" ); 219 | */ 220 | template T& GetCVarRef( const char* s ); 221 | template T& GetCVarRef( std::string s ); 222 | 223 | //////////////////////////////////////////////////////////////////////////////// 224 | /** These functions can be called to obtain the value of a previously 225 | * created CVar. 226 | * 227 | * The exception "CVarUtils::CVarNonExistant" will be thrown if the value 228 | * does not exist. 229 | * eg. int nGUIWidth = CVarUtils::GetCVar( "gui.Width" ); 230 | */ 231 | template T GetCVar( const char* s ); 232 | template T GetCVar( std::string s ); 233 | 234 | //////////////////////////////////////////////////////////////////////////////// 235 | /** This function can be called to determine if a particular CVar exists. 236 | */ 237 | bool CVarExists( std::string s ); 238 | 239 | //////////////////////////////////////////////////////////////////////////////// 240 | /** These functions can be called to change the value of a previously 241 | * created CVar. 242 | * 243 | * The exception "CVarUtils::CVarNonExistant" will be thrown if 244 | * the value does not exist. 245 | * eg. CVarUtils::SetCVar( "gui.Width", 20 ); 246 | */ 247 | template void SetCVar( const char* s, T val ); 248 | template void SetCVar( std::string s, T val ); 249 | 250 | //////////////////////////////////////////////////////////////////////////////// 251 | /** These functions can be called to obtain the help value associated with a 252 | * previously created CVar. 253 | * 254 | * The exception "CVarUtils::CVarNonExistant" will be thrown if 255 | * the value does not exist. 256 | * eg. printf( "GUI help: %s\n", CVarUtils::GetHelp( "gui.Width" ) ); 257 | */ 258 | const std::string& GetHelp( const char* s ); 259 | const std::string& GetHelp( std::string s ); 260 | 261 | //////////////////////////////////////////////////////////////////////////////// 262 | /** This function prints all the CVars out, along with their default values and 263 | * help message -- useful for creating documentation. 264 | */ 265 | // void PrintAllCVars(); 266 | 267 | //////////////////////////////////////////////////////////////////////////////// 268 | /// Changes the input/output types when calling Save and Load, options: 269 | /// - CVARS_XML_STREAM is the default 270 | /// - TXT_XML_STREAM is another option where the format is 'cvar_name = cvar_value' per line 271 | /// with commented lines starting by '#' or '//' 272 | inline void SetStreamType( const CVARS_STREAM_TYPE& stream_type ); 273 | 274 | //////////////////////////////////////////////////////////////////////////////// 275 | /** This function saves the CVars to "sFileName", it takes an optional 276 | * argument that is a vector of substrings indicating the CVars that should 277 | * or should not be saved. 278 | * 279 | * If this vector is empty, all the CVars are saved. 280 | * If "not" is add to the list, all the following substrings will not be saved. 281 | * If "true" is used as the last argument, the saving will be verbose. 282 | */ 283 | inline bool Save( const std::string& sFileName, 284 | std::vector vFilterSubstrings=std::vector() ); 285 | 286 | //////////////////////////////////////////////////////////////////////////////// 287 | /** This function loads the CVars from "sFileName", it takes an optional 288 | * argument that is a vector of substrings indicating the CVars that should 289 | * or should not be loaded. 290 | * 291 | * If this vector is empty, all the CVars are loaded. 292 | * If "not" is add to the list, all the following substrings will not be loaded. 293 | * If "true" is used as the last argument, the loading will be verbose. 294 | */ 295 | inline bool Load( const std::string& sFileName, 296 | std::vector vFilterSubstrings=std::vector() ); 297 | 298 | /** Utilities for the indentation of XML output */ 299 | inline std::string CVarSpc(); 300 | inline void CVarIndent(); 301 | inline void CVarUnIndent(); 302 | inline void CVarResetSpc(); 303 | } 304 | 305 | 306 | //////////////////////////////////////////////////////////////////////////////// 307 | namespace CVarUtils { 308 | enum CVarException { 309 | CVarsNotInitialized, 310 | CVarNonExistant, 311 | CVarAlreadyCreated, 312 | ReservedName 313 | }; 314 | } 315 | 316 | //////////////////////////////////////////////////////////////////////////////// 317 | namespace CVarUtils { 318 | template class CVar 319 | { 320 | public: 321 | //////////////////////////////////////////////////////////////////////////////// 322 | CVar( std::string sVarName, 323 | T TVarValue, std::string sHelp="No help available", 324 | bool bSerialise=true, /**< Input: if false, this CVar will not be taken into account when serialising (eg saving) the Trie */ 325 | std::ostream& (*pSerialisationFuncPtr)( std::ostream &, T ) = NULL, 326 | std::istream& (*pDeserialisationFuncPtr)( std::istream &, T ) = NULL ) { 327 | 328 | //std::cout << TToStream( std::cout, TVarValue ); 329 | m_pValueStringFuncPtr = CVarValueString; // template pointer to value string func 330 | m_pTypeStringFuncPtr = CVarTypeString; // template pointer to type string func 331 | m_pSetValueFuncPtr = StringToCVarValue; 332 | 333 | m_pSerialisationFuncPtr = pSerialisationFuncPtr; 334 | m_pDeserialisationFuncPtr = pDeserialisationFuncPtr; 335 | 336 | m_pVarData = new T; 337 | *m_pVarData = TVarValue; 338 | m_sVarName = sVarName; 339 | m_bSerialise = bSerialise; 340 | m_sHelp = sHelp; 341 | } 342 | 343 | //////////////////////////////////////////////////////////////////////////////// 344 | ~CVar() { 345 | delete m_pVarData; 346 | } 347 | 348 | //////////////////////////////////////////////////////////////////////////////// 349 | // Convert value to string representation 350 | // Call the original function that was installed at object creation time, 351 | // regardless of current object class type T. 352 | std::string GetValueAsString() { 353 | if( m_pSerialisationFuncPtr != NULL ) { 354 | std::stringstream sStream( "" ); 355 | m_pSerialisationFuncPtr( sStream, *m_pVarData ); 356 | return sStream.str(); 357 | } 358 | else { 359 | return (*m_pValueStringFuncPtr)( m_pVarData ); 360 | } 361 | } 362 | 363 | //////////////////////////////////////////////////////////////////////////////// 364 | // Convert string representation to value 365 | // Call the original function that was installed at object creation time, 366 | // regardless of current object class type T. 367 | void SetValueFromString( const std::string &sValue ) { 368 | if( m_pDeserialisationFuncPtr != NULL ) { 369 | std::stringstream sStream( sValue ); 370 | m_pDeserialisationFuncPtr( sStream, *m_pVarData ); 371 | } 372 | else { 373 | if( m_pSetValueFuncPtr != NULL ) { 374 | (*m_pSetValueFuncPtr)( m_pVarData, sValue ); 375 | } 376 | } 377 | } 378 | 379 | //////////////////////////////////////////////////////////////////////////////// 380 | // Convert type to string representation 381 | // Call the original function that was installed at object creation time, 382 | // regardless of current object class type T. 383 | std::string type() { 384 | return (*m_pTypeStringFuncPtr)( m_pVarData ); 385 | } 386 | 387 | //////////////////////////////////////////////////////////////////////////////// 388 | // Get values to and from a string representation (used for 389 | // serialization and console interaction) 390 | bool FromString( std::string s ); //return true if successful 391 | 392 | const std::string& GetHelp() { 393 | return m_sHelp; 394 | } 395 | 396 | 397 | public: // Public data 398 | std::string m_sVarName; 399 | T *m_pVarData; 400 | bool m_bSerialise; 401 | 402 | private: 403 | std::string m_sHelp; 404 | 405 | // pointer to func to get CVar type as a string 406 | std::string (*m_pTypeStringFuncPtr)( T *t ); 407 | 408 | // pointer to func to get CVar value as a string 409 | std::string (*m_pValueStringFuncPtr)( T *t ); 410 | 411 | // pointer to func to set CVar Value from a string 412 | void (*m_pSetValueFuncPtr)( T *t, const std::string & ); 413 | 414 | std::ostream& (*m_pSerialisationFuncPtr)( std::ostream &, T ); 415 | std::istream& (*m_pDeserialisationFuncPtr)( std::istream &, T ) ; 416 | }; 417 | } 418 | 419 | namespace CVarUtils { 420 | //////////////////////////////////////////////////////////////////////////////// 421 | template T& CreateCVar( 422 | const std::string& s, 423 | T val, 424 | std::string sHelp, 425 | std::ostream& (*pSerialisationFuncPtr)( std::ostream &, T ), 426 | std::istream& (*pDeserialisationFuncPtr)( std::istream &, T ) 427 | ) 428 | { 429 | Trie& trie = TrieInstance(); 430 | 431 | if( trie.Exists( s ) ) { 432 | throw CVarAlreadyCreated; 433 | } 434 | if( std::string( s ) == "true" || 435 | std::string( s ) == "false" || 436 | std::string( s ) == "not") { 437 | throw ReservedName; 438 | } 439 | #ifdef DEBUG_CVAR 440 | printf( "Creating variable: %s.\n", s ); 441 | #endif 442 | CVarUtils::CVar *pCVar = new CVarUtils::CVar( 443 | s, val, sHelp, true, pSerialisationFuncPtr, pDeserialisationFuncPtr ); 444 | trie.Insert( s, (void *) pCVar ); 445 | return *(pCVar->m_pVarData); 446 | } 447 | 448 | //////////////////////////////////////////////////////////////////////////////// 449 | template T& CreateGetCVar( 450 | const std::string& s, 451 | T val, 452 | std::string sHelp, 453 | std::ostream& (*pSerialisationFuncPtr)( std::ostream &, T ), 454 | std::istream& (*pDeserialisationFuncPtr)( std::istream &, T ) 455 | ) 456 | { 457 | try { 458 | return CreateCVar( s, val, sHelp, pSerialisationFuncPtr, pDeserialisationFuncPtr ); 459 | } 460 | catch( CVarUtils::CVarException e ){ 461 | switch( e ) { 462 | case CVarUtils::CVarAlreadyCreated: 463 | break; 464 | default: 465 | throw e; 466 | break; 467 | } 468 | } 469 | return CVarUtils::GetCVarRef( s ); 470 | } 471 | 472 | //////////////////////////////////////////////////////////////////////////////// 473 | template T& CreateGetUnsavedCVar( 474 | const std::string& s, 475 | T val, 476 | const std::string& sHelp, 477 | std::ostream& (*pSerialisationFuncPtr)( std::ostream &, T ), 478 | std::istream& (*pDeserialisationFuncPtr)( std::istream &, T ) 479 | ) 480 | { 481 | try { 482 | return CreateUnsavedCVar( s, val, sHelp, pSerialisationFuncPtr, pDeserialisationFuncPtr ); 483 | } 484 | catch( CVarUtils::CVarException e ){ 485 | switch( e ) { 486 | case CVarUtils::CVarAlreadyCreated: 487 | break; 488 | default: 489 | throw e; 490 | break; 491 | } 492 | } 493 | return CVarUtils::GetCVarRef( s ); 494 | } 495 | 496 | //////////////////////////////////////////////////////////////////////////////// 497 | template T& CreateUnsavedCVar( 498 | const std::string& s, 499 | T val, 500 | const std::string& sHelp, 501 | std::ostream& (*pSerialisationFuncPtr)( std::ostream &, T ), 502 | std::istream& (*pDeserialisationFuncPtr)( std::istream &, T ) 503 | ) 504 | { 505 | Trie& trie = TrieInstance(); 506 | 507 | if( trie.Exists( s ) ) { 508 | throw CVarAlreadyCreated; 509 | } 510 | if( std::string( s ) == "true" || 511 | std::string( s ) == "false" || 512 | std::string( s ) == "not") { 513 | throw ReservedName; 514 | } 515 | #ifdef DEBUG_CVAR 516 | printf( "Creating variable: %s.\n", s ); 517 | #endif 518 | CVarUtils::CVar *pCVar = new CVarUtils::CVar( s, val, sHelp, false, pSerialisationFuncPtr, pDeserialisationFuncPtr ); 519 | trie.Insert( s, (void *) pCVar ); 520 | return *(pCVar->m_pVarData); 521 | } 522 | 523 | //////////////////////////////////////////////////////////////////////////////// 524 | template 525 | void AttachCVar(const std::string& s, 526 | T* ref, 527 | const std::string& sHelp) 528 | { 529 | CreateCVar >(s, CVarRef(ref), sHelp, 0, 0); 530 | } 531 | 532 | //////////////////////////////////////////////////////////////////////////////// 533 | template T& GetCVarRef( const char* s ) { 534 | Trie& trie = TrieInstance(); 535 | 536 | if( !trie.Exists( s ) ) { 537 | throw CVarNonExistant; 538 | } 539 | return *(((CVar*)trie.Find(s)->m_pNodeData)->m_pVarData); 540 | } 541 | 542 | //////////////////////////////////////////////////////////////////////////////// 543 | template T& GetCVarRef( std::string s ) { 544 | return CVarUtils::GetCVarRef( s.c_str() ); 545 | } 546 | 547 | //////////////////////////////////////////////////////////////////////////////// 548 | template T GetCVar( const char* s ) { 549 | return CVarUtils::GetCVarRef( s ); 550 | } 551 | 552 | //////////////////////////////////////////////////////////////////////////////// 553 | template T GetCVar( std::string s ) { 554 | return CVarUtils::GetCVarRef( s.c_str() ); 555 | } 556 | 557 | //////////////////////////////////////////////////////////////////////////////// 558 | inline bool CVarExists( std::string s ){ 559 | return TrieInstance().Exists( s ); 560 | } 561 | 562 | //////////////////////////////////////////////////////////////////////////////// 563 | inline std::string GetCVarString( std::string s ) { 564 | Trie& trie = TrieInstance(); 565 | 566 | if( !trie.Exists( s ) ) { 567 | throw CVarNonExistant; 568 | } 569 | return 570 | ((CVar*)trie.Find(s)->m_pNodeData)->GetValueAsString(); 571 | } 572 | 573 | //////////////////////////////////////////////////////////////////////////////// 574 | template void SetCVar( const char* s, T val ) { 575 | Trie& trie = TrieInstance(); 576 | if( !trie.Exists( s ) ) { 577 | throw CVarNonExistant; 578 | } 579 | *(((CVar*)trie.Find(s)->m_pNodeData)->m_pVarData) = val; 580 | } 581 | 582 | //////////////////////////////////////////////////////////////////////////////// 583 | template void SetCVar( std::string s, T val ) { 584 | CVarUtils::SetCVar( s.c_str(), val ); 585 | } 586 | 587 | //////////////////////////////////////////////////////////////////////////////// 588 | inline const std::string& GetHelp( const char* s ) { 589 | Trie& trie = TrieInstance(); 590 | if( !trie.Exists( s ) ) { 591 | throw CVarNonExistant; 592 | } 593 | return ((CVar*)trie.Find(s)->m_pNodeData)->GetHelp(); 594 | } 595 | 596 | //////////////////////////////////////////////////////////////////////////////// 597 | inline const std::string& GetHelp( std::string s ) { 598 | return CVarUtils::GetHelp( s.c_str() ); 599 | } 600 | 601 | //////////////////////////////////////////////////////////////////////////////// 602 | inline std::string GetValueAsString( void* cvar ) { 603 | return ((CVar*) cvar)->GetValueAsString(); 604 | } 605 | 606 | //////////////////////////////////////////////////////////////////////////////// 607 | inline void SetValueFromString( void* cvar, const std::string &sValue ) { 608 | ((CVar*) cvar)->SetValueFromString( sValue ); 609 | } 610 | 611 | //////////////////////////////////////////////////////////////////////////////// 612 | inline void PrintCVars( 613 | const char* sRowBeginTag = "", 614 | const char* sRowEndTag = "", 615 | const char* sCellBeginTag = "", 616 | const char* sCellEndTag = "" 617 | ) 618 | { 619 | Trie& trie = TrieInstance(); 620 | TrieNode* node = trie.FindSubStr(""); 621 | if( !node ) { 622 | return; 623 | } 624 | std::cout << "CVars:" << std::endl; 625 | // Retrieve suggestions (retrieve all leaves by traversing from current node) 626 | std::vector suggest = trie.CollectAllNodes( node ); 627 | std::sort( suggest.begin(), suggest.end() ); 628 | //output suggestions 629 | unsigned int nLongestName = 0; 630 | unsigned int nLongestVal = 0; 631 | for( unsigned int ii = 0; ii < suggest.size(); ii++ ){ 632 | std::string sName = ( (CVarUtils::CVar*) suggest[ii]->m_pNodeData )->m_sVarName; 633 | std::string sVal = CVarUtils::GetValueAsString( suggest[ii]->m_pNodeData ); 634 | if( sName.length() > nLongestName ){ 635 | nLongestName = sName.length(); 636 | } 637 | if( sVal.length() > nLongestVal ){ 638 | nLongestVal = sVal.length(); 639 | } 640 | } 641 | 642 | if( suggest.size() > 1) { 643 | for( unsigned int ii = 0; ii < suggest.size(); ii++ ){ 644 | std::string sName = ( (CVarUtils::CVar*) suggest[ii]->m_pNodeData )->m_sVarName; 645 | std::string sVal = CVarUtils::GetValueAsString( suggest[ii]->m_pNodeData ); 646 | std::string sHelp = CVarUtils::GetHelp( sName ); 647 | // sName.resize( nLongestName, ' ' ); 648 | // sVal.resize( nLongestVal, ' ' ); 649 | // printf( "%-s: Default value = %-30s %-50s\n", sName.c_str(), sVal.c_str(), sHelp.empty() ? "" : sHelp.c_str() ); 650 | printf( "%s%s%-s%s%s %-30s %s%s %-50s%s%s\n", 651 | sRowBeginTag, 652 | sCellBeginTag, sName.c_str(), sCellEndTag, 653 | sCellBeginTag, sVal.c_str(), sCellEndTag, 654 | sCellBeginTag, sHelp.empty() ? "" : sHelp.c_str(), sCellEndTag, 655 | sRowEndTag ); 656 | printf( "%s", sRowEndTag ); 657 | } 658 | } 659 | } 660 | 661 | //////////////////////////////////////////////////////////////////////////////// 662 | inline void SetStreamType( const CVARS_STREAM_TYPE& stream_type ) 663 | { 664 | TrieInstance().SetStreamType( stream_type ); 665 | } 666 | 667 | //////////////////////////////////////////////////////////////////////////////// 668 | inline bool Save( const std::string& sFileName, std::vector vAcceptedSubstrings ) { 669 | std::ofstream sOut( sFileName.c_str() ); 670 | Trie& trie = TrieInstance(); 671 | if( sOut.is_open() ) { 672 | trie.SetVerbose( false ); 673 | trie.SetAcceptedSubstrings ( vAcceptedSubstrings ); 674 | sOut << trie; 675 | sOut.close(); 676 | return true; 677 | } 678 | else { 679 | // std::cerr << "ERROR opening cvars file for saving." << std::endl; 680 | return false; 681 | } 682 | } 683 | 684 | //////////////////////////////////////////////////////////////////////////////// 685 | inline bool Load( const std::string& sFileName, std::vector vAcceptedSubstrings ) { 686 | std::ifstream sIn( sFileName.c_str() ); 687 | Trie& trie = TrieInstance(); 688 | if( sIn.is_open() ) { 689 | trie.SetVerbose( false ); 690 | trie.SetAcceptedSubstrings ( vAcceptedSubstrings ); 691 | sIn >> trie; 692 | sIn.close(); 693 | return true; 694 | } 695 | else { 696 | // std::cerr << "ERROR opening cvars file for loading." << std::endl; 697 | return false; 698 | } 699 | } 700 | 701 | //////////////////////////////////////////////////////////////////////////////// 702 | inline std::string CVarSpc() { 703 | if( CVarUtils::GetCVar( "console.CVarIndent" ) <= 0 ) { 704 | return ""; 705 | } 706 | return std::string( CVarUtils::GetCVar( "console.CVarIndent" ), ' ' ); 707 | } 708 | 709 | //////////////////////////////////////////////////////////////////////////////// 710 | inline void CVarIndent() { 711 | CVarUtils::GetCVarRef( "console.CVarIndent" ) += CVarUtils::GetCVar( "console.CVarIndentIncr" ); 712 | } 713 | 714 | //////////////////////////////////////////////////////////////////////////////// 715 | inline void CVarUnIndent() { 716 | CVarUtils::GetCVarRef( "console.CVarIndent" ) -= CVarUtils::GetCVar( "console.CVarIndentIncr" ); 717 | } 718 | 719 | //////////////////////////////////////////////////////////////////////////////// 720 | inline void CVarResetSpc() { 721 | CVarUtils::SetCVar( "console.CVarIndent", 0 ); 722 | } 723 | 724 | //////////////////////////////////////////////////////////////////////////////// 725 | 726 | 727 | 728 | //////////////////////////////////////////////////////////////////////////////// 729 | /// This function parses console input for us -- useful function for glconsole, textconsole, etc 730 | bool ProcessCommand( 731 | const std::string& sCommand, //< Input: 732 | std::string& sResult, //< Output: 733 | bool bExecute = 1 //< Input: 734 | ); 735 | 736 | //////////////////////////////////////////////////////////////////////////////// 737 | bool ExecuteFunction( 738 | const std::string& sCommand, //< Input: 739 | CVarUtils::CVar *cvar, //< Input: 740 | std::string& sResult, //< Output: 741 | bool bExecute = 1 //< Input: 742 | ); 743 | 744 | //////////////////////////////////////////////////////////////////////////////// 745 | bool IsConsoleFunc( 746 | TrieNode *node //< Input: 747 | ); 748 | 749 | //////////////////////////////////////////////////////////////////////////////// 750 | bool IsConsoleFunc( 751 | const std::string sCmd //< Input 752 | ); 753 | 754 | //////////////////////////////////////////////////////////////////////////////// 755 | /// If 'sCommand' is 756 | /// - part of an existing unique variable, it will be completed and 'sCommand' 757 | /// will be the complete variable, sResult will be empty 758 | /// - part of multiple possible variables, it will be completed up to the common 759 | /// factor and possible solutions will be put in sResult (TO IMPROVE: differentiate type of 760 | /// results: command, variable, ...) 761 | /// - a full variable: 'sCommand' will be completed with '= variable_value' and 762 | /// sResult will also contain the variable name and its value 763 | bool TabComplete( const unsigned int nMaxNumCharactersPerLine, ///< Input: use for formatting the sResult when it returns the list of possible completions 764 | std::string& sCommand, 765 | std::vector& vResult ); 766 | 767 | 768 | } 769 | 770 | #endif 771 | --------------------------------------------------------------------------------