Merge tag 'v1.10.0' into astron-master

SDK 1.10.0 release
This commit is contained in:
Sam Edwards 2019-01-04 06:53:37 -07:00
commit ffe4f387ae
359 changed files with 21353 additions and 8711 deletions

View File

@ -49,7 +49,7 @@ script:
notifications:
irc:
channels:
- "chat.freenode.net#panda3d"
- secure: "jfwHT9RHAVOGRGTMY8TpYKJI6rq8nFoIj41Y0soZdJQNWtSSFEK9AyzZeMY+2dHga7cR/X+/0NWZ2ehhedTnd9FvlzOnMWWC3K0I/b3XWbEdVEqIZnggFkKGqs82Gy3omguRC63yWupeJCcSCckIhoWbLzWy6xV8lF5WC80iXi8="
on_success: change
on_failure: always
use_notice: true

View File

@ -55,8 +55,8 @@ depending on whether you are on a 32-bit or 64-bit system, or you can
[click here](https://github.com/rdb/panda3d-thirdparty) for instructions on
building them from source.
http://rdb.name/thirdparty-vc14-x64.7z
http://rdb.name/thirdparty-vc14.7z
https://www.panda3d.org/download/panda3d-1.10.0/panda3d-1.10.0-tools-win64.zip
https://www.panda3d.org/download/panda3d-1.10.0/panda3d-1.10.0-tools-win32.zip
After acquiring these dependencies, you may simply build Panda3D from the
command prompt using the following command. (Change `14.1` to `14` if you are

Binary file not shown.

Before

Width:  |  Height:  |  Size: 281 KiB

After

Width:  |  Height:  |  Size: 144 KiB

View File

@ -653,15 +653,11 @@ class Actor(DirectObject, NodePath):
"""
# make sure we don't call this twice in a row
# and pollute the the switches dictionary
## sortedKeys = list(self.switches.keys())
## sortedKeys.sort()
child = self.__LODNode.find(str(lodName))
index = self.__LODNode.node().findChild(child.node())
self.__LODNode.node().forceSwitch(index)
def printLOD(self):
## sortedKeys = list(self.switches.keys())
## sortedKeys.sort()
sortedKeys = self.__sortedLODNames
for eachLod in sortedKeys:
print("python switches for %s: in: %d, out %d" % (eachLod,
@ -679,12 +675,6 @@ class Actor(DirectObject, NodePath):
"""
Restore all switch distance info (usually after a useLOD call)"""
self.__LODNode.node().clearForceSwitch()
## sortedKeys = list(self.switches.keys())
## sortedKeys.sort()
## for eachLod in sortedKeys:
## index = sortedKeys.index(eachLod)
## self.__LODNode.node().setSwitch(index, self.switches[eachLod][0],
## self.switches[eachLod][1])
def addLOD(self, lodName, inDist=0, outDist=0, center=None):
"""addLOD(self, string)
@ -706,8 +696,6 @@ class Actor(DirectObject, NodePath):
# save the switch distance info
self.switches[lodName] = [inDist, outDist]
# add the switch distance info
## sortedKeys = list(self.switches.keys())
## sortedKeys.sort()
self.__LODNode.node().setSwitch(self.getLODIndex(lodName), inDist, outDist)
def getLODIndex(self, lodName):

View File

@ -262,6 +262,38 @@ pack_string(DCPackData &pack_data, const string &value,
}
}
/**
* Packs the indicated numeric or string value into the stream.
*/
void DCArrayParameter::
pack_blob(DCPackData &pack_data, const vector_uchar &value,
bool &pack_error, bool &range_error) const {
// We can only pack a string if the array element type is char or int8.
DCSimpleParameter *simple_type = _element_type->as_simple_parameter();
if (simple_type == nullptr) {
pack_error = true;
return;
}
size_t blob_size = value.size();
switch (simple_type->get_type()) {
case ST_char:
case ST_uint8:
case ST_int8:
_array_size_range.validate(blob_size, range_error);
if (_num_length_bytes != 0) {
nassertv(_num_length_bytes == 2);
do_pack_uint16(pack_data.get_write_pointer(2), blob_size);
}
pack_data.append_data((const char *)value.data(), blob_size);
break;
default:
pack_error = true;
}
}
/**
* Packs the arrayParameter's specified default value (or a sensible default
* if no value is specified) into the stream. Returns true if the default
@ -339,6 +371,46 @@ unpack_string(const char *data, size_t length, size_t &p, string &value,
}
}
/**
* Unpacks the current numeric or string value from the stream.
*/
void DCArrayParameter::
unpack_blob(const char *data, size_t length, size_t &p, vector_uchar &value,
bool &pack_error, bool &range_error) const {
// We can only unpack a string if the array element type is char or int8.
DCSimpleParameter *simple_type = _element_type->as_simple_parameter();
if (simple_type == nullptr) {
pack_error = true;
return;
}
size_t blob_size;
switch (simple_type->get_type()) {
case ST_char:
case ST_uint8:
case ST_int8:
if (_num_length_bytes != 0) {
blob_size = do_unpack_uint16(data + p);
p += 2;
} else {
nassertv(_array_size >= 0);
blob_size = _array_size;
}
if (p + blob_size > length) {
pack_error = true;
return;
}
value = vector_uchar((const unsigned char *)data + p,
(const unsigned char *)data + p + blob_size);
p += blob_size;
break;
default:
pack_error = true;
}
}
/**
* Returns true if the other interface is bitwise the same as this one--that
* is, a uint32 only matches a uint32, etc. Names of components, and range

View File

@ -51,9 +51,13 @@ public:
virtual void generate_hash(HashGenerator &hashgen) const;
virtual void pack_string(DCPackData &pack_data, const std::string &value,
bool &pack_error, bool &range_error) const;
virtual void pack_blob(DCPackData &pack_data, const vector_uchar &value,
bool &pack_error, bool &range_error) const;
virtual bool pack_default_value(DCPackData &pack_data, bool &pack_error) const;
virtual void unpack_string(const char *data, size_t length, size_t &p,
std::string &value, bool &pack_error, bool &range_error) const;
virtual void unpack_blob(const char *data, size_t length, size_t &p,
vector_uchar &value, bool &pack_error, bool &range_error) const;
protected:
virtual bool do_check_match(const DCPackerInterface *other) const;

View File

@ -88,11 +88,11 @@ get_element(int n) const {
* If the element is an array-type element, the returned value will include
* the two-byte length preceding the array data.
*
* This is deprecated; use get_element() instead.
* @deprecated use get_element() instead.
*/
string DCAtomicField::
vector_uchar DCAtomicField::
get_element_default(int n) const {
nassertr(n >= 0 && n < (int)_elements.size(), string());
nassertr(n >= 0 && n < (int)_elements.size(), vector_uchar());
return _elements[n]->get_default_value();
}
@ -100,7 +100,7 @@ get_element_default(int n) const {
* Returns true if the nth element of the field has a default value specified,
* false otherwise.
*
* This is deprecated; use get_element() instead.
* @deprecated use get_element() instead.
*/
bool DCAtomicField::
has_element_default(int n) const {
@ -113,7 +113,7 @@ has_element_default(int n) const {
* 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.
* @deprecated use get_element()->get_name() instead.
*/
string DCAtomicField::
get_element_name(int n) const {

View File

@ -40,7 +40,7 @@ PUBLISHED:
DCParameter *get_element(int n) const;
// These five methods are deprecated and will be removed soon.
std::string get_element_default(int n) const;
vector_uchar get_element_default(int n) const;
bool has_element_default(int n) const;
std::string get_element_name(int n) const;
DCSubatomicType get_element_type(int n) const;

View File

@ -587,7 +587,7 @@ receive_update_other(PyObject *distobj, DatagramIterator &di) const {
*/
void DCClass::
direct_update(PyObject *distobj, const string &field_name,
const string &value_blob) {
const vector_uchar &value_blob) {
DCField *field = get_field_by_name(field_name);
nassertv_always(field != nullptr);
@ -606,7 +606,14 @@ direct_update(PyObject *distobj, const string &field_name,
void DCClass::
direct_update(PyObject *distobj, const string &field_name,
const Datagram &datagram) {
direct_update(distobj, field_name, datagram.get_message());
DCField *field = get_field_by_name(field_name);
nassertv_always(field != nullptr);
DCPacker packer;
packer.set_unpack_data((const char *)datagram.get_data(), datagram.get_length(), false);
packer.begin_unpack(field);
field->receive_update(packer, distobj);
packer.end_unpack();
}
#endif // HAVE_PYTHON

View File

@ -95,7 +95,7 @@ PUBLISHED:
void receive_update_other(PyObject *distobj, DatagramIterator &di) const;
void direct_update(PyObject *distobj, const std::string &field_name,
const std::string &value_blob);
const vector_uchar &value_blob);
void direct_update(PyObject *distobj, const std::string &field_name,
const Datagram &datagram);
bool pack_required_field(Datagram &datagram, PyObject *distobj,

View File

@ -42,7 +42,7 @@ has_default_value() const {
* explicitly set (e.g. has_default_value() returns true), returns that
* value; otherwise, returns an implicit default for the field.
*/
INLINE const std::string &DCField::
INLINE const vector_uchar &DCField::
get_default_value() const {
if (_default_value_stale) {
((DCField *)this)->refresh_default_value();
@ -172,8 +172,8 @@ set_class(DCClass *dclass) {
* Establishes a default value for this field.
*/
INLINE void DCField::
set_default_value(const std::string &default_value) {
_default_value = default_value;
set_default_value(vector_uchar default_value) {
_default_value = std::move(default_value);
_has_default_value = true;
_default_value_stale = false;
}

View File

@ -162,7 +162,7 @@ as_parameter() const {
* is an error.
*/
string DCField::
format_data(const string &packed_data, bool show_field_names) {
format_data(const vector_uchar &packed_data, bool show_field_names) {
DCPacker packer;
packer.set_unpack_data(packed_data);
packer.begin_unpack(this);
@ -178,20 +178,20 @@ format_data(const string &packed_data, bool show_field_names) {
* above) that represents the value of this field, parse the string and return
* the corresponding packed data. Returns empty string if there is an error.
*/
string DCField::
vector_uchar DCField::
parse_string(const string &formatted_string) {
DCPacker packer;
packer.begin_pack(this);
if (!packer.parse_and_pack(formatted_string)) {
// Parse error.
return string();
return vector_uchar();
}
if (!packer.end_pack()) {
// Data type mismatch.
return string();
return vector_uchar();
}
return packer.get_string();
return packer.get_bytes();
}
/**
@ -200,7 +200,7 @@ parse_string(const string &formatted_string) {
* record. Returns true if all fields are valid, false otherwise.
*/
bool DCField::
validate_ranges(const string &packed_data) const {
validate_ranges(const vector_uchar &packed_data) const {
DCPacker packer;
packer.set_unpack_data(packed_data);
packer.begin_unpack(this);
@ -209,7 +209,7 @@ validate_ranges(const string &packed_data) const {
return false;
}
return (packer.get_num_unpacked_bytes() == packed_data.length());
return (packer.get_num_unpacked_bytes() == packed_data.size());
}
#ifdef HAVE_PYTHON
@ -488,7 +488,7 @@ pack_default_value(DCPackData &pack_data, bool &) const {
// The default behavior is to pack the default value if we got it;
// otherwise, to return false and let the packer visit our nested elements.
if (!_default_value_stale) {
pack_data.append_data(_default_value.data(), _default_value.length());
pack_data.append_data((const char *)_default_value.data(), _default_value.size());
return true;
}
@ -566,7 +566,8 @@ refresh_default_value() {
if (!packer.end_pack()) {
std::cerr << "Error while packing default value for " << get_name() << "\n";
} else {
_default_value.assign(packer.get_data(), packer.get_length());
const unsigned char *data = (const unsigned char *)packer.get_data();
_default_value = vector_uchar(data, data + packer.get_length());
}
_default_value_stale = false;
}

View File

@ -53,13 +53,13 @@ PUBLISHED:
virtual DCParameter *as_parameter();
virtual const DCParameter *as_parameter() const;
std::string format_data(const std::string &packed_data, bool show_field_names = true);
std::string parse_string(const std::string &formatted_string);
std::string format_data(const vector_uchar &packed_data, bool show_field_names = true);
vector_uchar parse_string(const std::string &formatted_string);
bool validate_ranges(const std::string &packed_data) const;
bool validate_ranges(const vector_uchar &packed_data) const;
INLINE bool has_default_value() const;
INLINE const std::string &get_default_value() const;
INLINE const vector_uchar &get_default_value() const;
INLINE bool is_bogus_field() const;
@ -98,7 +98,7 @@ public:
INLINE void set_number(int number);
INLINE void set_class(DCClass *dclass);
INLINE void set_default_value(const std::string &default_value);
INLINE void set_default_value(vector_uchar default_value);
#ifdef HAVE_PYTHON
static std::string get_pystr(PyObject *value);
@ -115,7 +115,7 @@ protected:
bool _bogus_field;
private:
std::string _default_value;
vector_uchar _default_value;
#ifdef WITHIN_PANDA
PStatCollector _field_update_pcollector;

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
/*
// Filename: dcLexer.lxx
// Created by: drose (05Oct00)
//
//
////////////////////////////////////////////////////////////////////
*/
@ -103,12 +103,12 @@ dcyyerror(const std::string &msg) {
if (!dc_filename.empty()) {
cerr << " in " << dc_filename;
}
cerr
cerr
<< " at line " << line_number << ", column " << col_number << ":\n"
<< current_line << "\n";
indent(cerr, col_number-1)
indent(cerr, col_number-1)
<< "^\n" << msg << "\n\n";
error_count++;
}
@ -120,10 +120,10 @@ dcyywarning(const std::string &msg) {
if (!dc_filename.empty()) {
cerr << " in " << dc_filename;
}
cerr
cerr
<< " at line " << line_number << ", column " << col_number << ":\n"
<< current_line << "\n";
indent(cerr, col_number-1)
indent(cerr, col_number-1)
<< "^\n" << msg << "\n\n";
warning_count++;
@ -313,9 +313,9 @@ scan_quoted_string(char quote_mark) {
// scan_hex_string reads a string of hexadecimal digits delimited by
// angle brackets and returns the representative string.
static std::string
static vector_uchar
scan_hex_string() {
std::string result;
vector_uchar 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
@ -345,24 +345,24 @@ scan_hex_string() {
line_number = line;
col_number = col;
dcyyerror("Invalid hex digit.");
return std::string();
return vector_uchar();
}
odd = !odd;
if (odd) {
last = value;
} else {
result += (char)((last << 4) | value);
result.push_back((unsigned char)((last << 4) | value));
}
c = read_char(line, col);
}
if (c == EOF) {
dcyyerror("This hex string is unterminated.");
return std::string();
return vector_uchar();
} else if (odd) {
dcyyerror("Odd number of hex digits.");
return std::string();
return vector_uchar();
}
line_number = line;
@ -382,7 +382,7 @@ eat_c_comment() {
int col = col_number;
int c, last_c;
last_c = '\0';
c = read_char(line, col);
while (c != EOF && !(last_c == '*' && c == '/')) {
@ -440,12 +440,12 @@ REALNUM ([+-]?(([0-9]+[.])|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
yyless(1);
}
[ \t\r] {
[ \t\r] {
// Eat whitespace.
accept();
}
"//".* {
"//".* {
// Eat C++-style comments.
accept();
}
@ -453,7 +453,7 @@ REALNUM ([+-]?(([0-9]+[.])|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
"/*" {
// Eat C-style comments.
accept();
eat_c_comment();
eat_c_comment();
}
@ -607,7 +607,7 @@ REALNUM ([+-]?(([0-9]+[.])|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
return KW_CHAR;
}
{UNSIGNED_INTEGERNUM} {
{UNSIGNED_INTEGERNUM} {
// An unsigned integer number.
accept();
@ -626,11 +626,11 @@ REALNUM ([+-]?(([0-9]+[.])|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
dcyylval.u.uint64 = next_value + (*p - '0');
++p;
}
return UNSIGNED_INTEGER;
}
{SIGNED_INTEGERNUM} {
{SIGNED_INTEGERNUM} {
// A signed integer number.
accept();
@ -671,14 +671,14 @@ REALNUM ([+-]?(([0-9]+[.])|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
dcyyerror("Number out of range.");
dcyylval.u.int64 = 1;
}
}
}
return SIGNED_INTEGER;
}
{UNSIGNED_HEXNUM} {
// A hexadecimal integer number.
accept();
accept();
// As above, we'll decode the hex string by hand.
dcyylval.str = dcyytext;
@ -700,15 +700,15 @@ REALNUM ([+-]?(([0-9]+[.])|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
++p;
}
return UNSIGNED_INTEGER;
return UNSIGNED_INTEGER;
}
{REALNUM} {
{REALNUM} {
// A floating-point number.
accept();
dcyylval.u.real = patof(dcyytext);
accept();
dcyylval.u.real = patof(dcyytext);
dcyylval.str = dcyytext;
return REAL;
return REAL;
}
["] {
@ -728,11 +728,11 @@ REALNUM ([+-]?(([0-9]+[.])|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
[<] {
// Long hex string.
accept();
dcyylval.str = scan_hex_string();
dcyylval.bytes = scan_hex_string();
return HEX_STRING;
}
[A-Za-z_][A-Za-z_0-9]* {
[A-Za-z_][A-Za-z_0-9]* {
// Identifier or keyword.
accept();
dcyylval.str = dcyytext;
@ -750,7 +750,7 @@ REALNUM ([+-]?(([0-9]+[.])|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
. {
// Send any other printable character as itself.
accept();
accept();
return dcyytext[0];
}

View File

@ -217,16 +217,30 @@ pack_string(const std::string &value) {
}
/**
* Adds the indicated string value into the stream, representing a single pre-
* packed field element, or a whole group of field elements at once.
* Packs the indicated numeric or string value into the stream.
*/
INLINE void DCPacker::
pack_literal_value(const std::string &value) {
pack_blob(const vector_uchar &value) {
nassertv(_mode == M_pack || _mode == M_repack);
if (_current_field == nullptr) {
_pack_error = true;
} else {
_pack_data.append_data(value.data(), value.length());
_current_field->pack_blob(_pack_data, value, _pack_error, _range_error);
advance();
}
}
/**
* Adds the indicated string value into the stream, representing a single pre-
* packed field element, or a whole group of field elements at once.
*/
INLINE void DCPacker::
pack_literal_value(const vector_uchar &value) {
nassertv(_mode == M_pack || _mode == M_repack);
if (_current_field == nullptr) {
_pack_error = true;
} else {
_pack_data.append_data((const char *)value.data(), value.size());
advance();
}
}
@ -345,16 +359,36 @@ unpack_string() {
return value;
}
/**
* Unpacks the current binary data value from the stream.
*/
INLINE vector_uchar DCPacker::
unpack_blob() {
vector_uchar value;
nassertr(_mode == M_unpack, value);
if (_current_field == nullptr) {
_pack_error = true;
} else {
_current_field->unpack_blob(_unpack_data, _unpack_length, _unpack_p,
value, _pack_error, _range_error);
advance();
}
return value;
}
/**
* Returns the literal string that represents the packed value of the current
* field, and advances the field pointer.
*/
INLINE std::string DCPacker::
INLINE vector_uchar DCPacker::
unpack_literal_value() {
size_t start = _unpack_p;
unpack_skip();
nassertr(_unpack_p >= start, std::string());
return std::string(_unpack_data + start, _unpack_p - start);
nassertr(_unpack_p >= start, vector_uchar());
return vector_uchar((const unsigned char *)_unpack_data + start,
(const unsigned char *)_unpack_data + _unpack_p);
}
/**
@ -453,16 +487,33 @@ unpack_string(std::string &value) {
}
}
/**
* Unpacks the current numeric or string value from the stream.
*/
INLINE void DCPacker::
unpack_blob(vector_uchar &value) {
nassertv(_mode == M_unpack);
if (_current_field == nullptr) {
_pack_error = true;
} else {
_current_field->unpack_blob(_unpack_data, _unpack_length, _unpack_p,
value, _pack_error, _range_error);
advance();
}
}
/**
* Returns the literal string that represents the packed value of the current
* field, and advances the field pointer.
*/
INLINE void DCPacker::
unpack_literal_value(std::string &value) {
unpack_literal_value(vector_uchar &value) {
size_t start = _unpack_p;
unpack_skip();
nassertv(_unpack_p >= start);
value.assign(_unpack_data + start, _unpack_p - start);
value = vector_uchar((const unsigned char *)_unpack_data + start,
(const unsigned char *)_unpack_data + _unpack_p);
}
/**
@ -541,6 +592,15 @@ get_string() const {
return _pack_data.get_string();
}
/**
* Returns the packed data buffer as a bytes object. Also see get_data().
*/
INLINE vector_uchar DCPacker::
get_bytes() const {
const unsigned char *p = (const unsigned char *)_pack_data.get_data();
return vector_uchar(p, p + _pack_data.get_length());
}
/**
* Returns the total number of bytes in the unpack data buffer. This is the
* buffer used when unpacking; it is separate from the pack data returned by
@ -601,9 +661,9 @@ take_data() {
* between packing sessions.
*/
INLINE void DCPacker::
append_data(const char *buffer, size_t size) {
append_data(const unsigned char *buffer, size_t size) {
nassertv(_mode == M_idle);
_pack_data.append_data(buffer, size);
_pack_data.append_data((const char *)buffer, size);
}
/**
@ -728,6 +788,16 @@ raw_pack_string(const std::string &value) {
_pack_data.append_data(value.data(), value.length());
}
/**
* Packs the data into the buffer between packing sessions.
*/
INLINE void DCPacker::
raw_pack_blob(const vector_uchar &value) {
nassertv(_mode == M_idle);
DCPackerInterface::do_pack_uint16(_pack_data.get_write_pointer(2), value.size());
_pack_data.append_data((const char *)value.data(), value.size());
}
/**
* Unpacks the data from the buffer between unpacking sessions.
*/
@ -870,6 +940,16 @@ raw_unpack_string() {
return value;
}
/**
* Unpacks the data from the buffer between unpacking sessions.
*/
INLINE vector_uchar DCPacker::
raw_unpack_blob() {
vector_uchar value;
raw_unpack_blob(value);
return value;
}
/**
* Unpacks the data from the buffer between unpacking sessions.
*/
@ -971,6 +1051,24 @@ raw_unpack_string(std::string &value) {
_unpack_p += string_length;
}
/**
* Unpacks the data from the buffer between unpacking sessions.
*/
INLINE void DCPacker::
raw_unpack_blob(vector_uchar &value) {
nassertv(_mode == M_idle && _unpack_data != nullptr);
unsigned int blob_size = raw_unpack_uint16();
if (_unpack_p + blob_size > _unpack_length) {
_pack_error = true;
return;
}
const unsigned char *p = (const unsigned char *)_unpack_data + _unpack_p;
value = vector_uchar(p, p + blob_size);
_unpack_p += blob_size;
}
/**
* Advances to the next field after a call to pack_value() or pop().
*/

View File

@ -114,12 +114,12 @@ end_pack() {
* version of begin_unpack() that takes only one parameter.
*/
void DCPacker::
set_unpack_data(const string &data) {
set_unpack_data(const vector_uchar &data) {
nassertv(_mode == M_idle);
char *buffer = new char[data.length()];
memcpy(buffer, data.data(), data.length());
set_unpack_data(buffer, data.length(), true);
char *buffer = new char[data.size()];
memcpy(buffer, data.data(), data.size());
set_unpack_data(buffer, data.size(), true);
}
/**
@ -721,11 +721,11 @@ pack_object(PyObject *object) {
pack_string(string(buffer, length));
}
} else if (PyBytes_Check(object)) {
char *buffer;
const unsigned char *buffer;
Py_ssize_t length;
PyBytes_AsStringAndSize(object, &buffer, &length);
PyBytes_AsStringAndSize(object, (char **)&buffer, &length);
if (buffer) {
pack_string(string(buffer, length));
pack_blob(vector_uchar(buffer, buffer + length));
}
#else
} else if (PyString_Check(object) || PyUnicode_Check(object)) {
@ -1118,9 +1118,9 @@ enquote_string(ostream &out, char quote_mark, const string &str) {
* Outputs the indicated string as a hex constant.
*/
void DCPacker::
output_hex_string(ostream &out, const string &str) {
output_hex_string(ostream &out, const vector_uchar &str) {
out << '<';
for (string::const_iterator pi = str.begin();
for (vector_uchar::const_iterator pi = str.begin();
pi != str.end();
++pi) {
char buffer[10];

View File

@ -41,7 +41,7 @@ PUBLISHED:
void begin_pack(const DCPackerInterface *root);
bool end_pack();
void set_unpack_data(const std::string &data);
void set_unpack_data(const vector_uchar &data);
public:
void set_unpack_data(const char *unpack_data, size_t unpack_length,
bool owns_unpack_data);
@ -75,7 +75,8 @@ PUBLISHED:
INLINE void pack_int64(int64_t value);
INLINE void pack_uint64(uint64_t value);
INLINE void pack_string(const std::string &value);
INLINE void pack_literal_value(const std::string &value);
INLINE void pack_blob(const vector_uchar &value);
INLINE void pack_literal_value(const vector_uchar &value);
void pack_default_value();
INLINE double unpack_double();
@ -84,7 +85,8 @@ PUBLISHED:
INLINE int64_t unpack_int64();
INLINE uint64_t unpack_uint64();
INLINE std::string unpack_string();
INLINE std::string unpack_literal_value();
INLINE vector_uchar unpack_blob();
INLINE vector_uchar unpack_literal_value();
void unpack_validate();
void unpack_skip();
@ -97,7 +99,8 @@ public:
INLINE void unpack_int64(int64_t &value);
INLINE void unpack_uint64(uint64_t &value);
INLINE void unpack_string(std::string &value);
INLINE void unpack_literal_value(std::string &value);
INLINE void unpack_blob(vector_uchar &value);
INLINE void unpack_literal_value(vector_uchar &value);
PUBLISHED:
@ -119,6 +122,7 @@ PUBLISHED:
INLINE size_t get_length() const;
INLINE std::string get_string() const;
INLINE vector_uchar get_bytes() const;
INLINE size_t get_unpack_length() const;
INLINE std::string get_unpack_string() const;
public:
@ -126,7 +130,7 @@ public:
INLINE const char *get_data() const;
INLINE char *take_data();
INLINE void append_data(const char *buffer, size_t size);
INLINE void append_data(const unsigned char *buffer, size_t size);
INLINE char *get_write_pointer(size_t size);
INLINE const char *get_unpack_data() const;
@ -148,6 +152,7 @@ PUBLISHED:
INLINE void raw_pack_uint64(uint64_t value);
INLINE void raw_pack_float64(double value);
INLINE void raw_pack_string(const std::string &value);
INLINE void raw_pack_blob(const vector_uchar &value);
// this is a hack to allw me to get in and out of 32bit Mode Faster need to
// agree with channel_type in dcbase.h
@ -165,6 +170,7 @@ PUBLISHED:
INLINE uint64_t raw_unpack_uint64();
INLINE double raw_unpack_float64();
INLINE std::string raw_unpack_string();
INLINE vector_uchar raw_unpack_blob();
public:
INLINE void raw_unpack_int8(int &value);
@ -177,10 +183,11 @@ public:
INLINE void raw_unpack_uint64(uint64_t &value);
INLINE void raw_unpack_float64(double &value);
INLINE void raw_unpack_string(std::string &value);
INLINE void raw_unpack_blob(vector_uchar &value);
public:
static void enquote_string(std::ostream &out, char quote_mark, const std::string &str);
static void output_hex_string(std::ostream &out, const std::string &str);
static void output_hex_string(std::ostream &out, const vector_uchar &str);
private:
INLINE void advance();

View File

@ -248,6 +248,14 @@ pack_string(DCPackData &, const string &, bool &pack_error, bool &) const {
pack_error = true;
}
/**
* Packs the indicated numeric or string value into the stream.
*/
void DCPackerInterface::
pack_blob(DCPackData &, const vector_uchar &, bool &pack_error, bool &) const {
pack_error = true;
}
/**
* Packs the field's specified default value (or a sensible default if no
* value is specified) into the stream. Returns true if the default value is
@ -306,6 +314,14 @@ unpack_string(const char *, size_t, size_t &, string &, bool &pack_error, bool &
pack_error = true;
}
/**
* Unpacks the current numeric or string value from the stream.
*/
void DCPackerInterface::
unpack_blob(const char *, size_t, size_t &, vector_uchar &, bool &pack_error, bool &) const {
pack_error = true;
}
/**
* Internally unpacks the current numeric or string value and validates it
* against the type range limits, but does not return the value. Returns true

View File

@ -16,6 +16,7 @@
#include "dcbase.h"
#include "dcSubatomicType.h"
#include "vector_uchar.h"
class DCFile;
class DCField;
@ -37,8 +38,8 @@ enum DCPackType {
// These PackTypes are all fundamental types, and should be packed (or
// unpacked) with the corresponding call to pack_double(), pack_int(), etc.
// PT_blob is the same as PT_string, but implies that the string contains
// binary data.
// PT_blob is similar to PT_string, except that it contains arbitrary binary
// data instead of just UTF-8 text.
PT_double,
PT_int,
PT_uint,
@ -113,6 +114,8 @@ public:
bool &pack_error, bool &range_error) const;
virtual void pack_string(DCPackData &pack_data, const std::string &value,
bool &pack_error, bool &range_error) const;
virtual void pack_blob(DCPackData &pack_data, const vector_uchar &value,
bool &pack_error, bool &range_error) const;
virtual bool pack_default_value(DCPackData &pack_data, bool &pack_error) const;
virtual void unpack_double(const char *data, size_t length, size_t &p,
@ -127,6 +130,8 @@ public:
uint64_t &value, bool &pack_error, bool &range_error) const;
virtual void unpack_string(const char *data, size_t length, size_t &p,
std::string &value, bool &pack_error, bool &range_error) const;
virtual void unpack_blob(const char *data, size_t length, size_t &p,
vector_uchar &value, bool &pack_error, bool &range_error) const;
virtual bool unpack_validate(const char *data, size_t length, size_t &p,
bool &pack_error, bool &range_error) const;
virtual bool unpack_skip(const char *data, size_t length, size_t &p,

File diff suppressed because it is too large Load Diff

View File

@ -1,20 +1,19 @@
/* A Bison parser, made by GNU Bison 2.4.2. */
/* A Bison parser, made by GNU Bison 3.1. */
/* Bison interface for Yacc-like parsers in C
Copyright (C) 1984, 1989-1990, 2000-2015, 2018 Free Software Foundation, Inc.
/* Skeleton interface for Bison's Yacc-like parsers in C
Copyright (C) 1984, 1989-1990, 2000-2006, 2009-2010 Free Software
Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
@ -27,66 +26,74 @@
special exception, which will cause the skeleton and the resulting
Bison output files to be licensed under the GNU General Public
License without this special exception.
This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */
#ifndef YY_DCYY_BUILT_TMP_DCPARSER_YXX_H_INCLUDED
# define YY_DCYY_BUILT_TMP_DCPARSER_YXX_H_INCLUDED
/* Debug traces. */
#ifndef YYDEBUG
# define YYDEBUG 0
#endif
#if YYDEBUG
extern int dcyydebug;
#endif
/* Tokens. */
/* Token type. */
#ifndef YYTOKENTYPE
# define YYTOKENTYPE
/* Put the tokens into the symbol table, so that GDB and other debuggers
know about them. */
enum yytokentype {
UNSIGNED_INTEGER = 258,
SIGNED_INTEGER = 259,
REAL = 260,
STRING = 261,
HEX_STRING = 262,
IDENTIFIER = 263,
KEYWORD = 264,
KW_DCLASS = 265,
KW_STRUCT = 266,
KW_FROM = 267,
KW_IMPORT = 268,
KW_TYPEDEF = 269,
KW_KEYWORD = 270,
KW_SWITCH = 271,
KW_CASE = 272,
KW_DEFAULT = 273,
KW_BREAK = 274,
KW_INT8 = 275,
KW_INT16 = 276,
KW_INT32 = 277,
KW_INT64 = 278,
KW_UINT8 = 279,
KW_UINT16 = 280,
KW_UINT32 = 281,
KW_UINT64 = 282,
KW_FLOAT64 = 283,
KW_STRING = 284,
KW_BLOB = 285,
KW_BLOB32 = 286,
KW_INT8ARRAY = 287,
KW_INT16ARRAY = 288,
KW_INT32ARRAY = 289,
KW_UINT8ARRAY = 290,
KW_UINT16ARRAY = 291,
KW_UINT32ARRAY = 292,
KW_UINT32UINT8ARRAY = 293,
KW_CHAR = 294,
START_DC = 295,
START_PARAMETER_VALUE = 296,
START_PARAMETER_DESCRIPTION = 297
};
enum yytokentype
{
UNSIGNED_INTEGER = 258,
SIGNED_INTEGER = 259,
REAL = 260,
STRING = 261,
IDENTIFIER = 262,
HEX_STRING = 263,
KEYWORD = 264,
KW_DCLASS = 265,
KW_STRUCT = 266,
KW_FROM = 267,
KW_IMPORT = 268,
KW_TYPEDEF = 269,
KW_KEYWORD = 270,
KW_SWITCH = 271,
KW_CASE = 272,
KW_DEFAULT = 273,
KW_BREAK = 274,
KW_INT8 = 275,
KW_INT16 = 276,
KW_INT32 = 277,
KW_INT64 = 278,
KW_UINT8 = 279,
KW_UINT16 = 280,
KW_UINT32 = 281,
KW_UINT64 = 282,
KW_FLOAT64 = 283,
KW_STRING = 284,
KW_BLOB = 285,
KW_BLOB32 = 286,
KW_INT8ARRAY = 287,
KW_INT16ARRAY = 288,
KW_INT32ARRAY = 289,
KW_UINT8ARRAY = 290,
KW_UINT16ARRAY = 291,
KW_UINT32ARRAY = 292,
KW_UINT32UINT8ARRAY = 293,
KW_CHAR = 294,
START_DC = 295,
START_PARAMETER_VALUE = 296,
START_PARAMETER_DESCRIPTION = 297
};
#endif
/* Tokens. */
#define UNSIGNED_INTEGER 258
#define SIGNED_INTEGER 259
#define REAL 260
#define STRING 261
#define HEX_STRING 262
#define IDENTIFIER 263
#define IDENTIFIER 262
#define HEX_STRING 263
#define KEYWORD 264
#define KW_DCLASS 265
#define KW_STRUCT 266
@ -122,15 +129,11 @@
#define START_PARAMETER_VALUE 296
#define START_PARAMETER_DESCRIPTION 297
/* Value type. */
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
#endif
extern YYSTYPE dcyylval;
int dcyyparse (void);
#endif /* !YY_DCYY_BUILT_TMP_DCPARSER_YXX_H_INCLUDED */

View File

@ -57,7 +57,7 @@ dc_init_parser(istream &in, const string &filename, DCFile &file) {
}
void
dc_init_parser_parameter_value(istream &in, const string &filename,
dc_init_parser_parameter_value(istream &in, const string &filename,
DCPacker &packer) {
dc_file = nullptr;
current_packer = &packer;
@ -89,15 +89,16 @@ dc_cleanup_parser() {
%token <u.uint64> UNSIGNED_INTEGER
%token <u.int64> SIGNED_INTEGER
%token <u.real> REAL
%token <str> STRING HEX_STRING IDENTIFIER
%token <str> STRING IDENTIFIER
%token <bytes> HEX_STRING
%token <u.keyword> KEYWORD
%token KW_DCLASS
%token KW_STRUCT
%token KW_FROM
%token KW_IMPORT
%token KW_TYPEDEF
%token KW_KEYWORD
%token KW_DCLASS
%token KW_STRUCT
%token KW_FROM
%token KW_IMPORT
%token KW_TYPEDEF
%token KW_KEYWORD
%token KW_SWITCH
%token KW_CASE
%token KW_DEFAULT
@ -224,7 +225,7 @@ import:
{
dc_file->add_import_module($2);
}
| KW_FROM import_identifier KW_IMPORT
| KW_FROM import_identifier KW_IMPORT
{
dc_file->add_import_module($2);
}
@ -255,7 +256,7 @@ typedef_decl:
{
if ($2 != nullptr) {
DCTypedef *dtypedef = new DCTypedef($2);
if (!dc_file->add_typedef(dtypedef)) {
DCTypedef *old_typedef = dc_file->get_typedef_by_name(dtypedef->get_name());
if (old_typedef->is_bogus_typedef()) {
@ -294,7 +295,7 @@ dclass_or_struct:
;
dclass:
KW_DCLASS optional_name
KW_DCLASS optional_name
{
current_class = new DCClass(dc_file, $2, false, false);
}
@ -322,7 +323,7 @@ dclass_name:
if (dclass->is_struct()) {
yyerror("struct name not allowed");
}
$$ = dclass;
}
}
@ -398,7 +399,7 @@ dclass_field:
;
struct:
KW_STRUCT optional_name
KW_STRUCT optional_name
{
current_class = new DCClass(dc_file, $2, true, false);
}
@ -426,7 +427,7 @@ struct_name:
if (!dstruct->is_struct()) {
yyerror("struct name required");
}
$$ = dstruct;
}
}
@ -538,7 +539,7 @@ unnamed_parameter:
named_parameter_with_default:
named_parameter
| named_parameter '='
| named_parameter '='
{
current_packer = &default_packer;
current_packer->clear_data();
@ -553,7 +554,7 @@ named_parameter_with_default:
is_valid = $1->is_valid();
}
if (current_packer->end_pack()) {
$1->set_default_value(current_packer->get_string());
$1->set_default_value(current_packer->get_bytes());
} else {
if (is_valid) {
@ -568,7 +569,7 @@ named_parameter_with_default:
unnamed_parameter_with_default:
unnamed_parameter
| unnamed_parameter '='
| unnamed_parameter '='
{
current_packer = &default_packer;
current_packer->clear_data();
@ -583,7 +584,7 @@ unnamed_parameter_with_default:
is_valid = $1->is_valid();
}
if (current_packer->end_pack()) {
$1->set_default_value(current_packer->get_string());
$1->set_default_value(current_packer->get_bytes());
} else {
if (is_valid) {
@ -663,7 +664,7 @@ simple_type_name:
$$ = simple_param;
}
| simple_type_name '%' number
{
{
DCSimpleParameter *simple_param = $1->as_simple_parameter();
nassertr(simple_param != nullptr, 0);
if (!simple_param->is_numeric_type()) {
@ -703,10 +704,10 @@ type_name:
dtypedef = new DCTypedef($1);
}
}
dc_file->add_typedef(dtypedef);
}
$$ = dtypedef->make_new_parameter();
}
}
@ -974,7 +975,7 @@ parameter_value:
{
if ($1 != current_packer->get_current_field_name()) {
ostringstream strm;
strm << "Got '" << $1 << "', expected '"
strm << "Got '" << $1 << "', expected '"
<< current_packer->get_current_field_name() << "'";
yyerror(strm.str());
}
@ -1005,7 +1006,7 @@ parameter_actual_value:
{
current_packer->pack_literal_value($1);
}
| '{'
| '{'
{
current_packer->push();
}
@ -1013,7 +1014,7 @@ parameter_actual_value:
{
current_packer->pop();
}
| '['
| '['
{
current_packer->push();
}
@ -1021,7 +1022,7 @@ parameter_actual_value:
{
current_packer->pop();
}
| '('
| '('
{
current_packer->push();
}
@ -1223,7 +1224,7 @@ molecular_atom_list:
if ($3 != nullptr) {
current_molecular->add_atomic($3);
if (!$3->is_bogus_field() && !current_molecular->compare_keywords(*$3)) {
yyerror("Mismatched keywords in molecule between " +
yyerror("Mismatched keywords in molecule between " +
current_molecular->get_atomic(0)->get_name() + " and " +
$3->get_name());
}
@ -1283,7 +1284,7 @@ switch_case:
yyerror("Invalid value for switch parameter");
current_switch->add_invalid_case();
} else {
int case_index = current_switch->add_case(current_packer->get_string());
int case_index = current_switch->add_case(current_packer->get_bytes());
if (case_index == -1) {
yyerror("Duplicate case value");
}

View File

@ -16,6 +16,7 @@
#include "dcbase.h"
#include "dcSubatomicType.h"
#include "vector_uchar.h"
class DCFile;
class DCClass;
@ -61,6 +62,7 @@ public:
const DCKeyword *keyword;
} u;
std::string str;
vector_uchar bytes;
};
// The yacc-generated code expects to use the symbol 'YYSTYPE' to refer to the

View File

@ -1069,6 +1069,52 @@ pack_string(DCPackData &pack_data, const string &value,
}
}
/**
* Packs the indicated numeric or string value into the stream.
*/
void DCSimpleParameter::
pack_blob(DCPackData &pack_data, const vector_uchar &value,
bool &pack_error, bool &range_error) const {
size_t blob_size = value.size();
switch (_type) {
case ST_char:
case ST_uint8:
case ST_int8:
if (blob_size == 0) {
pack_error = true;
} else {
if (blob_size != 1) {
range_error = true;
}
_uint_range.validate((unsigned int)value[0], range_error);
do_pack_uint8(pack_data.get_write_pointer(1), (unsigned int)value[0]);
}
break;
case ST_string:
case ST_blob:
_uint_range.validate(blob_size, range_error);
validate_uint_limits(blob_size, 16, range_error);
if (_num_length_bytes != 0) {
do_pack_uint16(pack_data.get_write_pointer(2), blob_size);
}
pack_data.append_data((const char *)value.data(), blob_size);
break;
case ST_blob32:
_uint_range.validate(blob_size, range_error);
if (_num_length_bytes != 0) {
do_pack_uint32(pack_data.get_write_pointer(4), blob_size);
}
pack_data.append_data((const char *)value.data(), blob_size);
break;
default:
pack_error = true;
}
}
/**
* Packs the simpleParameter's specified default value (or a sensible default
* if no value is specified) into the stream. Returns true if the default
@ -1937,6 +1983,79 @@ unpack_string(const char *data, size_t length, size_t &p, string &value,
return;
}
/**
* Unpacks the current numeric or string value from the stream.
*/
void DCSimpleParameter::
unpack_blob(const char *data, size_t length, size_t &p, vector_uchar &value,
bool &pack_error, bool &range_error) const {
// If the type is a single byte, unpack it into a string of length 1.
switch (_type) {
case ST_char:
case ST_int8:
case ST_uint8:
{
if (p + 1 > length) {
pack_error = true;
return;
}
unsigned int int_value = do_unpack_uint8(data + p);
_uint_range.validate(int_value, range_error);
value.resize(1);
value[0] = int_value;
p++;
}
return;
default:
break;
}
size_t blob_size;
if (_num_length_bytes == 0) {
blob_size = _fixed_byte_size;
} else {
switch (_type) {
case ST_string:
case ST_blob:
if (p + 2 > length) {
pack_error = true;
return;
}
blob_size = do_unpack_uint16(data + p);
p += 2;
break;
case ST_blob32:
if (p + 4 > length) {
pack_error = true;
return;
}
blob_size = do_unpack_uint32(data + p);
p += 4;
break;
default:
pack_error = true;
return;
}
}
_uint_range.validate(blob_size, range_error);
if (p + blob_size > length) {
pack_error = true;
return;
}
value = vector_uchar((const unsigned char *)data + p,
(const unsigned char *)data + p + blob_size);
p += blob_size;
return;
}
/**
* Internally unpacks the current numeric or string value and validates it
* against the type range limits, but does not return the value. Returns true

View File

@ -62,6 +62,8 @@ public:
bool &pack_error, bool &range_error) const;
virtual void pack_string(DCPackData &pack_data, const std::string &value,
bool &pack_error, bool &range_error) const;
virtual void pack_blob(DCPackData &pack_data, const vector_uchar &value,
bool &pack_error, bool &range_error) const;
virtual bool pack_default_value(DCPackData &pack_data, bool &pack_error) const;
virtual void unpack_double(const char *data, size_t length, size_t &p,
@ -76,6 +78,8 @@ public:
uint64_t &value, bool &pack_error, bool &range_error) const;
virtual void unpack_string(const char *data, size_t length, size_t &p,
std::string &value, bool &pack_error, bool &range_error) const;
virtual void unpack_blob(const char *data, size_t length, size_t &p,
vector_uchar &value, bool &pack_error, bool &range_error) const;
virtual bool unpack_validate(const char *data, size_t length, size_t &p,
bool &pack_error, bool &range_error) const;
virtual bool unpack_skip(const char *data, size_t length, size_t &p,

View File

@ -109,7 +109,7 @@ get_num_cases() const {
* if no case has this value.
*/
int DCSwitch::
get_case_by_value(const string &case_value) const {
get_case_by_value(const vector_uchar &case_value) const {
CasesByValue::const_iterator vi;
vi = _cases_by_value.find(case_value);
if (vi != _cases_by_value.end()) {
@ -140,9 +140,9 @@ get_default_case() const {
/**
* Returns the packed value associated with the indicated case.
*/
string DCSwitch::
vector_uchar DCSwitch::
get_value(int case_index) const {
nassertr(case_index >= 0 && case_index < (int)_cases.size(), string());
nassertr(case_index >= 0 && case_index < (int)_cases.size(), vector_uchar());
return _cases[case_index]->_value;
}
@ -198,7 +198,7 @@ is_field_valid() const {
* -1. This is normally called only by the parser.
*/
int DCSwitch::
add_case(const string &value) {
add_case(const vector_uchar &value) {
int case_index = (int)_cases.size();
if (!_cases_by_value.insert(CasesByValue::value_type(value, case_index)).second) {
add_invalid_case();
@ -283,7 +283,8 @@ add_break() {
const DCPackerInterface *DCSwitch::
apply_switch(const char *value_data, size_t length) const {
CasesByValue::const_iterator vi;
vi = _cases_by_value.find(string(value_data, length));
vi = _cases_by_value.find(vector_uchar((const unsigned char *)value_data,
(const unsigned char *)value_data + length));
if (vi != _cases_by_value.end()) {
return _cases[(*vi).second]->_fields;
}
@ -421,7 +422,7 @@ generate_hash(HashGenerator &hashgen) const {
Cases::const_iterator ci;
for (ci = _cases.begin(); ci != _cases.end(); ++ci) {
const SwitchCase *dcase = (*ci);
hashgen.add_string(dcase->_value);
hashgen.add_blob(dcase->_value);
const SwitchFields *fields = dcase->_fields;
hashgen.add_int(fields->_fields.size());
@ -702,7 +703,7 @@ do_check_match(const DCPackerInterface *) const {
*
*/
DCSwitch::SwitchCase::
SwitchCase(const string &value, DCSwitch::SwitchFields *fields) :
SwitchCase(const vector_uchar &value, DCSwitch::SwitchFields *fields) :
_value(value),
_fields(fields)
{

View File

@ -40,18 +40,18 @@ PUBLISHED:
DCField *get_key_parameter() const;
int get_num_cases() const;
int get_case_by_value(const std::string &case_value) const;
int get_case_by_value(const vector_uchar &case_value) const;
DCPackerInterface *get_case(int n) const;
DCPackerInterface *get_default_case() const;
std::string get_value(int case_index) const;
vector_uchar get_value(int case_index) const;
int get_num_fields(int case_index) const;
DCField *get_field(int case_index, int n) const;
DCField *get_field_by_name(int case_index, const std::string &name) const;
public:
bool is_field_valid() const;
int add_case(const std::string &value);
int add_case(const vector_uchar &value);
void add_invalid_case();
bool add_default();
bool add_field(DCField *field);
@ -98,13 +98,13 @@ public:
class SwitchCase {
public:
SwitchCase(const std::string &value, SwitchFields *fields);
SwitchCase(const vector_uchar &value, SwitchFields *fields);
~SwitchCase();
bool do_check_match_switch_case(const SwitchCase *other) const;
public:
std::string _value;
vector_uchar _value;
SwitchFields *_fields;
};
@ -137,7 +137,7 @@ private:
bool _fields_added;
// This map indexes into the _cases vector, above.
typedef pmap<std::string, int> CasesByValue;
typedef pmap<vector_uchar, int> CasesByValue;
CasesByValue _cases_by_value;
};

View File

@ -56,6 +56,18 @@ add_string(const std::string &str) {
}
}
/**
* Adds a blob to the hash, by breaking it down into a sequence of integers.
*/
void HashGenerator::
add_blob(const vector_uchar &bytes) {
add_int(bytes.size());
vector_uchar::const_iterator bi;
for (bi = bytes.begin(); bi != bytes.end(); ++bi) {
add_int(*bi);
}
}
/**
* Returns the hash number generated.
*/

View File

@ -16,6 +16,7 @@
#include "dcbase.h"
#include "primeNumberGenerator.h"
#include "vector_uchar.h"
/**
* This class generates an arbitrary hash number from a sequence of ints.
@ -26,6 +27,7 @@ public:
void add_int(int num);
void add_string(const std::string &str);
void add_blob(const vector_uchar &bytes);
unsigned long get_hash() const;

View File

@ -1,7 +1,7 @@
print('ThreeUpStart: Starting up environment.')
from pandac.PandaModules import *
from panda3d.core import *
from direct.showbase.PythonUtil import *
from direct.showbase import ThreeUpShow

View File

@ -797,7 +797,15 @@ EXCLUDE = dtool/src/parser-inc \
panda/src/linmath/fltnames.h \
panda/src/linmath/dblnames.h \
panda/src/linmath/dbl2fltnames.h \
panda/src/linmath/flt2dblnames.h
panda/src/linmath/flt2dblnames.h \
panda/src/android \
panda/src/iphone \
panda/src/tinydisplay \
panda/src/movies/dr_flac.h \
dtool/src/dtoolbase/pdtoa.cxx \
dtool/src/dtoolutil/panda_getopt_long.h \
dtool/src/dtoolutil/panda_getopt_impl.h \
dtool/src/dtoolutil/panda_getopt_impl.cxx
# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
# directories that are symbolic links (a Unix file system feature) are excluded
@ -1116,7 +1124,7 @@ HTML_EXTRA_FILES =
# Minimum value: 0, maximum value: 359, default value: 220.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_COLORSTYLE_HUE = 228
HTML_COLORSTYLE_HUE = 251
# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors
# in the HTML output. For a value of 0 the output will use grayscales only. A
@ -1124,7 +1132,7 @@ HTML_COLORSTYLE_HUE = 228
# Minimum value: 0, maximum value: 255, default value: 100.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_COLORSTYLE_SAT = 99
HTML_COLORSTYLE_SAT = 150
# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the
# luminance component of the colors in the HTML output. Values below 100
@ -1135,7 +1143,7 @@ HTML_COLORSTYLE_SAT = 99
# Minimum value: 40, maximum value: 240, default value: 80.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_COLORSTYLE_GAMMA = 56
HTML_COLORSTYLE_GAMMA = 39
# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
# page will contain the date and time when the page was generated. Setting this
@ -1972,7 +1980,13 @@ PREDEFINED = TVOLATILE= \
EXTEND= \
ALLOC_DELETED_CHAIN(x)= \
BLOCKING= \
TYPENAME=typename
TYPENAME=typename \
MAKE_PROPERTY(x)= \
MAKE_PROPERTY2(x)= \
MAKE_SEQ(x)= \
MAKE_SEQ_PROPERTY(x)= \
MAKE_MAP_PROPERTY(x)= \
MAKE_MAP_KEYS_SEQ(x)=
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
# tag can be used to specify a list of macro names that should be expanded. The

View File

@ -665,7 +665,9 @@ EXCLUDE_SYMLINKS = NO
# for example use the pattern */test/*
EXCLUDE_PATTERNS = */Opt*-*/* \
*/CVS/*
*/CVS/* \
*/.git/* \
*/__pycache__/*
# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
# (namespaces, classes, functions, etc.) that should be excluded from the
@ -862,13 +864,13 @@ HTML_STYLESHEET = $(DOXYGEN_HTML_STYLESHEET)
# 180 is cyan, 240 is blue, 300 purple, and 360 is red again.
# The allowed range is 0 to 359.
HTML_COLORSTYLE_HUE = 228
HTML_COLORSTYLE_HUE = 251
# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of
# the colors in the HTML output. For a value of 0 the output will use
# grayscales only. A value of 255 will produce the most vivid colors.
HTML_COLORSTYLE_SAT = 99
HTML_COLORSTYLE_SAT = 150
# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to
# the luminance component of the colors in the HTML output. Values below
@ -877,7 +879,7 @@ HTML_COLORSTYLE_SAT = 99
# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2,
# and 100 does not change the gamma.
HTML_COLORSTYLE_GAMMA = 56
HTML_COLORSTYLE_GAMMA = 39
# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
# page will contain the date and time when the page was generated. Setting

View File

@ -9,9 +9,20 @@ from __future__ import print_function
__all__ = []
import os
import os, sys
from distutils import sysconfig
import panda3d, pandac
from panda3d.dtoolconfig import *
from panda3d.interrogatedb import *
if 'interrogate_element_is_sequence' not in globals():
def interrogate_element_is_sequence(element):
return False
if 'interrogate_element_is_mapping' not in globals():
def interrogate_element_is_mapping(element):
return False
LICENSE = """PANDA 3D SOFTWARE
Copyright (c) Carnegie Mellon University. All rights reserved.
@ -19,6 +30,16 @@ All use of this software is subject to the terms of the revised BSD
license. You should have received a copy of this license along
with this source code in a file named \"LICENSE.\"""".split("\n")
MAINPAGE = """@mainpage Panda3D Python API Reference
Welcome to the Panda3D API reference.
Use the links at the top of this page to browse through the list of modules or
the list of classes.
This reference is automatically generated from comments in the source code.
"""
def comment(code):
if not code:
return ""
@ -45,49 +66,16 @@ def comment(code):
return ''
def block_comment(code):
if not code:
code = code.strip()
if not code.startswith('///<') and '@verbatim' not in code:
code = code.replace('<', '\\<').replace('>', '\\>')
if not code or code[0] != '/':
# Not really a comment; get rid of it.
return ""
lines = code.split("\n")
newlines = []
indent = 0
reading_desc = False
for line in lines:
if line.startswith("////"):
continue
line = line.rstrip()
strline = line.lstrip('/ \t')
if ':' in strline:
pre, post = strline.split(':', 1)
pre = pre.rstrip()
if pre == "Description":
strline = post.lstrip()
elif pre in ("Class", "Access", "Function", "Created by", "Enum"):
continue
if strline or len(newlines) > 0:
newlines.append('/// ' + strline)
#if reading_desc:
# newlines.append('/// ' + line[min(indent, len(line) - len(strline)):])
#else:
# # A "Description:" text starts the description.
# if strline.startswith("Description"):
# strline = strline[11:].lstrip(': \t')
# indent = len(line) - len(strline)
# reading_desc = True
# newlines.append('/// ' + strline)
# else:
# print line
newcode = '\n'.join(newlines)
if len(newcode) > 0:
return newcode
else:
return ""
return code
def translateFunctionName(name):
if name.startswith("__"):
@ -139,11 +127,17 @@ def translated_type_name(type, scoped=True):
return "object"
elif typename == "PN_stdfloat":
return "float"
elif typename == "size_t":
return "int"
if interrogate_type_is_atomic(type):
token = interrogate_type_atomic_token(type)
if token == 7:
return 'str'
elif token == 8:
return 'long'
elif token == 9:
return 'NoneType'
else:
return typename
@ -156,12 +150,25 @@ def translated_type_name(type, scoped=True):
else:
return typename
def processElement(handle, element):
if interrogate_element_has_comment(element):
print(comment(interrogate_element_comment(element)), file=handle)
elif interrogate_element_has_getter(element):
# If the property has no comment, use the comment of the getter.
getter = interrogate_element_getter(element)
if interrogate_function_has_comment(getter):
print(block_comment(interrogate_function_comment(getter)), file=handle)
if interrogate_element_is_mapping(element) or \
interrogate_element_is_sequence(element):
suffix = "[]"
else:
suffix = ""
print(translated_type_name(interrogate_element_type(element)), end=' ', file=handle)
print(interrogate_element_name(element) + ';', file=handle)
print(interrogate_element_name(element) + suffix + ';', file=handle)
def processFunction(handle, function, isConstructor = False):
for i_wrapper in range(interrogate_function_number_of_python_wrappers(function)):
@ -195,6 +202,7 @@ def processFunction(handle, function, isConstructor = False):
print(");", file=handle)
def processType(handle, type):
typename = translated_type_name(type, scoped=False)
derivations = [ translated_type_name(interrogate_type_get_derivation(type, n)) for n in range(interrogate_type_number_of_derivations(type)) ]
@ -211,8 +219,10 @@ def processType(handle, type):
print(interrogate_type_enum_value_name(type, i_value), "=", interrogate_type_enum_value(type, i_value), ",", file=handle)
elif interrogate_type_is_typedef(type):
wrapped_type = translated_type_name(interrogate_type_wrapped_type(type))
print("typedef %s %s;" % (wrapped_type, typename), file=handle)
wrapped_type = interrogate_type_wrapped_type(type)
if interrogate_type_is_global(wrapped_type):
wrapped_type_name = translated_type_name(wrapped_type)
print("typedef %s %s;" % (wrapped_type_name, typename), file=handle)
return
else:
if interrogate_type_is_struct(type):
@ -249,6 +259,7 @@ def processType(handle, type):
print("};", file=handle)
def processModule(handle, package):
print("Processing module %s" % (package))
print("namespace %s {" % package, file=handle)
if package != "core":
@ -280,22 +291,39 @@ def processModule(handle, package):
if __name__ == "__main__":
handle = open("pandadoc.hpp", "w")
mainpage = MAINPAGE.strip()
if mainpage:
print("/**\n * " + mainpage.replace('\n', '\n * ') + '\n */', file=handle)
print(comment("Panda3D modules that are implemented in C++."), file=handle)
print("namespace panda3d {", file=handle)
# Determine the path to the interrogatedb files
interrogate_add_search_directory(os.path.join(os.path.dirname(pandac.__file__), "..", "..", "etc"))
interrogate_add_search_directory(os.path.join(os.path.dirname(pandac.__file__), "input"))
pandac = os.path.dirname(pandac.__file__)
interrogate_add_search_directory(os.path.join(pandac, "..", "..", "etc"))
interrogate_add_search_directory(os.path.join(pandac, "input"))
import panda3d.core
processModule(handle, "core")
# Determine the suffix for the extension modules.
if sys.version_info >= (3, 0):
import _imp
ext_suffix = _imp.extension_suffixes()[0]
elif sys.platform == "win32":
ext_suffix = ".pyd"
else:
ext_suffix = ".so"
for lib in os.listdir(os.path.dirname(panda3d.__file__)):
if lib.endswith(('.pyd', '.so')) and not lib.startswith('core.'):
module_name = os.path.splitext(lib)[0]
if lib.endswith(ext_suffix) and not lib.startswith('core.'):
module_name = lib[:-len(ext_suffix)]
__import__("panda3d." + module_name)
processModule(handle, module_name)
print("}", file=handle)
handle.close()
print("Wrote output to pandadoc.hpp. You can now run:")
print()
print(" doxygen built/direct/directscripts/Doxyfile.python")

File diff suppressed because it is too large Load Diff

0
direct/src/dist/__init__.py vendored Normal file
View File

1388
direct/src/dist/commands.py vendored Normal file

File diff suppressed because it is too large Load Diff

908
direct/src/dist/pefile.py vendored Executable file
View File

@ -0,0 +1,908 @@
""" Tools for manipulating Portable Executable files.
This can be used, for example, to extract a list of dependencies from an .exe
or .dll file, or to add version information and an icon resource to it. """
__all__ = ["PEFile"]
from struct import Struct, unpack, pack, pack_into
from collections import namedtuple
from array import array
import time
from io import BytesIO
import sys
if sys.version_info >= (3, 0):
unicode = str
unichr = chr
# Define some internally used structures.
RVASize = namedtuple('RVASize', ('addr', 'size'))
impdirtab = namedtuple('impdirtab', ('lookup', 'timdat', 'forward', 'name', 'impaddr'))
expdirtab = namedtuple('expdirtab', ('flags', 'timdat', 'majver', 'minver', 'name', 'ordinal_base', 'nentries', 'nnames', 'entries', 'names', 'ordinals'))
def _unpack_zstring(mem, offs=0):
"Read a zero-terminated string from memory."
c = mem[offs]
str = ""
while c:
str += chr(c)
offs += 1
c = mem[offs]
return str
def _unpack_wstring(mem, offs=0):
"Read a UCS-2 string from memory."
name_len, = unpack('<H', mem[offs:offs+2])
name = ""
for i in range(name_len):
offs += 2
name += unichr(*unpack('<H', mem[offs:offs+2]))
return name
def _padded(n, boundary):
align = n % boundary
if align:
n += boundary - align
return n
class Section(object):
_header = Struct('<8sIIIIIIHHI')
modified = True
def read_header(self, fp):
name, vsize, vaddr, size, scnptr, relptr, lnnoptr, nreloc, nlnno, flags = \
self._header.unpack(fp.read(40))
self.name = name.rstrip(b'\x00')
self.vaddr = vaddr # Base virtual address to map to.
self.vsize = vsize
self.offset = scnptr # Offset of the section in the file.
self.size = size
self.flags = flags
self.modified = False
def write_header(self, fp):
fp.write(self._header.pack(self.name, self.vsize, self.vaddr,
self.size, self.offset, 0, 0, 0, 0,
self.flags))
def __repr__(self):
return "<section '%s' memory %x-%x>" % (self.name, self.vaddr, self.vaddr + self.vsize)
def __gt__(self, other):
return self.vaddr > other.vaddr
def __lt__(self, other):
return self.vaddr < other.vaddr
class DataResource(object):
""" A resource entry in the resource table. """
# Resource types.
cursor = 1
bitmap = 2
icon = 3
menu = 4
dialog = 5
string = 6
font_directory = 7
font = 8
accelerator = 9
rcdata = 10
message_table = 11
cursor_group = 12
icon_group = 14
version = 16
dlg_include = 17
plug_play = 19
vxd = 20
animated_cursor = 21
animated_icon = 22
html = 23
manifest = 24
def __init__(self):
self._ident = ()
self.data = None
self.code_page = 0
@property
def encoding(self):
if self.code_page == 0:
return 'ascii'
else:
return 'cp%d' % (self.code_page)
def get_data(self):
return self.data
def get_text(self, errors='strict'):
return self.data.decode(self.encoding, errors)
class IconGroupResource(object):
code_page = 0
type = 14
_entry = Struct('<BBBxHHIH')
Icon = namedtuple('Icon', ('width', 'height', 'planes', 'bpp', 'size', 'id'))
def __init__(self):
self.icons = []
def add_icon(self, *args, **kwargs):
self.icons.append(self.Icon(*args, **kwargs))
def get_data(self):
data = bytearray(pack('<HHH', 0, 1, len(self.icons)))
for width, height, planes, bpp, size, id in self.icons:
colors = 1 << (planes * bpp)
if colors >= 256:
colors = 0
if width >= 256:
width = 0
if height >= 256:
height = 0
data += self._entry.pack(width, height, colors, planes, bpp, size, id)
return data
def unpack_from(self, data, offs=0):
type, count = unpack('<HH', data[offs+2:offs+6])
offs += 6
for i in range(count):
width, height, colors, planes, bpp, size, id = \
self._entry.unpack(data[offs:offs+14])
if width == 0:
width = 256
if height == 0:
height = 256
self.icons.append(self.Icon(width, height, planes, bpp, size, id))
offs += 14
class VersionInfoResource(object):
code_page = 0
type = 16
def __init__(self):
self.string_info = {}
self.var_info = {}
self.signature = 0xFEEF04BD
self.struct_version = 0x10000
self.file_version = (0, 0, 0, 0)
self.product_version = (0, 0, 0, 0)
self.file_flags_mask = 0x3f
self.file_flags = 0
self.file_os = 0x40004 # Windows NT
self.file_type = 1 # Application
self.file_subtype = 0
self.file_date = (0, 0)
def get_data(self):
# The first part of the header is pretty much fixed - we'll go
# back later to write the struct size.
data = bytearray(b'\x00\x004\x00\x00\x00V\x00S\x00_\x00V\x00E\x00R\x00S\x00I\x00O\x00N\x00_\x00I\x00N\x00F\x00O\x00\x00\x00\x00\x00')
data += pack('<13I', self.signature, self.struct_version,
self.file_version[1] | (self.file_version[0] << 16),
self.file_version[3] | (self.file_version[2] << 16),
self.product_version[1] | (self.product_version[0] << 16),
self.product_version[3] | (self.product_version[2] << 16),
self.file_flags_mask, self.file_flags,
self.file_os, self.file_type, self.file_subtype,
self.file_date[0], self.file_date[1])
self._pack_info(data, 'StringFileInfo', self.string_info)
self._pack_info(data, 'VarFileInfo', self.var_info)
data[0:2] = pack('<H', len(data))
return data
def _pack_info(self, data, key, value):
offset = len(data)
if isinstance(value, dict):
type = 1
value_length = 0
elif isinstance(value, bytes) or isinstance(value, unicode):
type = 1
value_length = len(value) * 2 + 2
else:
type = 0
value_length = len(value)
data += pack('<HHH', 0, value_length, type)
for c in key:
data += pack('<H', ord(c))
data += b'\x00\x00'
if len(data) & 2:
data += b'\x00\x00'
assert len(data) & 3 == 0
if isinstance(value, dict):
for key2, value2 in sorted(value.items(), key=lambda x:x[0]):
self._pack_info(data, key2, value2)
elif isinstance(value, bytes) or isinstance(value, unicode):
for c in value:
data += pack('<H', ord(c))
data += b'\x00\x00'
else:
data += value
if len(data) & 1:
data += b'\x00'
if len(data) & 2:
data += b'\x00\x00'
assert len(data) & 3 == 0
data[offset:offset+2] = pack('<H', len(data) - offset)
def unpack_from(self, data):
length, value_length = unpack('<HH', data[0:4])
offset = 40 + value_length + (value_length & 1)
dwords = array('I')
dwords.fromstring(bytes(data[40:offset]))
if len(dwords) > 0:
self.signature = dwords[0]
if len(dwords) > 1:
self.struct_version = dwords[1]
if len(dwords) > 3:
self.file_version = \
(int(dwords[2] >> 16), int(dwords[2] & 0xffff),
int(dwords[3] >> 16), int(dwords[3] & 0xffff))
if len(dwords) > 5:
self.product_version = \
(int(dwords[4] >> 16), int(dwords[4] & 0xffff),
int(dwords[5] >> 16), int(dwords[5] & 0xffff))
if len(dwords) > 7:
self.file_flags_mask = dwords[6]
self.file_flags = dwords[7]
if len(dwords) > 8:
self.file_os = dwords[8]
if len(dwords) > 9:
self.file_type = dwords[9]
if len(dwords) > 10:
self.file_subtype = dwords[10]
if len(dwords) > 12:
self.file_date = (dwords[11], dwords[12])
while offset < length:
offset += self._unpack_info(self, data, offset)
def __getitem__(self, key):
if key == 'StringFileInfo':
return self.string_info
elif key == 'VarFileInfo':
return self.var_info
else:
raise KeyError("%s does not exist" % (key))
def __contains__(self, key):
return key in ('StringFileInfo', 'VarFileInfo')
def _unpack_info(self, dict, data, offset):
length, value_length, type = unpack('<HHH', data[offset:offset+6])
assert length > 0
end = offset + length
offset += 6
key = ""
c, = unpack('<H', data[offset:offset+2])
offset += 2
while c:
key += unichr(c)
c, = unpack('<H', data[offset:offset+2])
offset += 2
# Padding bytes to align value to 32-bit boundary.
offset = _padded(offset, 4)
if value_length > 0:
# It contains a value.
if type:
# It's a wchar array value.
value = u""
c, = unpack('<H', data[offset:offset+2])
offset += 2
while c:
value += unichr(c)
c, = unpack('<H', data[offset:offset+2])
offset += 2
else:
# A binary value.
value = bytes(data[offset:offset+value_length])
offset += value_length
dict[key] = value
else:
# It contains sub-entries.
if key not in dict:
dict[key] = {}
subdict = dict[key]
while offset < end:
offset += self._unpack_info(subdict, data, offset)
# Padding bytes to pad value to 32-bit boundary.
return _padded(length, 4)
class ResourceTable(object):
""" A table in the resource directory. """
_header = Struct('<IIHHHH')
def __init__(self, ident=()):
self.flags = 0
self.timdat = 0
self.version = (0, 0)
self._name_leaves = []
self._id_leaves = []
self._ident = ident
self._strings_size = 0 # Amount of space occupied by table keys.
self._descs_size = 0
def __getitem__(self, key):
if isinstance(key, int):
leaves = self._id_leaves
else:
leaves = self._name_leaves
i = 0
while i < len(leaves):
idname, leaf = leaves[i]
if idname >= key:
if key == idname:
return leaf
break
i += 1
if not isinstance(key, int):
self._strings_size += _padded(len(key) * 2 + 2, 4)
leaf = ResourceTable(ident=self._ident + (key,))
leaves.insert(i, (key, leaf))
return leaf
def __setitem__(self, key, value):
""" Adds the given item to the table. Maintains sort order. """
if isinstance(key, int):
leaves = self._id_leaves
else:
leaves = self._name_leaves
if not isinstance(value, ResourceTable):
self._descs_size += 16
value._ident = self._ident + (key,)
i = 0
while i < len(leaves):
idname, leaf = leaves[i]
if idname >= key:
if key == idname:
if not isinstance(leaves[i][1], ResourceTable):
self._descs_size -= 16
leaves[i] = (key, value)
return
break
i += 1
if not isinstance(key, int):
self._strings_size += _padded(len(key) * 2 + 2, 4)
leaves.insert(i, (key, value))
def __len__(self):
return len(self._name_leaves) + len(self._id_leaves)
def __iter__(self):
keys = []
for name, leaf in self._name_leaves:
keys.append(name)
for id, leaf in self._id_leaves:
keys.append(id)
return iter(keys)
def items(self):
return self._name_leaves + self._id_leaves
def count_resources(self):
"""Counts all of the resources."""
count = 0
for key, leaf in self._name_leaves + self._id_leaves:
if isinstance(leaf, ResourceTable):
count += leaf.count_resources()
else:
count += 1
return count
def get_nested_tables(self):
"""Returns all tables in this table and subtables."""
# First we yield child tables, then nested tables. This is the
# order in which pack_into assumes the tables will be written.
for key, leaf in self._name_leaves + self._id_leaves:
if isinstance(leaf, ResourceTable):
yield leaf
for key, leaf in self._name_leaves + self._id_leaves:
if isinstance(leaf, ResourceTable):
for table in leaf.get_nested_tables():
yield table
def pack_header(self, data, offs):
self._header.pack_into(data, offs, self.flags, self.timdat,
self.version[0], self.version[1],
len(self._name_leaves), len(self._id_leaves))
def unpack_from(self, mem, addr=0, offs=0):
start = addr + offs
self.flags, self.timdat, majver, minver, nnames, nids = \
self._header.unpack(mem[start:start+16])
self.version = (majver, minver)
start += 16
# Subtables/entries specified by string name.
self._name_leaves = []
for i in range(nnames):
name_p, data = unpack('<II', mem[start:start+8])
if name_p & 0x80000000:
name = _unpack_wstring(mem, addr + (name_p & 0x7fffffff))
else:
# Not sure what to do with this; I don't have a file with this.
name = str(name_p)
if data & 0x80000000:
entry = ResourceTable(self._ident + (name,))
entry.unpack_from(mem, addr, data & 0x7fffffff)
else:
entry = self._unpack_data_entry(mem, addr + data, ident=self._ident+(name,))
self._descs_size += 16
self._name_leaves.append((name, entry))
self._strings_size += _padded(len(name) * 2 + 2, 4)
start += 8
# Subtables/entries specified by integer ID.
self._id_leaves = []
for i in range(nids):
id, data = unpack('<II', mem[start:start+8])
if data & 0x80000000:
entry = ResourceTable(self._ident + (id,))
entry.unpack_from(mem, addr, data & 0x7fffffff)
else:
entry = self._unpack_data_entry(mem, addr + data, ident=self._ident+(id,))
self._descs_size += 16
self._id_leaves.append((id, entry))
start += 8
def _unpack_data_entry(self, mem, addr, ident):
rva, size, code_page = unpack('<III', mem[addr:addr+12])
type, name, lang = ident
#print("%s/%s/%s: %s [%s]" % (type, name, lang, size, code_page))
data = mem[rva:rva+size]
if type == VersionInfoResource.type:
entry = VersionInfoResource()
entry.unpack_from(data)
elif type == IconGroupResource.type:
entry = IconGroupResource()
entry.unpack_from(data)
else:
entry = DataResource()
entry.data = data
entry.code_page = code_page
class PEFile(object):
imports = ()
def open(self, fn, mode='r'):
if 'b' not in mode:
mode += 'b'
self.fp = open(fn, mode)
self.read(self.fp)
def close(self):
self.fp.close()
def read(self, fp):
""" Reads a PE file from the given file object, which must be opened
in binary mode. """
# Read position of header.
fp.seek(0x3c)
offset, = unpack('<I', fp.read(4))
fp.seek(offset)
if fp.read(4) != b'PE\0\0':
raise ValueError("Invalid PE file.")
# Read the COFF header.
self.machine, nscns, timdat, symptr, nsyms, opthdr, flags = \
unpack('<HHIIIHH', fp.read(20))
if nscns == 0:
raise ValueError("No sections found.")
if not opthdr:
raise ValueError("No opthdr found.")
# Read part of the opthdr.
magic, self.code_size, self.initialized_size, self.uninitialized_size = \
unpack('<HxxIII', fp.read(16))
# Read alignments.
fp.seek(16, 1)
self.section_alignment, self.file_alignment = unpack('<II', fp.read(8))
# Read header/image sizes.
fp.seek(16, 1)
self.image_size, self.header_size = unpack('<II', fp.read(8))
if magic == 0x010b: # 32-bit.
fp.seek(28, 1)
elif magic == 0x20B: # 64-bit.
fp.seek(44, 1)
else:
raise ValueError("unknown type 0x%x" % (magic))
self.rva_offset = fp.tell()
numrvas, = unpack('<I', fp.read(4))
self.exp_rva = RVASize(0, 0)
self.imp_rva = RVASize(0, 0)
self.res_rva = RVASize(0, 0)
# Locate the relevant tables in memory.
if numrvas >= 1:
self.exp_rva = RVASize(*unpack('<II', fp.read(8)))
if numrvas >= 2:
self.imp_rva = RVASize(*unpack('<II', fp.read(8)))
if numrvas >= 3:
self.res_rva = RVASize(*unpack('<II', fp.read(8)))
# Skip the rest of the tables.
if numrvas >= 4:
fp.seek((numrvas - 3) * 8, 1)
# Loop through the sections to find the ones containing our tables.
self.sections = []
for i in range(nscns):
section = Section()
section.read_header(fp)
self.sections.append(section)
self.sections.sort()
# Read the sections into some kind of virtual memory.
self.vmem = bytearray(self.sections[-1].vaddr + self.sections[-1].size)
memview = memoryview(self.vmem)
for section in self.sections:
fp.seek(section.offset)
fp.readinto(memview[section.vaddr:section.vaddr+section.size])
# Read the import table.
start = self.imp_rva.addr
dir = impdirtab(*unpack('<IIIII', self.vmem[start:start+20]))
imports = []
while dir.name and dir.lookup:
name = _unpack_zstring(self.vmem, dir.name)
imports.append(name)
start += 20
dir = impdirtab(*unpack('<IIIII', self.vmem[start:start+20]))
# Make it a tuple to indicate we don't support modifying it for now.
self.imports = tuple(imports)
# Read the resource tables from the .rsrc section.
self.resources = ResourceTable()
if self.res_rva.addr and self.res_rva.size:
self.resources.unpack_from(self.vmem, self.res_rva.addr)
def get_export_address(self, symbol_name):
""" Finds the virtual address for a named export symbol. """
if isinstance(symbol_name, bytes):
symbol_name = symbol_name.decode('ascii')
start = self.exp_rva.addr
expdir = expdirtab(*unpack('<IIHHIIIIIII', self.vmem[start:start+40]))
if expdir.nnames == 0 or expdir.ordinals == 0 or expdir.names == 0:
return None
nptr = expdir.names
optr = expdir.ordinals
for i in range(expdir.nnames):
name_rva, = unpack('<I', self.vmem[nptr:nptr+4])
ordinal, = unpack('<H', self.vmem[optr:optr+2])
if name_rva != 0:
name = _unpack_zstring(self.vmem, name_rva)
if name == symbol_name:
assert ordinal >= 0 and ordinal < expdir.nentries
start = expdir.entries + 4 * ordinal
addr, = unpack('<I', self.vmem[start:start+4])
return addr
nptr += 4
optr += 2
def get_address_offset(self, addr):
""" Turns an address into a offset relative to the file beginning. """
section = self.get_address_section(addr)
if section is not None:
return (addr - section.vaddr) + section.offset
def get_address_section(self, addr):
""" Returns the section that this virtual address belongs to. """
for section in self.sections:
if addr >= section.vaddr and addr < section.vaddr + section.size:
return section
def add_icon(self, icon, ordinal=2):
""" Adds an icon resource from the given Icon object. Requires
calling add_resource_section() afterwards. """
group = IconGroupResource()
self.resources[group.type][ordinal][1033] = group
images = sorted(icon.images.items(), key=lambda x:-x[0])
id = 1
# Write 8-bpp image headers for sizes under 256x256.
for size, image in images:
if size >= 256:
continue
xorsize = size
if xorsize % 4 != 0:
xorsize += 4 - (xorsize % 4)
andsize = (size + 7) >> 3
if andsize % 4 != 0:
andsize += 4 - (andsize % 4)
datasize = 40 + 256 * 4 + (xorsize + andsize) * size
group.add_icon(size, size, 1, 8, datasize, id)
buf = BytesIO()
icon._write_bitmap(buf, image, size, 8)
res = DataResource()
res.data = buf.getvalue()
self.resources[3][id][1033] = res
id += 1
# And now the 24/32 bpp versions.
for size, image in images:
if size > 256:
continue
# Calculate the size so we can write the offset within the file.
if image.hasAlpha():
bpp = 32
xorsize = size * 4
else:
bpp = 24
xorsize = size * 3 + (-(size * 3) & 3)
andsize = (size + 7) >> 3
if andsize % 4 != 0:
andsize += 4 - (andsize % 4)
datasize = 40 + (xorsize + andsize) * size
buf = BytesIO()
icon._write_bitmap(buf, image, size, bpp)
res = DataResource()
res.data = buf.getvalue()
self.resources[3][id][1033] = res
group.add_icon(size, size, 1, bpp, datasize, id)
id += 1
def add_section(self, name, flags, data):
""" Adds a new section with the given name, flags and data. The
virtual address space is automatically resized to fit the new data.
Returns the newly created Section object. """
if isinstance(name, unicode):
name = name.encode('ascii')
section = Section()
section.name = name
section.flags = flags
# Put it at the end of all the other sections.
section.offset = 0
for s in self.sections:
section.offset = max(section.offset, s.offset + s.size)
# Align the offset.
section.offset = _padded(section.offset, self.file_alignment)
# Find a place to put it in the virtual address space.
section.vaddr = len(self.vmem)
align = section.vaddr % self.section_alignment
if align:
pad = self.section_alignment - align
self.vmem += bytearray(pad)
section.vaddr += pad
section.vsize = len(data)
section.size = _padded(section.vsize, self.file_alignment)
self.vmem += data
self.sections.append(section)
# Update the size tallies from the opthdr.
self.image_size += _padded(section.vsize, self.section_alignment)
if flags & 0x20:
self.code_size += section.size
if flags & 0x40:
self.initialized_size += section.size
if flags & 0x80:
self.uninitialized_size += section.size
return section
def add_version_info(self, file_ver, product_ver, data, lang=1033, codepage=1200):
""" Adds a version info resource to the file. """
if "FileVersion" not in data:
data["FileVersion"] = '.'.join(file_ver)
if "ProductVersion" not in data:
data["ProductVersion"] = '.'.join(product_ver)
assert len(file_ver) == 4
assert len(product_ver) == 4
res = VersionInfoResource()
res.file_version = file_ver
res.product_version = product_ver
res.string_info = {
"%04x%04x" % (lang, codepage): data
}
res.var_info = {
"Translation": bytearray(pack("<HH", lang, codepage))
}
self.resources[16][1][lang] = res
def add_resource_section(self):
""" Adds a resource section to the file containing the resources that
were previously added via add_icon et al. Assumes the file does not
contain a resource section yet. """
# Calculate how much space to reserve.
tables = [self.resources] + list(self.resources.get_nested_tables())
table_size = 0
string_size = 0
desc_size = 16 * self.resources.count_resources()
for table in tables:
table._offset = table_size
table_size += 16 + 8 * len(table)
string_size += table._strings_size
desc_size += table._descs_size
# Now write the actual data.
tbl_offs = 0
str_offs = table_size
desc_offs = str_offs + string_size
data_offs = desc_offs + desc_size
data = bytearray(data_offs)
data_addr = _padded(len(self.vmem), self.section_alignment) + data_offs
for table in tables:
table.pack_header(data, tbl_offs)
tbl_offs += 16
for name, leaf in table._name_leaves:
if isinstance(leaf, ResourceTable):
pack_into('<II', data, tbl_offs, str_offs | 0x80000000, leaf._offset | 0x80000000)
else:
pack_into('<II', data, tbl_offs, str_offs | 0x80000000, desc_offs)
resdata = leaf.get_data()
pack_into('<IIII', data, desc_offs, data_addr, len(resdata), leaf.code_page, 0)
data += resdata
desc_offs += 16
data_addr += len(resdata)
align = len(resdata) & 3
if align:
data += bytearray(4 - align)
data_addr += 4 - align
tbl_offs += 8
# Pack the name into the string table.
pack_into('<H', data, str_offs, len(name))
str_offs += 2
for c in name:
pack_into('<H', data, str_offs, ord(c))
str_offs += 2
str_offs = _padded(str_offs, 4)
for id, leaf in table._id_leaves:
if isinstance(leaf, ResourceTable):
pack_into('<II', data, tbl_offs, id, leaf._offset | 0x80000000)
else:
pack_into('<II', data, tbl_offs, id, desc_offs)
resdata = leaf.get_data()
pack_into('<IIII', data, desc_offs, data_addr, len(resdata), leaf.code_page, 0)
data += resdata
desc_offs += 16
data_addr += len(resdata)
align = len(resdata) & 3
if align:
data += bytearray(4 - align)
data_addr += 4 - align
tbl_offs += 8
flags = 0x40000040 # readable, contains initialized data
section = self.add_section('.rsrc', flags, data)
self.res_rva = RVASize(section.vaddr, section.vsize)
def write_changes(self):
""" Assuming the file was opened in read-write mode, writes back the
changes made via this class to the .exe file. """
fp = self.fp
# Read position of header.
fp.seek(0x3c)
offset, = unpack('<I', fp.read(4))
fp.seek(offset)
if fp.read(4) != b'PE\0\0':
raise ValueError("Invalid PE file.")
# Sync read/write pointer. Necessary before write. Bug in Python?
fp.seek(fp.tell())
# Rewrite the first part of the COFF header.
timdat = int(time.time())
fp.write(pack('<HHI', self.machine, len(self.sections), timdat))
# Write calculated init and uninitialised sizes to the opthdr.
fp.seek(16, 1)
fp.write(pack('<III', self.code_size, self.initialized_size, self.uninitialized_size))
# Same for the image and header size.
fp.seek(40, 1)
fp.write(pack('<II', self.image_size, self.header_size))
# Write the modified RVA table.
fp.seek(self.rva_offset)
numrvas, = unpack('<I', fp.read(4))
assert numrvas >= 3
fp.seek(self.rva_offset + 4)
if numrvas >= 1:
fp.write(pack('<II', *self.exp_rva))
if numrvas >= 2:
fp.write(pack('<II', *self.imp_rva))
if numrvas >= 3:
fp.write(pack('<II', *self.res_rva))
# Skip the rest of the tables.
if numrvas >= 4:
fp.seek((numrvas - 3) * 8, 1)
# Write the modified section headers.
for section in self.sections:
section.write_header(fp)
assert fp.tell() <= self.header_size
# Write the section data of modified sections.
for section in self.sections:
if not section.modified:
continue
fp.seek(section.offset)
size = min(section.vsize, section.size)
fp.write(self.vmem[section.vaddr:section.vaddr+size])
pad = section.size - size
assert pad >= 0
if pad > 0:
fp.write(bytearray(pad))
section.modified = False

View File

@ -59,7 +59,7 @@ Options::
import getopt
import sys
import os
from direct.showutil import FreezeTool
from . import FreezeTool
def usage(code, msg = ''):
if __doc__:

View File

@ -891,7 +891,7 @@ describe_message(std::ostream &out, const string &prefix,
const Datagram &dg) const {
DCPacker packer;
packer.set_unpack_data(dg.get_message());
packer.set_unpack_data((const char *)dg.get_data(), dg.get_length(), false);
CHANNEL_TYPE do_id;
int msg_type;
bool is_update = false;

View File

@ -16,6 +16,13 @@ clunky approach. - Josh
"""
from .FilterManager import FilterManager
from .filterBloomI import BLOOM_I
from .filterBloomX import BLOOM_X
from .filterBloomY import BLOOM_Y
from .filterBlurX import BLUR_X
from .filterBlurY import BLUR_Y
from .filterCopy import COPY
from .filterDown4 import DOWN_4
from panda3d.core import LVecBase4, LPoint2
from panda3d.core import Filename
from panda3d.core import AuxBitplaneAttrib
@ -102,12 +109,6 @@ class CommonFilters:
self.task = None
self.cleanup()
def loadShader(self, name):
fn = os.path.join(os.path.abspath(os.path.dirname(__file__)), name)
fn = Filename.fromOsSpecific(fn)
fn.makeTrueCase()
return Shader.load(fn)
def cleanup(self):
self.manager.cleanup()
self.textures = {}
@ -187,9 +188,9 @@ class CommonFilters:
self.blur.append(self.manager.renderQuadInto("filter-blur0", colortex=blur0,div=2))
self.blur.append(self.manager.renderQuadInto("filter-blur1", colortex=blur1))
self.blur[0].setShaderInput("src", self.textures["color"])
self.blur[0].setShader(self.loadShader("filter-blurx.sha"))
self.blur[0].setShader(Shader.make(BLUR_X, Shader.SL_Cg))
self.blur[1].setShaderInput("src", blur0)
self.blur[1].setShader(self.loadShader("filter-blury.sha"))
self.blur[1].setShader(Shader.make(BLUR_Y, Shader.SL_Cg))
if ("AmbientOcclusion" in configuration):
ssao0=self.textures["ssao0"]
@ -203,9 +204,9 @@ class CommonFilters:
self.ssao[0].setShaderInput("random", loader.loadTexture("maps/random.rgb"))
self.ssao[0].setShader(Shader.make(SSAO_BODY % configuration["AmbientOcclusion"].numsamples, Shader.SL_Cg))
self.ssao[1].setShaderInput("src", ssao0)
self.ssao[1].setShader(self.loadShader("filter-blurx.sha"))
self.ssao[1].setShader(Shader.make(BLUR_X, Shader.SL_Cg))
self.ssao[2].setShaderInput("src", ssao1)
self.ssao[2].setShader(self.loadShader("filter-blury.sha"))
self.ssao[2].setShader(Shader.make(BLUR_Y, Shader.SL_Cg))
if ("Bloom" in configuration):
bloomconf = configuration["Bloom"]
@ -215,25 +216,28 @@ class CommonFilters:
bloom3=self.textures["bloom3"]
if (bloomconf.size == "large"):
scale=8
downsampler="filter-down4"
downsamplerName="filter-down4"
downsampler=DOWN_4
elif (bloomconf.size == "medium"):
scale=4
downsampler="filter-copy"
downsamplerName="filter-copy"
downsampler=COPY
else:
scale=2
downsampler="filter-copy"
downsamplerName="filter-copy"
downsampler=COPY
self.bloom.append(self.manager.renderQuadInto("filter-bloomi", colortex=bloom0, div=2, align=scale))
self.bloom.append(self.manager.renderQuadInto(downsampler, colortex=bloom1, div=scale, align=scale))
self.bloom.append(self.manager.renderQuadInto(downsamplerName, colortex=bloom1, div=scale, align=scale))
self.bloom.append(self.manager.renderQuadInto("filter-bloomx", colortex=bloom2, div=scale, align=scale))
self.bloom.append(self.manager.renderQuadInto("filter-bloomy", colortex=bloom3, div=scale, align=scale))
self.bloom[0].setShaderInput("src", self.textures["color"])
self.bloom[0].setShader(self.loadShader("filter-bloomi.sha"))
self.bloom[0].setShader(Shader.make(BLOOM_I, Shader.SL_Cg))
self.bloom[1].setShaderInput("src", bloom0)
self.bloom[1].setShader(self.loadShader(downsampler + ".sha"))
self.bloom[1].setShader(Shader.make(downsampler, Shader.SL_Cg))
self.bloom[2].setShaderInput("src", bloom1)
self.bloom[2].setShader(self.loadShader("filter-bloomx.sha"))
self.bloom[2].setShader(Shader.make(BLOOM_X, Shader.SL_Cg))
self.bloom[3].setShaderInput("src", bloom2)
self.bloom[3].setShader(self.loadShader("filter-bloomy.sha"))
self.bloom[3].setShader(Shader.make(BLOOM_Y, Shader.SL_Cg))
texcoords = {}
texcoordPadding = {}
@ -558,7 +562,6 @@ class CommonFilters:
set_cartoon_ink = setCartoonInk
del_bloom = delBloom
del_ambient_occlusion = delAmbientOcclusion
load_shader = loadShader
set_blur_sharpen = setBlurSharpen
del_blur_sharpen = delBlurSharpen
del_volumetric_lighting = delVolumetricLighting

View File

@ -1,3 +1,4 @@
BLOOM_I = """
//Cg
//
// blend.rgb
@ -23,7 +24,7 @@
// trigger.y
//
// Must be equal to (1.0/(maxtrigger-mintrigger)) where
//
//
// mintrigger is the minimum brightness to trigger a bloom,
// and maxtrigger is the brightness at which the bloom
// reaches maximum intensity.
@ -83,3 +84,4 @@ void fshader(float2 l_texcoordNW : TEXCOORD0,
o_color = (colorNW + colorNE + colorSW + colorSE) * 0.25;
}
"""

View File

@ -1,3 +1,4 @@
BLOOM_X = """
//Cg
void vshader(float4 vtx_position : POSITION,
@ -46,3 +47,4 @@ void fshader(float4 l_texcoord0 : TEXCOORD0,
color += 50 * tex2D(k_src, l_texcoord2.zw);
o_color = color / 1200.0;
}
"""

View File

@ -1,3 +1,4 @@
BLOOM_Y = """
//Cg
void vshader(float4 vtx_position : POSITION,
@ -37,3 +38,4 @@ void fshader(float4 l_texcoord0 : TEXCOORD0,
o_color = color / 1200.0;
o_color = o_color * k_intensity;
}
"""

View File

@ -1,3 +1,4 @@
BLUR_X = """
//Cg
//
//Cg profile arbvp1 arbfp1
@ -33,3 +34,4 @@ void fshader(float2 l_texcoord0 : TEXCOORD0,
o_color.w = 1;
}
"""

View File

@ -1,3 +1,4 @@
BLUR_Y = """
//Cg
//
//Cg profile arbvp1 arbfp1
@ -32,4 +33,4 @@ void fshader(float2 l_texcoord0 : TEXCOORD0,
o_color /= 7;
o_color.w = 1;
}
"""

View File

@ -1,3 +1,4 @@
COPY = """
//Cg
@ -17,4 +18,4 @@ void fshader(float2 l_texcoord : TEXCOORD0,
{
o_color = tex2D(k_src, l_texcoord);
}
"""

View File

@ -1,3 +1,4 @@
DOWN_4 = """
//Cg
void vshader(float4 vtx_position : POSITION,
@ -30,4 +31,4 @@ void fshader(float2 l_texcoordNW : TEXCOORD0,
float4 colorSE = tex2D(k_src, l_texcoordSE);
o_color = (colorNW + colorNE + colorSW + colorSE);
}
"""

View File

@ -19,7 +19,7 @@ from direct.p3d.SeqValue import SeqValue
from direct.p3d.HostInfo import HostInfo
from direct.showbase import Loader
from direct.showbase import AppRunnerGlobal
from direct.showutil import FreezeTool
from direct.dist import FreezeTool
from direct.directnotify.DirectNotifyGlobal import *
vfs = VirtualFileSystem.getGlobalPtr()

View File

@ -71,10 +71,6 @@ class panda3d(package):
if sys.version_info < (3, 0):
module('encodings.string_escape')
# Pick up the shader files that appear in direct/src/filter.
import direct
file(Filename(direct.__path__[0], 'filter/*.sha'), newDir = 'direct/filter')
# pandac.PandaModules pulls in other Panda3D libs automatically.
# Exclude these Panda3D libs; they are big and many applications don't
# use them. We define them as separate, optional packages, below,

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

After

Width:  |  Height:  |  Size: 144 KiB

View File

@ -170,6 +170,7 @@ class ShowBase(DirectObject.DirectObject):
self.trackball = None
self.texmem = None
self.showVertices = None
self.deviceButtonThrowers = []
## This is a NodePath pointing to the Camera object set up for the 3D scene.
## This is usually a child of self.camera.
@ -294,6 +295,7 @@ class ShowBase(DirectObject.DirectObject):
## The global job manager, as imported from JobManagerGlobal.
self.jobMgr = jobMgr
## Particle manager
self.particleMgr = None
self.particleMgrEnabled = 0
@ -303,6 +305,11 @@ class ShowBase(DirectObject.DirectObject):
self.physicsMgrEnabled = 0
self.physicsMgrAngular = 0
## This is the global input device manager, which keeps track of
## connected input devices.
self.devices = InputDeviceManager.getGlobalPtr()
self.__inputDeviceNodes = {}
self.createStats()
self.AppHasAudioFocus = 1
@ -1670,6 +1677,57 @@ class ShowBase(DirectObject.DirectObject):
return self.mouseWatcherNode.getModifierButtons().isDown(
KeyboardButton.meta())
def attachInputDevice(self, device, prefix=None):
"""
This function attaches an input device to the data graph, which will
cause the device to be polled and generate events. If a prefix is
given and not None, it is used to prefix events generated by this
device, separated by a hyphen.
If you call this, you should consider calling detachInputDevice when
you are done with the device or when it is disconnected.
"""
# Protect against the same device being attached multiple times.
assert device not in self.__inputDeviceNodes
idn = self.dataRoot.attachNewNode(InputDeviceNode(device, device.name))
# Setup the button thrower to generate events for the device.
bt = idn.attachNewNode(ButtonThrower(device.name))
if prefix is not None:
bt.node().setPrefix(prefix + '-')
assert self.notify.debug("Attached input device {0} with prefix {1}".format(device, prefix))
self.__inputDeviceNodes[device] = idn
self.deviceButtonThrowers.append(bt)
def detachInputDevice(self, device):
"""
This should be called after attaching an input device using
attachInputDevice and the device is disconnected or you no longer wish
to keep polling this device for events.
You do not strictly need to call this if you expect the device to be
reconnected (but be careful that you don't reattach it).
"""
if device not in self.__inputDeviceNodes:
assert device in self.__inputDeviceNodes
return
assert self.notify.debug("Detached device {0}".format(device.name))
# Remove the ButtonThrower from the deviceButtonThrowers list.
idn = self.__inputDeviceNodes[device]
for bt in self.deviceButtonThrowers:
if idn.isAncestorOf(bt):
self.deviceButtonThrowers.remove(bt)
break
idn.removeNode()
del self.__inputDeviceNodes[device]
def addAngularIntegrator(self):
if not self.physicsMgrAngular:
physics = importlib.import_module('panda3d.physics')
@ -1859,6 +1917,9 @@ class ShowBase(DirectObject.DirectObject):
return Task.cont
def __dataLoop(self, state):
# Check if there were newly connected devices.
self.devices.update()
# traverse the data graph. This reads all the control
# inputs (from the mouse and keyboard, for instance) and also
# directly acts upon them (for instance, to move the avatar).
@ -3074,6 +3135,8 @@ class ShowBase(DirectObject.DirectObject):
setup_mouse = setupMouse
setup_mouse_cb = setupMouseCB
enable_software_mouse_pointer = enableSoftwareMousePointer
detach_input_device = detachInputDevice
attach_input_device = attachInputDevice
add_angular_integrator = addAngularIntegrator
enable_particles = enableParticles
disable_particles = disableParticles

View File

@ -89,6 +89,8 @@ class Transitions:
self.fade.setBin('unsorted', 0)
self.fade.setColor(0,0,0,0)
self.fade.setScale(max(base.a2dRight, base.a2dTop))
def getFadeInIval(self, t=0.5, finishIval=None, blendType='noBlend'):
"""
Returns an interval without starting it. This is particularly useful in
@ -97,8 +99,7 @@ class Transitions:
#self.noTransitions() masad: this creates a one frame pop, is it necessary?
self.loadFade()
parent = aspect2d if self.fadeModel else render2d
transitionIval = Sequence(Func(self.fade.reparentTo, parent, DGG.FADE_SORT_INDEX),
transitionIval = Sequence(Func(self.fade.reparentTo, aspect2d, DGG.FADE_SORT_INDEX),
Func(self.fade.showThrough), # in case aspect2d is hidden for some reason
self.lerpFunc(self.fade, t,
self.alphaOff,
@ -120,8 +121,7 @@ class Transitions:
self.noTransitions()
self.loadFade()
parent = aspect2d if self.fadeModel else render2d
transitionIval = Sequence(Func(self.fade.reparentTo, parent, DGG.FADE_SORT_INDEX),
transitionIval = Sequence(Func(self.fade.reparentTo, aspect2d, DGG.FADE_SORT_INDEX),
Func(self.fade.showThrough), # in case aspect2d is hidden for some reason
self.lerpFunc(self.fade, t,
self.alphaOn,
@ -181,8 +181,7 @@ class Transitions:
self.noTransitions()
self.loadFade()
parent = aspect2d if self.fadeModel else render2d
self.fade.reparentTo(parent, DGG.FADE_SORT_INDEX)
self.fade.reparentTo(aspect2d, DGG.FADE_SORT_INDEX)
self.fade.setColor(self.alphaOn)
elif ConfigVariableBool('no-loading-screen', False):
if finishIval:
@ -215,8 +214,7 @@ class Transitions:
self.noTransitions()
self.loadFade()
parent = aspect2d if self.fadeModel else render2d
self.fade.reparentTo(parent, DGG.FADE_SORT_INDEX)
self.fade.reparentTo(aspect2d, DGG.FADE_SORT_INDEX)
self.fade.setColor(self.alphaOn[0],
self.alphaOn[1],
self.alphaOn[2],
@ -232,8 +230,7 @@ class Transitions:
self.noTransitions()
self.loadFade()
parent = aspect2d if self.fadeModel else render2d
self.fade.reparentTo(parent, DGG.FADE_SORT_INDEX)
self.fade.reparentTo(aspect2d, DGG.FADE_SORT_INDEX)
self.fade.setColor(color)
def noFade(self):

View File

@ -277,13 +277,6 @@ class _local(object):
d = _get_thread_locals(core.Thread.getCurrentThread(), id(self))
d[key] = value
## def __getattr__(self, key):
## d = _get_thread_locals(core.Thread.getCurrentThread(), id(self))
## try:
## return d[key]
## except KeyError:
## raise AttributeError
def __getattribute__(self, key):
d = _get_thread_locals(core.Thread.getCurrentThread(), id(self))
if key == '__dict__':
@ -292,6 +285,3 @@ class _local(object):
return d[key]
except KeyError:
return object.__getattribute__(self, key)

View File

@ -194,7 +194,6 @@ it will show you the available command-line options:
--use-wx --no-wx (enable/disable use of WX)
--use-fltk --no-fltk (enable/disable use of FLTK)
--use-rocket --no-rocket (enable/disable use of ROCKET)
--use-awesomium --no-awesomium (enable/disable use of AWESOMIUM)
--use-carbon --no-carbon (enable/disable use of CARBON)
--use-cocoa --no-cocoa (enable/disable use of COCOA)
--use-x11 --no-x11 (enable/disable use of X11)

View File

@ -1,3 +1,151 @@
------------------------ RELEASE 1.10.0 -----------------------
This is a major release with significant changes. Please review the
changes when upgrading. The list below is by no means exhaustive, but
should contain the most important changes.
General
* Experimental ability to build for Android
* New input framework to natively support gamepads, joysticks, etc.
* Multi-threaded render pipeline is a lot more stable now
* New setuptools-based deployment pipeline
* Improvements to mouselook smoothness
* Cache is now at $XDG_CACHE_HOME/panda3d (~/.cache/panda3d), not ~/.panda3d
* Addition of unit test suite
* Many improvements to thread safety
* Many performance improvements
* Tons of bugfixes
* Big style cleanup of C++ source code
Python API
* Complete support for Python 3
* Support for coroutines and async/await
* Property interfaces have been added for many settings
* More flexible handling for keyboard arguments in C++ APIs
* Python bindings are completely separated out of the C++ libraries.
* Interrogate binding generator has many improvements.
* Use of pandac.PandaModules is discouraged, use panda3d.core et al
* Use of libRocket is discouraged due to lack of Python 3 support
* Tasks are now sorted in addition order when lacking a sort value
* Fixes iris/fade transitions for extreme aspect ratios
* WeakNodePath is now exposed to Python
* WindowProperties.size(x, y) deprecated; use WindowProperties(size=(x, y))
* Calling bare run() is deprecated, use base.run() instead
* downcastTo*() methods have been removed, they were already no-ops
Rendering
* Add new shader-based terrain rendering method (ShaderTerrainMesh)
* The default ColorAttrib mode is now T_vertex
* The ColorAttrib T_off mode now properly disables vertex colors entirely
* Make handling of color attributes more consistent between renderers
* Ability to create an OpenGL core profile context; set "gl-version 3 2"
* Experimental support for reverse-Z rendering for best depth precision
* sRGB framebuffers supported more widely
* Support for infinite near/far clip in lens
* Add some PBR material parameters to material class
* Addition of more built-in GLSL shader inputs; see manual.
* Add p3d_FragData[] GLSL output for MRT in GLSL 1.30
* Add flag enabling vertex shader control over point size
* Support signed ints and double-precision floats in vertex data with GLSL
* Support unsigned 11/10/10-bit floating-point textures and vertex data
* Support for SSBOs via ShaderBuffer class
* Support OpenGL FBO buffers without any attachments
* Support passing uint variables to GLSL shader
* Allow rendering objects with empty vertex data (for vertex pulling)
* Add LogicOpAttrib, for supporting logical operator blending
* Improvements to OpenGL ES support
* Support for geometry with adjacency information
* Change default alpha blending to improve blending rendered result
* New method for obtaining native OpenGL texture object
* Support windowless offscreen rendering on macOS
* Panda resets OpenGL state better before and after draw callbacks
* OpenGL renderer better supports debugging tools like apitrace
* Support fixed-depth billboards, useful for 2D tags that don't change size
Shader generator
* Significant performance improvements
* Support for point light shadows
* Hardware skinning support
* Changes to match fixed-function pipeline better
* Fixes for normal vector normalization
* Support multiple normal maps (uses Reoriented Normal Mapping)
* Tracks modifications to materials and texture stages automatically
Lighting
* Allow specifying light color based on color temperature
* Setting specular color of a light separately is deprecated
* New GLSL inputs to make implementing lighting in shaders much easier
* Add representation for sphere light and rectangle light
* Efficiency improvements for passing light information to shader
* Interocular distance for shadow cameras now always defaults to 0
* Add low-level lighting module from RenderPipeline
Textures
* Support cube map arrays
* Support buffer textures
* Many more texture formats supported
* BC4 and BC5 compression modes supported
* Proper depth textures supported in DirectX 9 renderer
* set_ram_image(_as) directly supports buffer protocol
* TexturePeeker supports more formats and component types
Text
* Dramatic improvements to text rendering performance
* Support for HarfBuzz for higher-quality text shaping and kerning
* Support for right-to-left text
* Support for signed-distance-field rendering in egg-mkfont
Audio/video
* The default unit for audio is now 1 meter for each Panda unit.
* Native .flac loader
* Support videos with alpha channel in ffmpeg
* OpenAL stability improvements, especially on macOS
* Support loading .opus files with libopusfile
* Fix various memory leaks
Physics / collisions
* CollisionTube is renamed to CollisionCapsule.
* Box-box collision test is improved to work well with the Pusher
* More box tests for collision system: box-into-plane, box-into-poly
* Capsule (tube) can be used as "from" shape into plane, sphere, capsule, box
* Bullet objects are serializable to .bam files.
* Bullet bindings are now thread safe.
* Bullet debug drawer is more efficient; no longer inherits GeomNode.
* Various fixes to bullet vehicle wheel synchronization
* PhysX bindings are deprecated.
Pipeline / loading
* Support for Assimp library to load a broad variety of model formats
* Ability to specify min-lod, max-lod, lod-bias in .egg file
* Egg file materials support PBR-style material parameterization
* Support loading more DDS files, including DX10-style ones
* Add support for OpenEXR and HDR textures
* Support line/point thickness in bam2egg
* bam2egg no longer inserts a vestigial ModelNode at the top
* bam2egg supports depth test, offset, cull bin attributes
* Accept a .gz file wherever a .pz file is accepted
* egg-palettize supports mirror and border-color wrap modes
* More robust checks against memory corruptions when loading bad .bam files
* Support for Maya 2017 and 2018
* Support preprocessing GLSL shaders created with Shader.make
Build
* We now require using MSVC 2015 or 2017 to compile on Windows.
* At least GCC 4.8 is now required.
* With GCC/clang, enabling C++11 is now required.
* Allow building with more recent ffmpeg versions
* Support for old FFMpeg versions (before 1.1) dropped.
* The ppremake build system has been removed.
* Support for OpenSSL versions before 0.9.7 has been dropped.
C++
* Use of NULL is replaced with nullptr
* WeakPointerTo now requires use of lock() method for thread safety
* Mutex et al now satisfy C++11 Lockable constraints
* Panda headers no longer contain `using namespace std;`
* PN_int32 et al have been removed, use stdint.h types instead
* The need to link with pystub and add Python include dirs is removed.
------------------------ RELEASE 1.9.4 ------------------------
One of the bugfixes in the last 1.9.3 release introduced a regression,

File diff suppressed because it is too large Load Diff

View File

@ -25,6 +25,7 @@
#include "cppFunctionGroup.h"
#include "cppFunctionType.h"
#include "cppClosureType.h"
#include "cppReferenceType.h"
#include "cppStructType.h"
#include "cppBison.h"
#include "pdtoa.h"
@ -260,12 +261,12 @@ CPPExpression(CPPIdentifier *ident, CPPScope *current_scope,
_u._variable = inst;
return;
}
CPPFunctionGroup *fgroup = decl->as_function_group();
/*CPPFunctionGroup *fgroup = decl->as_function_group();
if (fgroup != nullptr) {
_type = T_function;
_u._fgroup = fgroup;
return;
}
}*/
}
_type = T_unknown_ident;
@ -1232,6 +1233,61 @@ determine_type() const {
return nullptr; // Compiler kludge; can't get here.
}
/**
* Returns true if this is an lvalue expression.
*/
bool CPPExpression::
is_lvalue() const {
switch (_type) {
case T_variable:
case T_function:
case T_unknown_ident:
return true;
case T_typecast:
case T_static_cast:
case T_dynamic_cast:
case T_const_cast:
case T_reinterpret_cast:
{
CPPReferenceType *ref_type = _u._typecast._to->as_reference_type();
return ref_type != nullptr && ref_type->_value_category == CPPReferenceType::VC_lvalue;
}
case T_unary_operation:
if (_u._op._operator == 'f') {
// A function returning an lvalue reference.
CPPType *return_type = determine_type();
if (return_type != nullptr) {
CPPReferenceType *ref_type = return_type->as_reference_type();
return ref_type != nullptr && ref_type->_value_category == CPPReferenceType::VC_lvalue;
}
}
return _u._op._operator == PLUSPLUS
|| _u._op._operator == MINUSMINUS
|| _u._op._operator == '*';
case T_binary_operation:
if (_u._op._operator == ',') {
CPPReferenceType *ref_type = _u._op._op2->as_reference_type();
return ref_type != nullptr && ref_type->_value_category == CPPReferenceType::VC_lvalue;
}
return (_u._op._operator == POINTSAT || _u._op._operator == ',');
case T_trinary_operation:
return _u._op._op2->is_lvalue() && _u._op._op3->is_lvalue();
case T_literal:
case T_raw_literal:
return true;
default:
break;
}
return false;
}
/**
* Returns true if this declaration is an actual, factual declaration, or
* false if some part of the declaration depends on a template parameter which

View File

@ -133,6 +133,7 @@ public:
Result evaluate() const;
CPPType *determine_type() const;
bool is_lvalue() const;
bool is_tbd() const;
virtual bool is_fully_specified() const;

View File

@ -12,6 +12,7 @@
*/
#include "globPattern.h"
#include "string_utils.h"
#include <ctype.h>
using std::string;
@ -199,9 +200,7 @@ r_match_files(const Filename &prefix, const string &suffix,
next_glob = *this;
}
vector_string::const_iterator fi;
for (fi = dir_files.begin(); fi != dir_files.end(); ++fi) {
const string &local_file = (*fi);
for (const string &local_file : dir_files) {
if (_pattern[0] == '.' || (local_file.empty() || local_file[0] != '.')) {
if (matches(local_file)) {
// We have a match; continue.
@ -227,6 +226,126 @@ r_match_files(const Filename &prefix, const string &suffix,
return num_matched;
}
/**
* Treats the GlobPattern as a filename pattern, and returns true if the given
* filename matches the pattern. Unlike matches(), this will not match slash
* characters for single asterisk characters, and it will ignore path
* components that only contain a dot.
*/
bool GlobPattern::
matches_file(Filename candidate) const {
if (_pattern.empty()) {
// Special case.
return candidate.empty();
}
// Either both must be absolute, or both must be relative.
if ((_pattern[0] != '/') != candidate.is_local()) {
return false;
}
return r_matches_file(_pattern, candidate);
}
/**
* The recursive implementation of matches_file().
*/
bool GlobPattern::
r_matches_file(const string &pattern, const Filename &candidate) const {
// Split off the next bit of pattern.
std::string next_pattern;
GlobPattern glob;
glob.set_case_sensitive(get_case_sensitive());
glob.set_nomatch_chars(get_nomatch_chars());
bool pattern_end;
size_t slash = pattern.find('/');
if (slash == string::npos) {
glob.set_pattern(pattern);
pattern_end = true;
} else {
glob.set_pattern(pattern.substr(0, slash));
next_pattern = pattern.substr(slash + 1);
pattern_end = false;
if (slash == 0 || (slash == 1 && pattern[0] == '.')) {
// Ignore // and /./ in patterns
return r_matches_file(next_pattern, candidate);
}
}
// Also split off the next component in the candidate filename.
std::string part;
Filename next_candidate;
bool candidate_end;
size_t fn_slash = ((const std::string &)candidate).find('/');
if (fn_slash == string::npos) {
part = candidate;
candidate_end = true;
} else {
part = candidate.substr(0, fn_slash);
next_candidate = candidate.substr(fn_slash + 1);
candidate_end = false;
// Ignore // and /./ in filenames.
if (fn_slash == 0 || part == ".") {
return r_matches_file(pattern, next_candidate);
}
}
// Now check if the current part matches the current pattern.
bool part_matches;
if (glob.get_pattern() == "**") {
// This matches any number of parts.
if (pattern_end) {
// We might as well stop checking here; it matches whatever might come.
return true;
}
// We branch out to three options: either we match nothing, we match this
// part only, or we match this part and maybe more.
return r_matches_file(next_pattern, candidate)
|| (!candidate_end && r_matches_file(next_pattern, next_candidate))
|| (!candidate_end && r_matches_file(pattern, next_candidate));
}
else if (glob.get_pattern() == "*" && _nomatch_chars.empty()) {
// Matches any part (faster version of below)
part_matches = true;
}
else if ((glob.get_pattern() == "." && part.empty())
|| (glob.get_pattern().empty() && part == ".")) {
// So that /path/. matches /path/, and vice versa.
part_matches = true;
}
else if (glob.has_glob_characters()) {
part_matches = glob.matches(part);
}
else if (get_case_sensitive()) {
part_matches = (part == glob.get_pattern());
}
else {
part_matches = (cmp_nocase(part, glob.get_pattern()) == 0);
}
if (!part_matches) {
// It doesn't match, so we end our search here.
return false;
}
if (candidate_end && pattern_end) {
// We've reached the end of both candidate and pattern, so it matches.
return true;
}
if (pattern_end != candidate_end) {
// One of them has ended, but the other hasn't, so it's not a match.
return false;
}
// It matches; move on to the next part.
return r_matches_file(next_pattern, next_candidate);
}
/**
* The recursive implementation of matches(). This returns true if the
* pattern substring [pi, pend) matches the candidate substring [ci, cend),

View File

@ -52,6 +52,7 @@ PUBLISHED:
MAKE_PROPERTY(nomatch_chars, get_nomatch_chars, set_nomatch_chars);
INLINE bool matches(const std::string &candidate) const;
bool matches_file(Filename candidate) const;
INLINE void output(std::ostream &out) const;
@ -74,6 +75,7 @@ private:
int r_match_files(const Filename &prefix, const std::string &suffix,
vector_string &results, const Filename &cwd);
bool r_matches_file(const std::string &suffix, const Filename &candidate) const;
std::string _pattern;
bool _case_sensitive;

View File

@ -1532,13 +1532,7 @@ write_module(ostream &out, ostream *out_h, InterrogateModuleDef *def) {
<< " nullptr, nullptr, nullptr, nullptr\n"
<< "};\n"
<< "\n"
<< "#ifdef _WIN32\n"
<< "extern \"C\" __declspec(dllexport) PyObject *PyInit_" << def->module_name << "();\n"
<< "#elif __GNUC__ >= 4\n"
<< "extern \"C\" __attribute__((visibility(\"default\"))) PyObject *PyInit_" << def->module_name << "();\n"
<< "#else\n"
<< "extern \"C\" PyObject *PyInit_" << def->module_name << "();\n"
<< "#endif\n"
<< "extern \"C\" EXPORT_CLASS PyObject *PyInit_" << def->module_name << "();\n"
<< "\n"
<< "PyObject *PyInit_" << def->module_name << "() {\n"
<< " LibraryDef *refs[] = {&" << def->library_name << "_moddef, nullptr};\n"
@ -1549,13 +1543,7 @@ write_module(ostream &out, ostream *out_h, InterrogateModuleDef *def) {
<< "\n"
<< "#else // Python 2 case\n"
<< "\n"
<< "#ifdef _WIN32\n"
<< "extern \"C\" __declspec(dllexport) void init" << def->module_name << "();\n"
<< "#elif __GNUC__ >= 4\n"
<< "extern \"C\" __attribute__((visibility(\"default\"))) void init" << def->module_name << "();\n"
<< "#else\n"
<< "extern \"C\" void init" << def->module_name << "();\n"
<< "#endif\n"
<< "extern \"C\" EXPORT_CLASS void init" << def->module_name << "();\n"
<< "\n"
<< "void init" << def->module_name << "() {\n"
<< " LibraryDef *refs[] = {&" << def->library_name << "_moddef, nullptr};\n"
@ -4078,13 +4066,9 @@ write_coerce_constructor(ostream &out, Object *obj, bool is_const) {
/**
* Special case optimization: if the last map is a subset of the map before
* it, and the last parameter is only a simple parameter type (that we have
* special default argument handling for), we can merge the cases. When this
* happens, we can make use of a special feature of PyArg_ParseTuple for
* handling of these last few default arguments. This doesn't work well for
* all types of default expressions, though, hence the need for this elaborate
* checking mechanism down here, which goes in parallel with the actual
* optional arg handling logic in write_function_instance.
* it, we can merge the cases. When this happens, we can make use of a
* special feature of PyArg_ParseTuple for handling of these last few default
* arguments.
*
* This isn't just to help reduce the amount of generated code; it also
* enables arbitrary selection of keyword arguments for many functions, ie.
@ -4095,14 +4079,6 @@ write_coerce_constructor(ostream &out, Object *obj, bool is_const) {
* Thanks to this mechanism, we can call it like so:
*
* func(c=True, d=".")
*
* The return value is the minimum of the number of maximum arguments.
*
* Sorry, let me try that again: it returns the largest number of arguments
* for which the overloads will be separated out rather than handled via the
* special default handling mechanism. Or something.
*
* Please don't hate me.
*/
int InterfaceMakerPythonNative::
collapse_default_remaps(std::map<int, std::set<FunctionRemap *> > &map_sets,
@ -4118,70 +4094,8 @@ collapse_default_remaps(std::map<int, std::set<FunctionRemap *> > &map_sets,
if (std::includes(rmi_next->second.begin(), rmi_next->second.end(),
rmi->second.begin(), rmi->second.end())) {
// Check if the nth argument is something we can easily create a default
// for.
std::set<FunctionRemap *>::iterator sii;
for (sii = rmi->second.begin(); sii != rmi->second.end(); ++sii) {
FunctionRemap *remap = (*sii);
size_t pn = (size_t)rmi->first;
if (!remap->_has_this || remap->_type == FunctionRemap::T_constructor) {
--pn;
}
nassertd(pn < remap->_parameters.size()) goto abort_iteration;
ParameterRemap *param = remap->_parameters[pn]._remap;
CPPType *type = param->get_new_type();
if (param->new_type_is_atomic_string()) {
CPPType *orig_type = param->get_orig_type();
if (TypeManager::is_char_pointer(orig_type)) {
} else if (TypeManager::is_wchar_pointer(orig_type)) {
goto abort_iteration;
} else if (TypeManager::is_wstring(orig_type)) {
goto abort_iteration;
} else if (TypeManager::is_const_ptr_to_basic_string_wchar(orig_type)) {
goto abort_iteration;
} else {
// Regular strings are OK if the default argument is a string
// literal or the default string constructor, since those are
// trivial to handle. This actually covers almost all of the
// cases of default string args.
CPPExpression::Type expr_type = param->get_default_value()->_type;
if (expr_type != CPPExpression::T_default_construct &&
expr_type != CPPExpression::T_string) {
goto abort_iteration;
}
}
} else if (TypeManager::is_integer(type)) {
} else if (TypeManager::is_float(type)) {
} else if (TypeManager::is_const_char_pointer(type)) {
} else if (TypeManager::is_pointer_to_PyTypeObject(type)) {
} else if (TypeManager::is_pointer_to_PyStringObject(type)) {
} else if (TypeManager::is_pointer_to_PyUnicodeObject(type)) {
} else if (TypeManager::is_pointer_to_PyObject(type)) {
} else if (TypeManager::is_pointer_to_Py_buffer(type)) {
goto abort_iteration;
} else if (TypeManager::is_pointer_to_simple(type)) {
goto abort_iteration;
} else if (TypeManager::is_pointer(type)) {
// I'm allowing other pointer types, but only if the expression
// happens to evaluate to a numeric constant (which will likely only
// be NULL). There are too many issues to resolve right now with
// allowing more complex default expressions, including issues in
// the C++ parser (but the reader is welcome to give it a try!)
CPPExpression::Result res = param->get_default_value()->evaluate();
if (res._type != CPPExpression::RT_integer &&
res._type != CPPExpression::RT_pointer) {
goto abort_iteration;
}
} else {
goto abort_iteration;
}
}
// rmi_next has a superset of the remaps in rmi, and we are going to
// erase rmi_next, so put all the remaps in rmi. rmi->second =
// rmi_next->second;
// erase rmi_next, so put all the remaps in rmi.
max_required_args = rmi_next->first;
rmi = rmi_next;
@ -4191,7 +4105,6 @@ collapse_default_remaps(std::map<int, std::set<FunctionRemap *> > &map_sets,
}
}
abort_iteration:
// Now erase the other remap sets. Reverse iterators are weird, we first
// need to get forward iterators and decrement them by one.
std::map<int, std::set<FunctionRemap *> >::iterator erase_begin, erase_end;
@ -4738,6 +4651,7 @@ write_function_instance(ostream &out, FunctionRemap *remap,
"(" + orig_type->get_local_name(&parser) + ")" + param_name;
string default_expr;
const char *null_assign = "";
if (is_optional) {
// If this is an optional argument, PyArg_ParseTuple will leave the
@ -4747,6 +4661,7 @@ write_function_instance(ostream &out, FunctionRemap *remap,
default_expr_str << " = ";
default_value->output(default_expr_str, 0, &parser, false);
default_expr = default_expr_str.str();
null_assign = " = nullptr";
// We should only ever have to consider optional arguments for functions
// taking a variable number of arguments.
@ -4776,23 +4691,40 @@ write_function_instance(ostream &out, FunctionRemap *remap,
expected_params += "str";
} else if (TypeManager::is_wchar_pointer(orig_type)) {
indent(out, indent_level) << "#if PY_VERSION_HEX >= 0x03020000\n";
indent(out, indent_level) << "PyObject *" << param_name << ";\n";
indent(out, indent_level) << "#else\n";
indent(out, indent_level) << "PyUnicodeObject *" << param_name << ";\n";
indent(out, indent_level) << "#endif\n";
out << "#if PY_VERSION_HEX >= 0x03020000\n";
indent(out, indent_level) << "PyObject *" << param_name << null_assign << ";\n";
out << "#else\n";
indent(out, indent_level) << "PyUnicodeObject *" << param_name << null_assign << ";\n";
out << "#endif\n";
format_specifiers += "U";
parameter_list += ", &" + param_name;
extra_convert
<< "#if PY_VERSION_HEX >= 0x03030000\n"
<< "wchar_t *" << param_name << "_str = PyUnicode_AsWideCharString(" << param_name << ", nullptr);\n"
<< "#else"
<< "Py_ssize_t " << param_name << "_len = PyUnicode_GET_SIZE(" << param_name << ");\n"
<< "wchar_t *" << param_name << "_str = (wchar_t *)alloca(sizeof(wchar_t) * (" + param_name + "_len + 1));\n"
<< "PyUnicode_AsWideChar(" << param_name << ", " << param_name << "_str, " << param_name << "_len);\n"
<< param_name << "_str[" << param_name << "_len] = 0;\n"
<< "#endif\n";
if (is_optional) {
extra_convert
<< "wchar_t *" << param_name << "_str;\n"
<< "if (" << param_name << " != nullptr) {\n"
<< "#if PY_VERSION_HEX >= 0x03030000\n"
<< " " << param_name << "_str = PyUnicode_AsWideCharString(" << param_name << ", nullptr);\n"
<< "#else"
<< "Py_ssize_t " << param_name << "_len = PyUnicode_GET_SIZE(" << param_name << ");\n"
<< " " << param_name << "_str = (wchar_t *)alloca(sizeof(wchar_t) * (" + param_name + "_len + 1));\n"
<< "PyUnicode_AsWideChar(" << param_name << ", " << param_name << "_str, " << param_name << "_len);\n"
<< param_name << "_str[" << param_name << "_len] = 0;\n"
<< "#endif\n"
<< "} else {\n"
<< " " << param_name << "_str" << default_expr << ";\n"
<< "}\n";
} else {
extra_convert
<< "#if PY_VERSION_HEX >= 0x03030000\n"
<< "wchar_t *" << param_name << "_str = PyUnicode_AsWideCharString(" << param_name << ", nullptr);\n"
<< "#else"
<< "Py_ssize_t " << param_name << "_len = PyUnicode_GET_SIZE(" << param_name << ");\n"
<< "wchar_t *" << param_name << "_str = (wchar_t *)alloca(sizeof(wchar_t) * (" + param_name + "_len + 1));\n"
<< "PyUnicode_AsWideChar(" << param_name << ", " << param_name << "_str, " << param_name << "_len);\n"
<< param_name << "_str[" << param_name << "_len] = 0;\n"
<< "#endif\n";
}
pexpr_string = param_name + "_str";
@ -4803,56 +4735,48 @@ write_function_instance(ostream &out, FunctionRemap *remap,
expected_params += "unicode";
} else if (TypeManager::is_wstring(orig_type)) {
indent(out, indent_level) << "#if PY_VERSION_HEX >= 0x03020000\n";
indent(out, indent_level) << "PyObject *" << param_name << ";\n";
indent(out, indent_level) << "#else\n";
indent(out, indent_level) << "PyUnicodeObject *" << param_name << ";\n";
indent(out, indent_level) << "#endif\n";
} else if (TypeManager::is_wstring(orig_type) ||
TypeManager::is_const_ptr_to_basic_string_wchar(orig_type)) {
out << "#if PY_VERSION_HEX >= 0x03020000\n";
indent(out, indent_level) << "PyObject *" << param_name << null_assign << ";\n";
out << "#else\n";
indent(out, indent_level) << "PyUnicodeObject *" << param_name << null_assign << ";\n";
out << "#endif\n";
format_specifiers += "U";
parameter_list += ", &" + param_name;
extra_convert
<< "#if PY_VERSION_HEX >= 0x03030000\n"
<< "Py_ssize_t " << param_name << "_len;\n"
<< "wchar_t *" << param_name << "_str = PyUnicode_AsWideCharString("
<< param_name << ", &" << param_name << "_len);\n"
<< "#else\n"
<< "Py_ssize_t " << param_name << "_len = PyUnicode_GET_SIZE(" << param_name << ");\n"
<< "wchar_t *" << param_name << "_str = (wchar_t *)alloca(sizeof(wchar_t) * (" + param_name + "_len + 1));\n"
<< "PyUnicode_AsWideChar(" << param_name << ", " << param_name << "_str, " << param_name << "_len);\n"
<< "#endif\n";
pexpr_string = param_name + "_str, " + param_name + "_len";
extra_cleanup
<< "#if PY_VERSION_HEX >= 0x03030000\n"
<< "PyMem_Free(" << param_name << "_str);\n"
<< "#endif\n";
expected_params += "unicode";
} else if (TypeManager::is_const_ptr_to_basic_string_wchar(orig_type)) {
indent(out, indent_level) << "#if PY_VERSION_HEX >= 0x03020000\n";
indent(out, indent_level) << "PyObject *" << param_name << ";\n";
indent(out, indent_level) << "#else\n";
indent(out, indent_level) << "PyUnicodeObject *" << param_name << ";\n";
indent(out, indent_level) << "#endif\n";
format_specifiers += "U";
parameter_list += ", &" + param_name;
extra_convert
<< "#if PY_VERSION_HEX >= 0x03030000\n"
<< "Py_ssize_t " << param_name << "_len;\n"
<< "wchar_t *" << param_name << "_str = PyUnicode_AsWideCharString("
<< param_name << ", &" << param_name << "_len);\n"
<< "#else\n"
<< "Py_ssize_t " << param_name << "_len = PyUnicode_GET_SIZE(" << param_name << ");\n"
<< "wchar_t *" << param_name << "_str = (wchar_t *)alloca(sizeof(wchar_t) * (" + param_name + "_len + 1));\n"
<< "PyUnicode_AsWideChar(" << param_name << ", " << param_name << "_str, " << param_name << "_len);\n"
<< "#endif\n";
pexpr_string = param_name + "_str, " + param_name + "_len";
if (is_optional) {
extra_convert
<< "Py_ssize_t " << param_name << "_len;\n"
<< "wchar_t *" << param_name << "_str;\n"
<< "std::wstring " << param_name << "_wstr;\n"
<< "if (" << param_name << " != nullptr) {\n"
<< "#if PY_VERSION_HEX >= 0x03030000\n"
<< " " << param_name << "_str = PyUnicode_AsWideCharString("
<< param_name << ", &" << param_name << "_len);\n"
<< "#else\n"
<< " " << param_name << "_len = PyUnicode_GET_SIZE(" << param_name << ");\n"
<< " " << param_name << "_str = (wchar_t *)alloca(sizeof(wchar_t) * (" + param_name + "_len + 1));\n"
<< "PyUnicode_AsWideChar(" << param_name << ", " << param_name << "_str, " << param_name << "_len);\n"
<< "#endif\n"
<< " " << param_name << "_wstr.assign(" << param_name << "_str, " << param_name << "_len);\n"
<< "} else {\n"
<< " " << param_name << "_wstr" << default_expr << ";\n"
<< "}\n";
pexpr_string = "std::move(" + param_name + "_wstr)";
} else {
extra_convert
<< "#if PY_VERSION_HEX >= 0x03030000\n"
<< "Py_ssize_t " << param_name << "_len;\n"
<< "wchar_t *" << param_name << "_str = PyUnicode_AsWideCharString("
<< param_name << ", &" << param_name << "_len);\n"
<< "#else\n"
<< "Py_ssize_t " << param_name << "_len = PyUnicode_GET_SIZE(" << param_name << ");\n"
<< "wchar_t *" << param_name << "_str = (wchar_t *)alloca(sizeof(wchar_t) * (" + param_name + "_len + 1));\n"
<< "PyUnicode_AsWideChar(" << param_name << ", " << param_name << "_str, " << param_name << "_len);\n"
<< "#endif\n";
pexpr_string = param_name + "_str, " + param_name + "_len";
}
extra_cleanup
<< "#if PY_VERSION_HEX >= 0x03030000\n"
@ -5019,11 +4943,11 @@ write_function_instance(ostream &out, FunctionRemap *remap,
only_pyobjects = false;
} else if (TypeManager::is_wchar(type)) {
indent(out, indent_level) << "#if PY_VERSION_HEX >= 0x03020000\n";
out << "#if PY_VERSION_HEX >= 0x03020000\n";
indent(out, indent_level) << "PyObject *" << param_name << ";\n";
indent(out, indent_level) << "#else\n";
out << "#else\n";
indent(out, indent_level) << "PyUnicodeObject *" << param_name << ";\n";
indent(out, indent_level) << "#endif\n";
out << "#endif\n";
format_specifiers += "U";
parameter_list += ", &" + param_name;
@ -5348,17 +5272,36 @@ write_function_instance(ostream &out, FunctionRemap *remap,
if (args_type == AT_single_arg) {
param_name = "arg";
} else {
indent(out, indent_level) << "PyObject *" << param_name << ";\n";
indent(out, indent_level) << "PyObject *" << param_name << null_assign << ";\n";
format_specifiers += "O";
parameter_list += ", &" + param_name;
}
indent(out, indent_level) << "Py_buffer " << param_name << "_view;\n";
extra_param_check << " && PyObject_GetBuffer("
<< param_name << ", &"
<< param_name << "_view, PyBUF_FULL) == 0";
pexpr_string = "&" + param_name + "_view";
extra_cleanup << "PyBuffer_Release(&" << param_name << "_view);\n";
if (is_optional) {
indent(out, indent_level) << "Py_buffer *" << param_name << "_viewp;\n";
extra_convert
<< "bool " << param_name << "_success;\n"
<< "if (" << param_name << " != nullptr) {\n"
<< " " << param_name << "_success = (PyObject_GetBuffer("
<< param_name << ", &" << param_name << "_view, PyBUF_FULL) == 0);\n"
<< " " << param_name << "_viewp = &" << param_name << "_view;\n"
<< "} else {\n"
<< " " << param_name << "_viewp" << default_expr << ";\n"
<< " " << param_name << "_success = true;\n"
<< "}\n";
extra_param_check << " && " << param_name << "_success";
pexpr_string = param_name + "_viewp";
extra_cleanup << "if (" << param_name << " != nullptr) PyBuffer_Release(&" << param_name << "_view);\n";
} else {
extra_param_check << " && PyObject_GetBuffer("
<< param_name << ", &"
<< param_name << "_view, PyBUF_FULL) == 0";
pexpr_string = "&" + param_name + "_view";
extra_cleanup << "PyBuffer_Release(&" << param_name << "_view);\n";
}
expected_params += "buffer";
may_raise_typeerror = true;
clear_error = true;
@ -5367,7 +5310,7 @@ write_function_instance(ostream &out, FunctionRemap *remap,
if (args_type == AT_single_arg) {
param_name = "arg";
} else {
indent(out, indent_level) << "PyObject *" << param_name << ";\n";
indent(out, indent_level) << "PyObject *" << param_name << null_assign << ";\n";
format_specifiers += "O";
parameter_list += ", &" + param_name;
}
@ -5496,18 +5439,15 @@ write_function_instance(ostream &out, FunctionRemap *remap,
if (args_type == AT_single_arg) {
param_name = "arg";
} else {
indent(out, indent_level) << "PyObject *" << param_name;
if (is_optional) {
out << " = nullptr";
}
out << ";\n";
indent(out, indent_level) << "PyObject *" << param_name << null_assign << ";\n";
format_specifiers += "O";
parameter_list += ", &" + param_name;
}
// If the default value is NULL, we also accept a None value.
bool maybe_none = false;
if (default_value != nullptr && (return_flags & RF_coerced) == 0) {
if (default_value != nullptr && (return_flags & RF_coerced) == 0 &&
TypeManager::is_pointer(orig_type)) {
CPPExpression::Result res = param->get_default_value()->evaluate();
if (res._type == CPPExpression::RT_integer ||
res._type == CPPExpression::RT_pointer) {
@ -5576,8 +5516,11 @@ write_function_instance(ostream &out, FunctionRemap *remap,
<< "if (" << param_name << " != nullptr && " << param_name << " != Py_None) {\n"
<< " " << param_name << "_this";
} else if (is_optional) {
if (TypeManager::is_pointer(orig_type)) {
extra_convert << default_expr;
}
extra_convert
<< default_expr << ";\n"
<< ";\n"
<< "if (" << param_name << " != nullptr) {\n"
<< " " << param_name << "_this";
} else if (maybe_none) {
@ -5590,7 +5533,13 @@ write_function_instance(ostream &out, FunctionRemap *remap,
extra_convert << " = Dtool_Coerce_" + make_safe_name(class_name) +
"(" + param_name + ", " + param_name + "_local);\n";
if (is_optional || maybe_none) {
if (is_optional && !TypeManager::is_pointer(orig_type)) {
extra_convert
<< "} else {\n"
<< " " << param_name << "_local" << default_expr << ";\n"
<< " " << param_name << "_this = &" << param_name << "_local;\n"
<< "}\n";
} else if (is_optional || maybe_none) {
extra_convert << "}\n";
}
@ -5645,21 +5594,60 @@ write_function_instance(ostream &out, FunctionRemap *remap,
} else { // The regular, non-coercion case.
type->output_instance(extra_convert, param_name + "_this", &parser);
if (is_optional && maybe_none) {
// This parameter has a default value of nullptr, so we need to also
// allow passing in None.
extra_convert
<< default_expr << ";\n"
<< "if (" << param_name << " != nullptr && " << param_name << " != Py_None) {\n"
<< " " << param_name << "_this";
} else if (is_optional) {
}
else if (is_optional && !TypeManager::is_pointer(orig_type) && !default_value->is_lvalue()) {
// Most annoying case, where we have to use an rvalue reference to
// extend the lifetime of the default argument. In this case, the
// default expression is invoked even if not used.
extra_convert << ";\n";
if (TypeManager::is_const_pointer_to_anything(type)) {
extra_convert << "const ";
obj_type->output_instance(extra_convert, "&" + param_name + "_ref", &parser);
} else {
obj_type->output_instance(extra_convert, "&&" + param_name + "_ref", &parser);
}
extra_convert
<< default_expr << ";\n"
<< "if (" << param_name << " != nullptr) {\n"
<< "if (" << param_name << " == nullptr) {\n"
<< " " << param_name << "_this = &" << param_name << "_ref;\n"
<< "} else {\n"
<< " " << param_name << "_this";
} else if (maybe_none) {
}
else if (is_optional) {
// General case where the default argument is either an lvalue or a
// pointer.
extra_convert
<< ";\n"
<< "if (" << param_name << " == nullptr) {\n"
<< " " << param_name << "_this = ";
if (TypeManager::is_pointer(orig_type)) {
default_value->output(extra_convert, 0, &parser, false);
extra_convert << ";\n";
} else {
// The rvalue case was handled above, so this is an lvalue, which
// means we can safely take a reference to it.
extra_convert << "&(";
default_value->output(extra_convert, 0, &parser, false);
extra_convert << ");\n";
}
extra_convert
<< "} else {\n"
<< " " << param_name << "_this";
}
else if (maybe_none) {
// No default argument, but we still need to check for None.
extra_convert
<< " = nullptr;\n"
<< "if (" << param_name << " != Py_None) {\n"
<< " " << param_name << "_this";
}
if (const_ok && !report_errors) {
// This function does the same thing in this case and is slightly
// simpler. But maybe we should just reorganize these functions

View File

@ -312,7 +312,10 @@ main(int argc, char **argv) {
string command_line;
int i;
for (i = 0; i < argc; i++) {
command_line += string(argv[i]) + " ";
if (i > 0) {
command_line += ' ';
}
command_line += string(argv[i]);
}
Filename fn;

View File

@ -656,13 +656,13 @@ get_preferred_name(CPPType *type) {
*/
string InterrogateBuilder::
hash_string(const string &name, int shift_offset) {
int hash = 0;
unsigned int hash = 0;
int shift = 0;
unsigned int shift = 0;
string::const_iterator ni;
for (ni = name.begin(); ni != name.end(); ++ni) {
int c = (int)(unsigned char)(*ni);
int shifted_c = (c << shift) & 0xffffff;
unsigned int c = (unsigned char)*ni;
unsigned int shifted_c = (c << shift) & 0xffffff;
if (shift > 16) {
// We actually want a circular shift, not an arithmetic shift.
shifted_c |= ((c >> (24 - shift)) & 0xff) ;
@ -675,10 +675,9 @@ hash_string(const string &name, int shift_offset) {
// bits back at the bottom, to scramble up the bits a bit. This helps
// reduce hash conflicts from names that are similar to each other, by
// separating adjacent hash codes.
int prime = 4999;
int low_order = (hash * prime) & 0xffffff;
int high_order = (int)((double)hash * (double)prime / (double)(1 << 24));
hash = low_order ^ high_order;
const unsigned int prime = 4999;
unsigned long long product = (unsigned long long)hash * prime;
hash = (product ^ (product >> 24)) & 0xffffff;
// Also add in the additional_number, times some prime factor. hash = (hash
// + additional_number * 1657) & 0xffffff;
@ -690,10 +689,9 @@ hash_string(const string &name, int shift_offset) {
// deal, since we have to resolve hash conflicts anyway.
string result;
int extract_h = hash;
for (int i = 0; i < 4; i++) {
int value = (extract_h & 0x3f);
extract_h >>= 6;
unsigned int value = (hash & 0x3f);
hash >>= 6;
if (value < 26) {
result += (char)('A' + value);
@ -2024,6 +2022,7 @@ get_make_property(CPPMakeProperty *make_property, CPPStructType *struct_type, CP
if (iproperty._type != 0 && iproperty._type != return_index) {
cerr << "Property " << property_name << " has inconsistent element type!\n";
}
iproperty._type = return_index;
} else {
iproperty._type = 0;
}

View File

@ -295,24 +295,10 @@ int write_python_table_native(std::ostream &out) {
out.put('\n');
out << "#if PY_MAJOR_VERSION >= 3 || !defined(NDEBUG)\n"
<< "#ifdef _WIN32\n"
<< "extern \"C\" __declspec(dllexport) PyObject *PyInit_" << library_name << "();\n"
<< "#elif __GNUC__ >= 4\n"
<< "extern \"C\" __attribute__((visibility(\"default\"))) PyObject *PyInit_" << library_name << "();\n"
out << "#if PY_MAJOR_VERSION >= 3\n"
<< "extern \"C\" EXPORT_CLASS PyObject *PyInit_" << library_name << "();\n"
<< "#else\n"
<< "extern \"C\" PyObject *PyInit_" << library_name << "();\n"
<< "#endif\n"
<< "#endif\n";
out << "#if PY_MAJOR_VERSION < 3 || !defined(NDEBUG)\n"
<< "#ifdef _WIN32\n"
<< "extern \"C\" __declspec(dllexport) void init" << library_name << "();\n"
<< "#elif __GNUC__ >= 4\n"
<< "extern \"C\" __attribute__((visibility(\"default\"))) void init" << library_name << "();\n"
<< "#else\n"
<< "extern \"C\" void init" << library_name << "();\n"
<< "#endif\n"
<< "extern \"C\" EXPORT_CLASS void init" << library_name << "();\n"
<< "#endif\n";
out << "\n"
@ -361,14 +347,6 @@ int write_python_table_native(std::ostream &out) {
<< "}\n"
<< "\n"
<< "#ifndef NDEBUG\n"
<< "void init" << library_name << "() {\n"
<< " PyErr_SetString(PyExc_ImportError, \"" << module_name << " was "
<< "compiled for Python \" PY_VERSION \", which is incompatible "
<< "with Python 2\");\n"
<< "}\n"
<< "#endif\n"
<< "#else // Python 2 case\n"
<< "\n"
<< "void init" << library_name << "() {\n";
@ -402,15 +380,6 @@ int write_python_table_native(std::ostream &out) {
out << " }\n"
<< "}\n"
<< "\n"
<< "#ifndef NDEBUG\n"
<< "PyObject *PyInit_" << library_name << "() {\n"
<< " PyErr_SetString(PyExc_ImportError, \"" << module_name << " was "
<< "compiled for Python \" PY_VERSION \", which is incompatible "
<< "with Python 3\");\n"
<< " return nullptr;\n"
<< "}\n"
<< "#endif\n"
<< "#endif\n"
<< "\n";

View File

@ -15,6 +15,16 @@
#ifdef HAVE_PYTHON
static PyMemberDef standard_type_members[] = {
{(char *)"this", (sizeof(void*) == sizeof(int)) ? T_UINT : T_ULONGLONG, offsetof(Dtool_PyInstDef, _ptr_to_object), READONLY, (char *)"C++ 'this' pointer, if any"},
{(char *)"this_ownership", T_BOOL, offsetof(Dtool_PyInstDef, _memory_rules), READONLY, (char *)"C++ 'this' ownership rules"},
{(char *)"this_const", T_BOOL, offsetof(Dtool_PyInstDef, _is_const), READONLY, (char *)"C++ 'this' const flag"},
// {(char *)"this_signature", T_INT, offsetof(Dtool_PyInstDef, _signature),
// READONLY, (char *)"A type check signature"},
{(char *)"this_metatype", T_OBJECT, offsetof(Dtool_PyInstDef, _My_Type), READONLY, (char *)"The dtool meta object"},
{nullptr} /* Sentinel */
};
static PyObject *GetSuperBase(PyObject *self) {
Dtool_PyTypedObject *super_base = Dtool_GetSuperBase();
Py_XINCREF((PyTypeObject *)super_base); // order is important .. this is used for static functions

View File

@ -176,6 +176,18 @@ interrogate_element_setter(ElementIndex element) {
return InterrogateDatabase::get_ptr()->get_element(element).get_setter();
}
bool
interrogate_element_is_sequence(ElementIndex element) {
// cerr << "interrogate_element_is_sequence(" << element << ")\n";
return InterrogateDatabase::get_ptr()->get_element(element).is_sequence();
}
bool
interrogate_element_is_mapping(ElementIndex element) {
// cerr << "interrogate_element_is_mapping(" << element << ")\n";
return InterrogateDatabase::get_ptr()->get_element(element).is_mapping();
}
int
interrogate_number_of_globals() {
// cerr << "interrogate_number_of_globals()\n";

View File

@ -153,6 +153,9 @@ EXPCL_INTERROGATEDB FunctionIndex interrogate_element_getter(ElementIndex elemen
EXPCL_INTERROGATEDB bool interrogate_element_has_setter(ElementIndex element);
EXPCL_INTERROGATEDB FunctionIndex interrogate_element_setter(ElementIndex element);
EXPCL_INTERROGATEDB bool interrogate_element_is_sequence(ElementIndex element);
EXPCL_INTERROGATEDB bool interrogate_element_is_mapping(ElementIndex element);
// Global Data
// This is the list of global data elements.

View File

@ -31,6 +31,14 @@
#include <Python.h>
#ifndef LINK_ALL_STATIC
# define EXPCL_PYPANDA
#elif defined(__GNUC__)
# define EXPCL_PYPANDA __attribute__((weak))
#else
# define EXPCL_PYPANDA extern inline
#endif
/* Python 2.4 */
// 2.4 macros which aren't available in 2.3
@ -99,7 +107,7 @@ typedef int Py_ssize_t;
// PyInt_FromSize_t automatically picks the right type.
# define PyLongOrInt_AS_LONG PyInt_AsLong
size_t PyLongOrInt_AsSize_t(PyObject *);
EXPCL_PYPANDA size_t PyLongOrInt_AsSize_t(PyObject *);
#endif
// Which character to use in PyArg_ParseTuple et al for a byte string.

View File

@ -12,16 +12,6 @@
using std::string;
PyMemberDef standard_type_members[] = {
{(char *)"this", (sizeof(void*) == sizeof(int)) ? T_UINT : T_ULONGLONG, offsetof(Dtool_PyInstDef, _ptr_to_object), READONLY, (char *)"C++ 'this' pointer, if any"},
{(char *)"this_ownership", T_BOOL, offsetof(Dtool_PyInstDef, _memory_rules), READONLY, (char *)"C++ 'this' ownership rules"},
{(char *)"this_const", T_BOOL, offsetof(Dtool_PyInstDef, _is_const), READONLY, (char *)"C++ 'this' const flag"},
// {(char *)"this_signature", T_INT, offsetof(Dtool_PyInstDef, _signature),
// READONLY, (char *)"A type check signature"},
{(char *)"this_metatype", T_OBJECT, offsetof(Dtool_PyInstDef, _My_Type), READONLY, (char *)"The dtool meta object"},
{nullptr} /* Sentinel */
};
/**
*/
@ -296,6 +286,43 @@ PyObject *_Dtool_Return(PyObject *value) {
}
#if PY_VERSION_HEX < 0x03040000
/**
* This function converts an int value to the appropriate enum instance.
*/
static PyObject *Dtool_EnumType_New(PyTypeObject *subtype, PyObject *args, PyObject *kwds) {
PyObject *arg;
if (!Dtool_ExtractArg(&arg, args, kwds, "value")) {
return PyErr_Format(PyExc_TypeError,
"%s() missing 1 required argument: 'value'",
subtype->tp_name);
}
if (Py_TYPE(arg) == subtype) {
Py_INCREF(arg);
return arg;
}
PyObject *value2member = PyDict_GetItemString(subtype->tp_dict, "_value2member_map_");
nassertr_always(value2member != nullptr, nullptr);
PyObject *member = PyDict_GetItem(value2member, arg);
if (member != nullptr) {
Py_INCREF(member);
return member;
}
PyObject *repr = PyObject_Repr(arg);
PyErr_Format(PyExc_ValueError, "%s is not a valid %s",
#if PY_MAJOR_VERSION >= 3
PyUnicode_AS_STRING(repr),
#else
PyString_AS_STRING(repr),
#endif
subtype->tp_name);
Py_DECREF(repr);
return nullptr;
}
static PyObject *Dtool_EnumType_Str(PyObject *self) {
PyObject *name = PyObject_GetAttrString(self, "name");
#if PY_MAJOR_VERSION >= 3
@ -347,6 +374,7 @@ PyTypeObject *Dtool_EnumType_Create(const char *name, PyObject *names, const cha
static PyObject *name_sunder_str;
static PyObject *value_str;
static PyObject *value_sunder_str;
static PyObject *value2member_map_sunder_str;
// Emulate something vaguely like the enum module.
if (enum_class == nullptr) {
#if PY_MAJOR_VERSION >= 3
@ -354,11 +382,13 @@ PyTypeObject *Dtool_EnumType_Create(const char *name, PyObject *names, const cha
value_str = PyUnicode_InternFromString("value");
name_sunder_str = PyUnicode_InternFromString("_name_");
value_sunder_str = PyUnicode_InternFromString("_value_");
value2member_map_sunder_str = PyUnicode_InternFromString("_value2member_map_");
#else
name_str = PyString_InternFromString("name");
value_str = PyString_InternFromString("value");
name_sunder_str = PyString_InternFromString("_name_");
value_sunder_str = PyString_InternFromString("_value_");
value2member_map_sunder_str = PyString_InternFromString("_value2member_map_");
#endif
PyObject *name_value_tuple = PyTuple_New(4);
PyTuple_SET_ITEM(name_value_tuple, 0, name_str);
@ -375,27 +405,39 @@ PyTypeObject *Dtool_EnumType_Create(const char *name, PyObject *names, const cha
enum_class = PyObject_CallFunction((PyObject *)&PyType_Type, (char *)"s()N", "Enum", slots_dict);
nassertr(enum_class != nullptr, nullptr);
}
PyObject *result = PyObject_CallFunction((PyObject *)&PyType_Type, (char *)"s(O)N", name, enum_class, PyDict_New());
// Create a subclass of this generic Enum class we just created.
PyObject *value2member = PyDict_New();
PyObject *dict = PyDict_New();
PyDict_SetItem(dict, value2member_map_sunder_str, value2member);
PyObject *result = PyObject_CallFunction((PyObject *)&PyType_Type, (char *)"s(O)N", name, enum_class, dict);
nassertr(result != nullptr, nullptr);
((PyTypeObject *)result)->tp_new = Dtool_EnumType_New;
((PyTypeObject *)result)->tp_str = Dtool_EnumType_Str;
((PyTypeObject *)result)->tp_repr = Dtool_EnumType_Repr;
// Copy the names as instances of the above to the class dict.
PyObject *empty_tuple = PyTuple_New(0);
// Copy the names as instances of the above to the class dict, and create a
// reverse mapping in the _value2member_map_ dict.
Py_ssize_t size = PyTuple_GET_SIZE(names);
for (Py_ssize_t i = 0; i < size; ++i) {
PyObject *item = PyTuple_GET_ITEM(names, i);
PyObject *name = PyTuple_GET_ITEM(item, 0);
PyObject *value = PyTuple_GET_ITEM(item, 1);
PyObject *member = _PyObject_CallNoArg(result);
PyObject *member = PyType_GenericNew((PyTypeObject *)result, empty_tuple, nullptr);
PyObject_SetAttr(member, name_str, name);
PyObject_SetAttr(member, name_sunder_str, name);
PyObject_SetAttr(member, value_str, value);
PyObject_SetAttr(member, value_sunder_str, value);
PyObject_SetAttr(result, name, member);
PyDict_SetItem(value2member, value, member);
Py_DECREF(member);
}
Py_DECREF(names);
Py_DECREF(value2member);
Py_DECREF(empty_tuple);
#endif
if (module != nullptr) {
@ -588,46 +630,48 @@ PyObject *Dtool_PyModuleInitHelper(const LibraryDef *defs[], const char *modulen
<< "Python " << version << "\n";
}
// Grab the __main__ module.
PyObject *main_module = PyImport_ImportModule("__main__");
if (main_module == nullptr) {
interrogatedb_cat.warning() << "Unable to import __main__\n";
}
// Extract the __file__ attribute, if present.
Filename main_dir;
PyObject *file_attr = nullptr;
if (main_module != nullptr) {
file_attr = PyObject_GetAttrString(main_module, "__file__");
}
if (file_attr == nullptr) {
// Must be running in the interactive interpreter. Use the CWD.
main_dir = ExecutionEnvironment::get_cwd();
} else {
if (!ExecutionEnvironment::has_environment_variable("MAIN_DIR")) {
// Grab the __main__ module.
PyObject *main_module = PyImport_ImportModule("__main__");
if (main_module == NULL) {
interrogatedb_cat.warning() << "Unable to import __main__\n";
}
// Extract the __file__ attribute, if present.
Filename main_dir;
PyObject *file_attr = nullptr;
if (main_module != nullptr) {
file_attr = PyObject_GetAttrString(main_module, "__file__");
}
if (file_attr == nullptr) {
// Must be running in the interactive interpreter. Use the CWD.
main_dir = ExecutionEnvironment::get_cwd();
} else {
#if PY_MAJOR_VERSION >= 3
Py_ssize_t length;
wchar_t *buffer = PyUnicode_AsWideCharString(file_attr, &length);
if (buffer != nullptr) {
main_dir = Filename::from_os_specific_w(std::wstring(buffer, length));
main_dir.make_absolute();
main_dir = main_dir.get_dirname();
PyMem_Free(buffer);
}
Py_ssize_t length;
wchar_t *buffer = PyUnicode_AsWideCharString(file_attr, &length);
if (buffer != nullptr) {
main_dir = Filename::from_os_specific_w(std::wstring(buffer, length));
main_dir.make_absolute();
main_dir = main_dir.get_dirname();
PyMem_Free(buffer);
}
#else
char *buffer;
Py_ssize_t length;
if (PyString_AsStringAndSize(file_attr, &buffer, &length) != -1) {
main_dir = Filename::from_os_specific(std::string(buffer, length));
main_dir.make_absolute();
main_dir = main_dir.get_dirname();
}
char *buffer;
Py_ssize_t length;
if (PyString_AsStringAndSize(file_attr, &buffer, &length) != -1) {
main_dir = Filename::from_os_specific(std::string(buffer, length));
main_dir.make_absolute();
main_dir = main_dir.get_dirname();
}
#endif
else {
interrogatedb_cat.warning() << "Invalid string for __main__.__file__\n";
else {
interrogatedb_cat.warning() << "Invalid string for __main__.__file__\n";
}
}
ExecutionEnvironment::shadow_environment_variable("MAIN_DIR", main_dir.to_os_specific());
PyErr_Clear();
}
ExecutionEnvironment::shadow_environment_variable("MAIN_DIR", main_dir.to_os_specific());
PyErr_Clear();
initialized_main_dir = true;
// Also, while we are at it, initialize the thread swap hook.
@ -673,7 +717,8 @@ PyObject *Dtool_BorrowThisReference(PyObject *self, PyObject *args) {
// We do expose a dictionay for dtool classes .. this should be removed at
// some point..
PyObject *Dtool_AddToDictionary(PyObject *self1, PyObject *args) {
EXPCL_PYPANDA PyObject *
Dtool_AddToDictionary(PyObject *self1, PyObject *args) {
PyObject *self;
PyObject *subject;
PyObject *key;

View File

@ -67,9 +67,6 @@ struct Dtool_PyInstDef {
bool _is_const;
};
// A Offset Dictionary Defining How to read the Above Object..
extern PyMemberDef standard_type_members[];
// The Class Definition Structor For a Dtool python type.
struct Dtool_PyTypedObject {
// Standard Python Features..
@ -182,19 +179,19 @@ static void Dtool_FreeInstance_##CLASS_NAME(PyObject *self) {\
typedef std::map<std::string, Dtool_PyTypedObject *> Dtool_TypeMap;
Dtool_TypeMap *Dtool_GetGlobalTypeMap();
EXPCL_PYPANDA Dtool_TypeMap *Dtool_GetGlobalTypeMap();
/**
*/
void DTOOL_Call_ExtractThisPointerForType(PyObject *self, Dtool_PyTypedObject *classdef, void **answer);
EXPCL_PYPANDA void DTOOL_Call_ExtractThisPointerForType(PyObject *self, Dtool_PyTypedObject *classdef, void **answer);
void *DTOOL_Call_GetPointerThisClass(PyObject *self, Dtool_PyTypedObject *classdef, int param, const std::string &function_name, bool const_ok, bool report_errors);
EXPCL_PYPANDA void *DTOOL_Call_GetPointerThisClass(PyObject *self, Dtool_PyTypedObject *classdef, int param, const std::string &function_name, bool const_ok, bool report_errors);
bool Dtool_Call_ExtractThisPointer(PyObject *self, Dtool_PyTypedObject &classdef, void **answer);
EXPCL_PYPANDA bool Dtool_Call_ExtractThisPointer(PyObject *self, Dtool_PyTypedObject &classdef, void **answer);
bool Dtool_Call_ExtractThisPointer_NonConst(PyObject *self, Dtool_PyTypedObject &classdef,
void **answer, const char *method_name);
EXPCL_PYPANDA bool Dtool_Call_ExtractThisPointer_NonConst(PyObject *self, Dtool_PyTypedObject &classdef,
void **answer, const char *method_name);
template<class T> INLINE bool DtoolInstance_GetPointer(PyObject *self, T *&into);
template<class T> INLINE bool DtoolInstance_GetPointer(PyObject *self, T *&into, Dtool_PyTypedObject &classdef);
@ -204,7 +201,7 @@ INLINE int DtoolInstance_ComparePointers(PyObject *v1, PyObject *v2);
INLINE PyObject *DtoolInstance_RichComparePointers(PyObject *v1, PyObject *v2, int op);
// Functions related to error reporting.
bool _Dtool_CheckErrorOccurred();
EXPCL_PYPANDA bool _Dtool_CheckErrorOccurred();
#ifdef NDEBUG
#define Dtool_CheckErrorOccurred() (UNLIKELY(_PyErr_OCCURRED() != nullptr))
@ -212,12 +209,12 @@ bool _Dtool_CheckErrorOccurred();
#define Dtool_CheckErrorOccurred() (UNLIKELY(_Dtool_CheckErrorOccurred()))
#endif
PyObject *Dtool_Raise_AssertionError();
PyObject *Dtool_Raise_TypeError(const char *message);
PyObject *Dtool_Raise_ArgTypeError(PyObject *obj, int param, const char *function_name, const char *type_name);
PyObject *Dtool_Raise_AttributeError(PyObject *obj, const char *attribute);
EXPCL_PYPANDA PyObject *Dtool_Raise_AssertionError();
EXPCL_PYPANDA PyObject *Dtool_Raise_TypeError(const char *message);
EXPCL_PYPANDA PyObject *Dtool_Raise_ArgTypeError(PyObject *obj, int param, const char *function_name, const char *type_name);
EXPCL_PYPANDA PyObject *Dtool_Raise_AttributeError(PyObject *obj, const char *attribute);
PyObject *_Dtool_Raise_BadArgumentsError();
EXPCL_PYPANDA PyObject *_Dtool_Raise_BadArgumentsError();
#ifdef NDEBUG
// Define it to a function that just prints a generic message.
#define Dtool_Raise_BadArgumentsError(x) _Dtool_Raise_BadArgumentsError()
@ -229,9 +226,9 @@ PyObject *_Dtool_Raise_BadArgumentsError();
// These functions are similar to Dtool_WrapValue, except that they also
// contain code for checking assertions and exceptions when compiling with
// NDEBUG mode on.
PyObject *_Dtool_Return_None();
PyObject *Dtool_Return_Bool(bool value);
PyObject *_Dtool_Return(PyObject *value);
EXPCL_PYPANDA PyObject *_Dtool_Return_None();
EXPCL_PYPANDA PyObject *Dtool_Return_Bool(bool value);
EXPCL_PYPANDA PyObject *_Dtool_Return(PyObject *value);
#ifdef NDEBUG
#define Dtool_Return_None() (LIKELY(_PyErr_OCCURRED() == nullptr) ? (Py_INCREF(Py_None), Py_None) : nullptr)
@ -244,19 +241,19 @@ PyObject *_Dtool_Return(PyObject *value);
/**
* Wrapper around Python 3.4's enum library, which does not have a C API.
*/
PyTypeObject *Dtool_EnumType_Create(const char *name, PyObject *names,
const char *module = nullptr);
EXPCL_PYPANDA PyTypeObject *Dtool_EnumType_Create(const char *name, PyObject *names,
const char *module = nullptr);
INLINE long Dtool_EnumValue_AsLong(PyObject *value);
/**
*/
PyObject *DTool_CreatePyInstanceTyped(void *local_this_in, Dtool_PyTypedObject &known_class_type, bool memory_rules, bool is_const, int RunTimeType);
EXPCL_PYPANDA PyObject *DTool_CreatePyInstanceTyped(void *local_this_in, Dtool_PyTypedObject &known_class_type, bool memory_rules, bool is_const, int RunTimeType);
// DTool_CreatePyInstance .. wrapper function to finalize the existance of a
// general dtool py instance..
PyObject *DTool_CreatePyInstance(void *local_this, Dtool_PyTypedObject &in_classdef, bool memory_rules, bool is_const);
EXPCL_PYPANDA PyObject *DTool_CreatePyInstance(void *local_this, Dtool_PyTypedObject &in_classdef, bool memory_rules, bool is_const);
// These template methods allow use when the Dtool_PyTypedObject is not known.
// They require a get_class_type() to be defined for the class.
@ -323,26 +320,26 @@ struct LibraryDef {
};
#if PY_MAJOR_VERSION >= 3
PyObject *Dtool_PyModuleInitHelper(const LibraryDef *defs[], PyModuleDef *module_def);
EXPCL_PYPANDA PyObject *Dtool_PyModuleInitHelper(const LibraryDef *defs[], PyModuleDef *module_def);
#else
PyObject *Dtool_PyModuleInitHelper(const LibraryDef *defs[], const char *modulename);
EXPCL_PYPANDA PyObject *Dtool_PyModuleInitHelper(const LibraryDef *defs[], const char *modulename);
#endif
// HACK.... Be carefull Dtool_BorrowThisReference This function can be used to
// grab the "THIS" pointer from an object and use it Required to support fom
// historical inharatence in the for of "is this instance of"..
PyObject *Dtool_BorrowThisReference(PyObject *self, PyObject *args);
EXPCL_PYPANDA PyObject *Dtool_BorrowThisReference(PyObject *self, PyObject *args);
#define DTOOL_PyObject_HashPointer DtoolInstance_HashPointer
#define DTOOL_PyObject_ComparePointers DtoolInstance_ComparePointers
PyObject *
EXPCL_PYPANDA PyObject *
copy_from_make_copy(PyObject *self, PyObject *noargs);
PyObject *
EXPCL_PYPANDA PyObject *
copy_from_copy_constructor(PyObject *self, PyObject *noargs);
PyObject *
EXPCL_PYPANDA PyObject *
map_deepcopy_to_copy(PyObject *self, PyObject *args);
/**
@ -351,14 +348,14 @@ map_deepcopy_to_copy(PyObject *self, PyObject *args);
*/
ALWAYS_INLINE bool Dtool_CheckNoArgs(PyObject *args);
ALWAYS_INLINE bool Dtool_CheckNoArgs(PyObject *args, PyObject *kwds);
bool Dtool_ExtractArg(PyObject **result, PyObject *args,
PyObject *kwds, const char *keyword);
bool Dtool_ExtractArg(PyObject **result, PyObject *args,
PyObject *kwds);
bool Dtool_ExtractOptionalArg(PyObject **result, PyObject *args,
PyObject *kwds, const char *keyword);
bool Dtool_ExtractOptionalArg(PyObject **result, PyObject *args,
PyObject *kwds);
EXPCL_PYPANDA bool Dtool_ExtractArg(PyObject **result, PyObject *args,
PyObject *kwds, const char *keyword);
EXPCL_PYPANDA bool Dtool_ExtractArg(PyObject **result, PyObject *args,
PyObject *kwds);
EXPCL_PYPANDA bool Dtool_ExtractOptionalArg(PyObject **result, PyObject *args,
PyObject *kwds, const char *keyword);
EXPCL_PYPANDA bool Dtool_ExtractOptionalArg(PyObject **result, PyObject *args,
PyObject *kwds);
/**
* These functions convert a C++ value into the corresponding Python object.
@ -393,7 +390,7 @@ ALWAYS_INLINE PyObject *Dtool_WrapValue(Py_buffer *value);
template<class T1, class T2>
ALWAYS_INLINE PyObject *Dtool_WrapValue(const std::pair<T1, T2> &value);
Dtool_PyTypedObject *Dtool_GetSuperBase();
EXPCL_PYPANDA Dtool_PyTypedObject *Dtool_GetSuperBase();
#include "py_panda.I"

View File

@ -49,12 +49,12 @@ struct Dtool_GeneratorWrapper {
iternextfunc _iternext_func;
};
Dtool_SequenceWrapper *Dtool_NewSequenceWrapper(PyObject *self, const char *name);
Dtool_MutableSequenceWrapper *Dtool_NewMutableSequenceWrapper(PyObject *self, const char *name);
Dtool_MappingWrapper *Dtool_NewMappingWrapper(PyObject *self, const char *name);
Dtool_MappingWrapper *Dtool_NewMutableMappingWrapper(PyObject *self, const char *name);
PyObject *Dtool_NewGenerator(PyObject *self, iternextfunc func);
PyObject *Dtool_NewStaticProperty(PyTypeObject *obj, const PyGetSetDef *getset);
EXPCL_PYPANDA Dtool_SequenceWrapper *Dtool_NewSequenceWrapper(PyObject *self, const char *name);
EXPCL_PYPANDA Dtool_MutableSequenceWrapper *Dtool_NewMutableSequenceWrapper(PyObject *self, const char *name);
EXPCL_PYPANDA Dtool_MappingWrapper *Dtool_NewMappingWrapper(PyObject *self, const char *name);
EXPCL_PYPANDA Dtool_MappingWrapper *Dtool_NewMutableMappingWrapper(PyObject *self, const char *name);
EXPCL_PYPANDA PyObject *Dtool_NewGenerator(PyObject *self, iternextfunc func);
EXPCL_PYPANDA PyObject *Dtool_NewStaticProperty(PyTypeObject *obj, const PyGetSetDef *getset);
#endif // HAVE_PYTHON

View File

@ -0,0 +1,5 @@
typedef struct _XINPUT_STATE XINPUT_STATE, *PXINPUT_STATE;
typedef struct _XINPUT_CAPABILITIES XINPUT_CAPABILITIES, *PXINPUT_CAPABILITIES;
typedef struct _XINPUT_VIBRATION XINPUT_VIBRATION, *PXINPUT_VIBRATION;
typedef struct _XINPUT_GAMEPAD XINPUT_GAMEPAD, *PXINPUT_GAMEPAD;
typedef struct _XINPUT_KEYSTROKE XINPUT_KEYSTROKE, *PXINPUT_KEYSTROKE;

View File

@ -38,8 +38,10 @@ typedef unsigned long ULONG_PTR;
// http://msdn.microsoft.com/en-us/library/cc230309.aspx
typedef bool BOOL;
typedef unsigned long DWORD;
typedef unsigned short WORD;
typedef long LONG;
typedef long UINT;
typedef unsigned char BYTE;
typedef unsigned long ULONG;
typedef long long LONGLONG;
typedef long HRESULT;

View File

@ -38,6 +38,10 @@
#include <algorithm>
#include <ctype.h>
#ifndef _MSC_VER
#include <dlfcn.h>
#endif
using std::string;
ConfigPageManager *ConfigPageManager::_global_ptr = nullptr;
@ -93,11 +97,60 @@ reload_implicit_pages() {
}
_implicit_pages.clear();
// If we are running inside a deployed application, see if it exposes
// information about how the PRC data should be initialized.
struct BlobInfo {
uint64_t blob_offset;
uint64_t blob_size;
uint16_t version;
uint16_t num_pointers;
uint16_t codepage;
uint16_t flags;
uint64_t reserved;
const void *module_table;
const char *prc_data;
const char *default_prc_dir;
const char *prc_dir_envvars;
const char *prc_path_envvars;
const char *prc_patterns;
const char *prc_encrypted_patterns;
const char *prc_encryption_key;
const char *prc_executable_patterns;
const char *prc_executable_args_envvar;
const char *main_dir;
const char *log_filename;
};
#ifdef _MSC_VER
const BlobInfo *blobinfo = (const BlobInfo *)GetProcAddress(GetModuleHandle(NULL), "blobinfo");
#elif defined(RTLD_MAIN_ONLY)
const BlobInfo *blobinfo = (const BlobInfo *)dlsym(RTLD_MAIN_ONLY, "blobinfo");
//#elif defined(RTLD_SELF)
// const BlobInfo *blobinfo = (const BlobInfo *)dlsym(RTLD_SELF, "blobinfo");
#else
const BlobInfo *blobinfo = (const BlobInfo *)dlsym(dlopen(NULL, RTLD_NOW), "blobinfo");
#endif
if (blobinfo != nullptr && (blobinfo->version == 0 || blobinfo->num_pointers < 10)) {
blobinfo = nullptr;
}
if (blobinfo != nullptr) {
if (blobinfo->num_pointers >= 11 && blobinfo->main_dir != nullptr) {
ExecutionEnvironment::set_environment_variable("MAIN_DIR", blobinfo->main_dir);
} else {
// Make sure that py_panda.cxx won't override MAIN_DIR.
ExecutionEnvironment::set_environment_variable("MAIN_DIR",
ExecutionEnvironment::get_environment_variable("MAIN_DIR"));
}
}
// PRC_PATTERNS lists one or more filename templates separated by spaces.
// Pull them out and store them in _prc_patterns.
_prc_patterns.clear();
string prc_patterns = PRC_PATTERNS;
if (blobinfo != nullptr && blobinfo->prc_patterns != nullptr) {
prc_patterns = blobinfo->prc_patterns;
}
if (!prc_patterns.empty()) {
vector_string pat_list;
ConfigDeclaration::extract_words(prc_patterns, pat_list);
@ -117,6 +170,9 @@ reload_implicit_pages() {
_prc_encrypted_patterns.clear();
string prc_encrypted_patterns = PRC_ENCRYPTED_PATTERNS;
if (blobinfo != nullptr && blobinfo->prc_encrypted_patterns != nullptr) {
prc_encrypted_patterns = blobinfo->prc_encrypted_patterns;
}
if (!prc_encrypted_patterns.empty()) {
vector_string pat_list;
ConfigDeclaration::extract_words(prc_encrypted_patterns, pat_list);
@ -134,6 +190,9 @@ reload_implicit_pages() {
_prc_executable_patterns.clear();
string prc_executable_patterns = PRC_EXECUTABLE_PATTERNS;
if (blobinfo != nullptr && blobinfo->prc_executable_patterns != nullptr) {
prc_executable_patterns = blobinfo->prc_executable_patterns;
}
if (!prc_executable_patterns.empty()) {
vector_string pat_list;
ConfigDeclaration::extract_words(prc_executable_patterns, pat_list);
@ -154,6 +213,9 @@ reload_implicit_pages() {
// spaces. Pull them out, and each of those contains the name of a single
// directory to search. Add it to the search path.
string prc_dir_envvars = PRC_DIR_ENVVARS;
if (blobinfo != nullptr && blobinfo->prc_dir_envvars != nullptr) {
prc_dir_envvars = blobinfo->prc_dir_envvars;
}
if (!prc_dir_envvars.empty()) {
vector_string prc_dir_envvar_list;
ConfigDeclaration::extract_words(prc_dir_envvars, prc_dir_envvar_list);
@ -173,6 +235,9 @@ reload_implicit_pages() {
// spaces. Pull them out, and then each one of those contains a list of
// directories to search. Add each of those to the search path.
string prc_path_envvars = PRC_PATH_ENVVARS;
if (blobinfo != nullptr && blobinfo->prc_path_envvars != nullptr) {
prc_path_envvars = blobinfo->prc_path_envvars;
}
if (!prc_path_envvars.empty()) {
vector_string prc_path_envvar_list;
ConfigDeclaration::extract_words(prc_path_envvars, prc_path_envvar_list);
@ -204,7 +269,7 @@ reload_implicit_pages() {
* DEFAULT_PATHSEP.
*/
string prc_path2_envvars = PRC_PATH2_ENVVARS;
if (!prc_path2_envvars.empty()) {
if (!prc_path2_envvars.empty() && blobinfo == nullptr) {
vector_string prc_path_envvar_list;
ConfigDeclaration::extract_words(prc_path2_envvars, prc_path_envvar_list);
for (size_t i = 0; i < prc_path_envvar_list.size(); ++i) {
@ -228,6 +293,9 @@ reload_implicit_pages() {
// If nothing's on the search path (PRC_DIR and PRC_PATH were not
// defined), then use the DEFAULT_PRC_DIR.
string default_prc_dir = DEFAULT_PRC_DIR;
if (blobinfo != nullptr && blobinfo->default_prc_dir != nullptr) {
default_prc_dir = blobinfo->default_prc_dir;
}
if (!default_prc_dir.empty()) {
// It's already from-os-specific by ppremake.
Filename prc_dir_filename = default_prc_dir;
@ -300,12 +368,24 @@ reload_implicit_pages() {
}
}
int i = 1;
// If prc_data is predefined, we load it as an implicit page.
if (blobinfo != nullptr && blobinfo->prc_data != nullptr) {
ConfigPage *page = new ConfigPage("builtin", true, i);
++i;
_implicit_pages.push_back(page);
_pages_sorted = false;
std::istringstream in(blobinfo->prc_data);
page->read_prc(in);
}
// Now we have a list of filenames in order from most important to least
// important. Walk through the list in reverse order to load their
// contents, because we want the first file in the list (the most important)
// to be on the top of the stack.
ConfigFiles::reverse_iterator ci;
int i = 1;
for (ci = config_files.rbegin(); ci != config_files.rend(); ++ci) {
const ConfigFile &file = (*ci);
Filename filename = file._filename;
@ -316,6 +396,9 @@ reload_implicit_pages() {
string command = filename.to_os_specific();
string envvar = PRC_EXECUTABLE_ARGS_ENVVAR;
if (blobinfo != nullptr && blobinfo->prc_executable_args_envvar != nullptr) {
envvar = blobinfo->prc_executable_args_envvar;
}
if (!envvar.empty()) {
string args = ExecutionEnvironment::get_environment_variable(envvar);
if (!args.empty()) {
@ -346,7 +429,11 @@ reload_implicit_pages() {
_implicit_pages.push_back(page);
_pages_sorted = false;
page->read_encrypted_prc(in, PRC_ENCRYPTION_KEY);
if (blobinfo != nullptr && blobinfo->prc_encryption_key != nullptr) {
page->read_encrypted_prc(in, blobinfo->prc_encryption_key);
} else {
page->read_encrypted_prc(in, PRC_ENCRYPTION_KEY);
}
}
} else if ((file._file_flags & FF_read) != 0) {

View File

@ -14,7 +14,7 @@
;
; BUILT - location of panda install tree.
; SOURCE - location of the panda source-tree if available, OR location of panda install tree.
; PYVER - version of Python that Panda was built with (ie, "2.7")
; INCLUDE_PYVER - version of Python that Panda was built with (eg. "2.7", "3.5-32")
; REGVIEW - either 32 or 64, depending on the build architecture.
;
@ -46,7 +46,9 @@ SetCompressor ${COMPRESSOR}
!insertmacro MUI_PAGE_LICENSE "${SOURCE}/doc/LICENSE"
!insertmacro MUI_PAGE_DIRECTORY
!ifdef INCLUDE_PYVER
!define MUI_PAGE_CUSTOMFUNCTION_LEAVE ConfirmPythonSelection
!endif
!insertmacro MUI_PAGE_COMPONENTS
!insertmacro MUI_PAGE_INSTFILES
@ -64,8 +66,9 @@ ShowUninstDetails hide
LicenseData "${SOURCE}/doc/LICENSE"
InstType "Full (Recommended)"
InstType "Minimal"
InstType "Auto (Recommended)"
InstType "Full"
InstType "Light"
LangString DESC_SecCore ${LANG_ENGLISH} "The Panda3D core libraries, configuration files and models/textures that are needed to use Panda3D."
LangString DESC_SecOpenGL ${LANG_ENGLISH} "The OpenGL graphics back-end is the most well-supported renderer."
@ -78,8 +81,9 @@ LangString DESC_SecODE ${LANG_ENGLISH} "Support for the Open Dynamics Engine to
LangString DESC_SecPhysX ${LANG_ENGLISH} "Support for NVIDIA PhysX to implement physics."
LangString DESC_SecRocket ${LANG_ENGLISH} "Support for the libRocket GUI library. This is an optional library that offers an HTML/CSS-like approach to creating user interfaces."
LangString DESC_SecTools ${LANG_ENGLISH} "Useful tools and model converters to help with Panda3D development. Recommended."
LangString DESC_SecPyBindings ${LANG_ENGLISH} "Contains the Python modules that allow use of Panda3D using Python. These will only work with a ${REGVIEW}-bit version of Python ${PYVER}."
LangString DESC_SecPython ${LANG_ENGLISH} "Contains a ${REGVIEW}-bit copy of Python ${PYVER} preconfigured to make use of Panda3D."
LangString DESC_SecGroupPython ${LANG_ENGLISH} "Contains modules that provide Python support for Panda3D."
LangString DESC_SecPyShared ${LANG_ENGLISH} "Contains the common Python code used by the Panda3D Python bindings."
LangString DESC_SecPython ${LANG_ENGLISH} "Contains a ${REGVIEW}-bit copy of Python ${INCLUDE_PYVER} preconfigured to make use of Panda3D."
LangString DESC_SecHeadersLibs ${LANG_ENGLISH} "Headers and libraries needed for C++ development with Panda3D."
LangString DESC_SecSamples ${LANG_ENGLISH} "The sample programs demonstrate how to make Python applications with Panda3D."
LangString DESC_SecMaxPlugins ${LANG_ENGLISH} "Plug-ins for Autodesk 3ds Max (${REGVIEW}-bit) that can be used to export models to Panda3D."
@ -112,228 +116,41 @@ var MANPAGE
!insertmacro !defineifexist HAVE_ODE "${BUILT}\bin\libpandaode.dll"
!insertmacro !defineifexist HAVE_PHYSX "${BUILT}\bin\libpandaphysx.dll"
!insertmacro !defineifexist HAVE_ROCKET "${BUILT}\bin\libp3rocket.dll"
!insertmacro !defineifexist HAVE_PYTHON "${BUILT}\python"
!insertmacro !defineifexist HAVE_SAMPLES "${SOURCE}\samples"
!insertmacro !defineifexist HAVE_MAX_PLUGINS "${BUILT}\plugins\*.dlo"
!insertmacro !defineifexist HAVE_MAYA_PLUGINS "${BUILT}\plugins\*.mll"
Function runFunction
ExecShell "open" "$SMPROGRAMS\${TITLE}\Panda3D Manual.lnk"
FunctionEnd
!macro RemovePythonPath PYVER
ReadRegStr $0 HKCU "Software\Python\PythonCore\${PYVER}\PythonPath\Panda3D" ""
StrCmp $0 "$INSTDIR" 0 +2
DeleteRegKey HKCU "Software\Python\PythonCore\${PYVER}\PythonPath\Panda3D"
!macroend
Function .onInit
${If} ${REGVIEW} = 64
${AndIfNot} ${RunningX64}
MessageBox MB_OK|MB_ICONEXCLAMATION "You are attempting to install the 64-bit version of Panda3D on a 32-bit version of Windows. Please download and install the 32-bit version of Panda3D instead."
Abort
${EndIf}
FunctionEnd
!macro PyBindingSection PYVER EXT_SUFFIX
LangString DESC_SecPyBindings${PYVER} ${LANG_ENGLISH} "Contains the Python modules that allow use of Panda3D using a ${REGVIEW}-bit version of Python ${PYVER}."
SectionGroup "Panda3D Libraries"
Section "Core Libraries" SecCore
SectionIn 1 2 RO
SetShellVarContext current
SetOverwrite try
!insertmacro !defineifexist _present "${BUILT}\panda3d\core${EXT_SUFFIX}"
!ifdef _present
Section "${PYVER} bindings" SecPyBindings${PYVER}
!if "${PYVER}" == "${INCLUDE_PYVER}"
SectionIn 1 2 3
!else
!if "${PYVER}" == "2.7"
SectionIn 1 2
!else
; See .onInit function where this is dynamically enabled.
SectionIn 2
!endif
!endif
SetDetailsPrint both
DetailPrint "Installing Panda3D libraries..."
DetailPrint "Installing Panda3D bindings for Python ${PYVER}..."
SetDetailsPrint listonly
SetOutPath "$INSTDIR"
File /nonfatal "${BUILT}\LICENSE"
File /nonfatal "${BUILT}\ReleaseNotes"
File /nonfatal "${BUILT}\pandaIcon.ico"
SetOutPath $INSTDIR\etc
File /r "${BUILT}\etc\*"
SetOutPath $INSTDIR\bin
File /r /x api-ms-win-*.dll /x ucrtbase.dll /x libpandagl.dll /x libpandadx9.dll /x cgD3D*.dll /x python*.dll /x libpandaode.dll /x libp3fmod_audio.dll /x fmodex*.dll /x libp3ffmpeg.dll /x av*.dll /x postproc*.dll /x swscale*.dll /x swresample*.dll /x NxCharacter*.dll /x cudart*.dll /x PhysX*.dll /x libpandaphysx.dll /x libp3rocket.dll /x boost_python*.dll /x Rocket*.dll /x _rocket*.pyd /x libpandabullet.dll /x OpenAL32.dll /x *_oal.dll /x libp3openal_audio.dll "${BUILT}\bin\*.dll"
File /nonfatal /r "${BUILT}\bin\Microsoft.*.manifest"
; Before Windows 10, we need these stubs for the UCRT as well.
ReadRegDWORD $0 HKLM "Software\Microsoft\Windows NT\CurrentVersion" "CurrentMajorVersionNumber"
${If} $0 < 10
ClearErrors
File /nonfatal /r "${BUILT}\bin\api-ms-win-*.dll"
File /nonfatal "${BUILT}\bin\ucrtbase.dll"
${Endif}
SetDetailsPrint both
DetailPrint "Installing models..."
SetDetailsPrint listonly
SetOutPath $INSTDIR\models
File /r /x CVS "${BUILT}\models\*"
SetDetailsPrint both
DetailPrint "Installing optional components..."
SetDetailsPrint listonly
RMDir /r "$SMPROGRAMS\${TITLE}"
CreateDirectory "$SMPROGRAMS\${TITLE}"
SectionEnd
!ifdef HAVE_GL
Section "OpenGL" SecOpenGL
SectionIn 1 2 RO
SetOutPath "$INSTDIR\bin"
File "${BUILT}\bin\libpandagl.dll"
SectionEnd
!endif
!ifdef HAVE_DX9
Section "Direct3D 9" SecDirect3D9
SectionIn 1
SetOutPath "$INSTDIR\bin"
File "${BUILT}\bin\libpandadx9.dll"
File /nonfatal /r "${BUILT}\bin\cgD3D9.dll"
SectionEnd
!endif
!ifdef HAVE_OPENAL
Section "OpenAL Audio" SecOpenAL
SectionIn 1 2
SetOutPath "$INSTDIR\bin"
File "${BUILT}\bin\libp3openal_audio.dll"
File /nonfatal /r "${BUILT}\bin\OpenAL32.dll"
File /nonfatal /r "${BUILT}\bin\*_oal.dll"
SectionEnd
!endif
!ifdef HAVE_FMOD
Section "FMOD Audio" SecFMOD
SectionIn 1
SetOutPath "$INSTDIR\bin"
File "${BUILT}\bin\libp3fmod_audio.dll"
File /r "${BUILT}\bin\fmodex*.dll"
SectionEnd
!endif
!ifdef HAVE_FFMPEG
Section "FFMpeg" SecFFMpeg
SectionIn 1
SetOutPath "$INSTDIR\bin"
File "${BUILT}\bin\libp3ffmpeg.dll"
File /nonfatal /r "${BUILT}\bin\av*.dll"
File /nonfatal /r "${BUILT}\bin\swscale*.dll"
File /nonfatal /r "${BUILT}\bin\swresample*.dll"
File /nonfatal /r "${BUILT}\bin\postproc*.dll"
SectionEnd
!endif
!ifdef HAVE_BULLET
Section "Bullet Physics" SecBullet
SectionIn 1
SetOutPath "$INSTDIR\bin"
File "${BUILT}\bin\libpandabullet.dll"
SectionEnd
!endif
!ifdef HAVE_ODE
Section "ODE Physics" SecODE
SectionIn 1
SetOutPath "$INSTDIR\bin"
File "${BUILT}\bin\libpandaode.dll"
SectionEnd
!endif
!ifdef HAVE_PHYSX
Section "NVIDIA PhysX" SecPhysX
SectionIn 1
SetOutPath "$INSTDIR\bin"
File "${BUILT}\bin\libpandaphysx.dll"
File /nonfatal /r "${BUILT}\bin\PhysX*.dll"
File /nonfatal /r "${BUILT}\bin\NxCharacter*.dll"
File /nonfatal /r "${BUILT}\bin\cudart*.dll"
SectionEnd
!endif
!ifdef HAVE_ROCKET
Section "libRocket GUI" SecRocket
SectionIn 1
SetOutPath "$INSTDIR\bin"
File "${BUILT}\bin\libp3rocket.dll"
File /nonfatal /r "${BUILT}\bin\Rocket*.dll"
File /nonfatal /r "${BUILT}\bin\_rocket*.pyd"
File /nonfatal /r "${BUILT}\bin\boost_python*.dll"
SectionEnd
!endif
SectionGroupEnd
Section "Tools and utilities" SecTools
SectionIn 1 2
SetDetailsPrint both
DetailPrint "Installing utilities..."
SetDetailsPrint listonly
SetOutPath "$INSTDIR\bin"
File /r "${BUILT}\bin\*.exe"
File /nonfatal /r "${BUILT}\bin\*.p3d"
SetOutPath "$INSTDIR\NSIS"
File /r /x CVS "${NSISDIR}\*"
WriteRegStr HKCU "Software\Classes\Panda3D.Model" "" "Panda3D model/animation"
WriteRegStr HKCU "Software\Classes\Panda3D.Model\DefaultIcon" "" "$INSTDIR\bin\pview.exe"
WriteRegStr HKCU "Software\Classes\Panda3D.Model\shell" "" "open"
WriteRegStr HKCU "Software\Classes\Panda3D.Model\shell\open\command" "" '"$INSTDIR\bin\pview.exe" -l "%1"'
WriteRegStr HKCU "Software\Classes\Panda3D.Model\shell\compress" "" "Compress to .pz"
WriteRegStr HKCU "Software\Classes\Panda3D.Model\shell\compress\command" "" '"$INSTDIR\bin\pzip.exe" "%1"'
WriteRegStr HKCU "Software\Classes\Panda3D.Compressed" "" "Compressed file"
WriteRegStr HKCU "Software\Classes\Panda3D.Compressed\DefaultIcon" "" "$INSTDIR\bin\pzip.exe"
WriteRegStr HKCU "Software\Classes\Panda3D.Compressed\shell" "" "open"
WriteRegStr HKCU "Software\Classes\Panda3D.Compressed\shell\open\command" "" '"$INSTDIR\bin\pview.exe" -l "%1"'
WriteRegStr HKCU "Software\Classes\Panda3D.Compressed\shell\decompress" "" "Decompress"
WriteRegStr HKCU "Software\Classes\Panda3D.Compressed\shell\decompress\command" "" '"$INSTDIR\bin\punzip.exe" "%1"'
WriteRegStr HKCU "Software\Classes\Panda3D.Multifile" "" "Panda3D Multifile"
WriteRegStr HKCU "Software\Classes\Panda3D.Multifile\DefaultIcon" "" "$INSTDIR\bin\multify.exe"
WriteRegStr HKCU "Software\Classes\Panda3D.Multifile\shell" "" "open"
WriteRegStr HKCU "Software\Classes\Panda3D.Multifile\shell\extract" "" "Extract here"
WriteRegStr HKCU "Software\Classes\Panda3D.Multifile\shell\extract\command" "" '"$INSTDIR\bin\multify.exe" -xf "%1"'
SectionEnd
SectionGroup "Python support"
Section "Python bindings" SecPyBindings
SectionIn 1 2
SetDetailsPrint both
DetailPrint "Installing Panda3D Python modules..."
SetDetailsPrint listonly
SetOutPath "$INSTDIR\bin"
File /nonfatal /r "${BUILT}\bin\*.pyd"
SetOutPath $INSTDIR\direct\directscripts
File /r /x CVS /x Opt?-Win32 "${BUILT}\direct\directscripts\*"
SetOutPath $INSTDIR\direct\filter
File /r /x CVS /x Opt?-Win32 "${BUILT}\direct\filter\*.sha"
SetOutPath $INSTDIR\direct
File /r /x CVS /x Opt?-Win32 "${BUILT}\direct\*.py"
Delete "$INSTDIR\panda3d.py"
Delete "$INSTDIR\panda3d.pyc"
Delete "$INSTDIR\panda3d.pyo"
SetOutPath $INSTDIR\pandac
File /r "${BUILT}\pandac\*.py"
SetOutPath $INSTDIR\panda3d
File /r "${BUILT}\panda3d\*.py"
File /nonfatal /r "${BUILT}\panda3d\core${EXT_SUFFIX}"
File /nonfatal /r "${BUILT}\panda3d\ai${EXT_SUFFIX}"
File /nonfatal /r "${BUILT}\panda3d\awesomium${EXT_SUFFIX}"
File /nonfatal /r "${BUILT}\panda3d\direct${EXT_SUFFIX}"
File /nonfatal /r "${BUILT}\panda3d\egg${EXT_SUFFIX}"
File /nonfatal /r "${BUILT}\panda3d\fx${EXT_SUFFIX}"
@ -380,92 +197,349 @@ SectionGroup "Python support"
File /r "${BUILT}\pandac\input\*"
SetOutPath $INSTDIR\Pmw
File /nonfatal /r /x CVS "${BUILT}\Pmw\*"
SetOutPath $INSTDIR\panda3d.dist-info
File /nonfatal /r "${BUILT}\panda3d.dist-info\*"
!ifdef REGVIEW
SetRegView ${REGVIEW}
!endif
; Check for a non-Panda3D system-wide Python installation.
ReadRegStr $0 HKLM "Software\Python\PythonCore\${PYVER}\InstallPath" ""
StrCmp $0 "$INSTDIR\python" UserExternalPthCheck 0
StrCmp $0 "" UserExternalPthCheck 0
IfFileExists "$0\ppython.exe" UserExternalPthCheck 0
IfFileExists "$0\python.exe" AskExternalPth UserExternalPthCheck
; Check for a non-Panda3D user installation of Python.
UserExternalPthCheck:
ReadRegStr $0 HKCU "Software\Python\PythonCore\${PYVER}\InstallPath" ""
StrCmp $0 "$INSTDIR\python" SkipExternalPth 0
StrCmp $0 "" SkipExternalPth 0
IfFileExists "$0\ppython.exe" SkipExternalPth 0
IfFileExists "$0\python.exe" AskExternalPth SkipExternalPth
; We're pretty sure this Python build is of the right architecture.
AskExternalPth:
MessageBox MB_YESNO|MB_ICONQUESTION \
"Your system already has a copy of Python ${PYVER} installed in:$\r$\n$0$\r$\nWould you like to configure it to be able to use the Panda3D libraries?$\r$\nIf you choose no, you will only be able to use Panda3D's own copy of Python." \
IDYES WriteExternalPth IDNO SkipExternalPth
WriteExternalPth:
;FileOpen $1 "$0\Lib\site-packages\panda.pth" w
;FileWrite $1 "$INSTDIR$\r$\n"
;FileWrite $1 "$INSTDIR\bin$\r$\n"
;FileClose $1
; Actually, it looks like we can just do this instead:
; Install a Panda3D path into the global PythonPath for this version
; of Python.
WriteRegStr HKCU "Software\Python\PythonCore\${PYVER}\PythonPath\Panda3D" "" "$INSTDIR"
SectionEnd
!undef _present
!endif
!macroend
SkipExternalPth:
Function runFunction
ExecShell "open" "$SMPROGRAMS\${TITLE}\Panda3D Manual.lnk"
FunctionEnd
SectionGroup "Panda3D Libraries"
Section "Core Libraries" SecCore
SectionIn 1 2 3 RO
SetShellVarContext current
SetOverwrite try
SetDetailsPrint both
DetailPrint "Installing Panda3D libraries..."
SetDetailsPrint listonly
SetOutPath "$INSTDIR"
File /nonfatal "${BUILT}\LICENSE"
File /nonfatal "${BUILT}\ReleaseNotes"
File /nonfatal "${BUILT}\pandaIcon.ico"
SetOutPath $INSTDIR\etc
File /r "${BUILT}\etc\*"
SetOutPath $INSTDIR\bin
File /r /x api-ms-win-*.dll /x ucrtbase.dll /x libpandagl.dll /x libpandadx9.dll /x cgD3D*.dll /x python*.dll /x libpandaode.dll /x libp3fmod_audio.dll /x fmodex*.dll /x libp3ffmpeg.dll /x av*.dll /x postproc*.dll /x swscale*.dll /x swresample*.dll /x NxCharacter*.dll /x cudart*.dll /x PhysX*.dll /x libpandaphysx.dll /x libp3rocket.dll /x boost_python*.dll /x Rocket*.dll /x _rocket*.pyd /x libpandabullet.dll /x OpenAL32.dll /x *_oal.dll /x libp3openal_audio.dll "${BUILT}\bin\*.dll"
File /nonfatal /r "${BUILT}\bin\Microsoft.*.manifest"
; Before Windows 10, we need these stubs for the UCRT as well.
ReadRegDWORD $0 HKLM "Software\Microsoft\Windows NT\CurrentVersion" "CurrentMajorVersionNumber"
${If} $0 < 10
ClearErrors
File /nonfatal /r "${BUILT}\bin\api-ms-win-*.dll"
File /nonfatal "${BUILT}\bin\ucrtbase.dll"
${Endif}
SetDetailsPrint both
DetailPrint "Installing models..."
SetDetailsPrint listonly
SetOutPath $INSTDIR\models
File /r /x CVS "${BUILT}\models\*"
SetDetailsPrint both
DetailPrint "Installing optional components..."
SetDetailsPrint listonly
RMDir /r "$SMPROGRAMS\${TITLE}"
CreateDirectory "$SMPROGRAMS\${TITLE}"
SectionEnd
!ifdef HAVE_PYTHON
Section "Python ${PYVER}" SecPython
SectionIn 1 2
!ifdef REGVIEW
SetRegView ${REGVIEW}
!endif
SetDetailsPrint both
DetailPrint "Installing Python ${PYVER} (${REGVIEW}-bit)..."
SetDetailsPrint listonly
!ifdef HAVE_GL
Section "OpenGL" SecOpenGL
SectionIn 1 2 3 RO
SetOutPath "$INSTDIR\bin"
File /nonfatal "${BUILT}\bin\python*.dll"
File "${BUILT}\bin\libpandagl.dll"
SectionEnd
!endif
SetOutPath "$INSTDIR\python"
File /r /x *.pdb "${BUILT}\python\*"
!ifdef HAVE_DX9
Section "Direct3D 9" SecDirect3D9
SectionIn 1 2
SetDetailsPrint both
DetailPrint "Adding registry keys for Python..."
SetDetailsPrint listonly
SetOutPath "$INSTDIR\bin"
File "${BUILT}\bin\libpandadx9.dll"
File /nonfatal /r "${BUILT}\bin\cgD3D9.dll"
SectionEnd
!endif
; Check if a copy of Python is installed for this user.
ReadRegStr $0 HKCU "Software\Python\PythonCore\${PYVER}\InstallPath" ""
StrCmp "$0" "$INSTDIR\python" RegPath 0
StrCmp "$0" "" SkipFileCheck 0
IfFileExists "$0\python.exe" AskRegPath 0
SkipFileCheck:
!ifdef HAVE_OPENAL
Section "OpenAL Audio" SecOpenAL
SectionIn 1 2 3
; Check if a system-wide copy of Python is installed.
ReadRegStr $0 HKLM "Software\Python\PythonCore\${PYVER}\InstallPath" ""
StrCmp "$0" "$INSTDIR\python" RegPath 0
StrCmp "$0" "" RegPath 0
IfFileExists "$0\python.exe" AskRegPath RegPath
SetOutPath "$INSTDIR\bin"
File "${BUILT}\bin\libp3openal_audio.dll"
File /nonfatal /r "${BUILT}\bin\OpenAL32.dll"
File /nonfatal /r "${BUILT}\bin\*_oal.dll"
SectionEnd
!endif
AskRegPath:
MessageBox MB_YESNO|MB_ICONQUESTION \
"You already have a copy of Python ${PYVER} installed in:$\r$\n$0$\r$\n$\r$\nPanda3D installs its own copy of Python ${PYVER}, which will install alongside your existing copy. Would you like to make Panda's copy the default Python for your user account?" \
IDNO SkipRegPath
!ifdef HAVE_FMOD
Section "FMOD Audio" SecFMOD
SectionIn 1 2
RegPath:
WriteRegStr HKCU "Software\Python\PythonCore\${PYVER}\InstallPath" "" "$INSTDIR\python"
SkipRegPath:
SetOutPath "$INSTDIR\bin"
File "${BUILT}\bin\libp3fmod_audio.dll"
File /r "${BUILT}\bin\fmodex*.dll"
SectionEnd
!endif
!ifdef HAVE_FFMPEG
Section "FFMpeg" SecFFMpeg
SectionIn 1 2
SetOutPath "$INSTDIR\bin"
File "${BUILT}\bin\libp3ffmpeg.dll"
File /nonfatal /r "${BUILT}\bin\av*.dll"
File /nonfatal /r "${BUILT}\bin\swscale*.dll"
File /nonfatal /r "${BUILT}\bin\swresample*.dll"
File /nonfatal /r "${BUILT}\bin\postproc*.dll"
SectionEnd
!endif
!ifdef HAVE_BULLET
Section "Bullet Physics" SecBullet
SectionIn 1 2
SetOutPath "$INSTDIR\bin"
File "${BUILT}\bin\libpandabullet.dll"
SectionEnd
!endif
!ifdef HAVE_ODE
Section "ODE Physics" SecODE
SectionIn 1 2
SetOutPath "$INSTDIR\bin"
File "${BUILT}\bin\libpandaode.dll"
SectionEnd
!endif
!ifdef HAVE_PHYSX
Section "NVIDIA PhysX" SecPhysX
; Only enable in "Full"
SectionIn 2
SetOutPath "$INSTDIR\bin"
File "${BUILT}\bin\libpandaphysx.dll"
File /nonfatal /r "${BUILT}\bin\PhysX*.dll"
File /nonfatal /r "${BUILT}\bin\NxCharacter*.dll"
File /nonfatal /r "${BUILT}\bin\cudart*.dll"
SectionEnd
!endif
!ifdef HAVE_ROCKET
Section "libRocket GUI" SecRocket
SectionIn 1 2
SetOutPath "$INSTDIR\bin"
File "${BUILT}\bin\libp3rocket.dll"
File /nonfatal /r "${BUILT}\bin\Rocket*.dll"
File /nonfatal /r "${BUILT}\bin\_rocket*.pyd"
File /nonfatal /r "${BUILT}\bin\boost_python*.dll"
SectionEnd
!endif
SectionGroupEnd
Section "Tools and utilities" SecTools
SectionIn 1 2 3
SetDetailsPrint both
DetailPrint "Installing utilities..."
SetDetailsPrint listonly
SetOutPath "$INSTDIR\bin"
File /r /x deploy-stub.exe /x deploy-stubw.exe "${BUILT}\bin\*.exe"
File /nonfatal /r "${BUILT}\bin\*.p3d"
SetOutPath "$INSTDIR\NSIS"
File /r /x CVS "${NSISDIR}\*"
WriteRegStr HKCU "Software\Classes\Panda3D.Model" "" "Panda3D model/animation"
WriteRegStr HKCU "Software\Classes\Panda3D.Model\DefaultIcon" "" "$INSTDIR\bin\pview.exe"
WriteRegStr HKCU "Software\Classes\Panda3D.Model\shell" "" "open"
WriteRegStr HKCU "Software\Classes\Panda3D.Model\shell\open\command" "" '"$INSTDIR\bin\pview.exe" -l "%1"'
WriteRegStr HKCU "Software\Classes\Panda3D.Model\shell\compress" "" "Compress to .pz"
WriteRegStr HKCU "Software\Classes\Panda3D.Model\shell\compress\command" "" '"$INSTDIR\bin\pzip.exe" "%1"'
WriteRegStr HKCU "Software\Classes\Panda3D.Compressed" "" "Compressed file"
WriteRegStr HKCU "Software\Classes\Panda3D.Compressed\DefaultIcon" "" "$INSTDIR\bin\pzip.exe"
WriteRegStr HKCU "Software\Classes\Panda3D.Compressed\shell" "" "open"
WriteRegStr HKCU "Software\Classes\Panda3D.Compressed\shell\open\command" "" '"$INSTDIR\bin\pview.exe" -l "%1"'
WriteRegStr HKCU "Software\Classes\Panda3D.Compressed\shell\decompress" "" "Decompress"
WriteRegStr HKCU "Software\Classes\Panda3D.Compressed\shell\decompress\command" "" '"$INSTDIR\bin\punzip.exe" "%1"'
WriteRegStr HKCU "Software\Classes\Panda3D.Multifile" "" "Panda3D Multifile"
WriteRegStr HKCU "Software\Classes\Panda3D.Multifile\DefaultIcon" "" "$INSTDIR\bin\multify.exe"
WriteRegStr HKCU "Software\Classes\Panda3D.Multifile\shell" "" "open"
WriteRegStr HKCU "Software\Classes\Panda3D.Multifile\shell\extract" "" "Extract here"
WriteRegStr HKCU "Software\Classes\Panda3D.Multifile\shell\extract\command" "" '"$INSTDIR\bin\multify.exe" -xf "%1"'
SectionEnd
SectionGroup "Python modules" SecGroupPython
Section "Shared code" SecPyShared
SectionIn 1 2 3
SetDetailsPrint both
DetailPrint "Installing Panda3D shared Python modules..."
SetDetailsPrint listonly
SetOutPath $INSTDIR\direct\directscripts
File /r /x CVS /x Opt?-Win32 "${BUILT}\direct\directscripts\*"
SetOutPath $INSTDIR\direct
File /r /x CVS /x Opt?-Win32 "${BUILT}\direct\*.py"
Delete "$INSTDIR\panda3d.py"
Delete "$INSTDIR\panda3d.pyc"
Delete "$INSTDIR\panda3d.pyo"
SetOutPath $INSTDIR\pandac
File /r "${BUILT}\pandac\*.py"
SetOutPath $INSTDIR\panda3d
File /r "${BUILT}\panda3d\*.py"
SectionEnd
!insertmacro PyBindingSection 2.7 .pyd
!if "${REGVIEW}" == "32"
!insertmacro PyBindingSection 3.5-32 .cp35-win32.pyd
!insertmacro PyBindingSection 3.6-32 .cp36-win32.pyd
!insertmacro PyBindingSection 3.7-32 .cp37-win32.pyd
!insertmacro PyBindingSection 3.8-32 .cp38-win32.pyd
!insertmacro PyBindingSection 3.9-32 .cp39-win32.pyd
!else
!insertmacro PyBindingSection 3.5 .cp35-win_amd64.pyd
!insertmacro PyBindingSection 3.6 .cp36-win_amd64.pyd
!insertmacro PyBindingSection 3.7 .cp37-win_amd64.pyd
!insertmacro PyBindingSection 3.8 .cp38-win_amd64.pyd
!insertmacro PyBindingSection 3.9 .cp39-win_amd64.pyd
!endif
SectionGroupEnd
!ifdef INCLUDE_PYVER
Section "Python ${INCLUDE_PYVER}" SecPython
SectionIn 1 2 3
!ifdef REGVIEW
SetRegView ${REGVIEW}
!endif
SetDetailsPrint both
DetailPrint "Installing Python ${INCLUDE_PYVER} interpreter (${REGVIEW}-bit)..."
SetDetailsPrint listonly
SetOutPath "$INSTDIR\bin"
File /nonfatal "${BUILT}\bin\python*.dll"
SetOutPath "$INSTDIR\python"
File /r /x *.pdb "${BUILT}\python\*"
SetDetailsPrint both
DetailPrint "Adding registry keys for Python..."
SetDetailsPrint listonly
; Check if a copy of Python is installed for this user.
ReadRegStr $0 HKCU "Software\Python\PythonCore\${INCLUDE_PYVER}\InstallPath" ""
StrCmp "$0" "$INSTDIR\python" RegPath 0
StrCmp "$0" "" SkipFileCheck 0
IfFileExists "$0\python.exe" AskRegPath 0
SkipFileCheck:
; Check if a system-wide copy of Python is installed.
ReadRegStr $0 HKLM "Software\Python\PythonCore\${INCLUDE_PYVER}\InstallPath" ""
StrCmp "$0" "$INSTDIR\python" RegPath 0
StrCmp "$0" "" RegPath 0
IfFileExists "$0\python.exe" AskRegPath RegPath
AskRegPath:
MessageBox MB_YESNO|MB_ICONQUESTION \
"You already have a copy of Python ${INCLUDE_PYVER} installed in:$\r$\n$0$\r$\n$\r$\nPanda3D installs its own copy of Python ${INCLUDE_PYVER}, which will install alongside your existing copy. Would you like to make Panda's copy the default Python for your user account?" \
IDNO SkipRegPath
RegPath:
WriteRegStr HKCU "Software\Python\PythonCore\${INCLUDE_PYVER}\InstallPath" "" "$INSTDIR\python"
WriteRegStr HKCU "Software\Python\PythonCore\${INCLUDE_PYVER}\InstallPath" "ExecutablePath" "$INSTDIR\python\python.exe"
SkipRegPath:
SectionEnd
!endif
!macro MaybeEnablePyBindingSection PYVER
!if "${INCLUDE_PYVER}" != "${PYVER}"
!ifdef SecPyBindings${PYVER}
; Check if a copy of Python is installed for this user.
Push $0
ReadRegStr $0 HKCU "Software\Python\PythonCore\${PYVER}\InstallPath" ""
StrCmp "$0" "" +2 0
IfFileExists "$0\python.exe" Py${PYVER}Exists 0
; Check if a system-wide copy of Python is installed.
ReadRegStr $0 HKLM "Software\Python\PythonCore\${PYVER}\InstallPath" ""
StrCmp "$0" "" Py${PYVER}ExistsNot 0
IfFileExists "$0\python.exe" Py${PYVER}Exists Py${PYVER}ExistsNot
Py${PYVER}Exists:
SectionSetFlags ${SecPyBindings${PYVER}} ${SF_SELECTED}
SectionSetInstTypes ${SecPyBindings${PYVER}} 3
Py${PYVER}ExistsNot:
Pop $0
!endif
!endif
!macroend
Function .onInit
${If} ${REGVIEW} = 64
${AndIfNot} ${RunningX64}
MessageBox MB_OK|MB_ICONEXCLAMATION "You are attempting to install the 64-bit version of Panda3D on a 32-bit version of Windows. Please download and install the 32-bit version of Panda3D instead."
Abort
${EndIf}
!ifdef REGVIEW
SetRegView ${REGVIEW}
!endif
; We never check for 2.7; it is always enabled in Auto mode
!if "${REGVIEW}" == "32"
!insertmacro MaybeEnablePyBindingSection 3.5-32
!insertmacro MaybeEnablePyBindingSection 3.6-32
!insertmacro MaybeEnablePyBindingSection 3.7-32
!insertmacro MaybeEnablePyBindingSection 3.8-32
!insertmacro MaybeEnablePyBindingSection 3.9-32
!else
!insertmacro MaybeEnablePyBindingSection 3.5
!insertmacro MaybeEnablePyBindingSection 3.6
!insertmacro MaybeEnablePyBindingSection 3.7
!insertmacro MaybeEnablePyBindingSection 3.8
!insertmacro MaybeEnablePyBindingSection 3.9
!endif
FunctionEnd
Function .onSelChange
; If someone selects any Python version, the "shared modules" must be on.
${If} ${SectionIsPartiallySelected} ${SecGroupPython}
SectionGetFlags ${SecPyShared} $R0
IntOp $R0 $R0 | ${SF_SELECTED}
SectionSetFlags ${SecPyShared} $R0
${EndIf}
FunctionEnd
!ifdef INCLUDE_PYVER
Function ConfirmPythonSelection
; Check the current state of the "Python" section selection.
SectionGetFlags ${SecPython} $R0
@ -475,16 +549,14 @@ Function ConfirmPythonSelection
StrCmp $R1 ${SF_SELECTED} SkipCheck 0
; Maybe the user just doesn't want Python support at all?
SectionGetFlags ${SecPyBindings} $R1
IntOp $R1 $R1 & ${SF_SELECTED}
StrCmp $R1 ${SF_SELECTED} 0 SkipCheck
!insertmacro SectionFlagIsSet ${SecGroupPython} ${SF_PSELECTED} 0 SkipCheck
!ifdef REGVIEW
SetRegView ${REGVIEW}
!endif
; Check for a user installation of Python.
ReadRegStr $0 HKCU "Software\Python\PythonCore\${PYVER}\InstallPath" ""
ReadRegStr $0 HKCU "Software\Python\PythonCore\${INCLUDE_PYVER}\InstallPath" ""
StrCmp $0 "$INSTDIR\python" CheckSystemWidePython 0
StrCmp $0 "" CheckSystemWidePython 0
IfFileExists "$0\ppython.exe" CheckSystemWidePython 0
@ -492,7 +564,7 @@ Function ConfirmPythonSelection
; Check for a system-wide Python installation.
CheckSystemWidePython:
ReadRegStr $0 HKLM "Software\Python\PythonCore\${PYVER}\InstallPath" ""
ReadRegStr $0 HKLM "Software\Python\PythonCore\${INCLUDE_PYVER}\InstallPath" ""
StrCmp $0 "$INSTDIR\python" AskConfirmation 0
StrCmp $0 "" AskConfirmation 0
IfFileExists "$0\ppython.exe" AskConfirmation 0
@ -502,7 +574,7 @@ Function ConfirmPythonSelection
; of a different Panda3D build.) Ask the user if he's sure about this.
AskConfirmation:
MessageBox MB_YESNO|MB_ICONQUESTION \
"You do not appear to have a ${REGVIEW}-bit version of Python ${PYVER} installed. Are you sure you don't want Panda to install a compatible copy of Python?$\r$\n$\r$\nIf you choose Yes, you will not be able to do Python development with Panda3D until you install a ${REGVIEW}-bit version of Python ${PYVER} and manually configure it to be able to use Panda3D." \
"You do not appear to have a ${REGVIEW}-bit version of Python ${INCLUDE_PYVER} installed. Are you sure you don't want Panda to install a compatible copy of Python?$\r$\n$\r$\nIf you choose Yes, you will not be able to do Python development with Panda3D until you install a ${REGVIEW}-bit version of Python and install the bindings for this version." \
IDYES SkipCheck
; User clicked no, so re-enable the select box and abort.
@ -512,9 +584,10 @@ Function ConfirmPythonSelection
SkipCheck:
FunctionEnd
!endif
Section "C++ support" SecHeadersLibs
SectionIn 1
SectionIn 1 2
SetDetailsPrint both
DetailPrint "Installing header files..."
@ -533,7 +606,7 @@ SectionEnd
!ifdef HAVE_SAMPLES
Section "Sample programs" SecSamples
SectionIn 1
SectionIn 1 2
; Necessary for proper start menu shortcut installation
SetShellVarContext current
@ -600,7 +673,7 @@ SectionEnd
!ifdef HAVE_MAX_PLUGINS
Section "3ds Max plug-ins" SecMaxPlugins
SectionIn 1 3
SectionIn 1 2
SetDetailsPrint both
DetailPrint "Installing Autodesk 3ds Max plug-ins..."
@ -615,7 +688,7 @@ SectionEnd
!ifdef HAVE_MAYA_PLUGINS
Section "Maya plug-ins" SecMayaPlugins
SectionIn 1 3
SectionIn 1 2
SetDetailsPrint both
DetailPrint "Installing Autodesk Maya plug-ins..."
@ -738,17 +811,30 @@ Section Uninstall
DeleteRegKey HKCU "Software\Classes\Panda3D.Multifile\DefaultIcon"
DeleteRegKey HKCU "Software\Classes\Panda3D.Multifile\shell"
ReadRegStr $0 HKLM "Software\Python\PythonCore\${PYVER}\InstallPath" ""
StrCmp $0 "$INSTDIR\python" 0 +2
DeleteRegKey HKLM "Software\Python\PythonCore\${PYVER}"
!ifdef INCLUDE_PYVER
ReadRegStr $0 HKLM "Software\Python\PythonCore\${INCLUDE_PYVER}\InstallPath" ""
StrCmp $0 "$INSTDIR\python" 0 +2
DeleteRegKey HKLM "Software\Python\PythonCore\${INCLUDE_PYVER}"
ReadRegStr $0 HKCU "Software\Python\PythonCore\${PYVER}\InstallPath" ""
StrCmp $0 "$INSTDIR\python" 0 +2
DeleteRegKey HKCU "Software\Python\PythonCore\${PYVER}"
ReadRegStr $0 HKCU "Software\Python\PythonCore\${INCLUDE_PYVER}\InstallPath" ""
StrCmp $0 "$INSTDIR\python" 0 +2
DeleteRegKey HKCU "Software\Python\PythonCore\${INCLUDE_PYVER}"
!endif
ReadRegStr $0 HKCU "Software\Python\PythonCore\${PYVER}\PythonPath\Panda3D" ""
StrCmp $0 "$INSTDIR" 0 +2
DeleteRegKey HKCU "Software\Python\PythonCore\${PYVER}\PythonPath\Panda3D"
!insertmacro RemovePythonPath 2.7
!if "${REGVIEW}" == "32"
!insertmacro RemovePythonPath 3.5-32
!insertmacro RemovePythonPath 3.6-32
!insertmacro RemovePythonPath 3.7-32
!insertmacro RemovePythonPath 3.8-32
!insertmacro RemovePythonPath 3.9-32
!else
!insertmacro RemovePythonPath 3.5
!insertmacro RemovePythonPath 3.6
!insertmacro RemovePythonPath 3.7
!insertmacro RemovePythonPath 3.8
!insertmacro RemovePythonPath 3.9
!endif
SetDetailsPrint both
DetailPrint "Deleting files..."
@ -813,8 +899,23 @@ SectionEnd
!insertmacro MUI_DESCRIPTION_TEXT ${SecRocket} $(DESC_SecRocket)
!endif
!insertmacro MUI_DESCRIPTION_TEXT ${SecTools} $(DESC_SecTools)
!insertmacro MUI_DESCRIPTION_TEXT ${SecPyBindings} $(DESC_SecPyBindings)
!ifdef HAVE_PYTHON
!insertmacro MUI_DESCRIPTION_TEXT ${SecGroupPython} $(DESC_SecGroupPython)
!insertmacro MUI_DESCRIPTION_TEXT ${SecPyShared} $(DESC_SecPyShared)
!insertmacro MUI_DESCRIPTION_TEXT ${SecPyBindings2.7} $(DESC_SecPyBindings2.7)
!if "${REGVIEW}" == "32"
!insertmacro MUI_DESCRIPTION_TEXT ${SecPyBindings3.5-32} $(DESC_SecPyBindings3.5-32)
!insertmacro MUI_DESCRIPTION_TEXT ${SecPyBindings3.6-32} $(DESC_SecPyBindings3.6-32)
!insertmacro MUI_DESCRIPTION_TEXT ${SecPyBindings3.7-32} $(DESC_SecPyBindings3.7-32)
!insertmacro MUI_DESCRIPTION_TEXT ${SecPyBindings3.8-32} $(DESC_SecPyBindings3.8-32)
!insertmacro MUI_DESCRIPTION_TEXT ${SecPyBindings3.9-32} $(DESC_SecPyBindings3.9-32)
!else
!insertmacro MUI_DESCRIPTION_TEXT ${SecPyBindings3.5} $(DESC_SecPyBindings3.5)
!insertmacro MUI_DESCRIPTION_TEXT ${SecPyBindings3.6} $(DESC_SecPyBindings3.6)
!insertmacro MUI_DESCRIPTION_TEXT ${SecPyBindings3.7} $(DESC_SecPyBindings3.7)
!insertmacro MUI_DESCRIPTION_TEXT ${SecPyBindings3.8} $(DESC_SecPyBindings3.8)
!insertmacro MUI_DESCRIPTION_TEXT ${SecPyBindings3.9} $(DESC_SecPyBindings3.9)
!endif
!ifdef INCLUDE_PYVER
!insertmacro MUI_DESCRIPTION_TEXT ${SecPython} $(DESC_SecPython)
!endif
!insertmacro MUI_DESCRIPTION_TEXT ${SecHeadersLibs} $(DESC_SecHeadersLibs)

View File

@ -13,10 +13,6 @@ from distutils.sysconfig import get_python_lib
from optparse import OptionParser
from makepandacore import *
def python_sitepackages_path():
from distutils.sysconfig import get_python_lib
return get_python_lib(1)
PYTHON_SITEPACKAGES=python_sitepackages_path()
MIME_INFO = (
("egg", "model/x-egg", "EGG model file", "pview"),
@ -153,18 +149,11 @@ def GetLibDir():
return "lib"
def InstallPanda(destdir="", prefix="/usr", outputdir="built", libdir=GetLibDir()):
def InstallPanda(destdir="", prefix="/usr", outputdir="built", libdir=GetLibDir(), python_versions=[]):
if (not prefix.startswith("/")):
prefix = "/" + prefix
libdir = prefix + "/" + libdir
# Determine the location of the Python executable and site-packages dir.
PPATH = get_python_lib(1)
if os.path.islink(sys.executable):
PEXEC = os.path.join(os.path.dirname(sys.executable), os.readlink(sys.executable))
else:
PEXEC = sys.executable
# Create the directory structure that we will be putting our files in.
oscmd("mkdir -m 0755 -p "+destdir+prefix+"/bin")
oscmd("mkdir -m 0755 -p "+destdir+prefix+"/include")
@ -174,8 +163,10 @@ def InstallPanda(destdir="", prefix="/usr", outputdir="built", libdir=GetLibDir(
oscmd("mkdir -m 0755 -p "+destdir+prefix+"/share/application-registry")
oscmd("mkdir -m 0755 -p "+destdir+prefix+"/share/applications")
oscmd("mkdir -m 0755 -p "+destdir+libdir+"/panda3d")
oscmd("mkdir -m 0755 -p "+destdir+PPATH)
oscmd("mkdir -m 0755 -p "+destdir+PPATH+"/panda3d")
for python_version in python_versions:
oscmd("mkdir -m 0755 -p "+destdir+python_version["purelib"])
oscmd("mkdir -m 0755 -p "+destdir+python_version["platlib"]+"/panda3d")
if (sys.platform.startswith("freebsd")):
oscmd("mkdir -m 0755 -p "+destdir+prefix+"/etc")
@ -201,10 +192,12 @@ def InstallPanda(destdir="", prefix="/usr", outputdir="built", libdir=GetLibDir(
if os.path.isdir(outputdir+"/Pmw"): oscmd("cp -R "+outputdir+"/Pmw "+destdir+prefix+"/share/panda3d/")
if os.path.isdir(outputdir+"/plugins"): oscmd("cp -R "+outputdir+"/plugins "+destdir+prefix+"/share/panda3d/")
suffix = GetExtensionSuffix()
for base in os.listdir(outputdir + "/panda3d"):
if base.endswith(".py") or (base.endswith(suffix) and '.' not in base[:-len(suffix)]):
oscmd("cp "+outputdir+"/panda3d/"+base+" "+destdir+PPATH+"/panda3d/"+base)
for python_version in python_versions:
for base in os.listdir(outputdir + "/panda3d"):
suffix = python_version["ext_suffix"]
platlib = python_version["platlib"]
if base.endswith(".py") or (base.endswith(suffix) and '.' not in base[:-len(suffix)]):
oscmd("cp "+outputdir+"/panda3d/"+base+" "+destdir+platlib+"/panda3d/"+base)
WriteMimeFile(destdir+prefix+"/share/mime-info/panda3d.mime", MIME_INFO)
WriteKeysFile(destdir+prefix+"/share/mime-info/panda3d.keys", MIME_INFO)
@ -214,19 +207,28 @@ def InstallPanda(destdir="", prefix="/usr", outputdir="built", libdir=GetLibDir(
oscmd("cp makepanda/pview.desktop "+destdir+prefix+"/share/applications/pview.desktop")
oscmd("cp doc/ReleaseNotes "+destdir+prefix+"/share/panda3d/ReleaseNotes")
oscmd("echo '"+prefix+"/share/panda3d' > "+destdir+PPATH+"/panda3d.pth")
oscmd("echo '"+libdir+"/panda3d'>> "+destdir+PPATH+"/panda3d.pth")
for python_version in python_versions:
pth_file = python_version["purelib"] + "/panda3d.pth"
oscmd("echo '"+prefix+"/share/panda3d' > "+destdir+pth_file)
if os.path.isdir(outputdir+"/panda3d.dist-info"):
oscmd("cp -R "+outputdir+"/panda3d.dist-info "+destdir+python_version["platlib"])
if (sys.platform.startswith("freebsd")):
oscmd("echo '"+libdir+"/panda3d'> "+destdir+"/usr/local/libdata/ldconfig/panda3d")
else:
oscmd("echo '"+libdir+"/panda3d'> "+destdir+"/etc/ld.so.conf.d/panda3d.conf")
oscmd("cp "+outputdir+"/bin/* "+destdir+prefix+"/bin/")
for base in os.listdir(outputdir+"/lib"):
if (not base.endswith(".a")) or base == "libp3pystub.a":
# We really need to specify -R in order not to follow symlinks on non-GNU
oscmd("cp -R -P "+outputdir+"/lib/"+base+" "+destdir+libdir+"/panda3d/"+base)
for base in os.listdir(outputdir+"/bin"):
if not base.startswith("deploy-stub"):
oscmd("cp -R -P "+outputdir+"/bin/"+base+" "+destdir+prefix+"/bin/"+base)
DeleteVCS(destdir+prefix+"/share/panda3d")
DeleteBuildFiles(destdir+prefix+"/share/panda3d")
DeleteEmptyDirs(destdir+prefix+"/share/panda3d")
@ -300,6 +302,8 @@ if (__name__ == "__main__"):
if (destdir != "" and not os.path.isdir(destdir)):
exit("Directory '%s' does not exist!" % destdir)
SetOutputDir(options.outputdir)
if options.verbose:
SetVerbose(True)
@ -308,6 +312,8 @@ if (__name__ == "__main__"):
InstallRuntime(destdir = destdir, prefix = options.prefix, outputdir = options.outputdir)
else:
print("Installing Panda3D SDK into " + destdir + options.prefix)
InstallPanda(destdir = destdir, prefix = options.prefix, outputdir = options.outputdir)
InstallPanda(destdir=destdir,
prefix=options.prefix,
outputdir=options.outputdir,
python_versions=ReadPythonVersionInfoFile())
print("Installation finished!")

1066
makepanda/makepackage.py Executable file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1043,7 +1043,7 @@
<File RelativePath="..\panda\src\collide\collisionLine.I"></File>
<File RelativePath="..\panda\src\collide\collisionHandlerFluidPusher.h"></File>
<File RelativePath="..\panda\src\collide\config_collide.h"></File>
<File RelativePath="..\panda\src\collide\collisionTube.h"></File>
<File RelativePath="..\panda\src\collide\collisionCapsule.h"></File>
<File RelativePath="..\panda\src\collide\collisionSegment.cxx"></File>
<File RelativePath="..\panda\src\collide\collisionBox.h"></File>
<File RelativePath="..\panda\src\collide\collide_composite1.cxx"></File>
@ -1054,7 +1054,7 @@
<File RelativePath="..\panda\src\collide\collisionNode.h"></File>
<File RelativePath="..\panda\src\collide\collisionGeom.I"></File>
<File RelativePath="..\panda\src\collide\collisionSegment.I"></File>
<File RelativePath="..\panda\src\collide\collisionTube.cxx"></File>
<File RelativePath="..\panda\src\collide\collisionCapsule.cxx"></File>
<File RelativePath="..\panda\src\collide\collisionHandlerQueue.h"></File>
<File RelativePath="..\panda\src\collide\collisionParabola.I"></File>
<File RelativePath="..\panda\src\collide\collisionPlane.cxx"></File>
@ -1089,7 +1089,7 @@
<File RelativePath="..\panda\src\collide\collisionInvSphere.cxx"></File>
<File RelativePath="..\panda\src\collide\collisionLine.cxx"></File>
<File RelativePath="..\panda\src\collide\collisionEntry.I"></File>
<File RelativePath="..\panda\src\collide\collisionTube.I"></File>
<File RelativePath="..\panda\src\collide\collisionCapsule.I"></File>
<File RelativePath="..\panda\src\collide\collisionSolid.h"></File>
<File RelativePath="..\panda\src\collide\collisionPlane.I"></File>
<File RelativePath="..\panda\src\collide\collisionHandlerGravity.cxx"></File>
@ -3578,25 +3578,6 @@
<File RelativePath="..\panda\src\net\datagram_ui.cxx"></File>
<File RelativePath="..\panda\src\net\netAddress.cxx"></File>
</Filter>
<Filter Name="awesomium">
<File RelativePath="..\panda\src\awesomium\WebBrowserTexture.cxx"></File>
<File RelativePath="..\panda\src\awesomium\awesomium_includes.h"></File>
<File RelativePath="..\panda\src\awesomium\pandaawesomium_composite1.cxx"></File>
<File RelativePath="..\panda\src\awesomium\awWebViewListener.cxx"></File>
<File RelativePath="..\panda\src\awesomium\awWebViewListener.h"></File>
<File RelativePath="..\panda\src\awesomium\awWebCore.h"></File>
<File RelativePath="..\panda\src\awesomium\WebBrowserTexture.h"></File>
<File RelativePath="..\panda\src\awesomium\awWebCore.cxx"></File>
<File RelativePath="..\panda\src\awesomium\AwMouseAndKeyboard.h"></File>
<File RelativePath="..\panda\src\awesomium\awWebViewListener.I"></File>
<File RelativePath="..\panda\src\awesomium\awWebView.h"></File>
<File RelativePath="..\panda\src\awesomium\config_awesomium.h"></File>
<File RelativePath="..\panda\src\awesomium\awWebCore.I"></File>
<File RelativePath="..\panda\src\awesomium\awWebView.I"></File>
<File RelativePath="..\panda\src\awesomium\awWebView.cxx"></File>
<File RelativePath="..\panda\src\awesomium\AwMouseAndKeyboard.cxx"></File>
<File RelativePath="..\panda\src\awesomium\config_awesomium.cxx"></File>
</Filter>
<Filter Name="movies">
<File RelativePath="..\panda\src\movies\ffmpegVideoCursor.h"></File>
<File RelativePath="..\panda\src\movies\movies_composite.cxx"></File>

View File

@ -3362,8 +3362,13 @@ def CalcLocation(fn, ipath):
def FindLocation(fn, ipath, pyabi=None):
if (GetLinkAllStatic() and fn.endswith(".dll")):
fn = fn[:-4] + ".lib"
if GetLinkAllStatic():
if fn.endswith(".dll"):
fn = fn[:-4] + ".lib"
elif fn.endswith(".pyd"):
fn = "libpy.panda3d." \
+ os.path.splitext(fn[:-4] + GetExtensionSuffix())[0] + ".lib"
loc = CalcLocation(fn, ipath)
base, ext = os.path.splitext(fn)
@ -3383,6 +3388,71 @@ def FindLocation(fn, ipath, pyabi=None):
ORIG_EXT[loc] = ext
return loc
########################################################################
##
## These files maintain a python_versions.json file in the built/tmp
## directory that can be used by the other scripts in this directory.
##
########################################################################
def GetCurrentPythonVersionInfo():
if PkgSkip("PYTHON"):
return
from distutils.sysconfig import get_python_lib
return {
"version": SDK["PYTHONVERSION"][6:9],
"soabi": GetPythonABI(),
"ext_suffix": GetExtensionSuffix(),
"executable": sys.executable,
"purelib": get_python_lib(False),
"platlib": get_python_lib(True),
}
def UpdatePythonVersionInfoFile(new_info):
import json
json_file = os.path.join(GetOutputDir(), "tmp", "python_versions.json")
json_data = []
if os.path.isfile(json_file) and not PkgSkip("PYTHON"):
try:
json_data = json.load(open(json_file, 'r'))
except:
json_data = []
# Prune the list by removing the entries that conflict with our build,
# plus the entries that no longer exist
for version_info in json_data[:]:
core_pyd = os.path.join(GetOutputDir(), "panda3d", "core" + version_info["ext_suffix"])
if version_info["ext_suffix"] == new_info["ext_suffix"] or \
version_info["soabi"] == new_info["soabi"] or \
not os.path.isfile(core_pyd):
json_data.remove(version_info)
if not PkgSkip("PYTHON"):
json_data.append(new_info)
if VERBOSE:
print("Writing %s" % (json_file))
json.dump(json_data, open(json_file, 'w'), indent=4)
def ReadPythonVersionInfoFile():
import json
json_file = os.path.join(GetOutputDir(), "tmp", "python_versions.json")
if os.path.isfile(json_file):
try:
return json.load(open(json_file, 'r'))
except:
pass
return []
########################################################################
##
## TargetAdd
@ -3513,11 +3583,15 @@ def TargetAdd(target, dummy=0, opts=[], input=[], dep=[], ipath=None, winrc=None
if winrc and GetTarget() == 'windows':
TargetAdd(target, input=WriteResourceFile(target.split("/")[-1].split(".")[0], **winrc))
if target.endswith(".in"):
ext = os.path.splitext(target)[1]
if ext == ".in":
if not CrossCompiling():
t.deps[FindLocation("interrogate.exe", [])] = 1
t.deps[FindLocation("dtool_have_python.dat", [])] = 1
if ext in (".obj", ".tlb", ".res", ".plugin", ".app") or ext in SUFFIX_DLL or ext in SUFFIX_LIB:
t.deps[FindLocation("platform.dat", [])] = 1
if target.endswith(".obj") and any(x.endswith(".in") for x in input):
if not CrossCompiling():
t.deps[FindLocation("interrogate_module.exe", [])] = 1

View File

@ -24,14 +24,6 @@ from makepandacore import ColorText, LocateBinary, ParsePandaVersion, GetExtensi
from base64 import urlsafe_b64encode
default_platform = get_platform()
if default_platform.startswith("linux-"):
# Is this manylinux1?
if (os.path.isfile("/lib/libc-2.5.so") or os.path.isfile("/lib64/libc-2.5.so")) and os.path.isdir("/opt/python"):
default_platform = default_platform.replace("linux", "manylinux1")
def get_abi_tag():
if sys.version_info >= (3, 0):
soabi = get_config_var('SOABI')
@ -68,26 +60,32 @@ def is_elf_file(path):
open(path, 'rb').read(4) == b'\x7FELF'
def is_mach_o_file(path):
def is_macho_or_fat_file(path):
base = os.path.basename(path)
return os.path.isfile(path) and '.' not in base and \
open(path, 'rb').read(4) in (b'\xCA\xFE\xBA\xBE', b'\xBE\xBA\xFE\bCA',
b'\xFE\xED\xFA\xCE', b'\xCE\xFA\xED\xFE',
b'\xFE\xED\xFA\xCF', b'\xCF\xFA\xED\xFE')
open(path, 'rb').read(4) in (b'\xFE\xED\xFA\xCE', b'\xCE\xFA\xED\xFE',
b'\xFE\xED\xFA\xCF', b'\xCF\xFA\xED\xFE',
b'\xCA\xFE\xBA\xBE', b'\xBE\xBA\xFE\xCA',
b'\xCA\xFE\xBA\xBF', b'\xBF\xBA\xFE\xCA')
def is_fat_file(path):
return os.path.isfile(path) and \
open(path, 'rb').read(4) in (b'\xCA\xFE\xBA\xBE', b'\xBE\xBA\xFE\bCA')
open(path, 'rb').read(4) in (b'\xCA\xFE\xBA\xBE', b'\xBE\xBA\xFE\xCA',
b'\xCA\xFE\xBA\xBF', b'\xBF\xBA\xFE\xCA')
def get_python_ext_module_dir():
import _ctypes
return os.path.dirname(_ctypes.__file__)
if sys.platform in ('win32', 'cygwin'):
is_executable = is_exe_file
elif sys.platform == 'darwin':
is_executable = is_mach_o_file
is_executable = is_macho_or_fat_file
else:
is_executable = is_elf_file
# Other global parameters
PY_VERSION = "cp{0}{1}".format(*sys.version_info)
ABI_TAG = get_abi_tag()
@ -96,6 +94,24 @@ EXCLUDE_EXT = [".pyc", ".pyo", ".N", ".prebuilt", ".xcf", ".plist", ".vcproj", "
# Plug-ins to install.
PLUGIN_LIBS = ["pandagl", "pandagles", "pandagles2", "pandadx9", "p3tinydisplay", "p3ptloader", "p3assimp", "p3ffmpeg", "p3openal_audio", "p3fmod_audio"]
# Libraries included in manylinux ABI that should be ignored. See PEP 513/571.
MANYLINUX_LIBS = [
"libgcc_s.so.1", "libstdc++.so.6", "libm.so.6", "libdl.so.2", "librt.so.1",
"libcrypt.so.1", "libc.so.6", "libnsl.so.1", "libutil.so.1",
"libpthread.so.0", "libresolv.so.2", "libX11.so.6", "libXext.so.6",
"libXrender.so.1", "libICE.so.6", "libSM.so.6", "libGL.so.1",
"libgobject-2.0.so.0", "libgthread-2.0.so.0", "libglib-2.0.so.0",
# These are not mentioned in manylinux1 spec but should nonetheless always
# be excluded.
"linux-vdso.so.1", "linux-gate.so.1", "ld-linux.so.2",
]
# Binaries to never scan for dependencies on non-Windows systems.
IGNORE_UNIX_DEPS_OF = [
"panda3d_tools/pstats",
]
WHEEL_DATA = """Wheel-Version: 1.0
Generator: makepanda
Root-Is-Purelib: false
@ -265,6 +281,7 @@ class WheelFile(object):
# Used to locate dependency libraries.
self.lib_path = []
self.dep_paths = {}
self.ignore_deps = set()
def consider_add_dependency(self, target_path, dep, search_path=None):
"""Considers adding a dependency library.
@ -277,29 +294,38 @@ class WheelFile(object):
self.dep_paths[dep] = None
if dep.lower().startswith("python") or os.path.basename(dep).startswith("libpython"):
# Don't include the Python library.
if dep in self.ignore_deps or dep.lower().startswith("python") or os.path.basename(dep).startswith("libpython"):
# Don't include the Python library, or any other explicit ignore.
if GetVerbose():
print("Ignoring {0} (explicitly ignored)".format(dep))
return
if sys.platform == "darwin" and dep.endswith(".so"):
# Temporary hack for 1.9, which had link deps on modules.
return
source_path = None
if sys.platform == "darwin" and dep.startswith("/System/"):
return
if search_path is None:
search_path = self.lib_path
if dep.startswith('/'):
source_path = dep
else:
source_path = None
for lib_dir in search_path:
# Ignore static stuff.
path = os.path.join(lib_dir, dep)
if os.path.isfile(path):
source_path = os.path.normpath(path)
break
if search_path is None:
search_path = self.lib_path
for lib_dir in search_path:
# Ignore static stuff.
path = os.path.join(lib_dir, dep)
if os.path.isfile(path):
source_path = os.path.normpath(path)
break
if not source_path:
# Couldn't find library in the panda3d lib dir.
#print("Ignoring %s" % (dep))
if GetVerbose():
print("Ignoring {0} (not in search path)".format(dep))
return
self.dep_paths[dep] = target_path
@ -309,20 +335,19 @@ class WheelFile(object):
def write_file(self, target_path, source_path):
"""Adds the given file to the .whl file."""
orig_source_path = source_path
# If this is a .so file, we should set the rpath appropriately.
temp = None
ext = os.path.splitext(source_path)[1]
basename, ext = os.path.splitext(source_path)
if ext in ('.so', '.dylib') or '.so.' in os.path.basename(source_path) or \
(not ext and is_executable(source_path)):
# Scan and add Unix dependencies.
deps = scan_dependencies(source_path)
for dep in deps:
# Only include dependencies with relative path. Otherwise we
# end up overwriting system files like /lib/ld-linux.so.2!
# Yes, it happened to me.
if '/' not in dep:
target_dep = os.path.dirname(target_path) + '/' + dep
self.consider_add_dependency(target_dep, dep)
# Scan Unix dependencies.
if target_path not in IGNORE_UNIX_DEPS_OF:
deps = scan_dependencies(source_path)
else:
deps = []
suffix = ''
if '.so' in os.path.basename(source_path):
@ -333,7 +358,10 @@ class WheelFile(object):
temp = tempfile.NamedTemporaryFile(suffix=suffix, prefix='whl', delete=False)
# On macOS, if no fat wheel was requested, extract the right architecture.
if sys.platform == "darwin" and is_fat_file(source_path) and not self.platform.endswith("_intel"):
if sys.platform == "darwin" and is_fat_file(source_path) \
and not self.platform.endswith("_intel") \
and "_fat" not in self.platform:
if self.platform.endswith("_x86_64"):
arch = 'x86_64'
else:
@ -343,26 +371,55 @@ class WheelFile(object):
# Otherwise, just copy it over.
temp.write(open(source_path, 'rb').read())
os.fchmod(temp.fileno(), os.fstat(temp.fileno()).st_mode | 0o111)
temp.close()
os.chmod(temp.name, os.stat(temp.name).st_mode | 0o711)
# Fix things like @loader_path/../lib references
# Now add dependencies. On macOS, fix @loader_path references.
if sys.platform == "darwin":
if source_path.endswith('deploy-stubw'):
deps_path = '@executable_path/../Frameworks'
else:
deps_path = '@loader_path'
loader_path = [os.path.dirname(source_path)]
for dep in deps:
if '@loader_path' not in dep:
if dep.endswith('/Python'):
# If this references the Python framework, change it
# to reference libpython instead.
new_dep = deps_path + '/libpython{0}.{1}.dylib'.format(*sys.version_info)
elif '@loader_path' in dep:
dep_path = dep.replace('@loader_path', '.')
target_dep = os.path.dirname(target_path) + '/' + os.path.basename(dep)
target_dep = self.consider_add_dependency(target_dep, dep_path, loader_path)
if not target_dep:
# It won't be included, so no use adjusting the path.
continue
new_dep = os.path.join(deps_path, os.path.relpath(target_dep, os.path.dirname(target_path)))
elif dep.startswith('/Library/Frameworks/Python.framework/'):
# Add this dependency if it's in the Python directory.
target_dep = os.path.dirname(target_path) + '/' + os.path.basename(dep)
target_dep = self.consider_add_dependency(target_dep, dep, loader_path)
if not target_dep:
# It won't be included, so no use adjusting the path.
continue
new_dep = os.path.join(deps_path, os.path.relpath(target_dep, os.path.dirname(target_path)))
else:
if '/' in dep:
if GetVerbose():
print("Ignoring dependency %s" % (dep))
continue
dep_path = dep.replace('@loader_path', '.')
target_dep = os.path.dirname(target_path) + '/' + os.path.basename(dep)
target_dep = self.consider_add_dependency(target_dep, dep_path, loader_path)
if not target_dep:
# It won't be included, so no use adjusting the path.
continue
new_dep = os.path.join('@loader_path', os.path.relpath(target_dep, os.path.dirname(target_path)))
subprocess.call(["install_name_tool", "-change", dep, new_dep, temp.name])
else:
# On other unixes, we just add dependencies normally.
for dep in deps:
# Only include dependencies with relative path, for now.
if '/' not in dep:
target_dep = os.path.dirname(target_path) + '/' + dep
self.consider_add_dependency(target_dep, dep)
subprocess.call(["strip", "-s", temp.name])
subprocess.call(["patchelf", "--set-rpath", "$ORIGIN", temp.name])
@ -392,7 +449,7 @@ class WheelFile(object):
self.records.append("{0},sha256={1},{2}\n".format(target_path, digest, size))
if GetVerbose():
print("Adding %s from %s" % (target_path, source_path))
print("Adding {0} from {1}".format(target_path, orig_source_path))
self.zip_file.write(source_path, target_path)
#if temp:
@ -433,11 +490,24 @@ class WheelFile(object):
self.zip_file.close()
def makewheel(version, output_dir, platform=default_platform):
def makewheel(version, output_dir, platform=None):
if sys.platform not in ("win32", "darwin") and not sys.platform.startswith("cygwin"):
if not LocateBinary("patchelf"):
raise Exception("patchelf is required when building a Linux wheel.")
if platform is None:
# Determine the platform from the build.
platform_dat = os.path.join(output_dir, 'tmp', 'platform.dat')
if os.path.isfile(platform_dat):
platform = open(platform_dat, 'r').read().strip()
else:
print("Could not find platform.dat in build directory")
platform = get_platform()
if platform.startswith("linux-"):
# Is this manylinux1?
if os.path.isfile("/lib/libc-2.5.so") and os.path.isdir("/opt/python"):
platform = platform.replace("linux", "manylinux1")
platform = platform.replace('-', '_').replace('.', '_')
# Global filepaths
@ -483,6 +553,21 @@ def makewheel(version, output_dir, platform=default_platform):
whl = WheelFile('panda3d', version, platform)
whl.lib_path = [libs_dir]
if sys.platform == "win32":
whl.lib_path.append(join(output_dir, "python", "DLLs"))
if platform.startswith("manylinux"):
# On manylinux1, we pick up all libraries except for the ones specified
# by the manylinux1 ABI.
whl.lib_path.append("/usr/local/lib")
if platform.endswith("_x86_64"):
whl.lib_path += ["/lib64", "/usr/lib64"]
else:
whl.lib_path += ["/lib", "/usr/lib"]
whl.ignore_deps.update(MANYLINUX_LIBS)
# Add the trees with Python modules.
whl.write_directory('direct', direct_dir)
@ -493,6 +578,7 @@ def makewheel(version, output_dir, platform=default_platform):
__version__ = '{0}'
""".format(version))
# Copy the extension modules from the panda3d directory.
ext_suffix = GetExtensionSuffix()
for file in os.listdir(panda3d_dir):
@ -509,6 +595,23 @@ __version__ = '{0}'
whl.write_file(target_path, source_path)
# And copy the extension modules from the Python installation into the
# deploy_libs directory, for use by deploy-ng.
ext_suffix = '.pyd' if sys.platform in ('win32', 'cygwin') else '.so'
ext_mod_dir = get_python_ext_module_dir()
for file in os.listdir(ext_mod_dir):
if file.endswith(ext_suffix):
source_path = os.path.join(ext_mod_dir, file)
if file.endswith('.pyd') and platform.startswith('cygwin'):
# Rename it to .dll for cygwin Python to be able to load it.
target_path = 'deploy_libs/' + os.path.splitext(file)[0] + '.dll'
else:
target_path = 'deploy_libs/' + file
whl.write_file(target_path, source_path)
# Add plug-ins.
for lib in PLUGIN_LIBS:
plugin_name = 'lib' + lib
@ -540,7 +643,7 @@ __version__ = '{0}'
# Add a panda3d-tools directory containing the executables.
entry_points = '[console_scripts]\n'
entry_points += 'eggcacher = direct.directscripts.eggcacher:main\n'
entry_points += 'pfreeze = direct.showutil.pfreeze:main\n'
entry_points += 'pfreeze = direct.dist.pfreeze:main\n'
tools_init = ''
for file in os.listdir(bin_dir):
basename = os.path.splitext(file)[0]
@ -557,6 +660,9 @@ __version__ = '{0}'
funcname = basename.replace('-', '_')
entry_points += '{0} = panda3d_tools:{1}\n'.format(basename, funcname)
tools_init += '{0} = lambda: _exec_tool({1!r})\n'.format(funcname, file)
entry_points += '[distutils.commands]\n'
entry_points += 'build_apps = direct.dist.commands:build_apps\n'
entry_points += 'bdist_apps = direct.dist.commands:bdist_apps\n'
whl.write_file_data('panda3d_tools/__init__.py', PANDA3D_TOOLS_INIT.format(tools_init))
@ -570,6 +676,18 @@ __version__ = '{0}'
whl.write_file(info_dir + '/README.md', readme_src)
whl.write_file_data(info_dir + '/top_level.txt', 'direct\npanda3d\npandac\npanda3d_tools\n')
# Add libpython for deployment
if sys.platform in ('win32', 'cygwin'):
pylib_name = 'python{0}{1}.dll'.format(*sys.version_info)
pylib_path = os.path.join(get_config_var('BINDIR'), pylib_name)
elif sys.platform == 'darwin':
pylib_name = 'libpython{0}.{1}.dylib'.format(*sys.version_info)
pylib_path = os.path.join(get_config_var('LIBDIR'), pylib_name)
else:
pylib_name = get_config_var('LDLIBRARY')
pylib_path = os.path.join(get_config_var('LIBDIR'), pylib_name)
whl.write_file('deploy_libs/' + pylib_name, pylib_path)
whl.close()
@ -580,7 +698,7 @@ if __name__ == "__main__":
parser.add_option('', '--version', dest = 'version', help = 'Panda3D version number (default: %s)' % (version), default = version)
parser.add_option('', '--outputdir', dest = 'outputdir', help = 'Makepanda\'s output directory (default: built)', default = 'built')
parser.add_option('', '--verbose', dest = 'verbose', help = 'Enable verbose output', action = 'store_true', default = False)
parser.add_option('', '--platform', dest = 'platform', help = 'Override platform tag (default: %s)' % (default_platform), default = get_platform())
parser.add_option('', '--platform', dest = 'platform', help = 'Override platform tag', default = None)
(options, args) = parser.parse_args()
SetVerbose(options.verbose)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 151 KiB

After

Width:  |  Height:  |  Size: 151 KiB

View File

@ -62,6 +62,7 @@ import direct.directutil.LargeBlobSenderConsts
import direct.directutil.Mopath
import direct.directutil.Verify
import direct.directutil.WeightedChoice
import direct.dist.FreezeTool
import direct.distributed.AsyncRequest
import direct.distributed.CRCache
import direct.distributed.CRDataCache
@ -234,7 +235,6 @@ import direct.showbase.VFSImporter
import direct.showbase.WxGlobal
import direct.showutil.BuildGeometry
import direct.showutil.Effects
import direct.showutil.FreezeTool
import direct.showutil.Rope
import direct.showutil.TexMemWatcher
import direct.showutil.TexViewer

Binary file not shown.

Before

Width:  |  Height:  |  Size: 151 KiB

After

Width:  |  Height:  |  Size: 151 KiB

View File

@ -55,9 +55,9 @@ AndroidGraphicsWindow(GraphicsEngine *engine, GraphicsPipe *pipe,
_app = panda_android_app;
GraphicsWindowInputDevice device =
GraphicsWindowInputDevice::pointer_and_keyboard(this, "keyboard_mouse");
PT(GraphicsWindowInputDevice) device = GraphicsWindowInputDevice::pointer_and_keyboard(this, "keyboard_mouse");
add_input_device(device);
_input = device;
}
/**
@ -486,22 +486,22 @@ handle_key_event(const AInputEvent *event) {
/*
int32_t meta = AKeyEvent_getMetaState(event);
if (meta | AMETA_ALT_ON) {
_input_devices[0].button_down(KeyboardButton.alt());
_input->button_down(KeyboardButton.alt());
}
if (meta | AMETA_ALT_LEFT_ON) {
_input_devices[0].button_down(KeyboardButton.lalt());
_input->button_down(KeyboardButton.lalt());
}
if (meta | AMETA_ALT_RIGHT_ON) {
_input_devices[0].button_down(KeyboardButton.ralt());
_input->button_down(KeyboardButton.ralt());
}
if (meta | AMETA_SHIFT_ON) {
_input_devices[0].button_down(KeyboardButton.shift());
_input->button_down(KeyboardButton.shift());
}
if (meta | AMETA_SHIFT_LEFT_ON) {
_input_devices[0].button_down(KeyboardButton.lshift());
_input->button_down(KeyboardButton.lshift());
}
if (meta | AMETA_SHIFT_RIGHT_ON) {
_input_devices[0].button_down(KeyboardButton.rshift());
_input->button_down(KeyboardButton.rshift());
}*/
int32_t keycode = AKeyEvent_getKeyCode(event);
@ -517,12 +517,12 @@ handle_key_event(const AInputEvent *event) {
int32_t action = AKeyEvent_getAction(event);
if (action == AKEY_EVENT_ACTION_DOWN) {
if (AKeyEvent_getRepeatCount(event) > 0) {
_input_devices[0].button_resume_down(button);
_input->button_resume_down(button);
} else {
_input_devices[0].button_down(button);
_input->button_down(button);
}
} else if (action == AKEY_EVENT_ACTION_UP) {
_input_devices[0].button_up(button);
_input->button_up(button);
}
// TODO AKEY_EVENT_ACTION_MULTIPLE
@ -549,16 +549,16 @@ handle_motion_event(const AInputEvent *event) {
if (changed != 0) {
if (changed & AMOTION_EVENT_BUTTON_PRIMARY) {
if (button_state & AMOTION_EVENT_BUTTON_PRIMARY) {
_input_devices[0].button_down(MouseButton::one());
_input->button_down(MouseButton::one());
} else {
_input_devices[0].button_up(MouseButton::one());
_input->button_up(MouseButton::one());
}
}
if (changed & AMOTION_EVENT_BUTTON_SECONDARY) {
if (button_state & AMOTION_EVENT_BUTTON_SECONDARY) {
_input_devices[0].button_down(MouseButton::three());
_input->button_down(MouseButton::three());
} else {
_input_devices[0].button_up(MouseButton::three());
_input->button_up(MouseButton::three());
}
}
_mouse_button_state = button_state;
@ -568,7 +568,7 @@ handle_motion_event(const AInputEvent *event) {
float x = AMotionEvent_getX(event, 0) - _app->contentRect.left;
float y = AMotionEvent_getY(event, 0) - _app->contentRect.top;
_input_devices[0].set_pointer_in_window(x, y);
_input->set_pointer_in_window(x, y);
return 1;
}

View File

@ -73,7 +73,7 @@ private:
int32_t _mouse_button_state;
const ARect *rect;
GraphicsWindowInputDevice *_input;
public:
static TypeHandle get_class_type() {

View File

@ -44,7 +44,7 @@ OpenALAudioSound(OpenALAudioManager* manager,
_loops_completed(0),
_source(0),
_manager(manager),
_volume(manager->get_volume()),
_volume(1.0f),
_balance(0),
_play_rate(1.0),
_positional(positional),

View File

@ -1,47 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file AwMouseAndKeyboard.cxx
* @author Bei Yang
* @date 2010-03
*/
#include "config_awesomium.h"
#include "AwMouseAndKeyboard.h"
#include "dataNodeTransmit.h"
TypeHandle AwMouseAndKeyboard::_type_handle;
AwMouseAndKeyboard::AwMouseAndKeyboard(const std::string &name):
DataNode(name)
{
_button_events_input = define_input("button_events", ButtonEventList::get_class_type());
_button_events_output = define_output("button_events", ButtonEventList::get_class_type());
}
void AwMouseAndKeyboard::do_transmit_data(DataGraphTraverser *trav, const DataNodeTransmit &input, DataNodeTransmit &output){
if (input.has_data(_button_events_input)) {
const ButtonEventList *button_events;
DCAST_INTO_V(button_events, input.get_data(_button_events_input).get_ptr());
int num_events = button_events->get_num_events();
for (int i = 0; i < num_events; i++) {
const ButtonEvent &be = button_events->get_event(i);
std::string event_name = be._button.get_name();
printf("Button Event! : %s with code %i and index %i ", event_name.c_str(), be._keycode, be._button.get_index());
if(be._type == ButtonEvent::T_down) printf("down");
if(be._type == ButtonEvent::T_repeat) printf("repeat");
if(be._type == ButtonEvent::T_up) printf("up");
if(be._type == ButtonEvent::T_resume_down) printf("T_resume_down");
printf("\n");
}
}
}

View File

@ -1,8 +0,0 @@
See http://www.sirikata.com/wiki/index.php?title=Compiling_Awesomium
But the Chromium revision 22725.
The awesomium git repository used is at: http://github.com/pathorn/awesomium/network
The version of awesomium is from the master August 7 checkin, tree fc3239b4f49031285682cb5d78256d56e9001b66
Any method that had a wstring in the parameter, a second method was created which just accepts all std::string. This fixes the VC7 - VC9 linker error.

View File

@ -1,194 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file WebBrowserTexture.cxx
* @author bei yang
* @date 2010-03
*/
#include "config_awesomium.h"
#include "WebBrowserTexture.h"
TypeHandle WebBrowserTexture::_type_handle;
/**
* Copy constructor for web browser texture. The behavior of copying a
* webtexture is that will be the same as a standard texture copy. However,
* the content will remain the system until set_web_view is called.
*/
WebBrowserTexture::WebBrowserTexture(const WebBrowserTexture &copy):
Texture(copy)
{
// this kind of assumes that the previous texture was initialized properly
_aw_web_view = copy._aw_web_view;
_update_active = copy._update_active;
_flip_texture_active = copy._flip_texture_active;
}
/**
* This initializes a web browser texture with the given AwWebView class.
*/
WebBrowserTexture::WebBrowserTexture(const std::string &name, AwWebView* aw_web_view):
Texture(name),
_update_active(true),
_flip_texture_active(false)
{
set_web_view(aw_web_view);
set_minfilter(FT_linear);
set_magfilter(FT_linear);
}
/**
* Standard destructor... doesn't do anything. All destructing happens in
* parent texture class.
*/
WebBrowserTexture::~WebBrowserTexture()
{
// do nothing
}
/**
* Standard destructor... doesn't do anything. All destructing happens in
* parent texture class.
*/
bool WebBrowserTexture::get_keep_ram_image() const {
return true;
}
/**
* A WebBrowserTexture must always keep its ram image. This is essentially a
* sub.
*/
void WebBrowserTexture::do_reload_ram_image() {
// A MovieTexture should never dump its RAM image. Therefore, this is not
// needed.
}
/**
* Should be overridden by derived classes to return true if cull_callback()
* has been defined. Otherwise, returns false to indicate cull_callback()
* does not need to be called for this node during the cull traversal.
*
* This one returns true because it uses the cull traverser method to do the
* texture udpate.
*/
bool WebBrowserTexture::has_cull_callback() const {
return true;
}
/**
* Sets the internal AwWebView of this texture. After calling this, the
* texture will automatically set it's width and height to match the AwWebView
* at the next time it is culled and rendered.
*/
void WebBrowserTexture::set_web_view(AwWebView* aw_web_view){
_aw_web_view = aw_web_view;
}
/**
* Gets the current internal AwWebView of this texture.
*/
AwWebView* WebBrowserTexture::get_web_view() const{
return _aw_web_view;
}
/**
* Gives the ability to toggle updating this texture or not. This can be
* disabled to improve performance so that only the one that needs to be
* active is active.
*/
void WebBrowserTexture::set_update_active(bool active_flag){
_update_active = active_flag;
}
/**
* Gets whether or not this texture is updating itself every time it is
* rendered.
*/
bool WebBrowserTexture::get_update_active() const{
return _update_active;
}
/**
* This toggles on/off automatic flipping of the of the texture at a source
* level. Awesomium renders things that are flipped vertically. This enables
* automatic flipping of that.
*
* Since it is doing byte manipulation, this can get rather slow. Turning
* this on should be avoided. Instead, flipping should be taken care of via
* UV coordinates or shaders.
*/
void WebBrowserTexture::set_flip_texture_active(bool active_flag){
_flip_texture_active = active_flag;
}
/**
* Returns whether automatic texture flipping is enabled.
*/
bool WebBrowserTexture::get_flip_texture_active() const {
return _flip_texture_active;
}
/**
* This function will be called during the cull traversal to update the
* WebBrowserTexture. This method calls the render method of AwWebView but
* does not call the update method of AwWebCore.
*/
bool WebBrowserTexture::cull_callback(CullTraverser *trav, const CullTraverserData &data) const{
// see if we are in a state where udpates can happen. else just return
if( !_update_active ) return true;
if( _aw_web_view == nullptr ) return true;
// do we even need to update?
if( !_aw_web_view->is_dirty() ) return true;
// see if we're the same size, if not we need to make sure this texture
// matches the webview
if( _aw_web_view->get_width() != get_x_size() || _aw_web_view->get_height() != get_y_size() || get_texture_type() != TT_2d_texture){
// these casts are so dirty especially when the method itself is
// labled as const. Really Texture::cull_callback should be not const
// first clean up
((WebBrowserTexture*)this)->clear_ram_mipmap_images();
((WebBrowserTexture*)this)->clear_ram_image();
// now set up the texture again
((WebBrowserTexture*)this)->setup_2d_texture( _aw_web_view->get_width(), _aw_web_view->get_height(), T_unsigned_byte, F_rgba );
// should be good to go at this point
}
// get the pointer
PTA_uchar ram_image = ((WebBrowserTexture*)this)->modify_ram_image();
unsigned char* cp_data = ram_image.p();
// render it
_aw_web_view->render((void*)cp_data, get_x_size()*4, 4);
if(_flip_texture_active){
// flips the texture around... this is super slow. Really this should
// never be enabled. However beginners might find this useful
size_t width = get_x_size();
size_t height = get_y_size();
for(size_t i=0; i < height/2; i++){
for(size_t j=0; j < width; j++){
unsigned char tmp[4];
size_t a_pos = j+width*i;
size_t b_pos = j + width*(height-i-1);
memcpy(tmp,&cp_data[4*a_pos], 4); //tmp = a
memcpy(&cp_data[4*a_pos], &cp_data[4*b_pos], 4); //a = b
memcpy(&cp_data[4*b_pos], tmp, 4); //b = tmp
}
}
}
// success
return true;
}

View File

@ -1,77 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file WebBrowserTexture.h
* @author Bei Yang
* @date 2010-08-03
*/
#ifndef WebBrowserTexture_H
#define WebBrowserTexture_H
#include "pandabase.h"
#include "texture.h"
#include "awWebView.h"
/**
* A Wrapper class for Awesomium webview. This implements most of Awesomium's
* features and updates on the cull_traverser callback much much like a movie
* texture.
*
* The use of class means that you will have to follow Awesomium license
* agreement give below http://www.khrona.com/products/awesomium/licensing
*/
class EXPCL_PANDAAWESOMIUM WebBrowserTexture : public Texture {
protected:
AwWebView* _aw_web_view;
bool _update_active;
bool _flip_texture_active;
// Constructors & Destructors ------------
private:
WebBrowserTexture(const WebBrowserTexture &copy);
PUBLISHED:
WebBrowserTexture(const std::string &name, AwWebView* aw_web_view = nullptr);
virtual ~WebBrowserTexture();
// methods --------------
protected:
bool get_keep_ram_image() const;
void do_reload_ram_image();
public:
virtual bool has_cull_callback() const;
virtual bool cull_callback(CullTraverser *trav, const CullTraverserData &data) const;
PUBLISHED:
void set_web_view(AwWebView* aw_web_view);
AwWebView* get_web_view() const;
void set_update_active(bool active_flag);
bool get_update_active() const;
void set_flip_texture_active(bool active_flag);
bool get_flip_texture_active() const;
// Type handles ----------------
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
Texture::init_type();
register_type(_type_handle, "WebBrowserTexture",
Texture::get_class_type());
}
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
private:
static TypeHandle _type_handle;
};
#endif

View File

@ -1,48 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file awWebCore.I
* @author rurbino
* @date 2009-10-12
*/
INLINE void AwWebCore::
setBaseDirectory(const std::string& baseDirectory) {
WebCore::setBaseDirectory(baseDirectory);
}
INLINE void AwWebCore::
setCustomResponsePage(int statusCode, const std::string& filePath) {
WebCore::setCustomResponsePage(statusCode, filePath);
}
INLINE void AwWebCore::
update() {
WebCore::update();
}
INLINE const std::string& AwWebCore::
getBaseDirectory() const {
return WebCore::getBaseDirectory();
}
INLINE bool AwWebCore::
arePluginsEnabled() const {
return WebCore::arePluginsEnabled();
}
INLINE void AwWebCore::
pause(){
WebCore::pause();
}
INLINE void AwWebCore::
resume() {
WebCore::resume();
}

View File

@ -1,56 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file awWebCore.cxx
* @author rurbino
* @date 2009-10-12
*/
#include "config_awesomium.h"
#include "awWebCore.h"
#include <WebCore.h>
TypeHandle AwWebCore::_type_handle;
AwWebCore::
AwWebCore(AwWebCore::LogLevel level, bool enablePlugins , AwWebCore::PixelFormat pixelFormat)
#ifndef CPPPARSER
:
WebCore(static_cast<Awesomium::LogLevel>(level), enablePlugins, static_cast<Awesomium::PixelFormat>(pixelFormat))
#endif
{
awesomium_cat.info() << "constructing webcore\n";
}
AwWebCore::
~AwWebCore() {
awesomium_cat.info() << "destructor webcore\n";
}
Awesomium::WebCore& AwWebCore::
Get() {
return WebCore::Get();
}
Awesomium::WebCore* AwWebCore::
GetPointer() {
return WebCore::GetPointer();
}
AwWebView * AwWebCore::
createWebView(int width, int height, bool isTransparent , bool enableAsyncRendering , int maxAsyncRenderPerSec ) {
Awesomium::WebView * newView = WebCore::createWebView(width, height, isTransparent, enableAsyncRendering, maxAsyncRenderPerSec);
AwWebView * result = new AwWebView(newView);
return result;
}
AwWebCore::PixelFormat AwWebCore::
getPixelFormat() const {
return ( static_cast<AwWebCore::PixelFormat>( WebCore::getPixelFormat()) );
}

View File

@ -1,94 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file awWebCore.h
* @author rurbino
* @date 2009-10-12
*/
#ifndef AWWEBCORE_H
#define AWWEBCORE_H
#include "pandabase.h"
#include "typedReferenceCount.h"
#include "luse.h"
#include "awesomium_includes.h"
class AwWebView;
/**
* Thin wrappings arround WebCore.h
*/
class EXPCL_PANDAAWESOMIUM AwWebCore : public TypedReferenceCount, public Awesomium::WebCore {
PUBLISHED:
/**
* An enumeration of the three verbosity settings for the Awesomium Log.
*/
enum LogLevel
{
LOG_NONE , // No log is created
LOG_NORMAL , // Logs only errors
LOG_VERBOSE // Logs everything
};
/**
* An enumeration of the two output pixel formats that WebView::render will use.
*/
enum PixelFormat
{
PF_BGRA, // BGRA byte ordering [Blue, Green, Red, Alpha]
PF_RGBA // RGBA byte ordering [Red, Green, Blue, Alpha]
};
AwWebCore(LogLevel level = LOG_NORMAL, bool enablePlugins = true, PixelFormat pixelFormat = PF_BGRA);
virtual ~AwWebCore();
static Awesomium::WebCore& Get();
static Awesomium::WebCore* GetPointer();
INLINE void setBaseDirectory(const std::string& baseDirectory);
AwWebView * createWebView(int width, int height, bool isTransparent = false, bool enableAsyncRendering = false, int maxAsyncRenderPerSec = 70);
INLINE void setCustomResponsePage(int statusCode, const std::string& filePath);
INLINE void update();
INLINE const std::string& getBaseDirectory() const;
AwWebCore::PixelFormat getPixelFormat() const;
INLINE bool arePluginsEnabled() const;
INLINE void pause();
INLINE void resume();
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
TypedReferenceCount::init_type();
register_type(_type_handle, "AwWebCore",
TypedReferenceCount::get_class_type());
}
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
private:
static TypeHandle _type_handle;
};
#include "awWebCore.I"
#endif

View File

@ -1,82 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file awWebView.I
* @author rurbino
* @date 2009-10-12
*/
INLINE void AwWebView::
destroy(void)
{
_myWebView->destroy();
}
INLINE void AwWebView::
setListener(Awesomium::WebViewListener * listener) {
_myWebView->setListener(listener);
}
INLINE Awesomium::WebViewListener* AwWebView::
getListener() {
return _myWebView->getListener();
}
INLINE void AwWebView::
goToHistoryOffset(int offset) {
_myWebView->goToHistoryOffset(offset);
}
INLINE void AwWebView::
executeJavascript2(const std::string& javascript, const std::string& frameName ) {
_myWebView->executeJavascript2(javascript, frameName);
}
INLINE Awesomium::FutureJSValue AwWebView::
executeJavascriptWithResult2(const std::string& javascript, const std::string& frameName ) {
return _myWebView->executeJavascriptWithResult2(javascript, frameName);
}
INLINE void AwWebView::
setProperty(const std::string& name, const Awesomium::JSValue& value) {
_myWebView->setProperty(name, value);
}
INLINE void AwWebView::
setCallback(const std::string& name) {
_myWebView->setCallback(name);
}
INLINE bool AwWebView::
isDirty() {
return _myWebView->isDirty();
}
INLINE void AwWebView::
render( size_t destination, int destRowSpan, int destDepth)
{
_myWebView->render( reinterpret_cast<unsigned char *>(destination), destRowSpan, destDepth, 0);
}
INLINE void AwWebView::
injectMouseUp(AwWebView::MouseButton button) {
_myWebView->injectMouseUp(static_cast<Awesomium::MouseButton>(button));
}
INLINE void AwWebView::
injectMouseWheelXY(int scrollAmountX, int scrollAmountY){
_myWebView->injectMouseWheelXY(scrollAmountX, scrollAmountY);
}
INLINE void AwWebView::
injectKeyEvent(bool press, int modifiers, int windowsCode, int nativeCode) {
_myWebView->injectKeyEvent(press, modifiers, windowsCode, nativeCode);
}

View File

@ -1,74 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file awWebView.cxx
* @author rurbino
* @date 2009-10-12
*/
#include "config_awesomium.h"
#include "awWebView.h"
TypeHandle AwWebView::_type_handle;
AwWebView::
AwWebView(Awesomium::WebView * webViewPtr) {
_myWebView = webViewPtr;
}
AwWebView::
~AwWebView() {
}
void AwWebView::
loadURL2(const std::string& url, const std::string& frameName , const std::string& username , const std::string& password )
{
_myWebView->loadURL2(url, frameName, username, password);
}
void AwWebView::
loadHTML2(const std::string& html, const std::string& frameName )
{
_myWebView->loadHTML2(html, frameName);
}
void AwWebView::
loadFile2(const std::string& file, const std::string& frameName )
{
_myWebView->loadFile2(file, frameName);
}
void AwWebView::
render(size_t destination, int destRowSpan, int destDepth, AwWebView::Rect * renderedRect) {
if (renderedRect) {
Awesomium::Rect rect(renderedRect->x, renderedRect->y, renderedRect->width, renderedRect->height);
_myWebView->Awesomium::WebView::render( reinterpret_cast<unsigned char *>(destination), destRowSpan, destDepth, &rect);
}
else
{
AwWebView::render(destination, destRowSpan, destDepth, 0);
}
}
void AwWebView::
injectMouseDown(AwWebView::MouseButton button) {
awesomium_cat.debug() <<"got mouse down " << button << "\n";
_myWebView->injectMouseDown(static_cast<Awesomium::MouseButton>(button));
}
void AwWebView::
injectMouseMove(int x, int y) {
// awesomium_cat.debug() <<"got mouse move " << x << " " << y << "\n";
_myWebView->injectMouseMove(x,y);
}

View File

@ -1,131 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file awWebView.h
* @author rurbino
* @date 2009-10-12
*/
#ifndef AWWEBVIEW_H
#define AWWEBVIEW_H
#include "pandabase.h"
#include "typedReferenceCount.h"
#include "luse.h"
#include "awesomium_includes.h"
class WebViewListener;
/**
* Thin bindings, wraps a WebView * returned from WebCore.createWebView
*/
class EXPCL_PANDAAWESOMIUM AwWebView : public TypedReferenceCount{
PUBLISHED:
/**
* Mouse button enumerations, used with WebView::injectMouseDown
* and WebView::injectMouseUp
*/
enum MouseButton {
LEFT_MOUSE_BTN,
MIDDLE_MOUSE_BTN,
RIGHT_MOUSE_BTN
};
/**
* A simple rectangle class, used with WebView::render
*/
struct Rect {
int x, y, width, height;
Rect();
Rect(int x, int y, int width, int height);
bool isEmpty() const;
};
PUBLISHED:
AwWebView(Awesomium::WebView * webView);
virtual ~AwWebView();
INLINE void destroy(void);
INLINE void setListener(Awesomium::WebViewListener * listener);
INLINE Awesomium::WebViewListener* getListener();
// VC7 linker doesn't like wstring from VS2008, hence using the all regular
// string version
void loadURL2(const std::string& url, const std::string& frameName ="", const std::string& username="" , const std::string& password="");
// VC7 linker doesn't like wstring from VS2008, hence using the all regular
// string version
void loadHTML2(const std::string& html, const std::string& frameName = "");
// VC7 linker doesn't like wstring from VS2008, hence using the all regular
// string version
void loadFile2(const std::string& file, const std::string& frameName = "" );
INLINE void goToHistoryOffset(int offset);
// VC7 linker doesn't like wstring from VS2008, hence using the all regular
// string version
INLINE void executeJavascript2(const std::string& javascript, const std::string& frameName = "" );
INLINE Awesomium::FutureJSValue executeJavascriptWithResult2(const std::string& javascript, const std::string& frameName = "");
INLINE void setProperty(const std::string& name, const Awesomium::JSValue& value);
INLINE void setCallback(const std::string& name);
INLINE bool isDirty();
INLINE void render(size_t destination, int destRowSpan, int destDepth);
void render(size_t destination, int destRowSpan, int destDepth, AwWebView::Rect * renderedRect);
void injectMouseMove(int x, int y);
void injectMouseDown(AwWebView::MouseButton button);
INLINE void injectMouseUp(AwWebView::MouseButton button);
INLINE void injectMouseWheelXY(int scrollAmountX, int scrollAmountY);
INLINE void injectMouseWheel(int scrollAmountY) {
injectMouseWheelXY(0, scrollAmountY);
}
INLINE void injectKeyEvent(bool press, int modifiers, int windowsCode, int nativeCode=0);
private:
Awesomium::WebView * _myWebView;
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
TypedReferenceCount::init_type();
register_type(_type_handle, "AwWebView",
TypedReferenceCount::get_class_type());
}
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
private:
static TypeHandle _type_handle;
};
#include "awWebView.I"
#endif

View File

@ -1,80 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file awWebViewListener.cxx
* @author rurbino
* @date 2009-10-12
*/
#include "config_awesomium.h"
#include "awWebViewListener.h"
TypeHandle AwWebViewListener::_type_handle;
AwWebViewListener::
AwWebViewListener() {
awesomium_cat.info() << "constructing WebViewListner" ;
}
void AwWebViewListener::onBeginNavigation(const std::string& url, const std::wstring& frameName){
}
void AwWebViewListener::onBeginLoading(const std::string& url, const std::wstring& frameName, int statusCode, const std::wstring& mimeType) {
awesomium_cat.info() << "onBeginLoading" ;
}
/**
* This event is fired when all loads have finished for a WebView.
*/
void AwWebViewListener::onFinishLoading() {
}
/**
* This event is fired when a Client callback has been invoked via Javascript from a page.
*
* @param name The name of the client callback that was invoked (specifically, "Client._this_name_here_(...)").
*
* @param args The arguments passed to the callback.
*/
void AwWebViewListener::onCallback(const std::string& name, const Awesomium::JSArguments& args) {
}
/**
* This event is fired when a page title is received.
*
* @param title The page title.
*
* @param frameName The name of the frame that this event originated from.
*/
void AwWebViewListener::onReceiveTitle(const std::wstring& title, const std::wstring& frameName) {
}
/**
* This event is fired when a tooltip has changed state.
*
* @param tooltip The tooltip text (or, is an empty string when the tooltip should disappear).
*/
void AwWebViewListener::onChangeTooltip(const std::wstring& tooltip) {
}
/**
* This event is fired when keyboard focus has changed.
*
* @param isFocused Whether or not the keyboard is currently focused.
*/
void AwWebViewListener::onChangeKeyboardFocus(bool isFocused) {
}
/**
* This event is fired when the target URL has changed. This is usually the result of
* hovering over a link on the page.
*
* @param url The updated target URL (or empty if the target URL is cleared).
*/
void AwWebViewListener::onChangeTargetURL(const std::string& url) {
}

View File

@ -1,123 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file awWebViewListener.h
* @author rurbino
* @date 2009-10-12
*/
#ifndef AWWEBVIEWLISTENER_H
#define AWWEBVIEWLISTENER_H
#include "pandabase.h"
#include "typedReferenceCount.h"
#include "luse.h"
#include "awesomium_includes.h"
/**
* Thin bindings, wraps a WebViewListener
*/
class EXPCL_PANDAAWESOMIUM AwWebViewListener : public TypedReferenceCount, public Awesomium::WebCore {
PUBLISHED:
PUBLISHED:
AwWebViewListener();
virtual ~AwWebViewListener() {}
/**
* This event is fired when a WebView begins navigating to a new URL.
*
* @param url The URL that is being navigated to.
*
* @param frameName The name of the frame that this event originated from.
*/
void onBeginNavigation(const std::string& url, const std::wstring& frameName) ;
/**
* This event is fired when a WebView begins to actually receive data from a server.
*
* @param url The URL of the frame that is being loaded.
*
* @param frameName The name of the frame that this event originated from.
*
* @param statusCode The HTTP status code returned by the server.
*
* @param mimeType The mime-type of the content that is being loaded.
*/
void onBeginLoading(const std::string& url, const std::wstring& frameName, int statusCode, const std::wstring& mimeType);
/**
* This event is fired when all loads have finished for a WebView.
*/
void onFinishLoading();
/**
* This event is fired when a Client callback has been invoked via Javascript from a page.
*
* @param name The name of the client callback that was invoked (specifically, "Client._this_name_here_(...)").
*
* @param args The arguments passed to the callback.
*/
void onCallback(const std::string& name, const Awesomium::JSArguments& args);
/**
* This event is fired when a page title is received.
*
* @param title The page title.
*
* @param frameName The name of the frame that this event originated from.
*/
void onReceiveTitle(const std::wstring& title, const std::wstring& frameName) ;
/**
* This event is fired when a tooltip has changed state.
*
* @param tooltip The tooltip text (or, is an empty string when the tooltip should disappear).
*/
void onChangeTooltip(const std::wstring& tooltip);
/**
* This event is fired when keyboard focus has changed.
*
* @param isFocused Whether or not the keyboard is currently focused.
*/
void onChangeKeyboardFocus(bool isFocused) ;
/**
* This event is fired when the target URL has changed. This is usually the result of
* hovering over a link on the page.
*
* @param url The updated target URL (or empty if the target URL is cleared).
*/
void onChangeTargetURL(const std::string& url) ;
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
TypedReferenceCount::init_type();
register_type(_type_handle, "AwWebViewListener",
TypedReferenceCount::get_class_type());
}
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
private:
static TypeHandle _type_handle;
};
// #include "awWebViewListener.I"
#endif

Some files were not shown because too many files have changed in this diff Show More