* Moved the code to retrieve an object by name to a seperate function in
authorMichel Selten <michel@mselten.demon.nl>
Tue, 18 Mar 2003 20:21:26 +0000 (20:21 +0000)
committerMichel Selten <michel@mselten.demon.nl>
Tue, 18 Mar 2003 20:21:26 +0000 (20:21 +0000)
  gen_utils.c (GetObjectByName).
* Blender.link, Blender.bylink and Blender.event should work. Somehow the
  only event coming through now is only REDRAW.
* Added include path to /intern/guardedalloc

Michel

source/blender/python/BPY_interface.c
source/blender/python/api2_2x/Blender.c
source/blender/python/api2_2x/Object.c
source/blender/python/api2_2x/gen_utils.c
source/blender/python/api2_2x/gen_utils.h
source/blender/python/api2_2x/interface.c
source/blender/python/api2_2x/interface.h

index 759bbcce885cf093ae0a796618f77a01dd7b5f11..ce63eace5011e48fc19d2a164feff4fbccad1b7b 100644 (file)
@@ -34,6 +34,8 @@
 #include <Python.h>
 #include <stdio.h>
 
+#include <MEM_guardedalloc.h>
+
 #include <BKE_text.h>
 #include <DNA_ID.h>
 #include <DNA_scriptlink_types.h>
@@ -43,6 +45,9 @@
 #include <BPY_extern.h>
 
 #include "api2_2x/interface.h"
+/* unfortunately the following #include is needed because of some missing */
+/* functionality in BKE/DNA */
+/* #include "api2_2x/gen_utils.h" */
 
 /*****************************************************************************/
 /* Structure definitions                                                     */
@@ -63,6 +68,8 @@ ScriptError g_script_error;
 /*****************************************************************************/
 PyObject * RunPython(Text *text, PyObject *globaldict);
 char *     GetName(Text *text);
+PyObject * CreateGlobalDictionary (void);
+void       ReleaseGlobalDictionary (PyObject * dict);
 
 /*****************************************************************************/
 /* Description: This function will initialise Python and all the implemented */
@@ -165,68 +172,41 @@ void BPY_do_all_scripts(short event)
        return;
 }
 
-/*
- * Description: Execute a Python script when an event occurs. The following
- *              events are possible: frame changed, load script and redraw.
- *              Only events happening to one of the following object types are
- *              handled: Object, Lamp, Camera, Material, World and Scene
- * Notes:       The call to BLO_findstruct_offset needs to be removed.
- *              Somehow the object triggered by the event has to be retrieved.
- */   
+/*****************************************************************************/
+/* Description: Execute a Python script when an event occurs. The following  */
+/*              events are possible: frame changed, load script and redraw.  */
+/*              Only events happening to one of the following object types   */
+/*              are handled: Object, Lamp, Camera, Material, World and       */
+/*              Scene.                                                       */
+/*****************************************************************************/
 void BPY_do_pyscript(struct ID *id, short event)
 {
-       int            obj_id;
-       char           structname[10];
-       int            offset;
-       ScriptLink   * scriptlink;
+       ScriptLink     * scriptlink;
+       int              index;
+       PyObject       * dict;
 
        printf ("In BPY_do_pyscript(id=%s, event=%d)\n",id->name, event);
 
-       /* First get the object type that the script is linked to. */
-       obj_id = MAKE_ID2(id->name[0], id->name[1]);
-       switch (obj_id)
-       {
-               case ID_OB:
-                       sprintf (structname, "Object");
-                       break;
-               case ID_LA:
-                       sprintf (structname, "Lamp");
-                       break;
-               case ID_CA:
-                       sprintf (structname, "Camera");
-                       break;
-               case ID_MA:
-                       sprintf (structname, "Material");
-                       break;
-               case ID_WO:
-                       sprintf (structname, "World");
-                       break;
-               case ID_SCE:
-                       sprintf (structname, "Scene");
-                       break;
-               default:
-                       /* TODO: Do we need to generate a nice error message here? */
-                       return;
-       }
+       scriptlink = setScriptLinks (id, event);
 
-/* TODO: Replace the following piece of code. See the Notes for info. */
-       /* Check if a script is provided */
-       offset = BLO_findstruct_offset (structname, "scriptlink");
-       if (offset < 0)
+       if (scriptlink == NULL)
        {
-               printf ("Internal error, unable to find script link\n");
                return;
        }
-       scriptlink = (ScriptLink*) (((char*)id) + offset);
 
-       if (!scriptlink->totscript)
+       for (index=0 ; index<scriptlink->totscript ; index++)
        {
-               /* no script provided */
-               return;
+               printf ("scriptnr: %d\tevent=%d, flag[index]=%d\n", index,
+                               event, scriptlink->flag[index]);
+               if ((scriptlink->flag[index] == event) &&
+                   (scriptlink->scripts[index]!=NULL))
+               {
+                       dict = CreateGlobalDictionary();
+                       RunPython ((Text*) scriptlink->scripts[index], dict);
+                       ReleaseGlobalDictionary (dict);
+               }
        }
-       
-       /* Get all links from blender and set them in the Python environment */
-       setScriptLinks (id, event);
+
        return;
 }
 
@@ -324,3 +304,24 @@ char * GetName(Text *text)
        return (text->id.name+2);
 }
 
+/*****************************************************************************/
+/* Description: This function creates a new Python dictionary object.        */
+/*****************************************************************************/
+PyObject * CreateGlobalDictionary (void)
+{
+       PyObject *dict = PyDict_New();
+       PyDict_SetItemString (dict, "__builtins__", PyEval_GetBuiltins());
+       PyDict_SetItemString (dict, "__name__", PyString_FromString("__main__"));
+
+       return (dict);
+}
+
+/*****************************************************************************/
+/* Description: This function deletes a given Python dictionary object.      */
+/*****************************************************************************/
+void ReleaseGlobalDictionary (PyObject * dict)
+{
+       PyDict_Clear (dict);
+       Py_DECREF (dict);               /* Release dictionary. */
+}
+
index fc67775f395cb10d97460d9b55c5e112784a0d97..d099d9ba3f751323e0716c7fd27245794646ca10 100644 (file)
@@ -239,6 +239,7 @@ void initBlender (void)
        module = Py_InitModule3("Blender", Blender_methods, NULL);
 
        dict = PyModule_GetDict (module);
+       g_blenderdict = dict;
        PyDict_SetItemString (dict, "Object", initObject());
 }
 
index 263dabdc5582d666688b43810570ffce8068e843..cc30827f235acf8b4a62e75269dde79da8533149 100644 (file)
@@ -131,7 +131,7 @@ PyObject *Object_Get(PyObject *self, PyObject *args)
 {
        char            * name;
        PyObject        * arg;
-       struct Object   * obj_iter;
+       struct Object   * object;
        BlenObject      * blen_object;
 
        printf ("In Object_Get()\n");
@@ -148,31 +148,18 @@ PyObject *Object_Get(PyObject *self, PyObject *args)
                return (PythonReturnErrorObject (PyExc_AttributeError,
                                        "expected string argument"));
        }
-       name = PyString_AsString (arg);
-
-       /* Use the name to search for the object requested. */
-       /* Should this lookup be a new function in blenkernel/intern/object.c? */
-       blen_object = NULL;
-       obj_iter = G.main->object.first;
-       while ((obj_iter) && (blen_object == NULL))
-       {
-               if (StringEqual (name, GetIdName (&(obj_iter->id))))
-               {
-                       blen_object = (BlenObject*)PyObject_NEW
-                               (BlenObject,
-                                &object_type);
 
-                       blen_object->object = obj_iter;
-               }
-               obj_iter = obj_iter->id.next;
-       }
+       name = PyString_AsString (arg);
+       object = GetObjectByName (name);
 
-       if (blen_object == NULL)
+       if (object == NULL)
        {
                /* No object exists with the name specified in the argument name. */
                return (PythonReturnErrorObject (PyExc_AttributeError,
-                                       "expected string argument"));
+                                       "Unknown object specified."));
        }
+       blen_object = (BlenObject*)PyObject_NEW (BlenObject, &object_type); 
+       blen_object->object = object;
 
        return ((PyObject*)blen_object);
 }
index 32c3bb660e9738b244145ef9f2277ac77c96c242..f44bc7f95144baf9879484577993fa08d2ae87c0 100644 (file)
 #include <string.h>
 #include <Python.h>
 
+#include <BKE_global.h>
+#include <BKE_main.h>
 #include <DNA_ID.h>
+#include <DNA_object_types.h>
 #include <DNA_scriptlink_types.h>
 
+/*****************************************************************************/
+/* Description: This function returns true if both given strings are equal,  */
+/*              otherwise it returns false.                                  */
+/*****************************************************************************/
 int StringEqual (char * string1, char * string2)
 {
        return (strcmp(string1, string2)==0);
 }
 
+/*****************************************************************************/
+/* Description: This function returns the name of the given ID struct        */
+/*              without the Object type identifying characters prepended.    */
+/*****************************************************************************/
 char * GetIdName (ID *id)
 {
        return ((id->name)+2);
 }
 
+/*****************************************************************************/
+/* Description: This function sets an internal string with the given type    */
+/*              and error_msg arguments.                                     */
+/*****************************************************************************/
 PyObject * PythonReturnErrorObject (PyObject * type, char * error_msg)
 {
        PyErr_SetString (type, error_msg);
        return (NULL);
 }
 
+/*****************************************************************************/
+/* Description: This function increments the reference count of the given    */
+/*              Python object.                                               */
+/*****************************************************************************/
 PyObject * PythonIncRef (PyObject *object)
 {
        Py_INCREF (object);
        return (object);
 }
 
+/*****************************************************************************/
+/* Description: This function maps the event identifier to a string.         */
+/*****************************************************************************/
 char * event_to_name(short event)
 {
        switch (event)
@@ -73,3 +95,29 @@ char * event_to_name(short event)
        }
 }      
 
+/*****************************************************************************/
+/* Description: Returns the object with the name specified by the argument   */
+/*              name. Note that the calling function has to remove the first */
+/*              two characters of the object name. These two characters      */
+/*              specify the type of the object (OB, ME, WO, ...)             */
+/*              The function will return NULL when no object with the given  */
+/*              name is found.                                               */
+/*****************************************************************************/
+struct Object * GetObjectByName (char * name)
+{
+       Object  * obj_iter;
+
+       obj_iter = G.main->object.first;
+       while (obj_iter)
+       {
+               if (StringEqual (name, GetIdName (&(obj_iter->id))))
+               {
+                       return (obj_iter);
+               }
+               obj_iter = obj_iter->id.next;
+       }
+
+       /* There is no object with the given name */
+       return (NULL);
+}
+
index ab41cf9d6177afd748dd0c4f2b62d712d0ab248c..038c7f814ad44d4f72a084596d46ca4d3e0c6362 100644 (file)
@@ -39,3 +39,8 @@ PyObject * PythonReturnErrorObject (PyObject * type, char * error_msg);
 PyObject * PythonIncRef (PyObject *object);
 char * event_to_name(short event);
 
+/* The following functions may need to be moved to the respective BKE or */
+/* DNA modules. */
+
+struct Object * GetObjectByName (char * name);
+
index 4d5d5962c6339fad3edf8027bb8e72e98ace3606..671160c000e44f80f3476d16bc5c72a33fd232b0 100644 (file)
@@ -31,6 +31,8 @@
 
 #include <stdio.h>
 
+#include <Python.h>
+
 #include <BKE_global.h>
 #include <BKE_main.h>
 #include <DNA_ID.h>
 #include <DNA_material_types.h>
 #include <DNA_object_types.h>
 #include <DNA_scene_types.h>
+#include <DNA_scriptlink_types.h>
 #include <DNA_world_types.h>
 
-#include "datablock.h"
 #include "gen_utils.h"
 #include "modules.h"
 
 void initBlenderApi2_2x (void)
 {
        printf ("initBlenderApi2_2x\n");
+       g_blenderdict = NULL;
        initBlender ();
 }
 
-void setScriptLinks(ID *id, short event)
+ScriptLink * setScriptLinks(ID *id, short event)
 {
-       PyObject *link;
-       int       obj_id;
-
-       printf ("In setScriptLinks (id=?, event=%d)\n", event);
-       if (!g_blenderdict)
-       {
-               /* Not initialized yet. This can happen at first file load. */
-               return;
-       }
+       ScriptLink  * scriptlink;
+       PyObject    * link;
+       Object      * object;
+       int           obj_id;
 
        obj_id = MAKE_ID2 (id->name[0], id->name[1]);
-       if (obj_id == ID_SCE)
-       {
-               Py_INCREF(Py_None);
-               link = Py_None;
-       }
-       else
+       printf ("In setScriptLinks (id=%s, event=%d)\n",id->name, event);
+
+       switch (obj_id)
        {
-               link = Py_None;
-               switch (obj_id)
-               {
-                       case ID_OB:
-                               /* Create a new datablock of type: Object */
-                               /*
-                               link = ObjectCreatePyObject (G.main->object);
-                               */
-                               break;
-                       case ID_ME:
-                               /* Create a new datablock of type: Mesh */
-                               break;
-                       case ID_LA:
-                               /* Create a new datablock of type: Lamp */
-                               break;
-                       case ID_CA:
-                               /* Create a new datablock of type: Camera */
-                               break;
-                       case ID_MA:
-                               /* Create a new datablock of type: Material */
-                               break;
-                       case ID_WO:
-                               /* Create a new datablock of type: World */
-                               break;
-                       case ID_IP:
-                               /* Create a new datablock of type: Ipo */
-                               break;
-                       case ID_IM:
-                               /* Create a new datablock of type: Image */
-                               break;
-                       case ID_TXT:
-                               /* Create a new datablock of type: Text */
-                               break;
-                       default:
-                               PythonReturnErrorObject (PyExc_SystemError,
-                                                       "Unable to create block for data");
-                               return;
-               }
-               /* link = DataBlockFromID(id); */
+               case ID_OB:
+                       object = GetObjectByName (GetIdName (id));
+                       if (object == NULL)
+                       {
+                               return NULL;
+                       }
+                       link = ObjectCreatePyObject (object);
+                       scriptlink = &(object->scriptlink);
+                       break;
+               case ID_LA:
+                       scriptlink = NULL;
+                       Py_INCREF(Py_None);
+                       link = Py_None;
+                       break;
+               case ID_CA:
+                       scriptlink = NULL;
+                       Py_INCREF(Py_None);
+                       link = Py_None;
+                       break;
+               case ID_MA:
+                       scriptlink = NULL;
+                       Py_INCREF(Py_None);
+                       link = Py_None;
+                       break;
+               case ID_WO:
+                       scriptlink = NULL;
+                       Py_INCREF(Py_None);
+                       link = Py_None;
+                       break;
+               case ID_SCE:
+                       scriptlink = NULL;
+                       Py_INCREF(Py_None);
+                       link = Py_None;
+                       break;
+               default:
+                       Py_INCREF(Py_None);
+                       link = Py_None;
+                       return NULL;
        }
 
-       if (!link)
+       if (scriptlink == NULL)
        {
+               /* This is probably not an internal error anymore :)
+TODO: Check this
                printf ("Internal error, unable to create PyBlock for script link\n");
-               printf ("This is a bug; please report to bugs@blender.nl");
+               */
                Py_INCREF(Py_False);
                PyDict_SetItemString(g_blenderdict, "bylink", Py_False);
-               return;
-       } else {
+               return NULL;
+       }
+       else
+       {
                Py_INCREF(Py_True);
                PyDict_SetItemString(g_blenderdict, "bylink", Py_True);
        }
@@ -127,4 +125,6 @@ void setScriptLinks(ID *id, short event)
        PyDict_SetItemString(g_blenderdict, "link", link);
        PyDict_SetItemString(g_blenderdict, "event",
                        Py_BuildValue("s", event_to_name(event)));
+
+       return (scriptlink);
 }
index 3495da8790c14efa7c9bcac16f90d9f9d026e5d1..e61e6c2d2dceaaefd0999ef2322ddcc735cee2dd 100644 (file)
@@ -32,4 +32,4 @@
 #include <DNA_ID.h>
 
 void initBlenderApi2_2x (void);
-void setScriptLinks(ID *id, short event);
+ScriptLink * setScriptLinks(ID *id, short event);