mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-01 09:23:03 -04:00
Add property support to interrogate (using MAKE_PROPERTY or using published members)
This commit is contained in:
parent
8afd8b1f57
commit
c178aba639
@ -29,13 +29,7 @@
|
||||
// on the mesh.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDAAI AINode {
|
||||
PUBLISHED:
|
||||
// This variable specifies whether the node is an obtacle or not.
|
||||
// Used for dynamic obstacle addition to the environment.
|
||||
// obstacle = false
|
||||
// navigational = true
|
||||
bool _type;
|
||||
|
||||
public:
|
||||
// This variable specifies the node status whether open, close
|
||||
// or neutral.
|
||||
// open = belongs to _open_list.
|
||||
@ -48,6 +42,12 @@ PUBLISHED:
|
||||
};
|
||||
Status _status;
|
||||
|
||||
// This variable specifies whether the node is an obtacle or not.
|
||||
// Used for dynamic obstacle addition to the environment.
|
||||
// obstacle = false
|
||||
// navigational = true
|
||||
bool _type;
|
||||
|
||||
// The score is used to compute the traversal expense to nodes
|
||||
// when using A*.
|
||||
// _score = _cost + heuristic
|
||||
@ -76,6 +76,7 @@ PUBLISHED:
|
||||
// is written into navmesh.csv file.
|
||||
AINode *_next;
|
||||
|
||||
PUBLISHED:
|
||||
AINode(int grid_x, int grid_y, LVecBase3f pos, float w, float l, float h);
|
||||
~AINode();
|
||||
|
||||
|
@ -15,7 +15,7 @@
|
||||
cppExpressionParser.h cppExtensionType.h cppFile.h \
|
||||
cppFunctionGroup.h cppFunctionType.h cppGlobals.h \
|
||||
cppIdentifier.h cppInstance.h cppInstanceIdentifier.h \
|
||||
cppMakeSeq.h cppManifest.h \
|
||||
cppMakeProperty.h cppMakeSeq.h cppManifest.h \
|
||||
cppNameComponent.h cppNamespace.h \
|
||||
cppParameterList.h cppParser.h cppPointerType.h \
|
||||
cppPreprocessor.h cppReferenceType.h cppScope.h \
|
||||
@ -31,7 +31,7 @@
|
||||
cppExtensionType.cxx cppFile.cxx cppFunctionGroup.cxx \
|
||||
cppFunctionType.cxx cppGlobals.cxx cppIdentifier.cxx \
|
||||
cppInstance.cxx cppInstanceIdentifier.cxx \
|
||||
cppMakeSeq.cxx cppManifest.cxx \
|
||||
cppMakeProperty.cxx cppMakeSeq.cxx cppManifest.cxx \
|
||||
cppNameComponent.cxx cppNamespace.cxx cppParameterList.cxx \
|
||||
cppParser.cxx cppPointerType.cxx cppPreprocessor.cxx \
|
||||
cppReferenceType.cxx cppScope.cxx cppSimpleType.cxx \
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "cppEnumType.h"
|
||||
#include "cppFunctionType.h"
|
||||
#include "cppTBDType.h"
|
||||
#include "cppMakeProperty.h"
|
||||
#include "cppMakeSeq.h"
|
||||
#include "cppParameterList.h"
|
||||
#include "cppInstance.h"
|
||||
@ -234,7 +235,6 @@ pop_struct() {
|
||||
%token XOREQUAL
|
||||
%token LSHIFTEQUAL
|
||||
%token RSHIFTEQUAL
|
||||
%token TOKENPASTE
|
||||
|
||||
%token KW_BEGIN_PUBLISH
|
||||
%token KW_BLOCKING
|
||||
@ -264,6 +264,7 @@ pop_struct() {
|
||||
%token KW_INT
|
||||
%token KW_LONG
|
||||
%token KW_LONGLONG
|
||||
%token KW_MAKE_PROPERTY
|
||||
%token KW_MAKE_SEQ
|
||||
%token KW_MUTABLE
|
||||
%token KW_NAMESPACE
|
||||
@ -475,7 +476,35 @@ declaration:
|
||||
{
|
||||
current_scope->set_current_vis(V_private);
|
||||
}
|
||||
| KW_MAKE_SEQ '(' name ',' name ',' name ')' ';'
|
||||
| KW_MAKE_PROPERTY '(' IDENTIFIER ',' IDENTIFIER ')' ';'
|
||||
{
|
||||
|
||||
CPPDeclaration *getter = $5->find_symbol(current_scope, global_scope, current_lexer);
|
||||
if (getter == (CPPDeclaration *)NULL || getter->get_subtype() != CPPDeclaration::ST_function_group) {
|
||||
yyerror("Reference to non-existent or invalid getter: " + $5->get_fully_scoped_name(), @1);
|
||||
}
|
||||
|
||||
CPPMakeProperty *make_property = new CPPMakeProperty($3, getter->as_function_group(), NULL, current_scope, @1.file);
|
||||
current_scope->add_declaration(make_property, global_scope, current_lexer, @1);
|
||||
}
|
||||
| KW_MAKE_PROPERTY '(' IDENTIFIER ',' IDENTIFIER ',' IDENTIFIER ')' ';'
|
||||
{
|
||||
CPPDeclaration *getter = $5->find_symbol(current_scope, global_scope, current_lexer);
|
||||
if (getter == (CPPDeclaration *)NULL || getter->get_subtype() != CPPDeclaration::ST_function_group) {
|
||||
yyerror("Reference to non-existent or invalid getter: " + $5->get_fully_scoped_name(), @1);
|
||||
}
|
||||
|
||||
CPPDeclaration *setter = $7->find_symbol(current_scope, global_scope, current_lexer);
|
||||
if (setter == (CPPDeclaration *)NULL || setter->get_subtype() != CPPDeclaration::ST_function_group) {
|
||||
yyerror("Reference to non-existent or invalid setter: " + $7->get_fully_scoped_name(), @1);
|
||||
}
|
||||
|
||||
CPPMakeProperty *make_property = new CPPMakeProperty($3, getter->as_function_group(),
|
||||
setter->as_function_group(),
|
||||
current_scope, @1.file);
|
||||
current_scope->add_declaration(make_property, global_scope, current_lexer, @1);
|
||||
}
|
||||
| KW_MAKE_SEQ '(' name ',' name ',' name ')' ';'
|
||||
{
|
||||
CPPMakeSeq *make_seq = new CPPMakeSeq($3->get_simple_name(), $5->get_simple_name(), $7->get_simple_name(), @1.file);
|
||||
current_scope->add_declaration(make_seq, global_scope, current_lexer, @1);
|
||||
@ -2086,7 +2115,7 @@ element:
|
||||
| KW_SHORT | KW_SIGNED | KW_SIZEOF | KW_STATIC | KW_STATIC_CAST
|
||||
| KW_STRUCT | KW_THROW | KW_TRUE | KW_TRY | KW_TYPEDEF | KW_TYPENAME
|
||||
| KW_UNION | KW_UNSIGNED | KW_VIRTUAL | KW_VOID | KW_VOLATILE
|
||||
| KW_WHILE | TOKENPASTE
|
||||
| KW_WHILE
|
||||
| KW_OPERATOR
|
||||
{
|
||||
}
|
||||
|
@ -356,6 +356,16 @@ as_type_proxy() {
|
||||
return (CPPTypeProxy *)NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPDeclaration::as_make_property
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPPMakeProperty *CPPDeclaration::
|
||||
as_make_property() {
|
||||
return (CPPMakeProperty *)NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPDeclaration::as_make_seq
|
||||
// Access: Public, Virtual
|
||||
@ -366,7 +376,6 @@ as_make_seq() {
|
||||
return (CPPMakeSeq *)NULL;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPDeclaration::is_equal
|
||||
// Access: Protected, Virtual
|
||||
|
@ -47,6 +47,7 @@ class CPPExtensionType;
|
||||
class CPPStructType;
|
||||
class CPPEnumType;
|
||||
class CPPTypeProxy;
|
||||
class CPPMakeProperty;
|
||||
class CPPMakeSeq;
|
||||
class CPPClassTemplateParameter;
|
||||
class CPPTBDType;
|
||||
@ -69,6 +70,7 @@ public:
|
||||
ST_type,
|
||||
ST_namespace,
|
||||
ST_using,
|
||||
ST_make_property,
|
||||
ST_make_seq,
|
||||
|
||||
// Subtypes of CPPType
|
||||
@ -136,6 +138,7 @@ public:
|
||||
virtual CPPEnumType *as_enum_type();
|
||||
virtual CPPTBDType *as_tbd_type();
|
||||
virtual CPPTypeProxy *as_type_proxy();
|
||||
virtual CPPMakeProperty *as_make_property();
|
||||
virtual CPPMakeSeq *as_make_seq();
|
||||
|
||||
CPPVisibility _vis;
|
||||
@ -154,8 +157,4 @@ operator << (ostream &out, const CPPDeclaration &decl) {
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
99
dtool/src/cppparser/cppMakeProperty.cxx
Normal file
99
dtool/src/cppparser/cppMakeProperty.cxx
Normal file
@ -0,0 +1,99 @@
|
||||
// Filename: cppMakeProperty.cxx
|
||||
// Created by: rdb (18Sep14)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "cppMakeProperty.h"
|
||||
#include "cppFunctionGroup.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPMakeProperty::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPPMakeProperty::
|
||||
CPPMakeProperty(CPPIdentifier *ident,
|
||||
CPPFunctionGroup *getter, CPPFunctionGroup *setter,
|
||||
CPPScope *current_scope, const CPPFile &file) :
|
||||
CPPDeclaration(file),
|
||||
_ident(ident),
|
||||
_getter(getter),
|
||||
_setter(setter)
|
||||
{
|
||||
_ident->_native_scope = current_scope;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPMakeProperty::get_simple_name
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
string CPPMakeProperty::
|
||||
get_simple_name() const {
|
||||
return _ident->get_simple_name();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPMakeProperty::get_local_name
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
string CPPMakeProperty::
|
||||
get_local_name(CPPScope *scope) const {
|
||||
return _ident->get_local_name(scope);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPMakeProperty::get_fully_scoped_name
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
string CPPMakeProperty::
|
||||
get_fully_scoped_name() const {
|
||||
return _ident->get_fully_scoped_name();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPMakeProperty::output
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CPPMakeProperty::
|
||||
output(ostream &out, int indent_level, CPPScope *scope, bool complete) const {
|
||||
out << "__make_property(" << _ident->get_local_name(scope)
|
||||
<< ", " << _getter->_name;
|
||||
|
||||
if (_setter != NULL) {
|
||||
out << ", " << _setter->_name;
|
||||
}
|
||||
out << ");";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPMakeProperty::get_subtype
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPPDeclaration::SubType CPPMakeProperty::
|
||||
get_subtype() const {
|
||||
return ST_make_property;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPMakeProperty::as_make_property
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPPMakeProperty *CPPMakeProperty::
|
||||
as_make_property() {
|
||||
return this;
|
||||
}
|
51
dtool/src/cppparser/cppMakeProperty.h
Normal file
51
dtool/src/cppparser/cppMakeProperty.h
Normal file
@ -0,0 +1,51 @@
|
||||
// Filename: cppMakeProperty.h
|
||||
// Created by: rdb (18Sep14)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 CPPMAKEPROPERTY_H
|
||||
#define CPPMAKEPROPERTY_H
|
||||
|
||||
#include "dtoolbase.h"
|
||||
|
||||
#include "cppDeclaration.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
// Class : CPPMakeProperty
|
||||
// Description : This is a MAKE_PROPERTY() declaration appearing
|
||||
// within a class body. It means to generate a property
|
||||
// within Python, replacing (for instance)
|
||||
// get_something()/set_something() with a synthetic
|
||||
// 'something' attribute.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class CPPMakeProperty : public CPPDeclaration {
|
||||
public:
|
||||
CPPMakeProperty(CPPIdentifier *ident,
|
||||
CPPFunctionGroup *getter, CPPFunctionGroup *setter,
|
||||
CPPScope *current_scope, const CPPFile &file);
|
||||
|
||||
virtual string get_simple_name() const;
|
||||
virtual string get_local_name(CPPScope *scope = NULL) const;
|
||||
virtual string get_fully_scoped_name() const;
|
||||
|
||||
virtual void output(ostream &out, int indent_level, CPPScope *scope,
|
||||
bool complete) const;
|
||||
|
||||
virtual SubType get_subtype() const;
|
||||
virtual CPPMakeProperty *as_make_property();
|
||||
|
||||
CPPIdentifier *_ident;
|
||||
CPPFunctionGroup *_getter;
|
||||
CPPFunctionGroup *_setter;
|
||||
};
|
||||
|
||||
#endif
|
@ -1987,6 +1987,7 @@ check_keyword(const string &name) {
|
||||
if (name == "inline") return KW_INLINE;
|
||||
if (name == "int") return KW_INT;
|
||||
if (name == "long") return KW_LONG;
|
||||
if (name == "__make_property") return KW_MAKE_PROPERTY;
|
||||
if (name == "__make_seq") return KW_MAKE_SEQ;
|
||||
if (name == "mutable") return KW_MUTABLE;
|
||||
if (name == "namespace") return KW_NAMESPACE;
|
||||
|
@ -247,10 +247,6 @@ output(ostream &out) const {
|
||||
out << "RSHIFTEQUAL";
|
||||
break;
|
||||
|
||||
case TOKENPASTE:
|
||||
out << "TOKENPASTE";
|
||||
break;
|
||||
|
||||
case KW_BOOL:
|
||||
out << "KW_BOOL";
|
||||
break;
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include "cppCommentBlock.cxx"
|
||||
#include "cppConstType.cxx"
|
||||
#include "cppDeclaration.cxx"
|
||||
#include "cppMakeProperty.cxx"
|
||||
#include "cppMakeSeq.cxx"
|
||||
#include "cppParameterList.cxx"
|
||||
#include "cppParser.cxx"
|
||||
|
@ -397,17 +397,16 @@
|
||||
#define BEGIN_PUBLISH __begin_publish
|
||||
#define END_PUBLISH __end_publish
|
||||
#define BLOCKING __blocking
|
||||
#define MAKE_PROPERTY(property_name, ...) __make_property(property_name, __VA_ARGS__)
|
||||
#define MAKE_SEQ(seq_name, num_name, element_name) __make_seq(seq_name, num_name, element_name)
|
||||
#undef USE_STL_ALLOCATOR /* Don't try to parse these template classes in interrogate. */
|
||||
#define EXTENSION(x) __extension x
|
||||
#define EXTEND __extension
|
||||
#define EXT_FUNC(func) ::func()
|
||||
#define EXT_FUNC_ARGS(func, ...) ::func(__VA_ARGS__)
|
||||
#define CALL_EXT_FUNC(func, ...) ::func (__VA_ARGS__)
|
||||
#else
|
||||
#define BEGIN_PUBLISH
|
||||
#define END_PUBLISH
|
||||
#define BLOCKING
|
||||
#define MAKE_PROPERTY(property_name, ...)
|
||||
#define MAKE_SEQ(seq_name, num_name, element_name)
|
||||
#define EXTENSION(x)
|
||||
#define EXTEND
|
||||
|
@ -371,7 +371,8 @@ get_call_str(const string &container, const vector_string &pexprs) const {
|
||||
}
|
||||
|
||||
call << " = ";
|
||||
_parameters[0]._remap->pass_parameter(call, get_parameter_expr(_first_true_parameter, pexprs));
|
||||
_parameters[_first_true_parameter]._remap->pass_parameter(call,
|
||||
get_parameter_expr(_first_true_parameter, pexprs));
|
||||
|
||||
} else {
|
||||
const char *separator = "";
|
||||
|
@ -87,6 +87,19 @@ MakeSeq(const string &name, CPPMakeSeq *cpp_make_seq) :
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InterfaceMaker::Property::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
InterfaceMaker::Property::
|
||||
Property(const InterrogateElement &ielement) :
|
||||
_ielement(ielement),
|
||||
_getter(NULL),
|
||||
_setter(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InterfaceMaker::Object::Constructor
|
||||
// Access: Public
|
||||
@ -156,6 +169,8 @@ check_protocols() {
|
||||
_protocol_types |= PT_iter;
|
||||
}
|
||||
|
||||
InterrogateDatabase *idb = InterrogateDatabase::get_ptr();
|
||||
|
||||
// Now are there any make_seq requests within this class?
|
||||
if (_itype._cpptype != NULL) {
|
||||
CPPStructType *stype = _itype._cpptype->as_struct_type();
|
||||
@ -230,9 +245,9 @@ InterfaceMaker::
|
||||
Object *object = (*oi).second;
|
||||
delete object;
|
||||
}
|
||||
Functions::iterator fi;
|
||||
FunctionsByIndex::iterator fi;
|
||||
for (fi = _functions.begin(); fi != _functions.end(); ++fi) {
|
||||
delete (*fi);
|
||||
delete (*fi).second;
|
||||
}
|
||||
}
|
||||
|
||||
@ -501,9 +516,9 @@ wrap_global_functions() {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void InterfaceMaker::
|
||||
get_function_remaps(vector<FunctionRemap *> &remaps) {
|
||||
Functions::iterator fi;
|
||||
FunctionsByIndex::iterator fi;
|
||||
for (fi = _functions.begin(); fi != _functions.end(); ++fi) {
|
||||
Function *func = (*fi);
|
||||
Function *func = (*fi).second;
|
||||
Function::Remaps::const_iterator ri;
|
||||
for (ri = func->_remaps.begin(); ri != func->_remaps.end(); ++ri) {
|
||||
FunctionRemap *remap = (*ri);
|
||||
@ -617,12 +632,17 @@ get_unique_prefix() {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
InterfaceMaker::Function *InterfaceMaker::
|
||||
record_function(const InterrogateType &itype, FunctionIndex func_index) {
|
||||
if (_functions.count(func_index)) {
|
||||
// Already exists.
|
||||
return _functions[func_index];
|
||||
}
|
||||
|
||||
InterrogateDatabase *idb = InterrogateDatabase::get_ptr();
|
||||
const InterrogateFunction &ifunc = idb->get_function(func_index);
|
||||
|
||||
string wrapper_name = get_wrapper_name(itype, ifunc, func_index);
|
||||
Function *func = new Function(wrapper_name, itype, ifunc);
|
||||
_functions.push_back(func);
|
||||
_functions[func_index] = func;
|
||||
|
||||
// printf(" Function Name = %s\n", ifunc.get_name().c_str());
|
||||
|
||||
|
@ -29,8 +29,9 @@ class ParameterRemap;
|
||||
class CPPType;
|
||||
class CPPInstance;
|
||||
class InterrogateBuilder;
|
||||
class InterrogateType;
|
||||
class InterrogateElement;
|
||||
class InterrogateFunction;
|
||||
class InterrogateType;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : InterfaceMaker
|
||||
@ -107,8 +108,9 @@ public:
|
||||
int _flags;
|
||||
ArgsType _args_type;
|
||||
};
|
||||
typedef map<FunctionIndex, Function *> FunctionsByIndex;
|
||||
typedef vector<Function *> Functions;
|
||||
Functions _functions;
|
||||
FunctionsByIndex _functions;
|
||||
|
||||
class MakeSeq {
|
||||
public:
|
||||
@ -121,6 +123,16 @@ public:
|
||||
};
|
||||
typedef vector<MakeSeq *> MakeSeqs;
|
||||
|
||||
class Property {
|
||||
public:
|
||||
Property(const InterrogateElement &ielement);
|
||||
|
||||
const InterrogateElement &_ielement;
|
||||
Function *_getter;
|
||||
Function *_setter;
|
||||
};
|
||||
typedef vector<Property *> Properties;
|
||||
|
||||
class Object {
|
||||
public:
|
||||
Object(const InterrogateType &itype);
|
||||
@ -133,6 +145,7 @@ public:
|
||||
Functions _constructors;
|
||||
Functions _methods;
|
||||
MakeSeqs _make_seqs;
|
||||
Properties _properties;
|
||||
|
||||
enum ProtocolTypes {
|
||||
PT_sequence = 0x0001,
|
||||
|
@ -53,9 +53,9 @@ InterfaceMakerC::
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void InterfaceMakerC::
|
||||
write_prototypes(ostream &out,ostream *out_h) {
|
||||
Functions::iterator fi;
|
||||
FunctionsByIndex::iterator fi;
|
||||
for (fi = _functions.begin(); fi != _functions.end(); ++fi) {
|
||||
Function *func = (*fi);
|
||||
Function *func = (*fi).second;
|
||||
write_prototype_for(out, func);
|
||||
}
|
||||
|
||||
@ -72,9 +72,9 @@ write_prototypes(ostream &out,ostream *out_h) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void InterfaceMakerC::
|
||||
write_functions(ostream &out) {
|
||||
Functions::iterator fi;
|
||||
FunctionsByIndex::iterator fi;
|
||||
for (fi = _functions.begin(); fi != _functions.end(); ++fi) {
|
||||
Function *func = (*fi);
|
||||
Function *func = (*fi).second;
|
||||
write_function_for(out, func);
|
||||
}
|
||||
|
||||
|
@ -817,9 +817,9 @@ write_functions(ostream &out) {
|
||||
out << "//********************************************************************\n";
|
||||
out << "//*** Functions for .. Global\n" ;
|
||||
out << "//********************************************************************\n";
|
||||
Functions::iterator fi;
|
||||
FunctionsByIndex::iterator fi;
|
||||
for (fi = _functions.begin(); fi != _functions.end(); ++fi) {
|
||||
Function *func = (*fi);
|
||||
Function *func = (*fi).second;
|
||||
if (!func->_itype.is_global() && is_function_legal(func)) {
|
||||
write_function_for_top(out, NULL, func);
|
||||
}
|
||||
@ -876,6 +876,23 @@ write_class_details(ostream &out, Object *obj) {
|
||||
}
|
||||
}
|
||||
|
||||
Properties::const_iterator pit;
|
||||
for (pit = obj->_properties.begin(); pit != obj->_properties.end(); ++pit) {
|
||||
Property *property = (*pit);
|
||||
const InterrogateElement &ielem = property->_ielement;
|
||||
bool coercion_attempted = false;
|
||||
|
||||
if (property->_getter != NULL) {
|
||||
std::string fname = "PyObject *Dtool_" + ClassName + "_" + ielem.get_name() + "_Getter(PyObject *self, void *)";
|
||||
write_function_for_name(out, obj, property->_getter, fname, true, coercion_attempted, AT_no_args, false, false);
|
||||
}
|
||||
|
||||
if (property->_setter != NULL) {
|
||||
std::string fname = "int Dtool_" + ClassName + "_" + ielem.get_name() + "_Setter(PyObject *self, PyObject *arg, void *)";
|
||||
write_function_for_name(out, obj, property->_setter, fname, true, coercion_attempted, AT_single_arg, true, false);
|
||||
}
|
||||
}
|
||||
|
||||
if (obj->_constructors.size() == 0) {
|
||||
out << "int Dtool_Init_" + ClassName + "(PyObject *self, PyObject *args, PyObject *kwds) {\n"
|
||||
<< " PyErr_SetString(PyExc_TypeError, \"cannot init constant class (" << cClassName << ")\");\n"
|
||||
@ -893,7 +910,7 @@ write_class_details(ostream &out, Object *obj) {
|
||||
Function *func = (*fi);
|
||||
std::string fname = "int Dtool_Init_" + ClassName + "(PyObject *self, PyObject *args, PyObject *kwds)";
|
||||
|
||||
write_function_for_name(out, obj, func, fname, true, coercion_attempted, AT_keyword_args, true);
|
||||
write_function_for_name(out, obj, func, fname, true, coercion_attempted, AT_keyword_args, true, false);
|
||||
}
|
||||
if (coercion_attempted) {
|
||||
// If a coercion attempt was written into the above constructor,
|
||||
@ -903,7 +920,7 @@ write_class_details(ostream &out, Object *obj) {
|
||||
Function *func = (*fi);
|
||||
std::string fname = "int Dtool_InitNoCoerce_" + ClassName + "(PyObject *self, PyObject *args)";
|
||||
|
||||
write_function_for_name(out, obj, func, fname, false, coercion_attempted, AT_varargs, true);
|
||||
write_function_for_name(out, obj, func, fname, false, coercion_attempted, AT_varargs, true, false);
|
||||
}
|
||||
} else {
|
||||
// Otherwise, since the above constructor didn't involve any
|
||||
@ -1114,9 +1131,9 @@ write_module_support(ostream &out, ostream *out_h, InterrogateModuleDef *def) {
|
||||
bool force_base_functions = true;
|
||||
|
||||
out << "static PyMethodDef python_simple_funcs[] = {\n";
|
||||
Functions::iterator fi;
|
||||
FunctionsByIndex::iterator fi;
|
||||
for (fi = _functions.begin(); fi != _functions.end(); ++fi) {
|
||||
Function *func = (*fi);
|
||||
Function *func = (*fi).second;
|
||||
if (!func->_itype.is_global() && is_function_legal(func)) {
|
||||
string name1 = methodNameFromCppName(func, "", false);
|
||||
string name2 = methodNameFromCppName(func, "", true);
|
||||
@ -2078,6 +2095,44 @@ write_module_class(ostream &out, Object *obj) {
|
||||
out << "}\n\n";
|
||||
}
|
||||
|
||||
if (obj->_properties.size() > 0) {
|
||||
// Write out the array of properties, telling Python which getter and setter
|
||||
// to call when they are assigned or queried in Python code.
|
||||
out << "PyGetSetDef Dtool_Properties_" << ClassName << "[] = {\n";
|
||||
|
||||
Properties::const_iterator pit;
|
||||
for (pit = obj->_properties.begin(); pit != obj->_properties.end(); ++pit) {
|
||||
Property *property = (*pit);
|
||||
const InterrogateElement &ielem = property->_ielement;
|
||||
if (property->_getter == NULL || !is_function_legal(property->_getter)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
out << " {(char *)\"" << ielem.get_name() << "\","
|
||||
<< " &Dtool_" << ClassName << "_" << ielem.get_name() << "_Getter,";
|
||||
|
||||
if (property->_setter == NULL || !is_function_legal(property->_setter)) {
|
||||
out << " NULL,";
|
||||
} else {
|
||||
out << " &Dtool_" << ClassName << "_" << ielem.get_name() << "_Setter,";
|
||||
}
|
||||
|
||||
if (ielem.has_comment()) {
|
||||
out << "(char *)\n";
|
||||
output_quoted(out, 4, ielem.get_comment());
|
||||
out << ",\n ";
|
||||
} else {
|
||||
out << " NULL, ";
|
||||
}
|
||||
|
||||
// Extra void* argument; we don't make use of it.
|
||||
out << "NULL},\n";
|
||||
}
|
||||
|
||||
out << " {NULL},\n";
|
||||
out << "};\n\n";
|
||||
}
|
||||
|
||||
out << "void Dtool_PyModuleClassInit_" << ClassName << "(PyObject *module) {\n";
|
||||
out << " static bool initdone = false;\n";
|
||||
out << " if (!initdone) {\n";
|
||||
@ -2190,6 +2245,11 @@ write_module_class(ostream &out, Object *obj) {
|
||||
out << " Dtool_" << ClassName << ".As_PyTypeObject().tp_str = &Dtool_Repr_" << ClassName << ";\n";
|
||||
}
|
||||
|
||||
if (obj->_properties.size() > 0) {
|
||||
// GetSet descriptor slots.
|
||||
out << " Dtool_" << ClassName << ".As_PyTypeObject().tp_getset = Dtool_Properties_" << ClassName << ";\n";
|
||||
}
|
||||
|
||||
int num_nested = obj->_itype.number_of_nested_types();
|
||||
for (int ni = 0; ni < num_nested; ni++) {
|
||||
TypeIndex nested_index = obj->_itype.get_nested_type(ni);
|
||||
@ -2395,7 +2455,7 @@ write_function_for_top(ostream &out, InterfaceMaker::Object *obj, InterfaceMaker
|
||||
fname += ")";
|
||||
|
||||
bool coercion_attempted = false;
|
||||
write_function_for_name(out, obj, func, fname, true, coercion_attempted, func->_args_type, false);
|
||||
write_function_for_name(out, obj, func, fname, true, coercion_attempted, func->_args_type, false, true);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -2407,7 +2467,7 @@ void InterfaceMakerPythonNative::
|
||||
write_function_for_name(ostream &out1, InterfaceMaker::Object *obj, InterfaceMaker::Function *func,
|
||||
const std::string &function_name,
|
||||
bool coercion_allowed, bool &coercion_attempted,
|
||||
ArgsType args_type, bool return_int) {
|
||||
ArgsType args_type, bool return_int, bool write_comment) {
|
||||
ostringstream out;
|
||||
|
||||
std::map<int, std::set<FunctionRemap *> > MapSets;
|
||||
@ -2462,7 +2522,11 @@ write_function_for_name(ostream &out1, InterfaceMaker::Object *obj, InterfaceMak
|
||||
// Other functions should raise an exception if the this
|
||||
// pointer isn't set or is the wrong type.
|
||||
out << " PyErr_SetString(PyExc_AttributeError, \"C++ object is not yet constructed, or already destructed.\");\n";
|
||||
out << " return NULL;\n";
|
||||
if (return_int) {
|
||||
out << " return -1;\n";
|
||||
} else {
|
||||
out << " return NULL;\n";
|
||||
}
|
||||
}
|
||||
out << " }\n";
|
||||
}
|
||||
@ -2639,7 +2703,7 @@ write_function_for_name(ostream &out1, InterfaceMaker::Object *obj, InterfaceMak
|
||||
FunctionComment = FunctionComment1 + "\n" + FunctionComment;
|
||||
}
|
||||
|
||||
if (!return_int) {
|
||||
if (write_comment) {
|
||||
// Write out the function doc string. We only do this if it is
|
||||
// not a constructor, since we don't have a place to put the
|
||||
// constructor doc string.
|
||||
@ -4004,13 +4068,30 @@ record_object(TypeIndex type_index) {
|
||||
for (int ei = 0; ei < num_elements; ei++) {
|
||||
ElementIndex element_index = itype.get_element(ei);
|
||||
const InterrogateElement &ielement = idb->get_element(element_index);
|
||||
if (ielement.has_getter()) {
|
||||
FunctionIndex func_index = ielement.get_getter();
|
||||
record_function(itype, func_index);
|
||||
}
|
||||
|
||||
Property *property = new Property(ielement);
|
||||
|
||||
if (ielement.has_setter()) {
|
||||
FunctionIndex func_index = ielement.get_setter();
|
||||
record_function(itype, func_index);
|
||||
Function *setter = record_function(itype, func_index);
|
||||
if (is_function_legal(setter)) {
|
||||
property->_setter = setter;
|
||||
}
|
||||
}
|
||||
|
||||
if (ielement.has_getter()) {
|
||||
FunctionIndex func_index = ielement.get_getter();
|
||||
Function *getter = record_function(itype, func_index);
|
||||
if (is_function_legal(getter)) {
|
||||
property->_getter = getter;
|
||||
}
|
||||
}
|
||||
|
||||
if (property->_getter != NULL) {
|
||||
object->_properties.push_back(property);
|
||||
} else {
|
||||
// No use exporting a property without a getter.
|
||||
delete property;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -95,7 +95,7 @@ private:
|
||||
void write_function_for_name(ostream &out, Object *obj, Function *func,
|
||||
const std::string &name,
|
||||
bool coercion_allowed, bool &coercion_attempted,
|
||||
ArgsType args_type, bool return_int);
|
||||
ArgsType args_type, bool return_int, bool write_comment);
|
||||
|
||||
void write_function_forset(ostream &out, Object *obj, Function *func,
|
||||
std::set<FunctionRemap*> &remaps, string &expected_params,
|
||||
|
@ -55,9 +55,9 @@ InterfaceMakerPythonObj::
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void InterfaceMakerPythonObj::
|
||||
write_prototypes(ostream &out, ostream *out_h) {
|
||||
Functions::iterator fi;
|
||||
FunctionsByIndex::iterator fi;
|
||||
for (fi = _functions.begin(); fi != _functions.end(); ++fi) {
|
||||
Function *func = (*fi);
|
||||
Function *func = (*fi).second;
|
||||
write_prototype_for(out, func);
|
||||
}
|
||||
|
||||
@ -74,9 +74,9 @@ write_prototypes(ostream &out, ostream *out_h) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void InterfaceMakerPythonObj::
|
||||
write_functions(ostream &out) {
|
||||
Functions::iterator fi;
|
||||
FunctionsByIndex::iterator fi;
|
||||
for (fi = _functions.begin(); fi != _functions.end(); ++fi) {
|
||||
Function *func = (*fi);
|
||||
Function *func = (*fi).second;
|
||||
write_function_for(out, func);
|
||||
}
|
||||
|
||||
|
@ -53,9 +53,9 @@ InterfaceMakerPythonSimple::
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void InterfaceMakerPythonSimple::
|
||||
write_prototypes(ostream &out,ostream *out_h) {
|
||||
Functions::iterator fi;
|
||||
FunctionsByIndex::iterator fi;
|
||||
for (fi = _functions.begin(); fi != _functions.end(); ++fi) {
|
||||
Function *func = (*fi);
|
||||
Function *func = (*fi).second;
|
||||
write_prototype_for(out, func);
|
||||
}
|
||||
|
||||
@ -72,9 +72,9 @@ write_prototypes(ostream &out,ostream *out_h) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void InterfaceMakerPythonSimple::
|
||||
write_functions(ostream &out) {
|
||||
Functions::iterator fi;
|
||||
FunctionsByIndex::iterator fi;
|
||||
for (fi = _functions.begin(); fi != _functions.end(); ++fi) {
|
||||
Function *func = (*fi);
|
||||
Function *func = (*fi).second;
|
||||
write_function_for(out, func);
|
||||
}
|
||||
|
||||
@ -93,9 +93,9 @@ write_module(ostream &out,ostream *out_h, InterrogateModuleDef *def) {
|
||||
|
||||
out << "static PyMethodDef python_simple_funcs[] = {\n";
|
||||
|
||||
Functions::iterator fi;
|
||||
FunctionsByIndex::iterator fi;
|
||||
for (fi = _functions.begin(); fi != _functions.end(); ++fi) {
|
||||
Function *func = (*fi);
|
||||
Function *func = (*fi).second;
|
||||
Function::Remaps::const_iterator ri;
|
||||
for (ri = func->_remaps.begin(); ri != func->_remaps.end(); ++ri) {
|
||||
FunctionRemap *remap = (*ri);
|
||||
|
@ -44,6 +44,7 @@
|
||||
#include "cppTypeDeclaration.h"
|
||||
#include "cppEnumType.h"
|
||||
#include "cppCommentBlock.h"
|
||||
#include "cppMakeProperty.h"
|
||||
#include "cppMakeSeq.h"
|
||||
#include "pnotify.h"
|
||||
|
||||
@ -1357,7 +1358,7 @@ scan_element(CPPInstance *element, CPPStructType *struct_type,
|
||||
ielement._name = element->get_local_name(scope);
|
||||
ielement._scoped_name = descope(element->get_local_name(&parser));
|
||||
|
||||
// See if there happens to be a comment before the element.
|
||||
// See if there happens to be a comment before the MAKE_PROPERTY macro.
|
||||
if (element->_leading_comment != (CPPCommentBlock *)NULL) {
|
||||
ielement._comment = trim_blanks(element->_leading_comment->_comment);
|
||||
}
|
||||
@ -1774,6 +1775,90 @@ get_function(CPPInstance *function, string description,
|
||||
return index;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InterrogateBuilder::get_make_property
|
||||
// Access: Private
|
||||
// Description: Adds the indicated make_property to the database,
|
||||
// if it is not already present. In either case,
|
||||
// returns the MakeSeqIndex of the make_seq within the
|
||||
// database.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
ElementIndex InterrogateBuilder::
|
||||
get_make_property(CPPMakeProperty *make_property, CPPStructType *struct_type) {
|
||||
string property_name = make_property->get_local_name(&parser);
|
||||
|
||||
// First, check to see if it's already there.
|
||||
PropertiesByName::const_iterator tni =
|
||||
_properties_by_name.find(property_name);
|
||||
if (tni != _properties_by_name.end()) {
|
||||
ElementIndex index = (*tni).second;
|
||||
return index;
|
||||
}
|
||||
|
||||
// Find the getter so we can get its return type.
|
||||
CPPInstance *getter = NULL;
|
||||
CPPType *return_type = NULL;
|
||||
|
||||
CPPFunctionGroup *fgroup = make_property->_getter;
|
||||
CPPFunctionGroup::Instances::const_iterator fi;
|
||||
for (fi = fgroup->_instances.begin(); fi != fgroup->_instances.end(); ++fi) {
|
||||
CPPInstance *function = (*fi);
|
||||
CPPFunctionType *ftype =
|
||||
function->_type->as_function_type();
|
||||
if (ftype != NULL && ftype->_parameters->_parameters.size() == 0) {
|
||||
getter = function;
|
||||
return_type = ftype->_return_type;
|
||||
|
||||
// The return type of the non-const method probably better represents
|
||||
// the type of the property we are creating.
|
||||
if ((ftype->_flags & CPPFunctionType::F_const_method) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (getter == NULL || return_type == NULL) {
|
||||
cerr << "No instance of getter '"
|
||||
<< make_property->_getter->_name << "' is suitable!\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
InterrogateDatabase *idb = InterrogateDatabase::get_ptr();
|
||||
// It isn't here, so we'll have to define it.
|
||||
ElementIndex index = idb->get_next_index();
|
||||
_properties_by_name[property_name] = index;
|
||||
|
||||
InterrogateElement iproperty;
|
||||
iproperty._name = make_property->get_simple_name();
|
||||
iproperty._scoped_name = descope(make_property->get_local_name(&parser));
|
||||
|
||||
iproperty._type = get_type(return_type, false);
|
||||
|
||||
iproperty._flags |= InterrogateElement::F_has_getter;
|
||||
iproperty._getter = get_function(getter, "", struct_type,
|
||||
struct_type->get_scope(), 0);
|
||||
|
||||
// See if there happens to be a comment before the element.
|
||||
if (make_property->_leading_comment != (CPPCommentBlock *)NULL) {
|
||||
iproperty._comment = trim_blanks(make_property->_leading_comment->_comment);
|
||||
}
|
||||
|
||||
// Now look for setters.
|
||||
fgroup = make_property->_setter;
|
||||
if (fgroup != NULL) {
|
||||
for (fi = fgroup->_instances.begin(); fi != fgroup->_instances.end(); ++fi) {
|
||||
CPPInstance *function = (*fi);
|
||||
iproperty._flags |= InterrogateElement::F_has_setter;
|
||||
iproperty._setter = get_function(function, "", struct_type,
|
||||
struct_type->get_scope(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
idb->add_element(index, iproperty);
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InterrogateBuilder::get_make_seq
|
||||
// Access: Private
|
||||
@ -2285,6 +2370,10 @@ define_struct_type(InterrogateType &itype, CPPStructType *cpptype,
|
||||
TypeIndex nested_index = get_type(type, false);
|
||||
itype._nested_types.push_back(nested_index);
|
||||
}
|
||||
|
||||
} else if ((*di)->get_subtype() == CPPDeclaration::ST_make_property) {
|
||||
ElementIndex element_index = get_make_property((*di)->as_make_property(), cpptype);
|
||||
itype._elements.push_back(element_index);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -38,6 +38,7 @@ class CPPScope;
|
||||
class CPPIdentifier;
|
||||
class CPPNameComponent;
|
||||
class CPPManifest;
|
||||
class CPPMakeProperty;
|
||||
class CPPMakeSeq;
|
||||
class InterrogateType;
|
||||
class InterrogateFunction;
|
||||
@ -108,6 +109,9 @@ public:
|
||||
CPPStructType *struct_type, CPPScope *scope,
|
||||
int flags, const string &expression = string());
|
||||
|
||||
ElementIndex
|
||||
get_make_property(CPPMakeProperty *make_property, CPPStructType *struct_type);
|
||||
|
||||
MakeSeqIndex
|
||||
get_make_seq(CPPMakeSeq *make_seq, CPPStructType *struct_type);
|
||||
|
||||
@ -132,10 +136,12 @@ public:
|
||||
typedef map<string, TypeIndex> TypesByName;
|
||||
typedef map<string, FunctionIndex> FunctionsByName;
|
||||
typedef map<string, MakeSeqIndex> MakeSeqsByName;
|
||||
typedef map<string, ElementIndex> PropertiesByName;
|
||||
|
||||
TypesByName _types_by_name;
|
||||
FunctionsByName _functions_by_name;
|
||||
MakeSeqsByName _make_seqs_by_name;
|
||||
PropertiesByName _properties_by_name;
|
||||
|
||||
typedef map<string, char> IncludeFiles;
|
||||
IncludeFiles _include_files;
|
||||
|
@ -73,11 +73,11 @@ PUBLISHED:
|
||||
|
||||
virtual void transform(const LMatrix4d &mat);
|
||||
|
||||
public:
|
||||
double _switch_in, _switch_out, _fade;
|
||||
LPoint3d _center;
|
||||
|
||||
public:
|
||||
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user