Browse Source

outbound scripting

David Rose 16 years ago
parent
commit
25dd6bcc71

+ 2 - 0
direct/src/plugin/Sources.pp

@@ -30,6 +30,7 @@
     p3dInstanceManager.h p3dInstanceManager.I \
     p3dInstanceManager.h p3dInstanceManager.I \
     p3dIntObject.h \
     p3dIntObject.h \
     p3dMultifileReader.h p3dMultifileReader.I \
     p3dMultifileReader.h p3dMultifileReader.I \
+    p3dNoneObject.h p3dNullObject.h \
     p3dPackage.h p3dPackage.I \
     p3dPackage.h p3dPackage.I \
     p3dPythonObject.h \
     p3dPythonObject.h \
     p3dSession.h p3dSession.I \
     p3dSession.h p3dSession.I \
@@ -51,6 +52,7 @@
     p3dInstanceManager.cxx \
     p3dInstanceManager.cxx \
     p3dIntObject.cxx \
     p3dIntObject.cxx \
     p3dMultifileReader.cxx \
     p3dMultifileReader.cxx \
+    p3dNoneObject.cxx p3dNullObject.cxx \
     p3dPackage.cxx \
     p3dPackage.cxx \
     p3dPythonObject.cxx \
     p3dPythonObject.cxx \
     p3dSession.cxx \
     p3dSession.cxx \

+ 5 - 0
direct/src/plugin/load_plugin.cxx

@@ -42,6 +42,7 @@ P3D_instance_finish_func *P3D_instance_finish;
 P3D_instance_setup_window_func *P3D_instance_setup_window;
 P3D_instance_setup_window_func *P3D_instance_setup_window;
 
 
 P3D_make_class_definition_func *P3D_make_class_definition;
 P3D_make_class_definition_func *P3D_make_class_definition;
+P3D_new_null_object_func *P3D_new_null_object;
 P3D_new_none_object_func *P3D_new_none_object;
 P3D_new_none_object_func *P3D_new_none_object;
 P3D_new_bool_object_func *P3D_new_bool_object;
 P3D_new_bool_object_func *P3D_new_bool_object;
 P3D_new_int_object_func *P3D_new_int_object;
 P3D_new_int_object_func *P3D_new_int_object;
@@ -165,6 +166,7 @@ load_plugin(const string &p3d_plugin_filename) {
   P3D_instance_setup_window = (P3D_instance_setup_window_func *)get_func(module, "P3D_instance_setup_window");  
   P3D_instance_setup_window = (P3D_instance_setup_window_func *)get_func(module, "P3D_instance_setup_window");  
 
 
   P3D_make_class_definition = (P3D_make_class_definition_func *)get_func(module, "P3D_make_class_definition");
   P3D_make_class_definition = (P3D_make_class_definition_func *)get_func(module, "P3D_make_class_definition");
+  P3D_new_null_object = (P3D_new_null_object_func *)get_func(module, "P3D_new_null_object");
   P3D_new_none_object = (P3D_new_none_object_func *)get_func(module, "P3D_new_none_object");
   P3D_new_none_object = (P3D_new_none_object_func *)get_func(module, "P3D_new_none_object");
   P3D_new_bool_object = (P3D_new_bool_object_func *)get_func(module, "P3D_new_bool_object");
   P3D_new_bool_object = (P3D_new_bool_object_func *)get_func(module, "P3D_new_bool_object");
   P3D_new_int_object = (P3D_new_int_object_func *)get_func(module, "P3D_new_int_object");
   P3D_new_int_object = (P3D_new_int_object_func *)get_func(module, "P3D_new_int_object");
@@ -189,6 +191,7 @@ load_plugin(const string &p3d_plugin_filename) {
       P3D_instance_setup_window == NULL ||
       P3D_instance_setup_window == NULL ||
 
 
       P3D_make_class_definition == NULL ||
       P3D_make_class_definition == NULL ||
+      P3D_new_null_object == NULL ||
       P3D_new_none_object == NULL ||
       P3D_new_none_object == NULL ||
       P3D_new_bool_object == NULL ||
       P3D_new_bool_object == NULL ||
       P3D_new_int_object == NULL ||
       P3D_new_int_object == NULL ||
@@ -212,6 +215,7 @@ load_plugin(const string &p3d_plugin_filename) {
       << "\nP3D_instance_setup_window = " << P3D_instance_setup_window
       << "\nP3D_instance_setup_window = " << P3D_instance_setup_window
       
       
       << "\nP3D_make_class_definition = " << P3D_make_class_definition
       << "\nP3D_make_class_definition = " << P3D_make_class_definition
+      << "\nP3D_new_null_object = " << P3D_new_null_object
       << "\nP3D_new_none_object = " << P3D_new_none_object
       << "\nP3D_new_none_object = " << P3D_new_none_object
       << "\nP3D_new_bool_object = " << P3D_new_bool_object
       << "\nP3D_new_bool_object = " << P3D_new_bool_object
       << "\nP3D_new_int_object = " << P3D_new_int_object
       << "\nP3D_new_int_object = " << P3D_new_int_object
@@ -293,6 +297,7 @@ unload_dso() {
   P3D_instance_setup_window = NULL;
   P3D_instance_setup_window = NULL;
 
 
   P3D_make_class_definition = NULL;
   P3D_make_class_definition = NULL;
+  P3D_new_null_object = NULL;
   P3D_new_none_object = NULL;
   P3D_new_none_object = NULL;
   P3D_new_bool_object = NULL;
   P3D_new_bool_object = NULL;
   P3D_new_int_object = NULL;
   P3D_new_int_object = NULL;

+ 1 - 0
direct/src/plugin/load_plugin.h

@@ -28,6 +28,7 @@ extern P3D_instance_finish_func *P3D_instance_finish;
 extern P3D_instance_setup_window_func *P3D_instance_setup_window;
 extern P3D_instance_setup_window_func *P3D_instance_setup_window;
 
 
 extern P3D_make_class_definition_func *P3D_make_class_definition;
 extern P3D_make_class_definition_func *P3D_make_class_definition;
+extern P3D_new_null_object_func *P3D_new_null_object;
 extern P3D_new_none_object_func *P3D_new_none_object;
 extern P3D_new_none_object_func *P3D_new_none_object;
 extern P3D_new_bool_object_func *P3D_new_bool_object;
 extern P3D_new_bool_object_func *P3D_new_bool_object;
 extern P3D_new_int_object_func *P3D_new_int_object;
 extern P3D_new_int_object_func *P3D_new_int_object;

+ 65 - 7
direct/src/plugin/p3dInstance.cxx

@@ -514,14 +514,14 @@ handle_script_request(P3D_request *request) {
   switch (request->_request._script._op) {
   switch (request->_request._script._op) {
   case P3D_SO_get_property:
   case P3D_SO_get_property:
     {
     {
-      P3D_object *value = P3D_OBJECT_GET_PROPERTY(object, request->_request._script._property_name);
+      P3D_object *result = P3D_OBJECT_GET_PROPERTY(object, request->_request._script._property_name);
       nout << "get_property, object = " << object << "\n";
       nout << "get_property, object = " << object << "\n";
       if (object != NULL) {
       if (object != NULL) {
         nout << "  *object = " << *object << "\n" << flush;
         nout << "  *object = " << *object << "\n" << flush;
       }
       }
-      nout << "value = " << value << "\n" << flush;
-      if (value != NULL) {
-        nout << "  *value = " << *value << "\n" << flush;
+      nout << "result = " << result << "\n" << flush;
+      if (result != NULL) {
+        nout << "  *result = " << *result << "\n" << flush;
       }
       }
       // We've got the property value; feed it back down to the
       // We've got the property value; feed it back down to the
       // subprocess.
       // subprocess.
@@ -533,14 +533,72 @@ handle_script_request(P3D_request *request) {
       
       
       doc->LinkEndChild(decl);
       doc->LinkEndChild(decl);
       doc->LinkEndChild(xcommand);
       doc->LinkEndChild(xcommand);
-      if (value != NULL) {
-        xcommand->LinkEndChild(_session->p3dobj_to_xml(value));
-        P3D_OBJECT_FINISH(value);
+      if (result != NULL) {
+        xcommand->LinkEndChild(_session->p3dobj_to_xml(result));
+        P3D_OBJECT_FINISH(result);
       }
       }
       
       
       _session->send_command(doc);
       _session->send_command(doc);
     }
     }
     break;
     break;
+
+  case P3D_SO_set_property:
+    {
+      bool result = P3D_OBJECT_SET_PROPERTY(object, request->_request._script._property_name,
+                                            request->_request._script._value);
+      nout << "set_property, object = " << object << "\n";
+      if (object != NULL) {
+        nout << "  *object = " << *object << "\n" << flush;
+      }
+      nout << "result = " << result << "\n" << flush;
+
+      // Feed the result back down to the subprocess.
+      TiXmlDocument *doc = new TiXmlDocument;
+      TiXmlDeclaration *decl = new TiXmlDeclaration("1.0", "utf-8", "");
+      TiXmlElement *xcommand = new TiXmlElement("command");
+      xcommand->SetAttribute("cmd", "script_response");
+      xcommand->SetAttribute("unique_id", unique_id);
+      
+      doc->LinkEndChild(decl);
+      doc->LinkEndChild(xcommand);
+
+      TiXmlElement *xvalue = new TiXmlElement("value");
+      xvalue->SetAttribute("type", "bool");
+      xvalue->SetAttribute("value", (int)result);
+      xcommand->LinkEndChild(xvalue);
+      
+      _session->send_command(doc);
+    }
+    break;
+
+  case P3D_SO_del_property:
+    {
+      bool result = P3D_OBJECT_SET_PROPERTY(object, request->_request._script._property_name,
+                                            NULL);
+      nout << "del_property, object = " << object << "\n";
+      if (object != NULL) {
+        nout << "  *object = " << *object << "\n" << flush;
+      }
+      nout << "result = " << result << "\n" << flush;
+
+      // Feed the result back down to the subprocess.
+      TiXmlDocument *doc = new TiXmlDocument;
+      TiXmlDeclaration *decl = new TiXmlDeclaration("1.0", "utf-8", "");
+      TiXmlElement *xcommand = new TiXmlElement("command");
+      xcommand->SetAttribute("cmd", "script_response");
+      xcommand->SetAttribute("unique_id", unique_id);
+      
+      doc->LinkEndChild(decl);
+      doc->LinkEndChild(xcommand);
+
+      TiXmlElement *xvalue = new TiXmlElement("value");
+      xvalue->SetAttribute("type", "bool");
+      xvalue->SetAttribute("value", (int)result);
+      xcommand->LinkEndChild(xvalue);
+      
+      _session->send_command(doc);
+    }
+    break;
   }
   }
 }
 }
 
 

+ 1 - 1
direct/src/plugin/p3dNoneObject.h

@@ -21,7 +21,7 @@
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //       Class : P3DNoneObject
 //       Class : P3DNoneObject
 // Description : An object type that contains no value, similar to
 // Description : An object type that contains no value, similar to
-//               Python's None type.
+//               Python's None type, or JavaScript's void type.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 class P3DNoneObject : public P3DObject {
 class P3DNoneObject : public P3DObject {
 public:
 public:

+ 56 - 0
direct/src/plugin/p3dNullObject.cxx

@@ -0,0 +1,56 @@
+// Filename: p3dNullObject.cxx
+// Created by:  drose (07Jul09)
+//
+////////////////////////////////////////////////////////////////////
+//
+// 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 "p3dNullObject.h"
+
+////////////////////////////////////////////////////////////////////
+//     Function: P3DNullObject::Constructor
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+P3DNullObject::
+P3DNullObject() {
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: P3DNullObject::get_type
+//       Access: Public, Virtual
+//  Description: Returns the fundamental type of this kind of object.
+////////////////////////////////////////////////////////////////////
+P3D_object_type P3DNullObject::
+get_type() const {
+  return P3D_OT_null;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: P3DNullObject::get_bool
+//       Access: Public, Virtual
+//  Description: Returns the object value coerced to a boolean, if
+//               possible.
+////////////////////////////////////////////////////////////////////
+bool P3DNullObject::
+get_bool() const {
+  return false;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: P3DNullObject::make_string
+//       Access: Public, Virtual
+//  Description: Fills the indicated C++ string object with the value
+//               of this object coerced to a string.
+////////////////////////////////////////////////////////////////////
+void P3DNullObject::
+make_string(string &value) const {
+  value = "Null";
+}

+ 39 - 0
direct/src/plugin/p3dNullObject.h

@@ -0,0 +1,39 @@
+// Filename: p3dNullObject.h
+// Created by:  drose (07Jul09)
+//
+////////////////////////////////////////////////////////////////////
+//
+// 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 P3DNULLOBJECT_H
+#define P3DNULLOBJECT_H
+
+#include "p3d_plugin_common.h"
+#include "p3dObject.h"
+
+////////////////////////////////////////////////////////////////////
+//       Class : P3DNullObject
+// Description : An object type that represents a NULL pointer.
+//               Python doesn't have such a concept, but C and
+//               JavaScript do, and it is sometimes an important
+//               return value.
+////////////////////////////////////////////////////////////////////
+class P3DNullObject : public P3DObject {
+public:
+  P3DNullObject();
+
+public:
+  virtual P3D_object_type get_type() const;
+  virtual bool get_bool() const;
+  virtual void make_string(string &value) const;
+};
+
+#endif
+

+ 24 - 1
direct/src/plugin/p3dPythonRun.cxx

@@ -126,6 +126,20 @@ run_python() {
   }
   }
   Py_DECREF(app_runner_class);
   Py_DECREF(app_runner_class);
 
 
+  // Get the NullObject class.
+  _null_object_class = PyObject_GetAttrString(runp3d, "NullObject");
+  if (_null_object_class == NULL) {
+    PyErr_Print();
+    return false;
+  }
+
+  // And the "Null" instance.
+  _null = PyObject_GetAttrString(runp3d, "Null");
+  if (_null == NULL) {
+    PyErr_Print();
+    return false;
+  }
+
   // Get the BrowserObject class.
   // Get the BrowserObject class.
   _browser_object_class = PyObject_GetAttrString(runp3d, "BrowserObject");
   _browser_object_class = PyObject_GetAttrString(runp3d, "BrowserObject");
   if (_browser_object_class == NULL) {
   if (_browser_object_class == NULL) {
@@ -552,7 +566,8 @@ py_request_func(PyObject *args) {
       nout << "Converting xvalue: " << *xvalue << "\n";
       nout << "Converting xvalue: " << *xvalue << "\n";
       value = xml_to_pyobj(xvalue);
       value = xml_to_pyobj(xvalue);
     } else {
     } else {
-      value = Py_None;
+      // An absence of a <value> element means a NULL pointer.
+      value = _null;
       Py_INCREF(value);
       Py_INCREF(value);
     }
     }
     nout << "Got script_response " << response_id << ", xvalue = " << xvalue << "\n";
     nout << "Got script_response " << response_id << ", xvalue = " << xvalue << "\n";
@@ -930,6 +945,10 @@ pyobj_to_xml(PyObject *value) {
       xvalue->SetAttribute("value", str);
       xvalue->SetAttribute("value", str);
     }
     }
 
 
+  } else if (PyObject_IsInstance(value, _null_object_class)) {
+    // This is a NullObject, our equivalent to a NULL pointer.
+    xvalue->SetAttribute("type", "null");
+
   } else if (PyObject_IsInstance(value, _browser_object_class)) {
   } else if (PyObject_IsInstance(value, _browser_object_class)) {
     // This is a BrowserObject, a reference to an object that actually
     // This is a BrowserObject, a reference to an object that actually
     // exists in the host namespace.  So, pass up the appropriate
     // exists in the host namespace.  So, pass up the appropriate
@@ -996,6 +1015,10 @@ xml_to_pyobj(TiXmlElement *xvalue) {
       return PyString_FromStringAndSize(value->data(), value->length());
       return PyString_FromStringAndSize(value->data(), value->length());
     }
     }
 
 
+  } else if (strcmp(type, "null") == 0) {
+    Py_INCREF(_null);
+    return _null;
+
   } else if (strcmp(type, "browser") == 0) {
   } else if (strcmp(type, "browser") == 0) {
     int object_id;
     int object_id;
     if (xvalue->QueryIntAttribute("object_id", &object_id) == TIXML_SUCCESS) {
     if (xvalue->QueryIntAttribute("object_id", &object_id) == TIXML_SUCCESS) {

+ 2 - 0
direct/src/plugin/p3dPythonRun.h

@@ -110,6 +110,8 @@ private:
   char **_py_argv;
   char **_py_argv;
 
 
   PyObject *_runner;
   PyObject *_runner;
+  PyObject *_null_object_class;
+  PyObject *_null;
   PyObject *_browser_object_class;
   PyObject *_browser_object_class;
   PyObject *_taskMgr;
   PyObject *_taskMgr;
 
 

+ 25 - 1
direct/src/plugin/p3dSession.cxx

@@ -16,6 +16,7 @@
 #include "p3dInstance.h"
 #include "p3dInstance.h"
 #include "p3dInstanceManager.h"
 #include "p3dInstanceManager.h"
 #include "p3d_plugin_config.h"
 #include "p3d_plugin_config.h"
+#include "p3dNullObject.h"
 #include "p3dNoneObject.h"
 #include "p3dNoneObject.h"
 #include "p3dBoolObject.h"
 #include "p3dBoolObject.h"
 #include "p3dIntObject.h"
 #include "p3dIntObject.h"
@@ -321,7 +322,10 @@ command_and_response(TiXmlDocument *command) {
 P3D_object *P3DSession::
 P3D_object *P3DSession::
 xml_to_p3dobj(const TiXmlElement *xvalue) {
 xml_to_p3dobj(const TiXmlElement *xvalue) {
   const char *type = xvalue->Attribute("type");
   const char *type = xvalue->Attribute("type");
-  if (strcmp(type, "none") == 0) {
+  if (strcmp(type, "null") == 0) {
+    return new P3DNullObject;
+
+  } else if (strcmp(type, "none") == 0) {
     return new P3DNoneObject;
     return new P3DNoneObject;
 
 
   } else if (strcmp(type, "bool") == 0) {
   } else if (strcmp(type, "bool") == 0) {
@@ -382,6 +386,10 @@ p3dobj_to_xml(const P3D_object *obj) {
   TiXmlElement *xvalue = new TiXmlElement("value");
   TiXmlElement *xvalue = new TiXmlElement("value");
 
 
   switch (P3D_OBJECT_GET_TYPE(obj)) {
   switch (P3D_OBJECT_GET_TYPE(obj)) {
+  case P3D_OT_null:
+    xvalue->SetAttribute("type", "null");
+    break;
+
   case P3D_OT_none:
   case P3D_OT_none:
     xvalue->SetAttribute("type", "none");
     xvalue->SetAttribute("type", "none");
     break;
     break;
@@ -704,6 +712,22 @@ rt_make_p3d_request(TiXmlElement *xrequest) {
           request->_request._script._property_name = strdup(property_name);
           request->_request._script._property_name = strdup(property_name);
           request->_request._script._value = NULL;
           request->_request._script._value = NULL;
           request->_request._script._unique_id = unique_id;
           request->_request._script._unique_id = unique_id;
+        } else if (strcmp(operation, "set_property") == 0 && property_name != NULL && xvalue != NULL) {
+          request = new P3D_request;
+          request->_request_type = P3D_RT_script;
+          request->_request._script._object = object;
+          request->_request._script._op = P3D_SO_set_property;
+          request->_request._script._property_name = strdup(property_name);
+          request->_request._script._value = xml_to_p3dobj(xvalue);
+          request->_request._script._unique_id = unique_id;
+        } else if (strcmp(operation, "del_property") == 0 && property_name != NULL) {
+          request = new P3D_request;
+          request->_request_type = P3D_RT_script;
+          request->_request._script._object = object;
+          request->_request._script._op = P3D_SO_del_property;
+          request->_request._script._property_name = strdup(property_name);
+          request->_request._script._value = NULL;
+          request->_request._script._unique_id = unique_id;
         }
         }
         if (request == NULL) {
         if (request == NULL) {
           // If we haven't dispatched a request yet, we didn't use the
           // If we haven't dispatched a request yet, we didn't use the

+ 12 - 0
direct/src/plugin/p3d_plugin.cxx

@@ -16,6 +16,7 @@
 #include "p3dInstanceManager.h"
 #include "p3dInstanceManager.h"
 #include "p3dInstance.h"
 #include "p3dInstance.h"
 #include "p3dWindowParams.h"
 #include "p3dWindowParams.h"
+#include "p3dNullObject.h"
 #include "p3dNoneObject.h"
 #include "p3dNoneObject.h"
 #include "p3dBoolObject.h"
 #include "p3dBoolObject.h"
 #include "p3dIntObject.h"
 #include "p3dIntObject.h"
@@ -132,6 +133,17 @@ P3D_make_class_definition() {
   return result;
   return result;
 }
 }
 
 
+P3D_object *
+P3D_new_null_object() {
+  assert(P3DInstanceManager::get_global_ptr()->is_initialized());
+  ACQUIRE_LOCK(_api_lock);
+
+  P3D_object *result = new P3DNullObject();
+  
+  RELEASE_LOCK(_api_lock);
+  return result;
+}
+
 P3D_object *
 P3D_object *
 P3D_new_none_object() {
 P3D_new_none_object() {
   assert(P3DInstanceManager::get_global_ptr()->is_initialized());
   assert(P3DInstanceManager::get_global_ptr()->is_initialized());

+ 10 - 0
direct/src/plugin/p3d_plugin.h

@@ -294,6 +294,7 @@ typedef struct _P3D_object P3D_object;
 
 
 /* A list of fundamental object types. */
 /* A list of fundamental object types. */
 typedef enum {
 typedef enum {
+  P3D_OT_null,
   P3D_OT_none,
   P3D_OT_none,
   P3D_OT_bool,
   P3D_OT_bool,
   P3D_OT_int,
   P3D_OT_int,
@@ -449,6 +450,13 @@ struct _P3D_object {
 typedef P3D_class_definition *
 typedef P3D_class_definition *
 P3D_make_class_definition_func();
 P3D_make_class_definition_func();
 
 
+/* Allocates a new P3D_object of type null.  This value has no
+   particular value and corresponds a NULL pointer in C or JavaScript.
+   It has no Python equivalent (but we map it to an explicit Null
+   instance in runp3d.py). */
+typedef P3D_object *
+P3D_new_null_object_func();
+
 /* Allocates a new P3D_object of type none.  This value has no
 /* Allocates a new P3D_object of type none.  This value has no
    particular value and corresponds to Python's None type or C's void
    particular value and corresponds to Python's None type or C's void
    type. */
    type. */
@@ -594,6 +602,7 @@ typedef struct {
 typedef enum {
 typedef enum {
   P3D_SO_get_property,
   P3D_SO_get_property,
   P3D_SO_set_property,
   P3D_SO_set_property,
+  P3D_SO_del_property,
   P3D_SO_call,
   P3D_SO_call,
 } P3D_script_operation;
 } P3D_script_operation;
 typedef struct {
 typedef struct {
@@ -729,6 +738,7 @@ EXPCL_P3D_PLUGIN P3D_instance_finish_func P3D_instance_finish;
 EXPCL_P3D_PLUGIN P3D_instance_setup_window_func P3D_instance_setup_window;
 EXPCL_P3D_PLUGIN P3D_instance_setup_window_func P3D_instance_setup_window;
 
 
 EXPCL_P3D_PLUGIN P3D_make_class_definition_func P3D_make_class_definition;
 EXPCL_P3D_PLUGIN P3D_make_class_definition_func P3D_make_class_definition;
+EXPCL_P3D_PLUGIN P3D_new_null_object_func P3D_new_null_object;
 EXPCL_P3D_PLUGIN P3D_new_none_object_func P3D_new_none_object;
 EXPCL_P3D_PLUGIN P3D_new_none_object_func P3D_new_none_object;
 EXPCL_P3D_PLUGIN P3D_new_bool_object_func P3D_new_bool_object;
 EXPCL_P3D_PLUGIN P3D_new_bool_object_func P3D_new_bool_object;
 EXPCL_P3D_PLUGIN P3D_new_int_object_func P3D_new_int_object;
 EXPCL_P3D_PLUGIN P3D_new_int_object_func P3D_new_int_object;

+ 1 - 0
direct/src/plugin/p3d_plugin_composite1.cxx

@@ -11,6 +11,7 @@
 #include "p3dMultifileReader.cxx"
 #include "p3dMultifileReader.cxx"
 #include "p3dPythonObject.cxx"
 #include "p3dPythonObject.cxx"
 #include "p3dNoneObject.cxx"
 #include "p3dNoneObject.cxx"
+#include "p3dNullObject.cxx"
 #include "p3dObject.cxx"
 #include "p3dObject.cxx"
 #include "p3dPackage.cxx"
 #include "p3dPackage.cxx"
 #include "p3dSession.cxx"
 #include "p3dSession.cxx"