mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-29 08:15:18 -04:00
Merge branch 'release/1.10.x'
This commit is contained in:
commit
ba993aea0d
27
README.md
27
README.md
@ -8,12 +8,12 @@ Panda3D
|
||||
Panda3D is a game engine, a framework for 3D rendering and game development for
|
||||
Python and C++ programs. Panda3D is open-source and free for any purpose,
|
||||
including commercial ventures, thanks to its
|
||||
[liberal license](https://www.panda3d.org/license.php). To learn more about
|
||||
Panda3D's capabilities, visit the [gallery](https://www.panda3d.org/gallery.php)
|
||||
and the [feature list](https://www.panda3d.org/features.php). To learn how to
|
||||
use Panda3D, check the [documentation](https://www.panda3d.org/documentation.php)
|
||||
[liberal license](https://www.panda3d.org/license/). To learn more about
|
||||
Panda3D's capabilities, visit the [gallery](https://www.panda3d.org/gallery/)
|
||||
and the [feature list](https://www.panda3d.org/features/). To learn how to
|
||||
use Panda3D, check the [documentation](https://www.panda3d.org/documentation/)
|
||||
resources. If you get stuck, ask for help from our active
|
||||
[community](https://www.panda3d.org/community.php).
|
||||
[community](https://discourse.panda3d.org).
|
||||
|
||||
Panda3D is licensed under the Modified BSD License. See the LICENSE file for
|
||||
more details.
|
||||
@ -21,7 +21,16 @@ more details.
|
||||
Installing Panda3D
|
||||
==================
|
||||
|
||||
By far, the easiest way to install the latest development build of Panda3D
|
||||
The latest Panda3D SDK can be downloaded from
|
||||
(this page)[https://www.panda3d.org/download/sdk-1-10-0/].
|
||||
If you are familiar with installing Python packages, you can use
|
||||
the following comand:
|
||||
|
||||
```bash
|
||||
pip install panda3d
|
||||
```
|
||||
|
||||
The easiest way to install the latest development build of Panda3D
|
||||
into an existing Python installation is using the following command:
|
||||
|
||||
```bash
|
||||
@ -31,9 +40,7 @@ pip install --pre --extra-index-url https://archive.panda3d.org/ panda3d
|
||||
If this command fails, please make sure your version of pip is up-to-date.
|
||||
|
||||
If you prefer to install the full SDK with all tools, the latest development
|
||||
builds can be obtained from this page:
|
||||
|
||||
https://www.panda3d.org/download.php?sdk&version=devel
|
||||
builds can be obtained from (this page)[https://www.panda3d.org/download/].
|
||||
|
||||
These are automatically kept up-to-date with the latest GitHub version of Panda.
|
||||
|
||||
@ -96,7 +103,7 @@ python makepanda/makepanda.py --everything --installer --no-egl --no-gles --no-g
|
||||
You will probably see some warnings saying that it's unable to find several
|
||||
dependency packages. You should determine which ones you want to include in
|
||||
your build and install the respective development packages. You may visit
|
||||
[this manual page](https://www.panda3d.org/manual/index.php/Dependencies)
|
||||
[this manual page](https://www.panda3d.org/manual/?title=Third-party_dependencies_and_license_info)
|
||||
for an overview of the various dependencies.
|
||||
|
||||
If you are on Ubuntu, this command should cover the most frequently
|
||||
|
@ -26,6 +26,9 @@ get_string() {
|
||||
|
||||
// First, get the length of the string
|
||||
size_t size = get_uint16();
|
||||
if (size == 0) {
|
||||
return string();
|
||||
}
|
||||
|
||||
char *buffer = (char *)alloca(size);
|
||||
_in->read(buffer, size);
|
||||
@ -42,6 +45,9 @@ get_string32() {
|
||||
|
||||
// First, get the length of the string
|
||||
size_t size = get_uint32();
|
||||
if (size == 0) {
|
||||
return string();
|
||||
}
|
||||
|
||||
char *buffer = (char *)PANDA_MALLOC_ARRAY(size);
|
||||
_in->read(buffer, size);
|
||||
@ -60,7 +66,7 @@ get_z_string() {
|
||||
|
||||
string result;
|
||||
int ch = _in->get();
|
||||
while (!_in->eof() && !_in->fail() && ch != '\0') {
|
||||
while (!_in->fail() && ch != EOF && ch != '\0') {
|
||||
result += (char)ch;
|
||||
ch = _in->get();
|
||||
}
|
||||
@ -76,6 +82,10 @@ string StreamReader::
|
||||
get_fixed_string(size_t size) {
|
||||
nassertr(!_in->eof() && !_in->fail(), string());
|
||||
|
||||
if (size == 0) {
|
||||
return string();
|
||||
}
|
||||
|
||||
char *buffer = (char *)alloca(size);
|
||||
_in->read(buffer, size);
|
||||
size_t read_bytes = _in->gcount();
|
||||
@ -90,8 +100,9 @@ get_fixed_string(size_t size) {
|
||||
*/
|
||||
void StreamReader::
|
||||
skip_bytes(size_t size) {
|
||||
nassertv(!_in->eof() && !_in->fail());
|
||||
nassertv(!_in->fail());
|
||||
nassertv((int)size >= 0);
|
||||
nassertv(size == 0 || !_in->eof());
|
||||
|
||||
while (size > 0) {
|
||||
_in->get();
|
||||
@ -145,9 +156,9 @@ string StreamReader::
|
||||
readline() {
|
||||
string line;
|
||||
int ch = _in->get();
|
||||
while (!_in->eof() && !_in->fail()) {
|
||||
while (ch != EOF && !_in->fail()) {
|
||||
line += (char)ch;
|
||||
if (ch == '\n') {
|
||||
if (ch == '\n' || _in->eof()) {
|
||||
// Here's the newline character.
|
||||
return line;
|
||||
}
|
||||
|
@ -45,9 +45,9 @@ readline() {
|
||||
|
||||
std::string line;
|
||||
int ch = in->get();
|
||||
while (!in->eof() && !in->fail()) {
|
||||
while (ch != EOF && !in->fail()) {
|
||||
line += ch;
|
||||
if (ch == '\n') {
|
||||
if (ch == '\n' || in->eof()) {
|
||||
// Here's the newline character.
|
||||
break;
|
||||
}
|
||||
|
@ -526,11 +526,6 @@ def makewheel(version, output_dir, platform=None):
|
||||
|
||||
# Update relevant METADATA entries
|
||||
METADATA['version'] = version
|
||||
version_classifiers = [
|
||||
"Programming Language :: Python :: {0}".format(*sys.version_info),
|
||||
"Programming Language :: Python :: {0}.{1}".format(*sys.version_info),
|
||||
]
|
||||
METADATA['classifiers'].extend(version_classifiers)
|
||||
|
||||
# Build out the metadata
|
||||
details = METADATA["extensions"]["python.details"]
|
||||
|
@ -183,7 +183,7 @@ decompress(const Filename &source_file) {
|
||||
return false;
|
||||
|
||||
int ch = _decompress->get();
|
||||
while (!_decompress->eof() && !_decompress->fail()) {
|
||||
while (ch != EOF && !_decompress->fail()) {
|
||||
_dest->put(ch);
|
||||
ch = _decompress->get();
|
||||
}
|
||||
@ -207,7 +207,7 @@ decompress(Ramfile &source_and_dest_file) {
|
||||
IDecompressStream decompress(&source, false);
|
||||
|
||||
int ch = decompress.get();
|
||||
while (!decompress.eof() && !decompress.fail()) {
|
||||
while (ch != EOF && !decompress.fail()) {
|
||||
dest.put(ch);
|
||||
ch = decompress.get();
|
||||
}
|
||||
|
@ -66,7 +66,7 @@ input(std::istream &in) {
|
||||
// Scan the tag, up to but not including the closing paren.
|
||||
std::string tag;
|
||||
in >> ch;
|
||||
while (!in.fail() && !in.eof() && ch != ')') {
|
||||
while (!in.fail() && ch != EOF && ch != ')') {
|
||||
tag += ch;
|
||||
// We want to include embedded whitespace, so we use get().
|
||||
ch = in.get();
|
||||
@ -81,7 +81,7 @@ input(std::istream &in) {
|
||||
// Scan the date, up to but not including the closing bracket.
|
||||
if (ch != ']') {
|
||||
std::string date;
|
||||
while (!in.fail() && !in.eof() && ch != ']') {
|
||||
while (!in.fail() && ch != EOF && ch != ']') {
|
||||
date += ch;
|
||||
ch = in.get();
|
||||
}
|
||||
|
@ -2762,7 +2762,7 @@ bool HTTPChannel::
|
||||
server_getline(string &str) {
|
||||
nassertr(!_source.is_null(), false);
|
||||
int ch = (*_source)->get();
|
||||
while (!(*_source)->eof() && !(*_source)->fail()) {
|
||||
while (ch != EOF && !(*_source)->fail()) {
|
||||
switch (ch) {
|
||||
case '\n':
|
||||
// end-of-line character, we're done.
|
||||
@ -2850,7 +2850,7 @@ bool HTTPChannel::
|
||||
server_get(string &str, size_t num_bytes) {
|
||||
nassertr(!_source.is_null(), false);
|
||||
int ch = (*_source)->get();
|
||||
while (!(*_source)->eof() && !(*_source)->fail()) {
|
||||
while (ch != EOF && !(*_source)->fail()) {
|
||||
_working_get += (char)ch;
|
||||
if (_working_get.length() >= num_bytes) {
|
||||
str = _working_get;
|
||||
|
@ -279,7 +279,7 @@ input(std::istream &in) {
|
||||
|
||||
string date;
|
||||
ch = in.get();
|
||||
while (!in.fail() && !in.eof() && ch != '"') {
|
||||
while (!in.fail() && ch != EOF && ch != '"') {
|
||||
date += ch;
|
||||
ch = in.get();
|
||||
}
|
||||
|
@ -56,7 +56,7 @@ do_receive_datagram(Datagram &dg) {
|
||||
// Read the first two bytes: the datagram length.
|
||||
while ((int)_data_so_far.size() < _tcp_header_size) {
|
||||
int ch = _istream->get();
|
||||
if (_istream->eof() || _istream->fail()) {
|
||||
if (ch == EOF || _istream->fail()) {
|
||||
_istream->clear();
|
||||
return false;
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ input_hex(istream &in) {
|
||||
size_t i = 0;
|
||||
int ch = in.get();
|
||||
|
||||
while (!in.eof() && !in.fail() && isxdigit(ch)) {
|
||||
while (ch != EOF && !in.fail() && isxdigit(ch)) {
|
||||
if (i < 32) {
|
||||
buffer[i] = (char)ch;
|
||||
}
|
||||
@ -63,7 +63,7 @@ input_hex(istream &in) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!in.eof()) {
|
||||
if (ch != EOF) {
|
||||
in.putback((char)ch);
|
||||
} else {
|
||||
in.clear();
|
||||
|
@ -108,7 +108,7 @@ main(int argc, char *argv[]) {
|
||||
int col = 0;
|
||||
unsigned int ch;
|
||||
ch = in.get();
|
||||
while (!in.fail() && !in.eof()) {
|
||||
while (!in.fail() && ch != EOF) {
|
||||
if (col == 0) {
|
||||
out << "\n ";
|
||||
} else if (col == col_width) {
|
||||
|
@ -1785,8 +1785,7 @@ compare_subfile(int index, const Filename &filename) {
|
||||
in2.seekg(0);
|
||||
int byte1 = in1->get();
|
||||
int byte2 = in2.get();
|
||||
while (!in1->fail() && !in1->eof() &&
|
||||
!in2.fail() && !in2.eof()) {
|
||||
while (!in1->fail() && !in2.fail()) {
|
||||
if (byte1 != byte2) {
|
||||
close_read_subfile(in1);
|
||||
return false;
|
||||
@ -2497,7 +2496,7 @@ read_index(istream &read, streampos fpos, Multifile *multifile) {
|
||||
StreamReader reader(read);
|
||||
|
||||
streampos next_index = multifile->word_to_streampos(reader.get_uint32());
|
||||
if (read.eof() || read.fail()) {
|
||||
if (read.fail()) {
|
||||
_flags |= SF_index_invalid;
|
||||
return 0;
|
||||
}
|
||||
@ -2529,7 +2528,7 @@ read_index(istream &read, streampos fpos, Multifile *multifile) {
|
||||
}
|
||||
|
||||
size_t name_length = reader.get_uint16();
|
||||
if (read.eof() || read.fail()) {
|
||||
if (read.fail()) {
|
||||
_flags |= SF_index_invalid;
|
||||
return 0;
|
||||
}
|
||||
@ -2543,7 +2542,7 @@ read_index(istream &read, streampos fpos, Multifile *multifile) {
|
||||
_name = string(name_buffer, name_length);
|
||||
PANDA_FREE_ARRAY(name_buffer);
|
||||
|
||||
if (read.eof() || read.fail()) {
|
||||
if (read.fail()) {
|
||||
_flags |= SF_index_invalid;
|
||||
return 0;
|
||||
}
|
||||
|
@ -4158,7 +4158,7 @@ do_read_dds(CData *cdata, istream &in, const string &filename, bool header_only)
|
||||
cdata->_num_mipmap_levels_read = cdata->_ram_images.size();
|
||||
}
|
||||
|
||||
if (in.fail() || in.eof()) {
|
||||
if (in.fail()) {
|
||||
gobj_cat.error()
|
||||
<< filename << ": truncated DDS file.\n";
|
||||
return false;
|
||||
@ -4924,7 +4924,7 @@ do_read_ktx(CData *cdata, istream &in, const string &filename, bool header_only)
|
||||
}
|
||||
}
|
||||
|
||||
if (in.fail() || in.eof()) {
|
||||
if (in.fail()) {
|
||||
gobj_cat.error()
|
||||
<< filename << ": truncated KTX file.\n";
|
||||
return false;
|
||||
|
@ -120,7 +120,7 @@ int
|
||||
pm_readbigshort(istream *in, short *sP) {
|
||||
StreamReader reader(in, false);
|
||||
*sP = reader.get_be_int16();
|
||||
return (!in->eof() && !in->fail()) ? 0 : -1;
|
||||
return (!in->fail()) ? 0 : -1;
|
||||
}
|
||||
|
||||
int
|
||||
@ -134,7 +134,7 @@ int
|
||||
pm_readbiglong(istream *in, long *lP) {
|
||||
StreamReader reader(in, false);
|
||||
*lP = reader.get_be_int32();
|
||||
return (!in->eof() && !in->fail()) ? 0 : -1;
|
||||
return (!in->fail()) ? 0 : -1;
|
||||
}
|
||||
|
||||
int
|
||||
@ -148,7 +148,7 @@ int
|
||||
pm_readlittleshort(istream *in, short *sP) {
|
||||
StreamReader reader(in, false);
|
||||
*sP = reader.get_int16();
|
||||
return (!in->eof() && !in->fail()) ? 0 : -1;
|
||||
return (!in->fail()) ? 0 : -1;
|
||||
}
|
||||
|
||||
int
|
||||
@ -162,7 +162,7 @@ int
|
||||
pm_readlittlelong(istream *in, long *lP) {
|
||||
StreamReader reader(in, false);
|
||||
*lP = reader.get_int32();
|
||||
return (!in->eof() && !in->fail()) ? 0 : -1;
|
||||
return (!in->fail()) ? 0 : -1;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -101,7 +101,7 @@ run() {
|
||||
int col = 0;
|
||||
unsigned int ch;
|
||||
ch = in.get();
|
||||
while (!in.fail() && !in.eof()) {
|
||||
while (!in.fail() && ch != EOF) {
|
||||
if (col == 0) {
|
||||
out << "\n ";
|
||||
} else if (col == col_width) {
|
||||
|
11
setup.cfg
11
setup.cfg
@ -13,10 +13,21 @@ classifiers =
|
||||
Operating System :: OS Independent
|
||||
Programming Language :: C++
|
||||
Programming Language :: Python
|
||||
Programming Language :: Python :: 2
|
||||
Programming Language :: Python :: 2.7
|
||||
Programming Language :: Python :: 3
|
||||
Programming Language :: Python :: 3.4
|
||||
Programming Language :: Python :: 3.5
|
||||
Programming Language :: Python :: 3.6
|
||||
Programming Language :: Python :: 3.7
|
||||
Programming Language :: Python :: Implementation :: CPython
|
||||
Topic :: Games/Entertainment
|
||||
Topic :: Multimedia
|
||||
Topic :: Multimedia :: Graphics
|
||||
Topic :: Multimedia :: Graphics :: 3D Rendering
|
||||
Topic :: Software Development :: Libraries
|
||||
Topic :: Software Development :: Libraries :: Application Frameworks
|
||||
Topic :: Software Development :: Libraries :: Python Modules
|
||||
author = Panda3D Team
|
||||
author_email = etc-panda3d@lists.andrew.cmu.edu
|
||||
|
||||
|
12
tests/express/test_multifile.py
Normal file
12
tests/express/test_multifile.py
Normal file
@ -0,0 +1,12 @@
|
||||
from panda3d.core import Multifile, StringStream, IStreamWrapper
|
||||
|
||||
|
||||
def test_multifile_read_empty():
|
||||
stream = StringStream(b'pmf\x00\n\r\x01\x00\x01\x00\x01\x00\x00\x00\xdb\x9d7\\\x00\x00\x00\x00')
|
||||
wrapper = IStreamWrapper(stream)
|
||||
|
||||
m = Multifile()
|
||||
assert m.open_read(wrapper)
|
||||
assert m.is_read_valid()
|
||||
assert m.get_num_subfiles() == 0
|
||||
m.close()
|
157
tests/prc/test_stream_reader.py
Normal file
157
tests/prc/test_stream_reader.py
Normal file
@ -0,0 +1,157 @@
|
||||
from panda3d.core import StreamReader, StringStream
|
||||
import pytest
|
||||
|
||||
|
||||
def test_streamreader_string():
|
||||
# Empty string
|
||||
stream = StringStream(b'\x00\x00')
|
||||
reader = StreamReader(stream, False)
|
||||
assert reader.get_string() == ''
|
||||
|
||||
# String size but no string contents
|
||||
stream = StringStream(b'\x01\x00')
|
||||
reader = StreamReader(stream, False)
|
||||
assert reader.get_string() == ''
|
||||
|
||||
# String of length 1
|
||||
stream = StringStream(b'\x01\x00A')
|
||||
reader = StreamReader(stream, False)
|
||||
assert reader.get_string() == 'A'
|
||||
|
||||
# String with excess data
|
||||
stream = StringStream(b'\x01\x00AB')
|
||||
reader = StreamReader(stream, False)
|
||||
assert reader.get_string() == 'A'
|
||||
|
||||
# EOF before end of string
|
||||
stream = StringStream(b'\x03\x00AB')
|
||||
reader = StreamReader(stream, False)
|
||||
assert reader.get_string() == 'AB'
|
||||
|
||||
# Preserves null bytes
|
||||
stream = StringStream(b'\x02\x00\x00\x00')
|
||||
reader = StreamReader(stream, False)
|
||||
assert reader.get_string() == '\x00\x00'
|
||||
|
||||
|
||||
def test_streamreader_string32():
|
||||
# Empty string
|
||||
stream = StringStream(b'\x00\x00\x00\x00')
|
||||
reader = StreamReader(stream, False)
|
||||
assert reader.get_string32() == ''
|
||||
|
||||
# String size but no string contents
|
||||
stream = StringStream(b'\x01\x00\x00\x00')
|
||||
reader = StreamReader(stream, False)
|
||||
assert reader.get_string32() == ''
|
||||
|
||||
# String of length 1
|
||||
stream = StringStream(b'\x01\x00\x00\x00A')
|
||||
reader = StreamReader(stream, False)
|
||||
assert reader.get_string32() == 'A'
|
||||
|
||||
# String with excess data
|
||||
stream = StringStream(b'\x01\x00\x00\x00AB')
|
||||
reader = StreamReader(stream, False)
|
||||
assert reader.get_string32() == 'A'
|
||||
|
||||
# EOF before end of string
|
||||
stream = StringStream(b'\x04\x00\x00\x00AB')
|
||||
reader = StreamReader(stream, False)
|
||||
assert reader.get_string32() == 'AB'
|
||||
|
||||
# Preserves null bytes
|
||||
stream = StringStream(b'\x02\x00\x00\x00\x00\x00')
|
||||
reader = StreamReader(stream, False)
|
||||
assert reader.get_string32() == '\x00\x00'
|
||||
|
||||
|
||||
def test_streamreader_z_string():
|
||||
# Empty stream
|
||||
stream = StringStream(b'')
|
||||
reader = StreamReader(stream, False)
|
||||
assert reader.get_z_string() == ''
|
||||
|
||||
# Empty string
|
||||
stream = StringStream(b'\x00')
|
||||
reader = StreamReader(stream, False)
|
||||
assert reader.get_z_string() == ''
|
||||
|
||||
# String of length 1
|
||||
stream = StringStream(b'A\x00')
|
||||
reader = StreamReader(stream, False)
|
||||
assert reader.get_z_string() == 'A'
|
||||
|
||||
# String with excess data
|
||||
stream = StringStream(b'ABC\x00AB')
|
||||
reader = StreamReader(stream, False)
|
||||
assert reader.get_z_string() == 'ABC'
|
||||
|
||||
# EOF before end of string
|
||||
stream = StringStream(b'ABC')
|
||||
reader = StreamReader(stream, False)
|
||||
assert reader.get_z_string() == 'ABC'
|
||||
|
||||
|
||||
def test_streamreader_fixed_string():
|
||||
# Zero-length string
|
||||
stream = StringStream(b'ABC')
|
||||
reader = StreamReader(stream, False)
|
||||
assert reader.get_fixed_string(0) == ''
|
||||
|
||||
# Empty stream
|
||||
stream = StringStream(b'')
|
||||
reader = StreamReader(stream, False)
|
||||
assert reader.get_fixed_string(1) == ''
|
||||
|
||||
# Empty string
|
||||
stream = StringStream(b'\x00')
|
||||
reader = StreamReader(stream, False)
|
||||
assert reader.get_fixed_string(1) == ''
|
||||
|
||||
# String of length 1
|
||||
stream = StringStream(b'A')
|
||||
reader = StreamReader(stream, False)
|
||||
assert reader.get_fixed_string(1) == 'A'
|
||||
|
||||
# String of length 1, excess data
|
||||
stream = StringStream(b'ABC\x00')
|
||||
reader = StreamReader(stream, False)
|
||||
assert reader.get_fixed_string(1) == 'A'
|
||||
|
||||
# EOF before end of string
|
||||
stream = StringStream(b'AB')
|
||||
reader = StreamReader(stream, False)
|
||||
assert reader.get_fixed_string(4) == 'AB'
|
||||
|
||||
|
||||
def test_streamreader_readline():
|
||||
# Empty stream
|
||||
stream = StringStream(b'')
|
||||
reader = StreamReader(stream, False)
|
||||
assert reader.readline() == b''
|
||||
assert reader.readline() == b''
|
||||
|
||||
# Single line without newline
|
||||
stream = StringStream(b'A')
|
||||
reader = StreamReader(stream, False)
|
||||
assert reader.readline() == b'A'
|
||||
assert reader.readline() == b''
|
||||
|
||||
# Single newline
|
||||
stream = StringStream(b'\n')
|
||||
reader = StreamReader(stream, False)
|
||||
assert reader.readline() == b'\n'
|
||||
assert reader.readline() == b''
|
||||
|
||||
# Line with text followed by empty line
|
||||
stream = StringStream(b'A\n\n')
|
||||
reader = StreamReader(stream, False)
|
||||
assert reader.readline() == b'A\n'
|
||||
assert reader.readline() == b'\n'
|
||||
assert reader.readline() == b''
|
||||
|
||||
# Preserve null byte
|
||||
stream = StringStream(b'\x00\x00')
|
||||
reader = StreamReader(stream, False)
|
||||
assert reader.readline() == b'\x00\x00'
|
Loading…
x
Reference in New Issue
Block a user