458 lines
16 KiB
C++
458 lines
16 KiB
C++
// Filename: dcAtomicField.cxx
|
|
// Created by: drose (05Oct00)
|
|
//
|
|
////////////////////////////////////////////////////////////////////
|
|
//
|
|
// 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
|
|
// along 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
|
|
// panda3d-general@lists.sourceforge.net .
|
|
//
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
#include "dcAtomicField.h"
|
|
#include "hashGenerator.h"
|
|
#include "dcindent.h"
|
|
#include "dcSimpleParameter.h"
|
|
#include "dcPacker.h"
|
|
|
|
#include <math.h>
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: DCAtomicField::ElementType::Constructor
|
|
// Access: Public
|
|
// Description: The type parameter should be a newly-allocated DCParameter
|
|
// object; it will eventually be freed with delete when
|
|
// this object destructs.
|
|
////////////////////////////////////////////////////////////////////
|
|
DCAtomicField::ElementType::
|
|
ElementType(DCParameter *param) {
|
|
_param = param;
|
|
_has_default_value = false;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: DCAtomicField::ElementType::Copy Constructor
|
|
// Access: Public
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
DCAtomicField::ElementType::
|
|
ElementType(const DCAtomicField::ElementType ©) :
|
|
_param(copy._param->make_copy()),
|
|
_default_value(copy._default_value),
|
|
_has_default_value(copy._has_default_value)
|
|
{
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: DCAtomicField::ElementType::Copy Assignment Operator
|
|
// Access: Public
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
void DCAtomicField::ElementType::
|
|
operator = (const DCAtomicField::ElementType ©) {
|
|
delete _param;
|
|
_param = copy._param->make_copy();
|
|
_default_value = copy._default_value;
|
|
_has_default_value = copy._has_default_value;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: DCAtomicField::ElementType::Destructor
|
|
// Access: Public
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
DCAtomicField::ElementType::
|
|
~ElementType() {
|
|
delete _param;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: DCAtomicField::ElementType::set_default_value
|
|
// Access: Public
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
void DCAtomicField::ElementType::
|
|
set_default_value(const string &default_value) {
|
|
_default_value = default_value;
|
|
_has_default_value = true;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: DCAtomicField::ElementType::output
|
|
// Access: Public
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
void DCAtomicField::ElementType::
|
|
output(ostream &out, bool brief) const {
|
|
_param->output(out, brief);
|
|
|
|
if (!brief && _has_default_value) {
|
|
out << " = ";
|
|
DCPacker packer;
|
|
packer.begin_unpack(_default_value, _param);
|
|
packer.unpack_and_format(out);
|
|
packer.end_unpack();
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: DCAtomicField::as_atomic_field
|
|
// Access: Published, Virtual
|
|
// Description: Returns the same field pointer converted to an atomic
|
|
// field pointer, if this is in fact an atomic field;
|
|
// otherwise, returns NULL.
|
|
////////////////////////////////////////////////////////////////////
|
|
DCAtomicField *DCAtomicField::
|
|
as_atomic_field() {
|
|
return this;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: DCAtomicField::get_num_elements
|
|
// Access: Published
|
|
// Description: Returns the number of elements (parameters) of the
|
|
// atomic field.
|
|
////////////////////////////////////////////////////////////////////
|
|
int DCAtomicField::
|
|
get_num_elements() const {
|
|
return _elements.size();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: DCAtomicField::get_element
|
|
// Access: Published
|
|
// Description: Returns the parameter object describing the
|
|
// nth element.
|
|
////////////////////////////////////////////////////////////////////
|
|
DCParameter *DCAtomicField::
|
|
get_element(int n) const {
|
|
nassertr(n >= 0 && n < (int)_elements.size(), NULL);
|
|
return _elements[n]._param;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: DCAtomicField::get_element_default
|
|
// Access: Published
|
|
// 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.
|
|
//
|
|
// If the element is an array-type element, the returned
|
|
// value will include the two-byte length preceding the
|
|
// array data.
|
|
////////////////////////////////////////////////////////////////////
|
|
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: Published
|
|
// 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::get_element_name
|
|
// Access: Published
|
|
// 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.
|
|
//
|
|
// This method is deprecated; use
|
|
// get_element()->get_name() instead.
|
|
////////////////////////////////////////////////////////////////////
|
|
string DCAtomicField::
|
|
get_element_name(int n) const {
|
|
nassertr(n >= 0 && n < (int)_elements.size(), string());
|
|
return _elements[n]._param->get_name();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: DCAtomicField::get_element_type
|
|
// Access: Published
|
|
// Description: Returns the numeric type of the nth element of the
|
|
// field. This method is deprecated; use
|
|
// get_element() instead.
|
|
////////////////////////////////////////////////////////////////////
|
|
DCSubatomicType DCAtomicField::
|
|
get_element_type(int n) const {
|
|
nassertr(n >= 0 && n < (int)_elements.size(), ST_invalid);
|
|
DCSimpleParameter *simple_parameter = _elements[n]._param->as_simple_parameter();
|
|
nassertr(simple_parameter != (DCSimpleParameter *)NULL, ST_invalid);
|
|
return simple_parameter->get_type();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: DCAtomicField::get_element_divisor
|
|
// Access: Published
|
|
// Description: Returns the divisor associated with the nth element
|
|
// of the field. This implements an implicit
|
|
// fixed-point system; floating-point values are to be
|
|
// multiplied by this value before encoding into a
|
|
// packet, and divided by this number after decoding.
|
|
//
|
|
// This method is deprecated; use
|
|
// get_element()->get_divisor() instead.
|
|
////////////////////////////////////////////////////////////////////
|
|
int DCAtomicField::
|
|
get_element_divisor(int n) const {
|
|
nassertr(n >= 0 && n < (int)_elements.size(), 1);
|
|
DCSimpleParameter *simple_parameter = _elements[n]._param->as_simple_parameter();
|
|
nassertr(simple_parameter != (DCSimpleParameter *)NULL, 1);
|
|
return simple_parameter->get_divisor();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: DCAtomicField::is_required
|
|
// Access: Published
|
|
// Description: Returns true if the "required" flag is set for this
|
|
// field, false otherwise.
|
|
////////////////////////////////////////////////////////////////////
|
|
bool DCAtomicField::
|
|
is_required() const {
|
|
return (_flags & F_required) != 0;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: DCAtomicField::is_broadcast
|
|
// Access: Published
|
|
// Description: Returns true if the "broadcast" flag is set for this
|
|
// field, false otherwise.
|
|
////////////////////////////////////////////////////////////////////
|
|
bool DCAtomicField::
|
|
is_broadcast() const {
|
|
return (_flags & F_broadcast) != 0;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: DCAtomicField::is_p2p
|
|
// Access: Published
|
|
// Description: Returns true if the "p2p" flag is set for this
|
|
// field, false otherwise.
|
|
////////////////////////////////////////////////////////////////////
|
|
bool DCAtomicField::
|
|
is_p2p() const {
|
|
return (_flags & F_p2p) != 0;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: DCAtomicField::is_ram
|
|
// Access: Published
|
|
// Description: Returns true if the "ram" flag is set for this
|
|
// field, false otherwise.
|
|
////////////////////////////////////////////////////////////////////
|
|
bool DCAtomicField::
|
|
is_ram() const {
|
|
return (_flags & F_ram) != 0;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: DCAtomicField::is_db
|
|
// Access: Published
|
|
// Description: Returns true if the "db" flag is set for this
|
|
// field, false otherwise.
|
|
////////////////////////////////////////////////////////////////////
|
|
bool DCAtomicField::
|
|
is_db() const {
|
|
return (_flags & F_db) != 0;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: DCAtomicField::is_clsend
|
|
// Access: Published
|
|
// Description: Returns true if the "clsend" flag is set for this
|
|
// field, false otherwise.
|
|
////////////////////////////////////////////////////////////////////
|
|
bool DCAtomicField::
|
|
is_clsend() const {
|
|
return (_flags & F_clsend) != 0;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: DCAtomicField::is_clrecv
|
|
// Access: Published
|
|
// Description: Returns true if the "clrecv" flag is set for this
|
|
// field, false otherwise.
|
|
////////////////////////////////////////////////////////////////////
|
|
bool DCAtomicField::
|
|
is_clrecv() const {
|
|
return (_flags & F_clrecv) != 0;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: DCAtomicField::is_ownsend
|
|
// Access: Published
|
|
// Description: Returns true if the "ownsend" flag is set for this
|
|
// field, false otherwise.
|
|
////////////////////////////////////////////////////////////////////
|
|
bool DCAtomicField::
|
|
is_ownsend() const {
|
|
return (_flags & F_ownsend) != 0;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: DCAtomicField::is_airecv
|
|
// Access: Published
|
|
// Description: Returns true if the "airecv" flag is set for this
|
|
// field, false otherwise.
|
|
////////////////////////////////////////////////////////////////////
|
|
bool DCAtomicField::
|
|
is_airecv() const {
|
|
return (_flags & F_airecv) != 0;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: DCAtomicField::compare_flags
|
|
// Access: Published
|
|
// Description: Returns true if this field has the same flags
|
|
// settings as the other field, false if some flags
|
|
// differ.
|
|
////////////////////////////////////////////////////////////////////
|
|
bool DCAtomicField::
|
|
compare_flags(const DCAtomicField &other) const {
|
|
return _flags == other._flags;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: DCAtomicField::Constructor
|
|
// Access: Public
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
DCAtomicField::
|
|
DCAtomicField(const string &name) : DCField(name) {
|
|
_flags = 0;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: DCAtomicField::write
|
|
// Access: Public, Virtual
|
|
// Description: Generates a parseable description of the object to
|
|
// the indicated output stream.
|
|
////////////////////////////////////////////////////////////////////
|
|
void DCAtomicField::
|
|
write(ostream &out, bool brief, int indent_level) const {
|
|
indent(out, indent_level)
|
|
<< _name << "(";
|
|
|
|
if (!_elements.empty()) {
|
|
Elements::const_iterator ei = _elements.begin();
|
|
(*ei).output(out, brief);
|
|
++ei;
|
|
while (ei != _elements.end()) {
|
|
out << ", ";
|
|
(*ei).output(out, brief);
|
|
++ei;
|
|
}
|
|
}
|
|
out << ")";
|
|
|
|
if ((_flags & F_required) != 0) {
|
|
out << " required";
|
|
}
|
|
if ((_flags & F_broadcast) != 0) {
|
|
out << " broadcast";
|
|
}
|
|
if ((_flags & F_p2p) != 0) {
|
|
out << " p2p";
|
|
}
|
|
if ((_flags & F_ram) != 0) {
|
|
out << " ram";
|
|
}
|
|
if ((_flags & F_db) != 0) {
|
|
out << " db";
|
|
}
|
|
if ((_flags & F_clsend) != 0) {
|
|
out << " clsend";
|
|
}
|
|
if ((_flags & F_clrecv) != 0) {
|
|
out << " clrecv";
|
|
}
|
|
if ((_flags & F_ownsend) != 0) {
|
|
out << " ownsend";
|
|
}
|
|
if ((_flags & F_airecv) != 0) {
|
|
out << " airecv";
|
|
}
|
|
|
|
out << ";";
|
|
if (!brief) {
|
|
out << " // field " << _number;
|
|
}
|
|
out << "\n";
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: DCAtomicField::generate_hash
|
|
// Access: Public, Virtual
|
|
// Description: Accumulates the properties of this field into the
|
|
// hash.
|
|
////////////////////////////////////////////////////////////////////
|
|
void DCAtomicField::
|
|
generate_hash(HashGenerator &hashgen) const {
|
|
DCField::generate_hash(hashgen);
|
|
|
|
hashgen.add_int(_elements.size());
|
|
Elements::const_iterator ei;
|
|
for (ei = _elements.begin(); ei != _elements.end(); ++ei) {
|
|
const ElementType &element = (*ei);
|
|
element._param->generate_hash(hashgen);
|
|
}
|
|
hashgen.add_int(_flags);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: DCAtomicField::get_nested_field
|
|
// Access: Public, Virtual
|
|
// Description: Returns the DCPackerInterface object that represents
|
|
// the nth nested field. This may return NULL if there
|
|
// is no such field (but it shouldn't do this if n is in
|
|
// the range 0 <= n < get_num_nested_fields()).
|
|
////////////////////////////////////////////////////////////////////
|
|
DCPackerInterface *DCAtomicField::
|
|
get_nested_field(int n) const {
|
|
nassertr(n >= 0 && n < (int)_elements.size(), NULL);
|
|
return _elements[n]._param;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: DCAtomicField::add_element
|
|
// Access: Public
|
|
// Description: Adds a new element (parameter) to the field.
|
|
// Normally this is called only during parsing.
|
|
////////////////////////////////////////////////////////////////////
|
|
void DCAtomicField::
|
|
add_element(const DCAtomicField::ElementType &element) {
|
|
_elements.push_back(element);
|
|
_num_nested_fields = (int)_elements.size();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: DCAtomicField::add_flag
|
|
// Access: Public
|
|
// Description: Adds a new flag to the field.
|
|
////////////////////////////////////////////////////////////////////
|
|
void DCAtomicField::
|
|
add_flag(enum Flags flag) {
|
|
_flags |= flag;
|
|
}
|