Browse Source

add ConfigVariableInt64

David Rose 18 years ago
parent
commit
5afa502948

+ 3 - 0
dtool/src/prc/Sources.pp

@@ -21,6 +21,7 @@
     configVariableEnum.I configVariableEnum.h \
     configVariableFilename.I configVariableFilename.h \
     configVariableInt.I configVariableInt.h \
+    configVariableInt64.I configVariableInt64.h \
     configVariableList.I configVariableList.h \
     configVariableManager.I configVariableManager.h \
     configVariableSearchPath.I configVariableSearchPath.h \
@@ -51,6 +52,7 @@
     configVariableEnum.cxx \
     configVariableFilename.cxx \
     configVariableInt.cxx \
+    configVariableInt64.cxx \
     configVariableList.cxx \
     configVariableManager.cxx \
     configVariableSearchPath.cxx \
@@ -80,6 +82,7 @@
     configVariableEnum.I configVariableEnum.h \
     configVariableFilename.I configVariableFilename.h \
     configVariableInt.I configVariableInt.h \
+    configVariableInt64.I configVariableInt64.h \
     configVariableList.I configVariableList.h \
     configVariableManager.I configVariableManager.h \
     configVariableSearchPath.I configVariableSearchPath.h \

+ 33 - 0
dtool/src/prc/configDeclaration.I

@@ -144,6 +144,21 @@ has_int_word(int n) const {
   return false;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: ConfigDeclaration::has_int64_word
+//       Access: Public
+//  Description: Returns true if the declaration's value has a valid
+//               int64 value for the nth word.
+////////////////////////////////////////////////////////////////////
+INLINE bool ConfigDeclaration::
+has_int64_word(int n) const {
+  if (has_string_word(n)) {
+    ((ConfigDeclaration *)this)->check_int64_word(n);
+    return (_words[n]._flags & F_valid_int64) != 0;
+  }
+  return false;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: ConfigDeclaration::has_double_word
 //       Access: Public
@@ -210,6 +225,24 @@ get_int_word(int n) const {
   return 0;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: ConfigDeclaration::get_int64_word
+//       Access: Public
+//  Description: Returns the int64 value of the nth word of the
+//               declaration's value, or 0 if there is no nth value.
+//               See also has_int64_word().
+////////////////////////////////////////////////////////////////////
+INLINE PN_int64 ConfigDeclaration::
+get_int64_word(int n) const {
+  // We use has_string_word() instead of has_int64_word(), so we can
+  // return a partial answer if there was one.
+  if (has_string_word(n)) {
+    ((ConfigDeclaration *)this)->check_int64_word(n);
+    return _words[n]._int64;
+  }
+  return 0;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: ConfigDeclaration::get_double_word
 //       Access: Public

+ 119 - 4
dtool/src/prc/configDeclaration.cxx

@@ -123,6 +123,23 @@ set_int_word(int n, int value) {
   invalidate_cache();
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: ConfigDeclaration::set_int64_word
+//       Access: Public
+//  Description: Changes the nth word to the indicated value without
+//               affecting the other words.
+////////////////////////////////////////////////////////////////////
+void ConfigDeclaration::
+set_int64_word(int n, PN_int64 value) {
+  ostringstream strm;
+  strm << value;
+  set_string_word(n, strm.str());
+
+  _words[n]._flags |= (F_checked_int64 | F_valid_int64);
+  _words[n]._int64 = value;
+  invalidate_cache();
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: ConfigDeclaration::set_double_word
 //       Access: Public
@@ -225,6 +242,10 @@ check_bool_word(int n) {
         } else {
           word._bool = false;
         }
+
+        prc_cat->warning()
+          << "Invalid bool value for ConfigVariable "
+          << get_variable()->get_name() << ": " << word._str << "\n";
         return;
       }
 
@@ -250,12 +271,102 @@ check_int_word(int n) {
     if ((word._flags & F_checked_int) == 0) {
       word._flags |= F_checked_int;
 
-      const char *nptr = word._str.c_str();
-      char *endptr;
-      word._int = strtol(nptr, &endptr, 0);
+      // We scan the word by hand, rather than relying on strtol(), so
+      // we can check for overflow of the 32-bit value.
+      word._int = 0;
+      bool overflow = false;
+
+      string::const_iterator pi = word._str.begin();
+      if (pi != word._str.end() && (*pi) == '-') {
+        ++pi;
+        // Negative number.
+        while (pi != word._str.end() && isdigit(*pi)) {
+          int next = word._int * 10 - (int)((*pi) - '0');
+          if ((int)(next / 10) != word._int) {
+            // Overflow.
+            overflow = true;
+          }
+          word._int = next;
+          ++pi;
+        }
 
-      if (*endptr == '\0') {
+      } else {
+        // Positive number.
+        while (pi != word._str.end() && isdigit(*pi)) {
+          int next = word._int * 10 + (int)((*pi) - '0');
+          if ((int)(next / 10) != word._int) {
+            // Overflow.
+            overflow = true;
+          }
+          word._int = next;
+          ++pi;
+        }
+      }
+
+      if (pi == word._str.end() && !overflow) {
         word._flags |= F_valid_int;
+      } else {
+        prc_cat->warning()
+          << "Invalid integer value for ConfigVariable "
+          << get_variable()->get_name() << ": " << word._str << "\n";
+      }
+    }
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ConfigDeclaration::check_int64_word
+//       Access: Private
+//  Description: Checks whether the nth word can be interpreted as an
+//               integer value.
+////////////////////////////////////////////////////////////////////
+void ConfigDeclaration::
+check_int64_word(int n) {
+  if (!_got_words) {
+    get_words();
+  }
+
+  if (n >= 0 && n < (int)_words.size()) {
+    Word &word = _words[n];
+    if ((word._flags & F_checked_int64) == 0) {
+      word._flags |= F_checked_int64;
+
+      word._int64 = 0;
+      bool overflow = false;
+
+      string::const_iterator pi = word._str.begin();
+      if (pi != word._str.end() && (*pi) == '-') {
+        ++pi;
+        // Negative number.
+        while (pi != word._str.end() && isdigit(*pi)) {
+          PN_int64 next = word._int64 * 10 - (int)((*pi) - '0');
+          if ((PN_int64)(next / 10) != word._int64) {
+            // Overflow.
+            overflow = true;
+          }
+          word._int64 = next;
+          ++pi;
+        }
+
+      } else {
+        // Positive number.
+        while (pi != word._str.end() && isdigit(*pi)) {
+          PN_int64 next = word._int64 * 10 + (int)((*pi) - '0');
+          if ((PN_int64)(next / 10) != word._int64) {
+            // Overflow.
+            overflow = true;
+          }
+          word._int64 = next;
+          ++pi;
+        }
+      }
+
+      if (pi == word._str.end() && !overflow) {
+        word._flags |= F_valid_int64;
+      } else {
+        prc_cat->warning()
+          << "Invalid int64 value for ConfigVariable "
+          << get_variable()->get_name() << ": " << word._str << "\n";
       }
     }
   }
@@ -284,6 +395,10 @@ check_double_word(int n) {
 
       if (*endptr == '\0') {
         word._flags |= F_valid_double;
+      } else {
+        prc_cat->warning()
+          << "Invalid floating-point value for ConfigVariable "
+          << get_variable()->get_name() << ": " << word._str << "\n";
       }
     }
   }

+ 8 - 0
dtool/src/prc/configDeclaration.h

@@ -23,6 +23,7 @@
 #include "configFlags.h"
 #include "configPage.h"
 #include "vector_string.h"
+#include "numeric_types.h"
 
 #include <vector>
 
@@ -57,16 +58,19 @@ public:
   INLINE bool has_string_word(int n) const;
   INLINE bool has_bool_word(int n) const;
   INLINE bool has_int_word(int n) const;
+  INLINE bool has_int64_word(int n) const;
   INLINE bool has_double_word(int n) const;
 
   INLINE string get_string_word(int n) const;
   INLINE bool get_bool_word(int n) const;
   INLINE int get_int_word(int n) const;
+  INLINE PN_int64 get_int64_word(int n) const;
   INLINE double get_double_word(int n) const;
 
   void set_string_word(int n, const string &value);
   void set_bool_word(int n, bool value);
   void set_int_word(int n, int value);
+  void set_int64_word(int n, PN_int64 value);
   void set_double_word(int n, double value);
 
   INLINE int get_decl_seq() const;
@@ -82,6 +86,7 @@ private:
   void get_words();
   void check_bool_word(int n);
   void check_int_word(int n);
+  void check_int64_word(int n);
   void check_double_word(int n);
 
 private:
@@ -97,6 +102,8 @@ private:
     F_valid_int      = 0x0008,
     F_checked_double = 0x0010,
     F_valid_double   = 0x0020,
+    F_checked_int64  = 0x0040,
+    F_valid_int64    = 0x0080,
   };
 
   class Word {
@@ -104,6 +111,7 @@ private:
     string _str;
     bool _bool;
     int _int;
+    PN_int64 _int64;
     double _double;
     short _flags;
   };

+ 3 - 0
dtool/src/prc/configFlags.cxx

@@ -53,6 +53,9 @@ operator << (ostream &out, ConfigFlags::ValueType type) {
 
   case ConfigFlags::VT_search_path:
     return out << "search-path";
+
+  case ConfigFlags::VT_int64:
+    return out << "int64";
   }
 
   return out << "**invalid(" << (int)type << ")**";

+ 1 - 0
dtool/src/prc/configFlags.h

@@ -42,6 +42,7 @@ PUBLISHED:
     VT_double,
     VT_enum,
     VT_search_path,
+    VT_int64,
   };
 
   enum VariableFlags {

+ 39 - 0
dtool/src/prc/configVariable.I

@@ -161,6 +161,19 @@ has_int_word(int n) const {
   return decl->has_int_word(n);
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: ConfigVariable::has_int64_word
+//       Access: Published
+//  Description: Returns true if the variable's value has a valid
+//               64-bit integer value for the nth word.
+////////////////////////////////////////////////////////////////////
+INLINE bool ConfigVariable::
+has_int64_word(int n) const {
+  nassertr(_core != (ConfigVariableCore *)NULL, false);
+  const ConfigDeclaration *decl = _core->get_declaration(0);
+  return decl->has_int64_word(n);
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: ConfigVariable::has_double_word
 //       Access: Published
@@ -216,6 +229,20 @@ get_int_word(int n) const {
   return decl->get_int_word(n);
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: ConfigVariable::get_int64_word
+//       Access: Published
+//  Description: Returns the int64 value of the nth word of the
+//               variable's value, or 0 if there is no nth value.
+//               See also has_int_word().
+////////////////////////////////////////////////////////////////////
+INLINE PN_int64 ConfigVariable::
+get_int64_word(int n) const {
+  nassertr(_core != (ConfigVariableCore *)NULL, 0);
+  const ConfigDeclaration *decl = _core->get_declaration(0);
+  return decl->get_int64_word(n);
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: ConfigVariable::get_double_word
 //       Access: Published
@@ -266,6 +293,18 @@ set_int_word(int n, int value) {
   _core->make_local_value()->set_int_word(n, value);
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: ConfigVariable::set_int64_word
+//       Access: Published
+//  Description: Changes the nth word to the indicated value without
+//               affecting the other words.
+////////////////////////////////////////////////////////////////////
+INLINE void ConfigVariable::
+set_int64_word(int n, PN_int64 value) {
+  nassertv(_core != (ConfigVariableCore *)NULL);
+  _core->make_local_value()->set_int_word(n, value);
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: ConfigVariable::set_double_word
 //       Access: Published

+ 4 - 0
dtool/src/prc/configVariable.h

@@ -21,6 +21,7 @@
 
 #include "dtoolbase.h"
 #include "configVariableBase.h"
+#include "numeric_types.h"
 
 ////////////////////////////////////////////////////////////////////
 //       Class : ConfigVariable
@@ -55,16 +56,19 @@ PUBLISHED:
   INLINE bool has_string_word(int n) const;
   INLINE bool has_bool_word(int n) const;
   INLINE bool has_int_word(int n) const;
+  INLINE bool has_int64_word(int n) const;
   INLINE bool has_double_word(int n) const;
 
   INLINE string get_string_word(int n) const;
   INLINE bool get_bool_word(int n) const;
   INLINE int get_int_word(int n) const;
+  INLINE PN_int64 get_int64_word(int n) const;
   INLINE double get_double_word(int n) const;
 
   INLINE void set_string_word(int n, const string &value);
   INLINE void set_bool_word(int n, bool value);
   INLINE void set_int_word(int n, int value);
+  INLINE void set_int64_word(int n, PN_int64 value);
   INLINE void set_double_word(int n, double value);
 };
 

+ 171 - 0
dtool/src/prc/configVariableInt64.I

@@ -0,0 +1,171 @@
+// Filename: configVariableInt64.I
+// Created by:  drose (19Dec07)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// aPN_int64 with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: ConfigVariableInt64::Constructor
+//       Access: Published
+//  Description: 
+////////////////////////////////////////////////////////////////////
+INLINE ConfigVariableInt64::
+ConfigVariableInt64(const string &name) :
+  ConfigVariable(name, VT_int64),
+  _local_modified(initial_invalid_cache())
+{
+  _core->set_used();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ConfigVariableInt64::Constructor
+//       Access: Published
+//  Description: 
+////////////////////////////////////////////////////////////////////
+INLINE ConfigVariableInt64::
+ConfigVariableInt64(const string &name, PN_int64 default_value, 
+                  const string &description, PN_int64 flags) :
+#ifdef PRC_SAVE_DESCRIPTIONS
+  ConfigVariable(name, ConfigVariableCore::VT_int64, description, flags),
+#else
+  ConfigVariable(name, ConfigVariableCore::VT_int64, string(), flags),
+#endif
+  _local_modified(initial_invalid_cache())
+{
+  set_default_value(default_value);
+  _core->set_used();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ConfigVariableInt64::Constructor
+//       Access: Published
+//  Description: 
+////////////////////////////////////////////////////////////////////
+INLINE ConfigVariableInt64::
+ConfigVariableInt64(const string &name, const string &default_value, 
+                  const string &description, PN_int64 flags) :
+#ifdef PRC_SAVE_DESCRIPTIONS
+  ConfigVariable(name, ConfigVariableCore::VT_int64, description, flags),
+#else
+  ConfigVariable(name, ConfigVariableCore::VT_int64, string(), flags),
+#endif
+  _local_modified(initial_invalid_cache())
+{
+  _core->set_default_value(default_value);
+  _core->set_used();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ConfigVariableInt64::operator =
+//       Access: Published
+//  Description: Reassigns the variable's local value.
+////////////////////////////////////////////////////////////////////
+INLINE void ConfigVariableInt64::
+operator = (PN_int64 value) {
+  set_value(value);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ConfigVariableInt64::typecast operator
+//       Access: Published
+//  Description: Returns the variable's value.
+////////////////////////////////////////////////////////////////////
+INLINE ConfigVariableInt64::
+operator PN_int64 () const {
+  return get_value();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ConfigVariableInt64::size()
+//       Access: Published
+//  Description: Returns the number of unique words in the variable.
+////////////////////////////////////////////////////////////////////
+INLINE PN_int64 ConfigVariableInt64::
+size() const {
+  return get_num_words();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ConfigVariableInt64::operator []
+//       Access: Published
+//  Description: Returns the value of the variable's nth word.
+////////////////////////////////////////////////////////////////////
+INLINE PN_int64 ConfigVariableInt64::
+operator [] (int n) const {
+  return get_word(n);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ConfigVariableInt64::set_value
+//       Access: Published
+//  Description: Reassigns the variable's local value.
+////////////////////////////////////////////////////////////////////
+INLINE void ConfigVariableInt64::
+set_value(PN_int64 value) {
+  set_string_value("");
+  set_int64_word(0, value);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ConfigVariableInt64::get_value
+//       Access: Published
+//  Description: Returns the variable's value.
+////////////////////////////////////////////////////////////////////
+INLINE PN_int64 ConfigVariableInt64::
+get_value() const {
+  TAU_PROFILE("PN_int64 ConfigVariableInt64::get_value() const", " ", TAU_USER);
+  if (!is_cache_valid(_local_modified)) {
+    mark_cache_valid(((ConfigVariableInt64 *)this)->_local_modified);
+    ((ConfigVariableInt64 *)this)->_cache = get_int64_word(0);
+  }
+  return _cache;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ConfigVariableInt64::get_default_value
+//       Access: Published
+//  Description: Returns the variable's default value.
+////////////////////////////////////////////////////////////////////
+INLINE PN_int64 ConfigVariableInt64::
+get_default_value() const {
+  const ConfigDeclaration *decl = ConfigVariable::get_default_value();
+  if (decl != (ConfigDeclaration *)NULL) {
+    return decl->get_int64_word(0);
+  }
+  return 0;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ConfigVariableInt64::get_word
+//       Access: Published
+//  Description: Returns the variable's nth value.
+////////////////////////////////////////////////////////////////////
+INLINE PN_int64 ConfigVariableInt64::
+get_word(int n) const {
+  return get_int64_word(n);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ConfigVariableInt64::set_word
+//       Access: Published
+//  Description: Reassigns the variable's nth value.  This makes a
+//               local copy of the variable's overall value.
+////////////////////////////////////////////////////////////////////
+INLINE void ConfigVariableInt64::
+set_word(int n, PN_int64 value) {
+  set_int64_word(n, value);
+}
+

+ 32 - 0
dtool/src/prc/configVariableInt64.cxx

@@ -0,0 +1,32 @@
+// Filename: configVariableInt64.cxx
+// Created by:  drose (19Dec07)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// aPN_int64 with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#include "configVariableInt64.h"
+
+////////////////////////////////////////////////////////////////////
+//     Function: ConfigVariableInt64::set_default_value
+//       Access: Private
+//  Description: 
+////////////////////////////////////////////////////////////////////
+void ConfigVariableInt64::
+set_default_value(PN_int64 default_value) {
+  ostringstream strm;
+  strm << default_value;
+
+  _core->set_default_value(strm.str());
+}

+ 64 - 0
dtool/src/prc/configVariableInt64.h

@@ -0,0 +1,64 @@
+// Filename: configVariableInt64.h
+// Created by:  drose (19Dec07)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// aint64 with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maint64ainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef CONFIGVARIABLEINT64_H
+#define CONFIGVARIABLEINT64_H
+
+#include "dtoolbase.h"
+#include "configVariable.h"
+#include "numeric_types.h"
+
+////////////////////////////////////////////////////////////////////
+//       Class : ConfigVariableInt64
+// Description : This is a convenience class to specialize
+//               ConfigVariable as a 64-bit integer type.
+////////////////////////////////////////////////////////////////////
+class EXPCL_DTOOLCONFIG ConfigVariableInt64 : public ConfigVariable {
+PUBLISHED:
+  INLINE ConfigVariableInt64(const string &name);
+  INLINE ConfigVariableInt64(const string &name, PN_int64 default_value,
+                             const string &description = string(), 
+                             PN_int64 flags = 0);
+  INLINE ConfigVariableInt64(const string &name, const string &default_value,
+                             const string &description = string(), 
+                             PN_int64 flags = 0);
+
+  INLINE void operator = (PN_int64 value);
+  INLINE operator PN_int64 () const;
+
+  INLINE PN_int64 size() const;
+  INLINE PN_int64 operator [] (int n) const;
+
+  INLINE void set_value(PN_int64 value);
+  INLINE PN_int64 get_value() const;
+  INLINE PN_int64 get_default_value() const;
+
+  INLINE PN_int64 get_word(int n) const;
+  INLINE void set_word(int n, PN_int64 value);
+
+private:
+  void set_default_value(PN_int64 default_value);
+
+private:
+  AtomicAdjust::Integer _local_modified;
+  PN_int64 _cache;
+};
+
+#include "configVariableInt64.I"
+
+#endif

+ 1 - 0
dtool/src/prc/prc_composite1.cxx

@@ -11,4 +11,5 @@
 #include "configVariableEnum.cxx"
 #include "configVariableFilename.cxx"
 #include "configVariableInt.cxx"
+#include "configVariableInt64.cxx"
 #include "configVariableList.cxx"

+ 1 - 0
panda/src/express/config_express.N

@@ -26,6 +26,7 @@ forcetype ConfigVariableBool
 forcetype ConfigVariableDouble
 forcetype ConfigVariableFilename
 forcetype ConfigVariableInt
+forcetype ConfigVariableInt64
 forcetype ConfigVariableList
 forcetype ConfigVariableManager
 forcetype ConfigVariableSearchPath

+ 1 - 0
panda/src/express/config_express.h

@@ -36,6 +36,7 @@
 #include "configVariableDouble.h"
 #include "configVariableFilename.h"
 #include "configVariableInt.h"
+#include "configVariableInt64.h"
 #include "configVariableList.h"
 #include "configVariableManager.h"
 #include "configVariableSearchPath.h"

+ 1 - 1
panda/src/express/memoryUsage.cxx

@@ -400,7 +400,7 @@ MemoryUsage(const MemoryHook &copy) : MemoryHook(copy) {
 
   _count_memory_usage = false;
 
-  int max_heap_size = ConfigVariableInt
+  PN_int64 max_heap_size = ConfigVariableInt64
     ("max-heap-size", 0,
      PRC_DESC("If this is nonzero, it is the maximum number of bytes expected "
               "to be allocated on the heap before we enter report-memory-usage "