mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 02:42:49 -04:00
Merge branch 'master' into deploy-ng
This commit is contained in:
commit
5cf2f92597
@ -35,6 +35,7 @@ addons:
|
||||
- python-dev
|
||||
- python3-dev
|
||||
- zlib1g-dev
|
||||
- fakeroot
|
||||
script: $PYTHONV makepanda/makepanda.py --everything --git-commit $TRAVIS_COMMIT $FLAGS --threads 4 && LD_LIBRARY_PATH=built/lib PYTHONPATH=built $PYTHONV makepanda/test_imports.py
|
||||
notifications:
|
||||
irc:
|
||||
|
@ -897,7 +897,7 @@ class Actor(DirectObject, NodePath):
|
||||
return ((toFrame+1)-fromFrame) / animControl.getFrameRate()
|
||||
|
||||
def getNumFrames(self, animName=None, partName=None):
|
||||
lodName = next(iter(self.__animControlDict))
|
||||
#lodName = next(iter(self.__animControlDict))
|
||||
controls = self.getAnimControls(animName, partName)
|
||||
if len(controls) == 0:
|
||||
return None
|
||||
|
@ -772,16 +772,14 @@ setup_properties(const InterrogateFunction &ifunc, InterfaceMaker *interface_mak
|
||||
first_param = 1;
|
||||
}
|
||||
|
||||
if (_has_this || _type == T_constructor) {
|
||||
if (_parameters.size() > (size_t)first_param && _parameters[first_param]._name == "self" &&
|
||||
TypeManager::is_pointer_to_PyObject(_parameters[first_param]._remap->get_orig_type())) {
|
||||
// Here's a special case. If the first parameter of a nonstatic method
|
||||
// is a PyObject * called "self", then we will automatically fill it in
|
||||
// from the this pointer, and remove it from the generated parameter
|
||||
// list.
|
||||
_parameters.erase(_parameters.begin() + first_param);
|
||||
_flags |= F_explicit_self;
|
||||
}
|
||||
if (_parameters.size() > (size_t)first_param && _parameters[first_param]._name == "self" &&
|
||||
TypeManager::is_pointer_to_PyObject(_parameters[first_param]._remap->get_orig_type())) {
|
||||
// Here's a special case. If the first parameter of a nonstatic method
|
||||
// is a PyObject * called "self", then we will automatically fill it in
|
||||
// from the this pointer, and remove it from the generated parameter
|
||||
// list.
|
||||
_parameters.erase(_parameters.begin() + first_param);
|
||||
_flags |= F_explicit_self;
|
||||
}
|
||||
|
||||
if ((int)_parameters.size() == first_param) {
|
||||
|
@ -616,7 +616,7 @@ record_function(const InterrogateType &itype, FunctionIndex func_index) {
|
||||
|
||||
// If *any* of the variants of this function has a "this" pointer,
|
||||
// the entire set of functions is deemed to have a "this" pointer.
|
||||
if (remap->_has_this) {
|
||||
if (remap->_has_this || (remap->_flags & FunctionRemap::F_explicit_self) != 0) {
|
||||
func->_has_this = true;
|
||||
}
|
||||
|
||||
|
@ -478,6 +478,11 @@ get_slotted_function_def(Object *obj, Function *func, FunctionRemap *remap,
|
||||
def._wrapper_type = WT_mapping_setitem;
|
||||
return true;
|
||||
}
|
||||
if (remap->_flags & FunctionRemap::F_size) {
|
||||
def._answer_location = "mp_length";
|
||||
def._wrapper_type = WT_sequence_size;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (obj->_protocol_types & Object::PT_iter) {
|
||||
@ -707,7 +712,10 @@ write_python_instance(ostream &out, int indent_level, const string &return_expr,
|
||||
|
||||
string class_name = itype.get_scoped_name();
|
||||
|
||||
if (IsPandaTypedObject(itype._cpptype->as_struct_type())) {
|
||||
// We don't handle final classes via DTool_CreatePyInstanceTyped since we
|
||||
// know it can't be of a subclass type, so we don't need to do the downcast.
|
||||
CPPStructType *struct_type = itype._cpptype->as_struct_type();
|
||||
if (IsPandaTypedObject(struct_type) && !struct_type->is_final()) {
|
||||
// We can't let DTool_CreatePyInstanceTyped do the NULL check since we
|
||||
// will be grabbing the type index (which would obviously crash when
|
||||
// called on a NULL pointer), so we do it here.
|
||||
@ -2100,10 +2108,10 @@ write_module_class(ostream &out, Object *obj) {
|
||||
for (ri = def._remaps.begin(); ri != def._remaps.end(); ++ri) {
|
||||
FunctionRemap *remap = (*ri);
|
||||
|
||||
if (remap->_flags & FunctionRemap::F_setitem_int) {
|
||||
if (remap->_flags & FunctionRemap::F_setitem) {
|
||||
setitem_remaps.insert(remap);
|
||||
|
||||
} else if (remap->_flags & FunctionRemap::F_delitem_int) {
|
||||
} else if (remap->_flags & FunctionRemap::F_delitem) {
|
||||
delitem_remaps.insert(remap);
|
||||
}
|
||||
}
|
||||
@ -2137,14 +2145,21 @@ write_module_class(ostream &out, Object *obj) {
|
||||
out << "// " << ClassName << " slot " << rfi->second._answer_location << " -> " << fname << "\n";
|
||||
out << "//////////////////\n";
|
||||
out << "static int " << def._wrapper_name << "(PyObject *self) {\n";
|
||||
out << " " << cClassName << " *local_this = NULL;\n";
|
||||
out << " if (!Dtool_Call_ExtractThisPointer(self, Dtool_" << ClassName << ", (void **)&local_this)) {\n";
|
||||
out << " return -1;\n";
|
||||
out << " }\n\n";
|
||||
|
||||
// Find the remap. There should be only one.
|
||||
FunctionRemap *remap = *def._remaps.begin();
|
||||
const char *container = "";
|
||||
|
||||
if (remap->_has_this) {
|
||||
out << " " << cClassName << " *local_this = NULL;\n";
|
||||
out << " if (!Dtool_Call_ExtractThisPointer(self, Dtool_" << ClassName << ", (void **)&local_this)) {\n";
|
||||
out << " return -1;\n";
|
||||
out << " }\n\n";
|
||||
container = "local_this";
|
||||
}
|
||||
|
||||
vector_string params;
|
||||
out << " return (int) " << remap->call_function(out, 4, false, "local_this", params) << ";\n";
|
||||
out << " return (int) " << remap->call_function(out, 4, false, container, params) << ";\n";
|
||||
out << "}\n\n";
|
||||
}
|
||||
break;
|
||||
@ -2374,23 +2389,25 @@ write_module_class(ostream &out, Object *obj) {
|
||||
out << "// " << ClassName << " slot " << rfi->second._answer_location << " -> " << fname << "\n";
|
||||
out << "//////////////////\n";
|
||||
out << "static int " << def._wrapper_name << "(PyObject *self, visitproc visit, void *arg) {\n";
|
||||
out << " " << cClassName << " *local_this = NULL;\n";
|
||||
out << " DTOOL_Call_ExtractThisPointerForType(self, &Dtool_" << ClassName << ", (void **) &local_this);\n";
|
||||
out << " if (local_this == NULL) {\n";
|
||||
out << " return 0;\n";
|
||||
out << " }\n\n";
|
||||
|
||||
// Find the remap. There should be only one.
|
||||
FunctionRemap *remap = *def._remaps.begin();
|
||||
const char *container = "";
|
||||
|
||||
vector_string params(1);
|
||||
if (remap->_flags & FunctionRemap::F_explicit_self) {
|
||||
params.push_back("self");
|
||||
if (remap->_has_this) {
|
||||
out << " " << cClassName << " *local_this = NULL;\n";
|
||||
out << " DTOOL_Call_ExtractThisPointerForType(self, &Dtool_" << ClassName << ", (void **) &local_this);\n";
|
||||
out << " if (local_this == NULL) {\n";
|
||||
out << " return 0;\n";
|
||||
out << " }\n\n";
|
||||
container = "local_this";
|
||||
}
|
||||
|
||||
vector_string params((int)remap->_has_this);
|
||||
params.push_back("visit");
|
||||
params.push_back("arg");
|
||||
|
||||
out << " return " << remap->call_function(out, 2, false, "local_this", params) << ";\n";
|
||||
out << " return " << remap->call_function(out, 2, false, container, params) << ";\n";
|
||||
out << "}\n\n";
|
||||
}
|
||||
break;
|
||||
@ -2857,11 +2874,9 @@ write_module_class(ostream &out, Object *obj) {
|
||||
}
|
||||
|
||||
// getattrofunc tp_getattro;
|
||||
write_function_slot(out, 4, slots, "tp_getattro",
|
||||
"PyObject_GenericGetAttr");
|
||||
write_function_slot(out, 4, slots, "tp_getattro");
|
||||
// setattrofunc tp_setattro;
|
||||
write_function_slot(out, 4, slots, "tp_setattro",
|
||||
"PyObject_GenericSetAttr");
|
||||
write_function_slot(out, 4, slots, "tp_setattro");
|
||||
|
||||
// PyBufferProcs *tp_as_buffer;
|
||||
if (has_parent_class || has_local_getbuffer) {
|
||||
@ -4180,7 +4195,7 @@ int get_type_sort(CPPType *type) {
|
||||
return 7;
|
||||
} else if (TypeManager::is_longlong(type)) {
|
||||
return 6;
|
||||
} else if (TypeManager::is_integer(type)) {
|
||||
} else if (TypeManager::is_integer(type) && !TypeManager::is_bool(type)) {
|
||||
return 5;
|
||||
} else if (TypeManager::is_double(type)) {
|
||||
return 4;
|
||||
@ -4973,7 +4988,7 @@ write_function_instance(ostream &out, FunctionRemap *remap,
|
||||
format_specifiers += "O";
|
||||
parameter_list += ", &" + param_name;
|
||||
}
|
||||
pexpr_string = "NULL";
|
||||
pexpr_string = "nullptr";
|
||||
expected_params += "NoneType";
|
||||
|
||||
} else if (TypeManager::is_char(type)) {
|
||||
@ -5800,7 +5815,8 @@ write_function_instance(ostream &out, FunctionRemap *remap,
|
||||
indent_level += 2;
|
||||
}
|
||||
|
||||
if (!remap->_has_this && (remap->_flags & FunctionRemap::F_explicit_self) != 0) {
|
||||
if (is_constructor && !remap->_has_this &&
|
||||
(remap->_flags & FunctionRemap::F_explicit_self) != 0) {
|
||||
// If we'll be passing "self" to the constructor, we need to pre-
|
||||
// initialize it here. Unfortunately, we can't pre-load the "this"
|
||||
// pointer, but the constructor itself can do this.
|
||||
|
@ -1850,12 +1850,24 @@ get_make_property(CPPMakeProperty *make_property, CPPStructType *struct_type, CP
|
||||
continue;
|
||||
}
|
||||
|
||||
const CPPParameterList::Parameters ¶ms = ftype->_parameters->_parameters;
|
||||
|
||||
size_t expected_num_args = (size_t)is_seq;
|
||||
size_t index_arg = 0;
|
||||
|
||||
if (!params.empty() && params[0]->get_simple_name() == "self" &&
|
||||
TypeManager::is_pointer_to_PyObject(params[0]->_type)) {
|
||||
// Taking a PyObject *self argument.
|
||||
expected_num_args += 1;
|
||||
index_arg += 1;
|
||||
}
|
||||
|
||||
// The getter must either take no arguments, or all defaults.
|
||||
if (ftype->_parameters->_parameters.size() == (size_t)is_seq ||
|
||||
(ftype->_parameters->_parameters.size() > (size_t)is_seq &&
|
||||
ftype->_parameters->_parameters[(size_t)is_seq]->_initializer != NULL)) {
|
||||
if (params.size() == expected_num_args ||
|
||||
(params.size() > expected_num_args &&
|
||||
params[expected_num_args]->_initializer != NULL)) {
|
||||
// If this is a sequence getter, it must take an index argument.
|
||||
if (is_seq && !TypeManager::is_integer(ftype->_parameters->_parameters[0]->_type)) {
|
||||
if (is_seq && !TypeManager::is_integer(params[index_arg]->_type)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -2428,6 +2440,10 @@ define_struct_type(InterrogateType &itype, CPPStructType *cpptype,
|
||||
break;
|
||||
}
|
||||
|
||||
if (cpptype->is_final()) {
|
||||
itype._flags |= InterrogateType::F_final;
|
||||
}
|
||||
|
||||
if (cpptype->_file.is_c_file()) {
|
||||
// This type declaration appears in a .C file. We can only export types
|
||||
// defined in a .h file.
|
||||
|
@ -289,6 +289,14 @@ is_union() const {
|
||||
return (_flags & F_union) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
INLINE bool InterrogateType::
|
||||
is_final() const {
|
||||
return (_flags & F_final) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
@ -75,6 +75,7 @@ public:
|
||||
INLINE bool is_struct() const;
|
||||
INLINE bool is_class() const;
|
||||
INLINE bool is_union() const;
|
||||
INLINE bool is_final() const;
|
||||
|
||||
INLINE bool is_fully_defined() const;
|
||||
INLINE bool is_unpublished() const;
|
||||
@ -139,6 +140,7 @@ private:
|
||||
F_typedef = 0x200000,
|
||||
F_array = 0x400000,
|
||||
F_scoped_enum = 0x800000,
|
||||
F_final =0x1000000,
|
||||
};
|
||||
|
||||
public:
|
||||
|
@ -17,6 +17,8 @@
|
||||
|
||||
#ifdef HAVE_PYTHON
|
||||
|
||||
PyTupleObject Dtool_EmptyTuple;
|
||||
|
||||
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"},
|
||||
@ -65,15 +67,6 @@ size_t PyLongOrInt_AsSize_t(PyObject *vv) {
|
||||
}
|
||||
#endif
|
||||
|
||||
#if PY_VERSION_HEX < 0x03060000
|
||||
INLINE static PyObject *_PyObject_CallNoArg(PyObject *func) {
|
||||
PyObject *args = PyTuple_New(0);
|
||||
PyObject *result = PyObject_Call(func, args, NULL);
|
||||
Py_DECREF(args);
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Given a valid (non-NULL) PyObject, does a simple check to see if it might
|
||||
* be an instance of a Panda type. It does this using a signature that is
|
||||
@ -625,6 +618,9 @@ PyObject *Dtool_PyModuleInitHelper(LibraryDef *defs[], const char *modulename) {
|
||||
return Dtool_Raise_TypeError("PyType_Ready(Dtool_StaticProperty_Type)");
|
||||
}
|
||||
|
||||
// Initialize the "empty tuple".
|
||||
(void)PyObject_INIT_VAR((PyObject *)&Dtool_EmptyTuple, &PyTuple_Type, 0);
|
||||
|
||||
// Initialize the base class of everything.
|
||||
Dtool_PyModuleClassInit_DTOOL_SUPER_BASE(NULL);
|
||||
}
|
||||
|
@ -138,6 +138,12 @@ typedef long Py_hash_t;
|
||||
#define FMTCHAR_BYTES "s"
|
||||
#endif
|
||||
|
||||
extern EXPCL_INTERROGATEDB PyTupleObject Dtool_EmptyTuple;
|
||||
|
||||
#ifndef _PyObject_CallNoArg
|
||||
#define _PyObject_CallNoArg(func) PyObject_Call((func), (PyObject *)&Dtool_EmptyTuple, NULL)
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
|
||||
// this is tempory .. untill this is glued better into the panda build system
|
||||
|
@ -142,7 +142,6 @@ extern "C" {
|
||||
EXPCL_PYSTUB int PyTuple_New(...);
|
||||
EXPCL_PYSTUB int PyTuple_Pack(...);
|
||||
EXPCL_PYSTUB int PyTuple_Size(...);
|
||||
EXPCL_PYSTUB int PyTuple_Type(...);
|
||||
EXPCL_PYSTUB int PyType_GenericAlloc(...);
|
||||
EXPCL_PYSTUB int PyType_IsSubtype(...);
|
||||
EXPCL_PYSTUB int PyType_Ready(...);
|
||||
@ -224,6 +223,7 @@ extern "C" {
|
||||
EXPCL_PYSTUB extern void *PyExc_SystemExit;
|
||||
EXPCL_PYSTUB extern void *PyExc_TypeError;
|
||||
EXPCL_PYSTUB extern void *PyExc_ValueError;
|
||||
EXPCL_PYSTUB extern void *PyTuple_Type;
|
||||
EXPCL_PYSTUB extern void *PyType_Type;
|
||||
EXPCL_PYSTUB extern void *_PyThreadState_Current;
|
||||
EXPCL_PYSTUB extern void *_Py_FalseStruct;
|
||||
@ -363,7 +363,6 @@ int PyTuple_GetItem(...) { return 0; }
|
||||
int PyTuple_New(...) { return 0; }
|
||||
int PyTuple_Pack(...) { return 0; }
|
||||
int PyTuple_Size(...) { return 0; };
|
||||
int PyTuple_Type(...) { return 0; };
|
||||
int PyType_GenericAlloc(...) { return 0; };
|
||||
int PyType_IsSubtype(...) { return 0; }
|
||||
int PyType_Ready(...) { return 0; };
|
||||
@ -451,6 +450,7 @@ void *PyExc_StopIteration = (void *)NULL;
|
||||
void *PyExc_SystemExit = (void *)NULL;
|
||||
void *PyExc_TypeError = (void *)NULL;
|
||||
void *PyExc_ValueError = (void *)NULL;
|
||||
void *PyTuple_Type = (void *)NULL;
|
||||
void *PyType_Type = (void *)NULL;
|
||||
void *_PyThreadState_Current = (void *)NULL;
|
||||
void *_Py_FalseStruct = (void *)NULL;
|
||||
|
@ -7,13 +7,19 @@ import os, importlib
|
||||
import direct.showbase.VerboseImport
|
||||
|
||||
|
||||
import imp
|
||||
import panda3d
|
||||
dir = os.path.dirname(panda3d.__file__)
|
||||
|
||||
for basename in os.listdir(dir):
|
||||
module, ext = os.path.splitext(basename)
|
||||
extensions = set()
|
||||
for suffix in imp.get_suffixes():
|
||||
extensions.add(suffix[0])
|
||||
|
||||
if ext in ('.pyd', '.so'):
|
||||
for basename in os.listdir(dir):
|
||||
module = basename.split('.', 1)[0]
|
||||
ext = basename[len(module):]
|
||||
|
||||
if ext in extensions:
|
||||
importlib.import_module('panda3d.%s' % (module))
|
||||
|
||||
|
||||
|
@ -40,6 +40,10 @@ PUBLISHED:
|
||||
virtual const Filename &get_filename();
|
||||
virtual const FileReference *get_file();
|
||||
virtual streampos get_file_pos();
|
||||
|
||||
MAKE_PROPERTY(filename, get_filename);
|
||||
MAKE_PROPERTY(file, get_file);
|
||||
MAKE_PROPERTY(file_pos, get_file_pos);
|
||||
};
|
||||
|
||||
#include "datagramSink.I"
|
||||
|
@ -28,14 +28,13 @@
|
||||
* header followed by a number of datagrams.
|
||||
*/
|
||||
class EXPCL_PANDA_PUTIL DatagramOutputFile : public DatagramSink {
|
||||
public:
|
||||
PUBLISHED:
|
||||
INLINE DatagramOutputFile();
|
||||
INLINE ~DatagramOutputFile();
|
||||
|
||||
bool open(const FileReference *file);
|
||||
INLINE bool open(const Filename &filename);
|
||||
bool open(ostream &out, const Filename &filename = Filename());
|
||||
INLINE ostream &get_stream();
|
||||
|
||||
void close();
|
||||
|
||||
@ -46,10 +45,16 @@ public:
|
||||
virtual bool is_error();
|
||||
virtual void flush();
|
||||
|
||||
public:
|
||||
virtual const Filename &get_filename();
|
||||
virtual const FileReference *get_file();
|
||||
virtual streampos get_file_pos();
|
||||
|
||||
INLINE ostream &get_stream();
|
||||
|
||||
PUBLISHED:
|
||||
MAKE_PROPERTY(stream, get_stream);
|
||||
|
||||
private:
|
||||
bool _wrote_first_datagram;
|
||||
bool _error;
|
||||
|
@ -1440,15 +1440,12 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
||||
break;
|
||||
|
||||
case WM_SIZE:
|
||||
// Actually, since we don't return in WM_WINDOWPOSCHANGED, WM_SIZE won't
|
||||
// end up being called at all. This is more efficient according to MSDN.
|
||||
if (windisplay_cat.is_debug()) {
|
||||
windisplay_cat.debug()
|
||||
<< "WM_SIZE: " << hwnd << ", " << wparam << "\n";
|
||||
}
|
||||
|
||||
// Resist calling handle_reshape before the window has opened.
|
||||
if (_hWnd != NULL) {
|
||||
handle_reshape();
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_EXITSIZEMOVE:
|
||||
@ -1456,8 +1453,15 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
||||
break;
|
||||
|
||||
case WM_WINDOWPOSCHANGED:
|
||||
if (windisplay_cat.is_debug()) {
|
||||
windisplay_cat.debug()
|
||||
<< "WM_WINDOWPOSCHANGED: " << hwnd << ", " << wparam << "\n";
|
||||
}
|
||||
if (_hWnd != NULL) {
|
||||
handle_reshape();
|
||||
}
|
||||
adjust_z_order();
|
||||
break;
|
||||
return 0;
|
||||
|
||||
case WM_PAINT:
|
||||
// In response to WM_PAINT, we check to see if there are any update
|
||||
|
Loading…
x
Reference in New Issue
Block a user