Merge branch 'master' into input-overhaul

This commit is contained in:
rdb 2018-11-06 22:10:39 +01:00
commit 70bfe21a63
91 changed files with 2239 additions and 2191 deletions

View File

@ -11,6 +11,8 @@ matrix:
before_install:
- export CC=gcc-4.7
- export CXX=g++-4.7
- compiler: clang
env: PYTHONV=python3 FLAGS=--no-python SKIP_TESTS=1
addons:
apt:
sources:
@ -42,8 +44,8 @@ install:
- $PYTHONV -m pip install pytest
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
- LD_LIBRARY_PATH=built/lib PYTHONPATH=built $PYTHONV -m pytest -v tests
- test -n "$SKIP_TESTS" || LD_LIBRARY_PATH=built/lib PYTHONPATH=built $PYTHONV makepanda/test_imports.py
- test -n "$SKIP_TESTS" || LD_LIBRARY_PATH=built/lib PYTHONPATH=built $PYTHONV -m pytest -v tests
notifications:
irc:
channels:

View File

@ -1,9 +0,0 @@
ATTACH dmodels
ATTACH panda
MODREL ETC_PATH etc
DOCSH set parent=`dirname $DIRECT`
DOCSH if ( ${?PANDA_ROOT} ) then
DOCSH setenv PYTHONPATH "${PYTHONPATH};"`cygpath -w "$parent"`
DOCSH else
DOCSH setenv PYTHONPATH "${PYTHONPATH}:$parent"
DOCSH endif

View File

@ -6,8 +6,7 @@ from .ClockDelta import *
from . import DistributedNode
from . import DistributedSmoothNodeBase
from direct.task.Task import cont
config = get_config_showbase()
from direct.showbase import DConfig as config
# This number defines our tolerance for out-of-sync telemetry packets.
# If a packet appears to have originated from more than MaxFuture

View File

@ -0,0 +1,25 @@
"This module contains a deprecated shim emulating the old DConfig API."
__all__ = []
from panda3d.core import (ConfigFlags, ConfigVariableBool, ConfigVariableInt,
ConfigVariableDouble, ConfigVariableString)
def GetBool(sym, default=False):
return ConfigVariableBool(sym, default, "DConfig", ConfigFlags.F_dconfig).value
def GetInt(sym, default=0):
return ConfigVariableInt(sym, default, "DConfig", ConfigFlags.F_dconfig).value
def GetDouble(sym, default=0.0):
return ConfigVariableDouble(sym, default, "DConfig", ConfigFlags.F_dconfig).value
def GetString(sym, default=""):
return ConfigVariableString(sym, default, "DConfig", ConfigFlags.F_dconfig).value
GetFloat = GetDouble

View File

@ -10,8 +10,9 @@ __all__ = ['ShowBase', 'WindowControls']
#import VerboseImport
from panda3d.core import *
from panda3d.direct import get_config_showbase, throw_new_frame, init_app_for_gui
from panda3d.direct import throw_new_frame, init_app_for_gui
from panda3d.direct import storeAccessibilityShortcutKeys, allowAccessibilityShortcutKeys
from . import DConfig
# Register the extension methods for NodePath.
from direct.extensions_native import NodePath_extensions
@ -22,7 +23,7 @@ if sys.version_info >= (3, 0):
import builtins
else:
import __builtin__ as builtins
builtins.config = get_config_showbase()
builtins.config = DConfig
from direct.directnotify.DirectNotifyGlobal import directNotify, giveNotify
from .MessengerGlobal import messenger
@ -57,7 +58,7 @@ def exitfunc():
# *seem* to cause anyone any problems.
class ShowBase(DirectObject.DirectObject):
config = get_config_showbase()
config = DConfig
notify = directNotify.newCategory("ShowBase")
def __init__(self, fStartDirect = True, windowType = None):

View File

@ -12,9 +12,8 @@ from direct.directnotify.DirectNotifyGlobal import directNotify, giveNotify
from panda3d.core import VirtualFileSystem, Notify, ClockObject, PandaSystem
from panda3d.core import ConfigPageManager, ConfigVariableManager
from panda3d.core import NodePath, PGTop
from panda3d.direct import get_config_showbase
from . import DConfig as config
config = get_config_showbase()
__dev__ = config.GetBool('want-dev', __debug__)
vfs = VirtualFileSystem.getGlobalPtr()

View File

@ -61,14 +61,6 @@ throw_new_frame() {
throw_event("NewFrame");
}
// Returns the configure object for accessing config variables from a
// scripting language.
DConfig &
get_config_showbase() {
static DConfig config_showbase;
return config_showbase;
}
// Initialize the application for making a Gui-based app, such as wx. At the
// moment, this is a no-op except on Mac.
void

View File

@ -38,7 +38,6 @@ EXPCL_DIRECT_SHOWBASE ConfigVariableSearchPath &get_particle_path();
EXPCL_DIRECT_SHOWBASE void throw_new_frame();
EXPCL_DIRECT_SHOWBASE DConfig &get_config_showbase();
EXPCL_DIRECT_SHOWBASE void init_app_for_gui();
// klunky interface since we cant pass array from python->C++

View File

@ -1,21 +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 config_dconfig.cxx
* @author drose
* @date 2000-05-15
*/
#include "config_dconfig.h"
#if !defined(CPPPARSER) && !defined(LINK_ALL_STATIC) && !defined(BUILDING_DTOOL_DCONFIG)
#error Buildsystem error: BUILDING_DTOOL_DCONFIG not defined
#endif
NotifyCategoryDef(dconfig, "");
NotifyCategoryDef(microconfig, "dconfig");

View File

@ -1,29 +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 config_dconfig.h
* @author drose
* @date 2000-05-15
*/
#ifndef CONFIG_DCONFIG_H
#define CONFIG_DCONFIG_H
#ifdef WIN32_VC
/* C4231: extern before template instantiation */
/* MPG - For some reason, this one only works if it's here */
#pragma warning (disable : 4231)
#endif
#include "dtoolbase.h"
#include "notifyCategoryProxy.h"
NotifyCategoryDecl(dconfig, EXPCL_DTOOL_DCONFIG, EXPTP_DTOOL_DCONFIG);
NotifyCategoryDecl(microconfig, EXPCL_DTOOL_DCONFIG, EXPTP_DTOOL_DCONFIG);
#endif

View File

@ -1,42 +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 dconfig.I
* @author cary
* @date 2000-03-20
*/
bool DConfig::
GetBool(const std::string &sym, bool def) {
ConfigVariableBool var(sym, def, "DConfig", ConfigFlags::F_dconfig);
return var.get_value();
}
int DConfig::
GetInt(const std::string &sym, int def) {
ConfigVariableInt var(sym, def, "DConfig", ConfigFlags::F_dconfig);
return var.get_value();
}
float DConfig::
GetFloat(const std::string &sym, float def) {
ConfigVariableDouble var(sym, (double)def, "DConfig", ConfigFlags::F_dconfig);
return (float)var.get_value();
}
double DConfig::
GetDouble(const std::string &sym, double def) {
ConfigVariableDouble var(sym, def, "DConfig", ConfigFlags::F_dconfig);
return var.get_value();
}
std::string DConfig::
GetString(const std::string &sym, const std::string &def) {
ConfigVariableString var(sym, def, "DConfig", ConfigFlags::F_dconfig);
return var.get_value();
}

View File

@ -1,14 +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 dconfig.cxx
* @author drose
* @date 1999-02-08
*/
#include "dconfig.h"

View File

@ -15,32 +15,7 @@
#define DCONFIG_H
#include "dtoolbase.h"
#include "config_dconfig.h"
#include "configVariableString.h"
#include "configVariableBool.h"
#include "configVariableInt.h"
#include "configVariableDouble.h"
#include "configVariableList.h"
#include "configFlags.h"
/**
* This class emulates the old dconfig-style interface to our Panda config
* system. It exists only to provide backward-compatible support, and it is
* used primarily by Python code. For modern code, use the new
* ConfigVariable* interface instead of this deprecated interface.
*/
class EXPCL_DTOOL_DCONFIG DConfig {
PUBLISHED:
static INLINE bool GetBool(const std::string &sym, bool def = false);
static INLINE int GetInt(const std::string &sym, int def = 0);
static INLINE float GetFloat(const std::string &sym, float def = 0.);
static INLINE double GetDouble(const std::string &sym, double def = 0.);
static INLINE std::string GetString(const std::string &sym, const std::string &def = "");
};
#include "dconfig.I"
#include "notifyCategoryProxy.h"
// These macros are used in each directory to call an initialization function
// at static-init time. These macros may eventually be phased out in favor of

View File

@ -1,3 +0,0 @@
#include "config_dconfig.cxx"
#include "dconfig.cxx"

View File

@ -1,35 +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 test_config.cxx
* @author cary
* @date 1998-09-10
*/
#include "dconfig.h"
using std::cout;
using std::endl;
#define SNARF
Configure(test);
std::string foo = test.GetString("user");
std::string path = test.GetString("LD_LIBRARY_PATH");
ConfigureFn(test)
{
cout << "AIEE! Doing work before main()! The sky is falling!" << endl;
}
main()
{
cout << "Testing Configuration functionality:" << endl;
cout << "foo = " << foo << endl;
cout << "path = " << path << endl;
}

View File

@ -1,87 +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 test_expand.cxx
* @author cary
* @date 1998-08-31
*/
#include "expand.h"
#include <string>
using std::cout;
using std::endl;
void TestExpandFunction()
{
std::string line;
line = "foo";
cout << "input: '" << line << "'" << endl;
cout << "output: '" << Expand::Expand(line) << "'" << endl;
line = "'foo'";
cout << "input: '" << line << "'" << endl;
cout << "output: '" << Expand::Expand(line) << "'" << endl;
line = "'$USER'";
cout << "input: '" << line << "'" << endl;
cout << "output: '" << Expand::Expand(line) << "'" << endl;
line = "$USER";
cout << "input: '" << line << "'" << endl;
cout << "output: '" << Expand::Expand(line) << "'" << endl;
line = "\"$USER\"";
cout << "input: '" << line << "'" << endl;
cout << "output: '" << Expand::Expand(line) << "'" << endl;
line = "`ls -l`";
cout << "input: '" << line << "'" << endl;
cout << "output: '" << Expand::Expand(line) << "'" << endl;
line = "~";
cout << "input: '" << line << "'" << endl;
cout << "output: '" << Expand::Expand(line) << "'" << endl;
line = "~cary";
cout << "input: '" << line << "'" << endl;
cout << "output: '" << Expand::Expand(line) << "'" << endl;
}
void TestExpandClass()
{
std::string line;
line = "foo";
Expand::Expander ex(line);
cout << "input: '" << line << "'" << endl;
cout << "output: '" << ex() << "'" << endl;
line = "'foo'";
cout << "input: '" << line << "'" << endl;
cout << "output: '" << ex(line) << "'" << endl;
line = "'$USER'";
cout << "input: '" << line << "'" << endl;
cout << "output: '" << ex(line) << "'" << endl;
line = "$USER";
cout << "input: '" << line << "'" << endl;
cout << "output: '" << ex(line) << "'" << endl;
line = "\"$USER\"";
cout << "input: '" << line << "'" << endl;
cout << "output: '" << ex(line) << "'" << endl;
line = "`ls -l`";
cout << "input: '" << line << "'" << endl;
cout << "output: '" << ex(line) << "'" << endl;
line = "~";
cout << "input: '" << line << "'" << endl;
cout << "output: '" << ex(line) << "'" << endl;
line = "~cary";
cout << "input: '" << line << "'" << endl;
cout << "output: '" << ex(line) << "'" << endl;
}
main()
{
cout << endl << "Testing shell expansion (function version):" << endl;
TestExpandFunction();
cout << endl << "Testing shell expansion (class version):" << endl;
TestExpandClass();
}

View File

@ -1,32 +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 test_pfstream.cxx
* @author cary
* @date 1998-08-31
*/
#include "pfstream.h"
#include <string>
void ReadIt(std::istream& ifs) {
std::string line;
while (!ifs.eof()) {
std::getline(ifs, line);
if (line.length() != 0)
std::cout << line << std::endl;
}
}
main()
{
IPipeStream ipfs("ls -l");
ReadIt(ipfs);
}

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 test_searchpath.cxx
* @author cary
* @date 1998-09-01
*/
#include "dSearchPath.h"
// #include "expand.h"
#include <string>
using std::cout;
using std::endl;
void TestSearch()
{
std::string line, path;
// path = ".:~ etc";
path = ". /etc";
// path = Expand::Expand(path);
line = "searchpath.h";
cout << "looking for file '" << line << "' in path '" << path << "': '";
line = DSearchPath::search_path(line, path);
cout << line << "'" << endl;
line = ".cshrc";
cout << "looking for file '" << line << "' in path '" << path << "': '";
line = DSearchPath::search_path(line, path);
cout << line << "'" << endl;
line = "passwd";
cout << "looking for file '" << line << "' in path '" << path << "': '";
line = DSearchPath::search_path(line, path);
cout << line << "'" << endl;
}
main()
{
cout << "Testing search path:" << endl;
TestSearch();
}

View File

@ -138,12 +138,10 @@
#endif
#endif
#ifdef HAVE_PYTHON
// Instead of including the Python headers, which will implicitly add a linker
// flag to link in Python, we'll just excerpt the forward declaration of
// PyObject.
typedef struct _object PyObject;
#endif
#ifndef HAVE_EIGEN
// If we don't have the Eigen library, don't define LINMATH_ALIGN.

View File

@ -153,6 +153,21 @@ deallocate_array(void *ptr) {
PANDA_FREE_ARRAY(ptr);
}
#ifdef HAVE_PYTHON
/**
* Returns the internal void pointer that is stored for interrogate's benefit.
*/
PyObject *TypeHandle::
get_python_type() const {
TypeRegistryNode *rnode = TypeRegistry::ptr()->look_up(*this, nullptr);
if (rnode != nullptr) {
return rnode->get_python_type();
} else {
return nullptr;
}
}
#endif
/**
* Return the Index of the BEst fit Classs from a set
*/

View File

@ -138,6 +138,10 @@ PUBLISHED:
MAKE_SEQ_PROPERTY(child_classes, get_num_child_classes, get_child_class);
public:
#ifdef HAVE_PYTHON
PyObject *get_python_type() const;
#endif
void *allocate_array(size_t size) RETURNS_ALIGNED(MEMORY_HOOK_ALIGNMENT);
void *reallocate_array(void *ptr, size_t size) RETURNS_ALIGNED(MEMORY_HOOK_ALIGNMENT);
void deallocate_array(void *ptr);

View File

@ -22,7 +22,8 @@
*/
TypeHandle Extension<TypeHandle>::
make(PyTypeObject *tp) {
if (!PyType_IsSubtype(tp, &Dtool_DTOOL_SUPER_BASE._PyType)) {
Dtool_PyTypedObject *super_base = Dtool_GetSuperBase();
if (!PyType_IsSubtype(tp, (PyTypeObject *)super_base)) {
PyErr_SetString(PyExc_TypeError, "a Panda type is required");
return TypeHandle::none();
}

View File

@ -207,6 +207,24 @@ record_alternate_name(TypeHandle type, const string &name) {
_lock->unlock();
}
#ifdef HAVE_PYTHON
/**
* Records the given Python type pointer in the type registry for the benefit
* of interrogate.
*/
void TypeRegistry::
record_python_type(TypeHandle type, PyObject *python_type) {
_lock->lock();
TypeRegistryNode *rnode = look_up(type, nullptr);
if (rnode != nullptr) {
rnode->_python_type = python_type;
}
_lock->unlock();
}
#endif
/**
* Looks for a previously-registered type of the given name. Returns its
* TypeHandle if it exists, or TypeHandle::none() if there is no such type.

View File

@ -45,6 +45,9 @@ PUBLISHED:
void record_derivation(TypeHandle child, TypeHandle parent);
void record_alternate_name(TypeHandle type, const std::string &name);
#ifdef HAVE_PYTHON
void record_python_type(TypeHandle type, PyObject *python_type);
#endif
TypeHandle find_type(const std::string &name) const;
TypeHandle find_type_by_id(int id) const;

View File

@ -11,6 +11,19 @@
* @date 2001-08-06
*/
/**
* Returns the Python type object associated with this node.
*/
INLINE PyObject *TypeRegistryNode::
get_python_type() const {
if (_python_type != nullptr || _parent_classes.empty()) {
return _python_type;
} else {
// Recurse through parent classes.
return r_get_python_type();
}
}
/**
*
*/

View File

@ -308,6 +308,29 @@ r_build_subtrees(TypeRegistryNode *top, int bit_count,
}
}
/**
* Recurses through the parent nodes to find the best Python type object to
* represent objects of this type.
*/
PyObject *TypeRegistryNode::
r_get_python_type() const {
Classes::const_iterator ni;
for (ni = _parent_classes.begin(); ni != _parent_classes.end(); ++ni) {
const TypeRegistryNode *parent = *ni;
if (parent->_python_type != nullptr) {
return parent->_python_type;
} else if (!parent->_parent_classes.empty()) {
PyObject *py_type = parent->r_get_python_type();
if (py_type != nullptr) {
return py_type;
}
}
}
return nullptr;
}
/**
* A recursive function to double-check the result of is_derived_from(). This
* is the slow, examine-the-whole-graph approach, as opposed to the clever and

View File

@ -37,6 +37,8 @@ public:
static TypeHandle get_parent_towards(const TypeRegistryNode *child,
const TypeRegistryNode *base);
INLINE PyObject *get_python_type() const;
void clear_subtree();
void define_subtree();
@ -46,6 +48,7 @@ public:
typedef std::vector<TypeRegistryNode *> Classes;
Classes _parent_classes;
Classes _child_classes;
PyObject *_python_type = nullptr;
AtomicAdjust::Integer _memory_usage[TypeHandle::MC_limit];
@ -77,6 +80,8 @@ private:
void r_build_subtrees(TypeRegistryNode *top,
int bit_count, SubtreeMaskType bits);
PyObject *r_get_python_type() const;
static bool check_derived_from(const TypeRegistryNode *child,
const TypeRegistryNode *base);

View File

@ -821,10 +821,54 @@ write_prototypes(ostream &out_code, ostream *out_h) {
}
}
out_code << "/**\n";
out_code << " * Declarations for exported classes\n";
out_code << " */\n";
out_code << "static const Dtool_TypeDef exports[] = {\n";
for (oi = _objects.begin(); oi != _objects.end(); ++oi) {
Object *object = (*oi).second;
if (object->_itype.is_class() || object->_itype.is_struct()) {
CPPType *type = object->_itype._cpptype;
if (isExportThisRun(type) && is_cpp_type_legal(type)) {
string class_name = type->get_local_name(&parser);
string safe_name = make_safe_name(class_name);
out_code << " {\"" << class_name << "\", &Dtool_" << safe_name << "},\n";
}
}
}
out_code << " {nullptr, nullptr},\n";
out_code << "};\n\n";
out_code << "/**\n";
out_code << " * Extern declarations for imported classes\n";
out_code << " */\n";
// Write out a table of the externally imported types that will be filled in
// upon module initialization.
if (!_external_imports.empty()) {
out_code << "#ifndef LINK_ALL_STATIC\n";
out_code << "static Dtool_TypeDef imports[] = {\n";
int idx = 0;
for (CPPType *type : _external_imports) {
string class_name = type->get_local_name(&parser);
string safe_name = make_safe_name(class_name);
out_code << " {\"" << class_name << "\", nullptr},\n";
out_code << "#define Dtool_Ptr_" << safe_name << " (imports[" << idx << "].type)\n";
++idx;
}
out_code << " {nullptr, nullptr},\n";
out_code << "};\n";
out_code << "#endif\n\n";
}
for (CPPType *type : _external_imports) {
string class_name = type->get_local_name(&parser);
string safe_name = make_safe_name(class_name);
@ -834,7 +878,9 @@ write_prototypes(ostream &out_code, ostream *out_h) {
out_code << "#ifndef LINK_ALL_STATIC\n";
// out_code << "IMPORT_THIS struct Dtool_PyTypedObject Dtool_" <<
// safe_name << ";\n";
out_code << "static struct Dtool_PyTypedObject *Dtool_Ptr_" << safe_name << ";\n";
//if (has_get_class_type_function(type)) {
// out_code << "static struct Dtool_PyTypedObject *Dtool_Ptr_" << safe_name << ";\n";
//}
// out_code << "#define Dtool_Ptr_" << safe_name << " &Dtool_" <<
// safe_name << "\n"; out_code << "IMPORT_THIS void
// Dtool_PyModuleClassInit_" << safe_name << "(PyObject *module);\n";
@ -1258,36 +1304,36 @@ write_module_support(ostream &out, ostream *out_h, InterrogateModuleDef *def) {
Objects::iterator oi;
out << "void Dtool_" << def->library_name << "_RegisterTypes() {\n";
out << "void Dtool_" << def->library_name << "_RegisterTypes() {\n"
" TypeRegistry *registry = TypeRegistry::ptr();\n"
" nassertv(registry != nullptr);\n";
for (oi = _objects.begin(); oi != _objects.end(); ++oi) {
Object *object = (*oi).second;
if (object->_itype.is_class() ||
object->_itype.is_struct()) {
if (is_cpp_type_legal(object->_itype._cpptype) &&
isExportThisRun(object->_itype._cpptype)) {
string class_name = make_safe_name(object->_itype.get_scoped_name());
bool is_typed = has_get_class_type_function(object->_itype._cpptype);
if (object->_itype.is_class() || object->_itype.is_struct()) {
CPPType *type = object->_itype._cpptype;
if (is_cpp_type_legal(type) && isExportThisRun(type)) {
string class_name = object->_itype.get_scoped_name();
string safe_name = make_safe_name(class_name);
bool is_typed = has_get_class_type_function(type);
if (is_typed) {
if (has_init_type_function(object->_itype._cpptype)) {
out << " {\n";
if (has_init_type_function(type)) {
// Call the init_type function. This isn't necessary for all
// types as many of them are automatically initialized at static
// init type, but for some extension classes it's useful.
out << " " << object->_itype._cpptype->get_local_name(&parser)
out << " " << type->get_local_name(&parser)
<< "::init_type();\n";
}
out << " Dtool_" << class_name << "._type = "
<< object->_itype._cpptype->get_local_name(&parser)
<< "::get_class_type();\n"
<< " RegisterRuntimeTypedClass(Dtool_" << class_name << ");\n";
out << " TypeHandle handle = " << type->get_local_name(&parser)
<< "::get_class_type();\n";
out << " Dtool_" << safe_name << "._type = handle;\n";
out << " registry->record_python_type(handle, "
"(PyObject *)&Dtool_" << safe_name << ");\n";
out << " }\n";
} else {
out << "#ifndef LINK_ALL_STATIC\n"
<< " RegisterNamedClass(\"" << object->_itype.get_scoped_name()
<< "\", Dtool_" << class_name << ");\n"
<< "#endif\n";
if (IsPandaTypedObject(object->_itype._cpptype->as_struct_type())) {
if (IsPandaTypedObject(type->as_struct_type())) {
nout << object->_itype.get_scoped_name() << " derives from TypedObject, "
<< "but does not define a get_class_type() function.\n";
}
@ -1297,23 +1343,6 @@ write_module_support(ostream &out, ostream *out_h, InterrogateModuleDef *def) {
}
out << "}\n\n";
out << "void Dtool_" << def->library_name << "_ResolveExternals() {\n";
out << "#ifndef LINK_ALL_STATIC\n";
out << " // Resolve externally imported types.\n";
for (CPPType *type : _external_imports) {
string class_name = type->get_local_name(&parser);
string safe_name = make_safe_name(class_name);
if (has_get_class_type_function(type)) {
out << " Dtool_Ptr_" << safe_name << " = LookupRuntimeTypedClass(" << class_name << "::get_class_type());\n";
} else {
out << " Dtool_Ptr_" << safe_name << " = LookupNamedClass(\"" << class_name << "\");\n";
}
}
out << "#endif\n";
out << "}\n\n";
out << "void Dtool_" << def->library_name << "_BuildInstants(PyObject *module) {\n";
out << " (void) module;\n";
@ -1466,9 +1495,14 @@ write_module_support(ostream &out, ostream *out_h, InterrogateModuleDef *def) {
out << " {nullptr, nullptr, 0, nullptr}\n" << "};\n\n";
out << "struct LibraryDef " << def->library_name << "_moddef = {python_simple_funcs};\n";
out << "extern const struct LibraryDef " << def->library_name << "_moddef = {python_simple_funcs, exports, ";
if (_external_imports.empty()) {
out << "nullptr};\n";
} else {
out << "imports};\n";
}
if (out_h != nullptr) {
*out_h << "extern struct LibraryDef " << def->library_name << "_moddef;\n";
*out_h << "extern const struct LibraryDef " << def->library_name << "_moddef;\n";
}
}
@ -3063,7 +3097,7 @@ write_module_class(ostream &out, Object *obj) {
out << " Dtool_" << ClassName << "._PyType.tp_bases = PyTuple_Pack(" << bases.size() << baseargs << ");\n";
} else {
out << " Dtool_" << ClassName << "._PyType.tp_base = (PyTypeObject *)&Dtool_DTOOL_SUPER_BASE;\n";
out << " Dtool_" << ClassName << "._PyType.tp_base = (PyTypeObject *)Dtool_GetSuperBase();\n";
}
int num_nested = obj->_itype.number_of_nested_types();

View File

@ -19,7 +19,6 @@
#include "pnotify.h"
#include "panda_getopt_long.h"
#include "preprocess_argv.h"
#include "pystub.h"
#include <time.h>
using std::cerr;
@ -309,8 +308,6 @@ predefine_macro(CPPParser& parser, const string& inoption) {
int
main(int argc, char **argv) {
pystub();
preprocess_argv(argc, argv);
string command_line;
int i;

View File

@ -19,7 +19,6 @@
#include "interrogate_interface.h"
#include "interrogate_request.h"
#include "load_dso.h"
#include "pystub.h"
#include "pnotify.h"
#include "panda_getopt_long.h"
#include "preprocess_argv.h"
@ -30,6 +29,9 @@
using std::cerr;
using std::string;
// This contains a big source string determined at compile time.
extern const char interrogate_preamble_python_native[];
Filename output_code_filename;
string module_name;
string library_name;
@ -286,9 +288,8 @@ int write_python_table_native(std::ostream &out) {
vector_string::const_iterator ii;
for (ii = libraries.begin(); ii != libraries.end(); ++ii) {
printf("Referencing Library %s\n", (*ii).c_str());
out << "extern LibraryDef " << *ii << "_moddef;\n";
out << "extern const struct LibraryDef " << *ii << "_moddef;\n";
out << "extern void Dtool_" << *ii << "_RegisterTypes();\n";
out << "extern void Dtool_" << *ii << "_ResolveExternals();\n";
out << "extern void Dtool_" << *ii << "_BuildInstants(PyObject *module);\n";
}
@ -339,12 +340,9 @@ int write_python_table_native(std::ostream &out) {
for (ii = libraries.begin(); ii != libraries.end(); ii++) {
out << " Dtool_" << *ii << "_RegisterTypes();\n";
}
for (ii = libraries.begin(); ii != libraries.end(); ii++) {
out << " Dtool_" << *ii << "_ResolveExternals();\n";
}
out << "\n";
out << " LibraryDef *defs[] = {";
out << " const LibraryDef *defs[] = {";
for(ii = libraries.begin(); ii != libraries.end(); ii++) {
out << "&" << *ii << "_moddef, ";
}
@ -386,12 +384,9 @@ int write_python_table_native(std::ostream &out) {
for (ii = libraries.begin(); ii != libraries.end(); ii++) {
out << " Dtool_" << *ii << "_RegisterTypes();\n";
}
for (ii = libraries.begin(); ii != libraries.end(); ii++) {
out << " Dtool_" << *ii << "_ResolveExternals();\n";
}
out << "\n";
out << " LibraryDef *defs[] = {";
out << " const LibraryDef *defs[] = {";
for(ii = libraries.begin(); ii != libraries.end(); ii++) {
out << "&" << *ii << "_moddef, ";
}
@ -545,8 +540,6 @@ int main(int argc, char *argv[]) {
extern int optind;
int flag;
pystub();
preprocess_argv(argc, argv);
flag = getopt_long_only(argc, argv, short_options, long_options, nullptr);
while (flag != EOF) {
@ -642,8 +635,10 @@ int main(int argc, char *argv[]) {
if (build_python_native_wrappers) {
write_python_table_native(output_code);
}
// Output the support code.
output_code << interrogate_preamble_python_native << "\n";
}
}
}

View File

@ -22,7 +22,6 @@
#include "cppGlobals.h"
#include "panda_getopt_long.h"
#include "preprocess_argv.h"
#include "pystub.h"
#include <stdlib.h>
using std::cerr;
@ -206,8 +205,6 @@ show_nested_types(const string &str) {
int
main(int argc, char **argv) {
pystub();
extern char *optarg;
extern int optind;
const char *optstr = "I:S:D:o:l:vp";

View File

@ -15,120 +15,132 @@
#ifdef HAVE_PYTHON
class EmptyClass {
};
Define_Module_Class_Private(dtoolconfig, DTOOL_SUPER_BASE, EmptyClass, DTOOL_SUPER_BASE111);
static PyObject *GetSuperBase(PyObject *self) {
Py_INCREF((PyTypeObject *)&Dtool_DTOOL_SUPER_BASE); // order is important .. this is used for static functions
return (PyObject *) &Dtool_DTOOL_SUPER_BASE;
Dtool_PyTypedObject *super_base = Dtool_GetSuperBase();
Py_XINCREF((PyTypeObject *)super_base); // order is important .. this is used for static functions
return (PyObject *)super_base;
};
PyMethodDef Dtool_Methods_DTOOL_SUPER_BASE[] = {
{ "DtoolGetSuperBase", (PyCFunction) &GetSuperBase, METH_NOARGS, "Will Return SUPERbase Class"},
{ nullptr, nullptr, 0, nullptr }
};
EXPCL_INTERROGATEDB void Dtool_PyModuleClassInit_DTOOL_SUPER_BASE(PyObject *module) {
static bool initdone = false;
if (!initdone) {
initdone = true;
Dtool_DTOOL_SUPER_BASE._PyType.tp_dict = PyDict_New();
PyDict_SetItemString(Dtool_DTOOL_SUPER_BASE._PyType.tp_dict, "DtoolClassDict", Dtool_DTOOL_SUPER_BASE._PyType.tp_dict);
if (PyType_Ready((PyTypeObject *)&Dtool_DTOOL_SUPER_BASE) < 0) {
PyErr_SetString(PyExc_TypeError, "PyType_Ready(Dtool_DTOOL_SUPER_BASE)");
return;
}
Py_INCREF((PyTypeObject *)&Dtool_DTOOL_SUPER_BASE);
PyDict_SetItemString(Dtool_DTOOL_SUPER_BASE._PyType.tp_dict, "DtoolGetSuperBase", PyCFunction_New(&Dtool_Methods_DTOOL_SUPER_BASE[0], (PyObject *)&Dtool_DTOOL_SUPER_BASE));
}
static void Dtool_PyModuleClassInit_DTOOL_SUPER_BASE(PyObject *module) {
if (module != nullptr) {
Py_INCREF((PyTypeObject *)&Dtool_DTOOL_SUPER_BASE);
PyModule_AddObject(module, "DTOOL_SUPER_BASE", (PyObject *)&Dtool_DTOOL_SUPER_BASE);
Dtool_PyTypedObject *super_base = Dtool_GetSuperBase();
Py_INCREF((PyTypeObject *)&super_base);
PyModule_AddObject(module, "DTOOL_SUPER_BASE", (PyObject *)&super_base);
}
}
inline void *Dtool_DowncastInterface_DTOOL_SUPER_BASE(void *from_this, Dtool_PyTypedObject *from_type) {
static void *Dtool_DowncastInterface_DTOOL_SUPER_BASE(void *from_this, Dtool_PyTypedObject *from_type) {
return nullptr;
}
inline void *Dtool_UpcastInterface_DTOOL_SUPER_BASE(PyObject *self, Dtool_PyTypedObject *requested_type) {
static void *Dtool_UpcastInterface_DTOOL_SUPER_BASE(PyObject *self, Dtool_PyTypedObject *requested_type) {
return nullptr;
}
int Dtool_Init_DTOOL_SUPER_BASE(PyObject *self, PyObject *args, PyObject *kwds) {
static int Dtool_Init_DTOOL_SUPER_BASE(PyObject *self, PyObject *args, PyObject *kwds) {
assert(self != nullptr);
PyErr_Format(PyExc_TypeError, "cannot init constant class %s", Py_TYPE(self)->tp_name);
return -1;
}
EXPORT_THIS Dtool_PyTypedObject Dtool_DTOOL_SUPER_BASE = {
{
PyVarObject_HEAD_INIT(nullptr, 0)
"dtoolconfig.DTOOL_SUPER_BASE",
sizeof(Dtool_PyInstDef),
0, // tp_itemsize
&Dtool_FreeInstance_DTOOL_SUPER_BASE,
nullptr, // tp_print
nullptr, // tp_getattr
nullptr, // tp_setattr
static void Dtool_FreeInstance_DTOOL_SUPER_BASE(PyObject *self) {
Py_TYPE(self)->tp_free(self);
}
/**
* Returns a pointer to the DTOOL_SUPER_BASE class that is the base class of
* all Panda types. This pointer is shared by all modules.
*/
Dtool_PyTypedObject *Dtool_GetSuperBase() {
Dtool_TypeMap *type_map = Dtool_GetGlobalTypeMap();
auto it = type_map->find("DTOOL_SUPER_BASE");
if (it != type_map->end()) {
return it->second;
}
static PyMethodDef methods[] = {
{ "DtoolGetSuperBase", (PyCFunction)&GetSuperBase, METH_NOARGS, "Will Return SUPERbase Class"},
{ nullptr, nullptr, 0, nullptr }
};
static Dtool_PyTypedObject super_base_type = {
{
PyVarObject_HEAD_INIT(nullptr, 0)
"dtoolconfig.DTOOL_SUPER_BASE",
sizeof(Dtool_PyInstDef),
0, // tp_itemsize
&Dtool_FreeInstance_DTOOL_SUPER_BASE,
nullptr, // tp_print
nullptr, // tp_getattr
nullptr, // tp_setattr
#if PY_MAJOR_VERSION >= 3
nullptr, // tp_compare
nullptr, // tp_compare
#else
&DtoolInstance_ComparePointers,
&DtoolInstance_ComparePointers,
#endif
nullptr, // tp_repr
nullptr, // tp_as_number
nullptr, // tp_as_sequence
nullptr, // tp_as_mapping
&DtoolInstance_HashPointer,
nullptr, // tp_call
nullptr, // tp_str
PyObject_GenericGetAttr,
PyObject_GenericSetAttr,
nullptr, // tp_as_buffer
(Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_CHECKTYPES),
nullptr, // tp_doc
nullptr, // tp_traverse
nullptr, // tp_clear
nullptr, // tp_repr
nullptr, // tp_as_number
nullptr, // tp_as_sequence
nullptr, // tp_as_mapping
&DtoolInstance_HashPointer,
nullptr, // tp_call
nullptr, // tp_str
PyObject_GenericGetAttr,
PyObject_GenericSetAttr,
nullptr, // tp_as_buffer
(Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_CHECKTYPES),
nullptr, // tp_doc
nullptr, // tp_traverse
nullptr, // tp_clear
#if PY_MAJOR_VERSION >= 3
&DtoolInstance_RichComparePointers,
&DtoolInstance_RichComparePointers,
#else
nullptr, // tp_richcompare
nullptr, // tp_richcompare
#endif
0, // tp_weaklistoffset
nullptr, // tp_iter
nullptr, // tp_iternext
Dtool_Methods_DTOOL_SUPER_BASE,
standard_type_members,
nullptr, // tp_getset
nullptr, // tp_base
nullptr, // tp_dict
nullptr, // tp_descr_get
nullptr, // tp_descr_set
0, // tp_dictoffset
Dtool_Init_DTOOL_SUPER_BASE,
PyType_GenericAlloc,
Dtool_new_DTOOL_SUPER_BASE,
PyObject_Del,
nullptr, // tp_is_gc
nullptr, // tp_bases
nullptr, // tp_mro
nullptr, // tp_cache
nullptr, // tp_subclasses
nullptr, // tp_weaklist
nullptr, // tp_del
},
TypeHandle::none(),
Dtool_PyModuleClassInit_DTOOL_SUPER_BASE,
Dtool_UpcastInterface_DTOOL_SUPER_BASE,
Dtool_DowncastInterface_DTOOL_SUPER_BASE,
nullptr,
nullptr,
};
0, // tp_weaklistoffset
nullptr, // tp_iter
nullptr, // tp_iternext
methods,
standard_type_members,
nullptr, // tp_getset
nullptr, // tp_base
nullptr, // tp_dict
nullptr, // tp_descr_get
nullptr, // tp_descr_set
0, // tp_dictoffset
Dtool_Init_DTOOL_SUPER_BASE,
PyType_GenericAlloc,
nullptr, // tp_new
PyObject_Del,
nullptr, // tp_is_gc
nullptr, // tp_bases
nullptr, // tp_mro
nullptr, // tp_cache
nullptr, // tp_subclasses
nullptr, // tp_weaklist
nullptr, // tp_del
},
TypeHandle::none(),
Dtool_PyModuleClassInit_DTOOL_SUPER_BASE,
Dtool_UpcastInterface_DTOOL_SUPER_BASE,
Dtool_DowncastInterface_DTOOL_SUPER_BASE,
nullptr,
nullptr,
};
super_base_type._PyType.tp_dict = PyDict_New();
PyDict_SetItemString(super_base_type._PyType.tp_dict, "DtoolClassDict", super_base_type._PyType.tp_dict);
if (PyType_Ready((PyTypeObject *)&super_base_type) < 0) {
PyErr_SetString(PyExc_TypeError, "PyType_Ready(Dtool_DTOOL_SUPER_BASE)");
return nullptr;
}
Py_INCREF((PyTypeObject *)&super_base_type);
PyDict_SetItemString(super_base_type._PyType.tp_dict, "DtoolGetSuperBase", PyCFunction_New(&methods[0], (PyObject *)&super_base_type));
(*type_map)["DTOOL_SUPER_BASE"] = &super_base_type;
return &super_base_type;
}
#endif // HAVE_PYTHON

View File

@ -1,5 +1,4 @@
#include "config_interrogatedb.cxx"
#include "dtool_super_base.cxx"
#include "indexRemapper.cxx"
#include "interrogateComponent.cxx"
#include "interrogateDatabase.cxx"

View File

@ -4,6 +4,3 @@
#include "interrogate_datafile.cxx"
#include "interrogate_interface.cxx"
#include "interrogate_request.cxx"
#include "py_panda.cxx"
#include "py_compat.cxx"
#include "py_wrappers.cxx"

View File

@ -1,11 +1,4 @@
/**
* 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 py_compat.cxx
* @author rdb
* @date 2017-12-03

View File

@ -1,11 +1,4 @@
/**
* 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 py_compat.h
* @author rdb
* @date 2017-12-02
@ -106,7 +99,7 @@ typedef int Py_ssize_t;
// PyInt_FromSize_t automatically picks the right type.
# define PyLongOrInt_AS_LONG PyInt_AsLong
EXPCL_INTERROGATEDB size_t PyLongOrInt_AsSize_t(PyObject *);
size_t PyLongOrInt_AsSize_t(PyObject *);
#endif
// Which character to use in PyArg_ParseTuple et al for a byte string.

View File

@ -1,11 +1,4 @@
/**
* 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 py_panda.I
* @author rdb
* @date 2016-06-06
@ -26,7 +19,7 @@
template<class T> INLINE bool
DtoolInstance_GetPointer(PyObject *self, T *&into) {
if (DtoolInstance_Check(self)) {
Dtool_PyTypedObject *target_class = Dtool_RuntimeTypeDtoolType(get_type_handle(T).get_index());
Dtool_PyTypedObject *target_class = (Dtool_PyTypedObject *)get_type_handle(T).get_python_type();
if (target_class != nullptr) {
if (_IS_FINAL(T)) {
if (DtoolInstance_TYPE(self) == target_class) {
@ -116,32 +109,44 @@ INLINE long Dtool_EnumValue_AsLong(PyObject *value) {
*/
template<class T> INLINE PyObject *
DTool_CreatePyInstance(const T *obj, bool memory_rules) {
Dtool_PyTypedObject *known_class = Dtool_RuntimeTypeDtoolType(get_type_handle(T).get_index());
Dtool_PyTypedObject *known_class = (Dtool_PyTypedObject *)get_type_handle(T).get_python_type();
nassertr(known_class != nullptr, nullptr);
return DTool_CreatePyInstance((void*) obj, *known_class, memory_rules, true);
}
template<class T> INLINE PyObject *
DTool_CreatePyInstance(T *obj, bool memory_rules) {
Dtool_PyTypedObject *known_class = Dtool_RuntimeTypeDtoolType(get_type_handle(T).get_index());
Dtool_PyTypedObject *known_class = (Dtool_PyTypedObject *)get_type_handle(T).get_python_type();
nassertr(known_class != nullptr, nullptr);
return DTool_CreatePyInstance((void*) obj, *known_class, memory_rules, false);
}
template<class T> INLINE PyObject *
DTool_CreatePyInstanceTyped(const T *obj, bool memory_rules) {
Dtool_PyTypedObject *known_class = Dtool_RuntimeTypeDtoolType(get_type_handle(T).get_index());
Dtool_PyTypedObject *known_class = (Dtool_PyTypedObject *)get_type_handle(T).get_python_type();
nassertr(known_class != nullptr, nullptr);
return DTool_CreatePyInstanceTyped((void*) obj, *known_class, memory_rules, true, obj->get_type().get_index());
}
template<class T> INLINE PyObject *
DTool_CreatePyInstanceTyped(T *obj, bool memory_rules) {
Dtool_PyTypedObject *known_class = Dtool_RuntimeTypeDtoolType(get_type_handle(T).get_index());
Dtool_PyTypedObject *known_class = (Dtool_PyTypedObject *)get_type_handle(T).get_python_type();
nassertr(known_class != nullptr, nullptr);
return DTool_CreatePyInstanceTyped((void*) obj, *known_class, memory_rules, false, obj->get_type().get_index());
}
/**
* Finishes initializing the Dtool_PyInstDef.
*/
INLINE int
DTool_PyInit_Finalize(PyObject *self, void *local_this, Dtool_PyTypedObject *type, bool memory_rules, bool is_const) {
((Dtool_PyInstDef *)self)->_My_Type = type;
((Dtool_PyInstDef *)self)->_ptr_to_object = local_this;
((Dtool_PyInstDef *)self)->_memory_rules = memory_rules;
((Dtool_PyInstDef *)self)->_is_const = is_const;
return 0;
}
/**
* Checks that the tuple is empty.
*/

View File

@ -1,11 +1,4 @@
/**
* 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 py_panda.cxx
* @author drose
* @date 2005-07-04
@ -29,10 +22,6 @@ PyMemberDef standard_type_members[] = {
{nullptr} /* Sentinel */
};
static RuntimeTypeMap runtime_type_map;
static RuntimeTypeSet runtime_type_set;
static NamedTypeMap named_type_map;
/**
*/
@ -431,7 +420,7 @@ PyObject *DTool_CreatePyInstanceTyped(void *local_this_in, Dtool_PyTypedObject &
// IF the class is possibly a run time typed object
if (type_index > 0) {
// get best fit class...
Dtool_PyTypedObject *target_class = Dtool_RuntimeTypeDtoolType(type_index);
Dtool_PyTypedObject *target_class = (Dtool_PyTypedObject *)TypeHandle::from_index(type_index).get_python_type();
if (target_class != nullptr) {
// cast to the type...
void *new_local_this = target_class->_Dtool_DowncastInterface(local_this_in, &known_class_type);
@ -484,132 +473,26 @@ PyObject *DTool_CreatePyInstance(void *local_this, Dtool_PyTypedObject &in_class
return (PyObject *)self;
}
// Th Finalizer for simple instances..
int DTool_PyInit_Finalize(PyObject *self, void *local_this, Dtool_PyTypedObject *type, bool memory_rules, bool is_const) {
// lets put some code in here that checks to see the memory is properly
// configured.. prior to my call ..
((Dtool_PyInstDef *)self)->_My_Type = type;
((Dtool_PyInstDef *)self)->_ptr_to_object = local_this;
((Dtool_PyInstDef *)self)->_memory_rules = memory_rules;
((Dtool_PyInstDef *)self)->_is_const = is_const;
return 0;
}
// A helper function to glue method definition together .. that can not be
// done at code generation time because of multiple generation passes in
// interrogate..
void Dtool_Accum_MethDefs(PyMethodDef in[], MethodDefmap &themap) {
for (; in->ml_name != nullptr; in++) {
if (themap.find(in->ml_name) == themap.end()) {
themap[in->ml_name] = in;
}
}
}
// ** HACK ** alert.. Need to keep a runtime type dictionary ... that is
// forward declared of typed object. We rely on the fact that typed objects
// are uniquly defined by an integer.
void
RegisterNamedClass(const string &name, Dtool_PyTypedObject &otype) {
std::pair<NamedTypeMap::iterator, bool> result =
named_type_map.insert(NamedTypeMap::value_type(name, &otype));
if (!result.second) {
// There was already a class with this name in the dictionary.
interrogatedb_cat.warning()
<< "Double definition for class " << name << "\n";
}
}
void
RegisterRuntimeTypedClass(Dtool_PyTypedObject &otype) {
int type_index = otype._type.get_index();
if (type_index == 0) {
interrogatedb_cat.warning()
<< "Class " << otype._PyType.tp_name
<< " has a zero TypeHandle value; check that init_type() is called.\n";
} else if (type_index < 0 || type_index >= TypeRegistry::ptr()->get_num_typehandles()) {
interrogatedb_cat.warning()
<< "Class " << otype._PyType.tp_name
<< " has an illegal TypeHandle value; check that init_type() is called.\n";
/**
* Returns a borrowed reference to the global type dictionary.
*/
Dtool_TypeMap *Dtool_GetGlobalTypeMap() {
PyObject *capsule = PySys_GetObject((char *)"_interrogate_types");
if (capsule != nullptr) {
return (Dtool_TypeMap *)PyCapsule_GetPointer(capsule, nullptr);
} else {
std::pair<RuntimeTypeMap::iterator, bool> result =
runtime_type_map.insert(RuntimeTypeMap::value_type(type_index, &otype));
if (!result.second) {
// There was already an entry in the dictionary for type_index.
Dtool_PyTypedObject *other_type = (*result.first).second;
interrogatedb_cat.warning()
<< "Classes " << otype._PyType.tp_name
<< " and " << other_type->_PyType.tp_name
<< " share the same TypeHandle value (" << type_index
<< "); check class definitions.\n";
} else {
runtime_type_set.insert(type_index);
}
Dtool_TypeMap *type_map = new Dtool_TypeMap;
capsule = PyCapsule_New((void *)type_map, nullptr, nullptr);
PySys_SetObject((char *)"_interrogate_types", capsule);
Py_DECREF(capsule);
return type_map;
}
}
Dtool_PyTypedObject *
LookupNamedClass(const string &name) {
NamedTypeMap::const_iterator it;
it = named_type_map.find(name);
if (it == named_type_map.end()) {
// Find a type named like this in the type registry.
TypeHandle handle = TypeRegistry::ptr()->find_type(name);
if (handle.get_index() > 0) {
RuntimeTypeMap::const_iterator it2;
it2 = runtime_type_map.find(handle.get_index());
if (it2 != runtime_type_map.end()) {
return it2->second;
}
}
interrogatedb_cat.error()
<< "Attempt to use type " << name << " which has not yet been defined!\n";
return nullptr;
} else {
return it->second;
}
}
Dtool_PyTypedObject *
LookupRuntimeTypedClass(TypeHandle handle) {
RuntimeTypeMap::const_iterator it;
it = runtime_type_map.find(handle.get_index());
if (it == runtime_type_map.end()) {
interrogatedb_cat.error()
<< "Attempt to use type " << handle << " which has not yet been defined!\n";
return nullptr;
} else {
return it->second;
}
}
Dtool_PyTypedObject *Dtool_RuntimeTypeDtoolType(int type) {
RuntimeTypeMap::iterator di = runtime_type_map.find(type);
if (di != runtime_type_map.end()) {
return di->second;
} else {
int type2 = get_best_parent_from_Set(type, runtime_type_set);
di = runtime_type_map.find(type2);
if (di != runtime_type_map.end()) {
return di->second;
}
}
return nullptr;
}
#if PY_MAJOR_VERSION >= 3
PyObject *Dtool_PyModuleInitHelper(LibraryDef *defs[], PyModuleDef *module_def) {
PyObject *Dtool_PyModuleInitHelper(const LibraryDef *defs[], PyModuleDef *module_def) {
#else
PyObject *Dtool_PyModuleInitHelper(LibraryDef *defs[], const char *modulename) {
PyObject *Dtool_PyModuleInitHelper(const LibraryDef *defs[], const char *modulename) {
#endif
// Check the version so we can print a helpful error if it doesn't match.
string version = Py_GetVersion();
@ -627,55 +510,46 @@ PyObject *Dtool_PyModuleInitHelper(LibraryDef *defs[], const char *modulename) {
return nullptr;
}
// Initialize the types we define in py_panda.
static bool dtool_inited = false;
if (!dtool_inited) {
dtool_inited = true;
if (PyType_Ready(&Dtool_SequenceWrapper_Type) < 0) {
return Dtool_Raise_TypeError("PyType_Ready(Dtool_SequenceWrapper)");
}
if (PyType_Ready(&Dtool_MutableSequenceWrapper_Type) < 0) {
return Dtool_Raise_TypeError("PyType_Ready(Dtool_MutableSequenceWrapper)");
}
if (PyType_Ready(&Dtool_MappingWrapper_Type) < 0) {
return Dtool_Raise_TypeError("PyType_Ready(Dtool_MappingWrapper)");
}
if (PyType_Ready(&Dtool_MutableMappingWrapper_Type) < 0) {
return Dtool_Raise_TypeError("PyType_Ready(Dtool_MutableMappingWrapper)");
}
if (PyType_Ready(&Dtool_MappingWrapper_Keys_Type) < 0) {
return Dtool_Raise_TypeError("PyType_Ready(Dtool_MappingWrapper_Keys)");
}
if (PyType_Ready(&Dtool_MappingWrapper_Values_Type) < 0) {
return Dtool_Raise_TypeError("PyType_Ready(Dtool_MappingWrapper_Values)");
}
if (PyType_Ready(&Dtool_MappingWrapper_Items_Type) < 0) {
return Dtool_Raise_TypeError("PyType_Ready(Dtool_MappingWrapper_Items)");
}
if (PyType_Ready(&Dtool_GeneratorWrapper_Type) < 0) {
return Dtool_Raise_TypeError("PyType_Ready(Dtool_GeneratorWrapper)");
}
if (PyType_Ready(&Dtool_StaticProperty_Type) < 0) {
return Dtool_Raise_TypeError("PyType_Ready(Dtool_StaticProperty_Type)");
}
// Initialize the base class of everything.
Dtool_PyModuleClassInit_DTOOL_SUPER_BASE(nullptr);
}
Dtool_TypeMap *type_map = Dtool_GetGlobalTypeMap();
// the module level function inits....
MethodDefmap functions;
for (int xx = 0; defs[xx] != nullptr; xx++) {
Dtool_Accum_MethDefs(defs[xx]->_methods, functions);
for (size_t i = 0; defs[i] != nullptr; i++) {
const LibraryDef &def = *defs[i];
// Accumulate method definitions.
for (PyMethodDef *meth = def._methods; meth->ml_name != nullptr; meth++) {
if (functions.find(meth->ml_name) == functions.end()) {
functions[meth->ml_name] = meth;
}
}
// Define exported types.
const Dtool_TypeDef *types = def._types;
if (types != nullptr) {
while (types->name != nullptr) {
(*type_map)[std::string(types->name)] = types->type;
++types;
}
}
}
// Resolve external types, in a second pass.
for (size_t i = 0; defs[i] != nullptr; i++) {
const LibraryDef &def = *defs[i];
Dtool_TypeDef *types = def._external_types;
if (types != nullptr) {
while (types->name != nullptr) {
auto it = type_map->find(std::string(types->name));
if (it != type_map->end()) {
types->type = it->second;
} else {
return PyErr_Format(PyExc_NameError, "name '%s' is not defined", types->name);
}
++types;
}
}
}
PyMethodDef *newdef = new PyMethodDef[functions.size() + 1];
@ -799,7 +673,7 @@ PyObject *Dtool_BorrowThisReference(PyObject *self, PyObject *args) {
// We do expose a dictionay for dtool classes .. this should be removed at
// some point..
EXPCL_INTERROGATEDB PyObject *Dtool_AddToDictionary(PyObject *self1, PyObject *args) {
PyObject *Dtool_AddToDictionary(PyObject *self1, PyObject *args) {
PyObject *self;
PyObject *subject;
PyObject *key;

View File

@ -1,11 +1,4 @@
/**
* 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 py_panda.h
*/
@ -43,9 +36,6 @@ using namespace std;
#endif
struct Dtool_PyTypedObject;
typedef std::map<int, Dtool_PyTypedObject *> RuntimeTypeMap;
typedef std::set<int> RuntimeTypeSet;
typedef std::map<std::string, Dtool_PyTypedObject *> NamedTypeMap;
// used to stamp dtool instance..
#define PY_PANDA_SIGNATURE 0xbeaf
@ -78,7 +68,7 @@ struct Dtool_PyInstDef {
};
// A Offset Dictionary Defining How to read the Above Object..
extern EXPCL_INTERROGATEDB PyMemberDef standard_type_members[];
extern PyMemberDef standard_type_members[];
// The Class Definition Structor For a Dtool python type.
struct Dtool_PyTypedObject {
@ -190,25 +180,21 @@ static void Dtool_FreeInstance_##CLASS_NAME(PyObject *self) {\
// forward declared of typed object. We rely on the fact that typed objects
// are uniquly defined by an integer.
EXPCL_INTERROGATEDB void RegisterNamedClass(const std::string &name, Dtool_PyTypedObject &otype);
EXPCL_INTERROGATEDB void RegisterRuntimeTypedClass(Dtool_PyTypedObject &otype);
typedef std::map<std::string, Dtool_PyTypedObject *> Dtool_TypeMap;
EXPCL_INTERROGATEDB Dtool_PyTypedObject *LookupNamedClass(const std::string &name);
EXPCL_INTERROGATEDB Dtool_PyTypedObject *LookupRuntimeTypedClass(TypeHandle handle);
EXPCL_INTERROGATEDB Dtool_PyTypedObject *Dtool_RuntimeTypeDtoolType(int type);
Dtool_TypeMap *Dtool_GetGlobalTypeMap();
/**
*/
EXPCL_INTERROGATEDB void DTOOL_Call_ExtractThisPointerForType(PyObject *self, Dtool_PyTypedObject *classdef, void **answer);
void DTOOL_Call_ExtractThisPointerForType(PyObject *self, Dtool_PyTypedObject *classdef, void **answer);
EXPCL_INTERROGATEDB void *DTOOL_Call_GetPointerThisClass(PyObject *self, Dtool_PyTypedObject *classdef, int param, const std::string &function_name, bool const_ok, bool report_errors);
void *DTOOL_Call_GetPointerThisClass(PyObject *self, Dtool_PyTypedObject *classdef, int param, const std::string &function_name, bool const_ok, bool report_errors);
EXPCL_INTERROGATEDB bool Dtool_Call_ExtractThisPointer(PyObject *self, Dtool_PyTypedObject &classdef, void **answer);
bool Dtool_Call_ExtractThisPointer(PyObject *self, Dtool_PyTypedObject &classdef, void **answer);
EXPCL_INTERROGATEDB bool Dtool_Call_ExtractThisPointer_NonConst(PyObject *self, Dtool_PyTypedObject &classdef,
void **answer, const char *method_name);
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);
@ -218,7 +204,7 @@ INLINE int DtoolInstance_ComparePointers(PyObject *v1, PyObject *v2);
INLINE PyObject *DtoolInstance_RichComparePointers(PyObject *v1, PyObject *v2, int op);
// Functions related to error reporting.
EXPCL_INTERROGATEDB bool _Dtool_CheckErrorOccurred();
bool _Dtool_CheckErrorOccurred();
#ifdef NDEBUG
#define Dtool_CheckErrorOccurred() (UNLIKELY(_PyErr_OCCURRED() != nullptr))
@ -226,12 +212,12 @@ EXPCL_INTERROGATEDB bool _Dtool_CheckErrorOccurred();
#define Dtool_CheckErrorOccurred() (UNLIKELY(_Dtool_CheckErrorOccurred()))
#endif
EXPCL_INTERROGATEDB PyObject *Dtool_Raise_AssertionError();
EXPCL_INTERROGATEDB PyObject *Dtool_Raise_TypeError(const char *message);
EXPCL_INTERROGATEDB PyObject *Dtool_Raise_ArgTypeError(PyObject *obj, int param, const char *function_name, const char *type_name);
EXPCL_INTERROGATEDB PyObject *Dtool_Raise_AttributeError(PyObject *obj, const char *attribute);
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_INTERROGATEDB PyObject *_Dtool_Raise_BadArgumentsError();
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()
@ -243,9 +229,9 @@ EXPCL_INTERROGATEDB 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.
EXPCL_INTERROGATEDB PyObject *_Dtool_Return_None();
EXPCL_INTERROGATEDB PyObject *Dtool_Return_Bool(bool value);
EXPCL_INTERROGATEDB PyObject *_Dtool_Return(PyObject *value);
PyObject *_Dtool_Return_None();
PyObject *Dtool_Return_Bool(bool value);
PyObject *_Dtool_Return(PyObject *value);
#ifdef NDEBUG
#define Dtool_Return_None() (LIKELY(_PyErr_OCCURRED() == nullptr) ? (Py_INCREF(Py_None), Py_None) : nullptr)
@ -258,19 +244,19 @@ EXPCL_INTERROGATEDB PyObject *_Dtool_Return(PyObject *value);
/**
* Wrapper around Python 3.4's enum library, which does not have a C API.
*/
EXPCL_INTERROGATEDB PyTypeObject *Dtool_EnumType_Create(const char *name, PyObject *names,
PyTypeObject *Dtool_EnumType_Create(const char *name, PyObject *names,
const char *module = nullptr);
EXPCL_INTERROGATEDB INLINE long Dtool_EnumValue_AsLong(PyObject *value);
INLINE long Dtool_EnumValue_AsLong(PyObject *value);
/**
*/
EXPCL_INTERROGATEDB PyObject *DTool_CreatePyInstanceTyped(void *local_this_in, Dtool_PyTypedObject &known_class_type, bool memory_rules, bool is_const, int RunTimeType);
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..
EXPCL_INTERROGATEDB PyObject *DTool_CreatePyInstance(void *local_this, Dtool_PyTypedObject &in_classdef, bool memory_rules, bool is_const);
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.
@ -314,43 +300,49 @@ Define_Dtool_FreeInstanceRef(CLASS_NAME,CNAME)\
Define_Dtool_Class(MODULE_NAME,CLASS_NAME,PUBLIC_NAME)
// The finalizer for simple instances.
EXPCL_INTERROGATEDB int DTool_PyInit_Finalize(PyObject *self, void *This, Dtool_PyTypedObject *type, bool memory_rules, bool is_const);
INLINE int DTool_PyInit_Finalize(PyObject *self, void *This, Dtool_PyTypedObject *type, bool memory_rules, bool is_const);
// A heler function to glu methed definition together .. that can not be done
// at code generation time becouse of multiple generation passes in
// interigate..
typedef std::map<std::string, PyMethodDef *> MethodDefmap;
EXPCL_INTERROGATEDB void Dtool_Accum_MethDefs(PyMethodDef in[], MethodDefmap &themap);
// We need a way to runtime merge compile units into a python "Module" .. this
// is done with the fallowing structors and code.. along with the support of
// interigate_module
struct Dtool_TypeDef {
const char *const name;
Dtool_PyTypedObject *type;
};
struct LibraryDef {
PyMethodDef *_methods;
PyMethodDef *const _methods;
const Dtool_TypeDef *const _types;
Dtool_TypeDef *const _external_types;
};
#if PY_MAJOR_VERSION >= 3
EXPCL_INTERROGATEDB PyObject *Dtool_PyModuleInitHelper(LibraryDef *defs[], PyModuleDef *module_def);
PyObject *Dtool_PyModuleInitHelper(const LibraryDef *defs[], PyModuleDef *module_def);
#else
EXPCL_INTERROGATEDB PyObject *Dtool_PyModuleInitHelper(LibraryDef *defs[], const char *modulename);
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"..
EXPCL_INTERROGATEDB PyObject *Dtool_BorrowThisReference(PyObject *self, PyObject *args);
PyObject *Dtool_BorrowThisReference(PyObject *self, PyObject *args);
#define DTOOL_PyObject_HashPointer DtoolInstance_HashPointer
#define DTOOL_PyObject_ComparePointers DtoolInstance_ComparePointers
EXPCL_INTERROGATEDB PyObject *
PyObject *
copy_from_make_copy(PyObject *self, PyObject *noargs);
EXPCL_INTERROGATEDB PyObject *
PyObject *
copy_from_copy_constructor(PyObject *self, PyObject *noargs);
EXPCL_INTERROGATEDB PyObject *
PyObject *
map_deepcopy_to_copy(PyObject *self, PyObject *args);
/**
@ -359,13 +351,13 @@ map_deepcopy_to_copy(PyObject *self, PyObject *args);
*/
ALWAYS_INLINE bool Dtool_CheckNoArgs(PyObject *args);
ALWAYS_INLINE bool Dtool_CheckNoArgs(PyObject *args, PyObject *kwds);
EXPCL_INTERROGATEDB bool Dtool_ExtractArg(PyObject **result, PyObject *args,
bool Dtool_ExtractArg(PyObject **result, PyObject *args,
PyObject *kwds, const char *keyword);
EXPCL_INTERROGATEDB bool Dtool_ExtractArg(PyObject **result, PyObject *args,
bool Dtool_ExtractArg(PyObject **result, PyObject *args,
PyObject *kwds);
EXPCL_INTERROGATEDB bool Dtool_ExtractOptionalArg(PyObject **result, PyObject *args,
bool Dtool_ExtractOptionalArg(PyObject **result, PyObject *args,
PyObject *kwds, const char *keyword);
EXPCL_INTERROGATEDB bool Dtool_ExtractOptionalArg(PyObject **result, PyObject *args,
bool Dtool_ExtractOptionalArg(PyObject **result, PyObject *args,
PyObject *kwds);
/**
@ -401,10 +393,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);
EXPCL_INTERROGATEDB extern struct Dtool_PyTypedObject Dtool_DTOOL_SUPER_BASE;
EXPCL_INTERROGATEDB extern void Dtool_PyModuleClassInit_DTOOL_SUPER_BASE(PyObject *module);
#define Dtool_Ptr_DTOOL_SUPER_BASE (&Dtool_DTOOL_SUPER_BASE)
Dtool_PyTypedObject *Dtool_GetSuperBase();
#include "py_panda.I"

File diff suppressed because it is too large Load Diff

View File

@ -1,11 +1,4 @@
/**
* 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 py_wrappers.h
* @author rdb
* @date 2017-11-26
@ -56,22 +49,12 @@ struct Dtool_GeneratorWrapper {
iternextfunc _iternext_func;
};
EXPCL_INTERROGATEDB extern PyTypeObject Dtool_SequenceWrapper_Type;
EXPCL_INTERROGATEDB extern PyTypeObject Dtool_MutableSequenceWrapper_Type;
EXPCL_INTERROGATEDB extern PyTypeObject Dtool_MappingWrapper_Type;
EXPCL_INTERROGATEDB extern PyTypeObject Dtool_MutableMappingWrapper_Type;
EXPCL_INTERROGATEDB extern PyTypeObject Dtool_MappingWrapper_Items_Type;
EXPCL_INTERROGATEDB extern PyTypeObject Dtool_MappingWrapper_Keys_Type;
EXPCL_INTERROGATEDB extern PyTypeObject Dtool_MappingWrapper_Values_Type;
EXPCL_INTERROGATEDB extern PyTypeObject Dtool_GeneratorWrapper_Type;
EXPCL_INTERROGATEDB extern PyTypeObject Dtool_StaticProperty_Type;
EXPCL_INTERROGATEDB Dtool_SequenceWrapper *Dtool_NewSequenceWrapper(PyObject *self, const char *name);
EXPCL_INTERROGATEDB Dtool_MutableSequenceWrapper *Dtool_NewMutableSequenceWrapper(PyObject *self, const char *name);
EXPCL_INTERROGATEDB Dtool_MappingWrapper *Dtool_NewMappingWrapper(PyObject *self, const char *name);
EXPCL_INTERROGATEDB Dtool_MappingWrapper *Dtool_NewMutableMappingWrapper(PyObject *self, const char *name);
EXPCL_INTERROGATEDB PyObject *Dtool_NewGenerator(PyObject *self, const char *name, iternextfunc func);
EXPCL_INTERROGATEDB PyObject *Dtool_NewStaticProperty(PyTypeObject *obj, const PyGetSetDef *getset);
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);
#endif // HAVE_PYTHON

View File

@ -0,0 +1,4 @@
#pragma once
class vrpn_Analog_Remote;
typedef void vrpn_ANALOGCB;

View File

@ -0,0 +1,4 @@
#pragma once
class vrpn_Button_Remote;
typedef void vrpn_BUTTONCB;

View File

@ -0,0 +1,3 @@
#pragma once
#define VRPN_CALLBACK

View File

@ -0,0 +1,3 @@
#pragma once
class vrpn_Connection;

View File

@ -0,0 +1,4 @@
#pragma once
class vrpn_Dial_Remote;
typedef void vrpn_DIALCB;

View File

@ -0,0 +1,6 @@
#pragma once
class vrpn_Tracker_Remote;
typedef void vrpn_TRACKERCB;
typedef void vrpn_TRACKERACCCB;
typedef void vrpn_TRACKERVELCB;

View File

@ -27,6 +27,8 @@ extern "C" {
EXPCL_PYSTUB int PyCFunction_New(...);
EXPCL_PYSTUB int PyCFunction_NewEx(...);
EXPCL_PYSTUB int PyCallable_Check(...);
EXPCL_PYSTUB int PyCapsule_GetPointer(...);
EXPCL_PYSTUB int PyCapsule_New(...);
EXPCL_PYSTUB int PyDict_DelItem(...);
EXPCL_PYSTUB int PyDict_DelItemString(...);
EXPCL_PYSTUB int PyDict_GetItem(...);
@ -133,6 +135,7 @@ extern "C" {
EXPCL_PYSTUB int PyString_InternInPlace(...);
EXPCL_PYSTUB int PyString_Size(...);
EXPCL_PYSTUB int PySys_GetObject(...);
EXPCL_PYSTUB int PySys_SetObject(...);
EXPCL_PYSTUB int PyThreadState_Clear(...);
EXPCL_PYSTUB int PyThreadState_Delete(...);
EXPCL_PYSTUB int PyThreadState_Get(...);
@ -216,6 +219,7 @@ extern "C" {
EXPCL_PYSTUB extern void *PyExc_ImportError;
EXPCL_PYSTUB extern void *PyExc_IndexError;
EXPCL_PYSTUB extern void *PyExc_KeyError;
EXPCL_PYSTUB extern void *PyExc_NameError;
EXPCL_PYSTUB extern void *PyExc_OSError;
EXPCL_PYSTUB extern void *PyExc_OverflowError;
EXPCL_PYSTUB extern void *PyExc_RuntimeError;
@ -257,6 +261,8 @@ int PyBytes_Size(...) { return 0; }
int PyCFunction_New(...) { return 0; };
int PyCFunction_NewEx(...) { return 0; };
int PyCallable_Check(...) { return 0; }
int PyCapsule_GetPointer(...) { return 0; }
int PyCapsule_New(...) { return 0; }
int PyDict_DelItem(...) { return 0; }
int PyDict_DelItemString(...) { return 0; }
int PyDict_GetItem(...) { return 0; }
@ -363,6 +369,7 @@ int PyString_FromStringAndSize(...) { return 0; }
int PyString_InternFromString(...) { return 0; }
int PyString_InternInPlace(...) { return 0; }
int PySys_GetObject(...) { return 0; }
int PySys_SetObject(...) { return 0; }
int PyThreadState_Clear(...) { return 0; }
int PyThreadState_Delete(...) { return 0; }
int PyThreadState_Get(...) { return 0; }
@ -452,6 +459,7 @@ void *PyExc_FutureWarning = nullptr;
void *PyExc_ImportError = nullptr;
void *PyExc_IndexError = nullptr;
void *PyExc_KeyError = nullptr;
void *PyExc_NameError = nullptr;
void *PyExc_OSError = nullptr;
void *PyExc_OverflowError = nullptr;
void *PyExc_RuntimeError = nullptr;

View File

@ -17,7 +17,6 @@
#include "interrogate_request.h"
#include "load_dso.h"
#include "filename.h"
#include "pystub.h"
#include "panda_getopt.h"
#include "preprocess_argv.h"
@ -526,8 +525,6 @@ main(int argc, char **argv) {
extern int optind;
const char *optstr = "p:ftqh";
pystub();
bool all_functions = false;
bool all_types = false;
bool quick_load = false;

View File

@ -331,13 +331,24 @@ SectionGroup "Python support"
SetOutPath $INSTDIR\panda3d
File /r "${BUILT}\panda3d\*.py"
File /r /x bullet.pyd /x ode.pyd /x physx.pyd /x rocket.pyd "${BUILT}\panda3d\*.pyd"
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}"
File /nonfatal /r "${BUILT}\panda3d\interrogatedb${EXT_SUFFIX}"
File /nonfatal /r "${BUILT}\panda3d\physics${EXT_SUFFIX}"
File /nonfatal /r "${BUILT}\panda3d\_rplight${EXT_SUFFIX}"
File /nonfatal /r "${BUILT}\panda3d\skel${EXT_SUFFIX}"
File /nonfatal /r "${BUILT}\panda3d\vision${EXT_SUFFIX}"
File /nonfatal /r "${BUILT}\panda3d\vrpn${EXT_SUFFIX}"
!ifdef HAVE_BULLET
SectionGetFlags ${SecBullet} $R0
IntOp $R0 $R0 & ${SF_SELECTED}
StrCmp $R0 ${SF_SELECTED} 0 SkipBulletPyd
File /nonfatal /r "${BUILT}\panda3d\bullet.pyd"
File /nonfatal /r "${BUILT}\panda3d\bullet${EXT_SUFFIX}"
SkipBulletPyd:
!endif
@ -345,7 +356,7 @@ SectionGroup "Python support"
SectionGetFlags ${SecODE} $R0
IntOp $R0 $R0 & ${SF_SELECTED}
StrCmp $R0 ${SF_SELECTED} 0 SkipODEPyd
File /nonfatal /r "${BUILT}\panda3d\ode.pyd"
File /nonfatal /r "${BUILT}\panda3d\ode${EXT_SUFFIX}"
SkipODEPyd:
!endif
@ -353,7 +364,7 @@ SectionGroup "Python support"
SectionGetFlags ${SecPhysX} $R0
IntOp $R0 $R0 & ${SF_SELECTED}
StrCmp $R0 ${SF_SELECTED} 0 SkipPhysXPyd
File /nonfatal /r "${BUILT}\panda3d\physx.pyd"
File /nonfatal /r "${BUILT}\panda3d\physx${EXT_SUFFIX}"
SkipPhysXPyd:
!endif
@ -361,7 +372,7 @@ SectionGroup "Python support"
SectionGetFlags ${SecRocket} $R0
IntOp $R0 $R0 & ${SF_SELECTED}
StrCmp $R0 ${SF_SELECTED} 0 SkipRocketPyd
File /nonfatal /r "${BUILT}\panda3d\rocket.pyd"
File /nonfatal /r "${BUILT}\panda3d\rocket${EXT_SUFFIX}"
SkipRocketPyd:
!endif
@ -589,7 +600,6 @@ Section "3ds Max plug-ins" SecMaxPlugins
File /nonfatal /r "${BUILT}\plugins\*.dle"
File /nonfatal /r "${BUILT}\plugins\*.dlo"
File /nonfatal /r "${BUILT}\plugins\*.ms"
File "${SOURCE}\doc\INSTALLING-PLUGINS.TXT"
SectionEnd
!endif
@ -604,7 +614,6 @@ Section "Maya plug-ins" SecMayaPlugins
SetOutPath $INSTDIR\plugins
File /nonfatal /r "${BUILT}\plugins\*.mll"
File /nonfatal /r "${BUILT}\plugins\*.mel"
File "${SOURCE}\doc\INSTALLING-PLUGINS.TXT"
SectionEnd
!endif

View File

@ -175,6 +175,7 @@ def InstallPanda(destdir="", prefix="/usr", outputdir="built", libdir=GetLibDir(
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")
if (sys.platform.startswith("freebsd")):
oscmd("mkdir -m 0755 -p "+destdir+prefix+"/etc")
@ -194,13 +195,17 @@ def InstallPanda(destdir="", prefix="/usr", outputdir="built", libdir=GetLibDir(
oscmd("cp -R "+outputdir+"/include "+destdir+prefix+"/include/panda3d")
oscmd("cp -R "+outputdir+"/pandac "+destdir+prefix+"/share/panda3d/")
oscmd("cp -R "+outputdir+"/panda3d "+destdir+PPATH+"/")
oscmd("cp -R "+outputdir+"/models "+destdir+prefix+"/share/panda3d/")
if os.path.isdir("samples"): oscmd("cp -R samples "+destdir+prefix+"/share/panda3d/")
if os.path.isdir(outputdir+"/direct"): oscmd("cp -R "+outputdir+"/direct "+destdir+prefix+"/share/panda3d/")
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)
WriteMimeFile(destdir+prefix+"/share/mime-info/panda3d.mime", MIME_INFO)
WriteKeysFile(destdir+prefix+"/share/mime-info/panda3d.keys", MIME_INFO)
WriteMimeXMLFile(destdir+prefix+"/share/mime/packages/panda3d.xml", MIME_INFO)

File diff suppressed because it is too large Load Diff

View File

@ -3190,6 +3190,48 @@ def WriteResourceFile(basename, **kwargs):
ConditionalWriteFile(basename, GenerateResourceFile(**kwargs))
return basename
def WriteEmbeddedStringFile(basename, inputs, string_name=None):
if os.path.splitext(basename)[1] not in SUFFIX_INC:
basename += '.cxx'
target = GetOutputDir() + "/tmp/" + basename
if string_name is None:
string_name = os.path.basename(os.path.splitext(target)[0])
string_name = string_name.replace('-', '_')
data = bytearray()
for input in inputs:
fp = open(input, 'rb')
# Insert a #line so that we get meaningful compile/assert errors when
# the result is inserted by interrogate_module into generated code.
if os.path.splitext(input)[1] in SUFFIX_INC:
line = '#line 1 "%s"\n' % (input)
data += bytearray(line.encode('ascii', 'replace'))
data += bytearray(fp.read())
fp.close()
data.append(0)
output = 'extern const char %s[] = {\n' % (string_name)
i = 0
for byte in data:
if i == 0:
output += ' '
output += ' 0x%02x,' % (byte)
i += 1
if i >= 12:
output += '\n'
i = 0
output += '\n};\n'
ConditionalWriteFile(target, output)
return target
########################################################################
##
## FindLocation
@ -3197,6 +3239,8 @@ def WriteResourceFile(basename, **kwargs):
########################################################################
ORIG_EXT = {}
PYABI_SPECIFIC = set()
WARNED_FILES = set()
def GetOrigExt(x):
return ORIG_EXT[x]
@ -3207,14 +3251,42 @@ def SetOrigExt(x, v):
def GetExtensionSuffix():
if sys.version_info >= (3, 0):
suffix = sysconfig.get_config_var('EXT_SUFFIX')
if suffix:
if suffix == '.so':
# On my FreeBSD system, this is not set correctly, but SOABI is.
soabi = sysconfig.get_config_var('SOABI')
if soabi:
return '.%s.so' % (soabi)
elif suffix:
return suffix
target = GetTarget()
if target == 'windows':
return '.pyd'
else:
return '.so'
def GetPythonABI():
soabi = sysconfig.get_config_var('SOABI')
if soabi:
return soabi
soabi = 'cpython-%d%d' % (sys.version_info[:2])
debug_flag = sysconfig.get_config_var('Py_DEBUG')
if (debug_flag is None and hasattr(sys, 'gettotalrefcount')) or debug_flag:
soabi += 'd'
malloc_flag = sysconfig.get_config_var('WITH_PYMALLOC')
if malloc_flag is None or malloc_flag:
soabi += 'm'
if sys.version_info < (3, 3):
usize = sysconfig.get_config_var('Py_UNICODE_SIZE')
if (usize is None and sys.maxunicode == 0x10ffff) or usize == 4:
soabi += 'u'
return soabi
def CalcLocation(fn, ipath):
if fn.startswith("panda3d/") and fn.endswith(".py"):
return OUTPUTDIR + "/" + fn
@ -3285,11 +3357,25 @@ def CalcLocation(fn, ipath):
return fn
def FindLocation(fn, ipath):
def FindLocation(fn, ipath, pyabi=None):
if (GetLinkAllStatic() and fn.endswith(".dll")):
fn = fn[:-4] + ".lib"
loc = CalcLocation(fn, ipath)
base, ext = os.path.splitext(fn)
# If this is a target created with PyTargetAdd, we need to make sure it
# it put in a Python-version-specific directory.
if loc in PYABI_SPECIFIC:
if loc.startswith(OUTPUTDIR + "/tmp"):
if pyabi is not None:
loc = OUTPUTDIR + "/tmp/" + pyabi + loc[len(OUTPUTDIR) + 4:]
else:
raise RuntimeError("%s is a Python-specific target, use PyTargetAdd instead of TargetAdd" % (fn))
elif ext != ".pyd" and loc not in WARNED_FILES:
WARNED_FILES.add(loc)
print("%sWARNING:%s file depends on Python but is not in an ABI-specific directory: %s%s%s" % (GetColor("red"), GetColor(), GetColor("green"), loc, GetColor()))
ORIG_EXT[loc] = ext
return loc
@ -3335,6 +3421,11 @@ def FindLocation(fn, ipath):
## be inserted: bison generates an OBJ and a secondary header
## file, interrogate generates an IN and a secondary IGATE.OBJ.
##
## PyTargetAdd is a special version for targets that depend on Python.
## It will create a target for each Python version we are building with,
## ensuring that builds with different Python versions won't conflict
## when we build for multiple Python ABIs side-by-side.
##
########################################################################
class Target:
@ -3343,7 +3434,7 @@ class Target:
TARGET_LIST = []
TARGET_TABLE = {}
def TargetAdd(target, dummy=0, opts=[], input=[], dep=[], ipath=None, winrc=None):
def TargetAdd(target, dummy=0, opts=[], input=[], dep=[], ipath=None, winrc=None, pyabi=None):
if (dummy != 0):
exit("Syntax error in TargetAdd "+target)
if ipath is None: ipath = opts
@ -3351,11 +3442,10 @@ def TargetAdd(target, dummy=0, opts=[], input=[], dep=[], ipath=None, winrc=None
if (type(input) == str): input = [input]
if (type(dep) == str): dep = [dep]
if os.path.splitext(target)[1] == '.pyd' and PkgSkip("PYTHON"):
# It makes no sense to build Python modules with python disabled.
return
if target.endswith(".pyd") and not pyabi:
raise RuntimeError("Use PyTargetAdd to build .pyd targets")
full = FindLocation(target, [OUTPUTDIR + "/include"])
full = FindLocation(target, [OUTPUTDIR + "/include"], pyabi=pyabi)
if (full not in TARGET_TABLE):
t = Target()
@ -3374,7 +3464,7 @@ def TargetAdd(target, dummy=0, opts=[], input=[], dep=[], ipath=None, winrc=None
ipath = [OUTPUTDIR + "/tmp"] + GetListOption(ipath, "DIR:") + [OUTPUTDIR+"/include"]
for x in input:
fullinput = FindLocation(x, ipath)
fullinput = FindLocation(x, ipath, pyabi=pyabi)
t.inputs.append(fullinput)
# Don't re-link a library or binary if just its dependency dlls have been altered.
# This should work out fine in most cases, and often reduces recompilation time.
@ -3413,7 +3503,7 @@ def TargetAdd(target, dummy=0, opts=[], input=[], dep=[], ipath=None, winrc=None
t.deps[fulln] = 1
for x in dep:
fulldep = FindLocation(x, ipath)
fulldep = FindLocation(x, ipath, pyabi=pyabi)
t.deps[fulldep] = 1
if winrc and GetTarget() == 'windows':
@ -3430,3 +3520,32 @@ def TargetAdd(target, dummy=0, opts=[], input=[], dep=[], ipath=None, winrc=None
if target.endswith(".pz") and not CrossCompiling():
t.deps[FindLocation("pzip.exe", [])] = 1
if target.endswith(".in"):
# Also add a target to compile the _igate.cxx file into an _igate.obj.
outbase = os.path.basename(target)[:-3]
woutc = OUTPUTDIR + "/tmp/" + outbase + "_igate.cxx"
CxxDependencyCache[woutc] = []
PyTargetAdd(outbase + "_igate.obj", opts=opts+['PYTHON','BIGOBJ'], input=woutc, dep=target)
def PyTargetAdd(target, opts=[], **kwargs):
if PkgSkip("PYTHON"):
return
if 'PYTHON' not in opts:
opts = opts + ['PYTHON']
abi = GetPythonABI()
MakeDirectory(OUTPUTDIR + "/tmp/" + abi)
# Mark this target as being a Python-specific target.
orig = CalcLocation(target, [OUTPUTDIR + "/include"])
PYABI_SPECIFIC.add(orig)
if orig.startswith(OUTPUTDIR + "/tmp/") and os.path.exists(orig):
print("Removing file %s" % (orig))
os.unlink(orig)
TargetAdd(target, opts=opts, pyabi=abi, **kwargs)

View File

@ -498,7 +498,7 @@ __version__ = '{0}'
for file in os.listdir(panda3d_dir):
if file == '__init__.py':
pass
elif file.endswith(ext_suffix) or file.endswith('.py'):
elif file.endswith('.py') or (file.endswith(ext_suffix) and '.' not in file[:-len(ext_suffix)]):
source_path = os.path.join(panda3d_dir, file)
if file.endswith('.pyd') and platform.startswith('cygwin'):

View File

@ -651,7 +651,7 @@ get_3d_max_distance() const {
* a balance [pan] function what is the point?
*/
PN_stdfloat FmodAudioSound::
get_speaker_mix(AudioManager::SpeakerId speaker) {
get_speaker_mix(int speaker) {
ReMutexHolder holder(FmodAudioManager::_lock);
if (_channel == 0) {
return 0.0;

View File

@ -126,7 +126,7 @@ public:
AudioSound::SoundStatus status() const;
virtual PN_stdfloat get_speaker_mix(AudioManager::SpeakerId speaker);
virtual PN_stdfloat get_speaker_mix(int speaker);
virtual void set_speaker_mix(PN_stdfloat frontleft, PN_stdfloat frontright, PN_stdfloat center, PN_stdfloat sub, PN_stdfloat backleft, PN_stdfloat backright, PN_stdfloat sideleft, PN_stdfloat sideright);
void set_active(bool active=true);

View File

@ -22,10 +22,15 @@ class CollisionEntrySorter {
public:
CollisionEntrySorter(CollisionEntry *entry) {
_entry = entry;
LVector3 vec =
entry->get_surface_point(entry->get_from_node_path()) -
entry->get_from()->get_collision_origin();
_dist2 = vec.length_squared();
if (entry->has_surface_point()) {
LVector3 vec =
entry->get_surface_point(entry->get_from_node_path()) -
entry->get_from()->get_collision_origin();
_dist2 = vec.length_squared();
}
else {
_dist2 = make_inf((PN_stdfloat)0);
}
}
bool operator < (const CollisionEntrySorter &other) const {
return _dist2 < other._dist2;

View File

@ -1,10 +0,0 @@
SETABS PANDA_VER 0.8
MODREL ETC_PATH built/etc
DOCSH if ( ! $?CFG_PATH ) then
DOCSH setenv CFG_PATH ~
DOCSH setenv CFG_PATH ". ${CFG_PATH} /usr/local/etc"
DOCSH endif
DOSH if [ -z "$CFG_PATH" ]; then
DOSH CFG_PATH=". $HOME /usr/local/etc"
DOSH export CFG_PATH
DOSH fi

View File

@ -211,7 +211,6 @@ struct DXScreenData {
bool _is_tnl_device;
bool _can_use_hw_vertex_shaders;
bool _can_use_pixel_shaders;
bool _is_dx9_1;
UINT _supported_screen_depths_mask;
UINT _supported_tex_formats_mask;
bool _supports_rgba16f_texture_format;

View File

@ -193,30 +193,10 @@ init() {
}
// Create a Direct3D object.
__d3d9 = (*_Direct3DCreate9)(D3D_SDK_VERSION);
// these were taken from the 8.0 and 8.1 d3d8.h SDK headers
__is_dx9_1 = false;
#define D3D_SDK_VERSION_9_0 D3D_SDK_VERSION
#define D3D_SDK_VERSION_9_1 D3D_SDK_VERSION
// are we using 9.0 or 9.1?
WIN32_FIND_DATA TempFindData;
HANDLE hFind;
char tmppath[_MAX_PATH + 128];
GetSystemDirectory(tmppath, MAX_PATH);
strcat(tmppath, "\\dpnhpast.dll");
hFind = FindFirstFile (tmppath, &TempFindData);
if (hFind != INVALID_HANDLE_VALUE) {
FindClose(hFind);
// ??? This was from DX8 __is_dx9_1 = true;
__d3d9 = (*_Direct3DCreate9)(D3D_SDK_VERSION_9_1);
} else {
__is_dx9_1 = false;
__d3d9 = (*_Direct3DCreate9)(D3D_SDK_VERSION_9_0);
}
if (__d3d9 == nullptr) {
wdxdisplay9_cat.error() << "Direct3DCreate9(9." << (__is_dx9_1 ? "1" : "0") << ") failed!, error = " << GetLastError() << endl;
wdxdisplay9_cat.error() << "Direct3DCreate9 failed!, error = " << GetLastError() << endl;
// release_gsg();
goto error;
}
@ -361,11 +341,13 @@ find_all_card_memavails() {
if (!ISPOW2(dwVidMemTotal)) {
// assume they wont return a proper max value, so round up to next pow
// of 2
UINT count = 0;
while ((dwVidMemTotal >> count) != 0x0) {
count++;
int count = get_next_higher_bit((uint32_t)(dwVidMemTotal - 1u));
if (count >= 32u) {
// Maximum value that fits in a UINT.
dwVidMemTotal = 0xffffffffu;
} else {
dwVidMemTotal = (1u << count);
}
dwVidMemTotal = (1 << count);
}
}

View File

@ -93,7 +93,6 @@ private:
typedef pvector<CardID> CardIDs;
CardIDs _card_ids;
bool __is_dx9_1;
public:
static TypeHandle get_class_type() {

View File

@ -878,7 +878,7 @@ choose_device() {
LARGE_INTEGER *DrvVer = &adapter_info.DriverVersion;
wdxdisplay9_cat.info()
<< "D3D9." << (dxpipe->__is_dx9_1 ?"1":"0") << " Adapter[" << i << "]: " << adapter_info.Description
<< "D3D9 Adapter[" << i << "]: " << adapter_info.Description
<< ", Driver: " << adapter_info.Driver << ", DriverVersion: ("
<< HIWORD(DrvVer->HighPart) << "." << LOWORD(DrvVer->HighPart) << "."
<< HIWORD(DrvVer->LowPart) << "." << LOWORD(DrvVer->LowPart)
@ -979,7 +979,6 @@ consider_device(wdxGraphicsPipe9 *dxpipe, DXDeviceInfo *device_info) {
nassertr(_dxgsg != nullptr, false);
_wcontext._d3d9 = _d3d9;
_wcontext._is_dx9_1 = dxpipe->__is_dx9_1;
_wcontext._card_id = device_info->cardID; // could this change by end?
bool bWantStencil = (_fb_properties.get_stencil_bits() > 0);

View File

@ -168,14 +168,7 @@ static PyObject *gen_next(PyObject *self) {
*/
PyObject *Extension<AsyncFuture>::
__await__(PyObject *self) {
Dtool_GeneratorWrapper *gen;
gen = (Dtool_GeneratorWrapper *)PyType_GenericAlloc(&Dtool_GeneratorWrapper_Type, 0);
if (gen != nullptr) {
Py_INCREF(self);
gen->_base._self = self;
gen->_iternext_func = &gen_next;
}
return (PyObject *)gen;
return Dtool_NewGenerator(self, &gen_next);
}
/**

View File

@ -16,7 +16,7 @@
#include "extension.h"
#include "py_panda.h"
#include "modelLoadRequest.h"
#include "asyncFuture.h"
#ifdef HAVE_PYTHON

View File

@ -190,11 +190,3 @@ get_verify_dcast() {
return *verify_dcast;
}
// Returns the configure object for accessing config variables from a
// scripting language.
DConfig &
get_config_express() {
static DConfig config_express;
return config_express;
}

View File

@ -54,11 +54,6 @@ extern ConfigVariableBool multifile_always_binary;
extern EXPCL_PANDA_EXPRESS ConfigVariableBool collect_tcp;
extern EXPCL_PANDA_EXPRESS ConfigVariableDouble collect_tcp_interval;
// Expose the Config variable for Python access.
BEGIN_PUBLISH
EXPCL_PANDA_EXPRESS DConfig &get_config_express();
END_PUBLISH
extern EXPCL_PANDA_EXPRESS void init_libexpress();
#endif /* __CONFIG_UTIL_H__ */

View File

@ -22,6 +22,8 @@
#include "dSearchPath.h"
#include "dcast.h"
#include "config_express.h"
#include "configVariableList.h"
#include "configVariableString.h"
#include "executionEnvironment.h"
#include "pset.h"

View File

@ -1145,6 +1145,78 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
}
return;
}
if (size > 4 && noprefix.substr(0, 4) == "Fog.") {
Shader::ShaderMatSpec bind;
bind._id = arg_id;
bind._func = Shader::SMF_first;
bind._arg[0] = nullptr;
bind._dep[0] = Shader::SSD_general | Shader::SSD_fog;
bind._part[1] = Shader::SMO_identity;
bind._arg[1] = nullptr;
bind._dep[1] = Shader::SSD_NONE;
if (noprefix == "Fog.color") {
bind._part[0] = Shader::SMO_attr_fogcolor;
if (param_type == GL_FLOAT_VEC3) {
bind._piece = Shader::SMP_row3x3;
} else if (param_type == GL_FLOAT_VEC4) {
bind._piece = Shader::SMP_row3;
} else {
GLCAT.error()
<< "p3d_Fog.color should be vec3 or vec4\n";
return;
}
} else if (noprefix == "Fog.density") {
bind._part[0] = Shader::SMO_attr_fog;
if (param_type == GL_FLOAT) {
bind._piece = Shader::SMP_row3x1;
} else {
GLCAT.error()
<< "p3d_Fog.density should be float\n";
return;
}
} else if (noprefix == "Fog.start") {
bind._part[0] = Shader::SMO_attr_fog;
if (param_type == GL_FLOAT) {
bind._piece = Shader::SMP_cell13;
} else {
GLCAT.error()
<< "p3d_Fog.start should be float\n";
return;
}
} else if (noprefix == "Fog.end") {
bind._part[0] = Shader::SMO_attr_fog;
if (param_type == GL_FLOAT) {
bind._piece = Shader::SMP_cell14;
} else {
GLCAT.error()
<< "p3d_Fog.end should be float\n";
return;
}
} else if (noprefix == "Fog.scale") {
bind._part[0] = Shader::SMO_attr_fog;
if (param_type == GL_FLOAT) {
bind._piece = Shader::SMP_cell15;
} else {
GLCAT.error()
<< "p3d_Fog.scale should be float\n";
return;
}
}
_shader->_mat_spec.push_back(bind);
_shader->_mat_deps |= bind._dep[0];
return;
}
if (noprefix == "LightModel.ambient") {
Shader::ShaderMatSpec bind;
bind._id = arg_id;

View File

@ -96,11 +96,7 @@ PUBLISHED:
#ifdef HAVE_PYTHON
// These versions are exposed to Python, which have additional logic to map
// from Python interned strings.
#if PY_MAJOR_VERSION >= 3
EXTENSION(static PT(InternalName) make(PyUnicodeObject *str));
#else
EXTENSION(static PT(InternalName) make(PyStringObject *str));
#endif
EXTENSION(static PT(InternalName) make(PyObject *str));
#endif
public:

View File

@ -24,7 +24,12 @@ using std::string;
*/
#if PY_MAJOR_VERSION >= 3
PT(InternalName) Extension<InternalName>::
make(PyUnicodeObject *str) {
make(PyObject *str) {
if (!PyUnicode_Check(str)) {
Dtool_Raise_ArgTypeError(str, 0, "InternalName.make", "str");
return nullptr;
}
if (!PyUnicode_CHECK_INTERNED(str)) {
// Not an interned string; don't bother.
Py_ssize_t len = 0;
@ -50,7 +55,12 @@ make(PyUnicodeObject *str) {
#else
PT(InternalName) Extension<InternalName>::
make(PyStringObject *str) {
make(PyObject *str) {
if (!PyString_Check(str)) {
Dtool_Raise_ArgTypeError(str, 0, "InternalName.make", "str");
return nullptr;
}
if (!PyString_CHECK_INTERNED(str)) {
// Not an interned string; don't bother.
string name(PyString_AS_STRING(str), PyString_GET_SIZE(str));

View File

@ -29,11 +29,7 @@
template<>
class Extension<InternalName> : public ExtensionBase<InternalName> {
public:
#if PY_MAJOR_VERSION >= 3
static PT(InternalName) make(PyUnicodeObject *str);
#else
static PT(InternalName) make(PyStringObject *str);
#endif
static PT(InternalName) make(PyObject *str);
};
#endif // HAVE_PYTHON

View File

@ -2468,6 +2468,96 @@ read(const ShaderFile &sfile, BamCacheRecord *record) {
return true;
}
/**
* Loads the shader from the given string(s). Returns a boolean indicating
* success or failure.
*/
bool Shader::
load(const ShaderFile &sbody, BamCacheRecord *record) {
_filename = ShaderFile("created-shader");
_fullpath = Filename();
_text._separate = sbody._separate;
if (sbody._separate) {
if (_language == SL_none) {
shader_cat.error()
<< "No shader language was specified!\n";
return false;
}
if (!sbody._vertex.empty() &&
!do_load_source(_text._vertex, sbody._vertex, record)) {
return false;
}
if (!sbody._fragment.empty() &&
!do_load_source(_text._fragment, sbody._fragment, record)) {
return false;
}
if (!sbody._geometry.empty() &&
!do_load_source(_text._geometry, sbody._geometry, record)) {
return false;
}
if (!sbody._tess_control.empty() &&
!do_load_source(_text._tess_control, sbody._tess_control, record)) {
return false;
}
if (!sbody._tess_evaluation.empty() &&
!do_load_source(_text._tess_evaluation, sbody._tess_evaluation, record)) {
return false;
}
if (!sbody._compute.empty() &&
!do_load_source(_text._compute, sbody._compute, record)) {
return false;
}
} else {
if (!do_load_source(_text._shared, sbody._shared, record)) {
return false;
}
// Determine which language the shader is written in.
if (_language == SL_none) {
string header;
parse_init();
parse_line(header, true, true);
if (header == "//Cg") {
_language = SL_Cg;
} else {
shader_cat.error()
<< "Unable to determine shader language of " << sbody._shared << "\n";
return false;
}
} else if (_language == SL_GLSL) {
shader_cat.error()
<< "GLSL shaders must have separate shader bodies!\n";
return false;
}
// Determine which language the shader is written in.
if (_language == SL_Cg) {
#ifdef HAVE_CG
cg_get_profile_from_header(_default_caps);
if (!cg_analyze_shader(_default_caps)) {
shader_cat.error()
<< "Shader encountered an error.\n";
return false;
}
#else
shader_cat.error()
<< "Tried to load Cg shader, but no Cg support is enabled.\n";
#endif
} else {
shader_cat.error()
<< "Shader is not in a supported shader-language.\n";
return false;
}
}
_loaded = true;
return true;
}
/**
* Reads the shader file from the given path into the given string.
*
@ -2476,37 +2566,85 @@ read(const ShaderFile &sfile, BamCacheRecord *record) {
*/
bool Shader::
do_read_source(string &into, const Filename &fn, BamCacheRecord *record) {
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
PT(VirtualFile) vf = vfs->find_file(fn, get_model_path());
if (vf == nullptr) {
shader_cat.error()
<< "Could not find shader file: " << fn << "\n";
return false;
}
if (_language == SL_GLSL && glsl_preprocess) {
// Preprocess the GLSL file as we read it.
std::set<Filename> open_files;
ostringstream sstr;
if (!r_preprocess_source(sstr, fn, Filename(), open_files, record)) {
istream *source = vf->open_read_file(true);
if (source == nullptr) {
shader_cat.error()
<< "Could not open shader file: " << fn << "\n";
return false;
}
// Preprocess the GLSL file as we read it.
shader_cat.info()
<< "Preprocessing shader file: " << fn << "\n";
std::set<Filename> open_files;
ostringstream sstr;
if (!r_preprocess_source(sstr, *source, fn, vf->get_filename(), open_files, record)) {
vf->close_read_file(source);
return false;
}
vf->close_read_file(source);
into = sstr.str();
} else {
shader_cat.info() << "Reading shader file: " << fn << "\n";
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
PT(VirtualFile) vf = vfs->find_file(fn, get_model_path());
if (vf == nullptr) {
shader_cat.error()
<< "Could not find shader file: " << fn << "\n";
return false;
}
if (!vf->read_file(into, true)) {
shader_cat.error()
<< "Could not read shader file: " << fn << "\n";
return false;
}
}
if (record != nullptr) {
record->add_dependent_file(vf);
if (record != nullptr) {
record->add_dependent_file(vf);
}
_last_modified = std::max(_last_modified, vf->get_timestamp());
_source_files.push_back(vf->get_filename());
// Strip trailing whitespace.
while (!into.empty() && isspace(into[into.size() - 1])) {
into.resize(into.size() - 1);
}
// Except add back a newline at the end, which is needed by Intel drivers.
into += "\n";
return true;
}
/**
* Loads the shader file from the given string into the given string,
* performing any pre-processing on it that may be necessary.
*
* Returns false if there was an error with this shader bad enough to consider
* it 'invalid'.
*/
bool Shader::
do_load_source(string &into, const std::string &source, BamCacheRecord *record) {
if (_language == SL_GLSL && glsl_preprocess) {
// Preprocess the GLSL file as we read it.
std::set<Filename> open_files;
std::ostringstream sstr;
std::istringstream in(source);
if (!r_preprocess_source(sstr, in, Filename("created-shader"), Filename(),
open_files, record)) {
return false;
}
_last_modified = std::max(_last_modified, vf->get_timestamp());
_source_files.push_back(vf->get_filename());
into = sstr.str();
} else {
into = source;
}
// Strip trailing whitespace.
@ -2528,10 +2666,10 @@ do_read_source(string &into, const Filename &fn, BamCacheRecord *record) {
* recursive includes.
*/
bool Shader::
r_preprocess_source(ostream &out, const Filename &fn,
const Filename &source_dir,
std::set<Filename> &once_files,
BamCacheRecord *record, int depth) {
r_preprocess_include(ostream &out, const Filename &fn,
const Filename &source_dir,
std::set<Filename> &once_files,
BamCacheRecord *record, int depth) {
if (depth > glsl_include_recursion_limit) {
shader_cat.error()
@ -2549,7 +2687,7 @@ r_preprocess_source(ostream &out, const Filename &fn,
PT(VirtualFile) vf = vfs->find_file(fn, path);
if (vf == nullptr) {
shader_cat.error()
<< "Could not find shader file: " << fn << "\n";
<< "Could not find shader include: " << fn << "\n";
return false;
}
@ -2562,7 +2700,7 @@ r_preprocess_source(ostream &out, const Filename &fn,
istream *source = vf->open_read_file(true);
if (source == nullptr) {
shader_cat.error()
<< "Could not open shader file: " << fn << "\n";
<< "Could not open shader include: " << fn << "\n";
return false;
}
@ -2578,34 +2716,52 @@ r_preprocess_source(ostream &out, const Filename &fn,
// than that, unfortunately. Don't do this for the top-level file, though.
// We don't want anything to get in before a potential #version directive.
int fileno = 0;
if (depth > 0) {
fileno = 2048 + _included_files.size();
// Write it into the vector so that we can substitute it later when we are
// parsing the GLSL error log. Don't store the full filename because it
// would just be too long to display.
_included_files.push_back(fn);
fileno = 2048 + _included_files.size();
out << "#line 1 " << fileno << " // " << fn << "\n";
if (shader_cat.is_debug()) {
shader_cat.debug()
<< "Preprocessing shader include " << fileno << ": " << fn << "\n";
}
} else {
shader_cat.info()
<< "Preprocessing shader file: " << fn << "\n";
// Write it into the vector so that we can substitute it later when we are
// parsing the GLSL error log. Don't store the full filename because it
// would just be too long to display.
_included_files.push_back(fn);
if (shader_cat.is_debug()) {
shader_cat.debug()
<< "Preprocessing shader include " << fileno << ": " << fn << "\n";
}
bool result = r_preprocess_source(out, *source, fn, full_fn, once_files, record, fileno, depth);
vf->close_read_file(source);
return result;
}
/**
* Loads a given GLSL stream line by line, processing any #pragma include and
* once statements, as well as removing any comments.
*
* The set keeps track of which files we have already included, for checking
* recursive includes.
*/
bool Shader::
r_preprocess_source(ostream &out, istream &in, const Filename &fn,
const Filename &full_fn, std::set<Filename> &once_files,
BamCacheRecord *record, int fileno, int depth) {
// Iterate over the lines for things we may need to preprocess.
string line;
int ext_google_include = 0; // 1 = warn, 2 = enable
int ext_google_line = 0;
bool had_include = false;
int lineno = 0;
while (std::getline(*source, line)) {
bool write_line_directive = (fileno != 0);
while (std::getline(in, line)) {
++lineno;
if (line.empty()) {
out.put('\n');
// We still write a newline to make sure the line numbering remains
// consistent, unless we are about to write a #line directive anyway.
if (!write_line_directive) {
out.put('\n');
}
continue;
}
@ -2615,9 +2771,11 @@ r_preprocess_source(ostream &out, const Filename &fn,
line.resize(line.size() - 1);
string line2;
if (std::getline(*source, line2)) {
if (std::getline(in, line2)) {
line += line2;
out.put('\n');
if (!write_line_directive) {
out.put('\n');
}
++lineno;
} else {
break;
@ -2644,8 +2802,10 @@ r_preprocess_source(ostream &out, const Filename &fn,
size_t block_end = line2.find("*/");
while (block_end == string::npos) {
// Didn't find it - look in the next line.
if (std::getline(*source, line2)) {
out.put('\n');
if (std::getline(in, line2)) {
if (!write_line_directive) {
out.put('\n');
}
++lineno;
block_end = line2.find("*/");
} else {
@ -2663,10 +2823,21 @@ r_preprocess_source(ostream &out, const Filename &fn,
line.resize(line.size() - 1);
}
if (line.empty()) {
if (!write_line_directive) {
out.put('\n');
}
continue;
}
// Check if this line contains a #directive.
char directive[64];
if (line.size() < 8 || sscanf(line.c_str(), " # %63s", directive) != 1) {
// Nope. Just pass the line through unmodified.
if (write_line_directive) {
out << "#line " << lineno << " " << fileno << " // " << fn << "\n";
write_line_directive = false;
}
out << line << "\n";
continue;
}
@ -2703,7 +2874,7 @@ r_preprocess_source(ostream &out, const Filename &fn,
}
// OK, great. Process the include.
if (!r_preprocess_source(out, incfn, source_dir, once_files, record, depth + 1)) {
if (!r_preprocess_include(out, incfn, source_dir, once_files, record, depth + 1)) {
// An error occurred. Pass on the failure.
shader_cat.error(false) << "included at line "
<< lineno << " of file " << fn << ":\n " << line << "\n";
@ -2711,8 +2882,9 @@ r_preprocess_source(ostream &out, const Filename &fn,
}
// Restore the line counter.
out << "#line " << (lineno + 1) << " " << fileno << " // " << fn << "\n";
write_line_directive = true;
had_include = true;
continue;
} else if (strcmp(pragma, "once") == 0) {
// Do a stricter syntax check, just to be extra safe.
@ -2724,26 +2896,35 @@ r_preprocess_source(ostream &out, const Filename &fn,
return false;
}
once_files.insert(full_fn);
if (fileno == 0) {
shader_cat.warning()
<< "#pragma once in main file at line "
<< lineno << " of file " << fn
#ifndef NDEBUG
<< ":\n " << line
#endif
<< "\n";
}
} else {
// Forward it, the driver will ignore it if it doesn't know it.
out << line << "\n";
if (!full_fn.empty()) {
once_files.insert(full_fn);
}
continue;
}
// Otherwise, just pass it through to the driver.
} else if (strcmp(directive, "endif") == 0) {
// Check for an #endif after an include. We have to restore the line
// number in case the include happened under an #if block.
out << line << "\n";
if (had_include) {
out << "#line " << (lineno + 1) << " " << fileno << "\n";
write_line_directive = true;
}
} else if (strcmp(directive, "extension") == 0) {
// Check for special preprocessing extensions.
char extension[256];
char behavior[9];
if (sscanf(line.c_str(), " # extension%*[ \t]%255s%*[ \t]:%*[ \t]%8s", extension, behavior) == 2) {
if (sscanf(line.c_str(), " # extension%*[ \t]%255[^: \t] : %8s", extension, behavior) == 2) {
// Parse the behavior string.
int mode;
if (strcmp(behavior, "require") == 0 || strcmp(behavior, "enable") == 0) {
@ -2769,7 +2950,8 @@ r_preprocess_source(ostream &out, const Filename &fn,
}
ext_google_include = mode;
ext_google_line = mode;
out << line << "\n";
// Still pass it through to the driver, so it can enable other
// extensions.
} else if (strcmp(extension, "GL_GOOGLE_include_directive") == 0) {
// Enable the Google extension support for #include statements.
@ -2777,14 +2959,12 @@ r_preprocess_source(ostream &out, const Filename &fn,
// This matches the behavior of Khronos' glslang reference compiler.
ext_google_include = mode;
ext_google_line = mode;
continue;
} else if (strcmp(extension, "GL_GOOGLE_cpp_style_line_directive") == 0) {
// Enables strings in #line statements.
ext_google_line = mode;
} else {
// It's an extension the driver should worry about.
out << line << "\n";
continue;
}
} else {
shader_cat.error()
@ -2792,6 +2972,7 @@ r_preprocess_source(ostream &out, const Filename &fn,
<< lineno << " of file " << fn << ":\n " << line << "\n";
return false;
}
} else if (ext_google_include > 0 && strcmp(directive, "include") == 0) {
// Warn about extension use if requested.
if (ext_google_include == 1) {
@ -2821,7 +3002,7 @@ r_preprocess_source(ostream &out, const Filename &fn,
// OK, great. Process the include.
Filename source_dir = full_fn.get_dirname();
if (!r_preprocess_source(out, incfn, source_dir, once_files, record, depth + 1)) {
if (!r_preprocess_include(out, incfn, source_dir, once_files, record, depth + 1)) {
// An error occurred. Pass on the failure.
shader_cat.error(false) << "included at line "
<< lineno << " of file " << fn << ":\n " << line << "\n";
@ -2829,8 +3010,9 @@ r_preprocess_source(ostream &out, const Filename &fn,
}
// Restore the line counter.
out << "#line " << (lineno + 1) << " " << fileno << " // " << fn << "\n";
write_line_directive = true;
had_include = true;
continue;
} else if (ext_google_line > 0 && strcmp(directive, "line") == 0) {
// It's a #line directive. See if it uses a string instead of number.
@ -2854,18 +3036,17 @@ r_preprocess_source(ostream &out, const Filename &fn,
_included_files.push_back(Filename(filestr));
out << "#line " << lineno << " " << fileno << " // " << filestr << "\n";
} else {
// We couldn't parse the #line directive. Pass it through unmodified.
out << line << "\n";
continue;
}
} else {
// Different directive (eg. #version). Leave it untouched.
out << line << "\n";
}
if (write_line_directive) {
out << "#line " << lineno << " " << fileno << " // " << fn << "\n";
write_line_directive = false;
}
out << line << "\n";
}
vf->close_read_file(source);
return true;
}
@ -3227,28 +3408,26 @@ make(string body, ShaderLanguage lang) {
if (cache_generated_shaders) {
ShaderTable::const_iterator i = _make_table.find(sbody);
if (i != _make_table.end() && (lang == SL_none || lang == i->second->_language)) {
return i->second;
// But check that someone hasn't modified its includes in the meantime.
if (!i->second->check_modified()) {
return i->second;
}
}
}
PT(Shader) shader = new Shader(lang);
shader->_filename = ShaderFile("created-shader");
shader->_text = move(sbody);
#ifdef HAVE_CG
if (lang == SL_Cg) {
shader->cg_get_profile_from_header(_default_caps);
if (!shader->cg_analyze_shader(_default_caps)) {
shader_cat.error()
<< "Shader encountered an error.\n";
return nullptr;
}
if (!shader->load(sbody)) {
return nullptr;
}
#endif
if (cache_generated_shaders) {
_make_table[shader->_text] = shader;
ShaderTable::const_iterator i = _make_table.find(shader->_text);
if (i != _make_table.end() && (lang == SL_none || lang == i->second->_language)) {
shader = i->second;
} else {
_make_table[shader->_text] = shader;
}
_make_table[std::move(sbody)] = shader;
}
if (dump_generated_shaders) {
@ -3290,26 +3469,27 @@ make(ShaderLanguage lang, string vertex, string fragment, string geometry,
if (cache_generated_shaders) {
ShaderTable::const_iterator i = _make_table.find(sbody);
if (i != _make_table.end() && (lang == SL_none || lang == i->second->_language)) {
return i->second;
// But check that someone hasn't modified its includes in the meantime.
if (!i->second->check_modified()) {
return i->second;
}
}
}
PT(Shader) shader = new Shader(lang);
shader->_filename = ShaderFile("created-shader");
shader->_text = move(sbody);
#ifdef HAVE_CG
if (lang == SL_Cg) {
if (!shader->cg_analyze_shader(_default_caps)) {
shader_cat.error()
<< "Shader encountered an error.\n";
return nullptr;
}
if (!shader->load(sbody)) {
return nullptr;
}
#endif
if (cache_generated_shaders) {
_make_table[shader->_text] = shader;
ShaderTable::const_iterator i = _make_table.find(shader->_text);
if (i != _make_table.end() && (lang == SL_none || lang == i->second->_language)) {
shader = i->second;
} else {
_make_table[shader->_text] = shader;
}
_make_table[std::move(sbody)] = shader;
}
return shader;
@ -3333,16 +3513,27 @@ make_compute(ShaderLanguage lang, string body) {
if (cache_generated_shaders) {
ShaderTable::const_iterator i = _make_table.find(sbody);
if (i != _make_table.end() && (lang == SL_none || lang == i->second->_language)) {
return i->second;
// But check that someone hasn't modified its includes in the meantime.
if (!i->second->check_modified()) {
return i->second;
}
}
}
PT(Shader) shader = new Shader(lang);
shader->_filename = ShaderFile("created-shader");
shader->_text = move(sbody);
if (!shader->load(sbody)) {
return nullptr;
}
if (cache_generated_shaders) {
_make_table[shader->_text] = shader;
ShaderTable::const_iterator i = _make_table.find(shader->_text);
if (i != _make_table.end() && (lang == SL_none || lang == i->second->_language)) {
shader = i->second;
} else {
_make_table[shader->_text] = shader;
}
_make_table[std::move(sbody)] = shader;
}
return shader;

View File

@ -616,11 +616,18 @@ private:
Shader(ShaderLanguage lang);
bool read(const ShaderFile &sfile, BamCacheRecord *record = nullptr);
bool load(const ShaderFile &sbody, BamCacheRecord *record = nullptr);
bool do_read_source(std::string &into, const Filename &fn, BamCacheRecord *record);
bool r_preprocess_source(std::ostream &out, const Filename &fn,
const Filename &source_dir,
bool do_load_source(std::string &into, const std::string &source, BamCacheRecord *record);
bool r_preprocess_include(std::ostream &out, const Filename &fn,
const Filename &source_dir,
std::set<Filename> &open_files,
BamCacheRecord *record, int depth);
bool r_preprocess_source(std::ostream &out, std::istream &in,
const Filename &fn, const Filename &full_fn,
std::set<Filename> &open_files,
BamCacheRecord *record, int depth = 0);
BamCacheRecord *record,
int fileno = 0, int depth = 0);
bool check_modified() const;

View File

@ -89,12 +89,10 @@ set_data(void *data) {
dBodySetData(_id, data);
}
#ifndef HAVE_PYTHON
INLINE void* OdeBody::
INLINE void *OdeBody::
get_data() const {
return dBodyGetData(_id);
}
#endif
INLINE void OdeBody::
set_position(dReal x, dReal y, dReal z) {

View File

@ -15,10 +15,6 @@
#include "odeBody.h"
#include "odeJoint.h"
#ifdef HAVE_PYTHON
#include "py_panda.h"
#endif
TypeHandle OdeBody::_type_handle;
OdeBody::
@ -38,29 +34,14 @@ OdeBody::
void OdeBody::
destroy() {
#ifdef HAVE_PYTHON
Py_XDECREF((PyObject*) dBodyGetData(_id));
#endif
if (_destroy_callback != nullptr) {
_destroy_callback(*this);
_destroy_callback = nullptr;
}
nassertv(_id);
dBodyDestroy(_id);
}
#ifdef HAVE_PYTHON
void OdeBody::
set_data(PyObject *data) {
Py_XDECREF((PyObject*) dBodyGetData(_id));
Py_XINCREF(data);
dBodySetData(_id, data);
}
PyObject* OdeBody::
get_data() const {
PyObject* data = (PyObject*) dBodyGetData(_id);
Py_XINCREF(data);
return data;
}
#endif
OdeJoint OdeBody::
get_joint(int index) const {
nassertr(_id != nullptr, OdeJoint(nullptr));

View File

@ -51,9 +51,7 @@ PUBLISHED:
INLINE void set_auto_disable_flag(int do_auto_disable);
INLINE void set_auto_disable_defaults();
INLINE void set_data(void *data);
#ifdef HAVE_PYTHON
void set_data(PyObject *data);
#endif
EXTENSION(void set_data(PyObject *data));
INLINE void set_position(dReal x, dReal y, dReal z);
INLINE void set_position(const LVecBase3f &pos);
@ -71,11 +69,10 @@ PUBLISHED:
INLINE int get_auto_disable_steps() const;
INLINE dReal get_auto_disable_time() const;
INLINE int get_auto_disable_flag() const;
#ifdef HAVE_PYTHON
PyObject* get_data() const;
#else
INLINE void* get_data() const;
#ifndef CPPPARSER
INLINE void *get_data() const;
#endif
EXTENSION(PyObject *get_data() const);
INLINE LVecBase3f get_position() const;
INLINE LMatrix3f get_rotation() const;
@ -150,6 +147,10 @@ PUBLISHED:
private:
dBodyID _id;
public:
typedef void (*DestroyCallback)(OdeBody &body);
DestroyCallback _destroy_callback = nullptr;
public:
static TypeHandle get_class_type() {
return _type_handle;

View File

@ -13,6 +13,19 @@
#include "odeJoint_ext.h"
/**
* Returns the custom data associated with the OdeBody.
*/
INLINE PyObject *Extension<OdeBody>::
get_data() const {
PyObject *data = (PyObject *)_this->get_data();
if (data == nullptr) {
data = Py_None;
}
Py_INCREF(data);
return data;
}
/**
* Equivalent to get_joint().convert()
*/

View File

@ -0,0 +1,37 @@
/**
* 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 odeBody_ext.cxx
* @author rdb
* @date 2018-11-06
*/
#include "odeBody_ext.h"
static void destroy_callback(OdeBody &body) {
Py_XDECREF((PyObject *)body.get_data());
}
/**
* Sets custom data to be associated with the OdeBody.
*/
void Extension<OdeBody>::
set_data(PyObject *data) {
void *old_data = _this->get_data();
if (data != nullptr && data != Py_None) {
Py_INCREF(data);
_this->set_data((void *)data);
_this->_destroy_callback = &destroy_callback;
} else {
_this->set_data(nullptr);
_this->_destroy_callback = nullptr;
}
Py_XDECREF((PyObject *)old_data);
}

View File

@ -30,6 +30,9 @@
template<>
class Extension<OdeBody> : public ExtensionBase<OdeBody> {
public:
void set_data(PyObject *);
INLINE PyObject *get_data() const;
INLINE PyObject *get_converted_joint(int i) const;
};

View File

@ -1,3 +1,4 @@
#include "odeBody_ext.cxx"
#include "odeGeom_ext.cxx"
#include "odeJoint_ext.cxx"
#include "odeSpace_ext.cxx"

View File

@ -21,6 +21,7 @@
#include "configVariableInt.h"
#include "configVariableDouble.h"
#include "configVariableList.h"
#include "configVariableString.h"
class DSearchPath;

View File

@ -19,6 +19,7 @@
#include "configVariableBool.h"
#include "configVariableEnum.h"
#include "configVariableInt.h"
#include "configVariableString.h"
#include "dconfig.h"
#include "physxEnums.h"

View File

@ -44,7 +44,7 @@ class EXPCL_PANDA_PIPELINE CycleData : public NodeReferenceCount
// If we are *not* compiling in pipelining support, the CycleData object is
// stored directly within its containing classes, and hence should not be a
// ReferenceCount object.
class EXPCL_PANDA_PIPELINE CycleData
class EXPCL_PANDA_PIPELINE CycleData : public MemoryBase
#endif // DO_PIPELINING
{

View File

@ -16,9 +16,11 @@
#include "pandabase.h"
#include "notifyCategoryProxy.h"
#include "configVariableBool.h"
#include "configVariableSearchPath.h"
#include "configVariableEnum.h"
#include "configVariableDouble.h"
#include "configVariableInt.h"
#include "bamEnums.h"
#include "dconfig.h"

View File

@ -11,12 +11,17 @@
* @date 2010-10-20
*/
#include "webcamVideoOpenCV.h"
#include "webcamVideoCursorOpenCV.h"
#ifdef HAVE_OPENCV
#include "webcamVideoOpenCV.h"
#include "movieVideoCursor.h"
#include "pStatTimer.h"
#include <opencv2/highgui/highgui.hpp>
TypeHandle WebcamVideoCursorOpenCV::_type_handle;
/**

View File

@ -22,6 +22,7 @@
#include "movieVideoCursor.h"
class WebcamVideoOpenCV;
struct CvCapture;
/**
* The Video4Linux implementation of webcams.

View File

@ -11,8 +11,13 @@
* @date 2010-06-11
*/
#include "webcamVideoCursorV4L.h"
#include "config_vision.h"
#include "webcamVideoV4L.h"
#include "movieVideoCursor.h"
#if defined(HAVE_VIDEO4LINUX) && !defined(CPPPARSER)
#include <fcntl.h>

View File

@ -16,16 +16,6 @@
#include "pandabase.h"
#ifdef CPPPARSER
// For correct interrogate parsing of UNC's vrpn library.
#if defined(WIN32_VC) || defined(WIN64_VC)
#define SOCKET int
#else
#define linux
typedef struct timeval timeval;
#endif
#endif
// VPRN misses an include to this in vrpn_Shared.h.
#include <stdint.h>

View File

@ -18,6 +18,7 @@
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN 1
#endif
#undef Configure
#include <d3d9.h>
#include "graphicsStateGuardian.h"
#include "graphicsPipe.h"

View File

@ -1 +0,0 @@
ATTACH panda

View File

@ -19,7 +19,6 @@
#include "dSearchPath.h"
#include "coordinateSystem.h"
#include "dconfig.h"
#include "config_dconfig.h"
#include "string_utils.h"
#include "vector_string.h"
#include "configVariableInt.h"