src/tools/tConfiguration.h

Go to the documentation of this file.
00001 /*
00002 
00003 *************************************************************************
00004 
00005 ArmageTron -- Just another Tron Lightcycle Game in 3D.
00006 Copyright (C) 2000  Manuel Moos (manuel@moosnet.de)
00007 
00008 **************************************************************************
00009 
00010 This program is free software; you can redistribute it and/or
00011 modify it under the terms of the GNU General Public License
00012 as published by the Free Software Foundation; either version 2
00013 of the License, or (at your option) any later version.
00014 
00015 This program is distributed in the hope that it will be useful,
00016 but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018 GNU General Public License for more details.
00019 
00020 You should have received a copy of the GNU General Public License
00021 along with this program; if not, write to the Free Software
00022 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00023 
00024 ***************************************************************************
00025 
00026 */
00027 
00028 #ifndef ArmageTron_CONFIGURATION_H
00029 #define ArmageTron_CONFIGURATION_H
00030 
00031 #include "tList.h"
00032 #include "tString.h"
00033 #include "tLinkedList.h"
00034 #include "tException.h"
00035 #include "tLocale.h"
00036 #include "tConsole.h"
00037 #include "tLocale.h"
00038 #include <iostream>
00039 #include <ctype.h>
00040 #include <string>
00041 #include <deque>
00042 #include <map>
00043 
00045 enum tAccessLevel
00046 {
00047     tAccessLevel_Owner = 0,        // the server owner
00048     tAccessLevel_Admin = 1,        // one of his admins
00049     tAccessLevel_Moderator = 2,    // one of the moderators
00050     tAccessLevel_3 = 3,            // reserved
00051     tAccessLevel_4 = 4,            // reserved
00052     tAccessLevel_5 = 5,            // reserved
00053     tAccessLevel_6 = 6,            // reserved
00054     tAccessLevel_TeamLeader = 7,   // a team leader
00055     tAccessLevel_TeamMember = 8,   // a team member
00056     tAccessLevel_9 = 9,            // reserved
00057     tAccessLevel_10 = 10,          // reserved
00058     tAccessLevel_11 = 11,          // reserved
00059     tAccessLevel_Local      = 12,  // user with a local account
00060     tAccessLevel_13 = 13,          // reserved
00061     tAccessLevel_14 = 14,          // reserved
00062     tAccessLevel_Remote = 15,      // user with remote account
00063     tAccessLevel_DefaultAuthenticated = 15,     // default access level for authenticated users
00064     tAccessLevel_FallenFromGrace = 16,          // authenticated, but not liked
00065     tAccessLevel_Shunned = 17,          // authenticated, but disliked
00066     tAccessLevel_18 = 18,          // reserved
00067     tAccessLevel_Authenticated = 19,// any authenticated player
00068     tAccessLevel_Program = 20,     // a regular player
00069     tAccessLevel_21 = 21,          // reserved
00070     tAccessLevel_22 = 22,          // reserved
00071     tAccessLevel_23 = 23,          // reserved
00072     tAccessLevel_24 = 24,          // reserved
00073     tAccessLevel_25 = 25,          // reserved
00074     tAccessLevel_Default = 20
00075 };
00076 
00078 class tCurrentAccessLevel
00079 {
00080     friend class tCasacl;
00081 public:
00083     tCurrentAccessLevel( tAccessLevel newLevel, bool allowElevation = false );
00084 
00086     tCurrentAccessLevel();
00087     ~tCurrentAccessLevel();
00088 
00090     static tAccessLevel GetAccessLevel();
00091 
00093     static tString GetName( tAccessLevel level );
00094 private:
00095     tCurrentAccessLevel( tCurrentAccessLevel const & );
00096     tCurrentAccessLevel & operator = ( tCurrentAccessLevel const & );
00097 
00098     tAccessLevel lastLevel_; 
00099     static tAccessLevel currentLevel_; 
00100 };
00101 
00102 class tConfItemBase
00103 {
00104     friend class tCheckedPTRBase;
00105     friend class tConfItemLevel;
00106     friend class tAccessLevelSetter;
00107 
00108     int id;
00109 protected:
00110     const tString title;
00111     const tOutput help;
00112     bool changed;
00113     tAccessLevel requiredLevel;
00114 
00115     typedef std::map< tString, tConfItemBase * > tConfItemMap;
00116     static tConfItemMap & ConfItemMap();
00117 
00118 public:
00119     typedef void callbackFunc(void);
00120 private:
00121     callbackFunc *callback;
00122 protected:
00123     void ExecuteCallback() {if (callback != 0) (*callback)(); }
00124 
00125     // static tConfItemBase* s_ConfItemAnchor;
00126     //static tConfItemBase* Anchor(){return dynamic_cast<tConfItemBase *>(s_ConfItemAnchor);}
00127 public:
00128     static bool printChange; 
00129     static bool printErrors; 
00130 
00131     tConfItemBase(const char *title, const tOutput& help, callbackFunc *cb=0);
00132     tConfItemBase(const char *title, callbackFunc *cb=0);
00133     virtual ~tConfItemBase();
00134 
00135     tString const & GetTitle() const {
00136         return title;
00137     }
00138 
00139     static int EatWhitespace(std::istream &s); // eat whitespace from stream; return: first non-whitespace char
00140 
00141     static void SaveAll(std::ostream &s);
00142     static void LoadAll(std::istream &s);  
00143     static void LoadLine(std::istream &s); 
00144     static bool LoadPlayback( bool print = false ); 
00145     static void DocAll(std::ostream &s);
00146     static std::deque<tString> GetCommands(void);
00147     static tConfItemBase *FindConfigItem(tString const &name);
00148 
00149     virtual void ReadVal(std::istream &s)=0;
00150     virtual void WriteVal(std::ostream &s)=0;
00151 
00152     virtual void WasChanged(){} // what to do if a read changed the thing
00153 
00154     virtual bool Writable(){
00155         return true;
00156     }
00157 
00158     virtual bool Save(){
00159         return true;
00160     }
00161 };
00162 
00164 class tAccessLevelSetter
00165 {
00166 public:
00168     tAccessLevelSetter( tConfItemBase & item, tAccessLevel level );
00169 };
00170 
00171 // Arg! Msvc++ could not handle bool IO. Seems to be fine now.
00172 #ifdef _MSC_VER_XXX
00173 inline std::istream & operator >> (std::istream &s,bool &b){
00174     int x;
00175     s >> x;
00176     b=(x!=0);
00177     return s;
00178 }
00179 
00180 inline std::ostream & operator << (std::ostream &s,bool b){
00181     if (b)
00182         return s << 1;
00183     else
00184         return s << 0;
00185 }
00186 #endif
00187 
00189 template< class T > struct tTypeToConfig
00190 {
00191     typedef T TOSTREAM;             
00192     typedef int DUMMYREQUIRED;      
00193 };
00194 
00196 // recording (and back after playback) by specializing the tTypeToStream class template
00197 #define tCONFIG_AS( TYPE, STREAM ) \
00198 template<> struct tTypeToConfig< TYPE > \
00199 { \
00200     typedef STREAM TOSTREAM; \
00201   typedef int * DUMMYREQUIRED; \
00202 } \
00203  
00205 #define tCONFIG_ENUM( TYPE ) tCONFIG_AS( TYPE, int )
00206 
00207 tCONFIG_ENUM( tAccessLevel );
00208 
00210 class tAbortLoading: public tException
00211 {
00212 public:
00213     tAbortLoading( char const * command );
00214 private:
00215     tString command_; 
00216 
00217     virtual tString DoGetName() const;
00218     virtual tString DoGetDescription() const;
00219 };
00220 
00221 template<class T> class tConfItem:virtual public tConfItemBase{
00222 protected:
00223     T    *target;
00224 
00225     tConfItem(T &t):tConfItemBase(""),target(&t){};
00226 public:
00227     tConfItem(const char *title,const tOutput& help,T& t, callbackFunc *cb=0)
00228             :tConfItemBase(title,help,cb),target(&t){}
00229 
00230     tConfItem(const char *title,T& t, callbackFunc *cb=0)
00231             :tConfItemBase(title,cb),target(&t){}
00232 
00233     virtual ~tConfItem(){}
00234 
00235     typedef typename tTypeToConfig< T >::DUMMYREQUIRED DUMMYREQUIRED;
00236 
00237     // read without conversion
00238     static void DoRead(std::istream &s, T & value, int )
00239     {
00240         s >> value;
00241     }
00242 
00243     // read with conversion
00244     static void DoRead(std::istream &s, T & value, int * )
00245     {
00246         typename tTypeToConfig< T >::TOSTREAM dummy;
00247         s >> dummy;
00248         value = static_cast< T >( dummy );
00249     }
00250 
00251     // write without conversion
00252     static void DoWrite(std::ostream &s, T const & value, int )
00253     {
00254         s << value;
00255     }
00256 
00257     // write with conversion
00258     static void DoWrite(std::ostream &s, T const & value, int * )
00259     {
00260         s << static_cast< typename tTypeToConfig< T >::TOSTREAM >( value );
00261     }
00262 
00263     virtual void ReadVal(std::istream &s){
00264         // eat whitepsace
00265         int c= EatWhitespace(s);
00266 
00267         T dummy( *target );
00268         if (c!='\n' && s && !s.eof() && s.good()){
00269             DoRead( s, dummy, DUMMYREQUIRED() );
00270             if (!s.good() && !s.eof() )
00271             {
00272                 tOutput o;
00273                 o.SetTemplateParameter(1, title);
00274                 o << "$config_error_read";
00275                 con << o;
00276             }
00277             else
00278                 if (dummy!=*target){
00279                     if (!Writable())
00280                     {
00281                         tOutput o;
00282                         o.SetTemplateParameter(1, title);
00283                         o << "nconfig_errror_protected";
00284                         con << "";
00285                     }
00286                     else{
00287                         if (printChange)
00288                         {
00289                             tOutput o;
00290                             o.SetTemplateParameter(1, title);
00291                             o.SetTemplateParameter(2, *target);
00292                             o.SetTemplateParameter(3, dummy);
00293                             o << "$config_value_changed";
00294                             con << o;
00295                         }
00296 
00297                         *target=dummy;
00298                         changed=true;
00299                         ExecuteCallback();
00300                     }
00301                 }
00302         }
00303         else
00304         {
00305             tOutput o;
00306             o.SetTemplateParameter(1, title);
00307             o.SetTemplateParameter(2, *target);
00308             o << "$config_message_info";
00309             con << o;
00310         }
00311 
00312         // read the rest of the line
00313         c=' ';
00314         while (c!='\n' && s.good() && !s.eof()) c=s.get();
00315     }
00316 
00317     virtual void WriteVal(std::ostream &s){
00318         DoWrite( s, *target, DUMMYREQUIRED() );
00319     }
00320 };
00321 
00322 template<class T> class tSettingItem:public tConfItem<T>{
00323 public:
00324     //  tSettingItem(const char *title,const tOutput& help,T& t)
00325     //    :tConfItemBase(title,help),tConfItem<T>(t){}
00326 
00327     tSettingItem(const char *title,T& t, void (*cb)(void)=0)
00328             :tConfItemBase(title),tConfItem<T>(title, t, cb){}
00329 
00330     virtual ~tSettingItem(){}
00331 
00332     virtual bool Save(){
00333         return false;
00334     }
00335 };
00336 
00337 
00338 class tConfItemLine:public tConfItem<tString>, virtual public tConfItemBase{
00339 public:
00340     tConfItemLine(const char *title,const char *help,tString &s, callbackFunc *cb=0)
00341             :tConfItemBase(title,help),tConfItem<tString>(title,help,s,cb){};
00342 
00343     virtual ~tConfItemLine(){}
00344 
00345     tConfItemLine(const char *title, tString &s, callbackFunc *cb=0)
00346             :tConfItemBase(title,cb),tConfItem<tString>(title,s){};
00347 
00348     virtual void ReadVal(std::istream &s);
00349     virtual void WriteVal(std::ostream &s);
00350 };
00351 
00352 typedef void CONF_FUNC(std::istream &s);
00353 
00354 class tConfItemFunc:public tConfItemBase{
00355     CONF_FUNC *f;
00356 public:
00357     tConfItemFunc(const char *title, CONF_FUNC *func);
00358     virtual ~tConfItemFunc();
00359 
00360     virtual void ReadVal(std::istream &s);
00361     virtual void WriteVal(std::ostream &s);
00362 
00363     virtual bool Save();
00364 };
00365 
00366 // includes a single configuration file by name, searches in var and config directories
00367 void st_Include( tString const & file, bool reportError = true );
00368 
00369 void st_LoadConfig();
00370 void st_SaveConfig();
00371 
00372 extern bool st_FirstUse;
00373 
00374 #endif
00375 

Generated on Sat Mar 15 22:55:59 2008 for Armagetron Advanced by  doxygen 1.5.4