Revision: 19497
          
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=19497
Author:   campbellbarton
Date:     2009-04-02 07:38:05 +0200 (Thu, 02 Apr 2009)

Log Message:
-----------
Added getitem/setitem access for KX_GameObject
ob.someProp = 10
can now be...
ob["someProp"] = 10

For simple get/set test with an objects 10 properties, this is ~30% faster.

Though I like the attribute access, its slower because it needs to lookup BGE 
attributes and methods (for parent classes as well as KX_GameObject class).

This could also be an advantage if there are collisions between new attributes 
added for 2.49 and existing properties a game uses.

Made some other small optimizations,
- Getting and setting property can use const char* as well as STR_String 
(avoids making new STR_Strings just to do the lookup).
- CValue::SetPropertiesModified() and CValue::SetPropertiesModified(), were 
looping through all items in the std::map, advancing from the beginning each 
time.

Modified Paths:
--------------
    trunk/blender/source/gameengine/Expressions/Value.cpp
    trunk/blender/source/gameengine/Expressions/Value.h
    trunk/blender/source/gameengine/Ketsji/KX_GameObject.cpp
    trunk/blender/source/gameengine/Ketsji/KX_GameObject.h

Modified: trunk/blender/source/gameengine/Expressions/Value.cpp
===================================================================
--- trunk/blender/source/gameengine/Expressions/Value.cpp       2009-04-02 
01:39:33 UTC (rev 19496)
+++ trunk/blender/source/gameengine/Expressions/Value.cpp       2009-04-02 
05:38:05 UTC (rev 19497)
@@ -320,56 +320,71 @@
 //
 void CValue::SetProperty(const STR_String & name,CValue* ioProperty)
 {
-       // Check if somebody is setting an empty property
        if (ioProperty==NULL)
-       {
+       {       // Check if somebody is setting an empty property
                trace("Warning:trying to set empty property!");
                return;
        }
 
-       // Make sure we have a property array
-       if (m_pNamedPropertyArray == NULL)
+       if (m_pNamedPropertyArray)
+       {       // Try to replace property (if so -> exit as soon as we 
replaced it)
+               CValue* oldval = (*m_pNamedPropertyArray)[name];
+               if (oldval)
+                       oldval->Release();
+       }
+       else { // Make sure we have a property array
                m_pNamedPropertyArray = new std::map<STR_String,CValue *>;
-
-       // Try to replace property (if so -> exit as soon as we replaced it)
-       CValue* oldval = (*m_pNamedPropertyArray)[name];
-       if (oldval)
-       {
-               oldval->Release();
        }
        
        // Add property at end of array
        (*m_pNamedPropertyArray)[name] = 
ioProperty->AddRef();//->Add(ioProperty);
 }
 
+void CValue::SetProperty(const char* name,CValue* ioProperty)
+{
+       if (ioProperty==NULL)
+       {       // Check if somebody is setting an empty property
+               trace("Warning:trying to set empty property!");
+               return;
+       }
 
+       if (m_pNamedPropertyArray)
+       {       // Try to replace property (if so -> exit as soon as we 
replaced it)
+               CValue* oldval = (*m_pNamedPropertyArray)[name];
+               if (oldval)
+                       oldval->Release();
+       }
+       else { // Make sure we have a property array
+               m_pNamedPropertyArray = new std::map<STR_String,CValue *>;
+       }
+       
+       // Add property at end of array
+       (*m_pNamedPropertyArray)[name] = 
ioProperty->AddRef();//->Add(ioProperty);
+}
 
 //
 // Get pointer to a property with name <inName>, returns NULL if there is no 
property named <inName>
 //
 CValue* CValue::GetProperty(const STR_String & inName)
 {
-       // Check properties, as soon as we found it -> Return a pointer to the 
property
-       CValue* result = NULL;
-       if (m_pNamedPropertyArray)
-       {
-               std::map<STR_String,CValue*>::iterator it = 
(*m_pNamedPropertyArray).find(inName);
-               if (!( it==m_pNamedPropertyArray->end()))
-               {
-                       result = (*it).second;
-               }
+       if (m_pNamedPropertyArray) {
+               std::map<STR_String,CValue*>::iterator it = 
m_pNamedPropertyArray->find(inName);
+               if (it != m_pNamedPropertyArray->end())
+                       return (*it).second;
+       }
+       return NULL;
+}
 
+CValue* CValue::GetProperty(const char *inName)
+{
+       if (m_pNamedPropertyArray) {
+               std::map<STR_String,CValue*>::iterator it = 
m_pNamedPropertyArray->find(inName);
+               if (it != m_pNamedPropertyArray->end())
+                       return (*it).second;
        }
-               //for (int i=0; i<m_pValuePropertyArray->size(); i++)
-               //      if ((*m_pValuePropertyArray)[i]->GetName() == inName)
-               //              return (*m_pValuePropertyArray)[i];
-       
-       // Did not find property with name <inName>, return NULL property 
pointer
-       return result;
+       return NULL;
 }
 
-
-
 //
 // Get text description of property with name <inName>, returns an empty 
string if there is no property named <inName>
 //
@@ -396,26 +411,20 @@
 //
 // Remove the property named <inName>, returns true if the property was 
succesfully removed, false if property was not found or could not be removed
 //
-bool CValue::RemoveProperty(const STR_String & inName)
+bool CValue::RemoveProperty(const char *inName)
 {
        // Check if there are properties at all which can be removed
-       if (m_pNamedPropertyArray) {    
-               CValue* val = GetProperty(inName);
-               if (NULL != val) 
+       if (m_pNamedPropertyArray)
+       {
+               std::map<STR_String,CValue*>::iterator it = 
m_pNamedPropertyArray->find(inName);
+               if (it != m_pNamedPropertyArray->end())
                {
-                       val->Release();
-                       m_pNamedPropertyArray->erase(inName);
+                       ((*it).second)->Release();
+                       m_pNamedPropertyArray->erase(it);
                        return true;
                }
-       } 
+       }
        
-       char err[128];
-       if (m_pNamedPropertyArray)
-               sprintf(err, "attribute \"%s\" dosnt exist", inName.ReadPtr());
-       else
-               sprintf(err, "attribute \"%s\" dosnt exist (no property 
array)", inName.ReadPtr());
-       
-       PyErr_SetString(PyExc_AttributeError, err);
        return false;
 }
 
@@ -426,8 +435,8 @@
 {
        vector<STR_String> result;
        if(!m_pNamedPropertyArray) return result;
-       for ( std::map<STR_String,CValue*>::iterator it = 
m_pNamedPropertyArray->begin();
-       !(it == m_pNamedPropertyArray->end());it++)
+       std::map<STR_String,CValue*>::iterator it;
+       for (it= m_pNamedPropertyArray->begin(); (it != 
m_pNamedPropertyArray->end()); it++)
        {
                result.push_back((*it).first);
        }
@@ -444,8 +453,8 @@
                return;
 
        // Remove all properties
-       for ( std::map<STR_String,CValue*>::iterator it = 
m_pNamedPropertyArray->begin();
-       !(it == m_pNamedPropertyArray->end());it++)
+       std::map<STR_String,CValue*>::iterator it;
+       for (it= m_pNamedPropertyArray->begin();(it != 
m_pNamedPropertyArray->end()); it++)
        {
                CValue* tmpval = (*it).second;
                //STR_String name = (*it).first;
@@ -464,9 +473,11 @@
 //
 void CValue::SetPropertiesModified(bool inModified)
 {
-       int numprops = GetPropertyCount();
-       for (int i=0; i<numprops; i++)
-               GetProperty(i)->SetModified(inModified);
+       if(!m_pNamedPropertyArray) return;
+       std::map<STR_String,CValue*>::iterator it;
+       
+       for (it= m_pNamedPropertyArray->begin();(it != 
m_pNamedPropertyArray->end()); it++)
+               ((*it).second)->SetModified(inModified);
 }
 
 
@@ -476,11 +487,13 @@
 //
 bool CValue::IsAnyPropertyModified()
 {
-       int numprops = GetPropertyCount();
-       for (int i=0;i<numprops;i++)
-               if (GetProperty(i)->IsModified())
+       if(!m_pNamedPropertyArray) return false;
+       std::map<STR_String,CValue*>::iterator it;
+       
+       for (it= m_pNamedPropertyArray->begin();(it != 
m_pNamedPropertyArray->end()); it++)
+               if (((*it).second)->IsModified())
                        return true;
-
+       
        return false;
 }
 
@@ -489,7 +502,6 @@
 //
 // Get property number <inIndex>
 //
-
 CValue* CValue::GetProperty(int inIndex)
 {
 
@@ -498,8 +510,8 @@
 
        if (m_pNamedPropertyArray)
        {
-               for ( std::map<STR_String,CValue*>::iterator it = 
m_pNamedPropertyArray->begin();
-               !(it == m_pNamedPropertyArray->end());it++)
+               std::map<STR_String,CValue*>::iterator it;
+               for (it= m_pNamedPropertyArray->begin(); (it != 
m_pNamedPropertyArray->end()); it++)
                {
                        if (count++==inIndex)
                        {
@@ -535,8 +547,8 @@
        if (m_pNamedPropertyArray)
        {
                replica->m_pNamedPropertyArray=NULL;
-               for ( std::map<STR_String,CValue*>::iterator it = 
m_pNamedPropertyArray->begin();
-               !(it == m_pNamedPropertyArray->end());it++)
+               std::map<STR_String,CValue*>::iterator it;
+               for (it= m_pNamedPropertyArray->begin(); (it != 
m_pNamedPropertyArray->end()); it++)
                {
                        CValue *val = (*it).second->GetReplica();
                        replica->SetProperty((*it).first,val);
@@ -687,28 +699,15 @@
 
 PyObject*      CValue::_getattr(const char *attr)
 {
-       CValue* resultattr = FindIdentifier(STR_String(attr));
-       STR_String text;
+       CValue* resultattr = GetProperty(attr);
        if (resultattr)
        {
-               if (resultattr->IsError())
-               {
-                       resultattr->Release();
-               } else
-               {
-                       // to avoid some compare problems, return a real 
pythonthing
-                       PyObject* pyconvert = 
resultattr->ConvertValueToPython();
-                       if (pyconvert)
-                       {
-                               resultattr->Release();
-                               return pyconvert;
-                       } else
-                       {
-                               // also check if it's already in 
pythoninterpreter!
-                               return resultattr;
-                       }
-                       
-               }
+               PyObject* pyconvert = resultattr->ConvertValueToPython();
+       
+               if (pyconvert)
+                       return pyconvert;
+               else
+                       return resultattr; // also check if it's already in 
pythoninterpreter!
        }
        _getattr_up(PyObjectPlus);
 }
@@ -774,26 +773,25 @@
 
 int    CValue::_delattr(const char *attr)
 {
-       if (!RemoveProperty(STR_String(attr))) /* sets error */
-               return 1;
-       return 0;
+       if (RemoveProperty(STR_String(attr)))
+               return 0;
+       
+       PyErr_Format(PyExc_AttributeError, "attribute \"%s\" dosnt exist", 
attr);
+       return 1;
 }
 
-int    CValue::_setattr(const char *attr,PyObject* pyobj)
+int    CValue::_setattr(const char *attr, PyObject* pyobj)
 {
        CValue* vallie = ConvertPythonToValue(pyobj);
        if (vallie)
        {
-               STR_String attr_str = attr;
-               CValue* oldprop = GetProperty(attr_str);
+               CValue* oldprop = GetProperty(attr);
                
                if (oldprop)
-               {
                        oldprop->SetValue(vallie);
-               } else
-               {
-                       SetProperty(attr_str, vallie);
-               }
+               else
+                       SetProperty(attr, vallie);
+               
                vallie->Release();
        } else
        {
@@ -811,8 +809,8 @@
        
        if (m_pNamedPropertyArray)
        {
-               for ( std::map<STR_String,CValue*>::iterator it = 
m_pNamedPropertyArray->begin();
-               !(it == m_pNamedPropertyArray->end());it++)
+               std::map<STR_String,CValue*>::iterator it;
+               for (it= m_pNamedPropertyArray->begin(); (it != 
m_pNamedPropertyArray->end()); it++)
                {
                        pystr = PyString_FromString( (*it).first );
                        PyList_Append(pylist, pystr);

Modified: trunk/blender/source/gameengine/Expressions/Value.h
===================================================================
--- trunk/blender/source/gameengine/Expressions/Value.h 2009-04-02 01:39:33 UTC 
(rev 19496)
+++ trunk/blender/source/gameengine/Expressions/Value.h 2009-04-02 05:38:05 UTC 
(rev 19497)
@@ -283,10 +283,12 @@
 
        /// Property Management
        virtual void            SetProperty(const STR_String& name,CValue* 
ioProperty);                                         // Set property 
<ioProperty>, overwrites and releases a previous property with the same name if 
needed
-       virtual CValue*         GetProperty(const STR_String & inName);         
                                        // Get pointer to a property with name 
<inName>, returns NULL if there is no property named <inName>
+       virtual void            SetProperty(const char* name,CValue* 
ioProperty);
+       virtual CValue*         GetProperty(const char* inName);                
                                        // Get pointer to a property with name 
<inName>, returns NULL if there is no property named <inName>
+       virtual CValue*         GetProperty(const STR_String & inName);
        STR_String                      GetPropertyText(const STR_String & 
inName,const STR_String& deftext="");                                           
     // Get text description of property with name <inName>, returns an empty 
string if there is no property named <inName>
        float                           GetPropertyNumber(const STR_String& 
inName,float defnumber);
-       virtual bool            RemoveProperty(const STR_String & inName);      
                                        // Remove the property named <inName>, 
returns true if the property was succesfully removed, false if property was not 
found or could not be removed

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to