Sfoglia il codice sorgente

resolve confusion between null, none, void, and undefined

David Rose 16 anni fa
parent
commit
095c719f9d

+ 6 - 4
direct/src/plugin/Sources.pp

@@ -30,13 +30,14 @@
     p3dInstanceManager.h p3dInstanceManager.I \
     p3dIntObject.h \
     p3dMultifileReader.h p3dMultifileReader.I \
-    p3dNoneObject.h p3dNullObject.h \
+    p3dNoneObject.h \
+    p3dObject.h p3dObject.I \
     p3dPackage.h p3dPackage.I \
     p3dPythonObject.h \
     p3dSession.h p3dSession.I \
     p3dSplashWindow.h p3dSplashWindow.I \
     p3dStringObject.h \
-    p3dObject.h p3dObject.I \
+    p3dUndefinedObject.h \
     p3dWinSplashWindow.h p3dWinSplashWindow.I \
     p3dWindowParams.h p3dWindowParams.I
 
@@ -52,13 +53,14 @@
     p3dInstanceManager.cxx \
     p3dIntObject.cxx \
     p3dMultifileReader.cxx \
-    p3dNoneObject.cxx p3dNullObject.cxx \
+    p3dNoneObject.cxx \
+    p3dObject.cxx \
     p3dPackage.cxx \
     p3dPythonObject.cxx \
     p3dSession.cxx \
     p3dSplashWindow.cxx \
     p3dStringObject.cxx \
-    p3dObject.cxx \
+    p3dUndefinedObject.cxx \
     p3dWinSplashWindow.cxx \
     p3dWindowParams.cxx
 

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

@@ -42,7 +42,7 @@ P3D_instance_finish_func *P3D_instance_finish;
 P3D_instance_setup_window_func *P3D_instance_setup_window;
 
 P3D_make_class_definition_func *P3D_make_class_definition;
-P3D_new_null_object_func *P3D_new_null_object;
+P3D_new_undefined_object_func *P3D_new_undefined_object;
 P3D_new_none_object_func *P3D_new_none_object;
 P3D_new_bool_object_func *P3D_new_bool_object;
 P3D_new_int_object_func *P3D_new_int_object;
@@ -166,7 +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_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_undefined_object = (P3D_new_undefined_object_func *)get_func(module, "P3D_new_undefined_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_int_object = (P3D_new_int_object_func *)get_func(module, "P3D_new_int_object");
@@ -191,7 +191,7 @@ load_plugin(const string &p3d_plugin_filename) {
       P3D_instance_setup_window == NULL ||
 
       P3D_make_class_definition == NULL ||
-      P3D_new_null_object == NULL ||
+      P3D_new_undefined_object == NULL ||
       P3D_new_none_object == NULL ||
       P3D_new_bool_object == NULL ||
       P3D_new_int_object == NULL ||
@@ -215,7 +215,7 @@ load_plugin(const string &p3d_plugin_filename) {
       << "\nP3D_instance_setup_window = " << P3D_instance_setup_window
       
       << "\nP3D_make_class_definition = " << P3D_make_class_definition
-      << "\nP3D_new_null_object = " << P3D_new_null_object
+      << "\nP3D_new_undefined_object = " << P3D_new_undefined_object
       << "\nP3D_new_none_object = " << P3D_new_none_object
       << "\nP3D_new_bool_object = " << P3D_new_bool_object
       << "\nP3D_new_int_object = " << P3D_new_int_object
@@ -294,7 +294,7 @@ unload_dso() {
   P3D_instance_setup_window = NULL;
 
   P3D_make_class_definition = NULL;
-  P3D_new_null_object = NULL;
+  P3D_new_undefined_object = NULL;
   P3D_new_none_object = NULL;
   P3D_new_bool_object = NULL;
   P3D_new_int_object = NULL;

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

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

+ 2 - 2
direct/src/plugin/p3dInstance.cxx

@@ -20,7 +20,7 @@
 #include "p3dSplashWindow.h"
 #include "p3dWinSplashWindow.h"
 #include "p3dObject.h"
-#include "p3dNullObject.h"
+#include "p3dUndefinedObject.h"
 
 #include <sstream>
 #include <algorithm>
@@ -195,7 +195,7 @@ get_panda_script_object() const {
   }
 
   if (result == NULL) {
-    result = new P3DNullObject;
+    result = new P3DUndefinedObject;
   }
 
   return result;

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

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

+ 16 - 15
direct/src/plugin/p3dPythonRun.cxx

@@ -126,16 +126,16 @@ run_python() {
   }
   Py_DECREF(app_runner_class);
 
-  // Get the NullObject class.
-  _null_object_class = PyObject_GetAttrString(runp3d, "NullObject");
-  if (_null_object_class == NULL) {
+  // Get the UndefinedObject class.
+  _undefined_object_class = PyObject_GetAttrString(runp3d, "UndefinedObject");
+  if (_undefined_object_class == NULL) {
     PyErr_Print();
     return false;
   }
 
-  // And the "Null" instance.
-  _null = PyObject_GetAttrString(runp3d, "Null");
-  if (_null == NULL) {
+  // And the "Undefined" instance.
+  _undefined = PyObject_GetAttrString(runp3d, "Undefined");
+  if (_undefined == NULL) {
     PyErr_Print();
     return false;
   }
@@ -564,9 +564,10 @@ py_request_func(PyObject *args) {
     if (xvalue != NULL) {
       value = xml_to_pyobj(xvalue);
     } else {
-      // An absence of a <value> element means a NULL pointer.
-      value = _null;
-      Py_INCREF(value);
+      // An absence of a <value> element is an exception.  We will
+      // return NULL from this function, but first set the error
+      // condition.
+      PyErr_SetString(PyExc_EnvironmentError, "Error on script call");
     }
 
     delete doc;
@@ -937,9 +938,9 @@ pyobj_to_xml(PyObject *value) {
       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, _undefined_object_class)) {
+    // This is an UndefinedObject.
+    xvalue->SetAttribute("type", "undefined");
 
   } else if (PyObject_IsInstance(value, _browser_object_class)) {
     // This is a BrowserObject, a reference to an object that actually
@@ -1007,9 +1008,9 @@ xml_to_pyobj(TiXmlElement *xvalue) {
       return PyString_FromStringAndSize(value->data(), value->length());
     }
 
-  } else if (strcmp(type, "null") == 0) {
-    Py_INCREF(_null);
-    return _null;
+  } else if (strcmp(type, "undefined") == 0) {
+    Py_INCREF(_undefined);
+    return _undefined;
 
   } else if (strcmp(type, "browser") == 0) {
     int object_id;

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

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

+ 5 - 5
direct/src/plugin/p3dSession.cxx

@@ -16,7 +16,7 @@
 #include "p3dInstance.h"
 #include "p3dInstanceManager.h"
 #include "p3d_plugin_config.h"
-#include "p3dNullObject.h"
+#include "p3dUndefinedObject.h"
 #include "p3dNoneObject.h"
 #include "p3dBoolObject.h"
 #include "p3dIntObject.h"
@@ -321,8 +321,8 @@ command_and_response(TiXmlDocument *command) {
 P3D_object *P3DSession::
 xml_to_p3dobj(const TiXmlElement *xvalue) {
   const char *type = xvalue->Attribute("type");
-  if (strcmp(type, "null") == 0) {
-    return new P3DNullObject;
+  if (strcmp(type, "undefined") == 0) {
+    return new P3DUndefinedObject;
 
   } else if (strcmp(type, "none") == 0) {
     return new P3DNoneObject;
@@ -383,8 +383,8 @@ p3dobj_to_xml(const P3D_object *obj) {
   TiXmlElement *xvalue = new TiXmlElement("value");
 
   switch (P3D_OBJECT_GET_TYPE(obj)) {
-  case P3D_OT_null:
-    xvalue->SetAttribute("type", "null");
+  case P3D_OT_undefined:
+    xvalue->SetAttribute("type", "undefined");
     break;
 
   case P3D_OT_none:

+ 13 - 13
direct/src/plugin/p3dNullObject.cxx → direct/src/plugin/p3dUndefinedObject.cxx

@@ -1,4 +1,4 @@
-// Filename: p3dNullObject.cxx
+// Filename: p3dUndefinedObject.cxx
 // Created by:  drose (07Jul09)
 //
 ////////////////////////////////////////////////////////////////////
@@ -12,45 +12,45 @@
 //
 ////////////////////////////////////////////////////////////////////
 
-#include "p3dNullObject.h"
+#include "p3dUndefinedObject.h"
 
 ////////////////////////////////////////////////////////////////////
-//     Function: P3DNullObject::Constructor
+//     Function: P3DUndefinedObject::Constructor
 //       Access: Public
 //  Description: 
 ////////////////////////////////////////////////////////////////////
-P3DNullObject::
-P3DNullObject() {
+P3DUndefinedObject::
+P3DUndefinedObject() {
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: P3DNullObject::get_type
+//     Function: P3DUndefinedObject::get_type
 //       Access: Public, Virtual
 //  Description: Returns the fundamental type of this kind of object.
 ////////////////////////////////////////////////////////////////////
-P3D_object_type P3DNullObject::
+P3D_object_type P3DUndefinedObject::
 get_type() const {
-  return P3D_OT_null;
+  return P3D_OT_undefined;
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: P3DNullObject::get_bool
+//     Function: P3DUndefinedObject::get_bool
 //       Access: Public, Virtual
 //  Description: Returns the object value coerced to a boolean, if
 //               possible.
 ////////////////////////////////////////////////////////////////////
-bool P3DNullObject::
+bool P3DUndefinedObject::
 get_bool() const {
   return false;
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: P3DNullObject::make_string
+//     Function: P3DUndefinedObject::make_string
 //       Access: Public, Virtual
 //  Description: Fills the indicated C++ string object with the value
 //               of this object coerced to a string.
 ////////////////////////////////////////////////////////////////////
-void P3DNullObject::
+void P3DUndefinedObject::
 make_string(string &value) const {
-  value = "Null";
+  value = "Undefined";
 }

+ 9 - 10
direct/src/plugin/p3dNullObject.h → direct/src/plugin/p3dUndefinedObject.h

@@ -1,4 +1,4 @@
-// Filename: p3dNullObject.h
+// Filename: p3dUndefinedObject.h
 // Created by:  drose (07Jul09)
 //
 ////////////////////////////////////////////////////////////////////
@@ -12,22 +12,21 @@
 //
 ////////////////////////////////////////////////////////////////////
 
-#ifndef P3DNULLOBJECT_H
-#define P3DNULLOBJECT_H
+#ifndef P3DUNDEFINEDOBJECT_H
+#define P3DUNDEFINEDOBJECT_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 : P3DUndefinedObject
+// Description : An object type that represents an undefined value.
+//               Python doesn't have such a concept, but JavaScript
+//               does, and it is sometimes an important return value.
 ////////////////////////////////////////////////////////////////////
-class P3DNullObject : public P3DObject {
+class P3DUndefinedObject : public P3DObject {
 public:
-  P3DNullObject();
+  P3DUndefinedObject();
 
 public:
   virtual P3D_object_type get_type() const;

+ 3 - 3
direct/src/plugin/p3d_plugin.cxx

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

+ 9 - 9
direct/src/plugin/p3d_plugin.h

@@ -294,7 +294,7 @@ typedef struct _P3D_object P3D_object;
 
 /* A list of fundamental object types. */
 typedef enum {
-  P3D_OT_null,
+  P3D_OT_undefined,
   P3D_OT_none,
   P3D_OT_bool,
   P3D_OT_int,
@@ -461,16 +461,16 @@ struct _P3D_object {
 typedef P3D_class_definition *
 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). */
+/* Allocates a new P3D_object of type "undefined".  This corresponds
+   to the undefined or void type on JavaScript.  It is similar to
+   Python's None, but has a subtly different shade of meaning; we map
+   it to an explicit Undefined instance in runp3d.py. */
 typedef P3D_object *
-P3D_new_null_object_func();
+P3D_new_undefined_object_func();
 
 /* 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
-   type. */
+   particular value and corresponds to Python's None type or
+   JavaScript's null type. */
 typedef P3D_object *
 P3D_new_none_object_func();
 
@@ -752,7 +752,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_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_undefined_object_func P3D_new_undefined_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_int_object_func P3D_new_int_object;

+ 2 - 2
direct/src/plugin/p3d_plugin_composite1.cxx

@@ -9,13 +9,13 @@
 #include "p3dInstanceManager.cxx"
 #include "p3dIntObject.cxx"
 #include "p3dMultifileReader.cxx"
-#include "p3dPythonObject.cxx"
 #include "p3dNoneObject.cxx"
-#include "p3dNullObject.cxx"
 #include "p3dObject.cxx"
 #include "p3dPackage.cxx"
+#include "p3dPythonObject.cxx"
 #include "p3dSession.cxx"
 #include "p3dSplashWindow.cxx"
 #include "p3dStringObject.cxx"
+#include "p3dUndefinedObject.cxx"
 #include "p3dWinSplashWindow.cxx"
 #include "p3dWindowParams.cxx"

+ 5 - 11
direct/src/plugin_npapi/ppBrowserObject.cxx

@@ -157,17 +157,11 @@ set_property(const string &property, P3D_object *value) {
   bool result;
   if (value != NULL) {
     // Set the property.
-    if (P3D_OBJECT_GET_TYPE(value) != P3D_OT_null) {
-      NPVariant npvalue;
-      _instance->p3dobj_to_variant(&npvalue, value);
-      result = browser->setproperty(_instance->get_npp_instance(), _npobj,
-                                    property_name, &npvalue);
-      browser->releasevariantvalue(&npvalue);
-    } else {
-      // Actually, delete the property after all.
-      result = browser->removeproperty(_instance->get_npp_instance(), _npobj,
-                                       property_name);
-    }
+    NPVariant npvalue;
+    _instance->p3dobj_to_variant(&npvalue, value);
+    result = browser->setproperty(_instance->get_npp_instance(), _npobj,
+                                  property_name, &npvalue);
+    browser->releasevariantvalue(&npvalue);
     P3D_OBJECT_FINISH(value);
 
   } else {

+ 6 - 6
direct/src/plugin_npapi/ppInstance.cxx

@@ -500,12 +500,12 @@ get_panda_script_object() {
 void PPInstance::
 p3dobj_to_variant(NPVariant *result, const P3D_object *object) {
   switch (P3D_OBJECT_GET_TYPE(object)) {
-  case P3D_OT_null:
-    NULL_TO_NPVARIANT(*result);
+  case P3D_OT_undefined:
+    VOID_TO_NPVARIANT(*result);
     break;
 
   case P3D_OT_none:
-    VOID_TO_NPVARIANT(*result);
+    NULL_TO_NPVARIANT(*result);
     break;
 
   case P3D_OT_bool:
@@ -548,9 +548,9 @@ p3dobj_to_variant(NPVariant *result, const P3D_object *object) {
 ////////////////////////////////////////////////////////////////////
 P3D_object *PPInstance::
 variant_to_p3dobj(const NPVariant *variant) {
-  if (NPVARIANT_IS_NULL(*variant)) {
-    return P3D_new_null_object();
-  } else if (NPVARIANT_IS_VOID(*variant)) {
+  if (NPVARIANT_IS_VOID(*variant)) {
+    return P3D_new_undefined_object();
+  } else if (NPVARIANT_IS_NULL(*variant)) {
     return P3D_new_none_object();
   } else if (NPVARIANT_IS_BOOLEAN(*variant)) {
     return P3D_new_bool_object(NPVARIANT_TO_BOOLEAN(*variant));

+ 20 - 17
direct/src/showutil/runp3d.py

@@ -59,9 +59,9 @@ class AppRunner(DirectObject):
         self.windowOpened = False
         self.windowPrc = None
 
-        # Store this Null instance where the application can easily
+        # Store this Undefined instance where the application can easily
         # get to it.
-        self.Null = Null
+        self.Undefined = Undefined
 
         # This is per session.
         self.nextScriptId = 0
@@ -413,15 +413,20 @@ class AppRunner(DirectObject):
 
         return (osFilename, tokens)
 
-class NullObject:
+class UndefinedObject:
     """ This is a special object that is returned by the browser to
     represent a NULL pointer, typically the return value for a failed
-    operation.  It has no attributes. """
-    pass
+    operation.  It has no attributes, similar to None. """
+
+    def __nonzero__(self):
+        return False
+
+    def __str__(self):
+        return "Undefined"
 
 # In fact, we normally always return this precise instance of the
-# NullObject.
-Null = NullObject()
+# UndefinedObject.
+Undefined = UndefinedObject()
 
 class BrowserObject:
     """ This class provides the Python wrapper around some object that
@@ -475,10 +480,6 @@ class BrowserObject:
             # Call it as a plain function.
             result = self.__runner.scriptRequest('call', self, value = args)
 
-        if result is Null:
-            # Could not call the method.
-            raise TypeError
-
         return result
 
     def __getattr__(self, name):
@@ -486,9 +487,10 @@ class BrowserObject:
         into the appropriate calls to query the actual browser object
         under the hood.  """
 
-        value = self.__runner.scriptRequest('get_property', self,
-                                            propertyName = name)
-        if value is Null:
+        try:
+            value = self.__runner.scriptRequest('get_property', self,
+                                                propertyName = name)
+        except EnvironmentError:
             # Failed to retrieve the attribute.
             raise AttributeError(name)
 
@@ -528,9 +530,10 @@ class BrowserObject:
         under the hood.  Following the JavaScript convention, we treat
         obj['attr'] almost the same as obj.attr. """
 
-        value = self.__runner.scriptRequest('get_property', self,
-                                            propertyName = str(key))
-        if value is Null:
+        try:
+            value = self.__runner.scriptRequest('get_property', self,
+                                                propertyName = str(key))
+        except EnvironmentError:
             # Failed to retrieve the property.  We return IndexError
             # for numeric keys so we can properly support Python's
             # iterators, but we return KeyError for string keys to