mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 02:42:49 -04:00
*** empty log message ***
This commit is contained in:
parent
c47d83286d
commit
121fb2faa3
@ -3,8 +3,8 @@
|
||||
dclass Movable {
|
||||
|
||||
// Declare a few atomic fields
|
||||
set_xyz(int16 / 1000, int16 / 1000, int16 / 1000) required broadcast ram;
|
||||
set_hpr(int16, int16, int16) required broadcast ram;
|
||||
set_xyz(int16 x = 1024 / 1000, int16 y / 1000 = 1.024, int16 z / 1000 = 0.512) required broadcast ram;
|
||||
set_hpr(int16 h, int16 p , int16 r = 0) required broadcast ram;
|
||||
|
||||
// And a molecular field
|
||||
set_xyzhpr : set_xyz, set_hpr;
|
||||
@ -14,7 +14,7 @@ dclass Movable {
|
||||
dclass Attitude : Movable {
|
||||
// methods are inherited from parent class.
|
||||
|
||||
set_attitude(int8) required broadcast ram;
|
||||
set_attitude(int16array attitude = { 1 * 3 }) required broadcast ram;
|
||||
|
||||
// This molecular field uses some inherited atomic fields.
|
||||
set_xyzhprattitude : set_xyz, set_hpr, set_attitude;
|
||||
|
@ -6,6 +6,7 @@
|
||||
directbase
|
||||
#define YACC_PREFIX dcyy
|
||||
#define C++FLAGS -DWITHIN_PANDA
|
||||
#define UNIX_SYS_LIBS m
|
||||
|
||||
#begin lib_target
|
||||
#define TARGET dcparser
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "hashGenerator.h"
|
||||
#include "dcindent.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
ostream &
|
||||
operator << (ostream &out, const DCAtomicField::ElementType &et) {
|
||||
@ -14,9 +15,281 @@ operator << (ostream &out, const DCAtomicField::ElementType &et) {
|
||||
if (et._divisor != 1) {
|
||||
out << " / " << et._divisor;
|
||||
}
|
||||
if (!et._name.empty()) {
|
||||
out << " " << et._name;
|
||||
}
|
||||
if (et._has_default_value) {
|
||||
out << " = <" << hex;
|
||||
string::const_iterator si;
|
||||
for (si = et._default_value.begin(); si != et._default_value.end(); ++si) {
|
||||
out << setw(2) << setfill('0') << (int)(unsigned char)(*si);
|
||||
}
|
||||
out << dec << ">";
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCAtomicField::ElementType::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
DCAtomicField::ElementType::
|
||||
ElementType() {
|
||||
_type = ST_invalid;
|
||||
_divisor = 1;
|
||||
_has_default_value = false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCAtomicField::ElementType::set_default_value
|
||||
// Access: Public
|
||||
// Description: Stores the indicated value as the default value for
|
||||
// this element.
|
||||
//
|
||||
// Returns true if the element type reasonably accepts a
|
||||
// default value of numeric type, false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool DCAtomicField::ElementType::
|
||||
set_default_value(double num) {
|
||||
switch (_type) {
|
||||
case ST_int16array:
|
||||
case ST_uint16array:
|
||||
case ST_int32array:
|
||||
case ST_uint32array:
|
||||
case ST_blob:
|
||||
// These array types don't take numbers.
|
||||
return false;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
string formatted;
|
||||
if (!format_default_value(num, formatted)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
_default_value = formatted;
|
||||
_has_default_value = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCAtomicField::ElementType::set_default_value
|
||||
// Access: Public
|
||||
// Description: Stores the indicated value as the default value for
|
||||
// this element.
|
||||
//
|
||||
// Returns true if the element type reasonably accepts a
|
||||
// default value of string type, false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool DCAtomicField::ElementType::
|
||||
set_default_value(const string &str) {
|
||||
switch (_type) {
|
||||
case ST_int16array:
|
||||
case ST_uint16array:
|
||||
case ST_int32array:
|
||||
case ST_uint32array:
|
||||
// These array types don't take strings.
|
||||
return false;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
string formatted;
|
||||
if (!format_default_value(str, formatted)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
_default_value = formatted;
|
||||
_has_default_value = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCAtomicField::ElementType::set_default_value_literal
|
||||
// Access: Public
|
||||
// Description: Explicitly sets the default value to the given
|
||||
// pre-formatted string.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DCAtomicField::ElementType::
|
||||
set_default_value_literal(const string &str) {
|
||||
_default_value = str;
|
||||
_has_default_value = true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCAtomicField::ElementType::add_default_value
|
||||
// Access: Public
|
||||
// Description: Appends the indicated value as the next array element
|
||||
// value for the default value for this type.
|
||||
//
|
||||
// Returns true if the element type reasonably accepts a
|
||||
// default value of numeric type, false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool DCAtomicField::ElementType::
|
||||
add_default_value(double num) {
|
||||
string formatted;
|
||||
if (!format_default_value(num, formatted)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
_default_value += formatted;
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCAtomicField::ElementType::end_array
|
||||
// Access: Public
|
||||
// Description: Called by the parser after a number of calls to
|
||||
// add_default_value(), to indicate the array has been
|
||||
// completed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool DCAtomicField::ElementType::
|
||||
end_array() {
|
||||
switch (_type) {
|
||||
case ST_int16array:
|
||||
case ST_uint16array:
|
||||
case ST_int32array:
|
||||
case ST_uint32array:
|
||||
case ST_blob:
|
||||
{
|
||||
// We've accumulated all the elements of the array; now we must
|
||||
// prepend the array length.
|
||||
int length = _default_value.length();
|
||||
_default_value =
|
||||
string(1, (char)(length & 0xff)) +
|
||||
string(1, (char)((length >> 8) & 0xff)) +
|
||||
_default_value;
|
||||
}
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCAtomicField::ElementType::format_default_value
|
||||
// Access: Private
|
||||
// Description: Formats the indicated default value to a sequence of
|
||||
// bytes, according to the element type. Returns true
|
||||
// if the element type reasonably accepts a number,
|
||||
// false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool DCAtomicField::ElementType::
|
||||
format_default_value(double num, string &formatted) const {
|
||||
double real_value = num * _divisor;
|
||||
int int_value = (int)floor(real_value + 0.5);
|
||||
|
||||
switch (_type) {
|
||||
case ST_int8:
|
||||
case ST_uint8:
|
||||
case ST_blob:
|
||||
formatted = string(1, (char)(int_value & 0xff));
|
||||
break;
|
||||
|
||||
case ST_int16:
|
||||
case ST_uint16:
|
||||
case ST_int16array:
|
||||
case ST_uint16array:
|
||||
formatted =
|
||||
string(1, (char)(int_value & 0xff)) +
|
||||
string(1, (char)((int_value >> 8) & 0xff));
|
||||
break;
|
||||
|
||||
case ST_int32:
|
||||
case ST_uint32:
|
||||
case ST_int32array:
|
||||
case ST_uint32array:
|
||||
formatted =
|
||||
string(1, (char)(int_value & 0xff)) +
|
||||
string(1, (char)((int_value >> 8) & 0xff)) +
|
||||
string(1, (char)((int_value >> 16) & 0xff)) +
|
||||
string(1, (char)((int_value >> 24) & 0xff));
|
||||
break;
|
||||
|
||||
case ST_int64:
|
||||
// We don't fully support default values for int64. The
|
||||
// high-order 32 bits cannot be specified.
|
||||
formatted =
|
||||
string(1, (char)(int_value & 0xff)) +
|
||||
string(1, (char)((int_value >> 8) & 0xff)) +
|
||||
string(1, (char)((int_value >> 16) & 0xff)) +
|
||||
string(1, (char)((int_value >> 24) & 0xff)) +
|
||||
((int_value & 0x80000000) != 0 ? string(4, '\xff') : string(4, '\0'));
|
||||
break;
|
||||
|
||||
case ST_uint64:
|
||||
// We don't fully support default values for int64. The
|
||||
// high-order 32 bits cannot be specified.
|
||||
formatted =
|
||||
string(1, (char)(int_value & 0xff)) +
|
||||
string(1, (char)((int_value >> 8) & 0xff)) +
|
||||
string(1, (char)((int_value >> 16) & 0xff)) +
|
||||
string(1, (char)((int_value >> 24) & 0xff)) +
|
||||
string(4, '\0');
|
||||
break;
|
||||
|
||||
case ST_float64:
|
||||
// This may not be fully portable.
|
||||
formatted = string((char *)&real_value, 8);
|
||||
#ifdef IS_BIG_ENDIAN
|
||||
{
|
||||
// Reverse the byte ordering for big-endian machines.
|
||||
string str;
|
||||
str = reserve(8);
|
||||
|
||||
for (size_t i = 0; i < 8; i++) {
|
||||
str += formatted[length - 1 - i];
|
||||
}
|
||||
formatted = str;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
||||
case ST_string:
|
||||
// It doesn't make sense to assign a numeric default value to a
|
||||
// string.
|
||||
return false;
|
||||
|
||||
case ST_invalid:
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCAtomicField::ElementType::format_default_value
|
||||
// Access: Private
|
||||
// Description: Formats the indicated default value to a sequence of
|
||||
// bytes, according to the element type. Returns true
|
||||
// if the element type reasonably accepts a string,
|
||||
// false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool DCAtomicField::ElementType::
|
||||
format_default_value(const string &str, string &formatted) const {
|
||||
switch (_type) {
|
||||
case ST_string:
|
||||
case ST_blob:
|
||||
{
|
||||
int length = str.length();
|
||||
formatted =
|
||||
string(1, (char)(length & 0xff)) +
|
||||
string(1, (char)((length >> 8) & 0xff)) +
|
||||
str;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// It doesn't make sense to assign a string default to a number.
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCAtomicField::as_atomic_field
|
||||
// Access: Public, Virtual
|
||||
@ -51,6 +324,20 @@ get_element_type(int n) const {
|
||||
return _elements[n]._type;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCAtomicField::get_element_name
|
||||
// Access: Public
|
||||
// Description: Returns the name of the nth element of the field.
|
||||
// This name is strictly for documentary purposes; it
|
||||
// does not generally affect operation. If a name is
|
||||
// not specified, this will be the empty string.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
string DCAtomicField::
|
||||
get_element_name(int n) const {
|
||||
nassertr(n >= 0 && n < (int)_elements.size(), string());
|
||||
return _elements[n]._name;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCAtomicField::get_element_divisor
|
||||
// Access: Public
|
||||
@ -66,6 +353,34 @@ get_element_divisor(int n) const {
|
||||
return _elements[n]._divisor;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCAtomicField::get_element_default
|
||||
// Access: Public
|
||||
// Description: Returns the pre-formatted default value associated
|
||||
// with the nth element of the field. This is only
|
||||
// valid if has_element_default() returns true, in which
|
||||
// case this string represents the bytes that should be
|
||||
// assigned to the field as a default value.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
string DCAtomicField::
|
||||
get_element_default(int n) const {
|
||||
nassertr(has_element_default(n), string());
|
||||
nassertr(n >= 0 && n < (int)_elements.size(), string());
|
||||
return _elements[n]._default_value;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCAtomicField::has_element_default
|
||||
// Access: Public
|
||||
// Description: Returns true if the nth element of the field has a
|
||||
// default value specified, false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool DCAtomicField::
|
||||
has_element_default(int n) const {
|
||||
nassertr(n >= 0 && n < (int)_elements.size(), false);
|
||||
return _elements[n]._has_default_value;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCAtomicField::is_required
|
||||
// Access: Public
|
||||
|
@ -25,7 +25,10 @@ PUBLISHED:
|
||||
|
||||
int get_num_elements() const;
|
||||
DCSubatomicType get_element_type(int n) const;
|
||||
string get_element_name(int n) const;
|
||||
int get_element_divisor(int n) const;
|
||||
string get_element_default(int n) const;
|
||||
bool has_element_default(int n) const;
|
||||
|
||||
bool is_required() const;
|
||||
bool is_broadcast() const;
|
||||
@ -46,8 +49,23 @@ public:
|
||||
// definition as read from the file.
|
||||
class ElementType {
|
||||
public:
|
||||
ElementType();
|
||||
bool set_default_value(double num);
|
||||
bool set_default_value(const string &str);
|
||||
void set_default_value_literal(const string &str);
|
||||
|
||||
bool add_default_value(double num);
|
||||
bool end_array();
|
||||
|
||||
DCSubatomicType _type;
|
||||
string _name;
|
||||
int _divisor;
|
||||
string _default_value;
|
||||
bool _has_default_value;
|
||||
|
||||
private:
|
||||
bool format_default_value(double num, string &formatted) const;
|
||||
bool format_default_value(const string &str, string &formatted) const;
|
||||
};
|
||||
|
||||
typedef vector<ElementType> Elements;
|
||||
|
@ -188,6 +188,66 @@ scan_quoted_string() {
|
||||
return result;
|
||||
}
|
||||
|
||||
// scan_hex_string reads a string of hexadecimal digits delimited by
|
||||
// angle brackets and returns the representative string.
|
||||
static string
|
||||
scan_hex_string() {
|
||||
string result;
|
||||
|
||||
// We don't touch the current line number and column number during
|
||||
// scanning, so that if we detect an error while scanning the string
|
||||
// (e.g. an unterminated string), we'll report the error as
|
||||
// occurring at the start of the string, not at the end--somewhat
|
||||
// more convenient for the user.
|
||||
|
||||
// Instead of adjusting the global line_number and col_number
|
||||
// variables, we'll operate on our own local variables for the
|
||||
// interim.
|
||||
int line = line_number;
|
||||
int col = col_number;
|
||||
|
||||
bool odd = false;
|
||||
int last = 0;
|
||||
int c;
|
||||
c = read_char(line, col);
|
||||
while (c != '>' && c != EOF) {
|
||||
int value;
|
||||
if (c >= '0' && c <= '9') {
|
||||
value = c - '0';
|
||||
} else if (c >= 'a' && c <= 'f') {
|
||||
value = c - 'a' + 10;
|
||||
} else if (c >= 'A' && c <= 'F') {
|
||||
value = c - 'A' + 10;
|
||||
} else {
|
||||
line_number = line;
|
||||
col_number = col;
|
||||
dcyyerror("Invalid hex digit.");
|
||||
return string();
|
||||
}
|
||||
|
||||
odd = !odd;
|
||||
if (odd) {
|
||||
last = value;
|
||||
} else {
|
||||
result += (char)((last << 4) | value);
|
||||
}
|
||||
c = read_char(line, col);
|
||||
}
|
||||
|
||||
if (c == EOF) {
|
||||
dcyyerror("This hex string is unterminated.");
|
||||
return string();
|
||||
} else if (odd) {
|
||||
dcyyerror("Odd number of hex digits.");
|
||||
return string();
|
||||
}
|
||||
|
||||
line_number = line;
|
||||
col_number = col;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// eat_c_comment scans past all characters up until the first */
|
||||
// encountered.
|
||||
static void
|
||||
@ -229,6 +289,7 @@ inline void accept() {
|
||||
%}
|
||||
|
||||
INTEGERNUM ([+-]?([0-9]+))
|
||||
HEXNUM 0x[0-9a-fA-F]*
|
||||
REALNUM ([+-]?(([0-9]+[.])|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
|
||||
|
||||
%%
|
||||
@ -403,6 +464,14 @@ mol[0-9]+ {
|
||||
return INTEGER;
|
||||
}
|
||||
|
||||
{HEXNUM} {
|
||||
// A hexadecimal integer number.
|
||||
accept();
|
||||
dcyylval.u.integer = strtoul(yytext+2, NULL, 16);
|
||||
dcyylval.str = yytext;
|
||||
return INTEGER;
|
||||
}
|
||||
|
||||
{REALNUM} {
|
||||
// A floating-point number.
|
||||
accept();
|
||||
@ -418,6 +487,13 @@ mol[0-9]+ {
|
||||
return STRING;
|
||||
}
|
||||
|
||||
[<] {
|
||||
// Long hex string.
|
||||
accept();
|
||||
dcyylval.str = scan_hex_string();
|
||||
return HEX_STRING;
|
||||
}
|
||||
|
||||
[A-Za-z_][A-Za-z_0-9]* {
|
||||
// Identifier.
|
||||
accept();
|
||||
|
@ -23,6 +23,7 @@ static DCFile *dc_file = (DCFile *)NULL;
|
||||
static DCClass *current_class = (DCClass *)NULL;
|
||||
static DCAtomicField *current_atomic = (DCAtomicField *)NULL;
|
||||
static DCMolecularField *current_molecular = (DCMolecularField *)NULL;
|
||||
static DCAtomicField::ElementType atomic_element;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Defining the interface to the parser.
|
||||
@ -43,7 +44,7 @@ dc_cleanup_parser() {
|
||||
|
||||
%token <u.integer> INTEGER
|
||||
%token <u.real> REAL
|
||||
%token <str> STRING IDENTIFIER
|
||||
%token <str> STRING HEX_STRING IDENTIFIER
|
||||
|
||||
%token KW_DCLASS
|
||||
|
||||
@ -171,27 +172,112 @@ parameter_list:
|
||||
;
|
||||
|
||||
nonempty_parameter_list:
|
||||
subatomic_type
|
||||
| nonempty_parameter_list ',' subatomic_type
|
||||
atomic_element
|
||||
| nonempty_parameter_list ',' atomic_element
|
||||
;
|
||||
|
||||
subatomic_type:
|
||||
type_token
|
||||
atomic_element:
|
||||
type_token
|
||||
{
|
||||
DCAtomicField::ElementType et;
|
||||
et._type = $1;
|
||||
et._divisor = 1;
|
||||
current_atomic->_elements.push_back(et);
|
||||
atomic_element = DCAtomicField::ElementType();
|
||||
atomic_element._type = $1;
|
||||
}
|
||||
| type_token '/' INTEGER
|
||||
atomic_element_definition
|
||||
{
|
||||
DCAtomicField::ElementType et;
|
||||
et._type = $1;
|
||||
et._divisor = $3;
|
||||
current_atomic->_elements.push_back(et);
|
||||
current_atomic->_elements.push_back(atomic_element)
|
||||
}
|
||||
;
|
||||
|
||||
atomic_element_definition:
|
||||
empty
|
||||
| atomic_element_definition '/' INTEGER
|
||||
{
|
||||
atomic_element._divisor = $3;
|
||||
}
|
||||
| atomic_element_definition IDENTIFIER
|
||||
{
|
||||
atomic_element._name = $2;
|
||||
}
|
||||
| atomic_element_definition '=' INTEGER
|
||||
{
|
||||
if (!atomic_element.set_default_value($3)) {
|
||||
yyerror("Invalid default value: " + $<str>3);
|
||||
}
|
||||
}
|
||||
| atomic_element_definition '=' REAL
|
||||
{
|
||||
if (!atomic_element.set_default_value($3)) {
|
||||
yyerror("Invalid default value: " + $<str>3);
|
||||
}
|
||||
}
|
||||
| atomic_element_definition '=' STRING
|
||||
{
|
||||
if (!atomic_element.set_default_value($3)) {
|
||||
yyerror("Invalid default value: \"" + $3 + "\"");
|
||||
}
|
||||
}
|
||||
| atomic_element_definition '=' HEX_STRING
|
||||
{
|
||||
atomic_element.set_default_value($3);
|
||||
}
|
||||
| atomic_element_definition '=' '{' default_array '}'
|
||||
{
|
||||
if (!atomic_element.end_array()) {
|
||||
yyerror("Array default value inappropriate");
|
||||
} else {
|
||||
atomic_element._has_default_value = true;
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
default_array:
|
||||
empty
|
||||
| default_array_def maybe_comma
|
||||
;
|
||||
|
||||
maybe_comma:
|
||||
empty
|
||||
| ','
|
||||
;
|
||||
|
||||
default_array_def:
|
||||
default_array_element
|
||||
| default_array_def ',' default_array_element
|
||||
;
|
||||
|
||||
default_array_element:
|
||||
INTEGER
|
||||
{
|
||||
if (!atomic_element.add_default_value($1)) {
|
||||
yyerror("Invalid default value: " + $<str>1);
|
||||
}
|
||||
}
|
||||
| REAL
|
||||
{
|
||||
if (!atomic_element.add_default_value($1)) {
|
||||
yyerror("Invalid default value: " + $<str>1);
|
||||
}
|
||||
}
|
||||
| INTEGER '*' INTEGER
|
||||
{
|
||||
for (int i = 0; i < $3; i++) {
|
||||
if (!atomic_element.add_default_value($1)) {
|
||||
yyerror("Invalid default value: " + $<str>1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
| REAL '*' INTEGER
|
||||
{
|
||||
for (int i = 0; i < $3; i++) {
|
||||
if (!atomic_element.add_default_value($1)) {
|
||||
yyerror("Invalid default value: " + $<str>1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
type_token:
|
||||
KW_INT8
|
||||
{
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include <directbase.h>
|
||||
#include <notify.h>
|
||||
#include <filename.h>
|
||||
#include <numeric_types.h>
|
||||
|
||||
#else
|
||||
|
||||
@ -75,6 +76,14 @@ using namespace std;
|
||||
// string instead.
|
||||
typedef string Filename;
|
||||
|
||||
// Panda defines IS_BIG_ENDIAN or IS_LITTLE_ENDIAN as appropriate.
|
||||
// Outside of panda, you'll have to do it yourself. If neither is
|
||||
// defined, we'll assume IS_LITTLE_ENDIAN.
|
||||
#if !defined(IS_BIG_ENDIAN) && !defined(IS_LITTLE_ENDIAN)
|
||||
#define IS_LITTLE_ENDIAN
|
||||
#endif
|
||||
|
||||
|
||||
#endif // WITHIN_PANDA
|
||||
|
||||
#endif // DCBASE_H
|
||||
|
@ -7,18 +7,15 @@
|
||||
#include "primeNumberGenerator.h"
|
||||
|
||||
// We multiply each consecutive integer by the next prime number and
|
||||
// add it to the total, so in theory we will truly generate a unique
|
||||
// hash number for each unique sequence of ints, as long as the number
|
||||
// of ints does not exceed the number of prime numbers we have, and we
|
||||
// do not overflow the limits of a 32-bit integer.
|
||||
// add it to the total. This will generate pretty evenly-distributed
|
||||
// hash numbers for an arbitrary sequence of ints.
|
||||
|
||||
// We do recycle the prime number table at some point, just to keep it
|
||||
// from growing insanely large, however, and we also truncate
|
||||
// everything to the low-order 32 bits, so we introduce ambiguity in
|
||||
// this way.
|
||||
// from growing insanely large, however (and to avoid wasting time
|
||||
// computing large prime numbers unnecessarily), and we also truncate
|
||||
// the result to the low-order 32 bits.
|
||||
|
||||
static const int max_prime_numbers = 10000;
|
||||
static PrimeNumberGenerator primes;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HashGenerator::Constructor
|
||||
@ -39,7 +36,7 @@ HashGenerator() {
|
||||
void HashGenerator::
|
||||
add_int(int num) {
|
||||
nassertv(_index >= 0 && _index < max_prime_numbers);
|
||||
_hash += (int)primes[_index] * num;
|
||||
_hash += _primes[_index] * num;
|
||||
_index = (_index + 1) % max_prime_numbers;
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,7 @@
|
||||
#define DCHASHGENERATOR_H
|
||||
|
||||
#include "dcbase.h"
|
||||
#include "primeNumberGenerator.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : HashGenerator
|
||||
@ -25,6 +26,7 @@ public:
|
||||
private:
|
||||
long _hash;
|
||||
int _index;
|
||||
PrimeNumberGenerator _primes;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user