Difference between revisions of "Python TipsAndTricks"

From Valve Developer Community
Jump to: navigation, search
Line 4: Line 4:
  
 
If you add no_init to a class define then that class cant be constructed via python. This is good for classes like players, weapons and entitys that have a special method of constuction.
 
If you add no_init to a class define then that class cant be constructed via python. This is good for classes like players, weapons and entitys that have a special method of constuction.
 
+
<br>
 
Example:
 
Example:
 
<source lang=cpp>
 
<source lang=cpp>
Line 10: Line 10:
 
</source>
 
</source>
  
<br><br>
+
<br>
  
 
Alot of classes in Source are non copyable (i.e. you use pointers to reference them not stack objects) and thus you will need to state that they are non copyable otherwise strange compile errors or run time errors occur. This doesnt mean you cant make multiplie objects in python that point to this, just that boost wont try and copy it in the python bindings.
 
Alot of classes in Source are non copyable (i.e. you use pointers to reference them not stack objects) and thus you will need to state that they are non copyable otherwise strange compile errors or run time errors occur. This doesnt mean you cant make multiplie objects in python that point to this, just that boost wont try and copy it in the python bindings.
Line 23: Line 23:
 
When a function (or member function) your rapping returns a pointer you will have to tell boost how to handle it. If your return a new object, boost needs to know to hang onto and if you return a pointer to an existing object you have to boost to just use it. If you do the latter your python classes shouldnt hold on to the object as boost only ensures its valid for the lifetime of the function call.
 
When a function (or member function) your rapping returns a pointer you will have to tell boost how to handle it. If your return a new object, boost needs to know to hang onto and if you return a pointer to an existing object you have to boost to just use it. If you do the latter your python classes shouldnt hold on to the object as boost only ensures its valid for the lifetime of the function call.
  
 
+
<br>
 
Example New Object:
 
Example New Object:
 
<source lang=cpp>
 
<source lang=cpp>
Line 34: Line 34:
 
</source>
 
</source>
  
 
+
<br>
 
Example Existing Object:
 
Example Existing Object:
 
<source lang=cpp>
 
<source lang=cpp>
Line 48: Line 48:
  
 
If your passing a pointer to a python function call and you marked the class as non copyable (see above) you will need to wrap it in the function ptr().
 
If your passing a pointer to a python function call and you marked the class as non copyable (see above) you will need to wrap it in the function ptr().
 
+
<br>
 
Example:
 
Example:
 
<source lang=cpp>
 
<source lang=cpp>

Revision as of 02:37, 6 September 2009

Some tips to help you out

Class Defines

If you add no_init to a class define then that class cant be constructed via python. This is good for classes like players, weapons and entitys that have a special method of constuction.
Example:

bp::class_< NoNew >("CantMakeMe", bp::no_init);


Alot of classes in Source are non copyable (i.e. you use pointers to reference them not stack objects) and thus you will need to state that they are non copyable otherwise strange compile errors or run time errors occur. This doesnt mean you cant make multiplie objects in python that point to this, just that boost wont try and copy it in the python bindings.

bp::class_< NoCopy, boost::noncopyable >("BoostCantCopyMe", bp::no_init);


Function Defines

When a function (or member function) your rapping returns a pointer you will have to tell boost how to handle it. If your return a new object, boost needs to know to hang onto and if you return a pointer to an existing object you have to boost to just use it. If you do the latter your python classes shouldnt hold on to the object as boost only ensures its valid for the lifetime of the function call.


Example New Object:

MyClass* pyGetNewClass()
{
   return new MyClass();
}

bp::def("NewClass", pyGetNewClass, bp::return_value_policy<bp::manage_new_object>()); //callee needs to delete it


Example Existing Object:

CBasePlayer* pyGetPlayerByIndex(int index)
{
   return UTIL_PlayerByIndex(index);
}

bp::def("GetPlayerByIndex", pyGetPlayerByIndex, bp::return_value_policy<bp::reference_existing_object>()); //callee doesnt need to delete it

Function Calls

If your passing a pointer to a python function call and you marked the class as non copyable (see above) you will need to wrap it in the function ptr().
Example:

virtual void OnPlayerKilled(CBasePlayer *pVictim, CBasePlayer *pKiller, CBaseEntity *pWeapon)
{
	this->get_override("OnPlayerKilled")(bp::ptr(pVictim), bp::ptr(pKiller), bp::ptr(pWeapon));
}