Browse Source

wide interrogate improvements: sequence protocol, MAKE_SEQ, __setitem__, and parameter coercion

David Rose 17 years ago
parent
commit
58e0537e3c
100 changed files with 3539 additions and 3085 deletions
  1. 4 2
      dtool/src/cppparser/Sources.pp
  2. 1705 2303
      dtool/src/cppparser/cppBison.cxx.prebuilt
  3. 114 256
      dtool/src/cppparser/cppBison.h.prebuilt
  4. 7 0
      dtool/src/cppparser/cppBison.yxx
  5. 10 0
      dtool/src/cppparser/cppDeclaration.cxx
  6. 3 0
      dtool/src/cppparser/cppDeclaration.h
  7. 9 9
      dtool/src/cppparser/cppExpression.cxx
  8. 61 0
      dtool/src/cppparser/cppMakeSeq.cxx
  9. 48 0
      dtool/src/cppparser/cppMakeSeq.h
  10. 1 0
      dtool/src/cppparser/cppParser_composite1.cxx
  11. 1 0
      dtool/src/cppparser/cppPreprocessor.cxx
  12. 2 0
      dtool/src/dtoolbase/dtoolbase.h
  13. 37 1
      dtool/src/interrogate/functionRemap.cxx
  14. 10 1
      dtool/src/interrogate/functionRemap.h
  15. 75 1
      dtool/src/interrogate/interfaceMaker.cxx
  16. 21 2
      dtool/src/interrogate/interfaceMaker.h
  17. 569 407
      dtool/src/interrogate/interfaceMakerPythonNative.cxx
  18. 105 80
      dtool/src/interrogate/interfaceMakerPythonNative.h
  19. 18 0
      dtool/src/interrogate/typeManager.cxx
  20. 1 0
      dtool/src/interrogate/typeManager.h
  21. 129 1
      dtool/src/interrogatedb/py_panda.cxx
  22. 28 3
      dtool/src/interrogatedb/py_panda.h
  23. 13 0
      dtool/src/pystub/pystub.cxx
  24. 3 0
      panda/src/chan/animControlCollection.h
  25. 2 0
      panda/src/chan/animGroup.h
  26. 1 0
      panda/src/chan/partBundle.h
  27. 2 0
      panda/src/chan/partGroup.h
  28. 5 5
      panda/src/collide/collisionFloorMesh.I
  29. 4 2
      panda/src/collide/collisionFloorMesh.h
  30. 3 0
      panda/src/collide/collisionHandlerEvent.h
  31. 1 0
      panda/src/collide/collisionHandlerQueue.h
  32. 1 0
      panda/src/collide/collisionNode.h
  33. 1 0
      panda/src/collide/collisionPolygon.h
  34. 1 0
      panda/src/collide/collisionTraverser.h
  35. 1 0
      panda/src/display/graphicsEngine.h
  36. 2 0
      panda/src/display/graphicsOutput.h
  37. 1 0
      panda/src/display/graphicsPipeSelection.h
  38. 1 0
      panda/src/display/graphicsWindow.h
  39. 4 0
      panda/src/distort/nonlinearImager.h
  40. 6 6
      panda/src/downloader/httpChannel.I
  41. 3 2
      panda/src/downloader/httpChannel.h
  42. 1 0
      panda/src/egg/eggCompositePrimitive.h
  43. 2 0
      panda/src/egg/eggGroup.h
  44. 1 0
      panda/src/egg/eggNurbsCurve.h
  45. 2 0
      panda/src/egg/eggNurbsSurface.h
  46. 2 0
      panda/src/egg/eggPrimitive.h
  47. 1 0
      panda/src/egg/eggTextureCollection.h
  48. 2 1
      panda/src/egg/eggVertexPool.h
  49. 11 0
      panda/src/event/asyncTaskCollection.cxx
  50. 2 0
      panda/src/event/asyncTaskCollection.h
  51. 1 0
      panda/src/event/asyncTaskManager.h
  52. 1 0
      panda/src/event/event.h
  53. 3 0
      panda/src/express/memoryUsagePointers.h
  54. 1 0
      panda/src/express/multifile.h
  55. 13 0
      panda/src/express/pointerToArray.I
  56. 5 0
      panda/src/express/pointerToArray.h
  57. 21 0
      panda/src/express/virtualFileList.I
  58. 5 1
      panda/src/express/virtualFileList.h
  59. 1 0
      panda/src/gobj/geom.h
  60. 1 0
      panda/src/gobj/geomPrimitive.h
  61. 1 0
      panda/src/gobj/geomVertexData.h
  62. 7 0
      panda/src/gobj/geomVertexFormat.h
  63. 1 0
      panda/src/gobj/sliderTable.h
  64. 1 0
      panda/src/gobj/transformBlend.h
  65. 1 0
      panda/src/gobj/transformBlendTable.h
  66. 1 0
      panda/src/gobj/transformTable.h
  67. 2 1
      panda/src/grutil/lineSegs.h
  68. 117 0
      panda/src/linmath/lmatrix3_src.I
  69. 34 0
      panda/src/linmath/lmatrix3_src.h
  70. 117 0
      panda/src/linmath/lmatrix4_src.I
  71. 33 1
      panda/src/linmath/lmatrix4_src.h
  72. 23 0
      panda/src/linmath/lvecBase2_src.I
  73. 4 0
      panda/src/linmath/lvecBase2_src.h
  74. 23 0
      panda/src/linmath/lvecBase3_src.I
  75. 4 0
      panda/src/linmath/lvecBase3_src.h
  76. 23 0
      panda/src/linmath/lvecBase4_src.I
  77. 4 0
      panda/src/linmath/lvecBase4_src.h
  78. 2 0
      panda/src/mathutil/boundingBox.h
  79. 2 0
      panda/src/mathutil/boundingHexahedron.h
  80. 1 0
      panda/src/mathutil/triangulator.h
  81. 1 0
      panda/src/movies/microphoneAudio.h
  82. 1 0
      panda/src/movies/webcamVideo.h
  83. 1 0
      panda/src/ode/odeAMotorJoint.h
  84. 1 0
      panda/src/ode/odeBody.h
  85. 11 0
      panda/src/ode/odeJointCollection.cxx
  86. 2 0
      panda/src/ode/odeJointCollection.h
  87. 1 0
      panda/src/ode/odeLMotorJoint.h
  88. 2 0
      panda/src/parametrics/nurbsCurveEvaluator.h
  89. 2 0
      panda/src/parametrics/nurbsCurveResult.h
  90. 2 0
      panda/src/parametrics/nurbsSurfaceEvaluator.h
  91. 1 0
      panda/src/particlesystem/spriteParticleRenderer.h
  92. 1 0
      panda/src/pgraph/attribNodeRegistry.h
  93. 1 0
      panda/src/pgraph/camera.h
  94. 2 0
      panda/src/pgraph/clipPlaneAttrib.h
  95. 1 0
      panda/src/pgraph/cullBinManager.h
  96. 2 0
      panda/src/pgraph/geomNode.h
  97. 11 0
      panda/src/pgraph/internalNameCollection.cxx
  98. 2 0
      panda/src/pgraph/internalNameCollection.h
  99. 2 0
      panda/src/pgraph/lightAttrib.h
  100. 2 0
      panda/src/pgraph/loader.h

+ 4 - 2
dtool/src/cppparser/Sources.pp

@@ -15,7 +15,8 @@
      cppExpressionParser.h cppExtensionType.h cppFile.h  \
      cppFunctionGroup.h cppFunctionType.h cppGlobals.h  \
      cppIdentifier.h cppInstance.h cppInstanceIdentifier.h  \
-     cppManifest.h cppNameComponent.h cppNamespace.h  \
+     cppMakeSeq.h cppManifest.h \
+     cppNameComponent.h cppNamespace.h  \
      cppParameterList.h cppParser.h cppPointerType.h  \
      cppPreprocessor.h cppReferenceType.h cppScope.h  \
      cppSimpleType.h cppStructType.h cppTBDType.h  \
@@ -29,7 +30,8 @@
      cppEnumType.cxx cppExpression.cxx cppExpressionParser.cxx  \
      cppExtensionType.cxx cppFile.cxx cppFunctionGroup.cxx  \
      cppFunctionType.cxx cppGlobals.cxx cppIdentifier.cxx  \
-     cppInstance.cxx cppInstanceIdentifier.cxx cppManifest.cxx  \
+     cppInstance.cxx cppInstanceIdentifier.cxx \
+     cppMakeSeq.cxx cppManifest.cxx  \
      cppNameComponent.cxx cppNamespace.cxx cppParameterList.cxx  \
      cppParser.cxx cppPointerType.cxx cppPreprocessor.cxx  \
      cppReferenceType.cxx cppScope.cxx cppSimpleType.cxx  \

File diff suppressed because it is too large
+ 1705 - 2303
dtool/src/cppparser/cppBison.cxx.prebuilt


+ 114 - 256
dtool/src/cppparser/cppBison.h.prebuilt

@@ -1,260 +1,118 @@
-/* A Bison parser, made by GNU Bison 2.0.  */
 
-/* Skeleton parser for Yacc-like parsing with Bison,
-   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2, or (at your option)
-   any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
-
-/* As a special exception, when this file is copied by Bison into a
-   Bison output file, you may use that output file without restriction.
-   This special exception was added by the Free Software Foundation
-   in version 1.24 of Bison.  */
-
-/* Tokens.  */
-#ifndef YYTOKENTYPE
-# define YYTOKENTYPE
-   /* Put the tokens into the symbol table, so that GDB and other debuggers
-      know about them.  */
-   enum yytokentype {
-     REAL = 258,
-     INTEGER = 259,
-     CHAR_TOK = 260,
-     STRING = 261,
-     SIMPLE_IDENTIFIER = 262,
-     IDENTIFIER = 263,
-     TYPENAME_IDENTIFIER = 264,
-     SCOPING = 265,
-     TYPEDEFNAME = 266,
-     ELLIPSIS = 267,
-     OROR = 268,
-     ANDAND = 269,
-     EQCOMPARE = 270,
-     NECOMPARE = 271,
-     LECOMPARE = 272,
-     GECOMPARE = 273,
-     LSHIFT = 274,
-     RSHIFT = 275,
-     POINTSAT_STAR = 276,
-     DOT_STAR = 277,
-     UNARY = 278,
-     UNARY_NOT = 279,
-     UNARY_NEGATE = 280,
-     UNARY_MINUS = 281,
-     UNARY_STAR = 282,
-     UNARY_REF = 283,
-     POINTSAT = 284,
-     SCOPE = 285,
-     PLUSPLUS = 286,
-     MINUSMINUS = 287,
-     TIMESEQUAL = 288,
-     DIVIDEEQUAL = 289,
-     MODEQUAL = 290,
-     PLUSEQUAL = 291,
-     MINUSEQUAL = 292,
-     OREQUAL = 293,
-     ANDEQUAL = 294,
-     XOREQUAL = 295,
-     LSHIFTEQUAL = 296,
-     RSHIFTEQUAL = 297,
-     TOKENPASTE = 298,
-     KW_BEGIN_PUBLISH = 299,
-     KW_BLOCKING = 300,
-     KW_BOOL = 301,
-     KW_CATCH = 302,
-     KW_CHAR = 303,
-     KW_WCHAR_T = 304,
-     KW_CLASS = 305,
-     KW_CONST = 306,
-     KW_DELETE = 307,
-     KW_DOUBLE = 308,
-     KW_DYNAMIC_CAST = 309,
-     KW_ELSE = 310,
-     KW_END_PUBLISH = 311,
-     KW_ENUM = 312,
-     KW_EXTERN = 313,
-     KW_EXPLICIT = 314,
-     KW_PUBLISHED = 315,
-     KW_FALSE = 316,
-     KW_FLOAT = 317,
-     KW_FRIEND = 318,
-     KW_FOR = 319,
-     KW_GOTO = 320,
-     KW_IF = 321,
-     KW_INLINE = 322,
-     KW_INT = 323,
-     KW_LONG = 324,
-     KW_LONGLONG = 325,
-     KW_MUTABLE = 326,
-     KW_NAMESPACE = 327,
-     KW_NEW = 328,
-     KW_OPERATOR = 329,
-     KW_PRIVATE = 330,
-     KW_PROTECTED = 331,
-     KW_PUBLIC = 332,
-     KW_REGISTER = 333,
-     KW_RETURN = 334,
-     KW_SHORT = 335,
-     KW_SIGNED = 336,
-     KW_SIZEOF = 337,
-     KW_STATIC = 338,
-     KW_STATIC_CAST = 339,
-     KW_STRUCT = 340,
-     KW_TEMPLATE = 341,
-     KW_THROW = 342,
-     KW_TRUE = 343,
-     KW_TRY = 344,
-     KW_TYPEDEF = 345,
-     KW_TYPENAME = 346,
-     KW_UNION = 347,
-     KW_UNSIGNED = 348,
-     KW_USING = 349,
-     KW_VIRTUAL = 350,
-     KW_VOID = 351,
-     KW_VOLATILE = 352,
-     KW_WHILE = 353,
-     START_CPP = 354,
-     START_CONST_EXPR = 355,
-     START_TYPE = 356
-   };
-#endif
-#define REAL 258
-#define INTEGER 259
-#define CHAR_TOK 260
-#define STRING 261
-#define SIMPLE_IDENTIFIER 262
-#define IDENTIFIER 263
-#define TYPENAME_IDENTIFIER 264
-#define SCOPING 265
-#define TYPEDEFNAME 266
-#define ELLIPSIS 267
-#define OROR 268
-#define ANDAND 269
-#define EQCOMPARE 270
-#define NECOMPARE 271
-#define LECOMPARE 272
-#define GECOMPARE 273
-#define LSHIFT 274
-#define RSHIFT 275
-#define POINTSAT_STAR 276
-#define DOT_STAR 277
-#define UNARY 278
-#define UNARY_NOT 279
-#define UNARY_NEGATE 280
-#define UNARY_MINUS 281
-#define UNARY_STAR 282
-#define UNARY_REF 283
-#define POINTSAT 284
-#define SCOPE 285
-#define PLUSPLUS 286
-#define MINUSMINUS 287
-#define TIMESEQUAL 288
-#define DIVIDEEQUAL 289
-#define MODEQUAL 290
-#define PLUSEQUAL 291
-#define MINUSEQUAL 292
-#define OREQUAL 293
-#define ANDEQUAL 294
-#define XOREQUAL 295
-#define LSHIFTEQUAL 296
-#define RSHIFTEQUAL 297
-#define TOKENPASTE 298
-#define KW_BEGIN_PUBLISH 299
-#define KW_BLOCKING 300
-#define KW_BOOL 301
-#define KW_CATCH 302
-#define KW_CHAR 303
-#define KW_WCHAR_T 304
-#define KW_CLASS 305
-#define KW_CONST 306
-#define KW_DELETE 307
-#define KW_DOUBLE 308
-#define KW_DYNAMIC_CAST 309
-#define KW_ELSE 310
-#define KW_END_PUBLISH 311
-#define KW_ENUM 312
-#define KW_EXTERN 313
-#define KW_EXPLICIT 314
-#define KW_PUBLISHED 315
-#define KW_FALSE 316
-#define KW_FLOAT 317
-#define KW_FRIEND 318
-#define KW_FOR 319
-#define KW_GOTO 320
-#define KW_IF 321
-#define KW_INLINE 322
-#define KW_INT 323
-#define KW_LONG 324
-#define KW_LONGLONG 325
-#define KW_MUTABLE 326
-#define KW_NAMESPACE 327
-#define KW_NEW 328
-#define KW_OPERATOR 329
-#define KW_PRIVATE 330
-#define KW_PROTECTED 331
-#define KW_PUBLIC 332
-#define KW_REGISTER 333
-#define KW_RETURN 334
-#define KW_SHORT 335
-#define KW_SIGNED 336
-#define KW_SIZEOF 337
-#define KW_STATIC 338
-#define KW_STATIC_CAST 339
-#define KW_STRUCT 340
-#define KW_TEMPLATE 341
-#define KW_THROW 342
-#define KW_TRUE 343
-#define KW_TRY 344
-#define KW_TYPEDEF 345
-#define KW_TYPENAME 346
-#define KW_UNION 347
-#define KW_UNSIGNED 348
-#define KW_USING 349
-#define KW_VIRTUAL 350
-#define KW_VOID 351
-#define KW_VOLATILE 352
-#define KW_WHILE 353
-#define START_CPP 354
-#define START_CONST_EXPR 355
-#define START_TYPE 356
-
-
-
-
-#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
-typedef int YYSTYPE;
-# define yystype YYSTYPE /* obsolescent; will be withdrawn */
-# define YYSTYPE_IS_DECLARED 1
-# define YYSTYPE_IS_TRIVIAL 1
-#endif
-
-
-
-#if ! defined (YYLTYPE) && ! defined (YYLTYPE_IS_DECLARED)
-typedef struct YYLTYPE
-{
-  int first_line;
-  int first_column;
-  int last_line;
-  int last_column;
-} YYLTYPE;
-# define yyltype YYLTYPE /* obsolescent; will be withdrawn */
-# define YYLTYPE_IS_DECLARED 1
-# define YYLTYPE_IS_TRIVIAL 1
+#ifndef YYLTYPE
+typedef
+  struct yyltype
+    {
+      int timestamp;
+      int first_line;
+      int first_column;
+      int last_line;
+      int last_column;
+      char *text;
+   }
+  yyltype;
+
+#define YYLTYPE yyltype
 #endif
 
-
-
+#define	REAL	257
+#define	INTEGER	258
+#define	CHAR_TOK	259
+#define	STRING	260
+#define	SIMPLE_IDENTIFIER	261
+#define	IDENTIFIER	262
+#define	TYPENAME_IDENTIFIER	263
+#define	SCOPING	264
+#define	TYPEDEFNAME	265
+#define	ELLIPSIS	266
+#define	OROR	267
+#define	ANDAND	268
+#define	EQCOMPARE	269
+#define	NECOMPARE	270
+#define	LECOMPARE	271
+#define	GECOMPARE	272
+#define	LSHIFT	273
+#define	RSHIFT	274
+#define	POINTSAT_STAR	275
+#define	DOT_STAR	276
+#define	UNARY	277
+#define	UNARY_NOT	278
+#define	UNARY_NEGATE	279
+#define	UNARY_MINUS	280
+#define	UNARY_STAR	281
+#define	UNARY_REF	282
+#define	POINTSAT	283
+#define	SCOPE	284
+#define	PLUSPLUS	285
+#define	MINUSMINUS	286
+#define	TIMESEQUAL	287
+#define	DIVIDEEQUAL	288
+#define	MODEQUAL	289
+#define	PLUSEQUAL	290
+#define	MINUSEQUAL	291
+#define	OREQUAL	292
+#define	ANDEQUAL	293
+#define	XOREQUAL	294
+#define	LSHIFTEQUAL	295
+#define	RSHIFTEQUAL	296
+#define	TOKENPASTE	297
+#define	KW_BEGIN_PUBLISH	298
+#define	KW_BLOCKING	299
+#define	KW_BOOL	300
+#define	KW_CATCH	301
+#define	KW_CHAR	302
+#define	KW_WCHAR_T	303
+#define	KW_CLASS	304
+#define	KW_CONST	305
+#define	KW_DELETE	306
+#define	KW_DOUBLE	307
+#define	KW_DYNAMIC_CAST	308
+#define	KW_ELSE	309
+#define	KW_END_PUBLISH	310
+#define	KW_ENUM	311
+#define	KW_EXTERN	312
+#define	KW_EXPLICIT	313
+#define	KW_PUBLISHED	314
+#define	KW_FALSE	315
+#define	KW_FLOAT	316
+#define	KW_FRIEND	317
+#define	KW_FOR	318
+#define	KW_GOTO	319
+#define	KW_IF	320
+#define	KW_INLINE	321
+#define	KW_INT	322
+#define	KW_LONG	323
+#define	KW_LONGLONG	324
+#define	KW_MAKE_SEQ	325
+#define	KW_MUTABLE	326
+#define	KW_NAMESPACE	327
+#define	KW_NEW	328
+#define	KW_OPERATOR	329
+#define	KW_PRIVATE	330
+#define	KW_PROTECTED	331
+#define	KW_PUBLIC	332
+#define	KW_REGISTER	333
+#define	KW_RETURN	334
+#define	KW_SHORT	335
+#define	KW_SIGNED	336
+#define	KW_SIZEOF	337
+#define	KW_STATIC	338
+#define	KW_STATIC_CAST	339
+#define	KW_STRUCT	340
+#define	KW_TEMPLATE	341
+#define	KW_THROW	342
+#define	KW_TRUE	343
+#define	KW_TRY	344
+#define	KW_TYPEDEF	345
+#define	KW_TYPENAME	346
+#define	KW_UNION	347
+#define	KW_UNSIGNED	348
+#define	KW_USING	349
+#define	KW_VIRTUAL	350
+#define	KW_VOID	351
+#define	KW_VOLATILE	352
+#define	KW_WHILE	353
+#define	START_CPP	354
+#define	START_CONST_EXPR	355
+#define	START_TYPE	356
 

+ 7 - 0
dtool/src/cppparser/cppBison.yxx

@@ -14,6 +14,7 @@
 #include "cppEnumType.h"
 #include "cppFunctionType.h"
 #include "cppTBDType.h"
+#include "cppMakeSeq.h"
 #include "cppParameterList.h"
 #include "cppInstance.h"
 #include "cppClassTemplateParameter.h"
@@ -262,6 +263,7 @@ pop_struct() {
 %token KW_INT
 %token KW_LONG
 %token KW_LONGLONG
+%token KW_MAKE_SEQ
 %token KW_MUTABLE
 %token KW_NAMESPACE
 %token KW_NEW
@@ -471,6 +473,11 @@ declaration:
         | KW_PRIVATE ':'
 {
   current_scope->set_current_vis(V_private);
+}
+	| 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);
 }
         ;
 

+ 10 - 0
dtool/src/cppparser/cppDeclaration.cxx

@@ -356,6 +356,16 @@ as_type_proxy() {
   return (CPPTypeProxy *)NULL;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: CPPDeclaration::as_make_seq
+//       Access: Public, Virtual
+//  Description:
+////////////////////////////////////////////////////////////////////
+CPPMakeSeq *CPPDeclaration::
+as_make_seq() {
+  return (CPPMakeSeq *)NULL;
+}
+
 
 ////////////////////////////////////////////////////////////////////
 //     Function: CPPDeclaration::is_equal

+ 3 - 0
dtool/src/cppparser/cppDeclaration.h

@@ -47,6 +47,7 @@ class CPPExtensionType;
 class CPPStructType;
 class CPPEnumType;
 class CPPTypeProxy;
+class CPPMakeSeq;
 class CPPClassTemplateParameter;
 class CPPTBDType;
 class CPPScope;
@@ -68,6 +69,7 @@ public:
     ST_type,
     ST_namespace,
     ST_using,
+    ST_make_seq,
 
     // Subtypes of CPPType
     ST_simple,
@@ -134,6 +136,7 @@ public:
   virtual CPPEnumType *as_enum_type();
   virtual CPPTBDType *as_tbd_type();
   virtual CPPTypeProxy *as_type_proxy();
+  virtual CPPMakeSeq *as_make_seq();
 
   CPPVisibility _vis;
   CPPTemplateScope *_template_scope;

+ 9 - 9
dtool/src/cppparser/cppExpression.cxx

@@ -30,7 +30,7 @@
 #include <assert.h>
 
 ////////////////////////////////////////////////////////////////////
-//     Function: CPPExpresion::Result::Constructor
+//     Function: CPPExpression::Result::Constructor
 //       Access: Public
 //  Description:
 ////////////////////////////////////////////////////////////////////
@@ -40,7 +40,7 @@ Result() {
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: CPPExpresion::Result::Constructor
+//     Function: CPPExpression::Result::Constructor
 //       Access: Public
 //  Description:
 ////////////////////////////////////////////////////////////////////
@@ -51,7 +51,7 @@ Result(int value) {
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: CPPExpresion::Result::Constructor
+//     Function: CPPExpression::Result::Constructor
 //       Access: Public
 //  Description:
 ////////////////////////////////////////////////////////////////////
@@ -62,7 +62,7 @@ Result(double value) {
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: CPPExpresion::Result::Constructor
+//     Function: CPPExpression::Result::Constructor
 //       Access: Public
 //  Description:
 ////////////////////////////////////////////////////////////////////
@@ -74,7 +74,7 @@ Result(void *value) {
 
 
 ////////////////////////////////////////////////////////////////////
-//     Function: CPPExpresion::Result::as_integer
+//     Function: CPPExpression::Result::as_integer
 //       Access: Public
 //  Description:
 ////////////////////////////////////////////////////////////////////
@@ -99,7 +99,7 @@ as_integer() const {
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: CPPExpresion::Result::as_real
+//     Function: CPPExpression::Result::as_real
 //       Access: Public
 //  Description:
 ////////////////////////////////////////////////////////////////////
@@ -124,7 +124,7 @@ as_real() const {
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: CPPExpresion::Result::as_pointer
+//     Function: CPPExpression::Result::as_pointer
 //       Access: Public
 //  Description:
 ////////////////////////////////////////////////////////////////////
@@ -148,7 +148,7 @@ as_pointer() const {
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: CPPExpresion::Result::output
+//     Function: CPPExpression::Result::output
 //       Access: Public
 //  Description:
 ////////////////////////////////////////////////////////////////////
@@ -177,7 +177,7 @@ output(ostream &out) const {
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: CPPExpresion::Constructor
+//     Function: CPPExpression::Constructor
 //       Access: Public
 //  Description:
 ////////////////////////////////////////////////////////////////////

+ 61 - 0
dtool/src/cppparser/cppMakeSeq.cxx

@@ -0,0 +1,61 @@
+// Filename: cppMakeSeq.cxx
+// Created by:  drose (06Nov08)
+//
+////////////////////////////////////////////////////////////////////
+//
+// 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 "cppMakeSeq.h"
+
+////////////////////////////////////////////////////////////////////
+//     Function: CPPMakeSeq::Constructor
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+CPPMakeSeq::
+CPPMakeSeq(const string &seq_name, const string &num_name,
+           const string &element_name, const CPPFile &file) :
+  CPPDeclaration(file),
+  _seq_name(seq_name),
+  _num_name(num_name),
+  _element_name(element_name)
+{
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: CPPMakeSeq::output
+//       Access: Public, Virtual
+//  Description:
+////////////////////////////////////////////////////////////////////
+void CPPMakeSeq::
+output(ostream &out, int indent_level, CPPScope *scope, bool complete) const {
+  out << "__make_seq(" << _seq_name << ", " << _num_name << ", "
+      << _element_name << ");";
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: CPPMakeSeq::get_subtype
+//       Access: Public, Virtual
+//  Description:
+////////////////////////////////////////////////////////////////////
+CPPDeclaration::SubType CPPMakeSeq::
+get_subtype() const {
+  return ST_make_seq;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: CPPMakeSeq::as_make_seq
+//       Access: Public, Virtual
+//  Description:
+////////////////////////////////////////////////////////////////////
+CPPMakeSeq *CPPMakeSeq::
+as_make_seq() {
+  return this;
+}

+ 48 - 0
dtool/src/cppparser/cppMakeSeq.h

@@ -0,0 +1,48 @@
+// Filename: cppMakeSeq.h
+// Created by:  drose (06Nov08)
+//
+////////////////////////////////////////////////////////////////////
+//
+// 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 CPPMAKESEQ_H
+#define CPPMAKESEQ_H
+
+#include "dtoolbase.h"
+
+#include "cppDeclaration.h"
+
+///////////////////////////////////////////////////////////////////
+//       Class : CPPMakeSeq
+// Description : This is a MAKE_SEQ() declaration appearing within a
+//               class body.  It means to generate a sequence method
+//               within Python, replacing (for instance)
+//               get_num_nodes()/get_node(n) with a synthetic
+//               get_nodes() method.
+////////////////////////////////////////////////////////////////////
+class CPPMakeSeq : public CPPDeclaration {
+public:
+  CPPMakeSeq(const string &seq_name, const string &num_name,
+             const string &element_name, const CPPFile &file);
+
+  virtual void output(ostream &out, int indent_level, CPPScope *scope,
+                      bool complete) const;
+
+  virtual SubType get_subtype() const;
+  virtual CPPMakeSeq *as_make_seq();
+
+  string _seq_name;
+  string _num_name;
+  string _element_name;
+};
+
+#endif
+
+

+ 1 - 0
dtool/src/cppparser/cppParser_composite1.cxx

@@ -4,6 +4,7 @@
 #include "cppCommentBlock.cxx"
 #include "cppConstType.cxx"
 #include "cppDeclaration.cxx"
+#include "cppMakeSeq.cxx"
 #include "cppParameterList.cxx"
 #include "cppParser.cxx"
 #include "cppPointerType.cxx"

+ 1 - 0
dtool/src/cppparser/cppPreprocessor.cxx

@@ -1976,6 +1976,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_seq") return KW_MAKE_SEQ;
   if (name == "mutable") return KW_MUTABLE;
   if (name == "namespace") return KW_NAMESPACE;
   if (name == "new") return KW_NEW;

+ 2 - 0
dtool/src/dtoolbase/dtoolbase.h

@@ -291,11 +291,13 @@
 #define BEGIN_PUBLISH __begin_publish
 #define END_PUBLISH __end_publish
 #define BLOCKING __blocking
+#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.
 #else
 #define BEGIN_PUBLISH
 #define END_PUBLISH
 #define BLOCKING
+#define MAKE_SEQ(seq_name, num_name, element_name)
 #endif
 
 #ifdef __cplusplus

+ 37 - 1
dtool/src/interrogate/functionRemap.cxx

@@ -48,6 +48,7 @@ FunctionRemap(const InterrogateType &itype, const InterrogateFunction &ifunc,
   _first_true_parameter = 0;
   _num_default_parameters = num_default_parameters;
   _type = T_normal;
+  _flags = 0;
   _wrapper_index = 0;
 
   _return_value_needs_management = false;
@@ -446,6 +447,8 @@ setup_properties(const InterrogateFunction &ifunc, InterfaceMaker *interface_mak
     _blocking = true;
   }
 
+  string fname = _cppfunc->get_simple_name();
+
   if (_cpptype != (CPPType *)NULL &&
       ((_cppfunc->_storage_class & CPPInstance::SC_static) == 0) &&
       _type != T_constructor) {
@@ -469,7 +472,6 @@ setup_properties(const InterrogateFunction &ifunc, InterfaceMaker *interface_mak
       
     // Also check the name of the function.  If it's one of the
     // assignment-style operators, flag it as such.
-    string fname = _cppfunc->get_simple_name();
     if (fname == "operator =" ||
         fname == "operator *=" ||
         fname == "operator /=" ||
@@ -592,5 +594,39 @@ setup_properties(const InterrogateFunction &ifunc, InterfaceMaker *interface_mak
     _return_value_destructor = builder.get_destructor_for(return_meat_type);
   }
 
+  // Check for a special meaning by name and signature.
+  if (_type == T_normal) {
+    int first_param = 0;
+    if (_has_this) {
+      first_param = 1;
+    }
+
+    if (fname == "operator []" || fname == "__getitem__") {
+      _flags |= F_getitem;
+      if (_has_this && _parameters.size() == 2) {
+        if (TypeManager::is_integer(_parameters[1]._remap->get_new_type())) {
+          // It receives a single int parameter.
+          _flags |= F_getitem_int;
+        }
+      }
+
+    } else if (fname == "__setitem__") {
+      _flags |= F_setitem;
+      if (_has_this && _parameters.size() > 2) {
+        if (TypeManager::is_integer(_parameters[1]._remap->get_new_type())) {
+          // Its first parameter is an int parameter, presumably an index.
+          _flags |= F_setitem_int;
+        }
+      }
+
+    } else if (fname == "size" || fname == "__len__") {
+      if (_parameters.size() == first_param &&
+          TypeManager::is_integer(_return_type->get_new_type())) {
+        // It receives no parameters, and returns an integer.
+        _flags |= F_size;
+      }
+    }
+  }
+
   return true;
 }

+ 10 - 1
dtool/src/interrogate/functionRemap.h

@@ -75,7 +75,15 @@ public:
     T_assignment_method,
     T_typecast,
     T_getter,
-    T_setter
+    T_setter,
+  };
+
+  enum Flags {
+    F_getitem      = 0x0001,
+    F_getitem_int  = 0x0002,
+    F_size         = 0x0004,
+    F_setitem      = 0x0008,
+    F_setitem_int  = 0x0010,
   };
 
   typedef vector<Parameter> Parameters;
@@ -90,6 +98,7 @@ public:
   int _first_true_parameter;
   int _num_default_parameters;
   Type _type;
+  int _flags;
   string _expression;
   string _function_signature;
   string _hash;

+ 75 - 1
dtool/src/interrogate/interfaceMaker.cxx

@@ -35,6 +35,8 @@
 #include "interrogateElement.h"
 #include "cppFunctionType.h"
 #include "cppParameterList.h"
+#include "cppMakeSeq.h"
+#include "cppStructType.h"
 #include "pnotify.h"
 
  InterrogateType dummy_type;
@@ -54,6 +56,7 @@ Function(const string &name,
   _ifunc(ifunc)
 {
   _has_this = false;
+  _flags = 0;
 }
  
 ////////////////////////////////////////////////////////////////////
@@ -68,6 +71,20 @@ InterfaceMaker::Function::
     delete (*ri);
   }
 }
+ 
+////////////////////////////////////////////////////////////////////
+//     Function: InterfaceMaker::MakeSeq::Constructor
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+InterfaceMaker::MakeSeq::
+MakeSeq(const string &name, CPPMakeSeq *cpp_make_seq) :
+  _name(name),
+  _seq_name(cpp_make_seq->_seq_name),
+  _num_name(cpp_make_seq->_num_name),
+  _element_name(cpp_make_seq->_element_name)
+{
+}
 
 ////////////////////////////////////////////////////////////////////
 //     Function: InterfaceMaker::Object::Constructor
@@ -76,7 +93,8 @@ InterfaceMaker::Function::
 ////////////////////////////////////////////////////////////////////
 InterfaceMaker::Object::
 Object(const InterrogateType &itype) :
-  _itype(itype)
+  _itype(itype),
+  _protocol_types(0)
 {
 }
 
@@ -89,6 +107,58 @@ InterfaceMaker::Object::
 ~Object() {
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: InterfaceMaker::Object::check_protocols
+//       Access: Public
+//  Description: To be called after all of the methods have been
+//               added, this checks which protocols this object
+//               appears to support (based on the methods it
+//               provides).
+////////////////////////////////////////////////////////////////////
+void InterfaceMaker::Object::
+check_protocols() {
+  InterrogateDatabase *idb = InterrogateDatabase::get_ptr();
+
+  int flags = 0;
+
+  Functions::const_iterator fi;
+  for (fi = _methods.begin(); fi != _methods.end(); ++fi) {
+    Function *func = (*fi);
+    flags |= func->_flags;
+  }
+
+  if ((flags & (FunctionRemap::F_getitem_int | FunctionRemap::F_size)) == 
+      (FunctionRemap::F_getitem_int | FunctionRemap::F_size)) {
+    // If we have both a getitem that receives an int, and a size,
+    // then we implement the sequence protocol: you can iterate
+    // through the elements of this object.
+    _protocol_types |= PT_sequence;
+
+  } else if (flags & FunctionRemap::F_getitem) {
+    // If we have any getitem, then we implement the mapping protocol.
+    _protocol_types |= PT_mapping;
+  }
+
+  // Now are there any make_seq requests within this class?
+  CPPStructType *stype = _itype._cpptype->as_struct_type();
+  if (stype != (CPPStructType *)NULL) {
+    CPPScope *scope = stype->get_scope();
+    if (scope != (CPPScope *)NULL) {
+      CPPScope::Declarations::iterator di;
+      for (di = scope->_declarations.begin(); di != scope->_declarations.end(); ++di) {
+        CPPMakeSeq *cpp_make_seq = (*di)->as_make_seq();
+        if (cpp_make_seq != (CPPMakeSeq *)NULL) {
+          string class_name = _itype.get_scoped_name();
+          string clean_name = InterrogateBuilder::clean_identifier(class_name);
+          string wrapper_name = "MakeSeq_" + clean_name + "_" + cpp_make_seq->_seq_name;
+          MakeSeq *make_seq = new MakeSeq(wrapper_name, cpp_make_seq);
+          _make_seqs.push_back(make_seq);
+        }
+      }
+    }
+  }
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: InterfaceMaker::Constructor
 //       Access: Public
@@ -548,6 +618,8 @@ record_function(const InterrogateType &itype, FunctionIndex func_index) {
           if (remap->_has_this) {
             func->_has_this = true;
           }
+
+          func->_flags |= remap->_flags;
           
           // Make a wrapper for the function.
           FunctionWrapperIndex wrapper_index = 
@@ -655,6 +727,8 @@ record_object(TypeIndex type_index) {
     }
   }    
 
+  object->check_protocols();
+
   int num_nested = itype.number_of_nested_types();
   for (int ni = 0; ni < num_nested; ni++) 
   {

+ 21 - 2
dtool/src/interrogate/interfaceMaker.h

@@ -58,7 +58,7 @@ public:
 
   virtual void write_module(ostream &out, ostream *out_h,InterrogateModuleDef *def);
 
-  virtual ParameterRemap *  remap_parameter(CPPType *struct_type, CPPType *param_type);
+  virtual ParameterRemap *remap_parameter(CPPType *struct_type, CPPType *param_type);
 
   virtual bool synthesize_this_parameter();
   virtual bool separate_overloading();
@@ -81,20 +81,39 @@ public:
     typedef vector<FunctionRemap *> Remaps;
     Remaps _remaps;
     bool _has_this;
+    int _flags;
   };
   typedef vector<Function *> Functions;
   Functions _functions;
 
+  class MakeSeq {
+  public:
+    MakeSeq(const string &name, CPPMakeSeq *cpp_make_seq);
+
+    string _name;
+    string _seq_name;
+    string _num_name;
+    string _element_name;
+  };
+  typedef vector<MakeSeq *> MakeSeqs;
+
   class Object {
   public:
     Object(const InterrogateType &itype);
     ~Object();
 
-    void add_method(Function *method);
+    void check_protocols();
 
     const InterrogateType &_itype;
     Functions _constructors;
     Functions _methods;
+    MakeSeqs _make_seqs;
+
+    enum ProtocolTypes {
+      PT_sequence =   0x0001,
+      PT_mapping =    0x0002,
+    };
+    int _protocol_types;
   };
   typedef map<TypeIndex, Object *> Objects;
   Objects _objects;

File diff suppressed because it is too large
+ 569 - 407
dtool/src/interrogate/interfaceMakerPythonNative.cxx


+ 105 - 80
dtool/src/interrogate/interfaceMakerPythonNative.h

@@ -30,89 +30,114 @@ class FunctionRemap;
 class InterfaceMakerPythonNative : public InterfaceMakerPython 
 {
 public:
-    InterfaceMakerPythonNative(InterrogateModuleDef *def);
-    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_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);
-
-    void write_module_class(ostream &out, Object *cls); 
-    virtual void write_sub_module(ostream &out,  Object *obj); 
-
-    virtual bool synthesize_this_parameter();
-
-    virtual Object *record_object(TypeIndex type_index);
-
+  InterfaceMakerPythonNative(InterrogateModuleDef *def);
+  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_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);
+  
+  void write_module_class(ostream &out, Object *cls); 
+  virtual void write_sub_module(ostream &out,  Object *obj); 
+  
+  virtual bool synthesize_this_parameter();
+  
+  virtual Object *record_object(TypeIndex type_index);
+  
 protected:
-    virtual string get_wrapper_prefix();
-    virtual string get_unique_prefix();
-    virtual void record_function_wrapper(InterrogateFunction &ifunc, 
-        FunctionWrapperIndex wrapper_index);
-
-    virtual void generate_wrappers();
-
+  virtual string get_wrapper_prefix();
+  virtual string get_unique_prefix();
+  virtual void record_function_wrapper(InterrogateFunction &ifunc, 
+                                       FunctionWrapperIndex wrapper_index);
+  
+  virtual void generate_wrappers();
+  
 private:
-    void write_prototype_for_name(ostream &out, Function *func, const std::string &name);
-    void write_prototype_for(ostream &out, Function *func);
-    void write_function_for_name(ostream &out, Function *func, const std::string &name, const std::string &PreProcess, const std::string &ClassName);
-    void write_function_for_top(ostream &out, Function *func, const std::string &PreProcess);
-    void write_function_instance(ostream &out, Function *func,
-        FunctionRemap *remap , string &expected_params, int indent_level, bool errors_fatal, ostream &forwarddecl, const std::string &functionnamestr, bool inplace ) ;
-
-    void write_function_forset(ostream &out, InterfaceMaker::Function *func,
-        std::set< FunctionRemap *> &remaps, string &expected_params, int indent_level , ostream &forwarddecl,const std::string &functionname, bool inplace) ;
-
-    void pack_return_value(ostream &out, int indent_level,
-        FunctionRemap *remap, std::string return_expr ,  ostream &forwarddecl, bool in_place);
-
-    void pack_return_value_tnit(ostream &out, int indent_level,
-        FunctionRemap *remap, string return_expr) ;
-
-    void write_class_prototypes(ostream &out) ;
-    void write_ClasseDeclarations(ostream &out ,  ostream *out_h,Object * obj);
-    void write_ClasseDetails(ostream &out, Object * obj);
-
-    void do_assert_init(ostream &out, int indent_level, bool constructor) const;
+  // This enum defines the various prototypes that must be generated
+  // for the specialty functions that Python requires, especially for
+  // the slotted functions.
+  enum WrapperType {
+    WT_none,
+    WT_no_params,
+    WT_one_param,
+    WT_numeric_operator,
+    WT_setattr,
+    WT_getattr,
+    WT_sequence_getitem,
+    WT_sequence_setitem,
+    WT_sequence_size,
+    WT_mapping_setitem,
+  };
+
+  class SlottedFunctionDef {
+  public:
+    string _answer_location;
+    WrapperType _wrapper_type;
+  };
+
+  static bool get_slotted_function_def(Object *obj, Function *func, SlottedFunctionDef &def);
+  
+  void write_prototype_for_name(ostream &out, Function *func, const std::string &name);
+  void write_prototype_for(ostream &out, Function *func);
+  void write_function_for_name(ostream &out, Object *obj, Function *func, const std::string &name, const std::string &PreProcess, const std::string &ClassName);
+  void write_function_for_top(ostream &out, Object *obj, Function *func, const std::string &PreProcess);
+  void write_function_instance(ostream &out, Object *obj, Function *func,
+                               FunctionRemap *remap, string &expected_params, 
+                               int indent_level, bool errors_fatal, 
+                               ostream &forwarddecl, const std::string &functionnamestr,
+                               bool is_inplace, bool coercion_possible);
+  
+  void write_function_forset(ostream &out, Object *obj, Function *func,
+                             std::set< FunctionRemap *> &remaps, string &expected_params, int indent_level , ostream &forwarddecl,const std::string &functionname, bool inplace) ;
+  
+  void pack_return_value(ostream &out, int indent_level,
+                         FunctionRemap *remap, std::string return_expr ,  ostream &forwarddecl, 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_ClasseDeclarations(ostream &out ,  ostream *out_h,Object * obj);
+  void write_ClasseDetails(ostream &out, Object * obj);
+  
+  void do_assert_init(ostream &out, int indent_level, bool constructor) const;
 public:
-    bool isRemapLegal( FunctionRemap &remap);
-    bool isFunctionLegal( Function *func);
-    bool isCppTypeLegal(CPPType *ctype);
-    bool isExportThisRun(CPPType *ctype);
-    bool isExportThisRun(Function *func);
-    bool isFunctionWithThis( Function *func);
-    bool IsRunTimeTyped(const InterrogateType &itype);
-
-    // comunicates the cast capabilites among methods..
-    struct CastDetails
-    {
-        CPPStructType   *_structType;
-        std::string     _to_class_name;
-        std::string     _up_cast_string;
-        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);
-    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);
-    bool HasAGetKeyFunction(const InterrogateType &itype_class);
-    bool HasAGetClassTypeFunction(const InterrogateType &itype_class);
-    int NeedsAStrFunction(const InterrogateType &itype_class);
-    int NeedsAReprFunction(const InterrogateType &itype_class);
-
-    void output_quoted(ostream &out, int indent_level, const std::string &str);
-
-    // stash the forwad declarations for this compile pass..
-    std::set< std::string >     _external_imports;    
-
+  bool isRemapLegal( FunctionRemap &remap);
+  bool isFunctionLegal( Function *func);
+  bool isCppTypeLegal(CPPType *ctype);
+  bool isExportThisRun(CPPType *ctype);
+  bool isExportThisRun(Function *func);
+  bool isFunctionWithThis( Function *func);
+  bool IsRunTimeTyped(const InterrogateType &itype);
+  
+  // comunicates the cast capabilites among methods..
+  struct CastDetails {
+    CPPStructType   *_structType;
+    std::string     _to_class_name;
+    std::string     _up_cast_string;
+    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);
+  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);
+  bool HasAGetKeyFunction(const InterrogateType &itype_class);
+  bool HasAGetClassTypeFunction(const InterrogateType &itype_class);
+  int NeedsAStrFunction(const InterrogateType &itype_class);
+  int NeedsAReprFunction(const InterrogateType &itype_class);
+  
+  void output_quoted(ostream &out, int indent_level, const std::string &str);
+  
+  // stash the forwad declarations for this compile pass..
+  std::set< std::string >     _external_imports;    
 };
 
 #endif

+ 18 - 0
dtool/src/interrogate/typeManager.cxx

@@ -375,6 +375,24 @@ is_const_ref_to_simple(CPPType *type) {
   }
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: TypeManager::is_ref_to_simple
+//       Access: Public, Static
+//  Description: Returns true if the indicated type is a non-const
+//               reference to something that a scripting language can
+//               handle directly as a concrete.
+////////////////////////////////////////////////////////////////////
+bool TypeManager::
+is_ref_to_simple(CPPType *type) {
+  switch (type->get_subtype()) {
+  case CPPDeclaration::ST_reference:
+    return is_simple(type->as_reference_type()->_pointing_at);
+
+  default:
+    return false;
+  }
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: TypeManager::is_pointable
 //       Access: Public, Static

+ 1 - 0
dtool/src/interrogate/typeManager.h

@@ -60,6 +60,7 @@ public:
   static bool is_simple(CPPType *type);
   static bool is_const_simple(CPPType *type);
   static bool is_const_ref_to_simple(CPPType *type);
+  static bool is_ref_to_simple(CPPType *type);
   static bool is_pointable(CPPType *type);
   static bool is_char(CPPType *type);
   static bool is_char_pointer(CPPType *type);

+ 129 - 1
dtool/src/interrogatedb/py_panda.cxx

@@ -56,9 +56,91 @@ void DTOOL_Call_ExtractThisPointerForType(PyObject *self, Dtool_PyTypedObject *
         answer = NULL;
 };
 
+////////////////////////////////////////////////////////////////////
+//     Function: attempt_coercion
+//  Description: A helper function for DTOOL_Call_GetPointerThisClass,
+//               below.  This attempts to coerce the given object to
+//               the indicated Panda object, by creating a temporary
+//               instance of the required Panda object.  If
+//               successful, returns the "this" pointer of the
+//               temporary object; otherwise, returns NULL.
+////////////////////////////////////////////////////////////////////
+static void *
+attempt_coercion(PyObject *self, Dtool_PyTypedObject *classdef,
+                 PyObject **coerced) {
+  // The supplied parameter is not the required type.
+  if (coerced != NULL) {
+    // Attempt coercion: try to create a temporary instance of the
+    // required class using the supplied parameter.
+    PyObject *obj = PyObject_Call((PyObject *)classdef, self, NULL);
+    if (obj != NULL) {
+      // Well, whaddaya know?  The supplied parameter(s) suited
+      // the object's constructor.  Now we have a temporary object
+      // that we can pass to the function.
+      Dtool_PyTypedObject *my_type = ((Dtool_PyInstDef *)obj)->_My_Type;
+      void *result = my_type->_Dtool_UpcastInterface(obj, classdef);
+      if (result != NULL) {
+        // Successfully coerced.  Store the newly-allocated
+        // pointer, so the caller can release the coerced object
+        // at his leisure.  We store it in a list, so that other
+        // parameters can accumulate there too.
+        if ((*coerced) == NULL) {
+          (*coerced) = PyList_New(0);
+        }
+        PyList_Append(*coerced, obj);
+        return result;
+      }
+      // Some problem getting the C++ pointer from our created
+      // temporary object.  Weird.
+      Py_DECREF(obj);
+    }
+  }
+  return NULL;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DTOOL_Call_GetPointerThisClass
+//  Description: Extracts the C++ pointer for an object, given its
+//               Python wrapper object, for passing as the parameter
+//               to a C++ function.
+//
+//               self is the Python wrapper object in question.
+//
+//               classdef is the Python class wrapper for the C++
+//               class in which the this pointer should be returned.
+//               (This may require an upcast operation, if self is not
+//               already an instance of classdef.)
+//
+//               param and function_name are used for error reporting
+//               only, and describe the particular function and
+//               parameter index for this parameter.
+//
+//               const_ok is true if the function is declared const
+//               and can therefore be called with either a const or
+//               non-const "this" pointer, or false if the function is
+//               declared non-const, and can therefore be called with
+//               only a non-const "this" pointer.
+//
+//               If coerced is non-NULL, parameter coercion will be
+//               attempted.  This means the supplied parameter may not
+//               exactly match the required type, but will satisfy the
+//               require type's constructor; and we will create
+//               temporary object(s) of the required type instead.  In
+//               this case, coerced is a pointer to a PyList that will
+//               be filled with these temporary objects.  If coerced
+//               is a pointer to a NULL PyObject, a new PyList will be
+//               created on the first successful coercion.  If coerced
+//               itself is NULL, parameter coercion will not be
+//               attempted.
+//
+//               The return value is the C++ pointer that was
+//               extracted, or NULL if there was a problem (in which
+//               case the Python exception state will have been set).
+////////////////////////////////////////////////////////////////////
 void *
 DTOOL_Call_GetPointerThisClass(PyObject *self, Dtool_PyTypedObject *classdef,
-                               int param, const string &function_name, bool const_ok) {
+                               int param, const string &function_name, bool const_ok,
+                               PyObject **coerced) {
   if (self != NULL) {
     if (DtoolCanThisBeAPandaInstance(self)) {
       Dtool_PyTypedObject *my_type = ((Dtool_PyInstDef *)self)->_My_Type;
@@ -99,6 +181,14 @@ DTOOL_Call_GetPointerThisClass(PyObject *self, Dtool_PyTypedObject *classdef,
       }
 
     } else {
+      // The parameter was not a Panda type.  Can we coerce it to the
+      // appropriate type, by creating a temporary object?
+      void *result = attempt_coercion(self, classdef, coerced);
+      if (result != NULL) {
+        return result;
+      }
+
+      // Coercion failed.
       ostringstream str;
       str << function_name << "() argument " << param << " must be ";
 
@@ -561,4 +651,42 @@ int DTOOL_PyObject_Compare(PyObject *v1, PyObject *v2)
     return 0;   
 }
 
+
+PyObject *make_list_for_item(PyObject *self, const char *num_name,
+                             const char *element_name) {
+  PyObject *num_result = PyObject_CallMethod(self, (char *)num_name, "()");
+  if (num_result == NULL) {
+    return NULL;
+  }
+  Py_ssize_t num_elements = PyInt_AsSsize_t(num_result);
+  Py_DECREF(num_result);
+  
+  PyObject *list = PyList_New(num_elements);
+  for (int i = 0; i < num_elements; ++i) {
+    PyObject *element = PyObject_CallMethod(self, (char *)element_name, "(i)", i);
+    if (element == NULL) {
+      Py_DECREF(list);
+      return NULL;
+    }
+    PyList_SetItem(list, i, element);
+  }
+  return list;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PyLongOrInt_FromUnsignedLong
+//  Description: Similar to PyLong_FromUnsignedLong(), but returns
+//               either a regular integer or a long integer, according
+//               to whether the indicated value will fit.
+////////////////////////////////////////////////////////////////////
+EXPCL_DTOOLCONFIG PyObject *
+PyLongOrInt_FromUnsignedLong(unsigned long value) {
+  if ((long)value < 0) {
+    return PyLong_FromUnsignedLong(value);
+  } else {
+    return PyInt_FromLong((long)value);
+  }
+}
+
+
 #endif  // HAVE_PYTHON

+ 28 - 3
dtool/src/interrogatedb/py_panda.h

@@ -55,6 +55,15 @@
 #undef HAVE_LONG_LONG
 #endif 
 
+#if PY_VERSION_HEX < 0x02050000
+
+// Prior to Python 2.5, we didn't have Py_ssize_t.
+typedef int Py_ssize_t;
+#define PyInt_FromSsize_t PyInt_FromLong
+#define PyInt_AsSsize_t PyInt_AsLong
+
+#endif  // PY_VERSION_HEX
+
 using namespace std;
 
 #define PY_PANDA_SMALLER_FOOTPRINT  1
@@ -189,6 +198,16 @@ static  PyNumberMethods     Dtool_PyNumberMethods_##CLASS_NAME ={\
         0,/*binaryfunc nb_inplace_floor_divide*/\
         0,/*binaryfunc nb_inplace_true_divide*/\
     };\
+static  PySequenceMethods    Dtool_PySequenceMethods_##CLASS_NAME ={\
+        0,/*lenfunc sq_length */\
+        0,/*binaryfunc sq_concat */\
+        0,/*ssizeargfunc sq_repeat */\
+        0,/*ssizeargfunc sq_item */\
+        0,/*ssizeargfunc sq_ass_item */\
+        0,/*objobjproc sq_contains */\
+        0,/*binaryfunc sq_inplace_concat */\
+        0,/*ssizeargfunc sq_inplace_repeat */\
+};\
 static  PyMappingMethods    Dtool_PyMappingMethods_##CLASS_NAME ={\
         0,/*inquiry mp_length */\
         0,/*binaryfunc mp_subscript */\
@@ -207,8 +226,8 @@ EXPORT_THIS Dtool_PyTypedObject Dtool_##CLASS_NAME =  {\
     0,              /*tp_setattr*/\
     0,              /*tp_compare*/\
     0,              /*tp_repr*/\
-    &Dtool_PyNumberMethods_##CLASS_NAME,              /*tp_as_number*/\
-    0,              /*tp_as_sequence*/\
+    &Dtool_PyNumberMethods_##CLASS_NAME,               /*tp_as_number*/\
+    &Dtool_PySequenceMethods_##CLASS_NAME,             /*tp_as_sequence*/\
     &Dtool_PyMappingMethods_##CLASS_NAME,              /*tp_as_mapping*/\
     0,     /*tp_hash */\
         0,                                      /* tp_call */\
@@ -326,7 +345,7 @@ EXPCL_DTOOLCONFIG bool DtoolCanThisBeAPandaInstance(PyObject *self);
 EXPCL_DTOOLCONFIG void DTOOL_Call_ExtractThisPointerForType(PyObject *self, Dtool_PyTypedObject * classdef, void ** answer);
 
 
-EXPCL_DTOOLCONFIG void * DTOOL_Call_GetPointerThisClass(PyObject *self, Dtool_PyTypedObject  *classdef, int param, const string &function_name, bool const_ok);
+EXPCL_DTOOLCONFIG void * DTOOL_Call_GetPointerThisClass(PyObject *self, Dtool_PyTypedObject  *classdef, int param, const string &function_name, bool const_ok, PyObject **coerced);
 
 EXPCL_DTOOLCONFIG void * DTOOL_Call_GetPointerThis(PyObject *self);
 
@@ -495,6 +514,12 @@ EXPCL_DTOOLCONFIG int DTOOL_PyObject_Compare_old(PyObject *v1, PyObject *v2);
 
 EXPCL_DTOOLCONFIG int DTOOL_PyObject_Compare(PyObject *v1, PyObject *v2);
 
+EXPCL_DTOOLCONFIG PyObject *
+make_list_for_item(PyObject *self, const char *num_name,
+                   const char *element_name);
+EXPCL_DTOOLCONFIG PyObject *
+PyLongOrInt_FromUnsignedLong(unsigned long value);
+
 EXPCL_DTOOLCONFIG extern struct   Dtool_PyTypedObject Dtool_DTOOL_SUPPER_BASE;
 
 #endif  // HAVE_PYTHON

+ 13 - 0
dtool/src/pystub/pystub.cxx

@@ -54,6 +54,7 @@ extern "C" {
   EXPCL_DTOOLCONFIG int PyList_Append(...);
   EXPCL_DTOOLCONFIG int PyList_AsTuple(...);
   EXPCL_DTOOLCONFIG int PyList_New(...);
+  EXPCL_DTOOLCONFIG int PyList_SetItem(...);
   EXPCL_DTOOLCONFIG int PyLong_AsLong(...);
   EXPCL_DTOOLCONFIG int PyLong_AsLongLong(...);
   EXPCL_DTOOLCONFIG int PyLong_AsUnsignedLong(...);
@@ -68,6 +69,7 @@ extern "C" {
   EXPCL_DTOOLCONFIG int PyModule_AddObject(...);
   EXPCL_DTOOLCONFIG int PyNumber_Long(...);
   EXPCL_DTOOLCONFIG int PyObject_Call(...);
+  EXPCL_DTOOLCONFIG int PyObject_CallMethod(...);
   EXPCL_DTOOLCONFIG int PyObject_CallMethodObjArgs(...);
   EXPCL_DTOOLCONFIG int PyObject_CallObject(...);
   EXPCL_DTOOLCONFIG int PyObject_Cmp(...);
@@ -120,8 +122,11 @@ extern "C" {
   EXPCL_DTOOLCONFIG int _Py_NegativeRefcount(...);
   EXPCL_DTOOLCONFIG int _Py_RefTotal(...);
 
+  EXPCL_DTOOLCONFIG int Py_IsInitialized();
+
   EXPCL_DTOOLCONFIG extern void *PyExc_AssertionError;
   EXPCL_DTOOLCONFIG extern void *PyExc_AttributeError;
+  EXPCL_DTOOLCONFIG extern void *PyExc_IndexError;
   EXPCL_DTOOLCONFIG extern void *PyExc_RuntimeError;
   EXPCL_DTOOLCONFIG extern void *PyExc_StopIteration;
   EXPCL_DTOOLCONFIG extern void *PyExc_TypeError;
@@ -170,6 +175,7 @@ int PyInt_Type(...) { return 0; }
 int PyList_Append(...) { return 0; }
 int PyList_AsTuple(...) { return 0; }
 int PyList_New(...) { return 0; }
+int PyList_SetItem(...) { return 0; }
 int PyLong_AsLong(...) { return 0; }
 int PyLong_AsLongLong(...) { return 0; }
 int PyLong_AsUnsignedLong(...) { return 0; }
@@ -184,6 +190,7 @@ int PyModule_AddIntConstant(...) { return 0; };
 int PyModule_AddObject(...) { return 0; };
 int PyNumber_Long(...) { return 0; }
 int PyObject_Call(...) { return 0; }
+int PyObject_CallMethod(...) { return 0; }
 int PyObject_CallMethodObjArgs(...) { return 0; }
 int PyObject_CallObject(...) { return 0; }
 int PyObject_Cmp(...) { return 0; }
@@ -236,9 +243,15 @@ int _Py_Dealloc(...) { return 0; };
 int _Py_NegativeRefcount(...) { return 0; };
 int _Py_RefTotal(...) { return 0; };
 
+// We actually might call this one.
+int Py_IsInitialized() {
+  return 0;
+}
+
 
 void *PyExc_AssertionError = (void *)NULL;
 void *PyExc_AttributeError = (void *)NULL;
+void *PyExc_IndexError = (void *)NULL;
 void *PyExc_RuntimeError = (void *)NULL;
 void *PyExc_StopIteration = (void *)NULL;
 void *PyExc_TypeError = (void *)NULL;

+ 3 - 0
panda/src/chan/animControlCollection.h

@@ -46,6 +46,9 @@ PUBLISHED:
   int get_num_anims() const;
   AnimControl *get_anim(int n) const;
   string get_anim_name(int n) const;
+  MAKE_SEQ(get_anims, get_num_anims, get_anim);
+  MAKE_SEQ(get_anim_names, get_num_anims, get_anim_name);
+
   void clear_anims();
 
   // The following functions are convenience functions that vector

+ 2 - 0
panda/src/chan/animGroup.h

@@ -45,6 +45,8 @@ PUBLISHED:
 
   int get_num_children() const;
   AnimGroup *get_child(int n) const;
+  MAKE_SEQ(get_children, get_num_children, get_child);
+
   AnimGroup *find_child(const string &name) const;
 
 public:

+ 1 - 0
panda/src/chan/partBundle.h

@@ -116,6 +116,7 @@ PUBLISHED:
 
   INLINE int get_num_nodes() const;
   INLINE PartBundleNode *get_node(int n) const;
+  MAKE_SEQ(get_nodes, get_num_nodes, get_node);
 
   void clear_control_effects();
   INLINE void set_control_effect(AnimControl *control, float effect);

+ 2 - 0
panda/src/chan/partGroup.h

@@ -72,6 +72,8 @@ PUBLISHED:
 
   int get_num_children() const;
   PartGroup *get_child(int n) const;
+  MAKE_SEQ(get_children, get_num_children, get_child);
+
   PartGroup *find_child(const string &name) const;
 
   virtual bool apply_freeze(const TransformState *transform);

+ 5 - 5
panda/src/collide/collisionFloorMesh.I

@@ -61,6 +61,11 @@ get_num_vertices() const {
   return _vertices.size();
 }
 
+INLINE const LPoint3f CollisionFloorMesh::
+get_vertex(unsigned int index) const {
+  return _vertices[index];
+}
+
 INLINE const unsigned int  CollisionFloorMesh::
 get_num_triangles() const {
   return _triangles.size();
@@ -72,8 +77,3 @@ get_triangle(unsigned int index) const {
   return LPoint3d(tri.p1, tri.p2, tri.p3);
 }
 
-
-INLINE const LPoint3f CollisionFloorMesh::
-get_vertex(unsigned int index) const {
-  return _vertices[index];
-}

+ 4 - 2
panda/src/collide/collisionFloorMesh.h

@@ -51,10 +51,12 @@ PUBLISHED:
   void add_triangle(unsigned int pointA, unsigned int pointB, unsigned int pointC);
 
   INLINE const unsigned int get_num_vertices() const;
+  INLINE const LPoint3f get_vertex(unsigned int index) const;
+  MAKE_SEQ(get_vertices, get_num_vertices, get_vertex);
   INLINE const unsigned int get_num_triangles() const;
   INLINE const LPoint3d get_triangle(unsigned int index) const;
-  INLINE const LPoint3f get_vertex(unsigned int index) const;
-  
+  MAKE_SEQ(get_triangles, get_num_triangles, get_triangle);
+
   virtual LPoint3f get_collision_origin() const;
 
 public:

+ 3 - 0
panda/src/collide/collisionHandlerEvent.h

@@ -48,18 +48,21 @@ PUBLISHED:
   INLINE void set_in_pattern(const string &in_pattern);
   INLINE int get_num_in_patterns() const;
   INLINE string get_in_pattern(int n) const;
+  MAKE_SEQ(get_in_patterns, get_num_in_patterns, get_in_pattern);
 
   INLINE void clear_again_patterns();
   INLINE void add_again_pattern(const string &again_pattern);
   INLINE void set_again_pattern(const string &again_pattern);
   INLINE int get_num_again_patterns() const;
   INLINE string get_again_pattern(int n) const;
+  MAKE_SEQ(get_again_patterns, get_num_again_patterns, get_again_pattern);
 
   INLINE void clear_out_patterns();
   INLINE void add_out_pattern(const string &out_pattern);
   INLINE void set_out_pattern(const string &out_pattern);
   INLINE int get_num_out_patterns() const;
   INLINE string get_out_pattern(int n) const;
+  MAKE_SEQ(get_out_patterns, get_num_out_patterns, get_out_pattern);
 
   void clear();
   void flush();

+ 1 - 0
panda/src/collide/collisionHandlerQueue.h

@@ -43,6 +43,7 @@ PUBLISHED:
 
   int get_num_entries() const;
   CollisionEntry *get_entry(int n) const;
+  MAKE_SEQ(get_entries, get_num_entries, get_entry);
 
   void output(ostream &out) const;
   void write(ostream &out, int indent_level = 0) const;

+ 1 - 0
panda/src/collide/collisionNode.h

@@ -60,6 +60,7 @@ PUBLISHED:
   INLINE void clear_solids();
   INLINE int get_num_solids() const;
   INLINE CPT(CollisionSolid) get_solid(int n) const;
+  MAKE_SEQ(get_solids, get_num_solids, get_solid);
   INLINE PT(CollisionSolid) modify_solid(int n);
   INLINE void set_solid(int n, CollisionSolid *solid);
   INLINE void remove_solid(int n);

+ 1 - 0
panda/src/collide/collisionPolygon.h

@@ -50,6 +50,7 @@ PUBLISHED:
 
   INLINE int get_num_points() const;
   INLINE LPoint3f get_point(int n) const;
+  MAKE_SEQ(get_points, get_num_points, get_point);
 
   INLINE static bool verify_points(const LPoint3f &a, const LPoint3f &b,
                                    const LPoint3f &c);

+ 1 - 0
panda/src/collide/collisionTraverser.h

@@ -59,6 +59,7 @@ PUBLISHED:
   bool has_collider(const NodePath &collider) const;
   int get_num_colliders() const;
   NodePath get_collider(int n) const;
+  MAKE_SEQ(get_colliders, get_num_colliders, get_collider);
   CollisionHandler *get_handler(const NodePath &collider) const;
   void clear_colliders();
 

+ 1 - 0
panda/src/display/graphicsEngine.h

@@ -93,6 +93,7 @@ PUBLISHED:
   bool is_empty() const;
   int get_num_windows() const;
   GraphicsOutput *get_window(int n) const;
+  MAKE_SEQ(get_windows, get_num_windows, get_window);
 
   BLOCKING void render_frame();
   BLOCKING void open_windows();

+ 2 - 0
panda/src/display/graphicsOutput.h

@@ -148,9 +148,11 @@ PUBLISHED:
 
   int get_num_display_regions() const;
   PT(DisplayRegion) get_display_region(int n) const;
+  MAKE_SEQ(get_display_regions, get_num_display_regions, get_display_region);
 
   int get_num_active_display_regions() const;
   PT(DisplayRegion) get_active_display_region(int n) const;
+  MAKE_SEQ(get_active_display_regions, get_num_active_display_regions, get_active_display_region);
 
   GraphicsOutput *make_texture_buffer(
       const string &name, int x_size, int y_size,

+ 1 - 0
panda/src/display/graphicsPipeSelection.h

@@ -41,6 +41,7 @@ protected:
 PUBLISHED:
   int get_num_pipe_types() const;
   TypeHandle get_pipe_type(int n) const;
+  MAKE_SEQ(get_pipe_types, get_num_pipe_types, get_pipe_type);
   void print_pipe_types() const;
 
   PT(GraphicsPipe) make_pipe(const string &type_name,

+ 1 - 0
panda/src/display/graphicsWindow.h

@@ -65,6 +65,7 @@ PUBLISHED:
   // Mouse and keyboard routines
   int get_num_input_devices() const;
   string get_input_device_name(int device) const;
+  MAKE_SEQ(get_input_device_names, get_num_input_devices, get_input_device_name);
   bool has_pointer(int device) const;
   bool has_keyboard(int device) const;
   

+ 4 - 0
panda/src/distort/nonlinearImager.h

@@ -101,7 +101,10 @@ PUBLISHED:
 
   int get_num_screens() const;
   NodePath get_screen(int index) const;
+  MAKE_SEQ(get_screens, get_num_screens, get_screen);
   GraphicsOutput *get_buffer(int index) const;
+  MAKE_SEQ(get_buffers, get_num_screens, get_buffer);
+
   void set_texture_size(int index, int width, int height);
   void set_source_camera(int index, const NodePath &source_camera);
 
@@ -119,6 +122,7 @@ PUBLISHED:
 
   int get_num_viewers() const;
   DisplayRegion *get_viewer(int index) const;
+  MAKE_SEQ(get_viewers, get_num_viewers, get_viewer);
 
   NodePath get_dark_room() const;
   GraphicsEngine *get_graphics_engine() const;

+ 6 - 6
panda/src/downloader/httpChannel.I

@@ -162,29 +162,29 @@ get_redirect() const {
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: HTTPChannel::get_num_redirect_trail
+//     Function: HTTPChannel::get_num_redirect_steps
 //       Access: Published
 //  Description: If the document automatically followed one or more
 //               redirects, this will return the number of redirects
 //               that were automatically followed.  Use
-//               get_redirect_trail() to retrieve each URL in
+//               get_redirect_step() to retrieve each URL in
 //               sequence.
 ////////////////////////////////////////////////////////////////////
 INLINE int HTTPChannel::
-get_num_redirect_trail() const {
+get_num_redirect_steps() const {
   return _redirect_trail.size();
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: HTTPChannel::get_redirect_trail
+//     Function: HTTPChannel::get_redirect_step
 //       Access: Published
-//  Description: Use in conjunction with get_num_redirect_trail() to
+//  Description: Use in conjunction with get_num_redirect_steps() to
 //               extract the chain of URL's that the channel was
 //               automatically redirected through to arrive at the
 //               final document.
 ////////////////////////////////////////////////////////////////////
 INLINE const URLSpec &HTTPChannel::
-get_redirect_trail(int n) const {
+get_redirect_step(int n) const {
   nassertr(n >= 0 && n < (int)_redirect_trail.size(), _redirect_trail[0]);
   return _redirect_trail[n];
 }

+ 3 - 2
panda/src/downloader/httpChannel.h

@@ -111,8 +111,9 @@ PUBLISHED:
   INLINE const URLSpec &get_redirect() const;
   string get_header_value(const string &key) const;
 
-  INLINE int get_num_redirect_trail() const;
-  INLINE const URLSpec &get_redirect_trail(int n) const;
+  INLINE int get_num_redirect_steps() const;
+  INLINE const URLSpec &get_redirect_step(int n) const;
+  MAKE_SEQ(get_redirect_steps, get_num_redirect_steps, get_redirect_step);
 
   INLINE void set_persistent_connection(bool persistent_connection);
   INLINE bool get_persistent_connection() const;

+ 1 - 0
panda/src/egg/eggCompositePrimitive.h

@@ -38,6 +38,7 @@ PUBLISHED:
   INLINE int get_num_components() const;
   INLINE const EggAttributes *get_component(int i) const;
   INLINE EggAttributes *get_component(int i);
+  MAKE_SEQ(get_components, get_num_components, get_component);
   INLINE void set_component(int i, const EggAttributes *attrib);
 
   INLINE bool triangulate_into(EggGroupNode *container) const;

+ 2 - 0
panda/src/egg/eggGroup.h

@@ -195,6 +195,7 @@ PUBLISHED:
   INLINE void clear_object_types();
   INLINE int get_num_object_types() const;
   INLINE string get_object_type(int index) const;
+  MAKE_SEQ(get_object_types, get_num_object_types, get_object_type);
   bool has_object_type(const string &object_type) const;
   bool remove_object_type(const string &object_type);
 
@@ -288,6 +289,7 @@ PUBLISHED:
   void add_group_ref(EggGroup *group);
   int get_num_group_refs() const;
   EggGroup *get_group_ref(int n) const;
+  MAKE_SEQ(get_group_refs, get_num_group_refs, get_group_ref);
   void remove_group_ref(int n);
   void clear_group_refs();
 

+ 1 - 0
panda/src/egg/eggNurbsCurve.h

@@ -48,6 +48,7 @@ PUBLISHED:
   bool is_closed() const;
 
   INLINE double get_knot(int k) const;
+  MAKE_SEQ(get_knots, get_num_knots, get_knot);
 
   virtual void write(ostream &out, int indent_level) const;
 

+ 2 - 0
panda/src/egg/eggNurbsSurface.h

@@ -70,7 +70,9 @@ PUBLISHED:
   bool is_closed_v() const;
 
   INLINE double get_u_knot(int k) const;
+  MAKE_SEQ(get_u_knots, get_num_u_knots, get_u_knot);
   INLINE double get_v_knot(int k) const;
+  MAKE_SEQ(get_v_knots, get_num_v_knots, get_v_knot);
   INLINE EggVertex *get_cv(int ui, int vi) const;
 
   virtual void write(ostream &out, int indent_level) const;

+ 2 - 0
panda/src/egg/eggPrimitive.h

@@ -98,6 +98,7 @@ PUBLISHED:
   INLINE void clear_texture();
   INLINE int get_num_textures() const;
   INLINE EggTexture *get_texture(int n) const;
+  MAKE_SEQ(get_textures, get_num_textures, get_texture);
 
   INLINE void set_material(EggMaterial *material);
   INLINE void clear_material();
@@ -174,6 +175,7 @@ PUBLISHED:
   INLINE int get_num_vertices() const;
   INLINE void set_vertex(int index, EggVertex *vertex);
   INLINE EggVertex *get_vertex(int index) const;
+  MAKE_SEQ(get_vertices, get_num_vertices, get_vertex);
 
   INLINE EggVertexPool *get_pool() const;
 

+ 1 - 0
panda/src/egg/eggTextureCollection.h

@@ -63,6 +63,7 @@ PUBLISHED:
   bool is_empty() const;
   int get_num_textures() const;
   EggTexture *get_texture(int index) const;
+  MAKE_SEQ(get_textures, get_num_textures, get_texture);
 
 public:
   EggGroupNode::iterator insert_textures(EggGroupNode *node);

+ 2 - 1
panda/src/egg/eggVertexPool.h

@@ -104,9 +104,10 @@ public:
   iterator begin() const;
   iterator end() const;
   bool empty() const;
-  size_type size() const;
 
 PUBLISHED:
+  size_type size() const;
+
   // add_vertex() adds a freshly-allocated vertex.  It is up to the
   // user to allocate the vertex.
   EggVertex *add_vertex(EggVertex *vertex, int index = -1);

+ 11 - 0
panda/src/event/asyncTaskCollection.cxx

@@ -270,6 +270,17 @@ operator [] (int index) const {
   return _tasks[index];
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: AsyncTaskCollection::size
+//       Access: Published
+//  Description: Returns the number of tasks in the collection.  This
+//               is the same thing as get_num_tasks().
+////////////////////////////////////////////////////////////////////
+int AsyncTaskCollection::
+size() const {
+  return _tasks.size();
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: AsyncTaskCollection::output
 //       Access: Published

+ 2 - 0
panda/src/event/asyncTaskCollection.h

@@ -46,8 +46,10 @@ PUBLISHED:
 
   int get_num_tasks() const;
   AsyncTask *get_task(int index) const;
+  MAKE_SEQ(get_tasks, get_num_tasks, get_task);
   void remove_task(int index);
   AsyncTask *operator [] (int index) const;
+  int size() const;
 
   void output(ostream &out) const;
   void write(ostream &out, int indent_level = 0) const;

+ 1 - 0
panda/src/event/asyncTaskManager.h

@@ -66,6 +66,7 @@ PUBLISHED:
 
   int get_num_task_chains() const;
   AsyncTaskChain *get_task_chain(int n) const;
+  MAKE_SEQ(get_task_chains, get_num_task_chains, get_task_chain);
   AsyncTaskChain *make_task_chain(const string &name);
   AsyncTaskChain *find_task_chain(const string &name);
   BLOCKING bool remove_task_chain(const string &name);

+ 1 - 0
panda/src/event/event.h

@@ -49,6 +49,7 @@ PUBLISHED:
 
   int get_num_parameters() const;
   EventParameter get_parameter(int n) const;
+  MAKE_SEQ(get_parameters, get_num_parameters, get_parameter);
 
   bool has_receiver() const;
   EventReceiver *get_receiver() const;

+ 3 - 0
panda/src/express/memoryUsagePointers.h

@@ -59,7 +59,10 @@ PUBLISHED:
 
   int get_num_pointers() const;
   ReferenceCount *get_pointer(int n) const;
+  MAKE_SEQ(get_pointers, get_num_pointers, get_pointer);
   TypedObject *get_typed_pointer(int n) const;
+  MAKE_SEQ(get_typed_pointers, get_num_pointers, get_typed_pointer);
+
   TypeHandle get_type(int n) const;
   string get_type_name(int n) const;
   double get_age(int n) const;

+ 1 - 0
panda/src/express/multifile.h

@@ -83,6 +83,7 @@ PUBLISHED:
                       const string &subfile_name) const;
   void remove_subfile(int index);
   const string &get_subfile_name(int index) const;
+  MAKE_SEQ(get_subfile_names, get_num_subfiles, get_subfile_name);
   size_t get_subfile_length(int index) const;
   time_t get_subfile_timestamp(int index) const;
   bool is_subfile_compressed(int index) const;

+ 13 - 0
panda/src/express/pointerToArray.I

@@ -458,6 +458,19 @@ set_element(size_type n, const Element &value) {
   (*this)[n] = value;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: PointerToArray::__setitem__
+//       Access: Published
+//  Description: Same as set_element(), this replaces the nth element
+//               of the array.
+////////////////////////////////////////////////////////////////////
+template<class Element>
+INLINE void PointerToArray<Element>::
+__setitem__(size_type n, const Element &value) {
+  nassertv(n < ((To *)(this->_void_ptr))->size());
+  (*this)[n] = value;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: PointerToArray::get_data
 //       Access: Published

+ 5 - 0
panda/src/express/pointerToArray.h

@@ -109,8 +109,12 @@ PUBLISHED:
   INLINE static PointerToArray<Element> empty_array(size_type n, TypeHandle type_handle = get_type_handle(Element));
   INLINE PointerToArray(const PointerToArray<Element> &copy);
   INLINE size_type size() const;
+  INLINE void push_back(const Element &x);
+  INLINE void pop_back();
   INLINE const Element &get_element(size_type n) const;
   INLINE void set_element(size_type n, const Element &value);
+  INLINE const Element &operator [](size_type n) const;
+  INLINE void __setitem__(size_type n, const Element &value);
   INLINE string get_data() const;
   INLINE void set_data(const string &data);
   INLINE string get_subdata(size_type n, size_type count) const;
@@ -189,6 +193,7 @@ public:
   // Methods to help out Python and other high-level languages.
   INLINE const Element &get_element(size_type n) const;
   INLINE void set_element(size_type n, const Element &value);
+  INLINE void __setitem__(size_type n, const Element &value);
   INLINE string get_data() const;
   INLINE void set_data(const string &data);
   INLINE string get_subdata(size_type n, size_type count) const;

+ 21 - 0
panda/src/express/virtualFileList.I

@@ -61,3 +61,24 @@ get_file(int n) const {
   nassertr(n >= 0 && n < (int)_files.size(), NULL);
   return _files[n];
 }
+
+////////////////////////////////////////////////////////////////////
+//     Function: VirtualFileList::operator []
+//       Access: Published
+//  Description: Returns the nth file in the list.
+////////////////////////////////////////////////////////////////////
+INLINE VirtualFile *VirtualFileList::
+operator [](int n) const {
+  nassertr(n >= 0 && n < (int)_files.size(), NULL);
+  return _files[n];
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: VirtualFileList::size
+//       Access: Published
+//  Description: Returns the number of files in the list.
+////////////////////////////////////////////////////////////////////
+INLINE int VirtualFileList::
+size() const {
+  return _files.size();
+}

+ 5 - 1
panda/src/express/virtualFileList.h

@@ -23,7 +23,7 @@
 ////////////////////////////////////////////////////////////////////
 //       Class : VirtualFileList
 // Description : A list of VirtualFiles, as returned by 
-//               VirtualDirectory::scan().
+//               VirtualFile::scan_directory().
 ////////////////////////////////////////////////////////////////////
 class EXPCL_PANDAEXPRESS VirtualFileList : public ReferenceCount {
 public:
@@ -38,6 +38,10 @@ public:
 PUBLISHED:
   INLINE int get_num_files() const;
   INLINE VirtualFile *get_file(int n) const;
+  MAKE_SEQ(get_files, get_num_files, get_file);
+
+  INLINE VirtualFile *operator [](int n) const;
+  INLINE int size() const;
 
 private:
   typedef pvector< PT(VirtualFile) > Files;

+ 1 - 0
panda/src/gobj/geom.h

@@ -89,6 +89,7 @@ PUBLISHED:
 
   INLINE int get_num_primitives() const;
   INLINE CPT(GeomPrimitive) get_primitive(int i) const;
+  MAKE_SEQ(get_primitives, get_num_primitives, get_primitive);
   INLINE PT(GeomPrimitive) modify_primitive(int i);
   void set_primitive(int i, const GeomPrimitive *primitive);
   void add_primitive(const GeomPrimitive *primitive);

+ 1 - 0
panda/src/gobj/geomPrimitive.h

@@ -98,6 +98,7 @@ PUBLISHED:
   INLINE int get_first_vertex() const;
   INLINE int get_num_vertices() const;
   INLINE int get_vertex(int i) const;
+  MAKE_SEQ(get_vertices, get_num_vertices, get_vertex);
   void add_vertex(int vertex);
   INLINE void add_vertices(int v1, int v2);
   INLINE void add_vertices(int v1, int v2, int v3);

+ 1 - 0
panda/src/gobj/geomVertexData.h

@@ -109,6 +109,7 @@ PUBLISHED:
 
   INLINE int get_num_arrays() const;
   INLINE CPT(GeomVertexArrayData) get_array(int i) const;
+  MAKE_SEQ(get_arrays, get_num_arrays, get_array);
   INLINE PT(GeomVertexArrayData) modify_array(int i);
   INLINE void set_array(int i, const GeomVertexArrayData *array);
 

+ 7 - 0
panda/src/gobj/geomVertexFormat.h

@@ -80,6 +80,7 @@ PUBLISHED:
 
   INLINE int get_num_arrays() const;
   INLINE const GeomVertexArrayFormat *get_array(int array) const;
+  MAKE_SEQ(get_arrays, get_num_arrays, get_array);
   GeomVertexArrayFormat *modify_array(int array);
   void set_array(int array, const GeomVertexArrayFormat *format);
   void remove_array(int array);
@@ -100,17 +101,23 @@ PUBLISHED:
 
   INLINE int get_num_points() const;
   INLINE const InternalName *get_point(int n) const;
+  MAKE_SEQ(get_points, get_num_points, get_point);
 
   INLINE int get_num_vectors() const;
   INLINE const InternalName *get_vector(int n) const;
+  MAKE_SEQ(get_vectors, get_num_vectors, get_vector);
 
   INLINE int get_num_texcoords() const;
   INLINE const InternalName *get_texcoord(int n) const;
+  MAKE_SEQ(get_texcoords, get_num_texcoords, get_texcoord);
 
   INLINE int get_num_morphs() const;
   INLINE const InternalName *get_morph_slider(int n) const;
   INLINE const InternalName *get_morph_base(int n) const;
   INLINE const InternalName *get_morph_delta(int n) const;
+  MAKE_SEQ(get_morph_sliders, get_num_morphs, get_morph_slider);
+  MAKE_SEQ(get_morph_bases, get_num_morphs, get_morph_base);
+  MAKE_SEQ(get_morph_deltas, get_num_morphs, get_morph_delta);
 
   void output(ostream &out) const;
   void write(ostream &out, int indent_level = 0) const;

+ 1 - 0
panda/src/gobj/sliderTable.h

@@ -51,6 +51,7 @@ PUBLISHED:
 
   INLINE int get_num_sliders() const;
   INLINE const VertexSlider *get_slider(int n) const;
+  MAKE_SEQ(get_sliders, get_num_sliders, get_slider);
   INLINE const SparseArray &get_slider_rows(int n) const;
 
   INLINE const SparseArray &find_sliders(const InternalName *name) const;

+ 1 - 0
panda/src/gobj/transformBlend.h

@@ -63,6 +63,7 @@ PUBLISHED:
 
   INLINE int get_num_transforms() const;
   INLINE const VertexTransform *get_transform(int n) const;
+  MAKE_SEQ(get_transforms, get_num_transforms, get_transform);
   INLINE float get_weight(int n) const;
   INLINE void set_transform(int n, const VertexTransform *transform);
   INLINE void set_weight(int n, float weight);

+ 1 - 0
panda/src/gobj/transformBlendTable.h

@@ -59,6 +59,7 @@ PUBLISHED:
 
   INLINE int get_num_blends() const;
   INLINE const TransformBlend &get_blend(int n) const;
+  MAKE_SEQ(get_blends, get_num_blends, get_blend);
   INLINE UpdateSeq get_modified(Thread *current_thread) const;
 
   void set_blend(int n, const TransformBlend &blend);

+ 1 - 0
panda/src/gobj/transformTable.h

@@ -51,6 +51,7 @@ PUBLISHED:
 
   INLINE int get_num_transforms() const;
   INLINE const VertexTransform *get_transform(int n) const;
+  MAKE_SEQ(get_transforms, get_num_transforms, get_transform);
   INLINE UpdateSeq get_modified(Thread *current_thread) const;
 
   void set_transform(int n, const VertexTransform *transform);

+ 2 - 1
panda/src/grutil/lineSegs.h

@@ -57,12 +57,13 @@ PUBLISHED:
 
   // Functions to move the line vertices after they have been created.
   INLINE int get_num_vertices() const;
-
   Vertexf get_vertex(int n) const;
+  MAKE_SEQ(get_vertices, get_num_vertices, get_vertex);
   void set_vertex(int n, const Vertexf &vert);
   INLINE void set_vertex(int vertex, float x, float y, float z);
 
   Colorf get_vertex_color(int vertex) const;
+  MAKE_SEQ(get_vertex_colors, get_num_vertices, get_vertex_color);
   void set_vertex_color(int vertex, const Colorf &c);
   INLINE void set_vertex_color(int vertex, float r, float g, float b, float a = 1.0f);
 

+ 117 - 0
panda/src/linmath/lmatrix3_src.I

@@ -12,6 +12,91 @@
 //
 ////////////////////////////////////////////////////////////////////
 
+
+////////////////////////////////////////////////////////////////////
+//     Function: LMatrix3::Row::Constructor
+//       Access: Private
+//  Description: Defines a row-level index accessor to the matrix.
+////////////////////////////////////////////////////////////////////
+INLINE_LINMATH FLOATNAME(LMatrix3)::Row::
+Row(FLOATTYPE *row) : _row(row) {
+}
+    
+////////////////////////////////////////////////////////////////////
+//     Function: LMatrix3::Row::operator []
+//       Access: Published
+//  Description: 
+////////////////////////////////////////////////////////////////////
+INLINE_LINMATH FLOATTYPE FLOATNAME(LMatrix3)::Row::
+operator [](int i) const {
+  nassertr(i >= 0 && i < 3, 0.0);
+  return _row[i];
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: LMatrix3::Row::operator []
+//       Access: Published
+//  Description: 
+////////////////////////////////////////////////////////////////////
+INLINE_LINMATH FLOATTYPE &FLOATNAME(LMatrix3)::Row::
+operator [](int i) {
+  nassertr(i >= 0 && i < 3, _row[0]);
+  return _row[i];
+}
+
+#ifdef HAVE_PYTHON
+////////////////////////////////////////////////////////////////////
+//     Function: LMatrix3::Row::__setitem__
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+INLINE_LINMATH void FLOATNAME(LMatrix3)::Row::
+__setitem__(int i, FLOATTYPE v) {
+  nassertv(i >= 0 && i < 3);
+  _row[i] = v;
+}
+#endif  // HAVE_PYTHON
+
+////////////////////////////////////////////////////////////////////
+//     Function: LMatrix3::Row::size
+//       Access: Public, Static
+//  Description: Returns 3: the number of columns of a LMatrix3.
+////////////////////////////////////////////////////////////////////
+INLINE_LINMATH size_t FLOATNAME(LMatrix3)::Row::
+size() {
+  return 3;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: LMatrix3::CRow::Constructor
+//       Access: Private
+//  Description: Defines a row-level constant accessor to the matrix.
+////////////////////////////////////////////////////////////////////
+INLINE_LINMATH FLOATNAME(LMatrix3)::CRow::
+CRow(const FLOATTYPE *row) : _row(row) {
+}
+    
+////////////////////////////////////////////////////////////////////
+//     Function: LMatrix3::CRow::operator []
+//       Access: Published
+//  Description: 
+////////////////////////////////////////////////////////////////////
+INLINE_LINMATH FLOATTYPE FLOATNAME(LMatrix3)::CRow::
+operator [](int i) const {
+  nassertr(i >= 0 && i < 3, 0.0);
+  return _row[i];
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: LMatrix3::CRow::size
+//       Access: Public, Static
+//  Description: Returns 3: the number of columns of a LMatrix3.
+////////////////////////////////////////////////////////////////////
+INLINE_LINMATH size_t FLOATNAME(LMatrix3)::CRow::
+size() {
+  return 3;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: LMatrix3::ident_mat
 //       Access: Public, Static
@@ -235,6 +320,38 @@ operator () (int row, int col) const {
   return _m.data[row * 3 + col];
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: LMatrix3::Indexing Operator
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+INLINE_LINMATH FLOATNAME(LMatrix3)::CRow FLOATNAME(LMatrix3)::
+operator [](int i) const {
+  nassertr(i >= 0 && i < 3, CRow(&_m.data[0]));
+  return CRow(&_m.data[i * 3]);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: LMatrix3::Indexing Operator
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+INLINE_LINMATH FLOATNAME(LMatrix3)::Row FLOATNAME(LMatrix3)::
+operator [](int i) {
+  nassertr(i >= 0 && i < 3, Row(&_m.data[0]));
+  return Row(&_m.data[i * 3]);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: LMatrix3::size
+//       Access: Public, Static
+//  Description: Returns 3: the number of rows of a LMatrix3.
+////////////////////////////////////////////////////////////////////
+INLINE_LINMATH size_t FLOATNAME(LMatrix3)::
+size() {
+  return 3;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: LMatrix3::is_nan
 //       Access: Public

+ 34 - 0
panda/src/linmath/lmatrix3_src.h

@@ -28,6 +28,32 @@ public:
   typedef const FLOATTYPE *const_iterator;
 
 PUBLISHED:
+  // These helper classes are used to support two-level operator [].
+  class Row {
+  private:
+    INLINE_LINMATH Row(FLOATTYPE *row);
+  PUBLISHED:
+    INLINE_LINMATH FLOATTYPE operator [](int i) const;
+    INLINE_LINMATH FLOATTYPE &operator [](int i);
+#ifdef HAVE_PYTHON
+    INLINE_LINMATH void __setitem__(int i, FLOATTYPE v);
+#endif
+    INLINE_LINMATH static size_t size();
+  private:
+    FLOATTYPE *_row;
+    friend class FLOATNAME(LMatrix3);
+  };
+  class CRow {
+  private:
+    INLINE_LINMATH CRow(const FLOATTYPE *row);
+  PUBLISHED:
+    INLINE_LINMATH FLOATTYPE operator [](int i) const;
+    INLINE_LINMATH static size_t size();
+  private:
+    const FLOATTYPE *_row;
+    friend class FLOATNAME(LMatrix3);
+  };
+
   INLINE_LINMATH FLOATNAME(LMatrix3)();
   INLINE_LINMATH FLOATNAME(LMatrix3)(const FLOATNAME(LMatrix3) &other);
   INLINE_LINMATH FLOATNAME(LMatrix3) &operator = (
@@ -53,9 +79,13 @@ PUBLISHED:
 
   INLINE_LINMATH FLOATNAME(LVecBase3) get_row(int row) const;
   INLINE_LINMATH FLOATNAME(LVecBase3) get_col(int col) const;
+  MAKE_SEQ(get_rows, size, get_row);
+  MAKE_SEQ(get_cols, size, get_col);
 
   INLINE_LINMATH FLOATNAME(LVecBase2) get_row2(int row) const;
   INLINE_LINMATH FLOATNAME(LVecBase2) get_col2(int col) const;
+  MAKE_SEQ(get_col2s, size, get_col2);
+  MAKE_SEQ(get_row2s, size, get_row2);
 
   // these versions inline better
   INLINE_LINMATH void get_row(
@@ -64,6 +94,10 @@ PUBLISHED:
   INLINE_LINMATH FLOATTYPE &operator () (int row, int col);
   INLINE_LINMATH FLOATTYPE operator () (int row, int col) const;
 
+  INLINE_LINMATH CRow operator [](int i) const;
+  INLINE_LINMATH Row operator [](int i);
+  INLINE_LINMATH static size_t size();
+
   INLINE_LINMATH bool is_nan() const;
 
   INLINE_LINMATH FLOATTYPE get_cell(int row, int col) const;

+ 117 - 0
panda/src/linmath/lmatrix4_src.I

@@ -12,6 +12,91 @@
 //
 ////////////////////////////////////////////////////////////////////
 
+
+////////////////////////////////////////////////////////////////////
+//     Function: LMatrix4::Row::Constructor
+//       Access: Private
+//  Description: Defines a row-level index accessor to the matrix.
+////////////////////////////////////////////////////////////////////
+INLINE_LINMATH FLOATNAME(LMatrix4)::Row::
+Row(FLOATTYPE *row) : _row(row) {
+}
+    
+////////////////////////////////////////////////////////////////////
+//     Function: LMatrix4::Row::operator []
+//       Access: Published
+//  Description: 
+////////////////////////////////////////////////////////////////////
+INLINE_LINMATH FLOATTYPE FLOATNAME(LMatrix4)::Row::
+operator [](int i) const {
+  nassertr(i >= 0 && i < 4, 0.0);
+  return _row[i];
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: LMatrix4::Row::operator []
+//       Access: Published
+//  Description: 
+////////////////////////////////////////////////////////////////////
+INLINE_LINMATH FLOATTYPE &FLOATNAME(LMatrix4)::Row::
+operator [](int i) {
+  nassertr(i >= 0 && i < 4, _row[0]);
+  return _row[i];
+}
+
+#ifdef HAVE_PYTHON
+////////////////////////////////////////////////////////////////////
+//     Function: LMatrix4::Row::__setitem__
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+INLINE_LINMATH void FLOATNAME(LMatrix4)::Row::
+__setitem__(int i, FLOATTYPE v) {
+  nassertv(i >= 0 && i < 4);
+  _row[i] = v;
+}
+#endif  // HAVE_PYTHON
+
+////////////////////////////////////////////////////////////////////
+//     Function: LMatrix4::Row::size
+//       Access: Public, Static
+//  Description: Returns 4: the number of columns of a LMatrix4.
+////////////////////////////////////////////////////////////////////
+INLINE_LINMATH size_t FLOATNAME(LMatrix4)::Row::
+size() {
+  return 4;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: LMatrix4::CRow::Constructor
+//       Access: Private
+//  Description: Defines a row-level constant accessor to the matrix.
+////////////////////////////////////////////////////////////////////
+INLINE_LINMATH FLOATNAME(LMatrix4)::CRow::
+CRow(const FLOATTYPE *row) : _row(row) {
+}
+    
+////////////////////////////////////////////////////////////////////
+//     Function: LMatrix4::CRow::operator []
+//       Access: Published
+//  Description: 
+////////////////////////////////////////////////////////////////////
+INLINE_LINMATH FLOATTYPE FLOATNAME(LMatrix4)::CRow::
+operator [](int i) const {
+  nassertr(i >= 0 && i < 4, 0.0);
+  return _row[i];
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: LMatrix4::CRow::size
+//       Access: Public, Static
+//  Description: Returns 4: the number of columns of a LMatrix4.
+////////////////////////////////////////////////////////////////////
+INLINE_LINMATH size_t FLOATNAME(LMatrix4)::CRow::
+size() {
+  return 4;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: LMatrix4::ident_mat
 //       Access: Public, Static
@@ -413,6 +498,38 @@ operator () (int row, int col) const {
   return _m.data[row * 4 + col];
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: LMatrix4::Indexing Operator
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+INLINE_LINMATH FLOATNAME(LMatrix4)::CRow FLOATNAME(LMatrix4)::
+operator [](int i) const {
+  nassertr(i >= 0 && i < 4, CRow(&_m.data[0]));
+  return CRow(&_m.data[i * 4]);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: LMatrix4::Indexing Operator
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+INLINE_LINMATH FLOATNAME(LMatrix4)::Row FLOATNAME(LMatrix4)::
+operator [](int i) {
+  nassertr(i >= 0 && i < 4, Row(&_m.data[0]));
+  return Row(&_m.data[i * 4]);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: LMatrix4::size
+//       Access: Public, Static
+//  Description: Returns 4: the number of rows of a LMatrix4.
+////////////////////////////////////////////////////////////////////
+INLINE_LINMATH size_t FLOATNAME(LMatrix4)::
+size() {
+  return 4;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: LMatrix4::is_nan
 //       Access: Public

+ 33 - 1
panda/src/linmath/lmatrix4_src.h

@@ -23,6 +23,32 @@ public:
   typedef const FLOATTYPE *const_iterator;
 
 PUBLISHED:
+  // These helper classes are used to support two-level operator [].
+  class Row {
+  private:
+    INLINE_LINMATH Row(FLOATTYPE *row);
+  PUBLISHED:
+    INLINE_LINMATH FLOATTYPE operator [](int i) const;
+    INLINE_LINMATH FLOATTYPE &operator [](int i);
+#ifdef HAVE_PYTHON
+    INLINE_LINMATH void __setitem__(int i, FLOATTYPE v);
+#endif
+    INLINE_LINMATH static size_t size();
+  private:
+    FLOATTYPE *_row;
+    friend class FLOATNAME(LMatrix4);
+  };
+  class CRow {
+  private:
+    INLINE_LINMATH CRow(const FLOATTYPE *row);
+  PUBLISHED:
+    INLINE_LINMATH FLOATTYPE operator [](int i) const;
+    INLINE_LINMATH static size_t size();
+  private:
+    const FLOATTYPE *_row;
+    friend class FLOATNAME(LMatrix4);
+  };
+
   INLINE_LINMATH FLOATNAME(LMatrix4)();
   INLINE_LINMATH FLOATNAME(LMatrix4)(const FLOATNAME(LMatrix4) &other);
   INLINE_LINMATH FLOATNAME(LMatrix4) &operator = (const FLOATNAME(LMatrix4) &other);
@@ -57,8 +83,10 @@ PUBLISHED:
 
   INLINE_LINMATH FLOATNAME(LVecBase4) get_row(int row) const;
   INLINE_LINMATH FLOATNAME(LVecBase4) get_col(int col) const;
-
   INLINE_LINMATH FLOATNAME(LVecBase3) get_row3(int row) const;
+  MAKE_SEQ(get_rows, size, get_row);
+  MAKE_SEQ(get_cols, size, get_col);
+  MAKE_SEQ(get_row3s, size, get_row3);
 
   // these versions inline better
   INLINE_LINMATH void get_row(FLOATNAME(LVecBase4) &result_vec, int row) const;
@@ -69,6 +97,10 @@ PUBLISHED:
   INLINE_LINMATH FLOATTYPE &operator () (int row, int col);
   INLINE_LINMATH FLOATTYPE operator () (int row, int col) const;
 
+  INLINE_LINMATH CRow operator [](int i) const;
+  INLINE_LINMATH Row operator [](int i);
+  INLINE_LINMATH static size_t size();
+
   INLINE_LINMATH bool is_nan() const;
 
   INLINE_LINMATH FLOATTYPE get_cell(int row, int col) const;

+ 23 - 0
panda/src/linmath/lvecBase2_src.I

@@ -144,6 +144,29 @@ operator [](int i) {
   return _v.data[i];
 }
 
+#ifdef HAVE_PYTHON
+////////////////////////////////////////////////////////////////////
+//     Function: LVecBase2::__setitem__
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+INLINE_LINMATH void FLOATNAME(LVecBase2)::
+__setitem__(int i, FLOATTYPE v) {
+  nassertv(i >= 0 && i < 2);
+  _v.data[i] = v;
+}
+#endif  // HAVE_PYTHON
+
+////////////////////////////////////////////////////////////////////
+//     Function: LVecBase2::size
+//       Access: Public, Static
+//  Description: Returns 2: the number of components of a LVecBase2.
+////////////////////////////////////////////////////////////////////
+INLINE_LINMATH size_t FLOATNAME(LVecBase2)::
+size() {
+  return 2;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: LVecBase2::is_nan
 //       Access: Public

+ 4 - 0
panda/src/linmath/lvecBase2_src.h

@@ -41,6 +41,10 @@ PUBLISHED:
 
   INLINE_LINMATH FLOATTYPE operator [](int i) const;
   INLINE_LINMATH FLOATTYPE &operator [](int i);
+#ifdef HAVE_PYTHON
+  INLINE_LINMATH void __setitem__(int i, FLOATTYPE v);
+#endif
+  INLINE_LINMATH static size_t size();
 
   INLINE_LINMATH bool is_nan() const;
 

+ 23 - 0
panda/src/linmath/lvecBase3_src.I

@@ -156,6 +156,29 @@ operator [](int i) {
   return _v.data[i];
 }
 
+#ifdef HAVE_PYTHON
+////////////////////////////////////////////////////////////////////
+//     Function: LVecBase3::__setitem__
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+INLINE_LINMATH void FLOATNAME(LVecBase3)::
+__setitem__(int i, FLOATTYPE v) {
+  nassertv(i >= 0 && i < 3);
+  _v.data[i] = v;
+}
+#endif  // HAVE_PYTHON
+
+////////////////////////////////////////////////////////////////////
+//     Function: LVecBase3::size
+//       Access: Public, Static
+//  Description: Returns 3: the number of components of a LVecBase3.
+////////////////////////////////////////////////////////////////////
+INLINE_LINMATH size_t FLOATNAME(LVecBase3)::
+size() {
+  return 3;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: LVecBase3::is_nan
 //       Access: Public

+ 4 - 0
panda/src/linmath/lvecBase3_src.h

@@ -39,6 +39,10 @@ PUBLISHED:
 
   INLINE_LINMATH FLOATTYPE operator [](int i) const;
   INLINE_LINMATH FLOATTYPE &operator [](int i);
+#ifdef HAVE_PYTHON
+  INLINE_LINMATH void __setitem__(int i, FLOATTYPE v);
+#endif
+  INLINE_LINMATH static size_t size();
 
   INLINE_LINMATH bool is_nan() const;
 

+ 23 - 0
panda/src/linmath/lvecBase4_src.I

@@ -170,6 +170,29 @@ operator [](int i) {
   return _v.data[i];
 }
 
+#ifdef HAVE_PYTHON
+////////////////////////////////////////////////////////////////////
+//     Function: LVecBase4::__setitem__
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+INLINE_LINMATH void FLOATNAME(LVecBase4)::
+__setitem__(int i, FLOATTYPE v) {
+  nassertv(i >= 0 && i < 4);
+  _v.data[i] = v;
+}
+#endif  // HAVE_PYTHON
+
+////////////////////////////////////////////////////////////////////
+//     Function: LVecBase4::size
+//       Access: Public, Static
+//  Description: Returns 4: the number of components of a LVecBase4.
+////////////////////////////////////////////////////////////////////
+INLINE_LINMATH size_t FLOATNAME(LVecBase4)::
+size() {
+  return 4;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: LVecBase4::is_nan
 //       Access: Public

+ 4 - 0
panda/src/linmath/lvecBase4_src.h

@@ -40,6 +40,10 @@ PUBLISHED:
 
   INLINE_LINMATH FLOATTYPE operator [](int i) const;
   INLINE_LINMATH FLOATTYPE &operator [](int i);
+#ifdef HAVE_PYTHON
+  INLINE_LINMATH void __setitem__(int i, FLOATTYPE v);
+#endif
+  INLINE_LINMATH static size_t size();
 
   INLINE_LINMATH bool is_nan() const;
 

+ 2 - 0
panda/src/mathutil/boundingBox.h

@@ -49,8 +49,10 @@ public:
 PUBLISHED:
   INLINE_MATHUTIL int get_num_points() const;
   INLINE_MATHUTIL LPoint3f get_point(int n) const;
+  MAKE_SEQ(get_points, get_num_points, get_point);
   INLINE_MATHUTIL int get_num_planes() const;
   INLINE_MATHUTIL Planef get_plane(int n) const;
+  MAKE_SEQ(get_planes, get_num_planes, get_plane);
 
 public:
   // Inline accessors for speed.

+ 2 - 0
panda/src/mathutil/boundingHexahedron.h

@@ -61,8 +61,10 @@ public:
 PUBLISHED:
   INLINE_MATHUTIL int get_num_points() const;
   INLINE_MATHUTIL LPoint3f get_point(int n) const;
+  MAKE_SEQ(get_points, get_num_points, get_point);
   INLINE_MATHUTIL int get_num_planes() const;
   INLINE_MATHUTIL Planef get_plane(int n) const;
+  MAKE_SEQ(get_planes, get_num_planes, get_plane);
 
 public:
   virtual const BoundingHexahedron *as_bounding_hexahedron() const;

+ 1 - 0
panda/src/mathutil/triangulator.h

@@ -45,6 +45,7 @@ PUBLISHED:
 
   INLINE int get_num_vertices() const;
   INLINE const LPoint2d &get_vertex(int n) const;
+  MAKE_SEQ(get_vertices, get_num_vertices, get_vertex);
 
   void clear_polygon();
   void add_polygon_vertex(int index);

+ 1 - 0
panda/src/movies/microphoneAudio.h

@@ -31,6 +31,7 @@ class EXPCL_PANDA_MOVIES MicrophoneAudio : public MovieAudio {
 
   static int                 get_num_options();
   static PT(MicrophoneAudio) get_option(int n);
+  MAKE_SEQ(get_options, get_num_options, get_option);
   
   INLINE int get_channels() const;
   INLINE int get_rate() const;

+ 1 - 0
panda/src/movies/webcamVideo.h

@@ -29,6 +29,7 @@ PUBLISHED:
 
   static int             get_num_options();
   static PT(WebcamVideo) get_option(int n);
+  MAKE_SEQ(get_options, get_num_options, get_option);
   
   INLINE int get_size_x() const;
   INLINE int get_size_y() const;

+ 1 - 0
panda/src/ode/odeAMotorJoint.h

@@ -33,6 +33,7 @@ PUBLISHED:
 
   INLINE int get_num_axes() const;
   INLINE LVecBase3f get_axis(int anum) const;
+  MAKE_SEQ(get_axes, get_num_axes, get_axis);
   INLINE int get_axis_rel(int anum) const;
   INLINE dReal get_angle(int anum) const;
   INLINE dReal get_angle_rate(int anum) const;

+ 1 - 0
panda/src/ode/odeBody.h

@@ -124,6 +124,7 @@ PUBLISHED:
 
   INLINE int get_num_joints() const;
   OdeJoint get_joint(int index) const;
+  MAKE_SEQ(get_joints, get_num_joints, get_joint);
   INLINE void enable();
   INLINE void disable();
   INLINE int is_enabled() const;

+ 11 - 0
panda/src/ode/odeJointCollection.cxx

@@ -150,3 +150,14 @@ OdeJoint OdeJointCollection::
 operator [] (int index) const {
   return get_joint(index);
 }
+
+////////////////////////////////////////////////////////////////////
+//     Function: OdeJointCollection::size
+//       Access: Published
+//  Description: Returns the number of joints in the collection.  This
+//               is the same thing as get_num_joints().
+////////////////////////////////////////////////////////////////////
+int OdeJointCollection::
+size() const {
+  return _joints.size();
+}

+ 2 - 0
panda/src/ode/odeJointCollection.h

@@ -39,7 +39,9 @@ PUBLISHED:
   bool is_empty() const;
   int get_num_joints() const;
   OdeJoint get_joint(int index) const;
+  MAKE_SEQ(get_joints, get_num_joints, get_joint);
   OdeJoint operator [] (int index) const;
+  int size() const;
   
 private:  
   typedef PTA(OdeJoint) Joints;

+ 1 - 0
panda/src/ode/odeLMotorJoint.h

@@ -30,6 +30,7 @@ PUBLISHED:
 
   INLINE int get_num_axes() const;
   INLINE LVecBase3f get_axis(int anum) const;
+  MAKE_SEQ(get_axes, get_num_axes, get_axis);
   INLINE dReal get_param(int parameter) const;
 
 public:

+ 2 - 0
panda/src/parametrics/nurbsCurveEvaluator.h

@@ -55,6 +55,7 @@ PUBLISHED:
   INLINE void set_vertex(int i, const LVecBase3f &vertex, float weight = 1.0);
   INLINE const LVecBase4f &get_vertex(int i) const;
   INLINE LVecBase4f get_vertex(int i, const NodePath &rel_to) const;
+  MAKE_SEQ(get_vertices, get_num_vertices, get_vertex);
 
   INLINE void set_vertex_space(int i, const NodePath &space);
   INLINE void set_vertex_space(int i, const string &space);
@@ -68,6 +69,7 @@ PUBLISHED:
   INLINE int get_num_knots() const;
   void set_knot(int i, float knot);
   float get_knot(int i) const;
+  MAKE_SEQ(get_knots, get_num_knots, get_knot);
   void normalize_knots();
 
   INLINE int get_num_segments() const;

+ 2 - 0
panda/src/parametrics/nurbsCurveResult.h

@@ -65,6 +65,8 @@ PUBLISHED:
   INLINE int get_num_samples() const;
   INLINE float get_sample_t(int n) const;
   INLINE const LPoint3f &get_sample_point(int n) const;
+  MAKE_SEQ(get_sample_ts, get_num_samples, get_sample_t);
+  MAKE_SEQ(get_sample_points, get_num_samples, get_sample_points);
   
 private:
   int find_segment(float t);

+ 2 - 0
panda/src/parametrics/nurbsSurfaceEvaluator.h

@@ -66,11 +66,13 @@ PUBLISHED:
   INLINE int get_num_u_knots() const;
   void set_u_knot(int i, float knot);
   float get_u_knot(int i) const;
+  MAKE_SEQ(get_u_knots, get_num_u_knots, get_u_knot);
   void normalize_u_knots();
 
   INLINE int get_num_v_knots() const;
   void set_v_knot(int i, float knot);
   float get_v_knot(int i) const;
+  MAKE_SEQ(get_v_knots, get_num_v_knots, get_v_knot);
   void normalize_v_knots();
 
   INLINE int get_num_u_segments() const;

+ 1 - 0
panda/src/particlesystem/spriteParticleRenderer.h

@@ -198,6 +198,7 @@ PUBLISHED:
   INLINE Texture *get_texture(const int anim, const int frame) const;
   INLINE int get_num_anims() const;
   INLINE SpriteAnim *get_anim(const int n) const;
+  MAKE_SEQ(get_anims, get_num_anims, get_anim);
   INLINE SpriteAnim *get_last_anim() const;
   INLINE ColorInterpolationManager* get_color_interpolation_manager() const;
   INLINE TexCoordf get_ll_uv() const;

+ 1 - 0
panda/src/pgraph/attribNodeRegistry.h

@@ -46,6 +46,7 @@ PUBLISHED:
 
   int get_num_nodes() const;
   NodePath get_node(int n) const;
+  MAKE_SEQ(get_nodes, get_num_nodes, get_node);
   TypeHandle get_node_type(int n) const;
   string get_node_name(int n) const;
 

+ 1 - 0
panda/src/pgraph/camera.h

@@ -55,6 +55,7 @@ PUBLISHED:
 
   INLINE int get_num_display_regions() const;
   INLINE DisplayRegion *get_display_region(int n) const;
+  MAKE_SEQ(get_display_regions, get_num_display_regions, get_display_region);
 
   INLINE void set_camera_mask(DrawMask mask);
   INLINE DrawMask get_camera_mask() const;

+ 2 - 0
panda/src/pgraph/clipPlaneAttrib.h

@@ -75,10 +75,12 @@ PUBLISHED:
 
   INLINE int get_num_on_planes() const;
   INLINE NodePath get_on_plane(int n) const;
+  MAKE_SEQ(get_on_planes, get_num_on_planes, get_on_plane);
   INLINE bool has_on_plane(const NodePath &plane) const;
 
   INLINE int get_num_off_planes() const;
   INLINE NodePath get_off_plane(int n) const;
+  MAKE_SEQ(get_off_planes, get_num_off_planes, get_off_plane);
   INLINE bool has_off_plane(const NodePath &plane) const;
   INLINE bool has_all_off() const;
 

+ 1 - 0
panda/src/pgraph/cullBinManager.h

@@ -45,6 +45,7 @@ PUBLISHED:
 
   INLINE int get_num_bins() const;
   INLINE int get_bin(int n) const;
+  MAKE_SEQ(get_bins, get_num_bins, get_bin);
   int find_bin(const string &name) const;
 
   INLINE string get_bin_name(int bin_index) const;

+ 2 - 0
panda/src/pgraph/geomNode.h

@@ -69,8 +69,10 @@ PUBLISHED:
 
   INLINE int get_num_geoms() const;
   INLINE CPT(Geom) get_geom(int n) const;
+  MAKE_SEQ(get_geoms, get_num_geoms, get_geom);
   INLINE PT(Geom) modify_geom(int n);
   INLINE const RenderState *get_geom_state(int n) const;
+  MAKE_SEQ(get_geom_states, get_num_geoms, get_geom_state);
   INLINE void set_geom_state(int n, const RenderState *state);
 
   void add_geom(Geom *geom, const RenderState *state = RenderState::make_empty());

+ 11 - 0
panda/src/pgraph/internalNameCollection.cxx

@@ -230,6 +230,17 @@ operator [] (int index) const {
   return _names[index];
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: InternalNameCollection::size
+//       Access: Published
+//  Description: Returns the number of names in the collection.  This
+//               is the same thing as get_num_names().
+////////////////////////////////////////////////////////////////////
+int InternalNameCollection::
+size() const {
+  return _names.size();
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: InternalNameCollection::output
 //       Access: Published

+ 2 - 0
panda/src/pgraph/internalNameCollection.h

@@ -40,7 +40,9 @@ PUBLISHED:
 
   int get_num_names() const;
   InternalName *get_name(int index) const;
+  MAKE_SEQ(get_names, get_num_names, get_name);
   InternalName *operator [] (int index) const;
+  int size() const;
 
   void output(ostream &out) const;
   void write(ostream &out, int indent_level = 0) const;

+ 2 - 0
panda/src/pgraph/lightAttrib.h

@@ -73,10 +73,12 @@ PUBLISHED:
 
   INLINE int get_num_on_lights() const;
   INLINE NodePath get_on_light(int n) const;
+  MAKE_SEQ(get_on_lights, get_num_on_lights, get_on_light);
   INLINE bool has_on_light(const NodePath &light) const;
 
   INLINE int get_num_off_lights() const;
   INLINE NodePath get_off_light(int n) const;
+  MAKE_SEQ(get_off_lights, get_num_off_lights, get_off_light);
   INLINE bool has_off_light(const NodePath &light) const;
   INLINE bool has_all_off() const;
 

+ 2 - 0
panda/src/pgraph/loader.h

@@ -63,7 +63,9 @@ PUBLISHED:
     INLINE void clear();
     INLINE int get_num_files() const;
     INLINE const Filename &get_file(int n) const;
+    MAKE_SEQ(get_files, get_num_files, get_file);
     INLINE LoaderFileType *get_file_type(int n) const;
+    MAKE_SEQ(get_file_types, get_num_files, get_file_type);
 
   public:
     INLINE void add_file(const Filename &file, LoaderFileType *type);

Some files were not shown because too many files changed in this diff