Big interrogate cleanup, new extension system, add __iter__ support, add buffer protocol support

This commit is contained in:
rdb 2013-09-17 10:11:43 +00:00
parent 5aa773b41a
commit cc3bae7e76
79 changed files with 2507 additions and 925 deletions

View File

@ -23,7 +23,7 @@
#include "dtool_config.h"
/* Make sure WIN32 and WIN32_VC are defined when using MSVC */
#ifdef _WIN32
#if defined(_WIN32) || defined(_WIN64)
#ifndef WIN32
#define WIN32
#endif
@ -411,11 +411,6 @@
#define MAKE_SEQ(seq_name, num_name, element_name)
#define EXTENSION(x)
#define EXTEND
/* If you change these, don't forget to also change it in interrogate itself. */
#define _EXT_FUNC(func) _ext__ ## func
#define EXT_FUNC(func) _EXT_FUNC(func) ()
#define EXT_FUNC_ARGS(func, ...) _EXT_FUNC(func) (__VA_ARGS__)
#define CALL_EXT_FUNC(func, ...) _EXT_METHOD(cl, m) (__VA_ARGS__)
#endif
#ifdef __cplusplus

View File

@ -220,32 +220,16 @@ private:
#endif // USE_TAU
#ifdef CPPPARSER
#define EXT_METHOD(cl, m) cl::m()
#define EXT_METHOD_ARGS(cl, m, ...) cl::m(__VA_ARGS__)
#define EXT_CONST_METHOD(cl, m) cl::m() const
#define EXT_CONST_METHOD_ARGS(cl, m, ...) cl::m(__VA_ARGS__) const
#define EXT_NESTED_METHOD(cl1, cl2, m) cl1::cl2::m()
#define EXT_NESTED_METHOD_ARGS(cl1, cl2, m, ...) cl1::cl2::m(__VA_ARGS__)
#define EXT_NESTED_CONST_METHOD(cl1, cl2, m) cl1::cl2::m() const
#define EXT_NESTED_CONST_METHOD_ARGS(cl1, cl2, m, ...) cl1::cl2::m(__VA_ARGS__) const
#define CALL_EXT_METHOD(cl, m, obj, ...) (obj)-> m(__VA_ARGS__)
#else
/* If you change these, don't forget to also change it in interrogate itself. */
#define __EXT_METHOD(cl, m) _ext_ ## cl ## _ ## m
#define _EXT_METHOD(cl, m) __EXT_METHOD(cl, m)
#define __EXT_NEST(cl1, cl2) cl1 ## __ ## cl2
#define _EXT_NEST(cl1, cl2) __EXT_NEST(cl1, cl2)
#define EXT_METHOD(cl, m) _EXT_METHOD(cl, m) (cl * _ext_this)
#define EXT_METHOD_ARGS(cl, m, ...) _EXT_METHOD(cl, m) (cl * _ext_this, __VA_ARGS__)
#define EXT_CONST_METHOD(cl, m) _EXT_METHOD(cl, m) (const cl * _ext_this)
#define EXT_CONST_METHOD_ARGS(cl, m, ...) _EXT_METHOD(cl, m) (const cl * _ext_this, __VA_ARGS__)
#define EXT_NESTED_METHOD(cl1, cl2, m) _EXT_METHOD(_EXT_NEST(cl1, cl2), m) (cl1::cl2 * _ext_this)
#define EXT_NESTED_METHOD_ARGS(cl1, cl2, m, ...) _EXT_METHOD(_EXT_NEST(cl1, cl2), m) (cl1::cl2 * _ext_this, __VA_ARGS__)
#define EXT_NESTED_CONST_METHOD(cl1, cl2, m) _EXT_METHOD(_EXT_NEST(cl1, cl2), m) (const cl1::cl2 * _ext_this)
#define EXT_NESTED_CONST_METHOD_ARGS(cl1, cl2, m, ...) _EXT_METHOD(_EXT_NEST(cl1, cl2), m) (const cl1::cl2 * _ext_this, __VA_ARGS__)
#define CALL_EXT_METHOD(cl, m, ...) _EXT_METHOD(cl, m) (__VA_ARGS__)
#endif
// Macros from hell.
#define EXT_METHOD(cl, m) Extension<cl>::m()
#define EXT_METHOD_ARGS(cl, m, ...) Extension<cl>::m(__VA_ARGS__)
#define EXT_CONST_METHOD(cl, m) Extension<cl>::m() const
#define EXT_CONST_METHOD_ARGS(cl, m, ...) Extension<cl>::m(__VA_ARGS__) const
#define EXT_NESTED_METHOD(cl1, cl2, m) Extension<cl1::cl2>::m()
#define EXT_NESTED_METHOD_ARGS(cl1, cl2, m, ...) Extension<cl1::cl2>::m(__VA_ARGS__)
#define EXT_NESTED_CONST_METHOD(cl1, cl2, m) Extension<cl1::cl2>::m() const
#define EXT_NESTED_CONST_METHOD_ARGS(cl1, cl2, m, ...) Extension<cl1::cl2>::m(__VA_ARGS__) const
#define CALL_EXT_METHOD(cl, m, obj, ...) invoke_extension(obj).m(__VA_ARGS__)
#endif // __cplusplus
#endif

View File

@ -244,8 +244,12 @@ string FunctionRemap::call_function(ostream &out, int indent_level, bool convert
// comment.
////////////////////////////////////////////////////////////////////
void FunctionRemap::
write_orig_prototype(ostream &out, int indent_level) const {
_cppfunc->output(out, indent_level, &parser, false, _num_default_parameters);
write_orig_prototype(ostream &out, int indent_level, bool local) const {
if (local) {
_cppfunc->output(out, indent_level, NULL, false, _num_default_parameters);
} else {
_cppfunc->output(out, indent_level, &parser, false, _num_default_parameters);
}
}
////////////////////////////////////////////////////////////////////
@ -392,28 +396,13 @@ get_call_str(const string &container, const vector_string &pexprs) const {
const char *separator = "";
// If this function is marked as having an extension function,
// call that instead. The naming convention of the extension
// function has to match the EXT_IMPL definition in dtoolbase.h.
if (_extension) {
if (_cpptype != NULL) {
// Fix nested classes by replacing :: with __
char* nested_name = strdup(_cpptype->get_local_name(&parser).c_str());
for (size_t i = 0; i < strlen(nested_name); ++i) {
if (nested_name[i] == ':') {
nested_name[i] = '_';
}
}
call << "_ext_" << nested_name << "_"
<< _cppfunc->get_local_name() << "(";
delete[] nested_name;
} else {
call << "_ext__" << _cppfunc->get_local_name() << "(";
}
// call that instead.
if (_extension && !container.empty()) {
call << "invoke_extension(" << container << ").";
call << _cppfunc->get_local_name();
call << "(";
if (_has_this && !container.empty()) {
call << container;
separator = ", ";
}
} else {
if (_type == T_constructor) {
@ -569,11 +558,13 @@ setup_properties(const InterrogateFunction &ifunc, InterfaceMaker *interface_mak
if (param._remap == (ParameterRemap *)NULL) {
// If we can't handle one of the parameter types, we can't call
// the function.
//nout << "Can't handle parameter " << i << " of method " << *_cppfunc << "\n";
return false;
}
param._remap->set_default_value(params[i]->_initializer);
if (!param._remap->is_valid()) {
nout << "Invalid remap for parameter " << i << " of method " << *_cppfunc << "\n";
return false;
}
@ -693,6 +684,31 @@ setup_properties(const InterrogateFunction &ifunc, InterfaceMaker *interface_mak
// It receives no parameters, and returns a pointer.
_flags |= F_make_copy;
}
} else if (fname == "__iter__" ) {
if (_has_this && _parameters.size() == 1 &&
TypeManager::is_pointer(_return_type->get_new_type())) {
// It receives no parameters, and returns a pointer.
_flags |= F_iter;
}
} else if (fname == "__getbuffer__" ) {
if (_has_this && _parameters.size() == 4 &&
TypeManager::is_integer(_return_type->get_new_type()) &&
TypeManager::is_pointer_to_PyObject(_parameters[1]._remap->get_orig_type()) &&
TypeManager::is_pointer_to_Py_buffer(_parameters[2]._remap->get_orig_type()) &&
TypeManager::is_integer(_parameters[3]._remap->get_orig_type())) {
_flags |= F_getbuffer;
}
} else if (fname == "__releasebuffer__" ) {
if (_has_this && _parameters.size() == 3 &&
TypeManager::is_pointer_to_PyObject(_parameters[1]._remap->get_orig_type()) &&
TypeManager::is_pointer_to_Py_buffer(_parameters[2]._remap->get_orig_type())) {
_flags |= F_releasebuffer;
}
}
} else if (_type == T_constructor) {
@ -709,25 +725,21 @@ setup_properties(const InterrogateFunction &ifunc, InterfaceMaker *interface_mak
return true;
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
std::string make_safe_name(const std::string & name)
{
return InterrogateBuilder::clean_identifier(name);
std::string make_safe_name(const std::string &name) {
return InterrogateBuilder::clean_identifier(name);
/*
static const char safe_chars2[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_";
std::string result = name;
/*
static const char safe_chars2[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_";
std::string result = name;
size_t pos = result.find_first_not_of(safe_chars2);
while (pos != std::string::npos) {
result[pos] = '_';
pos = result.find_first_not_of(safe_chars2);
}
size_t pos = result.find_first_not_of(safe_chars2);
while (pos != std::string::npos)
{
result[pos] = '_';
pos = result.find_first_not_of(safe_chars2);
}
return result;
*/
return result;
*/
}

View File

@ -56,7 +56,7 @@ public:
bool convert_result, const string &container,
const vector_string &pexprs = vector_string()) const;
void write_orig_prototype(ostream &out, int indent_level) const;
void write_orig_prototype(ostream &out, int indent_level, bool local=false) const;
FunctionWrapperIndex make_wrapper_entry(FunctionIndex function_index);
@ -87,6 +87,9 @@ public:
F_make_copy = 0x0020,
F_copy_constructor = 0x0040,
F_explicit_self = 0x0080,
F_iter = 0x0100,
F_getbuffer = 0x0200,
F_releasebuffer = 0x0400,
};
typedef vector<Parameter> Parameters;

View File

@ -40,8 +40,7 @@
#include "cppStructType.h"
#include "pnotify.h"
InterrogateType dummy_type;
InterrogateType dummy_type;
////////////////////////////////////////////////////////////////////
// Function: InterfaceMaker::Function::Constructor
@ -152,6 +151,10 @@ check_protocols() {
_protocol_types |= PT_copy_constructor;
}
if (flags & FunctionRemap::F_iter) {
_protocol_types |= PT_iter;
}
// Now are there any make_seq requests within this class?
CPPStructType *stype = _itype._cpptype->as_struct_type();
if (stype != (CPPStructType *)NULL) {
@ -361,10 +364,9 @@ write_functions(ostream &out) {
// support a module file.
////////////////////////////////////////////////////////////////////
void InterfaceMaker::
write_module(ostream &, ostream *out_h,InterrogateModuleDef *) {
write_module(ostream &, ostream *out_h, InterrogateModuleDef *) {
}
////////////////////////////////////////////////////////////////////
// Function: InterfaceMaker::remap_parameter
// Access: Public, Virtual
@ -379,6 +381,8 @@ write_module(ostream &, ostream *out_h,InterrogateModuleDef *) {
////////////////////////////////////////////////////////////////////
ParameterRemap *InterfaceMaker::
remap_parameter(CPPType *struct_type, CPPType *param_type) {
nassertr(param_type != NULL, NULL);
if (convert_strings) {
if (TypeManager::is_char_pointer(param_type)) {
return new ParameterRemapCharStarToString(param_type);

View File

@ -115,6 +115,7 @@ public:
PT_mapping = 0x0002,
PT_make_copy = 0x0004,
PT_copy_constructor = 0x0008,
PT_iter = 0x0010,
};
int _protocol_types;
};

View File

@ -15,7 +15,6 @@
#include "interfaceMakerPython.h"
#include "interrogate.h"
////////////////////////////////////////////////////////////////////
// Function: InterfaceMakerPython::Constructor
// Access: Public

File diff suppressed because it is too large Load Diff

View File

@ -34,17 +34,17 @@ public:
virtual ~InterfaceMakerPythonNative();
virtual void write_prototypes(ostream &out,ostream *out_h);
void write_prototypes_class(ostream &out,ostream *out_h, Object * obj) ;
void write_prototypes_class_external(ostream &out, Object * obj);
virtual void write_prototypes(ostream &out, ostream *out_h);
void write_prototypes_class(ostream &out, ostream *out_h, Object *obj) ;
void write_prototypes_class_external(ostream &out, Object *obj);
virtual void write_functions(ostream &out);
virtual void write_module(ostream &out,ostream *out_h, InterrogateModuleDef *def);
virtual void write_module_support(ostream &out, ostream *out_h,InterrogateModuleDef *moduledefdef);
virtual void write_module(ostream &out, ostream *out_h, InterrogateModuleDef *def);
virtual void write_module_support(ostream &out, ostream *out_h, InterrogateModuleDef *def);
void write_module_class(ostream &out, Object *cls);
virtual void write_sub_module(ostream &out, Object *obj);
virtual void write_sub_module(ostream &out, Object *obj);
virtual bool synthesize_this_parameter();
@ -74,6 +74,8 @@ private:
WT_sequence_size,
WT_mapping_setitem,
WT_inquiry,
WT_getbuffer,
WT_releasebuffer,
};
class SlottedFunctionDef {
@ -102,22 +104,25 @@ private:
int indent_level, ostream &forwarddecl, bool inplace,
bool coercion_allowed, bool &coercion_attempted,
const string &args_cleanup);
void pack_return_value(ostream &out, int indent_level,
FunctionRemap *remap, std::string return_expr, ostream &forwarddecl, bool in_place);
void pack_return_value(ostream &out, int indent_level, FunctionRemap *remap,
const std::string &return_expr, bool in_place);
void pack_python_value(ostream &out, int indent_level, FunctionRemap *remap,
ParameterRemap *return_type, const std::string &return_expr,
const std::string &assign_expr, bool in_place);
void write_make_seq(ostream &out, Object *obj, const std::string &ClassName,
MakeSeq *make_seq);
void write_class_prototypes(ostream &out) ;
void write_class_declarations(ostream &out, ostream *out_h, Object *obj);
void write_class_details(ostream &out, Object *obj);
void do_assert_init(ostream &out, int &indent_level, bool constructor, const string &args_cleanup) const;
public:
bool isRemapLegal(FunctionRemap &remap);
bool isFunctionLegal( Function *func);
bool isCppTypeLegal(CPPType *ctype);
bool is_remap_legal(FunctionRemap &remap);
bool is_function_legal( Function *func);
bool is_cpp_type_legal(CPPType *ctype);
bool isExportThisRun(CPPType *ctype);
bool isExportThisRun(Function *func);
bool isFunctionWithThis( Function *func);
@ -131,11 +136,11 @@ public:
bool _can_downcast;
bool _is_legal_py_class;
};
void GetValideChildClasses( std::map< std::string ,CastDetails > &answer, CPPStructType * inclass, const std::string &up_cast_seed = "", bool downcastposible = true);
bool DoesInheritFromIsClass( const CPPStructType * inclass, const std::string &name);
void get_valid_child_classes(std::map<std::string, CastDetails> &answer, CPPStructType *inclass, const std::string &upcast_seed = "", bool can_downcast = true);
bool DoesInheritFromIsClass(const CPPStructType * inclass, const std::string &name);
bool IsPandaTypedObject(CPPStructType * inclass) { return DoesInheritFromIsClass(inclass,"TypedObject"); };
void WriteReturnInstance(ostream &out, int indent_level, std::string &return_expr, std::string &ows_memory_flag,const std::string &class_name, CPPType *ctype, bool inplace, const std::string &const_flag);
void write_python_instance(ostream &out, int indent_level, const std::string &return_expr, const std::string &assign_expr, std::string &owns_memory_flag, const std::string &class_name, CPPType *ctype, bool inplace, const std::string &const_flag);
string HasAGetKeyFunction(const InterrogateType &itype_class);
bool HasAGetClassTypeFunction(const InterrogateType &itype_class);
int NeedsAStrFunction(const InterrogateType &itype_class);

View File

@ -128,17 +128,16 @@ read_command_file(istream &in) {
void InterrogateBuilder::
do_command(const string &command, const string &params) {
if(command == "forcevisible")
{
CPPType *type = parser.parse_type(params);
if (type == (CPPType *)NULL) {
nout << "Unknown type: allowtype " << params << "\n";
} else {
type = type->resolve_type(&parser, &parser);
type->_vis = min_vis;
}
}
else if (command == "forcetype") {
if (command == "forcevisible") {
CPPType *type = parser.parse_type(params);
if (type == (CPPType *)NULL) {
nout << "Unknown type: allowtype " << params << "\n";
} else {
type = type->resolve_type(&parser, &parser);
type->_vis = min_vis;
}
} else if (command == "forcetype") {
// forcetype explicitly exports the given type.
CPPType *type = parser.parse_type(params);
if (type == (CPPType *)NULL) {
@ -364,7 +363,6 @@ void InterrogateBuilder::write_code(ostream &out_code,ostream * out_include, Int
<< "#include \"dconfig.h\"\n";
}
ostringstream declaration_bodies;
if (watch_asserts) {
@ -377,7 +375,8 @@ void InterrogateBuilder::write_code(ostream &out_code,ostream * out_include, Int
if (library_name.size() > 1) {
declaration_bodies << "#define PANDA_LIBRARY_NAME_" << library_name << "\n";
}
declaration_bodies << "#include \"py_panda.h\" \n";
declaration_bodies << "#include \"py_panda.h\"\n";
declaration_bodies << "#include \"extension.h\"\n";
}
declaration_bodies << "\n";
@ -393,12 +392,6 @@ void InterrogateBuilder::write_code(ostream &out_code,ostream * out_include, Int
} else {
declaration_bodies << "#include <" << filename << ">\n";
}
// Check if it's a special extension file.
} else if (filename.length() > 6 && filename.substr(filename.length() - 6) == "_ext.I") {
declaration_bodies
<< "#define this _ext_this\n"
<< "#include \"" << filename << "\"\n"
<< "#undef this\n";
}
}
declaration_bodies << "\n";
@ -1757,6 +1750,11 @@ get_function(CPPInstance *function, string description,
ifunction->_flags |= InterrogateFunction::F_operator_typecast;
}
if (function->_storage_class & CPPInstance::SC_virtual) {
// This is a virtual function.
ifunction->_flags |= InterrogateFunction::F_virtual;
}
ifunction->_flags |= flags;
ifunction->_instances->insert(InterrogateFunction::Instances::value_type(function_signature, function));
ifunction->_expression = expression;

View File

@ -56,7 +56,7 @@ public:
void read_command_file(istream &in);
void do_command(const string &command, const string &params);
void build();
void write_code(ostream &out_code,ostream *out_include, InterrogateModuleDef *def);
void write_code(ostream &out_code, ostream *out_include, InterrogateModuleDef *def);
InterrogateModuleDef *make_module_def(int file_identifier);
static string clean_identifier(const string &name);

View File

@ -23,7 +23,7 @@
// Class : ParameterRemapConstToNonConst
// Description : A ParameterRemap class that handles remapping a
// simple const parameter (like const int) to an
// ordinary parameter (line int). It doesn't apply to
// ordinary parameter (like int). It doesn't apply to
// const references or const pointers, however.
////////////////////////////////////////////////////////////////////
class ParameterRemapConstToNonConst : public ParameterRemap {

View File

@ -23,6 +23,7 @@
#include "cppPointerType.h"
#include "cppSimpleType.h"
#include "cppStructType.h"
#include "cppTemplateScope.h"
#include "cppTypeDeclaration.h"
#include "pnotify.h"
#include "cppTypedef.h"
@ -1052,6 +1053,35 @@ is_const_ref_to_pointer_to_base(CPPType *type) {
}
}
////////////////////////////////////////////////////////////////////
// Function: TypeManager::is_pair
// Access: Public, Static
// Description: Returns true if the type is pair<>, or
// a reference to it.
////////////////////////////////////////////////////////////////////
bool TypeManager::
is_pair(CPPType *type) {
// We only check the simple name of the type against pair,
// since we need to allow for the various template instantiations of
// this thing.
if (type->get_simple_name() == "pair") {
return true;
}
switch (type->get_subtype()) {
case CPPDeclaration::ST_const:
return is_pair(type->as_const_type()->_wrapped_around);
case CPPDeclaration::ST_reference:
return is_pair(type->as_reference_type()->_pointing_at);
default:
break;
}
return false;
}
////////////////////////////////////////////////////////////////////
// Function: TypeManager::is_pointer_to_PyObject
// Access: Public, Static
@ -1090,6 +1120,43 @@ is_PyObject(CPPType *type) {
}
}
////////////////////////////////////////////////////////////////////
// Function: TypeManager::is_pointer_to_Py_buffer
// Access: Public, Static
// Description: Returns true if the indicated type is Py_buffer *.
////////////////////////////////////////////////////////////////////
bool TypeManager::
is_pointer_to_Py_buffer(CPPType *type) {
switch (type->get_subtype()) {
case CPPDeclaration::ST_const:
return is_pointer_to_Py_buffer(type->as_const_type()->_wrapped_around);
case CPPDeclaration::ST_pointer:
return is_Py_buffer(type->as_pointer_type()->_pointing_at);
default:
return false;
}
}
////////////////////////////////////////////////////////////////////
// Function: TypeManager::is_Py_buffer
// Access: Public, Static
// Description: Returns true if the indicated type is Py_buffer.
////////////////////////////////////////////////////////////////////
bool TypeManager::
is_Py_buffer(CPPType *type) {
switch (type->get_subtype()) {
case CPPDeclaration::ST_const:
return is_Py_buffer(type->as_const_type()->_wrapped_around);
case CPPDeclaration::ST_extension:
return (type->get_local_name(&parser) == "Py_buffer");
default:
return false;
}
}
////////////////////////////////////////////////////////////////////
// Function: TypeManager::is_ostream
@ -1390,6 +1457,40 @@ get_pointer_type(CPPStructType *pt_type) {
return (CPPType *)NULL;
}
////////////////////////////////////////////////////////////////////
// Function: TypeManager::get_template_parameter_type
// Access: Public, Static
// Description: Returns the ith template parameter type. For
// instance, if the type is pair<A, B>, then this
// function will return type A when passing 0 and
// type B when passing 1, and NULL otherwise.
////////////////////////////////////////////////////////////////////
CPPType *TypeManager::
get_template_parameter_type(CPPType *source_type, int i) {
switch (source_type->get_subtype()) {
case CPPDeclaration::ST_const:
return get_template_parameter_type(source_type->as_const_type()->_wrapped_around, i);
case CPPDeclaration::ST_reference:
return get_template_parameter_type(source_type->as_reference_type()->_pointing_at, i);
}
CPPStructType *type = source_type->as_struct_type();
if (type == NULL) {
return NULL;
}
// I'm not sure how reliable this is, but I don't know if there
// is a more proper way to access this.
CPPTemplateParameterList *templ = type->_ident->_names.back().get_templ();
if (templ == NULL || i >= templ->_parameters.size()) {
return NULL;
}
CPPDeclaration *decl = templ->_parameters[i];
return decl->as_type();
}
////////////////////////////////////////////////////////////////////
// Function: TypeManager::wrap_pointer
// Access: Public, Static

View File

@ -76,6 +76,7 @@ public:
static bool is_const_ref_to_basic_string_wchar(CPPType *type);
static bool is_const_ptr_to_basic_string_wchar(CPPType *type);
static bool is_wstring(CPPType *type);
static bool is_pair(CPPType *type);
static bool is_bool(CPPType *type);
static bool is_integer(CPPType *type);
static bool is_unsigned_integer(CPPType *type);
@ -90,6 +91,8 @@ public:
static bool is_const_ref_to_pointer_to_base(CPPType *type);
static bool is_pointer_to_PyObject(CPPType *type);
static bool is_PyObject(CPPType *type);
static bool is_pointer_to_Py_buffer(CPPType *type);
static bool is_Py_buffer(CPPType *type);
static bool involves_unpublished(CPPType *type);
static bool involves_protected(CPPType *type);
@ -103,6 +106,7 @@ public:
static CPPType *unwrap(CPPType *type);
static CPPType *get_pointer_type(CPPStructType *pt_type);
static CPPType *get_template_parameter_type(CPPType *type, int i = 0);
static CPPType *wrap_pointer(CPPType *type);
static CPPType *wrap_const_pointer(CPPType *type);

View File

@ -17,7 +17,7 @@
interrogateType.I interrogateType.h \
interrogate_datafile.I interrogate_datafile.h \
interrogate_interface.h interrogate_request.h \
py_panda.h \
extension.h py_panda.h \
vector_int.h
#define INCLUDED_SOURCES \
@ -37,7 +37,7 @@
#define INSTALL_HEADERS \
interrogate_interface.h interrogate_request.h vector_int.h \
config_interrogatedb.h \
py_panda.h \
extension.h py_panda.h \
vector_int.h
#end lib_target

View File

@ -0,0 +1,75 @@
// Filename: extension.h
// Created by: rdb (11Sep13)
//
////////////////////////////////////////////////////////////////////
//
// 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."
//
////////////////////////////////////////////////////////////////////
#ifndef EXTENSION_H
#define EXTENSION_H
#include "dtoolbase.h"
struct _object;
typedef struct _object PyObject;
////////////////////////////////////////////////////////////////////
// Class : ExtensionBase
// Description : This is where all extensions should derive from.
// It defines the _self and _this members that can
// be used from the extension method.
////////////////////////////////////////////////////////////////////
template<class T>
class EXPCL_DTOOLCONFIG ExtensionBase {
public:
T * _this;
PyObject * _self;
};
////////////////////////////////////////////////////////////////////
// Class : Extension
// Description : The default class template does not define any
// methods. Classes that are extended should create
// a specialization of this class template.
////////////////////////////////////////////////////////////////////
template<class T>
class EXPCL_DTOOLCONFIG Extension : public ExtensionBase<T> {
};
////////////////////////////////////////////////////////////////////
// Function : invoke_extension
// Description : Creates a new extension object for the given
// pointer that can then be used to call extension
// methods, as follows:
// invoke_extension((MyClass) *ptr).method()
////////////////////////////////////////////////////////////////////
template<class T>
inline Extension<T>
invoke_extension(T *ptr, PyObject *self = NULL) {
Extension<T> ext;
ext._this = ptr;
ext._self = self;
return ext;
}
////////////////////////////////////////////////////////////////////
// Function : invoke_extension
// Description : The const version of the above function.
////////////////////////////////////////////////////////////////////
template<class T>
inline const Extension<T>
invoke_extension(const T *ptr, PyObject *self = NULL) {
Extension<T> ext;
ext._this = (T *) ptr;
ext._self = self;
return ext;
}
#endif

View File

@ -437,7 +437,7 @@ RegisterRuntimeClass(Dtool_PyTypedObject * otype, int class_id) {
Dtool_PyTypedObject *Dtool_RuntimeTypeDtoolType(int type) {
RunTimeTypeDictionary::iterator di = GetRunTimeDictionary().find(type);
if (di != GetRunTimeDictionary().end()) {
return di->second;
return di->second;
} else {
int type2 = get_best_parent_from_Set(type, GetRunTimeTypeList());
di = GetRunTimeDictionary().find(type2);
@ -468,6 +468,7 @@ PyObject *Dtool_PyModuleInitHelper(LibraryDef *defs[], const char *modulename) {
newdef[offset].ml_flags = 0;
#if PY_MAJOR_VERSION >= 3
cerr << "About to create module " << modulename << "\n";
struct PyModuleDef moduledef = {
PyModuleDef_HEAD_INIT,
modulename,
@ -477,6 +478,7 @@ PyObject *Dtool_PyModuleInitHelper(LibraryDef *defs[], const char *modulename) {
NULL, NULL, NULL, NULL
};
PyObject *module = PyModule_Create(&moduledef);
cerr << "Module created!\n";
#else
PyObject *module = Py_InitModule((char *)modulename, newdef);
#endif

View File

@ -221,7 +221,7 @@ struct Dtool_PyTypedObject {
0, /* tp_str */ \
PyObject_GenericGetAttr, /* tp_getattro */ \
PyObject_GenericSetAttr, /* tp_setattro */ \
0, /* tp_as_buffer */ \
&Dtool_PyBufferProcs_##CLASS_NAME, /* tp_as_buffer */ \
(Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_CHECKTYPES), /* tp_flags */ \
0, /* tp_doc */ \
0, /* tp_traverse */ \
@ -310,6 +310,11 @@ struct Dtool_PyTypedObject {
0,/*binaryfunc mp_subscript */ \
0,/*objobjargproc mp_ass_subscript */ \
}; \
static PyMappingMethods Dtool_PyBufferProcs_##CLASS_NAME = \
{ \
0,/*getbufferproc bf_getbuffer */ \
0,/*releasebufferproc bf_releasebuffer */ \
}; \
Define_Dtool_PyTypedObject(MODULE_NAME, CLASS_NAME, PUBLIC_NAME)
#else // Python 2:
@ -373,6 +378,15 @@ struct Dtool_PyTypedObject {
0,/*binaryfunc mp_subscript */ \
0,/*objobjargproc mp_ass_subscript */ \
}; \
static PyBufferProcs Dtool_PyBufferProcs_##CLASS_NAME = \
{ \
0,/*readbufferproc bf_getreadbuffer */ \
0,/*writebufferproc bf_getwritebuffer */ \
0,/*segcountproc bf_getsegcount */ \
0,/*charbufferproc bf_getcharbuffer */ \
0,/*getbufferproc bf_getbuffer */ \
0,/*releasebufferproc bf_releasebuffer */ \
}; \
Define_Dtool_PyTypedObject(MODULE_NAME, CLASS_NAME, PUBLIC_NAME)
#endif

View File

@ -11,5 +11,6 @@ namespace OVR {
class SensorInfo;
class SensorFusion;
template<class T> class DeviceEnumerator;
template<class T> class Ptr;
};

View File

@ -23,5 +23,6 @@
class PyObject;
class PyThreadState;
typedef int Py_ssize_t;
struct Py_buffer;
#endif // PYTHON_H

View File

@ -70,6 +70,7 @@
virtualFileMountSystem.h virtualFileMountSystem.I \
virtualFileSimple.h virtualFileSimple.I \
virtualFileSystem.h virtualFileSystem.I \
virtualFileSystem_ext.h virtualFileSystem_ext.cxx \
weakPointerCallback.I weakPointerCallback.h \
weakPointerTo.I weakPointerTo.h \
weakPointerToBase.I weakPointerToBase.h \

View File

@ -83,11 +83,12 @@ PointerToArray(const PointerToArray<Element> &copy) :
// Access: Published
// Description: This special constructor accepts a Python list of
// elements, or a Python string (or a bytes object,
// in Python 3).
// in Python 3), or any object that supports the
// Python buffer protocol.
////////////////////////////////////////////////////////////////////
template<class Element>
PointerToArray<Element>::
PointerToArray(PyObject *self, PyObject *sequence) :
PointerToArray(PyObject *self, PyObject *source) :
PointerToArrayBase<Element>((ReferenceCountedVector<Element> *)NULL),
_type_handle(get_type_handle(Element))
{
@ -95,9 +96,33 @@ PointerToArray(PyObject *self, PyObject *sequence) :
// self in the constructor--the caller can't initialize this for us.
((Dtool_PyInstDef *)self)->_ptr_to_object = this;
if (!PySequence_Check(sequence)) {
if (PyObject_CheckBuffer(source)) {
// User passed a buffer object.
Py_buffer view;
if (PyObject_GetBuffer(source, &view, PyBUF_CONTIG_RO) == -1) {
PyErr_SetString(PyExc_TypeError, "PointerToArray constructor requires a contiguous buffer");
return;
}
if (view.itemsize != 1 && view.itemsize != sizeof(Element)) {
PyErr_SetString(PyExc_TypeError, "buffer.itemsize does not match PointerToArray element size");
return;
}
int num_elements = view.len / sizeof(Element);
insert(begin(), num_elements, Element());
if (view.len > 0) {
memcpy(p(), view.buf, view.len);
}
PyBuffer_Release(&view);
return;
}
if (!PySequence_Check(source)) {
// If passed with a non-sequence, this isn't the right constructor.
PyErr_SetString(PyExc_TypeError, "PointerToArray constructor requires a sequence");
PyErr_SetString(PyExc_TypeError, "PointerToArray constructor requires a sequence or buffer object");
return;
}
@ -105,8 +130,8 @@ PointerToArray(PyObject *self, PyObject *sequence) :
// character-at-a-time, just load the whole string as a data
// buffer.
#if PY_MAJOR_VERSION >= 3
if (PyBytes_Check(sequence)) {
int size = PyBytes_Size(sequence);
if (PyBytes_Check(source)) {
int size = PyBytes_Size(source);
if (size % sizeof(Element) != 0) {
ostringstream stream;
stream << "Buffer not a multiple of " << sizeof(Element) << " bytes";
@ -121,14 +146,14 @@ PointerToArray(PyObject *self, PyObject *sequence) :
// Hope there aren't any constructors or destructors involved
// here.
if (size != 0) {
const char *data = PyBytes_AsString(sequence);
const char *data = PyBytes_AsString(source);
memcpy(p(), data, size);
}
return;
}
#else
if (PyString_CheckExact(sequence)) {
int size = PyString_Size(sequence);
if (PyString_CheckExact(source)) {
int size = PyString_Size(source);
if (size % sizeof(Element) != 0) {
ostringstream stream;
stream << "Buffer not a multiple of " << sizeof(Element) << " bytes";
@ -143,7 +168,7 @@ PointerToArray(PyObject *self, PyObject *sequence) :
// Hope there aren't any constructors or destructors involved
// here.
if (size != 0) {
const char *data = PyString_AsString(sequence);
const char *data = PyString_AsString(source);
memcpy(p(), data, size);
}
return;
@ -152,9 +177,9 @@ PointerToArray(PyObject *self, PyObject *sequence) :
// Now construct the internal list by copying the elements
// one-at-a-time from Python.
int size = PySequence_Size(sequence);
int size = PySequence_Size(source);
for (int i = 0; i < size; ++i) {
PyObject *item = PySequence_GetItem(sequence, i);
PyObject *item = PySequence_GetItem(source, i);
if (item == NULL) {
return;
}
@ -715,6 +740,32 @@ get_ref_count() const {
return ((this->_void_ptr) == NULL) ? 0 : ((To *)(this->_void_ptr))->get_ref_count();
}
////////////////////////////////////////////////////////////////////
// Function: PointerToArray::ref
// Access: Public
// Description: Increments the reference count of the underlying vector.
////////////////////////////////////////////////////////////////////
template<class Element>
INLINE void PointerToArray<Element>::
ref() const {
if ((this->_void_ptr) == NULL) {
((PointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>(_type_handle));
}
((To *)(this->_void_ptr))->ref();
}
////////////////////////////////////////////////////////////////////
// Function: PointerToArray::unref
// Access: Public
// Description: Decrements the reference count of the underlying vector.
////////////////////////////////////////////////////////////////////
template<class Element>
INLINE bool PointerToArray<Element>::
unref() const {
nassertr((this->_void_ptr) != NULL, true);
return ((To *)(this->_void_ptr))->unref();
}
////////////////////////////////////////////////////////////////////
// Function: PointerToArray::get_node_ref_count
// Access: Public
@ -841,8 +892,8 @@ ConstPointerToArray(const ConstPointerToArray<Element> &copy) :
////////////////////////////////////////////////////////////////////
template<class Element>
INLINE ConstPointerToArray<Element>::
ConstPointerToArray(PyObject *self, PyObject *sequence) :
PointerToArrayBase<Element>(PointerToArray<Element>(self, sequence)),
ConstPointerToArray(PyObject *self, PyObject *source) :
PointerToArrayBase<Element>(PointerToArray<Element>(self, source)),
_type_handle(get_type_handle(Element))
{
}
@ -1164,6 +1215,32 @@ get_ref_count() const {
return ((this->_void_ptr) == NULL) ? 0 : ((To *)(this->_void_ptr))->get_ref_count();
}
////////////////////////////////////////////////////////////////////
// Function: ConstPointerToArray::ref
// Access: Public
// Description: Increments the reference count of the underlying vector.
////////////////////////////////////////////////////////////////////
template<class Element>
INLINE void ConstPointerToArray<Element>::
ref() const {
if ((this->_void_ptr) == NULL) {
((ConstPointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>(_type_handle));
}
((To *)(this->_void_ptr))->ref();
}
////////////////////////////////////////////////////////////////////
// Function: ConstPointerToArray::unref
// Access: Public
// Description: Decrements the reference count of the underlying vector.
////////////////////////////////////////////////////////////////////
template<class Element>
INLINE bool ConstPointerToArray<Element>::
unref() const {
nassertr((this->_void_ptr) != NULL, true);
return ((To *)(this->_void_ptr))->unref();
}
////////////////////////////////////////////////////////////////////
// Function: ConstPointerToArray::get_node_ref_count
// Access: Public
@ -1252,4 +1329,151 @@ clear() {
((ConstPointerToArray<Element> *)this)->reassign((ReferenceCountedVector<Element> *)NULL);
}
#ifdef HAVE_PYTHON
////////////////////////////////////////////////////////////////////
// Function: PointerToArray::__getbuffer__
// Access: Published
// Description: This is used to implement the buffer protocol, in
// order to allow efficient access to the array data
// through a Python multiview object.
////////////////////////////////////////////////////////////////////
template<class Element>
INLINE int PointerToArray<Element>::
__getbuffer__(PyObject *self, Py_buffer *view, int flags) {
const char *format = get_format_code(Element);
cerr << "non-const __getbuffer__ with fmt " << format << "\n";
if (format == NULL) {
// Not supported.
return -1;
}
if (self != NULL) {
Py_INCREF(self);
}
view->obj = self;
view->buf = (void*) p();
view->len = size() * sizeof(Element);
view->readonly = 0;
view->itemsize = sizeof(Element);
view->format = NULL;
if ((flags & PyBUF_FORMAT) == PyBUF_FORMAT) {
view->format = (char*) format;
}
view->ndim = 1;
view->shape = NULL;
if ((flags & PyBUF_ND) == PyBUF_ND) {
// This leaks, which sucks, but __releasebuffer__ doesn't give us
// the same pointer, so we would need to store it elsewhere if we
// wanted to delete it there. Eh, it's just an int, who cares.
view->shape = new Py_ssize_t(size());
}
view->strides = NULL;
if ((flags & PyBUF_STRIDES) == PyBUF_STRIDES) {
view->strides = &(view->itemsize);
}
view->suboffsets = NULL;
// Store a reference to ourselves on the Py_buffer object
// as a reminder that we have increased our refcount.
ref();
view->internal = (void*) this;
return 0;
}
////////////////////////////////////////////////////////////////////
// Function: PointerToArray::__releasebuffer__
// Access: Published
// Description: Releases the buffer allocated by __getbuffer__.
////////////////////////////////////////////////////////////////////
template<class Element>
INLINE void PointerToArray<Element>::
__releasebuffer__(PyObject *self, Py_buffer *view) const {
// Note: PyBuffer_Release automatically decrements view->obj.
if (view->internal != NULL) {
// Oh, right, let's not forget to unref this.
((const PointerToArray<Element> *) view->internal)->unref();
view->internal = NULL;
}
}
////////////////////////////////////////////////////////////////////
// Function: ConstPointerToArray::__getbuffer__
// Access: Published
// Description: This is used to implement the buffer protocol, in
// order to allow efficient access to the array data
// through a Python multiview object.
////////////////////////////////////////////////////////////////////
template<class Element>
INLINE int ConstPointerToArray<Element>::
__getbuffer__(PyObject *self, Py_buffer *view, int flags) const {
if ((flags & PyBUF_WRITABLE) == PyBUF_WRITABLE) {
cerr << "writable buffer requested of const array\n";
PyErr_SetString(PyExc_BufferError,
"Object is not writable.");
return -1;
}
const char *format = get_format_code(Element);
cerr << "const __getbuffer__ with fmt " << format << "\n";
if (format == NULL) {
// Not supported.
return -1;
}
if (self != NULL) {
Py_INCREF(self);
}
view->obj = self;
view->buf = (void*) p();
view->len = size() * sizeof(Element);
view->readonly = 1;
view->itemsize = sizeof(Element);
view->format = NULL;
if ((flags & PyBUF_FORMAT) == PyBUF_FORMAT) {
view->format = (char*) format;
}
view->ndim = 1;
view->shape = NULL;
if ((flags & PyBUF_ND) == PyBUF_ND) {
// This leaks, which sucks, but __releasebuffer__ doesn't give us
// the same pointer, so we would need to store it elsewhere if we
// wanted to delete it there. Eh, it's just an int, who cares.
view->shape = new Py_ssize_t(size());
}
view->strides = NULL;
if ((flags & PyBUF_STRIDES) == PyBUF_STRIDES) {
view->strides = &(view->itemsize);
}
view->suboffsets = NULL;
// Store a reference to ourselves on the Py_buffer object
// as a reminder that we have increased our refcount.
ref();
view->internal = (void*) this;
return 0;
}
////////////////////////////////////////////////////////////////////
// Function: ConstPointerToArray::__releasebuffer__
// Access: Published
// Description: Releases the buffer allocated by __getbuffer__.
////////////////////////////////////////////////////////////////////
template<class Element>
INLINE void ConstPointerToArray<Element>::
__releasebuffer__(PyObject *self, Py_buffer *view) const {
// Note: PyBuffer_Release automatically decrements obj->view.
if (view->internal != NULL) {
// Oh, right, let's not forget to unref this.
((const PointerToArray<Element> *) view->internal)->unref();
view->internal = NULL;
}
}
#endif // HAVE_PYTHON
#endif // CPPPARSER

View File

@ -113,7 +113,7 @@ PUBLISHED:
INLINE PointerToArray(const PointerToArray<Element> &copy);
#ifdef HAVE_PYTHON
PointerToArray(PyObject *self, PyObject *sequence);
PointerToArray(PyObject *self, PyObject *source);
#endif
INLINE size_type size() const;
@ -130,6 +130,11 @@ PUBLISHED:
INLINE int get_ref_count() const;
INLINE int get_node_ref_count() const;
#ifdef HAVE_PYTHON
int __getbuffer__(PyObject *self, Py_buffer *view, int flags);
void __releasebuffer__(PyObject *self, Py_buffer *view) const;
#endif
#else // CPPPARSER
// This is the actual, complete interface.
typedef TYPENAME PointerToArrayBase<Element>::To To;
@ -150,7 +155,7 @@ public:
INLINE PointerToArray(const PointerToArray<Element> &copy);
#ifdef HAVE_PYTHON
PointerToArray(PyObject *self, PyObject *sequence);
PointerToArray(PyObject *self, PyObject *source);
#endif
public:
@ -223,11 +228,18 @@ public:
INLINE void set_void_ptr(void* p);
INLINE int get_ref_count() const;
INLINE void ref() const;
INLINE bool unref() const;
INLINE int get_node_ref_count() const;
INLINE void node_ref() const;
INLINE bool node_unref() const;
#ifdef HAVE_PYTHON
int __getbuffer__(PyObject *self, Py_buffer *view, int flags);
void __releasebuffer__(PyObject *self, Py_buffer *view) const;
#endif
// Reassignment is by pointer, not memberwise as with a vector.
INLINE PointerToArray<Element> &
operator = (ReferenceCountedVector<Element> *ptr);
@ -268,7 +280,7 @@ PUBLISHED:
INLINE ConstPointerToArray(const ConstPointerToArray<Element> &copy);
#ifdef HAVE_PYTHON
INLINE ConstPointerToArray(PyObject *self, PyObject *sequence);
INLINE ConstPointerToArray(PyObject *self, PyObject *source);
#endif
typedef TYPENAME pvector<Element>::size_type size_type;
@ -280,6 +292,11 @@ PUBLISHED:
INLINE int get_ref_count() const;
INLINE int get_node_ref_count() const;
#ifdef HAVE_PYTHON
int __getbuffer__(PyObject *self, Py_buffer *view, int flags) const;
void __releasebuffer__(PyObject *self, Py_buffer *view) const;
#endif
#else // CPPPARSER
// This is the actual, complete interface.
typedef TYPENAME PointerToArrayBase<Element>::To To;
@ -303,7 +320,7 @@ PUBLISHED:
INLINE ConstPointerToArray(const ConstPointerToArray<Element> &copy);
#ifdef HAVE_PYTHON
INLINE ConstPointerToArray(PyObject *self, PyObject *sequence);
INLINE ConstPointerToArray(PyObject *self, PyObject *source);
#endif
// Duplicating the interface of vector.
@ -343,11 +360,18 @@ PUBLISHED:
INLINE string get_subdata(size_type n, size_type count) const;
INLINE int get_ref_count() const;
INLINE void ref() const;
INLINE bool unref() const;
INLINE int get_node_ref_count() const;
INLINE void node_ref() const;
INLINE bool node_unref() const;
#ifdef HAVE_PYTHON
int __getbuffer__(PyObject *self, Py_buffer *view, int flags) const;
void __releasebuffer__(PyObject *self, Py_buffer *view) const;
#endif
// Reassignment is by pointer, not memberwise as with a vector.
INLINE ConstPointerToArray<Element> &
operator = (ReferenceCountedVector<Element> *ptr);
@ -372,12 +396,40 @@ private:
friend class PointerToArray<Element>;
};
// And the brevity macros.
#define PTA(type) PointerToArray< type >
#define CPTA(type) ConstPointerToArray< type >
#ifdef HAVE_PYTHON
// This macro is used to map a data type to a format code
// as used in the Python 'struct' and 'array' modules.
#define get_format_code(type) _get_format_code((const type *)0)
#define define_format_code(code, type) template<> \
INLINE const char *_get_format_code(const type *) { \
return code; \
}
template<class T>
INLINE const char *_get_format_code(const T *) {
return NULL;
}
define_format_code("c", char);
define_format_code("b", signed char);
define_format_code("B", unsigned char);
define_format_code("h", short);
define_format_code("H", unsigned short);
define_format_code("i", int);
define_format_code("I", unsigned int);
define_format_code("l", long);
define_format_code("L", unsigned long);
define_format_code("q", long long);
define_format_code("Q", unsigned long long);
define_format_code("f", float);
define_format_code("d", double);
#endif // HAVE_PYTHON
#include "pointerToArray.I"
#endif
#endif // HAVE_POINTERTOARRAY_H

View File

@ -920,41 +920,6 @@ get_global_ptr() {
return _global_ptr;
}
#ifdef HAVE_PYTHON
////////////////////////////////////////////////////////////////////
// Function: VirtualFileSystem::__py__read_file
// Access: Published
// Description: Convenience function; returns the entire contents of
// the indicated file as a string (or as a bytes object,
// in Python 3).
//
// This variant on read_file() is implemented directly
// for Python, as a small optimization, to avoid the
// double-construction of a string object that would be
// otherwise required for the return value.
////////////////////////////////////////////////////////////////////
PyObject *VirtualFileSystem::
__py__read_file(const Filename &filename, bool auto_unwrap) const {
pvector<unsigned char> pv;
bool okflag = read_file(filename, pv, auto_unwrap);
nassertr(okflag, NULL);
#if PY_MAJOR_VERSION >= 3
if (pv.empty()) {
return PyBytes_FromStringAndSize("", 0);
} else {
return PyBytes_FromStringAndSize((const char *)&pv[0], pv.size());
}
#else
if (pv.empty()) {
return PyString_FromStringAndSize("", 0);
} else {
return PyString_FromStringAndSize((const char *)&pv[0], pv.size());
}
#endif
}
#endif // HAVE_PYTHON
////////////////////////////////////////////////////////////////////
// Function: VirtualFileSystem::open_read_file
// Access: Published
@ -1007,38 +972,6 @@ close_read_file(istream *stream) {
}
}
#ifdef HAVE_PYTHON
////////////////////////////////////////////////////////////////////
// Function: VirtualFileSystem::__py__write_file
// Access: Published
// Description: Convenience function; writes the entire contents of
// the indicated file as a string.
//
// This variant on write_file() is implemented directly
// for Python, as a small optimization, to avoid the
// double-construction of a string object that would be
// otherwise required.
////////////////////////////////////////////////////////////////////
PyObject *VirtualFileSystem::
__py__write_file(const Filename &filename, PyObject *data, bool auto_wrap) {
char *buffer;
Py_ssize_t length;
#if PY_MAJOR_VERSION >= 3
if (PyBytes_AsStringAndSize(data, &buffer, &length) == -1) {
return NULL;
}
#else
if (PyString_AsStringAndSize(data, &buffer, &length) == -1) {
return NULL;
}
#endif
bool result = write_file(filename, (const unsigned char *)buffer, length, auto_wrap);
return PyBool_FromLong(result);
}
#endif // HAVE_PYTHON
////////////////////////////////////////////////////////////////////
// Function: VirtualFileSystem::open_write_file
// Access: Published

View File

@ -98,18 +98,11 @@ PUBLISHED:
static VirtualFileSystem *get_global_ptr();
#ifdef HAVE_PYTHON
BLOCKING PyObject *__py__read_file(const Filename &filename, bool auto_unwrap) const;
#endif // HAVE_PYTHON
BLOCKING INLINE string read_file(const Filename &filename, bool auto_unwrap) const;
EXTENSION(BLOCKING PyObject *read_file(const Filename &filename, bool auto_unwrap) const);
BLOCKING istream *open_read_file(const Filename &filename, bool auto_unwrap) const;
BLOCKING static void close_read_file(istream *stream);
#ifdef HAVE_PYTHON
BLOCKING PyObject *__py__write_file(const Filename &filename, PyObject *data, bool auto_wrap);
#endif // HAVE_PYTHON
BLOCKING INLINE bool write_file(const Filename &filename, const string &data, bool auto_wrap);
EXTENSION(BLOCKING PyObject *write_file(const Filename &filename, PyObject *data, bool auto_wrap));
BLOCKING ostream *open_write_file(const Filename &filename, bool auto_wrap, bool truncate);
BLOCKING ostream *open_append_file(const Filename &filename);
BLOCKING static void close_write_file(ostream *stream);
@ -119,6 +112,10 @@ PUBLISHED:
BLOCKING static void close_read_write_file(iostream *stream);
public:
// We provide Python versions of these as efficient extension methods, above.
BLOCKING INLINE string read_file(const Filename &filename, bool auto_unwrap) const;
BLOCKING INLINE bool write_file(const Filename &filename, const string &data, bool auto_wrap);
bool atomic_compare_and_exchange_contents(const Filename &filename, string &orig_contents, const string &old_contents, const string &new_contents);
bool atomic_read_contents(const Filename &filename, string &contents) const;

View File

@ -0,0 +1,82 @@
// Filename: virtualFileSystem_ext.cxx
// Created by: rdb (12Sep13)
//
////////////////////////////////////////////////////////////////////
//
// 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."
//
////////////////////////////////////////////////////////////////////
#include "virtualFileSystem_ext.h"
#ifdef HAVE_PYTHON
////////////////////////////////////////////////////////////////////
// Function: VirtualFileSystem::read_file
// Access: Published
// Description: Convenience function; returns the entire contents of
// the indicated file as a string (or as a bytes object,
// in Python 3).
//
// This variant on read_file() is implemented directly
// for Python, as a small optimization, to avoid the
// double-construction of a string object that would be
// otherwise required for the return value.
////////////////////////////////////////////////////////////////////
PyObject *Extension<VirtualFileSystem>::
read_file(const Filename &filename, bool auto_unwrap) const {
pvector<unsigned char> pv;
bool okflag = _this->read_file(filename, pv, auto_unwrap);
nassertr(okflag, NULL);
#if PY_MAJOR_VERSION >= 3
if (pv.empty()) {
return PyBytes_FromStringAndSize("", 0);
} else {
return PyBytes_FromStringAndSize((const char *)&pv[0], pv.size());
}
#else
if (pv.empty()) {
return PyString_FromStringAndSize("", 0);
} else {
return PyString_FromStringAndSize((const char *)&pv[0], pv.size());
}
#endif
}
////////////////////////////////////////////////////////////////////
// Function: VirtualFileSystem::write_file
// Access: Published
// Description: Convenience function; writes the entire contents of
// the indicated file as a string.
//
// This variant on write_file() is implemented directly
// for Python, as a small optimization, to avoid the
// double-construction of a string object that would be
// otherwise required.
////////////////////////////////////////////////////////////////////
PyObject *Extension<VirtualFileSystem>::
write_file(const Filename &filename, PyObject *data, bool auto_wrap) {
char *buffer;
Py_ssize_t length;
#if PY_MAJOR_VERSION >= 3
if (PyBytes_AsStringAndSize(data, &buffer, &length) == -1) {
return NULL;
}
#else
if (PyString_AsStringAndSize(data, &buffer, &length) == -1) {
return NULL;
}
#endif
bool result = _this->write_file(filename, (const unsigned char *)buffer, length, auto_wrap);
return PyBool_FromLong(result);
}
#endif // HAVE_PYTHOS

View File

@ -0,0 +1,41 @@
// Filename: virtualFileSystem_ext.h
// Created by: rdb (12Sep13)
//
////////////////////////////////////////////////////////////////////
//
// 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."
//
////////////////////////////////////////////////////////////////////
#ifndef VIRTUALFILESYSTEM_EXT_H
#define VIRTUALFILESYSTEM_EXT_H
#include "dtoolbase.h"
#ifdef HAVE_PYTHON
#include "extension.h"
#include "virtualFileSystem.h"
#include "py_panda.h"
////////////////////////////////////////////////////////////////////
// Class : Extension<VirtualFileSystem>
// Description : This class defines the extension methods for
// VirtualFileSystem, which are called instead of
// any C++ methods with the same prototype.
////////////////////////////////////////////////////////////////////
template<>
class Extension<VirtualFileSystem> : public ExtensionBase<VirtualFileSystem> {
public:
PyObject *read_file(Filename const &filename, bool auto_unwrap) const;
PyObject *write_file(Filename const &filename, PyObject *data, bool auto_wrap);
};
#endif // HAVE_PYTHON
#endif // VIRTUALFILESYSTEM_EXT_H

View File

@ -30,6 +30,7 @@
geomLinestrips.h \
geomPoints.h \
geomVertexArrayData.h geomVertexArrayData.I \
geomVertexArrayData_ext.h geomVertexArrayData_ext.cxx \
geomVertexArrayFormat.h geomVertexArrayFormat.I \
geomCacheEntry.h geomCacheEntry.I \
geomCacheManager.h geomCacheManager.I \

View File

@ -114,6 +114,10 @@ PUBLISHED:
static void lru_epoch();
INLINE static VertexDataBook &get_book();
EXTENSION(int __getbuffer__(PyObject *self, Py_buffer *view, int flags));
EXTENSION(int __getbuffer__(PyObject *self, Py_buffer *view, int flags) const);
EXTENSION(void __releasebuffer__(PyObject *self, Py_buffer *view) const);
public:
virtual void evict_lru();

View File

@ -0,0 +1,167 @@
// Filename: geomVertexArrayData_ext.I
// Created by: rdb (05Sep13)
//
////////////////////////////////////////////////////////////////////
//
// 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."
//
////////////////////////////////////////////////////////////////////
#include "geomVertexArrayData_ext.h"
struct InternalBufferData {
CPT(GeomVertexArrayDataHandle) _handle;
Py_ssize_t _num_rows;
Py_ssize_t _stride;
string _format;
};
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayData::__getbuffer__
// Access: Published
// Description: This is used to implement the buffer protocol, in
// order to allow efficient access to the array data
// through a Python multiview object.
////////////////////////////////////////////////////////////////////
int Extension<GeomVertexArrayData>::
__getbuffer__(PyObject *self, Py_buffer *view, int flags) {
PT(GeomVertexArrayDataHandle) handle = _this->modify_handle();
CPT(GeomVertexArrayFormat) format = handle->get_array_format();
int row_size;
bool pad_fmt;
if ((flags & PyBUF_STRIDES) == PyBUF_STRIDES) {
// The consumer is fine with having a stride value.
row_size = format->get_total_bytes();
pad_fmt = false;
} else {
// The consumer expects a contiguous buffer. Give the
// stride as row size, and pad the format with extra bytes.
row_size = format->get_stride();
pad_fmt = true;
}
InternalBufferData *data = new InternalBufferData;
data->_handle = handle;
data->_num_rows = handle->get_num_rows();
data->_stride = format->get_stride();
data->_format = format->get_format_string(pad_fmt);
view->internal = (void*) data;
if (self != NULL) {
Py_INCREF(self);
}
view->obj = self;
view->buf = (void*) handle->get_write_pointer();
view->len = row_size * handle->get_num_rows();
view->readonly = 0;
view->itemsize = row_size;
view->format = NULL;
if ((flags & PyBUF_FORMAT) == PyBUF_FORMAT) {
view->format = (char*) data->_format.c_str();
}
view->ndim = 1;
view->shape = NULL;
if ((flags & PyBUF_ND) == PyBUF_ND) {
view->shape = &data->_num_rows;
}
view->strides = NULL;
if ((flags & PyBUF_STRIDES) == PyBUF_STRIDES) {
view->strides = &data->_stride;
}
view->suboffsets = NULL;
return 0;
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayData::__getbuffer__
// Access: Published
// Description: This is the const version of __getbuffer__, which
// does not support writing.
////////////////////////////////////////////////////////////////////
int Extension<GeomVertexArrayData>::
__getbuffer__(PyObject *self, Py_buffer *view, int flags) const {
if ((flags & PyBUF_WRITABLE) == PyBUF_WRITABLE) {
PyErr_SetString(PyExc_BufferError,
"Object is not writable.");
return -1;
}
CPT(GeomVertexArrayDataHandle) handle = _this->get_handle();
CPT(GeomVertexArrayFormat) format = handle->get_array_format();
int row_size;
bool pad_fmt;
if ((flags & PyBUF_STRIDES) == PyBUF_STRIDES) {
// The consumer is fine with having a stride value.
row_size = format->get_total_bytes();
pad_fmt = false;
} else {
// The consumer expects a contiguous buffer. Give the
// stride as row size, and pad the format with extra bytes.
row_size = format->get_stride();
pad_fmt = true;
}
InternalBufferData *data = new InternalBufferData;
data->_handle = handle;
data->_num_rows = handle->get_num_rows();
data->_stride = format->get_stride();
data->_format = format->get_format_string(pad_fmt);
view->internal = (void*) data;
if (self != NULL) {
Py_INCREF(self);
}
view->obj = self;
view->buf = (void*) handle->get_read_pointer(true);
view->len = row_size * handle->get_num_rows();
view->readonly = 1;
view->itemsize = row_size;
view->format = NULL;
if ((flags & PyBUF_FORMAT) == PyBUF_FORMAT) {
view->format = (char*) data->_format.c_str();
}
view->ndim = 1;
view->shape = NULL;
if ((flags & PyBUF_ND) == PyBUF_ND) {
view->shape = &data->_num_rows;
}
view->strides = NULL;
if ((flags & PyBUF_STRIDES) == PyBUF_STRIDES) {
view->strides = &data->_stride;
}
view->suboffsets = NULL;
return 0;
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayData::__releasebuffer__
// Access: Published
// Description: Releases the buffer allocated by __getbuffer__.
////////////////////////////////////////////////////////////////////
void Extension<GeomVertexArrayData>::
__releasebuffer__(PyObject *self, Py_buffer *view) const {
// Note: PyBuffer_Release automatically decrements view->obj.
InternalBufferData *data;
data = (InternalBufferData *) view->internal;
if (data == NULL) {
return;
}
delete data;
view->internal = NULL;
}

View File

@ -0,0 +1,42 @@
// Filename: geomVertexArrayData_ext.h
// Created by: rdb (13Sep13)
//
////////////////////////////////////////////////////////////////////
//
// 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."
//
////////////////////////////////////////////////////////////////////
#ifndef GEOMVERTEXARRAYDATA_EXT_H
#define GEOMVERTEXARRAYDATA_EXT_H
#include "dtoolbase.h"
#ifdef HAVE_PYTHON
#include "extension.h"
#include "geomVertexArrayData.h"
#include "py_panda.h"
////////////////////////////////////////////////////////////////////
// Class : Extension<GeomVertexArrayData>
// Description : This class defines the extension methods for
// GeomVertexArrayData, which are called instead of
// any C++ methods with the same prototype.
////////////////////////////////////////////////////////////////////
template<>
class Extension<GeomVertexArrayData> : public ExtensionBase<GeomVertexArrayData> {
public:
int __getbuffer__(PyObject *self, Py_buffer *view, int flags);
int __getbuffer__(PyObject *self, Py_buffer *view, int flags) const;
void __releasebuffer__(PyObject *self, Py_buffer *view) const;
};
#endif // HAVE_PYTHON
#endif // GEOMVERTEXARRAYDATA_EXT_H

View File

@ -578,6 +578,83 @@ write_with_data(ostream &out, int indent_level,
}
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayFormat::get_format_string
// Access: Published
// Description: Returns a string with format codes representing the
// exact memory layout of the columns in memory, as
// understood by Python's struct module.
// If pad is true, extra padding bytes are added to
// the end as 'x' characters as needed.
////////////////////////////////////////////////////////////////////
string GeomVertexArrayFormat::
get_format_string(bool pad) const {
consider_sort_columns();
int row_size;
if (pad) {
row_size = get_stride();
} else {
row_size = get_total_bytes();
}
// Synthesize the format string.
char *fmt = (char*) malloc(row_size + 1);
memset((void*) fmt, 0, row_size + 1);
int fi = 0;
int offset = 0;
for (int ci = 0; ci < get_num_columns(); ++ci) {
const GeomVertexColumn *column = get_column(ci);
if (offset < column->get_start()) {
// Add padding bytes to fill the gap.
int pad = column->get_start() - offset;
memset((void*) (fmt + fi), 'x', pad);
fi += pad;
offset += pad;
}
char fmt_code = 'x';
switch (column->get_numeric_type()) {
case NT_uint8:
fmt_code = 'B';
break;
case NT_uint16:
fmt_code = 'H';
break;
case NT_uint32:
case NT_packed_dcba:
case NT_packed_dabc:
fmt_code = 'I';
break;
case NT_float32:
fmt_code = 'f';
break;
case NT_float64:
fmt_code = 'd';
break;
default:
gobj_cat.error()
<< "Unknown numeric type " << column->get_numeric_type() << "!\n";
return NULL;
}
memset((void*) (fmt + fi), fmt_code, column->get_num_components());
offset += column->get_total_bytes();
fi += column->get_num_components();
}
if (offset < row_size) {
// Add padding bytes.
int pad = row_size - offset;
memset((void*) (fmt + fi), 'x', pad);
}
string fmt_string (fmt);
free(fmt);
return fmt_string;
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayFormat::compare_to
// Access: Public

View File

@ -115,6 +115,8 @@ PUBLISHED:
void write_with_data(ostream &out, int indent_level,
const GeomVertexArrayData *array_data) const;
string get_format_string(bool pad = true) const;
public:
int compare_to(const GeomVertexArrayFormat &other) const;

View File

@ -15,7 +15,7 @@
coordinateSystem.h dbl2fltnames.h dblnames.h \
deg_2_rad.h deg_2_rad.I \
flt2dblnames.h fltnames.h lcast_to.h lcast_to_src.h \
lcast_to_src.I lmatrix.h lmatrix_ext.I lmatrix3_src.I \
lcast_to_src.I lmatrix.h lmatrix_ext.h lmatrix3_src.I \
lmatrix3_src.cxx lmatrix3_src.h lmatrix4_src.I \
lmatrix4_src.cxx lmatrix4_src.h lorientation.h \
lorientation_src.I lorientation_src.cxx lorientation_src.h \
@ -37,12 +37,12 @@
lvector3.h lvector3_src.I lvector3_src.cxx lvector3_src.h \
lvector4.h lvector4_src.I lvector4_src.cxx lvector4_src.h \
lvector4.h lvector4_src.I lvector4_src.cxx lvector4_src.h \
lvecBase2_ext.I lvecBase3_ext.I lvecBase4_ext.I \
lpoint2_ext.I lpoint3_ext.I lpoint4_ext.I \
lvector2_ext.I lvector3_ext.I lvector4_ext.I \
lvecBase2_ext.h lvecBase3_ext.h lvecBase4_ext.h \
lpoint2_ext.h lpoint3_ext.h lpoint4_ext.h \
lvector2_ext.h lvector3_ext.h lvector4_ext.h \
mathNumbers.h mathNumbers.I
#define INCLUDED_SOURCES \
#define INCLUDED_SOURCES \
compose_matrix.cxx config_linmath.cxx coordinateSystem.cxx \
lmatrix.cxx \
lorientation.cxx lpoint2.cxx \

View File

@ -18,10 +18,10 @@
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE void EXT_NESTED_METHOD_ARGS(FLOATNAME(LMatrix3), Row,
__setitem__, int i, FLOATTYPE v) {
INLINE_LINMATH void Extension<FLOATNAME(LMatrix3)::Row>::
__setitem__(int i, FLOATTYPE v) {
nassertv(i >= 0 && i < 3);
this->_row[i] = v;
_this->_row[i] = v;
}
////////////////////////////////////////////////////////////////////
@ -30,8 +30,8 @@ __setitem__, int i, FLOATTYPE v) {
// Description: This special Python method is implement to provide
// support for the pickle module.
////////////////////////////////////////////////////////////////////
PyObject *EXT_CONST_METHOD_ARGS(FLOATNAME(LMatrix3),
__reduce__, PyObject *self) {
INLINE_LINMATH PyObject *Extension<FLOATNAME(LMatrix3)>::
__reduce__(PyObject *self) const {
// We should return at least a 2-tuple, (Class, (args)): the
// necessary class object whose constructor we should call
// (e.g. this), and the arguments necessary to reconstruct this
@ -42,9 +42,9 @@ __reduce__, PyObject *self) {
}
PyObject *result = Py_BuildValue("(O(fffffffff))", this_class,
this->_m(0, 0), this->_m(0, 1), this->_m(0, 2),
this->_m(1, 0), this->_m(1, 1), this->_m(1, 2),
this->_m(2, 0), this->_m(2, 1), this->_m(2, 2));
_this->_m(0, 0), _this->_m(0, 1), _this->_m(0, 2),
_this->_m(1, 0), _this->_m(1, 1), _this->_m(1, 2),
_this->_m(2, 0), _this->_m(2, 1), _this->_m(2, 2));
Py_DECREF(this_class);
return result;
@ -55,19 +55,19 @@ __reduce__, PyObject *self) {
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
void EXT_CONST_METHOD_ARGS(FLOATNAME(LMatrix3),
python_repr, ostream &out, const string &class_name) {
INLINE_LINMATH void Extension<FLOATNAME(LMatrix3)>::
python_repr(ostream &out, const string &class_name) const {
out << class_name << "("
<< MAYBE_ZERO(this->_m(0, 0)) << ", "
<< MAYBE_ZERO(this->_m(0, 1)) << ", "
<< MAYBE_ZERO(this->_m(0, 2)) << ", "
<< MAYBE_ZERO(_this->_m(0, 0)) << ", "
<< MAYBE_ZERO(_this->_m(0, 1)) << ", "
<< MAYBE_ZERO(_this->_m(0, 2)) << ", "
<< MAYBE_ZERO(this->_m(1, 0)) << ", "
<< MAYBE_ZERO(this->_m(1, 1)) << ", "
<< MAYBE_ZERO(this->_m(1, 2)) << ", "
<< MAYBE_ZERO(_this->_m(1, 0)) << ", "
<< MAYBE_ZERO(_this->_m(1, 1)) << ", "
<< MAYBE_ZERO(_this->_m(1, 2)) << ", "
<< MAYBE_ZERO(this->_m(2, 0)) << ", "
<< MAYBE_ZERO(this->_m(2, 1)) << ", "
<< MAYBE_ZERO(this->_m(2, 2)) << ")";
<< MAYBE_ZERO(_this->_m(2, 0)) << ", "
<< MAYBE_ZERO(_this->_m(2, 1)) << ", "
<< MAYBE_ZERO(_this->_m(2, 2)) << ")";
}

View File

@ -0,0 +1,41 @@
// Filename: lmatrix3_ext_src.h
// Created by: rdb (12Sep13)
//
////////////////////////////////////////////////////////////////////
//
// 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."
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Class : Extension<LMatrix3::Row>
// Description : This class defines the extension methods for
// LMatrix3::Row, which are called instead of
// any C++ methods with the same prototype.
////////////////////////////////////////////////////////////////////
template<>
class Extension<FLOATNAME(LMatrix3)::Row> : public ExtensionBase<FLOATNAME(LMatrix3)::Row> {
public:
INLINE_LINMATH void __setitem__(int i, FLOATTYPE v);
};
////////////////////////////////////////////////////////////////////
// Class : Extension<LMatrix3>
// Description : This class defines the extension methods for
// LMatrix3, which are called instead of
// any C++ methods with the same prototype.
////////////////////////////////////////////////////////////////////
template<>
class Extension<FLOATNAME(LMatrix3)> : public ExtensionBase<FLOATNAME(LMatrix3)> {
public:
INLINE_LINMATH PyObject *__reduce__(PyObject *self) const;
INLINE_LINMATH void python_repr(ostream &out, const string &class_name) const;
};
#include "lmatrix3_ext_src.I"

View File

@ -63,7 +63,7 @@ PUBLISHED:
FLOATTYPE e20, FLOATTYPE e21, FLOATTYPE e22);
ALLOC_DELETED_CHAIN(FLOATNAME(LMatrix3));
EXTENSION(PyObject *__reduce__(PyObject *self) const);
EXTENSION(INLINE_LINMATH PyObject *__reduce__(PyObject *self) const);
void fill(FLOATTYPE fill_value);
INLINE_LINMATH void set(
@ -283,7 +283,7 @@ PUBLISHED:
void output(ostream &out) const;
void write(ostream &out, int indent_level = 0) const;
EXTENSION(void python_repr(ostream &out, const string &class_name) const);
EXTENSION(INLINE_LINMATH void python_repr(ostream &out, const string &class_name) const);
INLINE_LINMATH void generate_hash(ChecksumHashGenerator &hashgen) const;
void generate_hash(

View File

@ -18,10 +18,10 @@
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE void EXT_NESTED_METHOD_ARGS(FLOATNAME(LMatrix4), Row,
__setitem__, int i, FLOATTYPE v) {
INLINE_LINMATH void Extension<FLOATNAME(LMatrix4)::Row>::
__setitem__(int i, FLOATTYPE v) {
nassertv(i >= 0 && i < 4);
this->_row[i] = v;
_this->_row[i] = v;
}
////////////////////////////////////////////////////////////////////
@ -30,8 +30,8 @@ __setitem__, int i, FLOATTYPE v) {
// Description: This special Python method is implement to provide
// support for the pickle module.
////////////////////////////////////////////////////////////////////
PyObject *EXT_CONST_METHOD_ARGS(FLOATNAME(LMatrix4),
__reduce__, PyObject *self) {
INLINE_LINMATH PyObject *Extension<FLOATNAME(LMatrix4)>::
__reduce__(PyObject *self) const {
// We should return at least a 2-tuple, (Class, (args)): the
// necessary class object whose constructor we should call
// (e.g. this), and the arguments necessary to reconstruct this
@ -42,10 +42,10 @@ __reduce__, PyObject *self) {
}
PyObject *result = Py_BuildValue("(O(ffffffffffffffff))", this_class,
this->_m(0, 0), this->_m(0, 1), this->_m(0, 2), this->_m(0, 3),
this->_m(1, 0), this->_m(1, 1), this->_m(1, 2), this->_m(1, 3),
this->_m(2, 0), this->_m(2, 1), this->_m(2, 2), this->_m(2, 3),
this->_m(3, 0), this->_m(3, 1), this->_m(3, 2), this->_m(3, 3));
_this->_m(0, 0), _this->_m(0, 1), _this->_m(0, 2), _this->_m(0, 3),
_this->_m(1, 0), _this->_m(1, 1), _this->_m(1, 2), _this->_m(1, 3),
_this->_m(2, 0), _this->_m(2, 1), _this->_m(2, 2), _this->_m(2, 3),
_this->_m(3, 0), _this->_m(3, 1), _this->_m(3, 2), _this->_m(3, 3));
Py_DECREF(this_class);
return result;
@ -56,27 +56,27 @@ __reduce__, PyObject *self) {
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
void EXT_CONST_METHOD_ARGS(FLOATNAME(LMatrix4),
python_repr, ostream &out, const string &class_name) {
INLINE_LINMATH void Extension<FLOATNAME(LMatrix4)>::
python_repr(ostream &out, const string &class_name) const {
out << class_name << "("
<< MAYBE_ZERO(this->_m(0, 0)) << ", "
<< MAYBE_ZERO(this->_m(0, 1)) << ", "
<< MAYBE_ZERO(this->_m(0, 2)) << ", "
<< MAYBE_ZERO(this->_m(0, 3)) << ", "
<< MAYBE_ZERO(_this->_m(0, 0)) << ", "
<< MAYBE_ZERO(_this->_m(0, 1)) << ", "
<< MAYBE_ZERO(_this->_m(0, 2)) << ", "
<< MAYBE_ZERO(_this->_m(0, 3)) << ", "
<< MAYBE_ZERO(this->_m(1, 0)) << ", "
<< MAYBE_ZERO(this->_m(1, 1)) << ", "
<< MAYBE_ZERO(this->_m(1, 2)) << ", "
<< MAYBE_ZERO(this->_m(1, 3)) << ", "
<< MAYBE_ZERO(_this->_m(1, 0)) << ", "
<< MAYBE_ZERO(_this->_m(1, 1)) << ", "
<< MAYBE_ZERO(_this->_m(1, 2)) << ", "
<< MAYBE_ZERO(_this->_m(1, 3)) << ", "
<< MAYBE_ZERO(this->_m(2, 0)) << ", "
<< MAYBE_ZERO(this->_m(2, 1)) << ", "
<< MAYBE_ZERO(this->_m(2, 2)) << ", "
<< MAYBE_ZERO(this->_m(2, 3)) << ", "
<< MAYBE_ZERO(_this->_m(2, 0)) << ", "
<< MAYBE_ZERO(_this->_m(2, 1)) << ", "
<< MAYBE_ZERO(_this->_m(2, 2)) << ", "
<< MAYBE_ZERO(_this->_m(2, 3)) << ", "
<< MAYBE_ZERO(this->_m(3, 0)) << ", "
<< MAYBE_ZERO(this->_m(3, 1)) << ", "
<< MAYBE_ZERO(this->_m(3, 2)) << ", "
<< MAYBE_ZERO(this->_m(3, 3)) << ")";
<< MAYBE_ZERO(_this->_m(3, 0)) << ", "
<< MAYBE_ZERO(_this->_m(3, 1)) << ", "
<< MAYBE_ZERO(_this->_m(3, 2)) << ", "
<< MAYBE_ZERO(_this->_m(3, 3)) << ")";
}

View File

@ -0,0 +1,41 @@
// Filename: lmatrix4_ext_src.h
// Created by: rdb (12Sep13)
//
////////////////////////////////////////////////////////////////////
//
// 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."
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Class : Extension<LMatrix4::Row>
// Description : This class defines the extension methods for
// LMatrix4::Row, which are called instead of
// any C++ methods with the same prototype.
////////////////////////////////////////////////////////////////////
template<>
class Extension<FLOATNAME(LMatrix4)::Row> : public ExtensionBase<FLOATNAME(LMatrix4)::Row> {
public:
INLINE_LINMATH void __setitem__(int i, FLOATTYPE v);
};
////////////////////////////////////////////////////////////////////
// Class : Extension<LMatrix4>
// Description : This class defines the extension methods for
// LMatrix4, which are called instead of
// any C++ methods with the same prototype.
////////////////////////////////////////////////////////////////////
template<>
class Extension<FLOATNAME(LMatrix4)> : public ExtensionBase<FLOATNAME(LMatrix4)> {
public:
INLINE_LINMATH PyObject *__reduce__(PyObject *self) const;
INLINE_LINMATH void python_repr(ostream &out, const string &class_name) const;
};
#include "lmatrix4_ext_src.I"

View File

@ -63,7 +63,7 @@ PUBLISHED:
FLOATTYPE e30, FLOATTYPE e31, FLOATTYPE e32, FLOATTYPE e33);
ALLOC_DELETED_CHAIN(FLOATNAME(LMatrix4));
EXTENSION(PyObject *__reduce__(PyObject *self) const);
EXTENSION(INLINE_LINMATH PyObject *__reduce__(PyObject *self) const);
// Construct a 4x4 matrix given a 3x3 rotation matrix and an optional
// translation component.
@ -257,7 +257,7 @@ PUBLISHED:
void output(ostream &out) const;
void write(ostream &out, int indent_level = 0) const;
EXTENSION(void python_repr(ostream &out, const string &class_name) const);
EXTENSION(INLINE_LINMATH void python_repr(ostream &out, const string &class_name) const);
INLINE_LINMATH void generate_hash(ChecksumHashGenerator &hashgen) const;
void generate_hash(ChecksumHashGenerator &hashgen, FLOATTYPE scale) const;

View File

@ -1,5 +1,5 @@
// Filename: lmatrix_ext.I
// Created by: rdb (02Jan11)
// Filename: lmatrix_ext.h
// Created by: rdb (13Sep13)
//
////////////////////////////////////////////////////////////////////
//
@ -12,12 +12,18 @@
//
////////////////////////////////////////////////////////////////////
#ifndef LMATRIX_EXT_H
#define LMATRIX_EXT_H
#include "lmatrix.h"
#include "extension.h"
#include "fltnames.h"
#include "lmatrix3_ext_src.I"
#include "lmatrix4_ext_src.I"
#include "lmatrix3_ext_src.h"
#include "lmatrix4_ext_src.h"
#include "dblnames.h"
#include "lmatrix3_ext_src.I"
#include "lmatrix4_ext_src.I"
#include "lmatrix3_ext_src.h"
#include "lmatrix4_ext_src.h"
#endif

View File

@ -1,5 +1,5 @@
// Filename: lpoint2_ext.I
// Created by: rdb (02Jan11)
// Created by: rdb (13Sep13)
//
////////////////////////////////////////////////////////////////////
//
@ -12,11 +12,18 @@
//
////////////////////////////////////////////////////////////////////
#ifndef LPOINT2_EXT_H
#define LPOINT2_EXT_H
#include "lpoint2.h"
#include "extension.h"
#include "lvecBase2_ext.h"
#include "fltnames.h"
#include "lpoint2_ext_src.I"
#include "lpoint2_ext_src.h"
#include "dblnames.h"
#include "lpoint2_ext_src.I"
#include "lpoint2_ext_src.h"
#endif

View File

@ -12,9 +12,10 @@
//
////////////////////////////////////////////////////////////////////
#ifndef CPPPARSER
IMPORT_THIS struct Dtool_PyTypedObject FLOATNAME(Dtool_LPoint2);
IMPORT_THIS struct Dtool_PyTypedObject FLOATNAME(Dtool_LPoint3);
IMPORT_THIS struct Dtool_PyTypedObject FLOATNAME(Dtool_LPoint4);
#endif
////////////////////////////////////////////////////////////////////
@ -22,11 +23,11 @@ IMPORT_THIS struct Dtool_PyTypedObject FLOATNAME(Dtool_LPoint2);
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE void EXT_CONST_METHOD_ARGS(FLOATNAME(LPoint2),
python_repr, ostream &out, const string &class_name) {
INLINE_LINMATH void Extension<FLOATNAME(LPoint2)>::
python_repr(ostream &out, const string &class_name) const {
out << class_name << "("
<< MAYBE_ZERO(this->_v(0)) << ", "
<< MAYBE_ZERO(this->_v(1)) << ")";
<< MAYBE_ZERO(_this->_v(0)) << ", "
<< MAYBE_ZERO(_this->_v(1)) << ")";
}
////////////////////////////////////////////////////////////////////
@ -34,8 +35,8 @@ python_repr, ostream &out, const string &class_name) {
// Access: Published
// Description: This is used to implement swizzle masks.
////////////////////////////////////////////////////////////////////
INLINE PyObject *EXT_CONST_METHOD_ARGS(FLOATNAME(LPoint2),
__getattr__, const string &attr_name) {
INLINE_LINMATH PyObject *Extension<FLOATNAME(LPoint2)>::
__getattr__(const string &attr_name) const {
// Validate the attribute name.
for (string::const_iterator it = attr_name.begin(); it < attr_name.end(); it++) {
if (*it != 'x' && *it != 'y') {
@ -43,28 +44,43 @@ __getattr__, const string &attr_name) {
}
}
if (attr_name.size() == 1) {
return PyFloat_FromDouble(this->_v(attr_name[0] - 'x'));
switch (attr_name.size()) {
case 1:
return PyFloat_FromDouble(_this->_v(attr_name[0] - 'x'));
} else if (attr_name.size() == 2) {
FLOATNAME(LPoint2) *vec = new FLOATNAME(LPoint2);
vec->_v(0) = this->_v(attr_name[0] - 'x');
vec->_v(1) = this->_v(attr_name[1] - 'x');
return DTool_CreatePyInstance((void *)vec, FLOATNAME(Dtool_LPoint2), true, false);
case 2: {
FLOATNAME(LPoint2) *vec = new FLOATNAME(LPoint2);
vec->_v(0) = _this->_v(attr_name[0] - 'x');
vec->_v(1) = _this->_v(attr_name[1] - 'x');
return DTool_CreatePyInstance((void *)vec, FLOATNAME(Dtool_LPoint2), true, false);
} case 3: {
FLOATNAME(LPoint3) *vec = new FLOATNAME(LPoint3);
vec->_v(0) = _this->_v(attr_name[0] - 'x');
vec->_v(1) = _this->_v(attr_name[1] - 'x');
vec->_v(2) = _this->_v(attr_name[2] - 'x');
return DTool_CreatePyInstance((void *)vec, FLOATNAME(Dtool_LPoint3), true, false);
} case 4: {
FLOATNAME(LPoint4) *vec = new FLOATNAME(LPoint4);
vec->_v(0) = _this->_v(attr_name[0] - 'x');
vec->_v(1) = _this->_v(attr_name[1] - 'x');
vec->_v(2) = _this->_v(attr_name[2] - 'x');
vec->_v(3) = _this->_v(attr_name[3] - 'x');
return DTool_CreatePyInstance((void *)vec, FLOATNAME(Dtool_LPoint4), true, false);
}
}
return NULL;
}
int EXT_METHOD_ARGS(FLOATNAME(LVecBase2), __setattr__, PyObject*, const string&, PyObject*);
////////////////////////////////////////////////////////////////////
// Function: LPoint2::__setattr__
// Access: Published
// Description: This is used to implement write masks.
////////////////////////////////////////////////////////////////////
INLINE int EXT_METHOD_ARGS(FLOATNAME(LPoint2),
__setattr__, PyObject *self, const string &attr_name, PyObject *assign) {
return CALL_EXT_METHOD(FLOATNAME(LVecBase2), __setattr__, this, self, attr_name, assign);
INLINE_LINMATH int Extension<FLOATNAME(LPoint2)>::
__setattr__(PyObject *self, const string &attr_name, PyObject *assign) {
// Upcall to LVecBase2.
return invoke_extension<FLOATNAME(LVecBase2)>(_this, _self).__setattr__(self, attr_name, assign);
}

View File

@ -0,0 +1,30 @@
// Filename: lpoint2_ext_src.h
// Created by: rdb (13Sep13)
//
////////////////////////////////////////////////////////////////////
//
// 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."
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Class : Extension<LPoint2>
// Description : This class defines the extension methods for
// LPoint2, which are called instead of
// any C++ methods with the same prototype.
////////////////////////////////////////////////////////////////////
template<>
class Extension<FLOATNAME(LPoint2)> : public ExtensionBase<FLOATNAME(LPoint2)> {
public:
INLINE_LINMATH PyObject *__getattr__(const string &attr_name) const;
INLINE_LINMATH int __setattr__(PyObject *self, const string &attr_name, PyObject *assign);
INLINE_LINMATH void python_repr(ostream &out, const string &class_name) const;
};
#include "lpoint2_ext_src.I"

View File

@ -26,8 +26,8 @@ PUBLISHED:
INLINE_LINMATH FLOATNAME(LPoint2)(FLOATTYPE fill_value);
INLINE_LINMATH FLOATNAME(LPoint2)(FLOATTYPE x, FLOATTYPE y);
EXTENSION(PyObject *__getattr__(const string &attr_name) const);
EXTENSION(int __setattr__(PyObject *self, const string &attr_name, PyObject *assign));
EXTENSION(INLINE_LINMATH PyObject *__getattr__(const string &attr_name) const);
EXTENSION(INLINE_LINMATH int __setattr__(PyObject *self, const string &attr_name, PyObject *assign));
INLINE_LINMATH static const FLOATNAME(LPoint2) &zero();
INLINE_LINMATH static const FLOATNAME(LPoint2) &unit_x();

View File

@ -1,5 +1,5 @@
// Filename: lpoint3_ext.I
// Created by: rdb (02Jan11)
// Created by: rdb (13Sep13)
//
////////////////////////////////////////////////////////////////////
//
@ -12,11 +12,18 @@
//
////////////////////////////////////////////////////////////////////
#ifndef LPOINT3_EXT_H
#define LPOINT3_EXT_H
#include "lpoint3.h"
#include "extension.h"
#include "lvecBase3_ext.h"
#include "fltnames.h"
#include "lpoint3_ext_src.I"
#include "lpoint3_ext_src.h"
#include "dblnames.h"
#include "lpoint3_ext_src.I"
#include "lpoint3_ext_src.h"
#endif

View File

@ -12,10 +12,10 @@
//
////////////////////////////////////////////////////////////////////
#ifndef CPPPARSER
IMPORT_THIS struct Dtool_PyTypedObject FLOATNAME(Dtool_LPoint2);
IMPORT_THIS struct Dtool_PyTypedObject FLOATNAME(Dtool_LPoint3);
IMPORT_THIS struct Dtool_PyTypedObject FLOATNAME(Dtool_LPoint4);
#endif
////////////////////////////////////////////////////////////////////
@ -23,12 +23,12 @@ IMPORT_THIS struct Dtool_PyTypedObject FLOATNAME(Dtool_LPoint3);
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE void EXT_CONST_METHOD_ARGS(FLOATNAME(LPoint3),
python_repr, ostream &out, const string &class_name) {
INLINE_LINMATH void Extension<FLOATNAME(LPoint3)>::
python_repr(ostream &out, const string &class_name) const {
out << class_name << "("
<< MAYBE_ZERO(this->_v(0)) << ", "
<< MAYBE_ZERO(this->_v(1)) << ", "
<< MAYBE_ZERO(this->_v(2)) << ")";
<< MAYBE_ZERO(_this->_v(0)) << ", "
<< MAYBE_ZERO(_this->_v(1)) << ", "
<< MAYBE_ZERO(_this->_v(2)) << ")";
}
////////////////////////////////////////////////////////////////////
@ -36,8 +36,8 @@ python_repr, ostream &out, const string &class_name) {
// Access: Published
// Description: This is used to implement swizzle masks.
////////////////////////////////////////////////////////////////////
PyObject *EXT_CONST_METHOD_ARGS(FLOATNAME(LPoint3),
__getattr__, const string &attr_name) {
INLINE_LINMATH PyObject *Extension<FLOATNAME(LPoint3)>::
__getattr__(const string &attr_name) const {
// Validate the attribute name.
for (string::const_iterator it = attr_name.begin(); it < attr_name.end(); it++) {
if (*it < 'x' || *it > 'z') {
@ -45,35 +45,43 @@ __getattr__, const string &attr_name) {
}
}
if (attr_name.size() == 1) {
return PyFloat_FromDouble(this->_v(attr_name[0] - 'x'));
switch (attr_name.size()) {
case 1:
return PyFloat_FromDouble(_this->_v(attr_name[0] - 'x'));
} else if (attr_name.size() == 2) {
FLOATNAME(LPoint2) *vec = new FLOATNAME(LPoint2);
vec->_v(0) = this->_v(attr_name[0] - 'x');
vec->_v(1) = this->_v(attr_name[1] - 'x');
return DTool_CreatePyInstance((void *)vec, FLOATNAME(Dtool_LPoint2), true, false);
case 2: {
FLOATNAME(LPoint2) *vec = new FLOATNAME(LPoint2);
vec->_v(0) = _this->_v(attr_name[0] - 'x');
vec->_v(1) = _this->_v(attr_name[1] - 'x');
return DTool_CreatePyInstance((void *)vec, FLOATNAME(Dtool_LPoint2), true, false);
} else if (attr_name.size() == 3) {
FLOATNAME(LPoint3) *vec = new FLOATNAME(LPoint3);
vec->_v(0) = this->_v(attr_name[0] - 'x');
vec->_v(1) = this->_v(attr_name[1] - 'x');
vec->_v(2) = this->_v(attr_name[2] - 'x');
return DTool_CreatePyInstance((void *)vec, FLOATNAME(Dtool_LPoint3), true, false);
} case 3: {
FLOATNAME(LPoint3) *vec = new FLOATNAME(LPoint3);
vec->_v(0) = _this->_v(attr_name[0] - 'x');
vec->_v(1) = _this->_v(attr_name[1] - 'x');
vec->_v(2) = _this->_v(attr_name[2] - 'x');
return DTool_CreatePyInstance((void *)vec, FLOATNAME(Dtool_LPoint3), true, false);
} case 4: {
FLOATNAME(LPoint4) *vec = new FLOATNAME(LPoint4);
vec->_v(0) = _this->_v(attr_name[0] - 'x');
vec->_v(1) = _this->_v(attr_name[1] - 'x');
vec->_v(2) = _this->_v(attr_name[2] - 'x');
vec->_v(3) = _this->_v(attr_name[3] - 'x');
return DTool_CreatePyInstance((void *)vec, FLOATNAME(Dtool_LPoint4), true, false);
}
}
return NULL;
}
int EXT_METHOD_ARGS(FLOATNAME(LVecBase3), __setattr__, PyObject*, const string&, PyObject*);
////////////////////////////////////////////////////////////////////
// Function: LPoint3::__setattr__
// Access: Published
// Description: This is used to implement write masks.
////////////////////////////////////////////////////////////////////
INLINE int EXT_METHOD_ARGS(FLOATNAME(LPoint3),
__setattr__, PyObject *self, const string &attr_name, PyObject *assign) {
return CALL_EXT_METHOD(FLOATNAME(LVecBase3), __setattr__, this, self, attr_name, assign);
INLINE_LINMATH int Extension<FLOATNAME(LPoint3)>::
__setattr__(PyObject *self, const string &attr_name, PyObject *assign) {
// Upcall to LVecBase2.
return invoke_extension<FLOATNAME(LVecBase3)>(_this, _self).__setattr__(self, attr_name, assign);
}

View File

@ -0,0 +1,30 @@
// Filename: lpoint3_ext_src.h
// Created by: rdb (13Sep13)
//
////////////////////////////////////////////////////////////////////
//
// 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."
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Class : Extension<LPoint3>
// Description : This class defines the extension methods for
// LPoint3, which are called instead of
// any C++ methods with the same prototype.
////////////////////////////////////////////////////////////////////
template<>
class Extension<FLOATNAME(LPoint3)> : public ExtensionBase<FLOATNAME(LPoint3)> {
public:
INLINE_LINMATH PyObject *__getattr__(const string &attr_name) const;
INLINE_LINMATH int __setattr__(PyObject *self, const string &attr_name, PyObject *assign);
INLINE_LINMATH void python_repr(ostream &out, const string &class_name) const;
};
#include "lpoint3_ext_src.I"

View File

@ -31,8 +31,8 @@ PUBLISHED:
INLINE_LINMATH FLOATNAME(LPoint3)(FLOATTYPE fill_value);
INLINE_LINMATH FLOATNAME(LPoint3)(FLOATTYPE x, FLOATTYPE y, FLOATTYPE z);
EXTENSION(PyObject *__getattr__(const string &attr_name) const);
EXTENSION(int __setattr__(PyObject *self, const string &attr_name, PyObject *assign));
EXTENSION(INLINE_LINMATH PyObject *__getattr__(const string &attr_name) const);
EXTENSION(INLINE_LINMATH int __setattr__(PyObject *self, const string &attr_name, PyObject *assign));
INLINE_LINMATH static const FLOATNAME(LPoint3) &zero();
INLINE_LINMATH static const FLOATNAME(LPoint3) &unit_x();

View File

@ -1,5 +1,5 @@
// Filename: lpoint4_ext.I
// Created by: rdb (02Jan11)
// Created by: rdb (13Sep13)
//
////////////////////////////////////////////////////////////////////
//
@ -12,11 +12,18 @@
//
////////////////////////////////////////////////////////////////////
#ifndef LPOINT4_EXT_H
#define LPOINT4_EXT_H
#include "lpoint4.h"
#include "extension.h"
#include "lvecBase4_ext.h"
#include "fltnames.h"
#include "lpoint4_ext_src.I"
#include "lpoint4_ext_src.h"
#include "dblnames.h"
#include "lpoint4_ext_src.I"
#include "lpoint4_ext_src.h"
#endif

View File

@ -12,7 +12,6 @@
//
////////////////////////////////////////////////////////////////////
#ifndef CPPPARSER
IMPORT_THIS struct Dtool_PyTypedObject FLOATNAME(Dtool_LPoint2);
IMPORT_THIS struct Dtool_PyTypedObject FLOATNAME(Dtool_LPoint3);
@ -24,13 +23,13 @@ IMPORT_THIS struct Dtool_PyTypedObject FLOATNAME(Dtool_LPoint4);
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE void EXT_CONST_METHOD_ARGS(FLOATNAME(LPoint4),
python_repr, ostream &out, const string &class_name) {
INLINE_LINMATH void Extension<FLOATNAME(LPoint4)>::
python_repr(ostream &out, const string &class_name) const {
out << class_name << "("
<< MAYBE_ZERO(this->_v(0)) << ", "
<< MAYBE_ZERO(this->_v(1)) << ", "
<< MAYBE_ZERO(this->_v(2)) << ", "
<< MAYBE_ZERO(this->_v(3)) << ")";
<< MAYBE_ZERO(_this->_v(0)) << ", "
<< MAYBE_ZERO(_this->_v(1)) << ", "
<< MAYBE_ZERO(_this->_v(2)) << ", "
<< MAYBE_ZERO(_this->_v(3)) << ")";
}
////////////////////////////////////////////////////////////////////
@ -38,8 +37,8 @@ python_repr, ostream &out, const string &class_name) {
// Access: Published
// Description: This is used to implement swizzle masks.
////////////////////////////////////////////////////////////////////
INLINE PyObject *EXT_CONST_METHOD_ARGS(FLOATNAME(LPoint4),
__getattr__, const string &attr_name) {
INLINE_LINMATH PyObject *Extension<FLOATNAME(LPoint4)>::
__getattr__(const string &attr_name) const {
// Validate the attribute name.
for (string::const_iterator it = attr_name.begin(); it < attr_name.end(); it++) {
if (*it < 'w' || *it > 'z') {
@ -47,47 +46,47 @@ __getattr__, const string &attr_name) {
}
}
if (attr_name.size() == 1) {
if (attr_name[0] == 'w') {
return PyFloat_FromDouble(this->_v(3));
} else {
return PyFloat_FromDouble(this->_v(attr_name[0] - 'x'));
switch (attr_name.size()) {
case 1:
if (attr_name[0] == 'w') {
return PyFloat_FromDouble(_this->_v(3));
} else {
return PyFloat_FromDouble(_this->_v(attr_name[0] - 'x'));
}
case 2: {
FLOATNAME(LPoint2) *vec = new FLOATNAME(LPoint2);
vec->_v(0) = _this->_v((attr_name[0] == 'w') ? 3 : attr_name[0] - 'x');
vec->_v(1) = _this->_v((attr_name[1] == 'w') ? 3 : attr_name[1] - 'x');
return DTool_CreatePyInstance((void *)vec, FLOATNAME(Dtool_LPoint2), true, false);
} case 3: {
FLOATNAME(LPoint3) *vec = new FLOATNAME(LPoint3);
vec->_v(0) = _this->_v((attr_name[0] == 'w') ? 3 : attr_name[0] - 'x');
vec->_v(1) = _this->_v((attr_name[1] == 'w') ? 3 : attr_name[1] - 'x');
vec->_v(2) = _this->_v((attr_name[2] == 'w') ? 3 : attr_name[2] - 'x');
return DTool_CreatePyInstance((void *)vec, FLOATNAME(Dtool_LPoint3), true, false);
} case 4: {
FLOATNAME(LPoint4) *vec = new FLOATNAME(LPoint4);
vec->_v(0) = _this->_v((attr_name[0] == 'w') ? 3 : attr_name[0] - 'x');
vec->_v(1) = _this->_v((attr_name[1] == 'w') ? 3 : attr_name[1] - 'x');
vec->_v(2) = _this->_v((attr_name[2] == 'w') ? 3 : attr_name[2] - 'x');
vec->_v(3) = _this->_v((attr_name[3] == 'w') ? 3 : attr_name[3] - 'x');
return DTool_CreatePyInstance((void *)vec, FLOATNAME(Dtool_LPoint4), true, false);
}
} else if (attr_name.size() == 2) {
FLOATNAME(LPoint2) *vec = new FLOATNAME(LPoint2);
vec->_v(0) = this->_v((attr_name[0] == 'w') ? 3 : attr_name[0] - 'x');
vec->_v(1) = this->_v((attr_name[1] == 'w') ? 3 : attr_name[1] - 'x');
return DTool_CreatePyInstance((void *)vec, FLOATNAME(Dtool_LPoint2), true, false);
} else if (attr_name.size() == 3) {
FLOATNAME(LPoint3) *vec = new FLOATNAME(LPoint3);
vec->_v(0) = this->_v((attr_name[0] == 'w') ? 3 : attr_name[0] - 'x');
vec->_v(1) = this->_v((attr_name[1] == 'w') ? 3 : attr_name[1] - 'x');
vec->_v(2) = this->_v((attr_name[2] == 'w') ? 3 : attr_name[2] - 'x');
return DTool_CreatePyInstance((void *)vec, FLOATNAME(Dtool_LPoint3), true, false);
} else if (attr_name.size() == 4) {
FLOATNAME(LPoint4) *vec = new FLOATNAME(LPoint4);
vec->_v(0) = this->_v((attr_name[0] == 'w') ? 3 : attr_name[0] - 'x');
vec->_v(1) = this->_v((attr_name[1] == 'w') ? 3 : attr_name[1] - 'x');
vec->_v(2) = this->_v((attr_name[2] == 'w') ? 3 : attr_name[2] - 'x');
vec->_v(3) = this->_v((attr_name[3] == 'w') ? 3 : attr_name[3] - 'x');
return DTool_CreatePyInstance((void *)vec, FLOATNAME(Dtool_LPoint4), true, false);
}
return NULL;
}
int EXT_METHOD_ARGS(FLOATNAME(LVecBase4), __setattr__, PyObject*, const string&, PyObject*);
////////////////////////////////////////////////////////////////////
// Function: LPoint4::__setattr__
// Access: Published
// Description: This is used to implement write masks.
////////////////////////////////////////////////////////////////////
INLINE int EXT_METHOD_ARGS(FLOATNAME(LPoint4),
__setattr__, PyObject *self, const string &attr_name, PyObject *assign) {
return CALL_EXT_METHOD(FLOATNAME(LVecBase4), __setattr__, this, self, attr_name, assign);
INLINE_LINMATH int Extension<FLOATNAME(LPoint4)>::
__setattr__(PyObject *self, const string &attr_name, PyObject *assign) {
// Upcall to LVecBase4.
return invoke_extension<FLOATNAME(LVecBase4)>(_this, _self).__setattr__(self, attr_name, assign);
}

View File

@ -0,0 +1,30 @@
// Filename: lpoint4_ext_src.h
// Created by: rdb (13Sep13)
//
////////////////////////////////////////////////////////////////////
//
// 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."
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Class : Extension<LPoint4>
// Description : This class defines the extension methods for
// LPoint4, which are called instead of
// any C++ methods with the same prototype.
////////////////////////////////////////////////////////////////////
template<>
class Extension<FLOATNAME(LPoint4)> : public ExtensionBase<FLOATNAME(LPoint4)> {
public:
INLINE_LINMATH PyObject *__getattr__(const string &attr_name) const;
INLINE_LINMATH int __setattr__(PyObject *self, const string &attr_name, PyObject *assign);
INLINE_LINMATH void python_repr(ostream &out, const string &class_name) const;
};
#include "lpoint4_ext_src.I"

View File

@ -25,8 +25,8 @@ PUBLISHED:
INLINE_LINMATH FLOATNAME(LPoint4)(FLOATTYPE fill_value);
INLINE_LINMATH FLOATNAME(LPoint4)(FLOATTYPE x, FLOATTYPE y, FLOATTYPE z, FLOATTYPE w);
EXTENSION(PyObject *__getattr__(const string &attr_name) const);
EXTENSION(int __setattr__(PyObject *self, const string &attr_name, PyObject *assign));
EXTENSION(INLINE_LINMATH PyObject *__getattr__(const string &attr_name) const);
EXTENSION(INLINE_LINMATH int __setattr__(PyObject *self, const string &attr_name, PyObject *assign));
INLINE_LINMATH static const FLOATNAME(LPoint4) &zero();
INLINE_LINMATH static const FLOATNAME(LPoint4) &unit_x();

View File

@ -1,5 +1,5 @@
// Filename: lvecBase2_ext.I
// Created by: rdb (02Jan11)
// Created by: rdb (13Sep13)
//
////////////////////////////////////////////////////////////////////
//
@ -12,11 +12,16 @@
//
////////////////////////////////////////////////////////////////////
#ifndef LVECBASE2_EXT_H
#define LVECBASE2_EXT_H
#include "lvecBase2.h"
#include "extension.h"
#include "fltnames.h"
#include "lvecBase2_ext_src.I"
#include "lvecBase2_ext_src.h"
#include "dblnames.h"
#include "lvecBase2_ext_src.I"
#include "lvecBase2_ext_src.h"
#endif

View File

@ -24,10 +24,10 @@ IMPORT_THIS struct Dtool_PyTypedObject FLOATNAME(Dtool_LVecBase4);
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE void EXT_METHOD_ARGS(FLOATNAME(LVecBase2),
__setitem__, int i, FLOATTYPE v) {
INLINE_LINMATH void Extension<FLOATNAME(LVecBase2)>::
__setitem__(int i, FLOATTYPE v) {
nassertv(i >= 0 && i < 2);
this->_v(i) = v;
_this->_v(i) = v;
}
////////////////////////////////////////////////////////////////////
@ -35,11 +35,11 @@ __setitem__, int i, FLOATTYPE v) {
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE void EXT_CONST_METHOD_ARGS(FLOATNAME(LVecBase2),
python_repr, ostream &out, const string &class_name) {
INLINE_LINMATH void Extension<FLOATNAME(LVecBase2)>::
python_repr(ostream &out, const string &class_name) const {
out << class_name << "("
<< MAYBE_ZERO(this->_v(0)) << ", "
<< MAYBE_ZERO(this->_v(1)) << ")";
<< MAYBE_ZERO(_this->_v(0)) << ", "
<< MAYBE_ZERO(_this->_v(1)) << ")";
}
////////////////////////////////////////////////////////////////////
@ -48,8 +48,8 @@ python_repr, ostream &out, const string &class_name) {
// Description: This special Python method is implement to provide
// support for the pickle module.
////////////////////////////////////////////////////////////////////
INLINE PyObject *EXT_CONST_METHOD_ARGS(FLOATNAME(LVecBase2),
__reduce__, PyObject *self) {
INLINE_LINMATH PyObject *Extension<FLOATNAME(LVecBase2)>::
__reduce__(PyObject *self) const {
// We should return at least a 2-tuple, (Class, (args)): the
// necessary class object whose constructor we should call
// (e.g. this), and the arguments necessary to reconstruct this
@ -60,7 +60,7 @@ __reduce__, PyObject *self) {
}
PyObject *result = Py_BuildValue("(O(ff))", this_class,
(*this)[0], (*this)[1]);
(*_this)[0], (*_this)[1]);
Py_DECREF(this_class);
return result;
}
@ -70,8 +70,8 @@ __reduce__, PyObject *self) {
// Access: Published
// Description: This is used to implement swizzle masks.
////////////////////////////////////////////////////////////////////
PyObject *EXT_CONST_METHOD_ARGS(FLOATNAME(LVecBase2),
__getattr__, const string &attr_name) {
INLINE_LINMATH PyObject *Extension<FLOATNAME(LVecBase2)>::
__getattr__(const string &attr_name) const {
// Validate the attribute name.
for (string::const_iterator it = attr_name.begin(); it < attr_name.end(); it++) {
if (*it != 'x' && *it != 'y') {
@ -79,29 +79,31 @@ __getattr__, const string &attr_name) {
}
}
if (attr_name.size() == 1) {
return PyFloat_FromDouble(this->_v(attr_name[0] - 'x'));
switch (attr_name.size()) {
case 1:
return PyFloat_FromDouble(_this->_v(attr_name[0] - 'x'));
} else if (attr_name.size() == 2) {
FLOATNAME(LVecBase2) *vec = new FLOATNAME(LVecBase2);
vec->_v(0) = this->_v(attr_name[0] - 'x');
vec->_v(1) = this->_v(attr_name[1] - 'x');
return DTool_CreatePyInstance((void *)vec, FLOATNAME(Dtool_LVecBase2), true, false);
case 2: {
FLOATNAME(LVecBase2) *vec = new FLOATNAME(LVecBase2);
vec->_v(0) = _this->_v(attr_name[0] - 'x');
vec->_v(1) = _this->_v(attr_name[1] - 'x');
return DTool_CreatePyInstance((void *)vec, FLOATNAME(Dtool_LVecBase2), true, false);
} else if (attr_name.size() == 3) {
FLOATNAME(LVecBase3) *vec = new FLOATNAME(LVecBase3);
vec->_v(0) = this->_v(attr_name[0] - 'x');
vec->_v(1) = this->_v(attr_name[1] - 'x');
vec->_v(2) = this->_v(attr_name[2] - 'x');
return DTool_CreatePyInstance((void *)vec, FLOATNAME(Dtool_LVecBase3), true, false);
} case 3: {
FLOATNAME(LVecBase3) *vec = new FLOATNAME(LVecBase3);
vec->_v(0) = _this->_v(attr_name[0] - 'x');
vec->_v(1) = _this->_v(attr_name[1] - 'x');
vec->_v(2) = _this->_v(attr_name[2] - 'x');
return DTool_CreatePyInstance((void *)vec, FLOATNAME(Dtool_LVecBase3), true, false);
} else if (attr_name.size() == 4) {
FLOATNAME(LVecBase4) *vec = new FLOATNAME(LVecBase4);
vec->_v(0) = this->_v(attr_name[0] - 'x');
vec->_v(1) = this->_v(attr_name[1] - 'x');
vec->_v(2) = this->_v(attr_name[2] - 'x');
vec->_v(3) = this->_v(attr_name[3] - 'x');
return DTool_CreatePyInstance((void *)vec, FLOATNAME(Dtool_LVecBase4), true, false);
} case 4: {
FLOATNAME(LVecBase4) *vec = new FLOATNAME(LVecBase4);
vec->_v(0) = _this->_v(attr_name[0] - 'x');
vec->_v(1) = _this->_v(attr_name[1] - 'x');
vec->_v(2) = _this->_v(attr_name[2] - 'x');
vec->_v(3) = _this->_v(attr_name[3] - 'x');
return DTool_CreatePyInstance((void *)vec, FLOATNAME(Dtool_LVecBase4), true, false);
}
}
return NULL;
@ -112,8 +114,8 @@ __getattr__, const string &attr_name) {
// Access: Published
// Description: This is used to implement write masks.
////////////////////////////////////////////////////////////////////
int EXT_METHOD_ARGS(FLOATNAME(LVecBase2),
__setattr__, PyObject *self, const string &attr_name, PyObject *assign) {
INLINE_LINMATH int Extension<FLOATNAME(LVecBase2)>::
__setattr__(PyObject *self, const string &attr_name, PyObject *assign) {
#ifndef NDEBUG
// Validate the attribute name.
for (string::const_iterator it = attr_name.begin(); it < attr_name.end(); it++) {
@ -156,7 +158,7 @@ __setattr__, PyObject *self, const string &attr_name, PyObject *assign) {
double value = PyFloat_AS_DOUBLE(fl);
Py_DECREF(fl);
this->_v(attr_name[i] - 'x') = value;
_this->_v(attr_name[i] - 'x') = value;
}
Py_DECREF(fast);
@ -181,7 +183,7 @@ __setattr__, PyObject *self, const string &attr_name, PyObject *assign) {
// Loop through the components in the attribute name,
// and assign the floating-point value to every one of them.
for (string::const_iterator it = attr_name.begin(); it < attr_name.end(); it++) {
this->_v((*it) - 'x') = value;
_this->_v((*it) - 'x') = value;
}
}

View File

@ -0,0 +1,32 @@
// Filename: lvecBase2_ext_src.h
// Created by: rdb (13Sep13)
//
////////////////////////////////////////////////////////////////////
//
// 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."
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Class : Extension<LVecBase2>
// Description : This class defines the extension methods for
// LVecBase2, which are called instead of
// any C++ methods with the same prototype.
////////////////////////////////////////////////////////////////////
template<>
class Extension<FLOATNAME(LVecBase2)> : public ExtensionBase<FLOATNAME(LVecBase2)> {
public:
INLINE_LINMATH PyObject *__reduce__(PyObject *self) const;
INLINE_LINMATH PyObject *__getattr__(const string &attr_name) const;
INLINE_LINMATH int __setattr__(PyObject *self, const string &attr_name, PyObject *assign);
INLINE_LINMATH void __setitem__(int i, FLOATTYPE v);
INLINE_LINMATH void python_repr(ostream &out, const string &class_name) const;
};
#include "lvecBase2_ext_src.I"

View File

@ -37,9 +37,9 @@ PUBLISHED:
INLINE_LINMATH ~FLOATNAME(LVecBase2)();
EXTENSION(PyObject *__reduce__(PyObject *self) const);
EXTENSION(PyObject *__getattr__(const string &attr_name) const);
EXTENSION(int __setattr__(PyObject *self, const string &attr_name, PyObject *assign));
EXTENSION(INLINE_LINMATH PyObject *__reduce__(PyObject *self) const);
EXTENSION(INLINE_LINMATH PyObject *__getattr__(const string &attr_name) const);
EXTENSION(INLINE_LINMATH int __setattr__(PyObject *self, const string &attr_name, PyObject *assign));
INLINE_LINMATH FLOATTYPE operator [](int i) const;
INLINE_LINMATH FLOATTYPE &operator [](int i);

View File

@ -1,5 +1,5 @@
// Filename: lvecBase3_ext.I
// Created by: rdb (02Jan11)
// Created by: rdb (13Sep13)
//
////////////////////////////////////////////////////////////////////
//
@ -12,11 +12,16 @@
//
////////////////////////////////////////////////////////////////////
#ifndef LVECBASE3_EXT_H
#define LVECBASE3_EXT_H
#include "lvecBase3.h"
#include "extension.h"
#include "fltnames.h"
#include "lvecBase3_ext_src.I"
#include "lvecBase3_ext_src.h"
#include "dblnames.h"
#include "lvecBase3_ext_src.I"
#include "lvecBase3_ext_src.h"
#endif

View File

@ -24,10 +24,10 @@ IMPORT_THIS struct Dtool_PyTypedObject FLOATNAME(Dtool_LVecBase4);
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE void EXT_METHOD_ARGS(FLOATNAME(LVecBase3),
__setitem__, int i, FLOATTYPE v) {
INLINE_LINMATH void Extension<FLOATNAME(LVecBase3)>::
__setitem__(int i, FLOATTYPE v) {
nassertv(i >= 0 && i < 3);
this->_v(i) = v;
_this->_v(i) = v;
}
////////////////////////////////////////////////////////////////////
@ -35,12 +35,12 @@ __setitem__, int i, FLOATTYPE v) {
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE void EXT_CONST_METHOD_ARGS(FLOATNAME(LVecBase3),
python_repr, ostream &out, const string &class_name) {
INLINE_LINMATH void Extension<FLOATNAME(LVecBase3)>::
python_repr(ostream &out, const string &class_name) const {
out << class_name << "("
<< MAYBE_ZERO(this->_v(0)) << ", "
<< MAYBE_ZERO(this->_v(1)) << ", "
<< MAYBE_ZERO(this->_v(2)) << ")";
<< MAYBE_ZERO(_this->_v(0)) << ", "
<< MAYBE_ZERO(_this->_v(1)) << ", "
<< MAYBE_ZERO(_this->_v(2)) << ")";
}
////////////////////////////////////////////////////////////////////
@ -49,8 +49,8 @@ python_repr, ostream &out, const string &class_name) {
// Description: This special Python method is implement to provide
// support for the pickle module.
////////////////////////////////////////////////////////////////////
INLINE PyObject *EXT_CONST_METHOD_ARGS(FLOATNAME(LVecBase3),
__reduce__, PyObject *self) {
INLINE_LINMATH PyObject *Extension<FLOATNAME(LVecBase3)>::
__reduce__(PyObject *self) const {
// We should return at least a 2-tuple, (Class, (args)): the
// necessary class object whose constructor we should call
// (e.g. this), and the arguments necessary to reconstruct this
@ -61,7 +61,7 @@ __reduce__, PyObject *self) {
}
PyObject *result = Py_BuildValue("(O(fff))", this_class,
(*this)[0], (*this)[1], (*this)[2]);
(*_this)[0], (*_this)[1], (*_this)[2]);
Py_DECREF(this_class);
return result;
}
@ -71,8 +71,8 @@ __reduce__, PyObject *self) {
// Access: Published
// Description: This is used to implement swizzle masks.
////////////////////////////////////////////////////////////////////
PyObject *EXT_CONST_METHOD_ARGS(FLOATNAME(LVecBase3),
__getattr__, const string &attr_name) {
INLINE_LINMATH PyObject *Extension<FLOATNAME(LVecBase3)>::
__getattr__(const string &attr_name) const {
// Validate the attribute name.
for (string::const_iterator it = attr_name.begin(); it < attr_name.end(); it++) {
if (*it < 'x' || *it > 'z') {
@ -80,29 +80,31 @@ __getattr__, const string &attr_name) {
}
}
if (attr_name.size() == 1) {
return PyFloat_FromDouble(this->_v(attr_name[0] - 'x'));
switch (attr_name.size()) {
case 1:
return PyFloat_FromDouble(_this->_v(attr_name[0] - 'x'));
} else if (attr_name.size() == 2) {
FLOATNAME(LVecBase2) *vec = new FLOATNAME(LVecBase2);
vec->_v(0) = this->_v(attr_name[0] - 'x');
vec->_v(1) = this->_v(attr_name[1] - 'x');
return DTool_CreatePyInstance((void *)vec, FLOATNAME(Dtool_LVecBase2), true, false);
case 2: {
FLOATNAME(LVecBase2) *vec = new FLOATNAME(LVecBase2);
vec->_v(0) = _this->_v(attr_name[0] - 'x');
vec->_v(1) = _this->_v(attr_name[1] - 'x');
return DTool_CreatePyInstance((void *)vec, FLOATNAME(Dtool_LVecBase2), true, false);
} else if (attr_name.size() == 3) {
FLOATNAME(LVecBase3) *vec = new FLOATNAME(LVecBase3);
vec->_v(0) = this->_v(attr_name[0] - 'x');
vec->_v(1) = this->_v(attr_name[1] - 'x');
vec->_v(2) = this->_v(attr_name[2] - 'x');
return DTool_CreatePyInstance((void *)vec, FLOATNAME(Dtool_LVecBase3), true, false);
} case 3: {
FLOATNAME(LVecBase3) *vec = new FLOATNAME(LVecBase3);
vec->_v(0) = _this->_v(attr_name[0] - 'x');
vec->_v(1) = _this->_v(attr_name[1] - 'x');
vec->_v(2) = _this->_v(attr_name[2] - 'x');
return DTool_CreatePyInstance((void *)vec, FLOATNAME(Dtool_LVecBase3), true, false);
} else if (attr_name.size() == 4) {
FLOATNAME(LVecBase4) *vec = new FLOATNAME(LVecBase4);
vec->_v(0) = this->_v(attr_name[0] - 'x');
vec->_v(1) = this->_v(attr_name[1] - 'x');
vec->_v(2) = this->_v(attr_name[2] - 'x');
vec->_v(3) = this->_v(attr_name[3] - 'x');
return DTool_CreatePyInstance((void *)vec, FLOATNAME(Dtool_LVecBase4), true, false);
} case 4: {
FLOATNAME(LVecBase4) *vec = new FLOATNAME(LVecBase4);
vec->_v(0) = _this->_v(attr_name[0] - 'x');
vec->_v(1) = _this->_v(attr_name[1] - 'x');
vec->_v(2) = _this->_v(attr_name[2] - 'x');
vec->_v(3) = _this->_v(attr_name[3] - 'x');
return DTool_CreatePyInstance((void *)vec, FLOATNAME(Dtool_LVecBase4), true, false);
}
}
return NULL;
@ -113,8 +115,8 @@ __getattr__, const string &attr_name) {
// Access: Published
// Description: This is used to implement write masks.
////////////////////////////////////////////////////////////////////
int EXT_METHOD_ARGS(FLOATNAME(LVecBase3),
__setattr__, PyObject *self, const string &attr_name, PyObject *assign) {
INLINE_LINMATH int Extension<FLOATNAME(LVecBase3)>::
__setattr__(PyObject *self, const string &attr_name, PyObject *assign) {
#ifndef NDEBUG
// Validate the attribute name.
for (string::const_iterator it = attr_name.begin(); it < attr_name.end(); it++) {
@ -157,7 +159,7 @@ __setattr__, PyObject *self, const string &attr_name, PyObject *assign) {
double value = PyFloat_AS_DOUBLE(fl);
Py_DECREF(fl);
this->_v(attr_name[i] - 'x') = value;
_this->_v(attr_name[i] - 'x') = value;
}
Py_DECREF(fast);
@ -182,7 +184,7 @@ __setattr__, PyObject *self, const string &attr_name, PyObject *assign) {
// Loop through the components in the attribute name,
// and assign the floating-point value to every one of them.
for (string::const_iterator it = attr_name.begin(); it < attr_name.end(); it++) {
this->_v((*it) - 'x') = value;
_this->_v((*it) - 'x') = value;
}
}

View File

@ -0,0 +1,32 @@
// Filename: lvecBase3_ext_src.h
// Created by: rdb (13Sep13)
//
////////////////////////////////////////////////////////////////////
//
// 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."
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Class : Extension<LVecBase3>
// Description : This class defines the extension methods for
// LVecBase3, which are called instead of
// any C++ methods with the same prototype.
////////////////////////////////////////////////////////////////////
template<>
class Extension<FLOATNAME(LVecBase3)> : public ExtensionBase<FLOATNAME(LVecBase3)> {
public:
INLINE_LINMATH PyObject *__reduce__(PyObject *self) const;
INLINE_LINMATH PyObject *__getattr__(const string &attr_name) const;
INLINE_LINMATH int __setattr__(PyObject *self, const string &attr_name, PyObject *assign);
INLINE_LINMATH void __setitem__(int i, FLOATTYPE v);
INLINE_LINMATH void python_repr(ostream &out, const string &class_name) const;
};
#include "lvecBase3_ext_src.I"

View File

@ -38,9 +38,9 @@ PUBLISHED:
INLINE_LINMATH ~FLOATNAME(LVecBase3)();
EXTENSION(PyObject *__reduce__(PyObject *self) const);
EXTENSION(PyObject *__getattr__(const string &attr_name) const);
EXTENSION(int __setattr__(PyObject *self, const string &attr_name, PyObject *assign));
EXTENSION(INLINE_LINMATH PyObject *__reduce__(PyObject *self) const);
EXTENSION(INLINE_LINMATH PyObject *__getattr__(const string &attr_name) const);
EXTENSION(INLINE_LINMATH int __setattr__(PyObject *self, const string &attr_name, PyObject *assign));
INLINE_LINMATH FLOATTYPE operator [](int i) const;
INLINE_LINMATH FLOATTYPE &operator [](int i);

View File

@ -1,5 +1,5 @@
// Filename: lvecBase4_ext.I
// Created by: rdb (02Jan11)
// Created by: rdb (13Sep13)
//
////////////////////////////////////////////////////////////////////
//
@ -12,11 +12,16 @@
//
////////////////////////////////////////////////////////////////////
#ifndef LVECBASE4_EXT_H
#define LVECBASE4_EXT_H
#include "lvecBase4.h"
#include "extension.h"
#include "fltnames.h"
#include "lvecBase4_ext_src.I"
#include "lvecBase4_ext_src.h"
#include "dblnames.h"
#include "lvecBase4_ext_src.I"
#include "lvecBase4_ext_src.h"
#endif

View File

@ -24,10 +24,10 @@ IMPORT_THIS struct Dtool_PyTypedObject FLOATNAME(Dtool_LVecBase4);
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE void EXT_METHOD_ARGS(FLOATNAME(LVecBase4),
__setitem__, int i, FLOATTYPE v) {
INLINE_LINMATH void Extension<FLOATNAME(LVecBase4)>::
__setitem__(int i, FLOATTYPE v) {
nassertv(i >= 0 && i < 4);
this->_v(i) = v;
_this->_v(i) = v;
}
////////////////////////////////////////////////////////////////////
@ -35,13 +35,13 @@ __setitem__, int i, FLOATTYPE v) {
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE void EXT_CONST_METHOD_ARGS(FLOATNAME(LVecBase4),
python_repr, ostream &out, const string &class_name) {
INLINE_LINMATH void Extension<FLOATNAME(LVecBase4)>::
python_repr(ostream &out, const string &class_name) const {
out << class_name << "("
<< MAYBE_ZERO(this->_v(0)) << ", "
<< MAYBE_ZERO(this->_v(1)) << ", "
<< MAYBE_ZERO(this->_v(2)) << ", "
<< MAYBE_ZERO(this->_v(3)) << ")";
<< MAYBE_ZERO(_this->_v(0)) << ", "
<< MAYBE_ZERO(_this->_v(1)) << ", "
<< MAYBE_ZERO(_this->_v(2)) << ", "
<< MAYBE_ZERO(_this->_v(3)) << ")";
}
////////////////////////////////////////////////////////////////////
@ -50,8 +50,8 @@ python_repr, ostream &out, const string &class_name) {
// Description: This special Python method is implement to provide
// support for the pickle module.
////////////////////////////////////////////////////////////////////
INLINE PyObject *EXT_CONST_METHOD_ARGS(FLOATNAME(LVecBase4),
__reduce__, PyObject *self) {
INLINE_LINMATH PyObject *Extension<FLOATNAME(LVecBase4)>::
__reduce__(PyObject *self) const {
// We should return at least a 2-tuple, (Class, (args)): the
// necessary class object whose constructor we should call
// (e.g. this), and the arguments necessary to reconstruct this
@ -62,7 +62,7 @@ __reduce__, PyObject *self) {
}
PyObject *result = Py_BuildValue("(O(ffff))", this_class,
(*this)[0], (*this)[1], (*this)[2], (*this)[3]);
(*_this)[0], (*_this)[1], (*_this)[2], (*_this)[3]);
Py_DECREF(this_class);
return result;
}
@ -72,8 +72,8 @@ __reduce__, PyObject *self) {
// Access: Published
// Description: This is used to implement swizzle masks.
////////////////////////////////////////////////////////////////////
PyObject *EXT_CONST_METHOD_ARGS(FLOATNAME(LVecBase4),
__getattr__, const string &attr_name) {
INLINE_LINMATH PyObject *Extension<FLOATNAME(LVecBase4)>::
__getattr__(const string &attr_name) const {
// Validate the attribute name.
for (string::const_iterator it = attr_name.begin(); it < attr_name.end(); it++) {
if (*it < 'w' || *it > 'z') {
@ -81,33 +81,35 @@ __getattr__, const string &attr_name) {
}
}
if (attr_name.size() == 1) {
if (attr_name[0] == 'w') {
return PyFloat_FromDouble(this->_v(3));
} else {
return PyFloat_FromDouble(this->_v(attr_name[0] - 'x'));
switch (attr_name.size()) {
case 1:
if (attr_name[0] == 'w') {
return PyFloat_FromDouble(_this->_v(3));
} else {
return PyFloat_FromDouble(_this->_v(attr_name[0] - 'x'));
}
case 2: {
FLOATNAME(LVecBase2) *vec = new FLOATNAME(LVecBase2);
vec->_v(0) = _this->_v((attr_name[0] == 'w') ? 3 : attr_name[0] - 'x');
vec->_v(1) = _this->_v((attr_name[1] == 'w') ? 3 : attr_name[1] - 'x');
return DTool_CreatePyInstance((void *)vec, FLOATNAME(Dtool_LVecBase2), true, false);
} case 3: {
FLOATNAME(LVecBase3) *vec = new FLOATNAME(LVecBase3);
vec->_v(0) = _this->_v((attr_name[0] == 'w') ? 3 : attr_name[0] - 'x');
vec->_v(1) = _this->_v((attr_name[1] == 'w') ? 3 : attr_name[1] - 'x');
vec->_v(2) = _this->_v((attr_name[2] == 'w') ? 3 : attr_name[2] - 'x');
return DTool_CreatePyInstance((void *)vec, FLOATNAME(Dtool_LVecBase3), true, false);
} case 4: {
FLOATNAME(LVecBase4) *vec = new FLOATNAME(LVecBase4);
vec->_v(0) = _this->_v((attr_name[0] == 'w') ? 3 : attr_name[0] - 'x');
vec->_v(1) = _this->_v((attr_name[1] == 'w') ? 3 : attr_name[1] - 'x');
vec->_v(2) = _this->_v((attr_name[2] == 'w') ? 3 : attr_name[2] - 'x');
vec->_v(3) = _this->_v((attr_name[3] == 'w') ? 3 : attr_name[3] - 'x');
return DTool_CreatePyInstance((void *)vec, FLOATNAME(Dtool_LVecBase4), true, false);
}
} else if (attr_name.size() == 2) {
FLOATNAME(LVecBase2) *vec = new FLOATNAME(LVecBase2);
vec->_v(0) = this->_v((attr_name[0] == 'w') ? 3 : attr_name[0] - 'x');
vec->_v(1) = this->_v((attr_name[1] == 'w') ? 3 : attr_name[1] - 'x');
return DTool_CreatePyInstance((void *)vec, FLOATNAME(Dtool_LVecBase2), true, false);
} else if (attr_name.size() == 3) {
FLOATNAME(LVecBase3) *vec = new FLOATNAME(LVecBase3);
vec->_v(0) = this->_v((attr_name[0] == 'w') ? 3 : attr_name[0] - 'x');
vec->_v(1) = this->_v((attr_name[1] == 'w') ? 3 : attr_name[1] - 'x');
vec->_v(2) = this->_v((attr_name[2] == 'w') ? 3 : attr_name[2] - 'x');
return DTool_CreatePyInstance((void *)vec, FLOATNAME(Dtool_LVecBase3), true, false);
} else if (attr_name.size() == 4) {
FLOATNAME(LVecBase4) *vec = new FLOATNAME(LVecBase4);
vec->_v(0) = this->_v((attr_name[0] == 'w') ? 3 : attr_name[0] - 'x');
vec->_v(1) = this->_v((attr_name[1] == 'w') ? 3 : attr_name[1] - 'x');
vec->_v(2) = this->_v((attr_name[2] == 'w') ? 3 : attr_name[2] - 'x');
vec->_v(3) = this->_v((attr_name[3] == 'w') ? 3 : attr_name[3] - 'x');
return DTool_CreatePyInstance((void *)vec, FLOATNAME(Dtool_LVecBase4), true, false);
}
return NULL;
@ -118,8 +120,8 @@ __getattr__, const string &attr_name) {
// Access: Published
// Description: This is used to implement write masks.
////////////////////////////////////////////////////////////////////
int EXT_METHOD_ARGS(FLOATNAME(LVecBase4),
__setattr__, PyObject *self, const string &attr_name, PyObject *assign) {
INLINE_LINMATH int Extension<FLOATNAME(LVecBase4)>::
__setattr__(PyObject *self, const string &attr_name, PyObject *assign) {
#ifndef NDEBUG
// Validate the attribute name.
for (string::const_iterator it = attr_name.begin(); it < attr_name.end(); it++) {
@ -162,7 +164,7 @@ __setattr__, PyObject *self, const string &attr_name, PyObject *assign) {
double value = PyFloat_AS_DOUBLE(fl);
Py_DECREF(fl);
this->_v((attr_name[i] == 'w') ? 3 : attr_name[i] - 'x') = value;
_this->_v((attr_name[i] == 'w') ? 3 : attr_name[i] - 'x') = value;
}
Py_DECREF(fast);
@ -187,21 +189,20 @@ __setattr__, PyObject *self, const string &attr_name, PyObject *assign) {
// Loop through the components in the attribute name,
// and assign the floating-point value to every one of them.
for (string::const_iterator it = attr_name.begin(); it < attr_name.end(); it++) {
this->_v(((*it) == 'w') ? 3 : (*it) - 'x') = value;
_this->_v(((*it) == 'w') ? 3 : (*it) - 'x') = value;
}
}
return 0;
}
////////////////////////////////////////////////////////////////////
// Function: UnalignedLVecBase4::__setitem__
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE void EXT_METHOD_ARGS(FLOATNAME(UnalignedLVecBase4),
__setitem__, int i, FLOATTYPE v) {
INLINE_LINMATH void Extension<FLOATNAME(UnalignedLVecBase4)>::
__setitem__(int i, FLOATTYPE v) {
nassertv(i >= 0 && i < 4);
this->_v(i) = v;
_this->_v(i) = v;
}

View File

@ -0,0 +1,44 @@
// Filename: lvecBase4_ext_src.h
// Created by: rdb (13Sep13)
//
////////////////////////////////////////////////////////////////////
//
// 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."
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Class : Extension<LVecBase4>
// Description : This class defines the extension methods for
// LVecBase4, which are called instead of
// any C++ methods with the same prototype.
////////////////////////////////////////////////////////////////////
template<>
class Extension<FLOATNAME(LVecBase4)> : public ExtensionBase<FLOATNAME(LVecBase4)> {
public:
INLINE_LINMATH PyObject *__reduce__(PyObject *self) const;
INLINE_LINMATH PyObject *__getattr__(const string &attr_name) const;
INLINE_LINMATH int __setattr__(PyObject *self, const string &attr_name, PyObject *assign);
INLINE_LINMATH void __setitem__(int i, FLOATTYPE v);
INLINE_LINMATH void python_repr(ostream &out, const string &class_name) const;
};
////////////////////////////////////////////////////////////////////
// Class : Extension<UnalignedLVecBase4>
// Description : This class defines the extension methods for
// UnalignedLVecBase4, which are called instead of
// any C++ methods with the same prototype.
////////////////////////////////////////////////////////////////////
template<>
class Extension<FLOATNAME(UnalignedLVecBase4)> : public ExtensionBase<FLOATNAME(UnalignedLVecBase4)> {
public:
INLINE_LINMATH void __setitem__(int i, FLOATTYPE v);
};
#include "lvecBase4_ext_src.I"

View File

@ -44,9 +44,9 @@ PUBLISHED:
INLINE_LINMATH ~FLOATNAME(LVecBase4)();
EXTENSION(PyObject *__reduce__(PyObject *self) const);
EXTENSION(PyObject *__getattr__(const string &attr_name) const);
EXTENSION(int __setattr__(PyObject *self, const string &attr_name, PyObject *assign));
EXTENSION(INLINE_LINMATH PyObject *__reduce__(PyObject *self) const);
EXTENSION(INLINE_LINMATH PyObject *__getattr__(const string &attr_name) const);
EXTENSION(INLINE_LINMATH int __setattr__(PyObject *self, const string &attr_name, PyObject *assign));
INLINE_LINMATH FLOATTYPE operator [](int i) const;
INLINE_LINMATH FLOATTYPE &operator [](int i);

View File

@ -1,5 +1,5 @@
// Filename: lvector2_ext.I
// Created by: rdb (02Jan11)
// Created by: rdb (13Sep13)
//
////////////////////////////////////////////////////////////////////
//
@ -12,11 +12,18 @@
//
////////////////////////////////////////////////////////////////////
#ifndef LVECTOR2_EXT_H
#define LVECTOR2_EXT_H
#include "lvector2.h"
#include "extension.h"
#include "lvecBase2_ext.h"
#include "fltnames.h"
#include "lvector2_ext_src.I"
#include "lvector2_ext_src.h"
#include "dblnames.h"
#include "lvector2_ext_src.I"
#include "lvector2_ext_src.h"
#endif

View File

@ -12,7 +12,6 @@
//
////////////////////////////////////////////////////////////////////
#ifndef CPPPARSER
IMPORT_THIS struct Dtool_PyTypedObject FLOATNAME(Dtool_LVector2);
IMPORT_THIS struct Dtool_PyTypedObject FLOATNAME(Dtool_LVector3);
@ -24,11 +23,11 @@ IMPORT_THIS struct Dtool_PyTypedObject FLOATNAME(Dtool_LVector4);
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE void EXT_CONST_METHOD_ARGS(FLOATNAME(LVector2),
python_repr, ostream &out, const string &class_name) {
INLINE_LINMATH void Extension<FLOATNAME(LVector2)>::
python_repr(ostream &out, const string &class_name) const {
out << class_name << "("
<< MAYBE_ZERO(this->_v(0)) << ", "
<< MAYBE_ZERO(this->_v(1)) << ")";
<< MAYBE_ZERO(_this->_v(0)) << ", "
<< MAYBE_ZERO(_this->_v(1)) << ")";
}
////////////////////////////////////////////////////////////////////
@ -36,8 +35,8 @@ python_repr, ostream &out, const string &class_name) {
// Access: Published
// Description: This is used to implement swizzle masks.
////////////////////////////////////////////////////////////////////
INLINE PyObject *EXT_CONST_METHOD_ARGS(FLOATNAME(LVector2),
__getattr__, const string &attr_name) {
INLINE_LINMATH PyObject *Extension<FLOATNAME(LVector2)>::
__getattr__(const string &attr_name) const {
// Validate the attribute name.
for (string::const_iterator it = attr_name.begin(); it < attr_name.end(); it++) {
if (*it != 'x' && *it != 'y') {
@ -45,42 +44,43 @@ __getattr__, const string &attr_name) {
}
}
if (attr_name.size() == 1) {
return PyFloat_FromDouble(this->_v(attr_name[0] - 'x'));
switch (attr_name.size()) {
case 1:
return PyFloat_FromDouble(_this->_v(attr_name[0] - 'x'));
} else if (attr_name.size() == 2) {
FLOATNAME(LVector2) *vec = new FLOATNAME(LVector2);
vec->_v(0) = this->_v(attr_name[0] - 'x');
vec->_v(1) = this->_v(attr_name[1] - 'x');
return DTool_CreatePyInstance((void *)vec, FLOATNAME(Dtool_LVector2), true, false);
case 2: {
FLOATNAME(LVector2) *vec = new FLOATNAME(LVector2);
vec->_v(0) = _this->_v(attr_name[0] - 'x');
vec->_v(1) = _this->_v(attr_name[1] - 'x');
return DTool_CreatePyInstance((void *)vec, FLOATNAME(Dtool_LVector2), true, false);
} else if (attr_name.size() == 3) {
FLOATNAME(LVector3) *vec = new FLOATNAME(LVector3);
vec->_v(0) = this->_v(attr_name[0] - 'x');
vec->_v(1) = this->_v(attr_name[1] - 'x');
vec->_v(2) = this->_v(attr_name[2] - 'x');
return DTool_CreatePyInstance((void *)vec, FLOATNAME(Dtool_LVector3), true, false);
} case 3: {
FLOATNAME(LVector3) *vec = new FLOATNAME(LVector3);
vec->_v(0) = _this->_v(attr_name[0] - 'x');
vec->_v(1) = _this->_v(attr_name[1] - 'x');
vec->_v(2) = _this->_v(attr_name[2] - 'x');
return DTool_CreatePyInstance((void *)vec, FLOATNAME(Dtool_LVector3), true, false);
} else if (attr_name.size() == 4) {
FLOATNAME(LVector4) *vec = new FLOATNAME(LVector4);
vec->_v(0) = this->_v(attr_name[0] - 'x');
vec->_v(1) = this->_v(attr_name[1] - 'x');
vec->_v(2) = this->_v(attr_name[2] - 'x');
vec->_v(3) = this->_v(attr_name[3] - 'x');
return DTool_CreatePyInstance((void *)vec, FLOATNAME(Dtool_LVector4), true, false);
} case 4: {
FLOATNAME(LVector4) *vec = new FLOATNAME(LVector4);
vec->_v(0) = _this->_v(attr_name[0] - 'x');
vec->_v(1) = _this->_v(attr_name[1] - 'x');
vec->_v(2) = _this->_v(attr_name[2] - 'x');
vec->_v(3) = _this->_v(attr_name[3] - 'x');
return DTool_CreatePyInstance((void *)vec, FLOATNAME(Dtool_LVector4), true, false);
}
}
return NULL;
}
int EXT_METHOD_ARGS(FLOATNAME(LVecBase2), __setattr__, PyObject*, const string&, PyObject*);
////////////////////////////////////////////////////////////////////
// Function: LVector2::__setattr__
// Access: Published
// Description: This is used to implement write masks.
////////////////////////////////////////////////////////////////////
INLINE int EXT_METHOD_ARGS(FLOATNAME(LVector2),
__setattr__, PyObject *self, const string &attr_name, PyObject *assign) {
return CALL_EXT_METHOD(FLOATNAME(LVecBase2), __setattr__, this, self, attr_name, assign);
INLINE_LINMATH int Extension<FLOATNAME(LVector2)>::
__setattr__(PyObject *self, const string &attr_name, PyObject *assign) {
// Upcall to LVecBase2.
return invoke_extension<FLOATNAME(LVecBase2)>(_this, _self).__setattr__(self, attr_name, assign);
}

View File

@ -0,0 +1,30 @@
// Filename: lvector2_ext_src.h
// Created by: rdb (13Sep13)
//
////////////////////////////////////////////////////////////////////
//
// 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."
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Class : Extension<LVector2>
// Description : This class defines the extension methods for
// LVector2, which are called instead of
// any C++ methods with the same prototype.
////////////////////////////////////////////////////////////////////
template<>
class Extension<FLOATNAME(LVector2)> : public ExtensionBase<FLOATNAME(LVector2)> {
public:
INLINE_LINMATH PyObject *__getattr__(const string &attr_name) const;
INLINE_LINMATH int __setattr__(PyObject *self, const string &attr_name, PyObject *assign);
INLINE_LINMATH void python_repr(ostream &out, const string &class_name) const;
};
#include "lvector2_ext_src.I"

View File

@ -25,8 +25,8 @@ PUBLISHED:
INLINE_LINMATH FLOATNAME(LVector2)(FLOATTYPE fill_value);
INLINE_LINMATH FLOATNAME(LVector2)(FLOATTYPE x, FLOATTYPE y);
EXTENSION(PyObject *__getattr__(const string &attr_name) const);
EXTENSION(int __setattr__(PyObject *self, const string &attr_name, PyObject *assign));
EXTENSION(INLINE_LINMATH PyObject *__getattr__(const string &attr_name) const);
EXTENSION(INLINE_LINMATH int __setattr__(PyObject *self, const string &attr_name, PyObject *assign));
INLINE_LINMATH static const FLOATNAME(LVector2) &zero();
INLINE_LINMATH static const FLOATNAME(LVector2) &unit_x();

View File

@ -1,5 +1,5 @@
// Filename: lvector3_ext.I
// Created by: rdb (02Jan11)
// Created by: rdb (13Sep13)
//
////////////////////////////////////////////////////////////////////
//
@ -12,11 +12,18 @@
//
////////////////////////////////////////////////////////////////////
#ifndef LVECTOR3_EXT_H
#define LVECTOR3_EXT_H
#include "lvector3.h"
#include "extension.h"
#include "lvecBase3_ext.h"
#include "fltnames.h"
#include "lvector3_ext_src.I"
#include "lvector3_ext_src.h"
#include "dblnames.h"
#include "lvector3_ext_src.I"
#include "lvector3_ext_src.h"
#endif

View File

@ -12,7 +12,6 @@
//
////////////////////////////////////////////////////////////////////
#ifndef CPPPARSER
IMPORT_THIS struct Dtool_PyTypedObject FLOATNAME(Dtool_LVector2);
IMPORT_THIS struct Dtool_PyTypedObject FLOATNAME(Dtool_LVector3);
@ -24,12 +23,12 @@ IMPORT_THIS struct Dtool_PyTypedObject FLOATNAME(Dtool_LVector4);
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE void EXT_CONST_METHOD_ARGS(FLOATNAME(LVector3),
python_repr, ostream &out, const string &class_name) {
INLINE_LINMATH void Extension<FLOATNAME(LVector3)>::
python_repr(ostream &out, const string &class_name) const {
out << class_name << "("
<< MAYBE_ZERO(this->_v(0)) << ", "
<< MAYBE_ZERO(this->_v(1)) << ", "
<< MAYBE_ZERO(this->_v(2)) << ")";
<< MAYBE_ZERO(_this->_v(0)) << ", "
<< MAYBE_ZERO(_this->_v(1)) << ", "
<< MAYBE_ZERO(_this->_v(2)) << ")";
}
////////////////////////////////////////////////////////////////////
@ -37,8 +36,8 @@ python_repr, ostream &out, const string &class_name) {
// Access: Published
// Description: This is used to implement swizzle masks.
////////////////////////////////////////////////////////////////////
INLINE PyObject *EXT_CONST_METHOD_ARGS(FLOATNAME(LVector3),
__getattr__, const string &attr_name) {
INLINE_LINMATH PyObject *Extension<FLOATNAME(LVector3)>::
__getattr__(const string &attr_name) const {
// Validate the attribute name.
for (string::const_iterator it = attr_name.begin(); it < attr_name.end(); it++) {
if (*it < 'x' || *it > 'z') {
@ -46,43 +45,43 @@ __getattr__, const string &attr_name) {
}
}
if (attr_name.size() == 1) {
return PyFloat_FromDouble(this->_v(attr_name[0] - 'x'));
switch (attr_name.size()) {
case 1:
return PyFloat_FromDouble(_this->_v(attr_name[0] - 'x'));
} else if (attr_name.size() == 2) {
FLOATNAME(LVector2) *vec = new FLOATNAME(LVector2);
vec->_v(0) = this->_v(attr_name[0] - 'x');
vec->_v(1) = this->_v(attr_name[1] - 'x');
return DTool_CreatePyInstance((void *)vec, FLOATNAME(Dtool_LVector2), true, false);
case 2: {
FLOATNAME(LVector2) *vec = new FLOATNAME(LVector2);
vec->_v(0) = _this->_v(attr_name[0] - 'x');
vec->_v(1) = _this->_v(attr_name[1] - 'x');
return DTool_CreatePyInstance((void *)vec, FLOATNAME(Dtool_LVector2), true, false);
} else if (attr_name.size() == 3) {
FLOATNAME(LVector3) *vec = new FLOATNAME(LVector3);
vec->_v(0) = this->_v(attr_name[0] - 'x');
vec->_v(1) = this->_v(attr_name[1] - 'x');
vec->_v(2) = this->_v(attr_name[2] - 'x');
return DTool_CreatePyInstance((void *)vec, FLOATNAME(Dtool_LVector3), true, false);
} case 3: {
FLOATNAME(LVector3) *vec = new FLOATNAME(LVector3);
vec->_v(0) = _this->_v(attr_name[0] - 'x');
vec->_v(1) = _this->_v(attr_name[1] - 'x');
vec->_v(2) = _this->_v(attr_name[2] - 'x');
return DTool_CreatePyInstance((void *)vec, FLOATNAME(Dtool_LVector3), true, false);
} else if (attr_name.size() == 4) {
FLOATNAME(LVector4) *vec = new FLOATNAME(LVector4);
vec->_v(0) = this->_v(attr_name[0] - 'x');
vec->_v(1) = this->_v(attr_name[1] - 'x');
vec->_v(2) = this->_v(attr_name[2] - 'x');
vec->_v(3) = this->_v(attr_name[3] - 'x');
return DTool_CreatePyInstance((void *)vec, FLOATNAME(Dtool_LVector4), true, false);
} case 4: {
FLOATNAME(LVector4) *vec = new FLOATNAME(LVector4);
vec->_v(0) = _this->_v(attr_name[0] - 'x');
vec->_v(1) = _this->_v(attr_name[1] - 'x');
vec->_v(2) = _this->_v(attr_name[2] - 'x');
vec->_v(3) = _this->_v(attr_name[3] - 'x');
return DTool_CreatePyInstance((void *)vec, FLOATNAME(Dtool_LVector4), true, false);
}
}
return NULL;
}
int EXT_METHOD_ARGS(FLOATNAME(LVecBase3), __setattr__, PyObject*, const string&, PyObject*);
////////////////////////////////////////////////////////////////////
// Function: LVector3::__setattr__
// Access: Published
// Description: This is used to implement write masks.
////////////////////////////////////////////////////////////////////
INLINE int EXT_METHOD_ARGS(FLOATNAME(LVector3),
__setattr__, PyObject *self, const string &attr_name, PyObject *assign) {
return CALL_EXT_METHOD(FLOATNAME(LVecBase3), __setattr__, this, self, attr_name, assign);
INLINE_LINMATH int Extension<FLOATNAME(LVector3)>::
__setattr__(PyObject *self, const string &attr_name, PyObject *assign) {
// Upcall to LVecBase3.
return invoke_extension<FLOATNAME(LVecBase3)>(_this, _self).__setattr__(self, attr_name, assign);
}

View File

@ -0,0 +1,30 @@
// Filename: lvector3_ext_src.h
// Created by: rdb (13Sep13)
//
////////////////////////////////////////////////////////////////////
//
// 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."
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Class : Extension<LVector3>
// Description : This class defines the extension methods for
// LVector3, which are called instead of
// any C++ methods with the same prototype.
////////////////////////////////////////////////////////////////////
template<>
class Extension<FLOATNAME(LVector3)> : public ExtensionBase<FLOATNAME(LVector3)> {
public:
INLINE_LINMATH PyObject *__getattr__(const string &attr_name) const;
INLINE_LINMATH int __setattr__(PyObject *self, const string &attr_name, PyObject *assign);
INLINE_LINMATH void python_repr(ostream &out, const string &class_name) const;
};
#include "lvector3_ext_src.I"

View File

@ -31,8 +31,8 @@ PUBLISHED:
INLINE_LINMATH FLOATNAME(LVector3)(FLOATTYPE fill_value);
INLINE_LINMATH FLOATNAME(LVector3)(FLOATTYPE x, FLOATTYPE y, FLOATTYPE z);
EXTENSION(PyObject *__getattr__(const string &attr_name) const);
EXTENSION(int __setattr__(PyObject *self, const string &attr_name, PyObject *assign));
EXTENSION(INLINE_LINMATH PyObject *__getattr__(const string &attr_name) const);
EXTENSION(INLINE_LINMATH int __setattr__(PyObject *self, const string &attr_name, PyObject *assign));
INLINE_LINMATH static const FLOATNAME(LVector3) &zero();
INLINE_LINMATH static const FLOATNAME(LVector3) &unit_x();

View File

@ -1,5 +1,5 @@
// Filename: lvector4_ext.I
// Created by: rdb (02Jan11)
// Created by: rdb (13Sep13)
//
////////////////////////////////////////////////////////////////////
//
@ -12,11 +12,18 @@
//
////////////////////////////////////////////////////////////////////
#ifndef LVECTOR4_EXT_H
#define LVECTOR4_EXT_H
#include "lvector4.h"
#include "extension.h"
#include "lvecBase4_ext.h"
#include "fltnames.h"
#include "lvector4_ext_src.I"
#include "lvector4_ext_src.h"
#include "dblnames.h"
#include "lvector4_ext_src.I"
#include "lvector4_ext_src.h"
#endif

View File

@ -12,7 +12,6 @@
//
////////////////////////////////////////////////////////////////////
#ifndef CPPPARSER
IMPORT_THIS struct Dtool_PyTypedObject FLOATNAME(Dtool_LVector2);
IMPORT_THIS struct Dtool_PyTypedObject FLOATNAME(Dtool_LVector3);
@ -24,13 +23,13 @@ IMPORT_THIS struct Dtool_PyTypedObject FLOATNAME(Dtool_LVector4);
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE void EXT_CONST_METHOD_ARGS(FLOATNAME(LVector4),
python_repr, ostream &out, const string &class_name) {
INLINE_LINMATH void Extension<FLOATNAME(LVector4)>::
python_repr(ostream &out, const string &class_name) const {
out << class_name << "("
<< MAYBE_ZERO(this->_v(0)) << ", "
<< MAYBE_ZERO(this->_v(1)) << ", "
<< MAYBE_ZERO(this->_v(2)) << ", "
<< MAYBE_ZERO(this->_v(3)) << ")";
<< MAYBE_ZERO(_this->_v(0)) << ", "
<< MAYBE_ZERO(_this->_v(1)) << ", "
<< MAYBE_ZERO(_this->_v(2)) << ", "
<< MAYBE_ZERO(_this->_v(3)) << ")";
}
////////////////////////////////////////////////////////////////////
@ -38,8 +37,8 @@ python_repr, ostream &out, const string &class_name) {
// Access: Published
// Description: This is used to implement swizzle masks.
////////////////////////////////////////////////////////////////////
INLINE PyObject *EXT_CONST_METHOD_ARGS(FLOATNAME(LVector4),
__getattr__, const string &attr_name) {
INLINE_LINMATH PyObject *Extension<FLOATNAME(LVector4)>::
__getattr__(const string &attr_name) const {
// Validate the attribute name.
for (string::const_iterator it = attr_name.begin(); it < attr_name.end(); it++) {
if (*it < 'w' || *it > 'z') {
@ -47,47 +46,47 @@ __getattr__, const string &attr_name) {
}
}
if (attr_name.size() == 1) {
if (attr_name[0] == 'w') {
return PyFloat_FromDouble(this->_v(3));
} else {
return PyFloat_FromDouble(this->_v(attr_name[0] - 'x'));
switch (attr_name.size()) {
case 1:
if (attr_name[0] == 'w') {
return PyFloat_FromDouble(_this->_v(3));
} else {
return PyFloat_FromDouble(_this->_v(attr_name[0] - 'x'));
}
case 2: {
FLOATNAME(LVector2) *vec = new FLOATNAME(LVector2);
vec->_v(0) = _this->_v((attr_name[0] == 'w') ? 3 : attr_name[0] - 'x');
vec->_v(1) = _this->_v((attr_name[1] == 'w') ? 3 : attr_name[1] - 'x');
return DTool_CreatePyInstance((void *)vec, FLOATNAME(Dtool_LVector2), true, false);
} case 3: {
FLOATNAME(LVector3) *vec = new FLOATNAME(LVector3);
vec->_v(0) = _this->_v((attr_name[0] == 'w') ? 3 : attr_name[0] - 'x');
vec->_v(1) = _this->_v((attr_name[1] == 'w') ? 3 : attr_name[1] - 'x');
vec->_v(2) = _this->_v((attr_name[2] == 'w') ? 3 : attr_name[2] - 'x');
return DTool_CreatePyInstance((void *)vec, FLOATNAME(Dtool_LVector3), true, false);
} case 4: {
FLOATNAME(LVector4) *vec = new FLOATNAME(LVector4);
vec->_v(0) = _this->_v((attr_name[0] == 'w') ? 3 : attr_name[0] - 'x');
vec->_v(1) = _this->_v((attr_name[1] == 'w') ? 3 : attr_name[1] - 'x');
vec->_v(2) = _this->_v((attr_name[2] == 'w') ? 3 : attr_name[2] - 'x');
vec->_v(3) = _this->_v((attr_name[3] == 'w') ? 3 : attr_name[3] - 'x');
return DTool_CreatePyInstance((void *)vec, FLOATNAME(Dtool_LVector4), true, false);
}
} else if (attr_name.size() == 2) {
FLOATNAME(LVector2) *vec = new FLOATNAME(LVector2);
vec->_v(0) = this->_v((attr_name[0] == 'w') ? 3 : attr_name[0] - 'x');
vec->_v(1) = this->_v((attr_name[1] == 'w') ? 3 : attr_name[1] - 'x');
return DTool_CreatePyInstance((void *)vec, FLOATNAME(Dtool_LVector2), true, false);
} else if (attr_name.size() == 3) {
FLOATNAME(LVector3) *vec = new FLOATNAME(LVector3);
vec->_v(0) = this->_v((attr_name[0] == 'w') ? 3 : attr_name[0] - 'x');
vec->_v(1) = this->_v((attr_name[1] == 'w') ? 3 : attr_name[1] - 'x');
vec->_v(2) = this->_v((attr_name[2] == 'w') ? 3 : attr_name[2] - 'x');
return DTool_CreatePyInstance((void *)vec, FLOATNAME(Dtool_LVector3), true, false);
} else if (attr_name.size() == 4) {
FLOATNAME(LVector4) *vec = new FLOATNAME(LVector4);
vec->_v(0) = this->_v((attr_name[0] == 'w') ? 3 : attr_name[0] - 'x');
vec->_v(1) = this->_v((attr_name[1] == 'w') ? 3 : attr_name[1] - 'x');
vec->_v(2) = this->_v((attr_name[2] == 'w') ? 3 : attr_name[2] - 'x');
vec->_v(3) = this->_v((attr_name[3] == 'w') ? 3 : attr_name[3] - 'x');
return DTool_CreatePyInstance((void *)vec, FLOATNAME(Dtool_LVector4), true, false);
}
return NULL;
}
int EXT_METHOD_ARGS(FLOATNAME(LVecBase4), __setattr__, PyObject*, const string&, PyObject*);
////////////////////////////////////////////////////////////////////
// Function: LVector4::__setattr__
// Access: Published
// Description: This is used to implement write masks.
////////////////////////////////////////////////////////////////////
INLINE int EXT_METHOD_ARGS(FLOATNAME(LVector4),
__setattr__, PyObject *self, const string &attr_name, PyObject *assign) {
return CALL_EXT_METHOD(FLOATNAME(LVecBase4), __setattr__, this, self, attr_name, assign);
INLINE_LINMATH int Extension<FLOATNAME(LVector4)>::
__setattr__(PyObject *self, const string &attr_name, PyObject *assign) {
// Upcall to LVecBase4.
return invoke_extension<FLOATNAME(LVecBase4)>(_this, _self).__setattr__(self, attr_name, assign);
}

View File

@ -0,0 +1,30 @@
// Filename: lvector4_ext_src.h
// Created by: rdb (13Sep13)
//
////////////////////////////////////////////////////////////////////
//
// 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."
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Class : Extension<LVector4>
// Description : This class defines the extension methods for
// LVector4, which are called instead of
// any C++ methods with the same prototype.
////////////////////////////////////////////////////////////////////
template<>
class Extension<FLOATNAME(LVector4)> : public ExtensionBase<FLOATNAME(LVector4)> {
public:
INLINE_LINMATH PyObject *__getattr__(const string &attr_name) const;
INLINE_LINMATH int __setattr__(PyObject *self, const string &attr_name, PyObject *assign);
INLINE_LINMATH void python_repr(ostream &out, const string &class_name) const;
};
#include "lvector4_ext_src.I"

View File

@ -25,8 +25,8 @@ PUBLISHED:
INLINE_LINMATH FLOATNAME(LVector4)(FLOATTYPE fill_value);
INLINE_LINMATH FLOATNAME(LVector4)(FLOATTYPE x, FLOATTYPE y, FLOATTYPE z, FLOATTYPE w);
EXTENSION(PyObject *__getattr__(const string &attr_name) const);
EXTENSION(int __setattr__(PyObject *self, const string &attr_name, PyObject *assign));
EXTENSION(INLINE_LINMATH PyObject *__getattr__(const string &attr_name) const);
EXTENSION(INLINE_LINMATH int __setattr__(PyObject *self, const string &attr_name, PyObject *assign));
INLINE_LINMATH static const FLOATNAME(LVector4) &zero();
INLINE_LINMATH static const FLOATNAME(LVector4) &unit_x();

View File

@ -1,4 +1,4 @@
// Filename: rocketRegion_ext.I
// Filename: rocketRegion_ext.cxx
// Created by: rdb (06Dec11)
//
////////////////////////////////////////////////////////////////////
@ -13,9 +13,9 @@
////////////////////////////////////////////////////////////////////
#include "rocketRegion.h"
#include "extension.h"
#ifndef CPPPARSER
#undef this
#define HAVE_LONG_LONG 1
#include <Rocket/Core/Context.h>
#include <Rocket/Core/Python/Utilities.h>
@ -31,10 +31,10 @@
// It's best to call this method just once and store
// the context in a Python variable, to avoid overhead.
////////////////////////////////////////////////////////////////////
PyObject* EXT_CONST_METHOD(RocketRegion,
get_context) {
PyObject* Extension<RocketRegion>::
get_context() const {
try {
Rocket::Core::Context* context = _ext_this->get_context();
Rocket::Core::Context* context = _this->get_context();
python::object py_context = Rocket::Core::Python::Utilities::MakeObject(context);
// Make sure the context won't be destroyed before both the Python

View File

@ -0,0 +1,39 @@
// Filename: rocketRegion_ext.h
// Created by: rdb (13Sep13)
//
////////////////////////////////////////////////////////////////////
//
// 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."
//
////////////////////////////////////////////////////////////////////
#ifndef ROCKETREGION_EXT_H
#define ROCKETREGION_EXT_H
#include "dtoolbase.h"
#ifdef HAVE_PYTHON
#include "extension.h"
#include "geomVertexArrayData.h"
#include "py_panda.h"
////////////////////////////////////////////////////////////////////
// Class : Extension<RocketRegion>
// Description : This class defines the extension methods for
// GeomVertexArrayData, which are called instead of
// any C++ methods with the same prototype.
////////////////////////////////////////////////////////////////////
template<>
class Extension<RocketRegion> : public ExtensionBase<RocketRegion> {
public:
};
#endif // HAVE_PYTHON
#endif // ROCKETREGION_EXT_H