Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

4968 lines
146 KiB

  1. //========== Copyright � 2008, Valve Corporation, All rights reserved. ========
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================
  6. #ifdef PLATFORM
  7. #define __PLATFORM PLATFORM
  8. #undef PLATFORM
  9. #endif
  10. #ifdef _DEBUG
  11. #undef _DEBUG // don't want a debug python header!
  12. #include "Python.h" // include python before any standard headers
  13. #define _DEBUG
  14. #else
  15. #include "Python.h"
  16. #endif // _DEBUG
  17. #ifdef __PLATFORM
  18. #undef PLATFORM
  19. #define PLATFORM __PLATFORM
  20. #undef __PLATFORM
  21. #endif
  22. #include <stdio.h>
  23. #include <io.h>
  24. #include <conio.h>
  25. #include <direct.h>
  26. #define _HAS_EXCEPTIONS 0
  27. #include <string>
  28. #include "platform.h"
  29. #include "tier1/utlmap.h"
  30. #include "datamap.h"
  31. #include "tier1/functors.h"
  32. #include "tier1/utlvector.h"
  33. #include "tier1/utlhash.h"
  34. #include "tier1/utlbuffer.h"
  35. #include "tier1/fmtstr.h"
  36. #include "tier1/convar.h"
  37. #include "mathlib/vector.h"
  38. #include "vstdlib/random.h"
  39. #include "vscript/ivscript.h"
  40. // #include <crtdbg.h> // DEBUG: memory overwrites
  41. #include "memdbgon.h"
  42. /*
  43. Implementation of the IVSCRIPT interface for Python 2.5
  44. -------------------------------------------------------
  45. The IVSCRIPT interface bridges the Python virtual machine (python25.dll), and a
  46. set of server-side systems and objects, such as CBaseEntity. Although the ivscript
  47. interface is not changed for python, the python implementation works quite differently
  48. from the Squirrel implementation from a programming standpoint.
  49. Squirrel ivscript associates instance data with an entity's
  50. code file, and each entity has its own copy of the code:
  51. -----------------------------------------------------
  52. The current implementation of ivscript that interfaces with the Squirrel virtual machine
  53. assumes that every map that spawns may cause one or more script files to load, compile and
  54. execute. In addition, every entity spawned within a map may also cause one or more
  55. script files to load, compile and execute. An entity's script code and data is fully isolated from other entities.
  56. Within an entity's code file, script variables such as 'self' and 'player'are auto-
  57. defined, and they refer to the entity that invokes the code, the player etc.
  58. This scheme creates an execution model with per-entity scope, and a global scope common
  59. to all entities. It also means that every entity keeps a unique, compiled copy of its code in memory.
  60. When a map is re/loaded, all code is flushed, and the Squirrel interpreter shuts down and restarts. No code or data persists
  61. beyond a level load or restart, and all code associated with a new map must be newly loaded and compiled.
  62. Python ivscript associates instance data with the entity itself,
  63. and all entities share the same compiled code:
  64. -------------------------------------------------------
  65. Python has a global scope, which contains a single compiled instance of each loaded code module.
  66. When a code module is loaded, it is compiled and executed exactly once. (Note that 'execution' of a
  67. loaded module creates module-global variables, and creates functions and classes).
  68. Any variables defined within a module are global to functions/classes defined in the module, but not to other modules.
  69. In other words, code defined within the module shares only the module's data scope. However, code can call
  70. into another module, and must simply refer to any 'foreign' module data through explicit use of the module name.
  71. Within a module, a class definition also creates a scope, as do method definitions with classes.
  72. Since all module-defined data is shared by all code within the module, we must associate instance
  73. data with the entity instance, instead of the module (as is done in the Squirrel implementation).
  74. This means that to preserve data associated with an entity, we pass the entity pointer as 'self' to all
  75. module functions that need to access instance data as the first parameter. In python, we have very
  76. simple ways to get and set data on an instance, including defining new data at runtime.
  77. Unlike Squirrel ivscript, the Python interpreter is not shut down when a new map is loaded or
  78. when the game is restarted. This means that more compiled code is shared between maps
  79. as new modules are imported. (NOTE: It also means that by the end of a game,
  80. all unique script code modules could be simultaneously loaded in memory. Compiled code is
  81. relatively small for full-featured modules- perhaps 10-20k. 20 modules would be a lot of
  82. script code for a game - so perhaps 200-400k total. To manage large amounts of in-memory code,
  83. we may need a mechanism for manually discarding
  84. modules from memory that we know to be unique to a particulary map or entity instance.)
  85. Hammer entity interface:
  86. -----------------------
  87. Rule 1: A python module should contain functionality corresponding to a particular type of entity. For instance,
  88. you might have a CameraMan.py module, a SpaceMarine.py module and a Medic.py module, each assigned as the ActivateScript
  89. for a camera, spacemarine and medic entity types you've placed in hammer.
  90. The 'ActivateScript' field of an entity may contain only one python module name, such as 'SpaceMarine.py'.
  91. This module will be loaded and run the first time an entity is spawned with this module listed as
  92. its ActivateScript. This module may contain definitions of various Valve callbacks. Each callback
  93. will be passed the entity instance as the first parameter, such as:
  94. ScriptThinkFunction( entity ) - called every tenth of a second during entity think
  95. OnDeath( entity ) - called when entity dies
  96. etc.
  97. These are identical to the regular vscript callbacks (see wiki), except that under the python
  98. system, they all take 'entity' as the first parameter.
  99. */
  100. static int GetNewProxyId( void );
  101. static void SetProxyBinding( int proxyId, ScriptFunctionBinding_t *pBinding );
  102. static PyCFunction GetProxyFunction( int proxyId );
  103. static ScriptFunctionBinding_t *GetProxyBinding( int proxyId );
  104. static void InitProxyTable( void );
  105. inline PyObject *CreatePyVector( Vector *pVector );
  106. inline bool IsPyVector( PyObject *pobj );
  107. inline bool VMInitFinalized( void );
  108. //------------------------------------------------------------------------------
  109. // python interpreter singleton
  110. //------------------------------------------------------------------------------
  111. static void *g_pVm = NULL;
  112. // object tags, largely used for memory validity checking on pointer casts
  113. #define TYPETAG_INSTANCE 71717171
  114. #define TYPETAG_SCOPE 81818181
  115. #define TYPETAG_VECTOR 91919191
  116. // NOTE: increase MAX_VALVE_FUNCTIONS_EXPORTED and the DPX(n) & SPX(n) entries at the end of this file if more than 260
  117. // functions/methods are exported from valve dlls to vscript.
  118. #define MAX_VALVE_FUNCTIONS_EXPORTED 260
  119. // NOTE: increase this if we export more than N classes to python.
  120. #define MAX_VALVE_CLASSES_EXPORTED 260
  121. //------------------------------------------------------------------------------
  122. // Module structs
  123. //------------------------------------------------------------------------------
  124. // a single python method definition followed by a null sentinel
  125. typedef struct
  126. {
  127. PyMethodDef defs[2];
  128. } pymethoddef_t;
  129. // valve server object instance data
  130. typedef struct
  131. {
  132. void *pInstance; // instance of the valve object
  133. ScriptClassDesc_t *pClassDesc; // binding descriptors for methods
  134. PyObject *pPyName; // name
  135. } InstanceContext_t;
  136. // python object with data for valve server object instances
  137. typedef struct
  138. {
  139. PyObject_HEAD;
  140. /* instance data */
  141. PyObject *pDict; // mapped to __dict__ of python instance object
  142. int typeTag;
  143. InstanceContext_t instanceContext;
  144. } scriptClassInstance_t;
  145. typedef struct
  146. {
  147. PyCFunction pfn;
  148. ScriptFunctionBinding_t *pBinding; // binding to valve function
  149. } proxybinding_t;
  150. // global array mapping from proxy function id to function binding data
  151. static proxybinding_t g_proxies[MAX_VALVE_FUNCTIONS_EXPORTED];
  152. //------------------------------------------------------------------------------
  153. // inline debug helpers
  154. //------------------------------------------------------------------------------
  155. // define this to always sanity check the object's ref counts
  156. // NOTE: failing this can imply a reference count bug (i.e. too many frees)
  157. // or possible memory corruption bug.
  158. #define DEBUG_PY 1
  159. inline void AssertIsPyObject( HSCRIPT hscript, int minRefCount = 0 )
  160. {
  161. #ifdef DEBUG_PY
  162. Assert( ((PyObject*)hscript == Py_None) || ((PyObject *)hscript)->ob_refcnt < 5000 && ((PyObject *)hscript)->ob_refcnt >= minRefCount);
  163. #endif // DEBUG_PY
  164. }
  165. // object must be a python object and an instance object
  166. inline void AssertIsInstance( HSCRIPT hscript )
  167. {
  168. #ifdef DEBUG_PY
  169. AssertIsPyObject( hscript, 0 );
  170. Assert ( ((scriptClassInstance_t *)hscript)->typeTag == TYPETAG_INSTANCE );
  171. #endif // DEBUG_PY
  172. }
  173. //-------------------------------------------------------------------------
  174. // Vector class
  175. //-------------------------------------------------------------------------
  176. // python vector instance with data for valve object instance
  177. typedef struct
  178. {
  179. PyObject_HEAD;
  180. /* instance data goes here*/
  181. int typeTag;
  182. Vector *pVector;
  183. } PyVectorInstance_t;
  184. inline void AssertIsVector( HSCRIPT hscope )
  185. {
  186. Assert( ((PyVectorInstance_t *)hscope)->typeTag == TYPETAG_VECTOR );
  187. }
  188. static int DEBUG_VECCOUNT = 0; // count the vector allocations vs frees (test for mem leaks)
  189. static int DEBUG_VARIANTCOUNT = 0; // count the variant allocations vs frees (test for mem leaks)
  190. static int DEBUG_FUNCCOUNT = 0; // count the function handle allocs vs frees (test for mem leaks)
  191. //-------------------------------------------------------------
  192. // called from python directly during object destruction.
  193. //-------------------------------------------------------------
  194. static void VectorRelease( PyObject *pSelf )
  195. {
  196. AssertIsVector( (HSCRIPT)pSelf );
  197. // free the game vector
  198. if ( ((PyVectorInstance_t *)pSelf)->pVector )
  199. {
  200. delete ((PyVectorInstance_t *)pSelf)->pVector;
  201. DEBUG_VECCOUNT--;
  202. }
  203. // free the python object
  204. pSelf->ob_type->tp_free( pSelf );
  205. }
  206. //-------------------------------------------------------------
  207. // called from python directly during object construction.
  208. // same as class __init__ function - init the member data for valve instance
  209. // Allocates a NEW Vector. The new Vector object will be deleted
  210. // when the python object is deleted via VectorRelease.
  211. //-------------------------------------------------------------
  212. static int VectorConstructNew( PyObject *pSelf, PyObject *pArgs, PyObject *pkwds )
  213. {
  214. float x = 0.0;
  215. float y = 0.0;
  216. float z = 0.0;
  217. if ( pArgs )
  218. {
  219. PyArg_ParseTuple( pArgs, "|fff", &x, &y, &z );
  220. }
  221. Vector *pVector = new Vector(x, y, z);
  222. DEBUG_VECCOUNT++;
  223. Assert( DEBUG_VECCOUNT < 1000 ); // if this fails, we're likely leaking new vectors each frame.
  224. ((PyVectorInstance_t *)pSelf)->pVector = pVector;
  225. ((PyVectorInstance_t *)pSelf)->typeTag = TYPETAG_VECTOR;
  226. return 0;
  227. }
  228. //--------------------------------------------------------------------
  229. // creates a new python vector object which references the given Vector.
  230. // (i.e. does NOT create a new Vector object). The referenced vector will
  231. // be deleted when the python object is deleted via VectorRelease.
  232. //--------------------------------------------------------------------
  233. void VectorBuildCopy( PyObject *pSelf, Vector *pVector)
  234. {
  235. ((PyVectorInstance_t *)pSelf)->pVector = pVector;
  236. ((PyVectorInstance_t *)pSelf)->typeTag = TYPETAG_VECTOR;
  237. }
  238. //-------------------------------------------------------------
  239. // called from python directly on object attribute x,y,z access
  240. //-------------------------------------------------------------
  241. static PyObject * VectorGet( PyObject *pSelf, PyObject *pname )
  242. {
  243. AssertIsVector( (HSCRIPT)pSelf );
  244. if (!PyString_Check( pname ))
  245. return NULL;
  246. Vector *pVector = ((PyVectorInstance_t *)pSelf)->pVector;
  247. if ( !pVector )
  248. {
  249. PyErr_SetString(PyExc_ValueError, "null vector");
  250. return NULL;
  251. }
  252. const char *pszKey = PyString_AsString( pname );
  253. if ( pszKey && *pszKey && !*(pszKey + 1) )
  254. {
  255. int index = *pszKey - 'x';
  256. if ( index >=0 && index <= 2)
  257. {
  258. float fret = (*pVector)[index];
  259. return PyFloat_FromDouble( (double)fret );
  260. }
  261. }
  262. return PyObject_GenericGetAttr( pSelf, pname );
  263. }
  264. //-------------------------------------------------------------
  265. // called from python directly on object attribute x,y,z access
  266. //-------------------------------------------------------------
  267. static int VectorSet( PyObject *pSelf, PyObject *pname, PyObject *pval )
  268. {
  269. AssertIsVector( (HSCRIPT)pSelf );
  270. if (!PyString_Check( pname ))
  271. return -1;
  272. Vector *pVector = ((PyVectorInstance_t *)pSelf)->pVector;
  273. if ( !pVector )
  274. {
  275. PyErr_SetString(PyExc_ValueError, "null vector");
  276. return -1;
  277. }
  278. const char *pszKey = PyString_AsString( pname );
  279. if ( pszKey && *pszKey && !*(pszKey + 1) )
  280. {
  281. int index = *pszKey - 'x';
  282. if ( index >=0 && index <= 2)
  283. {
  284. (*pVector)[index] = (float)PyFloat_AsDouble( pval );
  285. return 0;
  286. }
  287. }
  288. return -1;
  289. // no dictionary on vector object! return PyObject_GenericSetAttr( pSelf, pname, pval);
  290. }
  291. // repr function for vector
  292. static PyObject * VectorToString( PyObject *pSelf )
  293. {
  294. AssertIsVector( (HSCRIPT)pSelf );
  295. Vector *pVector = ((PyVectorInstance_t *)pSelf)->pVector;
  296. if ( !pVector )
  297. {
  298. return PyString_FromString("<Vector : null>");
  299. }
  300. return PyString_FromString( (static_cast<const char *>(CFmtStr("<Vector: %f %f %f>", pVector->x, pVector->y, pVector->z))) );
  301. }
  302. // repr function for instance
  303. static PyObject * InstanceToString( PyObject *pSelf )
  304. {
  305. AssertIsPyObject( (HSCRIPT)pSelf );
  306. return PyString_FromFormat("<%s at %p>", pSelf->ob_type->tp_name, (void*)pSelf );
  307. // UNDONE:
  308. // StackHandler sa(hVM);
  309. // InstanceContext_t *pContext = (InstanceContext_t *)sa.GetInstanceUp(1,0);
  310. // char szBuf[64];
  311. //
  312. // if ( pContext && pContext->pInstance && pContext->pClassDesc->pHelper && pContext->pClassDesc->pHelper->ToString( pContext->pInstance, szBuf, ARRAYSIZE(szBuf) ) )
  313. // {
  314. // sa.Return( szBuf );
  315. // }
  316. // else
  317. // {
  318. // HPYOBJECT hInstance = sa.GetObjectHandle( 1 );
  319. // sq_pushstring( hVM, CFmtStr( "(instance : 0x%p)", (void*)_rawval(hInstance) ), -1 );
  320. // }
  321. // return 1;
  322. }
  323. static PyObject * VectorToKeyValueString( PyObject *pSelf, PyObject *pArgs )
  324. {
  325. AssertIsVector( (HSCRIPT)pSelf );
  326. Vector *pVector = ((PyVectorInstance_t *)pSelf)->pVector;
  327. if ( !pVector )
  328. {
  329. PyErr_SetString(PyExc_ValueError, "null vector");
  330. return NULL;
  331. }
  332. return PyString_FromString( (static_cast<const char *>(CFmtStr("%f %f %f", pVector->x, pVector->y, pVector->z))) );
  333. }
  334. static PyObject * VectorAdd( PyObject *pSelf, PyObject *pOther )
  335. {
  336. AssertIsVector( (HSCRIPT)pSelf );
  337. Vector *pVector = ((PyVectorInstance_t *)pSelf)->pVector;
  338. Vector *pVectorOther = ((PyVectorInstance_t *)pOther)->pVector;
  339. if ( !pVectorOther || !pVector )
  340. {
  341. PyErr_SetString(PyExc_ValueError, "null vector");
  342. return NULL;
  343. }
  344. if ( !IsPyVector( pOther ) )
  345. {
  346. PyErr_SetString(PyExc_ValueError, "can't add vector to non vector type");
  347. return NULL;
  348. }
  349. // create new PyTypeVector object - explicitly calls VectorConstructNew
  350. PyObject *pretObj = CreatePyVector( NULL );
  351. *( ((PyVectorInstance_t *)pretObj)->pVector ) = *pVector + *pVectorOther;
  352. return pretObj;
  353. }
  354. static PyObject * VectorSubtract( PyObject *pSelf, PyObject *pOther )
  355. {
  356. AssertIsVector( (HSCRIPT)pSelf );
  357. Vector *pVector = ((PyVectorInstance_t *)pSelf)->pVector;
  358. Vector *pVectorOther = ((PyVectorInstance_t *)pOther)->pVector;
  359. if ( !pVectorOther || !pVector )
  360. {
  361. PyErr_SetString(PyExc_ValueError, "null vector");
  362. return NULL;
  363. }
  364. if ( !IsPyVector( pOther ) )
  365. {
  366. PyErr_SetString(PyExc_ValueError, "can't sub non vector type from vector");
  367. return NULL;
  368. }
  369. // create new PyTypeVector object
  370. PyObject *pretObj = CreatePyVector( NULL );
  371. *( ((PyVectorInstance_t *)pretObj)->pVector ) = *pVector - *pVectorOther;
  372. return pretObj;
  373. }
  374. static PyObject * VectorScale( PyObject *pSelf, PyObject *pScale )
  375. {
  376. PyObject *pPyVec;
  377. PyObject *pPyScale;
  378. if ( ((PyVectorInstance_t *)pSelf)->typeTag == TYPETAG_VECTOR )
  379. {
  380. pPyVec = pSelf;
  381. pPyScale = pScale;
  382. }
  383. else
  384. {
  385. pPyVec = pScale;
  386. pPyScale = pSelf;
  387. }
  388. Vector *pVector = ((PyVectorInstance_t *)pPyVec)->pVector;
  389. if ( !pVector )
  390. {
  391. PyErr_SetString(PyExc_ValueError, "null vector");
  392. return NULL;
  393. }
  394. if ( !PyFloat_Check( pPyScale ) )
  395. {
  396. PyErr_SetString(PyExc_ValueError, "can't scale vector by non float type");
  397. return NULL;
  398. }
  399. float scale = (float)PyFloat_AsDouble( pPyScale );
  400. PyObject *pretObj = CreatePyVector( NULL );
  401. *( ((PyVectorInstance_t *)pretObj)->pVector ) = *pVector * scale;
  402. return pretObj;
  403. }
  404. static int VectorCoerce(PyObject **pv, PyObject **pw)
  405. {
  406. if ( PyFloat_Check(*pw) )
  407. return 0; // NOTE: we don't actually coerce - vector multiply handles a float scalar
  408. // and all other math functions explicitly check 2nd arg type.
  409. else
  410. return 1; // can't coerce anything else
  411. }
  412. static PyObject * VectorLength( PyObject *pSelf, PyObject *pArgs )
  413. {
  414. AssertIsVector( (HSCRIPT)pSelf );
  415. Vector *pVector = ((PyVectorInstance_t *)pSelf)->pVector;
  416. if ( !pVector )
  417. {
  418. PyErr_SetString(PyExc_ValueError, "null vector");
  419. return NULL;
  420. }
  421. float flLength = pVector->Length();
  422. return PyFloat_FromDouble( (double)flLength );
  423. }
  424. static PyObject * VectorLengthSqr( PyObject *pSelf, PyObject *pArgs )
  425. {
  426. AssertIsVector( (HSCRIPT)pSelf );
  427. Vector *pVector = ((PyVectorInstance_t *)pSelf)->pVector;
  428. if ( !pVector )
  429. {
  430. PyErr_SetString(PyExc_ValueError, "null vector");
  431. return NULL;
  432. }
  433. float flLength = pVector->LengthSqr();
  434. return PyFloat_FromDouble( (double)flLength );
  435. }
  436. static PyObject * VectorLength2D( PyObject *pSelf, PyObject *pArgs )
  437. {
  438. AssertIsVector( (HSCRIPT)pSelf );
  439. Vector *pVector = ((PyVectorInstance_t *)pSelf)->pVector;
  440. if ( !pVector )
  441. {
  442. PyErr_SetString(PyExc_ValueError, "null vector");
  443. return NULL;
  444. }
  445. float flLength = pVector->Length2D();
  446. return PyFloat_FromDouble( (double)flLength );
  447. }
  448. static PyObject * VectorLength2DSqr( PyObject *pSelf, PyObject *pArgs )
  449. {
  450. AssertIsVector( (HSCRIPT)pSelf );
  451. Vector *pVector = ((PyVectorInstance_t *)pSelf)->pVector;
  452. if ( !pVector )
  453. {
  454. PyErr_SetString(PyExc_ValueError, "null vector");
  455. return NULL;
  456. }
  457. float flLength = pVector->Length2DSqr();
  458. return PyFloat_FromDouble( (double)flLength );
  459. }
  460. static PyObject * VectorCross( PyObject *pSelf, PyObject *pOther )
  461. {
  462. AssertIsVector( (HSCRIPT)pSelf );
  463. Vector *pVector = ((PyVectorInstance_t *)pSelf)->pVector;
  464. Vector *pVectorOther = ((PyVectorInstance_t *)pOther)->pVector;
  465. if ( !pVectorOther || !pVector )
  466. {
  467. PyErr_SetString(PyExc_ValueError, "null vector");
  468. return NULL;
  469. }
  470. // create new PyTypeVector object
  471. PyObject *pretObj = CreatePyVector( NULL );
  472. *( ((PyVectorInstance_t *)pretObj)->pVector ) = (*pVector).Cross( *pVectorOther );
  473. return pretObj;
  474. }
  475. static PyObject * VectorDot( PyObject *pSelf, PyObject *pOther )
  476. {
  477. AssertIsVector( (HSCRIPT)pSelf );
  478. Vector *pVector = ((PyVectorInstance_t *)pSelf)->pVector;
  479. Vector *pVectorOther = ((PyVectorInstance_t *)pOther)->pVector;
  480. if ( !pVectorOther || !pVector )
  481. {
  482. PyErr_SetString(PyExc_ValueError, "null vector");
  483. return NULL;
  484. }
  485. float flResult = (*pVector).Dot( *pVectorOther );
  486. return PyFloat_FromDouble( (double)flResult );
  487. }
  488. static PyObject * VectorNorm( PyObject *pSelf, PyObject *pArgs )
  489. {
  490. AssertIsVector( (HSCRIPT)pSelf );
  491. Vector *pVector = ((PyVectorInstance_t *)pSelf)->pVector;
  492. if ( !pVector )
  493. {
  494. PyErr_SetString(PyExc_ValueError, "null vector");
  495. return NULL;
  496. }
  497. float flLength = pVector->NormalizeInPlace();
  498. return PyFloat_FromDouble( (double)flLength );
  499. }
  500. // python vector class methods
  501. static PyMethodDef g_VectorFuncs[] =
  502. {
  503. { "ToKVString", VectorToKeyValueString, METH_NOARGS, "Get x,y,z as string of space-separated floats." },
  504. { "Length", VectorLength, METH_NOARGS, "Get the vector's magnitude." },
  505. { "LengthSqr", VectorLengthSqr, METH_NOARGS, "Get the vector's magnitude squared." },
  506. { "Length2D", VectorLength2D, METH_NOARGS, "2d x,y length." },
  507. { "Length2DSqr", VectorLength2DSqr, METH_NOARGS, "Square of x,y length." },
  508. { "Dot", VectorDot, METH_O, "Dot product of vectors." },
  509. { "Cross", VectorCross, METH_O, "Cross product of vectors."},
  510. { "Norm", VectorNorm, METH_NOARGS, "Normalize vector in place." },
  511. { NULL, NULL, 0, NULL }
  512. };
  513. static PyNumberMethods g_VectorAsNumber = {
  514. (binaryfunc)VectorAdd, /* nb_add */
  515. (binaryfunc)VectorSubtract, /* nb_subtract */
  516. (binaryfunc)VectorScale, /* nb_multiply */
  517. 0, /* nb_divide */
  518. 0, /* nb_remainder */
  519. 0, /* nb_divmod */
  520. 0, /* nb_power */
  521. 0, /* nb_negative */
  522. 0, /* nb_positive */
  523. 0, /* nb_absolute */
  524. 0, /* nb_nonzero */
  525. 0, /*nb_invert*/
  526. 0, /*nb_lshift*/
  527. 0, /*nb_rshift*/
  528. 0, /*nb_and*/
  529. 0, /*nb_xor*/
  530. 0, /*nb_or*/
  531. 0, // (coercion)VectorCoerce, /*nb_coerce*/
  532. 0, /*nb_int*/
  533. 0, /*nb_long*/
  534. 0, /*nb_float*/
  535. 0, /*nb_oct*/
  536. 0, /*nb_hex*/
  537. 0, /*nb_inplace_add*/
  538. 0, /*nb_inplace_subtract*/
  539. 0, /*nb_inplace_multiply*/
  540. 0, /*nb_inplace_divide*/
  541. 0, /*nb_inplace_remainder*/
  542. 0, /*nb_inplace_power*/
  543. 0, /*nb_inplace_lshift*/
  544. 0, /*nb_inplace_rshift*/
  545. 0, /*nb_inplace_and*/
  546. 0, /*nb_inplace_xor*/
  547. 0, /*nb_inplace_or*/
  548. 0, /* nb_floor_divide */
  549. 0, /* nb_true_divide */
  550. 0, /* nb_inplace_floor_divide */
  551. 0, /* nb_inplace_true_divide */
  552. };
  553. // python vector class template
  554. static PyTypeObject PyTypeVector = {
  555. PyObject_HEAD_INIT(NULL) /* type type */ // set up by PyType_Ready() call later.
  556. 0, /*ob_size*/
  557. "Vector", /*tp_name*/
  558. sizeof(PyVectorInstance_t),/*tp_basicsize*/
  559. 0, /*tp_itemsize*/
  560. (destructor)VectorRelease, /*tp_dealloc*/ // consider
  561. 0, /*tp_print*/
  562. 0, /*tp_getattr*/
  563. 0, /*tp_setattr*/
  564. 0, /*tp_compare*/
  565. (reprfunc )VectorToString, /*tp_repr*/ // consider
  566. &g_VectorAsNumber, /*tp_as_number*/
  567. 0, /*tp_as_sequence*/
  568. 0, /*tp_as_mapping*/
  569. 0, /*tp_hash */
  570. 0, /*tp_call*/
  571. 0, /*tp_str*/
  572. (getattrofunc)VectorGet, /*tp_getattro*/
  573. (setattrofunc)VectorSet, /*tp_setattro*/
  574. 0, /*tp_as_buffer*/
  575. Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, /*tp_flags*/ // don't coerce, all number functions check types
  576. 0, /* tp_doc */
  577. 0, /* tp_traverse */
  578. 0, /* tp_clear */
  579. 0, /* tp_richcompare */
  580. 0, /* tp_weaklistoffset */
  581. 0, /* tp_iter */
  582. 0, /* tp_iternext */
  583. g_VectorFuncs, /* tp_methods */
  584. 0, /* tp_members */
  585. 0, /* tp_getset */
  586. 0, /* tp_base */ // base class type object
  587. 0, /* tp_dict */
  588. 0, /* tp_descr_get */
  589. 0, /* tp_descr_set */
  590. 0, /* tp_dictoffset */
  591. (initproc)VectorConstructNew, /* tp_init */ // consider
  592. PyType_GenericAlloc, /* tp_alloc */
  593. PyType_GenericNew, /* tp_new */ // consider // BUG: doesn't call tp_init?
  594. PyObject_Del, /* tp_free */
  595. };
  596. //-----------------------------------------------------------------------------------
  597. // create a new python vector object from the PyTypeVector type
  598. // if pVector is null, allocs a new vector object, otherwise just references pVector
  599. //-----------------------------------------------------------------------------------
  600. inline PyObject *CreatePyVector( Vector *pVector )
  601. {
  602. PyObject *pretObj = PyType_GenericNew( &PyTypeVector, NULL, NULL ); // calls tp_alloc(type,0) -> calls PyType_GenericAlloc -> calls PyObject_MALLOC
  603. if ( pVector )
  604. {
  605. VectorBuildCopy( pretObj, pVector ); // use the provided vector to build the python object
  606. }
  607. else
  608. {
  609. VectorConstructNew( pretObj, NULL, NULL ); // allocate a new vector object within the python object
  610. }
  611. return pretObj;
  612. }
  613. inline bool IsPyVector( PyObject *pobj )
  614. {
  615. return ( pobj->ob_type == &PyTypeVector );
  616. }
  617. // -----------------------------------------------------------
  618. // register custom vector class into the 'valve' module scope
  619. // -----------------------------------------------------------
  620. bool RegisterVector( PyObject *pmodule )
  621. {
  622. // finalize the new python vector type
  623. if (PyType_Ready( &PyTypeVector ) < 0)
  624. return false;
  625. // add the new class type to the 'valve' module
  626. Py_INCREF( &PyTypeVector );
  627. PyModule_AddObject( pmodule, "Vector", (PyObject *)&PyTypeVector );
  628. return true;
  629. }
  630. // -------------------------------------------------------
  631. // Scope wrapper class. Python scope represents
  632. // a python module's dictionary, or an instance object's dictionary.
  633. // -------------------------------------------------------
  634. class CPyScope
  635. {
  636. public:
  637. CPyScope( )
  638. {
  639. m_pPyModule = NULL; // a python module object
  640. m_pPySelf = NULL; // an instance object
  641. m_pTempDict = PyDict_New(); // holding location for data until 'self' is set in scope
  642. m_typeTag = TYPETAG_SCOPE;
  643. }
  644. //-------------------------------------------------------
  645. // release all python objects on delete
  646. //-------------------------------------------------------
  647. ~CPyScope()
  648. {
  649. Py_XDECREF( m_pTempDict );
  650. Py_XDECREF( m_pPyModule );
  651. Py_XDECREF( m_pPySelf );
  652. }
  653. void SetInstanceObject( PyObject *pSelf )
  654. {
  655. m_pPySelf = (scriptClassInstance_t *)pSelf;
  656. Py_XINCREF( m_pPySelf );
  657. }
  658. void SetModuleObject( PyObject *pModule )
  659. {
  660. m_pPyModule = pModule;
  661. Py_XINCREF( m_pPyModule );
  662. }
  663. PyObject *GetInstanceObject ()
  664. {
  665. return (PyObject *)m_pPySelf; // return borrowed ref
  666. }
  667. PyObject * GetInstanceDict()
  668. {
  669. if ( !m_pPySelf )
  670. return NULL;
  671. return m_pPySelf->pDict; // return borrowed ref
  672. }
  673. PyObject * GetModuleDict()
  674. {
  675. if ( !m_pPyModule )
  676. return NULL;
  677. return PyModule_GetDict( m_pPyModule ); // return borrowed ref
  678. }
  679. PyObject *GetModule()
  680. {
  681. return m_pPyModule;
  682. }
  683. void TransferTempDictToInstance()
  684. {
  685. // move contents of temp dict into instance dict.
  686. // don't overwrite values in instance dict.
  687. Assert ( m_pPySelf );
  688. PyDict_Merge( m_pPySelf->pDict, m_pTempDict, false );
  689. }
  690. void SetTempDictValue( const char *pszKey, PyObject *pyobj )
  691. {
  692. // set python key:value in temp dict
  693. PyDict_SetItemString( m_pTempDict, pszKey, pyobj );
  694. }
  695. scriptClassInstance_t *m_pPySelf; // pointer to invoking entity instance - entity data lives here
  696. PyObject *m_pPyModule; // pointer to module - entity code lives here
  697. PyObject *m_pTempDict;
  698. int m_typeTag;
  699. };
  700. inline void AssertIsScope( HSCRIPT hScope )
  701. {
  702. // validate hscope handle as a CPyScope object
  703. Assert ( !hScope || ((CPyScope *)hScope)->m_typeTag == TYPETAG_SCOPE );
  704. }
  705. //--------------------------------------------------------------------------------
  706. // utility callback: display a string at the console
  707. // python sys.stdio and sys.stderr are redirected here
  708. //--------------------------------------------------------------------------------
  709. static PyObject *vprint(PyObject *self, PyObject *args)
  710. {
  711. const char *psz;
  712. int ret = PyArg_ParseTuple(args, "s", &psz);
  713. if ( ret )
  714. //DevMsg( (const tchar *)psz);
  715. Msg( (const tchar *)psz );
  716. else
  717. DevMsg("vpython.cpp, vprint error: bad argument?");
  718. return Py_BuildValue("i", 0);
  719. };
  720. //--------------------------------------------------------------------------------
  721. // Reload the named module & fixes up the internal module pointer saved in the hScope.
  722. // params: (PyObject *pSelf, PyObject *moduleName, PyObject *hScope )
  723. // ignores first param 'self'.
  724. //--------------------------------------------------------------------------------
  725. static PyObject *ReplaceClosures( PyObject *self, PyObject *args )
  726. {
  727. PyObject *pSelf; // this is called through ExecuteFunction, which adds the self param
  728. const char *pszModuleName;
  729. PyObject *hScope;
  730. int ret = PyArg_ParseTuple(args, "OsO", &pSelf, &pszModuleName, &hScope);
  731. if ( !ret )
  732. {
  733. DevMsg("vpython.cpp, ReplaceClosures argument error!");
  734. return Py_BuildValue("i", 0);
  735. }
  736. // get the previously imported module handle
  737. PyObject *pOldModule = PyImport_AddModule( pszModuleName );
  738. if ( !pOldModule )
  739. {
  740. DevMsg("vpython.cpp, ReplaceClosures error: module was never previously loaded!" );
  741. return Py_BuildValue("i", 0);
  742. }
  743. PyObject *pNewModule = PyImport_ReloadModule( pOldModule );
  744. if ( !pNewModule )
  745. {
  746. DevMsg("vpython.cpp, ReplaceClosures error: module failed to reload!" );
  747. return Py_BuildValue("i", 0);
  748. }
  749. // fixup refs to old module object in hScope
  750. if ( hScope )
  751. {
  752. if ( pOldModule != pNewModule )
  753. {
  754. Assert( pOldModule == ((CPyScope *)hScope)->GetModule() );
  755. Py_XDECREF( pOldModule ); // release the ref count that the hScope is holding on the old module
  756. ((CPyScope *)hScope)->SetModuleObject( pNewModule );
  757. }
  758. }
  759. return Py_BuildValue("i", 0);
  760. }
  761. //---------------------------------------------------------------------------------
  762. // given euler angles Pitch, Yaw, Roll, get forward vector
  763. //---------------------------------------------------------------------------------
  764. static PyObject *VectorFromAngles( PyObject *self, PyObject *args )
  765. {
  766. float fpitch, fyaw, froll;
  767. int ret = PyArg_ParseTuple(args, "|fff", &fpitch, &fyaw, &froll );
  768. if ( !ret )
  769. {
  770. DevMsg("vpython.cpp: invalid params to VectorFromAngles, expected 3 floats!");
  771. return Py_BuildValue("i",0);
  772. }
  773. // create new PyTypeVector object - explicitly calls VectorConstructNew
  774. PyObject *pretObj = CreatePyVector( NULL );
  775. QAngle angles(fpitch, fyaw, froll); // QAngle(pitch, yaw, roll);
  776. Vector forward;
  777. AngleVectors( angles, &forward );
  778. *( ((PyVectorInstance_t *)pretObj)->pVector ) = forward; // copy
  779. return pretObj;
  780. }
  781. //---------------------------------------------------------------------------------
  782. // given forward vector, get euler angles Pitch, Yaw, Roll. Roll is always 0.
  783. //---------------------------------------------------------------------------------
  784. static PyObject *AnglesFromVector( PyObject *self, PyObject *args )
  785. {
  786. PyObject *pyVector;
  787. int ret = PyArg_ParseTuple(args, "|O",&pyVector );
  788. if ( !ret )
  789. {
  790. DevMsg("vpython.cpp: invalid params to AnglesFromVector, expected 1 vector");
  791. return Py_BuildValue("i",0);
  792. }
  793. QAngle angles;
  794. Vector forward = *((PyVectorInstance_t *)pyVector)->pVector; // copy
  795. VectorAngles( forward, angles); // returns pitch (x), yaw (y), roll (z)
  796. PyObject *pretObj1 = PyFloat_FromDouble(angles[PITCH]);
  797. PyObject *pretObj2 = PyFloat_FromDouble(angles[YAW]);
  798. PyObject *pretObj3 = PyFloat_FromDouble(angles[ROLL]);
  799. PyObject *pretObj = PyTuple_Pack(3, pretObj1, pretObj2, pretObj3);
  800. Py_XDECREF(pretObj1);
  801. Py_XDECREF(pretObj2);
  802. Py_XDECREF(pretObj3);
  803. return pretObj;
  804. }
  805. // ----------------------------------------------------------------------------
  806. // given euler angles Pitch, Yaw, Roll, return tuple of vforward, vright, vup
  807. // ----------------------------------------------------------------------------
  808. static PyObject *VectorsFromAngles( PyObject *self, PyObject *args )
  809. {
  810. float fpitch, fyaw, froll;
  811. int ret = PyArg_ParseTuple(args, "|fff", &fpitch, &fyaw, &froll );
  812. if ( !ret )
  813. {
  814. DevMsg("vpython.cpp: invalid params to VectorFromAngles, expected 3 floats!");
  815. return Py_BuildValue("i",0);
  816. }
  817. // create new PyTypeVector object - explicitly calls VectorConstructNew
  818. PyObject *pretObj1 = CreatePyVector( NULL );
  819. PyObject *pretObj2 = CreatePyVector( NULL );
  820. PyObject *pretObj3 = CreatePyVector( NULL );
  821. QAngle angles(fpitch, fyaw, froll); // QAngle(pitch, yaw, roll);
  822. Vector forward;
  823. Vector right;
  824. Vector up;
  825. AngleVectors( angles, &forward, &right, &up );
  826. *( ((PyVectorInstance_t *)pretObj1)->pVector ) = forward; // copy
  827. *( ((PyVectorInstance_t *)pretObj2)->pVector ) = right; // copy
  828. *( ((PyVectorInstance_t *)pretObj3)->pVector ) = up; // copy
  829. PyObject *pretObj = PyTuple_Pack(3, pretObj1, pretObj2, pretObj3);
  830. Py_XDECREF(pretObj1);
  831. Py_XDECREF(pretObj2);
  832. Py_XDECREF(pretObj3);
  833. return pretObj;
  834. }
  835. //-----------------------------------------------------------------------------
  836. // Interpolate a Catmull-Rom spline.
  837. // t is a [0,1] value and interpolates a curve between p2 and p3.
  838. // takes p1,p2,p3,p4 vectors and float t, returns output vector.
  839. //-----------------------------------------------------------------------------
  840. static PyObject *CatmullRomSpline( PyObject *self, PyObject *args )
  841. {
  842. // UNDONE: use interpolatortypes.cpp types instead of a single interpolator here
  843. PyObject *pyv1,*pyv2,*pyv3,*pyv4;
  844. Vector p1,p2,p3,p4;
  845. float t;
  846. int ret = PyArg_ParseTuple(args, "|OOOOf", &pyv1, &pyv2, &pyv3, &pyv4, &t );
  847. if ( !ret )
  848. {
  849. DevMsg("vpython.cpp: invalid params to Catmull_Rom_Spline, expected 4 vectors and 1 float!");
  850. return Py_BuildValue("i",0);
  851. }
  852. p1 = *((PyVectorInstance_t *)pyv1)->pVector;
  853. p2 = *((PyVectorInstance_t *)pyv2)->pVector;
  854. p3 = *((PyVectorInstance_t *)pyv3)->pVector;
  855. p4 = *((PyVectorInstance_t *)pyv4)->pVector;
  856. // create new PyTypeVector object - explicitly calls VectorConstructNew
  857. PyObject *pretObj = CreatePyVector( NULL );
  858. Vector output(0,0,0);
  859. Catmull_Rom_Spline(p1,p2,p3,p4,t,output);
  860. *( ((PyVectorInstance_t *)pretObj)->pVector ) = output; // copy
  861. return pretObj;
  862. }
  863. //-----------------------------------------------------------------------------
  864. // Purpose: basic hermite spline. t = 0 returns p1, t = 1 returns p2,
  865. // d1 and d2 are used to entry and exit slope of curve
  866. // Input : p1,p2,d1,d2, t,
  867. //-----------------------------------------------------------------------------
  868. static PyObject *HermiteSpline( PyObject *self, PyObject *args )
  869. {
  870. // UNDONE: use interpolatortypes.cpp types instead of a single interpolator here
  871. PyObject *pyv1,*pyv2,*pyv3,*pyv4;
  872. Vector p1,p2,d1,d2;
  873. float t;
  874. int ret = PyArg_ParseTuple(args, "|OOOOf", &pyv1, &pyv2, &pyv3, &pyv4, &t );
  875. if ( !ret )
  876. {
  877. DevMsg("vpython.cpp: invalid params to HermiteSpline, expected 4 vectors and 1 float!");
  878. return Py_BuildValue("i",0);
  879. }
  880. p1 = *((PyVectorInstance_t *)pyv1)->pVector;
  881. p2 = *((PyVectorInstance_t *)pyv2)->pVector;
  882. d1 = *((PyVectorInstance_t *)pyv3)->pVector;
  883. d2 = *((PyVectorInstance_t *)pyv4)->pVector;
  884. // create new PyTypeVector object - explicitly calls VectorConstructNew
  885. PyObject *pretObj = CreatePyVector( NULL );
  886. Vector output(0,0,0);
  887. Hermite_Spline(p1,p2,d1,d2,t,output);
  888. *( ((PyVectorInstance_t *)pretObj)->pVector ) = output; // copy
  889. return pretObj;
  890. }
  891. static PyObject *HermiteSplineFloat( PyObject *self, PyObject *args )
  892. {
  893. float p1,p2,d1,d2;
  894. float t;
  895. int ret = PyArg_ParseTuple(args, "|fffff", &p1,&p2,&d1,&d2, &t );
  896. if ( !ret )
  897. {
  898. DevMsg("vpython.cpp: invalid params to HermiteSplineFloat, expected 5 floats!");
  899. return 0;
  900. }
  901. float output = Hermite_Spline(p1,p2,d1,d2,t);
  902. return Py_BuildValue("f", output);
  903. }
  904. //---------------------------------------------------------------------------------
  905. //
  906. //---------------------------------------------------------------------------------
  907. static PyObject *ExactTime( PyObject *self, PyObject *args )
  908. {
  909. return PyFloat_FromDouble( Plat_FloatTime() );
  910. }
  911. static PyMethodDef valvemethods[] =
  912. {
  913. {"vprint",(PyCFunction) vprint, METH_VARARGS, "Display a string on the Valve console."},
  914. {"__ReplaceClosures",(PyCFunction) ReplaceClosures, METH_VARARGS, "Reload a module."},
  915. {"VectorFromAngles",(PyCFunction) VectorFromAngles, METH_VARARGS, "Convert from Roll, Pitch, Yaw to Vector"},
  916. {"VectorsFromAngles",(PyCFunction) VectorsFromAngles, METH_VARARGS, "Convert from Roll, Pitch, Yaw to forward, right, up Vectors"},
  917. {"AnglesFromVector",(PyCFunction) AnglesFromVector, METH_VARARGS, "Convert Vector to Roll, Pitch, Yaw angles (Yaw always 0)"},
  918. {"ExactTime",(PyCFunction) ExactTime, METH_VARARGS, "Get accurate sub-frame time in seconds"},
  919. {"CatmullRomSpline",(PyCFunction) CatmullRomSpline, METH_VARARGS, "Interpolate along a Catmull Rom Spline. Takes p1,p2,p3,p4 vectors and t float fraction."},
  920. {"HermiteSpline", (PyCFunction) HermiteSpline, METH_VARARGS, "Interpolate along a Hermite Spline. Takes p1,p2,d1,d2 vectors and t float fraction."},
  921. {"HermiteSplineFloat",(PyCFunction) HermiteSplineFloat, METH_VARARGS, "Interpolate along a Hermite Spline. Takes f1,f2,d1,d2 floats, and t float fraction."},
  922. {NULL, NULL, 0, NULL} // sentinel
  923. };
  924. //------------------------------------------------------------------------------
  925. // UNUSED: Purpose: remove old module from sys.modules and decrement ref to module object.
  926. // may provide either module object, or module name
  927. //------------------------------------------------------------------------------
  928. void UnloadModule( PyObject *pmodule, const char *pszModuleName )
  929. {
  930. return; // BUG: the name of the last module to run becomes '__main__' - must not unload main!
  931. const char *pszName = NULL;
  932. PyObject *pSysModules = PyImport_GetModuleDict( ); // borrowed ref
  933. if ( pmodule )
  934. {
  935. pszName = PyModule_GetFilename( pmodule );
  936. pszName = PyModule_GetName( pmodule );
  937. }
  938. else
  939. {
  940. Assert ( pszModuleName );
  941. pszName = pszModuleName;
  942. }
  943. if ( !pszName )
  944. return; // scope module has no name
  945. PyObject *pPyKey = PyString_FromString( pszName );
  946. if ( PyDict_Contains( pSysModules, pPyKey) )
  947. {
  948. // remove module from dict
  949. PyObject *pOldModule = PyDict_GetItemString( pSysModules, pszName );
  950. PyDict_DelItemString( pSysModules, pszName );
  951. Py_XDECREF( pOldModule );
  952. }
  953. Py_XDECREF( pPyKey );
  954. }
  955. //------------------------------------------------------------------
  956. // SINGLETON python interpreter - do not instantiate more than one
  957. // (this module keeps a static global pointer to the interpreter instance.)
  958. //------------------------------------------------------------------
  959. class CPythonVM : public IScriptVM
  960. {
  961. public:
  962. CPythonVM( )
  963. : m_iUniqueIdSerialNumber( 0 )
  964. #ifndef VPYTHON_TEST
  965. , developer( "developer" )
  966. #else
  967. , developer( "developer", "1" )
  968. #endif
  969. {
  970. m_bInitialized = false; // becomes true on all subsequent attempts to kill/restart the interpreter
  971. m_pRootScope = NULL;
  972. m_pValveScope = NULL;
  973. m_iMethodDef = 0;
  974. m_iClassDef = 0;
  975. m_debugObjCount = 0;
  976. }
  977. //-------------------------------------------------------------
  978. // Init the interpreter class - NOP if interp already active
  979. //-------------------------------------------------------------
  980. bool Init()
  981. {
  982. // g_pMemAlloc->CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_CHECK_ALWAYS_DF | _CRTDBG_CHECK_CRT_DF );
  983. if ( VMInitFinalized() )
  984. return true;
  985. // Python makes use of mathlib, so we have to init it:
  986. MathLib_Init( 2.2f, 2.2f, 0.0f, 2.0f );
  987. // init static proxy table
  988. InitProxyTable();
  989. // start python interpreter installed on users machine.
  990. // i.e. python25.dll should be in c:\windows\system32 or on dll search path.
  991. Py_Initialize(); // this is a NOP if already initialized
  992. if ( !Py_IsInitialized() )
  993. {
  994. DevWarning("CPythonVM.Init(): python interperter failed to initialize!");
  995. return false;
  996. }
  997. const char *pszVersion = Py_GetVersion();
  998. char buffer[64];
  999. V_strncpy(buffer,pszVersion, 6);
  1000. buffer[5] = '\0';
  1001. if ( V_strncmp(pszVersion, buffer, 5) )
  1002. {
  1003. // we link with python25.lib from version 2.5.1
  1004. DevWarning("Python25.dll version mismatch: version %s loaded. Should be 2.5.1!\n", buffer);
  1005. }
  1006. // modify python's module search path in sys.path to point to current working directory + <gamename>/scripts/vscripts
  1007. int ret;
  1008. ret = PyRun_SimpleString(
  1009. "import sys\n"
  1010. "import os\n"
  1011. "a,b = os.path.split(os.getcwd())\n"
  1012. "c,gamename = os.path.split(a)\n"
  1013. "p = os.path.join (os.getcwd(),gamename,'scripts','vscripts')\n"
  1014. "sys.path.append( p )\n"
  1015. );
  1016. Assert ( ret == 0 ); // make sure we could set up the python sys.path to the vscripts directory
  1017. // save off the vscript directory - ex: U:\projects\sob\game\sob\scripts\vscripts
  1018. char szScriptPathTemp[MAX_PATH];
  1019. char szScriptPathTemp2[MAX_PATH];
  1020. char szDirectoryTemp[MAX_PATH];
  1021. char szGamename[MAX_PATH];
  1022. // get current working directory
  1023. V_GetCurrentDirectory( szDirectoryTemp, sizeof( szDirectoryTemp ) ); // U:\projects\sob\game
  1024. // get game name from current working directory
  1025. V_ExtractFilePath( szDirectoryTemp, szGamename, sizeof(szGamename) ); // U:\projects\sob
  1026. const char *pszGamename = V_UnqualifiedFileName( szGamename );
  1027. V_ComposeFileName( szDirectoryTemp, pszGamename, szScriptPathTemp, sizeof( szScriptPathTemp ) );
  1028. V_ComposeFileName( szScriptPathTemp, "scripts", szScriptPathTemp2, sizeof( szScriptPathTemp2 ) );
  1029. V_ComposeFileName( szScriptPathTemp2, "vscripts", m_szScriptPath, sizeof( m_szScriptPath ) );
  1030. // create a new global scope 'valve' module - all valve classes, functions, instances are registered in this module.
  1031. // NOTE: 'valve' must be imported by python modules that wish to access these c functions.
  1032. PyObject *pPyValve;
  1033. pPyValve = PyImport_AddModule("valve");
  1034. PyModule_AddStringConstant(pPyValve, "__file__", "<synthetic>");
  1035. PyObject *pmod = Py_InitModule("valve", valvemethods);
  1036. Assert ( pmod == pPyValve );
  1037. // Redirect python stdout & stderr to Valve console
  1038. ret = PyRun_SimpleString(
  1039. "import valve\n"
  1040. "import sys\n"
  1041. "class StdoutCatcher:\n"
  1042. "\tdef write(self, str):\n"
  1043. "\t\tvalve.vprint(str)\n"
  1044. "class StderrCatcher:\n"
  1045. "\tdef write(self, str):\n"
  1046. "\t\tvalve.vprint(str)\n"
  1047. "sys.stdout = StdoutCatcher()\n"
  1048. "sys.stderr = StderrCatcher()\n" );
  1049. Assert ( ret == 0 );
  1050. // create new valve module scope
  1051. m_pValveScope = new CPyScope( );
  1052. m_pValveScope->SetModuleObject( pPyValve );
  1053. // get the main module object
  1054. PyObject* pPyMain = PyImport_AddModule("__main__");
  1055. // create new root scope from main's dictionary
  1056. m_pRootScope = new CPyScope( );
  1057. m_pRootScope->SetModuleObject( pPyMain );
  1058. // load and run the init.py module in the global scope
  1059. PyObject *pPyModule;
  1060. PyObject *pystr = PyString_FromString( "init" );
  1061. pPyModule = PyImport_Import( pystr );
  1062. Py_XDECREF( pystr );
  1063. PyPrintError();
  1064. if ( !pPyModule )
  1065. {
  1066. DevWarning("CPythonVM.Init(): unable to load main module init.py - module not on PYTHONPATH (sys.path)?");
  1067. return false;
  1068. }
  1069. m_TypeMap.Init( 256 ); // must be power of 2
  1070. m_ClassMap.Init( 256 ); // must be power of 2
  1071. RegisterVector( m_pValveScope->GetModule() );
  1072. PyPrintError();
  1073. return true;
  1074. }
  1075. //-------------------------------------------------------------
  1076. // Called every frame with frame time
  1077. //-------------------------------------------------------------
  1078. bool Frame( float simTime )
  1079. {
  1080. // UNDONE: garbage collect periodically?
  1081. // UNDONE: invoke a per-frame global function? ex: to run generators
  1082. #ifdef DEBUG_PY
  1083. if (1)
  1084. {
  1085. // validate every instance object we've allocated
  1086. for (int i=0; i < m_debugObjCount; i++)
  1087. {
  1088. if ( m_debugObjects[i] )
  1089. AssertIsPyObject( (HSCRIPT) (m_debugObjects[i]) );
  1090. }
  1091. }
  1092. #endif // DEBUG_PY
  1093. return false;
  1094. }
  1095. //-------------------------------------------------------------
  1096. // Called on level load
  1097. //-------------------------------------------------------------
  1098. void Shutdown()
  1099. {
  1100. bool bGameExit = false; // UNDONE: need flag passed in - only kill interpreter data on game exit, not restart or level load
  1101. if ( bGameExit )
  1102. {
  1103. if(1)
  1104. Py_Finalize(); // interpreter shutdown - reliable only ONCE per game session.
  1105. // shut down the vm. called on restart, or game exit
  1106. if (1)
  1107. {
  1108. ReleaseScope( (HSCRIPT)m_pRootScope );
  1109. ReleaseScope( (HSCRIPT)m_pValveScope );
  1110. m_TypeMap.Purge();
  1111. m_ClassMap.Purge();
  1112. }
  1113. }
  1114. }
  1115. //-------------------------------------------------------------
  1116. //
  1117. //-------------------------------------------------------------
  1118. ScriptLanguage_t GetLanguage()
  1119. {
  1120. return SL_PYTHON;
  1121. }
  1122. //-------------------------------------------------------------
  1123. //
  1124. //-------------------------------------------------------------
  1125. virtual const char *GetLanguageName()
  1126. {
  1127. return "Python";
  1128. }
  1129. //-------------------------------------------------------------
  1130. //
  1131. //-------------------------------------------------------------
  1132. virtual void AddSearchPath( const char *pszSearchPath )
  1133. {
  1134. }
  1135. //-------------------------------------------------------------
  1136. //
  1137. //-------------------------------------------------------------
  1138. bool ConnectDebugger()
  1139. {
  1140. // for debugging from visual studio into python, running pydev in eclipse,
  1141. // first launch the pydev debug server in eclipse, then
  1142. // run python code containing the following line:
  1143. //
  1144. // import pydevd; pydevd.settrace()
  1145. // for debuggin in Wing IDE, place 'import wingdbstub.py' in
  1146. // the code module you wish to debug.
  1147. return false;
  1148. }
  1149. //-------------------------------------------------------------
  1150. //
  1151. //-------------------------------------------------------------
  1152. void DisconnectDebugger()
  1153. {
  1154. }
  1155. //-------------------------------------------------------------
  1156. // run script text in the root scope
  1157. //-------------------------------------------------------------
  1158. ScriptStatus_t Run( const char *pszScript, bool bWait = true )
  1159. {
  1160. Assert( bWait );
  1161. PyObject* pyret = PyRun_String( pszScript, Py_file_input, m_pRootScope->GetModuleDict(), m_pRootScope->GetModuleDict() ) ;
  1162. PyPrintError();
  1163. if ( pyret == NULL )
  1164. return SCRIPT_ERROR;
  1165. Py_XDECREF(pyret);
  1166. return SCRIPT_DONE;
  1167. }
  1168. //-------------------------------------------------------------
  1169. // run the compiled script in the given scope
  1170. //-------------------------------------------------------------
  1171. ScriptStatus_t Run( HSCRIPT hScript, HSCRIPT hScope = NULL, bool bWait = true )
  1172. {
  1173. return CPythonVM::ExecuteFunction( hScript, NULL, 0, NULL, hScope, bWait );
  1174. }
  1175. //-------------------------------------------------------------
  1176. // run the compiled script in the root scope
  1177. //-------------------------------------------------------------
  1178. ScriptStatus_t Run( HSCRIPT hScript, bool bWait )
  1179. {
  1180. Assert( bWait );
  1181. return CPythonVM::Run( hScript, (HSCRIPT)NULL, bWait );
  1182. }
  1183. //-------------------------------------------------------------
  1184. // python auto-compiles modules, so just return a python string containing the module name,
  1185. // or a python function object
  1186. //
  1187. // pyszScript - script file contents - module content - ignored if pszId is given
  1188. // pszId - module name with extension - modules live in scripts/vscripts
  1189. //
  1190. //-------------------------------------------------------------
  1191. HSCRIPT CompileScript( const char *pszScript, const char *pszId = NULL )
  1192. {
  1193. if ( pszId )
  1194. {
  1195. // pszId is the module name with extension - required for python
  1196. Assert(pszId != NULL);
  1197. PyObject *pName;
  1198. // strip module extension
  1199. char buffer[1024];
  1200. V_StripExtension( pszId, buffer, sizeof(buffer) );
  1201. pName = PyString_FromString(buffer); // new ref
  1202. return (HSCRIPT)pName; // return the name of the module to later import (and run). compilation is automatic.
  1203. }
  1204. else
  1205. {
  1206. // code string fixup:
  1207. /* Replace any occurances of "\r\n?" in the input string with "\n".
  1208. This converts DOS and Mac line endings to Unix line endings.
  1209. Also append a trailing "\n" to be compatible with
  1210. PyParser_SimpleParseFile(). Returns a new reference. */
  1211. if ( !pszScript || !*pszScript )
  1212. {
  1213. DevWarning ( "Vscript: no script text passed to CompileScript - ignoring compilation!");
  1214. return NULL;
  1215. }
  1216. char *buf;
  1217. {
  1218. char *q;
  1219. const char *p = pszScript;
  1220. if (!p)
  1221. return NULL;
  1222. /* one char extra for trailing \n and one for terminating \0 */
  1223. buf = (char *)PyMem_Malloc( strlen(pszScript) + 2);
  1224. if (buf == NULL) {
  1225. PyErr_SetString(PyExc_MemoryError,
  1226. "Python Source Compile - no memory to allocate conversion buffer!");
  1227. return NULL;
  1228. }
  1229. /* replace "\r\n?" by "\n" */
  1230. for (q = buf; *p != '\0'; p++) {
  1231. if (*p == '\r') {
  1232. *q++ = '\n';
  1233. if (*(p + 1) == '\n')
  1234. p++;
  1235. }
  1236. else
  1237. *q++ = *p;
  1238. }
  1239. *q++ = '\n'; /* add trailing \n */
  1240. *q = '\0';
  1241. }
  1242. // create a new python code object - we own the reference which we must release later
  1243. // NOTE: must pass full path to source file to enable debugging in external IDE (such as Wing IDE Professional).
  1244. char szFullPath[MAX_PATH];
  1245. if ( pszId )
  1246. {
  1247. V_ComposeFileName( m_szScriptPath, pszId, szFullPath, sizeof(szFullPath) );
  1248. }
  1249. PyObject *pyCodeObject = Py_CompileString(buf, (pszId) ? szFullPath : "unnamed", Py_file_input);
  1250. // PyObject *pyCodeObject = Py_CompileString(buf, "U:\\projects\\sob\\game\\sob\\scripts\\vscripts\\mapspawn.py", Py_file_input);
  1251. PyPrintError();
  1252. PyMem_Free(buf);
  1253. return (HSCRIPT)pyCodeObject; // return a code object - NULL on compile error
  1254. }
  1255. }
  1256. //-------------------------------------------------------------
  1257. // release code object, string object (module) or instance object
  1258. //-------------------------------------------------------------
  1259. void ReleaseScript( HSCRIPT hScript )
  1260. {
  1261. Assert( hScript );
  1262. AssertIsPyObject( hScript );
  1263. if ( !PyString_Check( (PyObject *)hScript ) && !PyCode_Check( (PyObject *)hScript ) )
  1264. {
  1265. AssertIsInstance( hScript );
  1266. }
  1267. Py_XDECREF((PyObject *)hScript);
  1268. }
  1269. //-------------------------------------------------------------
  1270. // create an empty scope object - use SetModule and SetInstance
  1271. // to create actual references to dictionaries.
  1272. //-------------------------------------------------------------
  1273. HSCRIPT CreateScope( const char *pszScope, HSCRIPT hParent = NULL )
  1274. {
  1275. CPyScope *pPyScope = new CPyScope();
  1276. if ( hParent )
  1277. {
  1278. DevMsg( "Warning, Python script language ignoring hParent parameter for CreateScope!" );
  1279. }
  1280. return (HSCRIPT)pPyScope;
  1281. }
  1282. //-------------------------------------------------------------
  1283. // delete the CPyScope object
  1284. //-------------------------------------------------------------
  1285. void ReleaseScope( HSCRIPT hScript )
  1286. {
  1287. AssertIsScope( hScript );
  1288. if ( hScript )
  1289. delete (CPyScope *)hScript;
  1290. }
  1291. //-------------------------------------------------------------
  1292. // return a python PyObject* given a named variable in the given scope's instance object.
  1293. // python object is a new reference if bAddRef is true, otherwise borrowed reference.
  1294. //-------------------------------------------------------------
  1295. PyObject* LookupObject( const char *pszObject, HSCRIPT hScope = NULL, bool bAddRef = true )
  1296. {
  1297. if ( hScope == INVALID_HSCRIPT )
  1298. return NULL;
  1299. PyObject *pGlobals = InstanceDictFromScope( hScope );
  1300. // Return the object from globals dict using key. Return NULL if the key is not present.
  1301. PyObject *pyobj;
  1302. pyobj = PyDict_GetItemString( pGlobals, pszObject); // returns borrowed reference - we don't own this obj unless we increment the reference.
  1303. PyPrintError();
  1304. if ( pyobj == NULL)
  1305. // key not in dict
  1306. return NULL;
  1307. if ( bAddRef )
  1308. Py_XINCREF(pyobj);
  1309. return pyobj;
  1310. }
  1311. //-------------------------------------------------------------
  1312. // return a python function object - lookup function in MODULE scope dict -
  1313. // NOTE: this will only work correctly AFTER CompileScript and
  1314. // Run or ExecuteFunction is called on the script which holds the function.
  1315. // NOTE: caller must call ReleaseFunction when finished with function!
  1316. //-------------------------------------------------------------
  1317. HSCRIPT LookupFunction( const char *pszFunction, HSCRIPT hScope = NULL )
  1318. {
  1319. // UNDONE: CBaseEntity calls this for EVERY think cycle -
  1320. // UNDONE: rewrite CBaseEntity to remember the think function handle!
  1321. if ( hScope == INVALID_HSCRIPT )
  1322. return NULL;
  1323. PyObject *pGlobals;
  1324. if ( hScope )
  1325. {
  1326. pGlobals = ((CPyScope *)hScope)->GetModuleDict();
  1327. }
  1328. else
  1329. {
  1330. pGlobals = m_pValveScope->GetModuleDict(); // lookup function in valve scope
  1331. }
  1332. if ( !pGlobals )
  1333. {
  1334. DevWarning("Vscript, vpython.cpp: LookupFunction - must first compile and run the script before you can lookup a function!");
  1335. return NULL;
  1336. }
  1337. PyObject *pFunc = PyDict_GetItemString(pGlobals, pszFunction); // borrowed reference
  1338. // set up function object with scope
  1339. PyPrintError();
  1340. if (pFunc != NULL && PyCallable_Check(pFunc) )
  1341. {
  1342. Py_INCREF( pFunc ); // inc ref so obj can be released later
  1343. DEBUG_FUNCCOUNT++;
  1344. Assert(DEBUG_FUNCCOUNT < 1000); // if this fails, server is likely not freeing function handles (leaking each frame)
  1345. return (HSCRIPT )pFunc;
  1346. }
  1347. else
  1348. {
  1349. return NULL;
  1350. }
  1351. }
  1352. //-------------------------------------------------------------
  1353. // decrement our reference to the function handle
  1354. //-------------------------------------------------------------
  1355. void ReleaseFunction( HSCRIPT hScript )
  1356. {
  1357. AssertIsPyObject( hScript );
  1358. Py_XDECREF((PyObject *)hScript);
  1359. DEBUG_FUNCCOUNT--;
  1360. //ReleaseScriptObject( hScript );
  1361. }
  1362. //-------------------------------------------------------------
  1363. // given a handle to a python function, a compiled code object,
  1364. // or a module name, execute the object. If given a module name,
  1365. // also sets the module object in the hScope for subsequent
  1366. // execution of functions in module scope. Caller must free
  1367. // variant args & any newly returned variant.
  1368. //-------------------------------------------------------------
  1369. ScriptStatus_t ExecuteFunction( HSCRIPT hFunction, ScriptVariant_t *pArgs, int nArgs, ScriptVariant_t *pReturn, HSCRIPT hScope = NULL, bool bWait = true )
  1370. {
  1371. if ( hScope == INVALID_HSCRIPT || !hFunction)
  1372. {
  1373. // DevWarning( "Invalid scope handed to script VM\n" );
  1374. return SCRIPT_ERROR;
  1375. }
  1376. AssertIsScope( hScope );
  1377. AssertIsPyObject( hFunction );
  1378. Assert ( bWait );
  1379. PyObject *pGlobals = ModuleDictFromScope( hScope );
  1380. // get type of hfunction - may be string (module), function, or compiled code object
  1381. if ( PyString_Check( (PyObject *)hFunction) )
  1382. {
  1383. // Import a module and set the hScope module variable.
  1384. // NOTE: this is required before lookup/executeFunction calls into the module.
  1385. // hFunction is a module name - may be returned by CompileScript
  1386. // equivalent to python "import modulename"
  1387. // note: python auto compiles the module if it is out of date, and saves the
  1388. // binary image to disk for faster load times (no compile) on future import calls.
  1389. ScriptStatus_t result = SCRIPT_DONE;
  1390. PyObject *pModule;
  1391. // char *pszModuleName = PyString_AsString( (PyObject *)hFunction ); // internal pointer
  1392. // import and run module - always runs in global scope
  1393. // PyObject *pystr = PyString_FromString( pszModuleName );
  1394. pModule = PyImport_Import( (PyObject *)hFunction );
  1395. // Py_XDECREF( pystr );
  1396. // set the module object in the scope.
  1397. if ( hScope )
  1398. ( (CPyScope *)hScope )->SetModuleObject( pModule );
  1399. Py_XDECREF(pModule);
  1400. PyPrintError();
  1401. if ( !pModule )
  1402. result = SCRIPT_ERROR;
  1403. return result;
  1404. }
  1405. else if ( PyFunction_Check( (PyObject *)hFunction) || PyCallable_Check((PyObject *)hFunction) )
  1406. {
  1407. // Run a function in a module:
  1408. // hFunction is a python function object.
  1409. // NOTE: hScope is ignored - it was associated with the function object during function lookup (function's module)
  1410. // NOTE: first argument is always 'self' of the calling entity, even if NULL
  1411. PyObject *pPyArgs = PyTuple_New(nArgs+1);
  1412. PyObject *pValue;
  1413. int i;
  1414. // first argument is always 'self' ,even if NULL
  1415. PyObject *pSelf = NULL;
  1416. if ( hScope )
  1417. {
  1418. pSelf = ((CPyScope *)hScope)->GetInstanceObject();
  1419. }
  1420. if ( !pSelf )
  1421. pSelf = Py_None;
  1422. Py_XINCREF( pSelf );
  1423. PyTuple_SetItem(pPyArgs, 0, pSelf); // steals ref to pSelf
  1424. for (i = 0; i < nArgs; ++i)
  1425. {
  1426. pValue = ConvertToPyObject( pArgs[i], true ); // new ref
  1427. // pValue reference stolen here: tuple owns the objects now
  1428. PyTuple_SetItem(pPyArgs, i+1, pValue);
  1429. }
  1430. PyObject *pPyReturn = PyObject_CallObject((PyObject *)hFunction, pPyArgs);
  1431. Py_DECREF(pPyArgs); // release tuple and contents
  1432. PyPrintError();
  1433. if ( pPyReturn == NULL )
  1434. {
  1435. // call failed
  1436. return SCRIPT_ERROR;
  1437. }
  1438. bool bFreeobj = false;
  1439. if ( pReturn )
  1440. {
  1441. bFreeobj = ConvertToVariant( pPyReturn, pReturn ); // caller must free this
  1442. }
  1443. Py_XDECREF(pPyReturn);
  1444. return SCRIPT_DONE;
  1445. }
  1446. else
  1447. {
  1448. // Run compiled code in a module:
  1449. // assume hFunction is a compiled code object
  1450. PyObject *pValue;
  1451. PyObject *rgpyArgs[31];
  1452. PyObject *pPyReturn;
  1453. Assert ( nArgs < 32 );
  1454. // first argument is always 'self' ,even if NULL
  1455. PyObject *pSelf = ((CPyScope *)hScope)->GetInstanceObject();
  1456. if ( !pSelf )
  1457. pSelf = Py_None;
  1458. Py_XINCREF( pSelf );
  1459. rgpyArgs[0] = pSelf; // arg steals ref to pSelf
  1460. int i;
  1461. for (i = 0; i < nArgs; i++)
  1462. {
  1463. pValue = ConvertToPyObject( pArgs[i], true ); // create new python objects with new refs
  1464. rgpyArgs[i+1] = pValue;
  1465. }
  1466. if (0)
  1467. {
  1468. char *pszdebug = PyString_AsString( ((PyCodeObject *)hFunction)->co_filename );
  1469. char buffer[1024];
  1470. V_StripExtension( pszdebug, buffer, sizeof(buffer) );
  1471. //Py_XDECREF( ((PyCodeObject *)hFunction)->co_filename );
  1472. //((PyCodeObject *)hFunction)->co_filename = PyString_FromString( buffer );
  1473. PyObject *pystr = PyString_FromString( buffer );
  1474. PyObject *pmodule = PyImport_Import( pystr );
  1475. Py_XDECREF( pystr );
  1476. // BUG: this executes in the module's scope, which is not per-instance.
  1477. // PyObject *pmodule = PyImport_ExecCodeModule( buffer, (PyObject *)hFunction );
  1478. Py_XDECREF( pmodule );
  1479. pPyReturn = Py_None;
  1480. Py_INCREF( pPyReturn );
  1481. }
  1482. else
  1483. {
  1484. // NOTE: This function will actually
  1485. // run the code within the given scope dictionary - must be a module-level dictionary.
  1486. pPyReturn = PyEval_EvalCodeEx((PyCodeObject *)hFunction,
  1487. pGlobals, //PyObject *globals,
  1488. pGlobals, //PyObject *locals,
  1489. rgpyArgs, nArgs, //PyObject **args, int argc,
  1490. NULL, 0, //PyObject **kwds, int kwdc,
  1491. NULL, 0, //PyObject **defs, int defc,
  1492. NULL); //PyObject *closure
  1493. }
  1494. // release arg objects
  1495. for (i = 0; i < nArgs; i++)
  1496. Py_XDECREF(rgpyArgs[i]);
  1497. if ( pPyReturn == NULL )
  1498. {
  1499. // call failed
  1500. PyPrintError();
  1501. return SCRIPT_ERROR;
  1502. }
  1503. bool bFreeobj = false;
  1504. if ( pReturn )
  1505. {
  1506. bFreeobj = ConvertToVariant( pPyReturn, pReturn ); // caller must free this
  1507. }
  1508. Py_XDECREF(pPyReturn);
  1509. return SCRIPT_DONE;
  1510. }
  1511. // invalid hFunction
  1512. return SCRIPT_ERROR;
  1513. }
  1514. //-------------------------------------------------------------
  1515. // register a new function so python code can call it
  1516. //-------------------------------------------------------------
  1517. void RegisterFunction( ScriptFunctionBinding_t *pScriptFunction )
  1518. {
  1519. // if ( VMInitFinalized() )
  1520. // return;
  1521. RegisterFunctionGuts( pScriptFunction );
  1522. // NOTE: DEFINE_SCRIPTFUNC and ScripRegisterFunction macros eventually call RegisterFunction.
  1523. // Templates automatically create the ScriptFunctionBinding_t.
  1524. // Following is a summary of the Template expansion for ScriptRegisterFunction(Named) which
  1525. // builds the ScriptFunctionBinding_t in place and then calls ResisterFunction with it.
  1526. // This scheme effectively uses C++ compile-time templates to implement function introspection:
  1527. /*
  1528. ScriptRegisterFunctionNamed( g_pScriptVM, ScriptCreateSceneEntity, "CreateSceneEntity", "Create a scene entity to play the specified scene." );
  1529. #define ScriptRegisterFunctionNamed( pVM, func, scriptName, description )
  1530. static ScriptFunctionBinding_t binding;
  1531. binding.m_desc.m_pszDescription = description;
  1532. binding.m_desc.m_Parameters.RemoveAll();
  1533. ScriptInitFunctionBindingNamed( &binding, func, scriptName );
  1534. #define ScriptInitFunctionBindingNamed( pScriptFunction, func, scriptName )
  1535. ScriptInitFuncDescriptorNamed( (&(pScriptFunction)->m_desc), func, scriptName );
  1536. #define ScriptInitFuncDescriptorNamed( pDesc, func, scriptName )
  1537. (pDesc)->m_pszScriptName = scriptName;
  1538. (pDesc)->m_pszFunction = #func;
  1539. ScriptDeduceFunctionSignature( pDesc, &func );
  1540. // this is a complex macro which, at compile time,
  1541. // inlines the code to fill out the remaing fields in the
  1542. // pDesc structure with the appropriate arg types and return types
  1543. // for the given function.
  1544. (pScriptFunction)->m_pfnBinding = ScriptCreateBinding( &func ); // uses functors to create the binding function
  1545. (pScriptFunction)->m_pFunction = (void *)&func;
  1546. pVM->RegisterFunction( &binding );
  1547. }
  1548. */
  1549. }
  1550. //-------------------------------------------------------------
  1551. // create a new python type object encapsulating the class -
  1552. // NOTE: must subsequently call PyType_Ready to finalize the class
  1553. //-------------------------------------------------------------
  1554. PyTypeObject *CreateClass( ScriptClassDesc_t *pDesc )
  1555. {
  1556. // python class template
  1557. static PyTypeObject scriptClassType = {
  1558. PyObject_HEAD_INIT(NULL) /* type type */ // set up by PyType_Ready() call later
  1559. 0, /*ob_size*/
  1560. 0, /*tp_name*/
  1561. sizeof(scriptClassInstance_t), /*tp_basicsize*/
  1562. 0, /*tp_itemsize*/
  1563. 0, /*tp_dealloc*/ // consider
  1564. 0, /*tp_print*/
  1565. 0, /*tp_getattr*/
  1566. 0, /*tp_setattr*/
  1567. 0, /*tp_compare*/
  1568. (reprfunc)InstanceToString, /*tp_repr*/ // consider
  1569. 0, /*tp_as_number*/
  1570. 0, /*tp_as_sequence*/
  1571. 0, /*tp_as_mapping*/
  1572. 0, /*tp_hash */
  1573. 0, /*tp_call*/
  1574. 0, /*tp_str*/
  1575. PyObject_GenericGetAttr, /*tp_getattro*/
  1576. PyObject_GenericSetAttr, /*tp_setattro*/
  1577. 0, /*tp_as_buffer*/
  1578. Py_TPFLAGS_DEFAULT, // | Py_TPFLAGS_BASETYPE, /*tp_flags*/ // allow subclassing
  1579. 0, /* tp_doc */
  1580. 0, /* tp_traverse */
  1581. 0, /* tp_clear */
  1582. 0, /* tp_richcompare */
  1583. 0, /* tp_weaklistoffset */
  1584. 0, /* tp_iter */
  1585. 0, /* tp_iternext */
  1586. 0, /* tp_methods */
  1587. 0, /* tp_members */
  1588. 0, /* tp_getset */
  1589. 0, /* tp_base */ // base class type object
  1590. 0, /* tp_dict */
  1591. 0, /* tp_descr_get */
  1592. 0, /* tp_descr_set */
  1593. offsetof(scriptClassInstance_t, pDict), // tp_dictoffset - used by generic getattr,setattr
  1594. 0, /* tp_init */ // consider
  1595. PyType_GenericAlloc, /* tp_alloc */
  1596. PyType_GenericNew, /* tp_new */ // consider
  1597. PyObject_Del, /* tp_free */
  1598. };
  1599. // build a new scriptClassType for each 'CreateClass' call
  1600. PyTypeObject *pnewtype = (PyTypeObject *) PyMem_Malloc( sizeof(PyTypeObject) ); //new PyTypeObject;
  1601. if ( !pnewtype )
  1602. {
  1603. // interperter out of memory
  1604. Assert( false );
  1605. return NULL;
  1606. }
  1607. // track it so we can free it later
  1608. Assert (m_iClassDef < MAX_VALVE_CLASSES_EXPORTED );
  1609. m_rgpClassDefs[m_iClassDef++] = pnewtype;
  1610. // allow mapping between PyTypeObject (accessed from pSelf->ob_type ptr) to ScriptClassDesc_t pDesc.
  1611. // init the pnewtype with the static template
  1612. V_memcpy( pnewtype, &scriptClassType, sizeof(PyTypeObject) );
  1613. pnewtype->tp_doc = pDesc->m_pszDescription;
  1614. pnewtype->tp_name = pDesc->m_pszScriptName; // BUG: prepend "valve." or pickling is impossible
  1615. // if base class given, make sure base class type already defined in root scope
  1616. // then hook it up to our type
  1617. if ( pDesc->m_pBaseDesc )
  1618. {
  1619. PyObject *pdict = m_pValveScope->GetModuleDict();
  1620. if ( PyDict_GetItemString( pdict, pDesc->m_pBaseDesc->m_pszScriptName ) == NULL )
  1621. {
  1622. Assert( false ); // base class should have been pre registered in 'valve' module
  1623. return NULL;
  1624. }
  1625. // lookup the corresponding type object
  1626. PyTypeObject *pbasetype = PyTypeFromDesc( pDesc->m_pBaseDesc );
  1627. if ( !pbasetype )
  1628. {
  1629. Assert ( false );
  1630. return NULL;
  1631. }
  1632. pnewtype->tp_base = pbasetype;
  1633. }
  1634. // set up constructor and destructor
  1635. // DEALLOCATION CHAIN: Py_XDECREF -> tp_dealloc (free any local allocations) -> tp_free (free python object allocation)
  1636. // ALLOCATION CHAIN: tp_new, tp_alloc (create empty python object) -> tp_init (set up local data)
  1637. pnewtype->tp_new = PyType_GenericNew; // create new uninitialized object (just calls tp_alloc) // BUG: doesn't call tp_init!
  1638. pnewtype->tp_init = (initproc)CPythonVM::InitInstance; // same as __init__ for class - init the context associated with the object
  1639. pnewtype->tp_alloc = PyType_GenericAlloc; // alloc space for a python object
  1640. pnewtype->tp_free = PyObject_Del; // delete the python object
  1641. pnewtype->tp_dealloc = (destructor)CPythonVM::FreeInstance; // called when ref count drops to 0 - release any memory held by object
  1642. // (ie: call destructor on underlaying valve object if object was allocated from python )
  1643. // UNDONE: implement these additional callbacks
  1644. //sq_pushstring( m_hVM, "_tostring", -1 );
  1645. //sq_newclosure( m_hVM, &InstanceToString, 0 );
  1646. //sq_createslot( m_hVM, -3 );
  1647. //sq_pushstring( m_hVM, "IsValid", -1 );
  1648. //sq_newclosure( m_hVM, &InstanceIsValid, 0 );
  1649. //sq_createslot( m_hVM, -3 );
  1650. // register all methods - create tp_methods table of pnewtype
  1651. int count = pDesc->m_FunctionBindings.Count();
  1652. if ( count )
  1653. {
  1654. // create an array large enough for all method defs + null semaphore
  1655. PyMethodDef *pmethods = (PyMethodDef *) PyMem_Malloc( sizeof(PyMethodDef) * (count + 1) ); // new PyMethodDef[count+1];
  1656. PyMethodDef *pm;
  1657. if ( !pmethods )
  1658. {
  1659. // interperter out of memory
  1660. Assert ( false );
  1661. return NULL;
  1662. }
  1663. Assert (m_iMethodDef < MAX_VALVE_FUNCTIONS_EXPORTED );
  1664. m_rgpMethodDefs[m_iMethodDef++] = pmethods;
  1665. // TEST1:m_pMethodDefs.AddToTail( pmethods );
  1666. int i;
  1667. for ( i = 0; i < count; i++ )
  1668. {
  1669. ScriptFunctionBinding_t *pScriptFunction = &(pDesc->m_FunctionBindings[i]);
  1670. pm = &(pmethods[i]);
  1671. // fill python method def
  1672. pm->ml_name = pScriptFunction->m_desc.m_pszScriptName;
  1673. pm->ml_flags = METH_VARARGS;
  1674. pm->ml_doc = pScriptFunction->m_desc.m_pszDescription;
  1675. int proxyId = GetNewProxyId();
  1676. SetProxyBinding( proxyId, pScriptFunction );
  1677. // the function/method callback chain - python calls Translate_XXX -> calls TranslateCall -> calls binding function -> actual function.
  1678. pm->ml_meth = GetProxyFunction( proxyId );
  1679. }
  1680. // set null semaphore at end of methods
  1681. pm = &(pmethods[i]);
  1682. pm->ml_name = NULL;
  1683. pm->ml_meth = NULL;
  1684. pm->ml_flags = 0;
  1685. pm->ml_doc = NULL;
  1686. pnewtype->tp_methods = pmethods;
  1687. }
  1688. return pnewtype;
  1689. }
  1690. //-------------------------------------------------------------
  1691. // create new python type object for this class and include
  1692. // ScriptClassDesc_t in the user type data.
  1693. //-------------------------------------------------------------
  1694. bool RegisterClass( ScriptClassDesc_t *pClassDesc )
  1695. {
  1696. // if ( VMInitFinalized() )
  1697. // return true;
  1698. PyObject *valveModule = m_pValveScope->GetModule();
  1699. PyObject *pdict = m_pValveScope->GetModuleDict();
  1700. if ( PyDict_GetItemString( pdict, pClassDesc->m_pszScriptName ) != NULL )
  1701. return true; // already registered
  1702. COMPILE_TIME_ASSERT( sizeof(pClassDesc) == sizeof(int) );
  1703. if ( PyTypeFromDesc( pClassDesc ) )
  1704. {
  1705. return true;
  1706. }
  1707. // register base class first
  1708. if ( pClassDesc->m_pBaseDesc )
  1709. {
  1710. CPythonVM::RegisterClass( pClassDesc->m_pBaseDesc );
  1711. }
  1712. PyTypeObject *pnewtype = CreateClass( pClassDesc );
  1713. if ( pnewtype == NULL )
  1714. return false;
  1715. // finalize the new python type
  1716. if (PyType_Ready( pnewtype ) < 0)
  1717. return false;
  1718. // add the new class type to the 'valve' module
  1719. Py_INCREF( pnewtype );
  1720. PyModule_AddObject( valveModule, pClassDesc->m_pszScriptName, (PyObject *)pnewtype );
  1721. m_TypeMap.Insert( (int)pClassDesc, pnewtype ); // mapping from pClassDesc to PyTypeObject needed for RegisterInstance
  1722. m_ClassMap.Insert( (int)pnewtype, pClassDesc ); // mapping from PyTypeObject to pClassDesc needed for InitInstance constructor callback
  1723. if ( PyDict_GetItemString( pdict, pClassDesc->m_pszScriptName ) == NULL )
  1724. {
  1725. Assert ( false );
  1726. return false; // class wasn't added to valve module!
  1727. }
  1728. PyPrintError();
  1729. return true;
  1730. }
  1731. //-------------------------------------------------------------
  1732. // auto-register instance class, and return script instance obj:
  1733. // such as a cbaseentity instance, Entities iterator list etc
  1734. //-------------------------------------------------------------
  1735. HSCRIPT RegisterInstance( ScriptClassDesc_t *pDesc, void *pInstance )
  1736. {
  1737. // auto-create the instance's class if not already created
  1738. if ( !CPythonVM::RegisterClass( pDesc ) )
  1739. {
  1740. return NULL;
  1741. }
  1742. // create a new python instance - this winds up calling InitInstance to set up the instanceContext
  1743. // x = CEntity( pInstance ) # python code
  1744. PyObject *pcallable = PyDict_GetItemString( m_pValveScope->GetModuleDict(), pDesc->m_pszScriptName ); // borrowed ref
  1745. scriptClassInstance_t *ppyobj = NULL;
  1746. if ( pcallable && PyCallable_Check( pcallable ) )
  1747. {
  1748. // create new script object
  1749. ppyobj = (scriptClassInstance_t *)PyObject_CallObject( pcallable, NULL); // new ref
  1750. ppyobj->typeTag = TYPETAG_INSTANCE;
  1751. // make sure type name matches
  1752. if ( ppyobj->ob_type->tp_name != pDesc->m_pszScriptName )
  1753. {
  1754. Assert ( false );
  1755. return NULL;
  1756. }
  1757. // fill in the instance context for the new object
  1758. ppyobj->instanceContext.pInstance = pInstance;
  1759. ppyobj->instanceContext.pPyName = NULL;
  1760. ppyobj->instanceContext.pClassDesc = pDesc;
  1761. ppyobj->pDict = PyDict_New();
  1762. }
  1763. PyPrintError();
  1764. return (HSCRIPT)ppyobj;
  1765. }
  1766. //-------------------------------------------------------------
  1767. // set a unique string in the instance object.
  1768. //-------------------------------------------------------------
  1769. void SetInstanceUniqeId( HSCRIPT hInstance, const char *pszId )
  1770. {
  1771. AssertIsInstance( hInstance );
  1772. // make sure this is an object type we have defined
  1773. if ( pszId && pDescFromPyObj( (PyObject *)hInstance ) )
  1774. {
  1775. ((scriptClassInstance_t *)hInstance)->instanceContext.pPyName = PyString_FromString( pszId );
  1776. }
  1777. }
  1778. //-------------------------------------------------------------
  1779. // set instance pointer to valve server object to null
  1780. // and release the python object
  1781. //-------------------------------------------------------------
  1782. void RemoveInstance( HSCRIPT hInstance )
  1783. {
  1784. AssertIsInstance( hInstance );
  1785. // make sure this is an object type we have defined
  1786. if ( pDescFromPyObj( (PyObject *)hInstance ) )
  1787. {
  1788. ReleaseScriptObject( hInstance );
  1789. debugRemoveTrackedObject( (PyObject *) hInstance );
  1790. }
  1791. }
  1792. //-------------------------------------------------------------
  1793. // Return server-side object from python object
  1794. //-------------------------------------------------------------
  1795. void *GetInstanceValue( HSCRIPT hInstance, ScriptClassDesc_t *pExpectedType )
  1796. {
  1797. AssertIsInstance( hInstance );
  1798. // make sure this is an object type we have defined
  1799. if ( pDescFromPyObj( (PyObject *)hInstance ) )
  1800. {
  1801. InstanceContext_t *pContext = &( ((scriptClassInstance_t *)hInstance)->instanceContext );
  1802. if ( !pExpectedType || pContext->pClassDesc == pExpectedType || IsClassDerivedFrom( pContext->pClassDesc, pExpectedType ) )
  1803. return pContext->pInstance;
  1804. }
  1805. return NULL;
  1806. }
  1807. //-------------------------------------------------------------
  1808. // return true if derived class derives from base class.
  1809. //-------------------------------------------------------------
  1810. bool IsClassDerivedFrom( const ScriptClassDesc_t *pDerivedClass, const ScriptClassDesc_t *pBaseClass )
  1811. {
  1812. const ScriptClassDesc_t* pType = pDerivedClass->m_pBaseDesc;
  1813. while ( pType )
  1814. {
  1815. if ( pType == pBaseClass )
  1816. return true;
  1817. pType = pType->m_pBaseDesc;
  1818. }
  1819. return false;
  1820. }
  1821. bool GenerateUniqueKey( const char *pszRoot, char *pBuf, int nBufSize )
  1822. {
  1823. Assert( V_strlen(pszRoot) + 32 <= nBufSize );
  1824. Q_snprintf( pBuf, nBufSize, "%x%I64x%s", RandomInt(0, 0xfff), m_iUniqueIdSerialNumber++, pszRoot ); // random to limit key compare when serial number gets large
  1825. return true;
  1826. }
  1827. //-------------------------------------------------------------
  1828. // return true if key has a value in scope's instance object.
  1829. // CONSIDER: if no instance object, try module object, if no module
  1830. // object, try global scope.
  1831. //-------------------------------------------------------------
  1832. virtual bool ValueExists( HSCRIPT hScope, const char *pszKey )
  1833. {
  1834. if ( hScope == INVALID_HSCRIPT )
  1835. return false;
  1836. AssertIsScope( hScope );
  1837. PyObject *pGlobals = InstanceDictFromScope( hScope );
  1838. if ( !pGlobals )
  1839. // pGlobals = ModuleDictFromScope( hScope );
  1840. return false;
  1841. Assert ( pGlobals );
  1842. if ( PyObject_HasAttrString( pGlobals, pszKey ) )
  1843. return true;
  1844. return false;
  1845. }
  1846. bool SetValue( HSCRIPT hScope, const char *pszKey, const char *pszValue )
  1847. {
  1848. return SetValueInternal( hScope, pszKey, NULL, pszValue );
  1849. }
  1850. bool SetValue( HSCRIPT hScope, const char *pszKey, const ScriptVariant_t &value )
  1851. {
  1852. return SetValueInternal( hScope, pszKey, value, NULL );
  1853. }
  1854. //-------------------------------------------------------------
  1855. // set key:value pair in given scope's instance object dict.
  1856. // if hScope is NULL, set data in global scope. caller still owns
  1857. // object if is an Hscript (i.e. must free it).
  1858. //
  1859. // !!!NOTE!!!: data is not actually flushed into the instance object
  1860. // until a 'self' instance value is set in the scope. At that
  1861. // time, all previously set data will be visible in python
  1862. // on the instance object. In python code, the instance is named 'self'
  1863. // and is passed as the first param to all function calls.
  1864. //-------------------------------------------------------------
  1865. bool SetValueInternal( HSCRIPT hScope, const char *pszKey, const ScriptVariant_t &value, const char *pszValue )
  1866. {
  1867. if ( hScope == INVALID_HSCRIPT )
  1868. return false;
  1869. AssertIsScope( hScope );
  1870. CPyScope *pScope = (CPyScope *)hScope;
  1871. PyObject *pyobj;
  1872. if ( pszValue )
  1873. {
  1874. pyobj = PyString_FromString( pszValue ); // new reference
  1875. }
  1876. else
  1877. {
  1878. // trap special 'self' instance - save it in the CPyScope object
  1879. if ( value.m_type == FIELD_HSCRIPT )
  1880. {
  1881. // instance object...
  1882. if ( !V_strcmp(pszKey, "self") )
  1883. {
  1884. // save instance in scope
  1885. PyObject *pyobj = ConvertToPyObject( value, true ); // new ref
  1886. pScope->SetInstanceObject( pyobj ); // inc ref to object
  1887. Py_XDECREF( pyobj ); // for hscript objects, caller owns the hscript within the variant, not us
  1888. // copy scope temp dict into instance dict.
  1889. pScope->TransferTempDictToInstance();
  1890. return true;
  1891. }
  1892. }
  1893. // set a new copy of the value in instance's dict
  1894. pyobj = ConvertToPyObject( value, true );
  1895. if ( value.m_type == FIELD_HSCRIPT)
  1896. {
  1897. Py_XDECREF( pyobj ); // for hscript objects, caller owns the hscript within the variant, not us
  1898. debugTrackObject( pyobj );
  1899. }
  1900. }
  1901. PyObject *pGlobals;
  1902. if ( !hScope )
  1903. {
  1904. // set data in valve module scope
  1905. pGlobals = m_pValveScope->GetModuleDict();
  1906. }
  1907. else
  1908. {
  1909. // place all other data in scope's instance object dict
  1910. pGlobals = InstanceDictFromScope( hScope );
  1911. }
  1912. if ( !pGlobals )
  1913. {
  1914. // instance object 'self' not yet set up in scope - add to temporary dict
  1915. pScope->SetTempDictValue( pszKey, pyobj );
  1916. return true;
  1917. }
  1918. else
  1919. {
  1920. int ret = PyDict_SetItemString( pGlobals, pszKey, pyobj); // dict does not own the objects in it - but will decref old obj when overwritten.
  1921. if ( ret == -1 )
  1922. return false;
  1923. return true;
  1924. }
  1925. }
  1926. //------------------------------------------------------------------------------
  1927. // Purpose: create a new python dictionary object and return wrapped in a
  1928. // scriptVariant HScript object.
  1929. //----------------------------------------------------------------------------
  1930. void CreateTable( ScriptVariant_t &Table )
  1931. {
  1932. PyObject *pdict = PyDict_New();
  1933. ConvertToVariant( pdict, &Table );
  1934. return;
  1935. }
  1936. //------------------------------------------------------------------------------
  1937. // Purpose: returns the number of elements in the scope's instance object dict
  1938. // Input : hScope - the table
  1939. // Output : returns the number of elements in the table
  1940. //------------------------------------------------------------------------------
  1941. int GetNumTableEntries( HSCRIPT hScope )
  1942. {
  1943. if ( hScope == INVALID_HSCRIPT )
  1944. return 0;
  1945. AssertIsScope( hScope );
  1946. PyObject *pGlobals = InstanceDictFromScope( hScope );
  1947. int ret = (int) PyDict_Size( pGlobals );
  1948. return ret;
  1949. }
  1950. //------------------------------------------------------------------------------
  1951. // Purpose: Gets a key / value pair from the instance dictionary
  1952. // Input : hScope - the instance dictionary
  1953. // nInterator - the current location inside of the table. NOTE this is nota linear representation
  1954. // Output : returns the next iterator spot, otherwise -1 if error or end of table
  1955. // pKey - the key entry
  1956. // pValue - the value entry
  1957. //------------------------------------------------------------------------------
  1958. int GetKeyValue( HSCRIPT hScope, int nIterator, ScriptVariant_t *pKey, ScriptVariant_t *pValue )
  1959. {
  1960. if ( hScope == INVALID_HSCRIPT )
  1961. return -1;
  1962. PyObject *pGlobals = InstanceDictFromScope( hScope );
  1963. Py_ssize_t nNextIterator = (Py_ssize_t)nIterator;
  1964. PyObject *pPyKey, *pPyValue;
  1965. int ret;
  1966. ret = PyDict_Next( pGlobals, &nNextIterator, &pPyKey, &pPyValue );
  1967. if ( !ret )
  1968. {
  1969. // iteration complete
  1970. return -1;
  1971. }
  1972. ConvertToVariant( pPyKey, pKey );
  1973. ConvertToVariant( pPyValue, pValue );
  1974. return (int)nNextIterator;
  1975. }
  1976. //-------------------------------------------------------------
  1977. // lookup a key value in the scope's instance dictionary
  1978. //-------------------------------------------------------------
  1979. bool GetValue( HSCRIPT hScope, const char *pszKey, ScriptVariant_t *pValue )
  1980. {
  1981. PyObject *result = LookupObject( pszKey, hScope, false );
  1982. if ( ConvertToVariant( result, pValue ) && (result != Py_None) )
  1983. {
  1984. return true;
  1985. }
  1986. return false;
  1987. }
  1988. //-------------------------------------------------------------
  1989. // remove key from the given hscope - search instance scope,
  1990. // then module scope.
  1991. //-------------------------------------------------------------
  1992. bool ClearValue( HSCRIPT hScope, const char *pszKey )
  1993. {
  1994. if ( hScope == INVALID_HSCRIPT )
  1995. return false;
  1996. PyObject *pInstGlobals = NULL;
  1997. PyObject *pModuleGlobals = NULL;
  1998. int res;
  1999. if ( !hScope )
  2000. {
  2001. // clear data in valve module scope
  2002. pModuleGlobals = m_pValveScope->GetModuleDict();
  2003. }
  2004. else
  2005. {
  2006. pInstGlobals = ((CPyScope *)hScope)->GetInstanceDict();
  2007. pModuleGlobals = ((CPyScope *)hScope)->GetModuleDict();
  2008. }
  2009. PyObject *pystr = PyString_FromString( pszKey );
  2010. if ( pInstGlobals && PyDict_Contains( pInstGlobals, pystr ) )
  2011. {
  2012. res = PyDict_DelItemString( pInstGlobals, pszKey);
  2013. Py_XDECREF( pystr);
  2014. if ( res == -1 )
  2015. return false;
  2016. return true;
  2017. }
  2018. if ( pModuleGlobals && PyDict_Contains( pModuleGlobals, pystr ) )
  2019. {
  2020. res = PyDict_DelItemString( pModuleGlobals, pszKey);
  2021. Py_XDECREF( pystr);
  2022. if ( res == -1 )
  2023. return false;
  2024. return true;
  2025. }
  2026. return false;
  2027. }
  2028. //-------------------------------------------------------------
  2029. // release resources saved in script variant
  2030. //-------------------------------------------------------------
  2031. void ReleaseValue( ScriptVariant_t &value )
  2032. {
  2033. if ( value.m_flags & SV_FREE )
  2034. DEBUG_VARIANTCOUNT--;
  2035. if ( value.m_type == FIELD_HSCRIPT )
  2036. {
  2037. // drop our ref count to the python object
  2038. Py_XDECREF((PyObject *)value.m_hScript);
  2039. }
  2040. else
  2041. {
  2042. value.Free();
  2043. }
  2044. value.m_type = FIELD_VOID;
  2045. }
  2046. bool RaiseException( const char *pszExceptionText )
  2047. {
  2048. PyErr_SetString(PyExc_Exception, pszExceptionText);
  2049. return true;
  2050. }
  2051. virtual void DumpState()
  2052. {
  2053. // UNDONE:
  2054. /*struct CIterator : public CSQStateIterator
  2055. {
  2056. CIterator( HPYTHONVM hVM )
  2057. {
  2058. indent = 0;
  2059. m_hVM = hVM;
  2060. m_bKey = false;
  2061. }
  2062. void Indent()
  2063. {
  2064. for ( int i = 0; i < indent; i++)
  2065. {
  2066. Msg( " " );
  2067. }
  2068. }
  2069. virtual void PsuedoKey( const char *pszPsuedoKey )
  2070. {
  2071. Indent();
  2072. Msg( "%s: ", pszPsuedoKey );
  2073. m_bKey = true;
  2074. }
  2075. virtual void Key( SQObjectPtr &key )
  2076. {
  2077. Indent();
  2078. SQObjectPtr res;
  2079. m_hVM->ToString( key, res );
  2080. Msg( "%s: ", res._unVal.pString->_val );
  2081. m_bKey = true;
  2082. }
  2083. virtual void Value( SQObjectPtr &value )
  2084. {
  2085. if ( !m_bKey )
  2086. {
  2087. Indent();
  2088. }
  2089. m_bKey = false;
  2090. SQObjectPtr res;
  2091. m_hVM->ToString( value, res );
  2092. if ( ISREFCOUNTED(value._type) )
  2093. Msg( "%s [%d]\n", res._unVal.pString->_val, value._unVal.pRefCounted->_uiRef );
  2094. else
  2095. Msg( "%s\n", res._unVal.pString->_val );
  2096. }
  2097. virtual bool BeginContained()
  2098. {
  2099. if ( m_bKey )
  2100. {
  2101. Msg( "\n" );
  2102. }
  2103. m_bKey = false;
  2104. Indent();
  2105. Msg( "{\n" );
  2106. indent++;
  2107. return true;
  2108. }
  2109. virtual void EndContained()
  2110. {
  2111. indent--;
  2112. Indent();
  2113. Msg( "}\n" );
  2114. }
  2115. int indent;
  2116. HPYTHONVM m_hVM;
  2117. bool m_bKey;
  2118. };
  2119. CIterator iter( m_hVM );
  2120. m_hVM->_sharedstate->Iterate( m_hVM, &iter );*/
  2121. }
  2122. //-------------------------------------------------------------
  2123. //
  2124. //-------------------------------------------------------------
  2125. void WriteState( CUtlBuffer *pBuffer)
  2126. {
  2127. // UNDONE:
  2128. //#ifdef VPYTHON_DEBUG_SERIALIZATION
  2129. // Msg( "BEGIN WRITE\n" );
  2130. //#endif
  2131. // m_pBuffer = pBuffer;
  2132. // sq_collectgarbage( m_hVM );
  2133. //
  2134. // m_pBuffer->PutInt( SAVEVERSION );
  2135. // m_pBuffer->PutInt64( m_iUniqueIdSerialNumber );
  2136. // WriteVM( m_hVM );
  2137. //
  2138. // m_pBuffer = NULL;
  2139. //
  2140. // SQCollectable *t = m_hVM->_sharedstate->_gc_chain;
  2141. // while(t)
  2142. // {
  2143. // t->UnMark();
  2144. // t = t->_next;
  2145. // }
  2146. //
  2147. // m_PtrMap.Purge();
  2148. }
  2149. //-------------------------------------------------------------
  2150. //
  2151. //-------------------------------------------------------------
  2152. void ReadState( CUtlBuffer *pBuffer )
  2153. {
  2154. // UNDONE:
  2155. //#ifdef VPYTHON_DEBUG_SERIALIZATION
  2156. //#ifdef VPYTHON_DEBUG_SERIALIZATION_HEAPCHK
  2157. // g_pMemAlloc->CrtCheckMemory();
  2158. // int flags = g_pMemAlloc->CrtSetDbgFlag( _CRTDBG_REPORT_FLAG );
  2159. // g_pMemAlloc->CrtSetDbgFlag( flags | _CRTDBG_DELAY_FREE_MEM_DF | _CRTDBG_CHECK_ALWAYS_DF | _CRTDBG_CHECK_CRT_DF );
  2160. //#endif
  2161. // Msg( "BEGIN READ\n" );
  2162. //#endif
  2163. //
  2164. // if ( pBuffer->GetInt() != SAVEVERSION )
  2165. // {
  2166. // DevMsg( "Incompatible script version\n" );
  2167. // return;
  2168. // }
  2169. // sq_collectgarbage( m_hVM );
  2170. // m_hVM->_sharedstate->_gc_disableDepth++;
  2171. // m_pBuffer = pBuffer;
  2172. // int64 uniqueIdSerialNumber = m_pBuffer->GetInt64();
  2173. // m_iUniqueIdSerialNumber = max( m_iUniqueIdSerialNumber, uniqueIdSerialNumber );
  2174. // Verify( pBuffer->GetInt() == OT_THREAD );
  2175. // m_PtrMap.Insert( pBuffer->GetPtr(), m_hVM );
  2176. // ReadVM( m_hVM );
  2177. // m_pBuffer = NULL;
  2178. // m_PtrMap.Purge();
  2179. // m_hVM->_sharedstate->_gc_disableDepth--;
  2180. // sq_collectgarbage( m_hVM );
  2181. //
  2182. //#ifdef VPYTHON_DEBUG_SERIALIZATION_HEAPCHK
  2183. // g_pMemAlloc->CrtSetDbgFlag( flags );
  2184. //#endif
  2185. }
  2186. //-------------------------------------------------------------
  2187. //
  2188. //-------------------------------------------------------------
  2189. void RemoveOrphanInstances()
  2190. {
  2191. }
  2192. //-------------------------------------------------------------
  2193. //
  2194. //-------------------------------------------------------------
  2195. virtual void SetOutputCallback( ScriptOutputFunc_t pFunc )
  2196. {
  2197. }
  2198. //-------------------------------------------------------------
  2199. //
  2200. //-------------------------------------------------------------
  2201. virtual void SetErrorCallback( ScriptErrorFunc_t pFunc )
  2202. {
  2203. }
  2204. //---------------------------------------------------------------------------------
  2205. // The main call dispatcher - dispatches to C++ functions called from python.
  2206. // Get script binding object, translate args and dispatch to actual c function call
  2207. // NOTE: this must be static! (ie - it is called without a this ptr from the proxy functions)
  2208. //---------------------------------------------------------------------------------
  2209. static PyObject *TranslateCall( ScriptFunctionBinding_t *pVMScriptFunction, scriptClassInstance_t *pSelf, PyObject *pArgs)
  2210. {
  2211. int nActualParams = (int) PyTuple_Size( pArgs );
  2212. int nFormalParams = pVMScriptFunction->m_desc.m_Parameters.Count();
  2213. CUtlVectorFixed<ScriptVariant_t, 14> params;
  2214. ScriptVariant_t returnValue;
  2215. params.SetSize( nFormalParams );
  2216. // convert python params to vector of scriptVariant_t params as req'd by binding function
  2217. int i = 0;
  2218. PyObject *pyobj;
  2219. if ( nActualParams )
  2220. {
  2221. int iLimit = MIN( nActualParams, nFormalParams );
  2222. ScriptDataType_t *pCurParamType = pVMScriptFunction->m_desc.m_Parameters.Base();
  2223. for ( i = 0; i < iLimit; i++, pCurParamType++ )
  2224. {
  2225. pyobj = PyTuple_GetItem( pArgs, (Py_ssize_t)i );
  2226. switch ( *pCurParamType )
  2227. {
  2228. case FIELD_FLOAT:
  2229. {
  2230. if ( !PyFloat_Check( pyobj) )
  2231. {
  2232. PyErr_SetString(PyExc_ValueError, "expected float argument");
  2233. return NULL;
  2234. }
  2235. params[i] = PyFloat_AsDouble( pyobj );
  2236. }
  2237. break;
  2238. case FIELD_CSTRING:
  2239. {
  2240. if ( !PyString_Check( pyobj ) )
  2241. {
  2242. PyErr_SetString(PyExc_ValueError, "expected string argument");
  2243. return NULL;
  2244. }
  2245. params[i] = PyString_AsString( pyobj ); // DO NOT FREE THIS
  2246. Assert( !(params[i].m_flags &= SV_FREE ) );
  2247. }
  2248. break;
  2249. case FIELD_VECTOR:
  2250. {
  2251. if ( pyobj->ob_type != &PyTypeVector )
  2252. {
  2253. if ( !PyString_Check( pyobj ) )
  2254. {
  2255. PyErr_SetString(PyExc_ValueError, "expected vector argument");
  2256. return NULL;
  2257. }
  2258. }
  2259. Vector *pVector = ((PyVectorInstance_t *)pyobj)->pVector; // get pointer
  2260. if ( pVector )
  2261. {
  2262. params[i] = pVector; // DO NOT FREE THIS
  2263. Assert( !(params[i].m_flags &= SV_FREE ) );
  2264. break;
  2265. }
  2266. }
  2267. break;
  2268. case FIELD_INTEGER:
  2269. {
  2270. if ( !PyInt_Check( pyobj ) )
  2271. {
  2272. PyErr_SetString(PyExc_ValueError, "expected integer argument");
  2273. return NULL;
  2274. }
  2275. params[i] = PyInt_AsLong( pyobj );
  2276. }
  2277. break;
  2278. case FIELD_BOOLEAN:
  2279. {
  2280. if ( pyobj == Py_False )
  2281. {
  2282. params[i] = false;
  2283. }
  2284. else if ( pyobj == Py_True )
  2285. {
  2286. params[i] = true;
  2287. }
  2288. else
  2289. {
  2290. PyErr_SetString(PyExc_ValueError, "expected boolean argument");
  2291. return NULL;
  2292. }
  2293. }
  2294. break;
  2295. case FIELD_CHARACTER:
  2296. {
  2297. if ( !PyString_Check( pyobj ) )
  2298. {
  2299. PyErr_SetString(PyExc_ValueError, "expected string argument");
  2300. return NULL;
  2301. }
  2302. const char *psz = PyString_AsString( pyobj );
  2303. params[i] = *psz;
  2304. }
  2305. case FIELD_HSCRIPT:
  2306. {
  2307. if ( pyobj == Py_None )
  2308. {
  2309. params[i] = (HSCRIPT)NULL;
  2310. }
  2311. else
  2312. {
  2313. if ( ((scriptClassInstance_t *)pyobj)->typeTag != TYPETAG_INSTANCE )
  2314. {
  2315. PyErr_SetString(PyExc_ValueError, "expected HSCRIPT instance object argument");
  2316. return NULL;
  2317. }
  2318. params[i] = (HSCRIPT)pyobj; // (HSCRIPT)PyCObject_AsVoidPtr( pyobj );
  2319. }
  2320. break;
  2321. }
  2322. default:
  2323. break;
  2324. }
  2325. }
  2326. }
  2327. #ifdef _DEBUG
  2328. for ( ; i < nFormalParams; i++ )
  2329. {
  2330. Assert( params[i].IsNull() );
  2331. }
  2332. #endif
  2333. // get object instance pointer from pSelf if this is a method call on object
  2334. InstanceContext_t *pContext;
  2335. void *pObject;
  2336. if ( pVMScriptFunction->m_flags & SF_MEMBER_FUNC )
  2337. {
  2338. pContext = &( pSelf->instanceContext );
  2339. if ( !pContext )
  2340. {
  2341. PyErr_SetString(PyExc_ValueError, "Accessed null instance");
  2342. return NULL;
  2343. }
  2344. pObject = pContext->pInstance;
  2345. if ( !pObject )
  2346. {
  2347. PyErr_SetString(PyExc_ValueError, "Accessed null instance");
  2348. return NULL;
  2349. }
  2350. if ( pContext->pClassDesc->pHelper )
  2351. {
  2352. pObject = pContext->pClassDesc->pHelper->GetProxied( pObject );
  2353. }
  2354. if ( !pObject )
  2355. {
  2356. PyErr_SetString(PyExc_ValueError, "Accessed null instance");
  2357. return NULL;
  2358. }
  2359. }
  2360. else
  2361. {
  2362. pObject = NULL;
  2363. }
  2364. // call the binding function, which will make the actual C function call
  2365. (*pVMScriptFunction->m_pfnBinding)( pVMScriptFunction->m_pFunction, pObject, params.Base(), params.Count(), ( pVMScriptFunction->m_desc.m_ReturnType != FIELD_VOID ) ? &returnValue : NULL );
  2366. PyObject *pret = NULL;
  2367. // use the returned scriptvariant to create a new python object
  2368. if ( pVMScriptFunction->m_desc.m_ReturnType != FIELD_VOID )
  2369. {
  2370. // this is the ONE case where we must actually embed a reference to the returned Vector,
  2371. // instead of creating a copy of the returned Vector.
  2372. // this is because the binding function call above auto-creates a new Vector for the return value. (see vscript_templates.h line 278 etc)
  2373. pret = ((CPythonVM *)g_pVm)->ConvertToPyObject( returnValue, false ); // create new ref
  2374. }
  2375. // NOTE: returning NULL and setting error state above should throw the python error...
  2376. if ( pret == NULL )
  2377. Py_RETURN_NONE;
  2378. return pret;
  2379. }
  2380. private:
  2381. //----------------
  2382. // inline Helpers
  2383. //----------------
  2384. //------------------------------------------------------------------------------
  2385. // Purpose: print most recent python error to console
  2386. //------------------------------------------------------------------------------
  2387. inline bool PyPrintError()
  2388. {
  2389. if ( PyErr_Occurred() )
  2390. {
  2391. PyErr_Print();
  2392. return true;
  2393. }
  2394. return false;
  2395. }
  2396. //------------------------------------------------------------------------------
  2397. // Purpose: given hscope, return scope's instance object's dictionary.
  2398. // returns NULL if no instance object associated with scope.
  2399. //------------------------------------------------------------------------------
  2400. inline PyObject *InstanceDictFromScope( HSCRIPT hScope )
  2401. {
  2402. if ( !hScope )
  2403. return NULL;
  2404. AssertIsScope( hScope );
  2405. Assert ( hScope != INVALID_HSCRIPT );
  2406. return ((CPyScope *)hScope)->GetInstanceDict();
  2407. }
  2408. //----------------------------------------------------------
  2409. // given hscope, return scope's module-level dictionary
  2410. //----------------------------------------------------------
  2411. inline PyObject *ModuleDictFromScope( HSCRIPT hScope )
  2412. {
  2413. if ( hScope )
  2414. {
  2415. // get module's dict
  2416. AssertIsScope( hScope );
  2417. Assert ( hScope != INVALID_HSCRIPT );
  2418. return ((CPyScope *)hScope)->GetModuleDict();
  2419. }
  2420. else
  2421. {
  2422. // get global scope dict
  2423. return m_pRootScope->GetModuleDict();
  2424. }
  2425. }
  2426. //---------------------------------------------------------------
  2427. // given class descriptor, get our pre-defined python type object.
  2428. // return NULL if not found.
  2429. //---------------------------------------------------------------
  2430. static inline PyTypeObject *PyTypeFromDesc( ScriptClassDesc_t *pDesc )
  2431. {
  2432. if ( !pDesc )
  2433. return NULL;
  2434. UtlHashFastHandle_t h = ((CPythonVM *)g_pVm)->m_TypeMap.Find( (int)pDesc );
  2435. if ( h == ((CPythonVM *)g_pVm)->m_TypeMap.InvalidHandle() )
  2436. {
  2437. return NULL;
  2438. }
  2439. return (PyTypeObject *)(((CPythonVM *)g_pVm)->m_TypeMap.Element ( h ));
  2440. }
  2441. //---------------------------------------------------------------
  2442. // given python object, get class descriptor associated with object's type.
  2443. // return NULL if object is not a server-side object.
  2444. //---------------------------------------------------------------
  2445. static inline ScriptClassDesc_t *pDescFromPyObj( PyObject *pobj )
  2446. {
  2447. if ( ! pobj )
  2448. return NULL;
  2449. AssertIsPyObject( (HSCRIPT)pobj );
  2450. PyTypeObject *ptype = pobj->ob_type;
  2451. UtlHashFastHandle_t h = ((CPythonVM *)g_pVm)->m_ClassMap.Find( (int)ptype );
  2452. if ( h == ((CPythonVM *)g_pVm)->m_ClassMap.InvalidHandle() )
  2453. {
  2454. return NULL;
  2455. }
  2456. return (ScriptClassDesc_t *)(((CPythonVM *)g_pVm)->m_ClassMap.Element ( h ));
  2457. }
  2458. ////---------------------------------------------------------
  2459. //// Callbacks
  2460. ////---------------------------------------------------------
  2461. //static void PrintFunc(HPYTHONVM m_hVM,const SQChar* s,...)
  2462. //{
  2463. // Msg( CFmtStr( &s ) );
  2464. //}
  2465. // //-------------------------------------------------------------
  2466. // //
  2467. // //-------------------------------------------------------------
  2468. // static SQInteger ReleaseHook( SQUserPointer p, SQInteger size )
  2469. // {
  2470. // InstanceContext_t *pInstanceContext = (InstanceContext_t *)p;
  2471. // pInstanceContext->pClassDesc->m_pfnDestruct( pInstanceContext->pInstance );
  2472. // delete pInstanceContext;
  2473. // return 0;
  2474. // }
  2475. //
  2476. // //-------------------------------------------------------------
  2477. // //
  2478. // //-------------------------------------------------------------
  2479. // static SQInteger ExternalInstanceReleaseHook( SQUserPointer p, SQInteger size )
  2480. // {
  2481. // InstanceContext_t *pInstanceContext = (InstanceContext_t *)p;
  2482. // delete pInstanceContext;
  2483. // return 0;
  2484. // }
  2485. //
  2486. // //-------------------------------------------------------------
  2487. // //
  2488. // //-------------------------------------------------------------
  2489. // static SQInteger GetFunctionSignature( HPYTHONVM hVM )
  2490. // {
  2491. // StackHandler sa(hVM);
  2492. // if ( sa.GetParamCount() != 3 )
  2493. // {
  2494. // return 0;
  2495. // }
  2496. //
  2497. // HPYOBJECT hFunction = sa.GetObjectHandle( 2 );
  2498. // if ( !sq_isclosure( hFunction ) )
  2499. // {
  2500. // return 0;
  2501. // }
  2502. //
  2503. // std::string result;
  2504. // const char *pszName = sa.GetString( 3 );
  2505. // SQClosure *pClosure = hFunction._unVal.pClosure;
  2506. // SQFunctionProto *pProto = pClosure->_function._unVal.pFunctionProto;
  2507. //
  2508. // result += "function ";
  2509. // if ( pszName && *pszName )
  2510. // {
  2511. // result += pszName;
  2512. // }
  2513. // else if ( sq_isstring( pProto->_name ) )
  2514. // {
  2515. // result += pProto->_name._unVal.pString->_val;
  2516. // }
  2517. // else
  2518. // {
  2519. // result += "<unnamed>";
  2520. // }
  2521. // result += "(";
  2522. //
  2523. // for ( int i = 1; i < pProto->_nparameters; i++ )
  2524. // {
  2525. // if ( i != 1 )
  2526. // result += ", ";
  2527. // if ( sq_isstring( pProto->_parameters[i] ) )
  2528. // {
  2529. // result += pProto->_parameters[i]._unVal.pString->_val;
  2530. // }
  2531. // else
  2532. // {
  2533. // result += "arg";
  2534. // }
  2535. // }
  2536. // result += ")";
  2537. //
  2538. // sa.Return( result.c_str() );
  2539. //
  2540. // return 1;
  2541. // }
  2542. //
  2543. // //-------------------------------------------------------------
  2544. // //
  2545. // //-------------------------------------------------------------
  2546. // static SQInteger GetDeveloper( HPYTHONVM hVM )
  2547. // {
  2548. // StackHandler sa(hVM);
  2549. // sa.Return( ((CPythonVM *)hVM->_sharedstate->m_pOwnerData)->developer.GetInt() );
  2550. // return 1;
  2551. // }
  2552. //
  2553. //-------------------------------------------------------------
  2554. // called from python directly during object construction.
  2555. // same as class __init__ function - init the member data for server object instance
  2556. // If the context has a constructor, call it to create the server object instance.
  2557. // args and keywords params currently ignored.
  2558. //-------------------------------------------------------------
  2559. static int InitInstance( scriptClassInstance_t *pSelf, PyObject *args, PyObject *kwds )
  2560. {
  2561. InstanceContext_t *pInstanceContext = &( pSelf->instanceContext );
  2562. pInstanceContext->pInstance = NULL;
  2563. pInstanceContext->pClassDesc = NULL;
  2564. pInstanceContext->pPyName = NULL;
  2565. pSelf->pDict = PyDict_New();
  2566. //((scriptClassInstance_t *)pSelf)->typeTag = TYPETAG_INSTANCE;
  2567. ScriptClassDesc_t *pDesc = pDescFromPyObj( (PyObject *)pSelf );
  2568. if ( pDesc )
  2569. {
  2570. pInstanceContext->pClassDesc = pDesc;
  2571. if ( pDesc->m_pfnConstruct )
  2572. {
  2573. pInstanceContext->pInstance = pDesc->m_pfnConstruct();
  2574. }
  2575. }
  2576. else
  2577. {
  2578. return -1;
  2579. }
  2580. return 0;
  2581. }
  2582. //----------------------------------------------------------------------
  2583. // called from python directly during object destruction (tp_dealloc)
  2584. // call destructor on the server object instance, then release the python object
  2585. //----------------------------------------------------------------------
  2586. static void FreeInstance( scriptClassInstance_t *pSelf )
  2587. {
  2588. AssertIsInstance( (HSCRIPT)pSelf );
  2589. InstanceContext_t *pcontext = &( pSelf->instanceContext );
  2590. ScriptClassDesc_t *pDesc = pDescFromPyObj( (PyObject *)pSelf );
  2591. if ( pDesc )
  2592. {
  2593. if ( pDesc->m_pfnDestruct )
  2594. {
  2595. pDesc->m_pfnDestruct( pcontext->pInstance );
  2596. }
  2597. }
  2598. pcontext->pInstance = NULL;
  2599. Py_XDECREF( pcontext->pPyName );
  2600. Py_XDECREF( pSelf->pDict ); // will decref all objs held in dict
  2601. pSelf->ob_type->tp_free( (PyObject *)pSelf );
  2602. }
  2603. //-------------------------------------------------------------
  2604. // UNDONE: script execution throttle - equivalent in python?
  2605. //static int QueryContinue( HPYTHONVM hVM )
  2606. //{
  2607. // CPythonVM *pVM = ((CPythonVM *)hVM->_sharedstate->m_pOwnerData);
  2608. // if ( !pVM->m_hDbg )
  2609. // {
  2610. // if ( pVM->m_TimeStartExecute != 0.0f && Plat_FloatTime() - pVM->m_TimeStartExecute > 0.03f )
  2611. // {
  2612. // DevMsg( "Script running too long, terminating\n" );
  2613. // // @TODO: Mark the offending closure so that it won't be executed again [5/13/2008 tom]
  2614. // return SQ_QUERY_BREAK;
  2615. // }
  2616. // }
  2617. // return SQ_QUERY_CONTINUE;
  2618. //}
  2619. //-------------------------------------------------------------
  2620. //
  2621. //-------------------------------------------------------------
  2622. static PyObject *InstanceIsValid( PyObject *pSelf, PyObject *pArgs )
  2623. {
  2624. // UNDONE:
  2625. //InstanceContext_t *pContext = (InstanceContext_t *)pSelf;
  2626. //
  2627. //if ( pContext && pContext->pInstance )
  2628. // Py_RETURN_TRUE;
  2629. //else
  2630. // Py_RETURN_FALSE;
  2631. }
  2632. //-------------------------------------------------------------
  2633. // allow C++ function to be called from python -
  2634. // function parameter binding is described by
  2635. // ScriptFunctionBinding_t
  2636. //-------------------------------------------------------------
  2637. void RegisterFunctionGuts( ScriptFunctionBinding_t *pScriptFunction )
  2638. {
  2639. PyObject *pdict = m_pValveScope->GetModuleDict();
  2640. if ( PyDict_GetItemString( pdict, pScriptFunction->m_desc.m_pszScriptName ) != NULL )
  2641. return; // already registered
  2642. // alloc space for small (2 element) array of PyMethodDefs - elements must not move in memory.
  2643. PyMethodDef *pmethod = new PyMethodDef[2];
  2644. // save pointers so we can free 'em all later
  2645. Assert (m_iMethodDef < MAX_VALVE_FUNCTIONS_EXPORTED );
  2646. m_rgpMethodDefs[m_iMethodDef++] = pmethod;
  2647. // create NULL semaphore at tail of list
  2648. PyMethodDef *pm = &(pmethod[1]);
  2649. pm->ml_name = NULL;
  2650. pm->ml_meth = NULL;
  2651. pm->ml_flags = 0;
  2652. pm->ml_doc = NULL;
  2653. // fill the python method def
  2654. pm = &(pmethod[0]);
  2655. pm->ml_name = pScriptFunction->m_desc.m_pszScriptName;
  2656. pm->ml_flags = METH_VARARGS;
  2657. pm->ml_doc = pScriptFunction->m_desc.m_pszDescription;
  2658. int proxyId = GetNewProxyId();
  2659. SetProxyBinding( proxyId, pScriptFunction );
  2660. // the function callback chain - python calls Translate_XXX -> calls TranslateCall -> calls binding function -> actual function.
  2661. pm->ml_meth = GetProxyFunction( proxyId );
  2662. Py_InitModule3("valve", pmethod, "Import module for access to all exported Valve methods.");
  2663. // set up parameter checking
  2664. char szTypeMask[64];
  2665. if ( pScriptFunction->m_desc.m_Parameters.Count() > ARRAYSIZE(szTypeMask) - 1 )
  2666. {
  2667. AssertMsg1( 0, "Too many arguments for script function %s\n", pScriptFunction->m_desc.m_pszFunction );
  2668. return;
  2669. }
  2670. // UNDONE: implement help - function param type documenting in python
  2671. //szTypeMask[0] = '.';
  2672. //char *pCurrent = &szTypeMask[1];
  2673. //for ( int i = 0; i < pScriptFunction->m_desc.m_Parameters.Count(); i++, pCurrent++ )
  2674. //{
  2675. // switch ( pScriptFunction->m_desc.m_Parameters[i] )
  2676. // {
  2677. // case FIELD_CSTRING:
  2678. // *pCurrent = 's';
  2679. // break;
  2680. // case FIELD_FLOAT:
  2681. // case FIELD_INTEGER:
  2682. // *pCurrent = 'n';
  2683. // break;
  2684. // case FIELD_BOOLEAN:
  2685. // *pCurrent = 'b';
  2686. // break;
  2687. // case FIELD_VECTOR:
  2688. // *pCurrent = 'x';
  2689. // break;
  2690. // case FIELD_HSCRIPT:
  2691. // *pCurrent = '.';
  2692. // break;
  2693. // case FIELD_CHARACTER:
  2694. // default:
  2695. // *pCurrent = FIELD_VOID;
  2696. // AssertMsg( 0 , "Not supported" );
  2697. // break;
  2698. // }
  2699. //}
  2700. //Assert( pCurrent - szTypeMask < ARRAYSIZE(szTypeMask) - 1 );
  2701. //*pCurrent = 0;
  2702. //sq_pushstring( m_hVM, pScriptFunction->m_desc.m_pszScriptName, -1 );
  2703. //ScriptFunctionBinding_t **pVMScriptFunction = (ScriptFunctionBinding_t **)sq_newuserdata(m_hVM, sizeof(ScriptFunctionBinding_t *));
  2704. //*pVMScriptFunction = pScriptFunction;
  2705. //sq_newclosure( m_hVM, &TranslateCall, 1 );
  2706. //HPYOBJECT hFunction;
  2707. //sq_getstackobj( m_hVM, -1, &hFunction );
  2708. //sq_setnativeclosurename(m_hVM, -1, pScriptFunction->m_desc.m_pszScriptName );
  2709. //sq_setparamscheck( m_hVM, pScriptFunction->m_desc.m_Parameters.Count() + 1, szTypeMask );
  2710. //sq_createslot( m_hVM, -3 );
  2711. //if ( developer.GetInt() )
  2712. //{
  2713. // const char *pszHide = SCRIPT_HIDE;
  2714. // if ( !pScriptFunction->m_desc.m_pszDescription || *pScriptFunction->m_desc.m_pszDescription != *pszHide )
  2715. // {
  2716. // std::string name;
  2717. // std::string signature;
  2718. // if ( pClassDesc )
  2719. // {
  2720. // name += pClassDesc->m_pszScriptName;
  2721. // name += "::";
  2722. // }
  2723. // name += pScriptFunction->m_desc.m_pszScriptName;
  2724. // signature += FieldTypeToString( pScriptFunction->m_desc.m_ReturnType );
  2725. // signature += ' ';
  2726. // signature += name;
  2727. // signature += '(';
  2728. // for ( int i = 0; i < pScriptFunction->m_desc.m_Parameters.Count(); i++ )
  2729. // {
  2730. // if ( i != 0 )
  2731. // {
  2732. // signature += ", ";
  2733. // }
  2734. // signature+= FieldTypeToString( pScriptFunction->m_desc.m_Parameters[i] );
  2735. // }
  2736. // signature += ')';
  2737. // sq_pushobject( m_hVM, LookupObject( "RegisterFunctionDocumentation", NULL, false ) );
  2738. // sq_pushroottable( m_hVM );
  2739. // sq_pushobject( m_hVM, hFunction );
  2740. // sq_pushstring( m_hVM, name.c_str(), name.length() );
  2741. // sq_pushstring( m_hVM, signature.c_str(), signature.length() );
  2742. // sq_pushstring( m_hVM, pScriptFunction->m_desc.m_pszDescription, -1 );
  2743. // sq_call( m_hVM, 5, false, /*false*/ true );
  2744. // sq_pop( m_hVM, 1 );
  2745. // }
  2746. //}
  2747. return;
  2748. }
  2749. //-------------------------------------------------------------
  2750. // drop our ref count on the script object
  2751. //-------------------------------------------------------------
  2752. void ReleaseScriptObject( HSCRIPT hScript )
  2753. {
  2754. AssertIsPyObject( hScript );
  2755. Py_XDECREF( (PyObject *)hScript );
  2756. }
  2757. //-------------------------------------------------------------
  2758. // create a new python object from the script variant
  2759. // UNLESS variant is an HSCRIPT - in this case, just returns
  2760. // the embedded PyObject * with incremented ref count.
  2761. // if bAllocNewVector is true, create a new C++ Vector,
  2762. // otherwise, embed a reference to the variant's Vector, within new py object.
  2763. // NOTE: all references will be freed when the py object is freed!
  2764. //-------------------------------------------------------------
  2765. PyObject *ConvertToPyObject( const ScriptVariant_t &value, bool bAllocNewVector )
  2766. {
  2767. switch ( value.m_type )
  2768. {
  2769. case FIELD_VOID: Py_RETURN_NONE;
  2770. case FIELD_FLOAT: return PyFloat_FromDouble( (double)value.m_float );
  2771. case FIELD_CSTRING:
  2772. if ( value.IsNull() )
  2773. Py_RETURN_NONE;
  2774. return PyString_FromStringAndSize( value, (Py_ssize_t) strlen( value.m_pszString ));
  2775. case FIELD_VECTOR:
  2776. {
  2777. PyObject *pretObj;
  2778. if ( !bAllocNewVector )
  2779. {
  2780. // Vector was alloc'd by caller, and in this (rare) case we are expected to free it.
  2781. // create a python vector object that references the variant's vector object
  2782. // NOTE: the variant's vector object will be deleted when the python object is deleted.
  2783. DEBUG_VECCOUNT++;
  2784. pretObj = CreatePyVector( (Vector *)value.m_pVector );
  2785. }
  2786. else
  2787. {
  2788. // create new python vector object and copy from scriptvariant data. must be freed by caller
  2789. pretObj = CreatePyVector( NULL );
  2790. *(((PyVectorInstance_t*)pretObj)->pVector) = *((Vector *)value.m_pVector); // copy operator
  2791. }
  2792. return pretObj;
  2793. }
  2794. case FIELD_INTEGER: return PyInt_FromLong( value.m_int );
  2795. case FIELD_BOOLEAN: return PyBool_FromLong( value.m_bool );
  2796. case FIELD_CHARACTER:
  2797. {
  2798. char sz[2];
  2799. sz[0] = value.m_char;
  2800. sz[1] = 0;
  2801. return PyString_FromStringAndSize( sz, (Py_ssize_t)1 );
  2802. }
  2803. case FIELD_HSCRIPT:
  2804. {
  2805. if ( value.m_hScript )
  2806. {
  2807. PyObject *pyobj = (PyObject *)value.m_hScript; //PyCObject_FromVoidPtr((void *)value.m_hScript, NULL);
  2808. Py_XINCREF( pyobj );
  2809. return pyobj;
  2810. }
  2811. else
  2812. {
  2813. Py_RETURN_NONE;
  2814. }
  2815. }
  2816. }
  2817. Py_RETURN_NONE;
  2818. }
  2819. //-------------------------------------------------------------
  2820. // fill variant struct with appropriate value from python object
  2821. // NOTE: does not decref the python object.
  2822. //-------------------------------------------------------------
  2823. bool ConvertToVariant( PyObject* object, ScriptVariant_t *pReturn )
  2824. {
  2825. AssertIsPyObject( (HSCRIPT)object );
  2826. if ( object == Py_None )
  2827. {
  2828. pReturn->m_type = FIELD_VOID;
  2829. }
  2830. else if ( PyLong_CheckExact( object ) )
  2831. {
  2832. *pReturn = (int)PyLong_AsLong( object ); // UNDONE: need error checking for overflow - will return NULL
  2833. }
  2834. else if ( PyInt_CheckExact( object ) )
  2835. {
  2836. *pReturn = (int)PyInt_AS_LONG( object ); // No error checking is performed, since we started with int
  2837. }
  2838. else if ( PyFloat_CheckExact( object ) )
  2839. {
  2840. *pReturn = (float)PyFloat_AS_DOUBLE( object ); // no error checking since we started with float
  2841. }
  2842. else if ( PyBool_Check( object ) )
  2843. {
  2844. if ( object == Py_True )
  2845. *pReturn = true;
  2846. else
  2847. *pReturn = false;
  2848. }
  2849. else if ( PyString_Check( object ) )
  2850. {
  2851. // create a new string in the variant
  2852. char *buffer;
  2853. Py_ssize_t length;
  2854. PyString_AsStringAndSize( object, &buffer, &length);
  2855. int size = (int)length + 1;
  2856. pReturn->m_type = FIELD_CSTRING;
  2857. pReturn->m_pszString = new char[size];
  2858. V_memcpy( (void *)pReturn->m_pszString, buffer, size );
  2859. pReturn->m_flags |= SV_FREE;
  2860. DEBUG_VARIANTCOUNT++;
  2861. Assert( DEBUG_VARIANTCOUNT < 1000 ); // if this fails, server is likely not freeing return values from python fn calls each frame
  2862. }
  2863. else if ( IsPyVector( object ) )
  2864. {
  2865. // create a new vector in the variant that copies the object's vector data
  2866. Vector *pVector = ((PyVectorInstance_t *)object)->pVector;
  2867. pReturn->m_type = FIELD_VECTOR;
  2868. pReturn->m_pVector = new Vector( *((Vector *)pVector) );
  2869. pReturn->m_flags |= SV_FREE;
  2870. DEBUG_VARIANTCOUNT++;
  2871. Assert( DEBUG_VARIANTCOUNT < 1000 ); // if this fails, server is likely not freeing return values from python fn calls each frame
  2872. }
  2873. else
  2874. {
  2875. // save the actual object pointer
  2876. pReturn->m_type = FIELD_HSCRIPT;
  2877. pReturn->m_hScript =(HSCRIPT)object; // PyCObject_AsVoidPtr( object );
  2878. return false; // don't free object
  2879. }
  2880. return true; // ok to free python object
  2881. }
  2882. //
  2883. // //-------------------------------------------------------------------------
  2884. // // UNDONE: Serialization for save/restore
  2885. // //-------------------------------------------------------------------------
  2886. // enum
  2887. // {
  2888. // SAVEVERSION = 2
  2889. // };
  2890. //
  2891. // void WriteObject( const SQObjectPtr &object )
  2892. // {
  2893. // switch ( object._type )
  2894. // {
  2895. // case OT_NULL:
  2896. // m_pBuffer->PutInt( OT_NULL );
  2897. // break;
  2898. // case OT_INTEGER:
  2899. // m_pBuffer->PutInt( OT_INTEGER );
  2900. // m_pBuffer->PutInt( object._unVal.nInteger );
  2901. // break;
  2902. // case OT_FLOAT:
  2903. // m_pBuffer->PutInt( OT_FLOAT );
  2904. // m_pBuffer->PutFloat( object._unVal.fFloat);
  2905. // break;
  2906. // case OT_BOOL:
  2907. // m_pBuffer->PutInt( OT_BOOL );
  2908. // m_pBuffer->PutInt( object._unVal.nInteger );
  2909. // break;
  2910. // case OT_STRING:
  2911. // m_pBuffer->PutInt( OT_STRING );
  2912. // m_pBuffer->PutInt( object._unVal.pString->_len );
  2913. // m_pBuffer->PutString( object._unVal.pString->_val );
  2914. // break;
  2915. // case OT_TABLE: WriteTable( object._unVal.pTable ); break;
  2916. // case OT_ARRAY: WriteArray( object._unVal.pArray ); break;
  2917. // case OT_USERDATA: WriteUserData( object._unVal.pUserData ); break;
  2918. // case OT_CLOSURE: WriteClosure( object._unVal.pClosure ); break;
  2919. // case OT_NATIVECLOSURE: WriteNativeClosure( object._unVal.pNativeClosure ); break;
  2920. // case OT_GENERATOR: WriteGenerator( object._unVal.pGenerator ); break;
  2921. // case OT_USERPOINTER: WriteUserPointer( object._unVal.pUserPointer ); break;
  2922. // case OT_THREAD: WriteVM( object._unVal.pThread ); break;
  2923. // case OT_FUNCPROTO: WriteFuncProto( object._unVal.pFunctionProto ); break;
  2924. // case OT_CLASS: WriteClass( object._unVal.pClass ); break;
  2925. // case OT_INSTANCE: WriteInstance( object._unVal.pInstance ); break;
  2926. // case OT_WEAKREF: WriteWeakRef( object._unVal.pWeakRef ); break;
  2927. // default: Assert( 0 ); break;
  2928. // }
  2929. //
  2930. //#ifdef VPYTHON_DEBUG_SERIALIZATION
  2931. // SQObjectPtr res;
  2932. // m_hVM->ToString( object, res );
  2933. // Msg( "%d: %s\n", m_pBuffer->TellPut(), res._unVal.pString->_val );
  2934. //#endif
  2935. // }
  2936. //
  2937. // //-------------------------------------------------------------
  2938. // //
  2939. // //-------------------------------------------------------------
  2940. // void WriteVM( PYVM *pVM )
  2941. // {
  2942. // unsigned i;
  2943. //
  2944. // m_pBuffer->PutInt( OT_THREAD );
  2945. // m_pBuffer->PutPtr( pVM );
  2946. //
  2947. // if ( pVM->_uiRef & MARK_FLAG )
  2948. // return;
  2949. // pVM->_uiRef |= MARK_FLAG;
  2950. //
  2951. // WriteObject( pVM->_roottable );
  2952. // m_pBuffer->PutInt( pVM->_top );
  2953. // m_pBuffer->PutInt( pVM->_stackbase );
  2954. // m_pBuffer->PutUnsignedInt( pVM->_stack.size() );
  2955. // for( i = 0; i < pVM->_stack.size(); i++ )
  2956. // {
  2957. // WriteObject( pVM->_stack[i] );
  2958. // }
  2959. // m_pBuffer->PutUnsignedInt( pVM->_vargsstack.size() );
  2960. // for( i = 0; i < pVM->_vargsstack.size(); i++ )
  2961. // {
  2962. // WriteObject( pVM->_vargsstack[i] );
  2963. // }
  2964. // }
  2965. //
  2966. // //-------------------------------------------------------------
  2967. // //
  2968. // //-------------------------------------------------------------
  2969. // void WriteArray( SQArray *pArray )
  2970. // {
  2971. // m_pBuffer->PutInt( OT_ARRAY );
  2972. // m_pBuffer->PutPtr( pArray );
  2973. //
  2974. // if ( pArray->_uiRef & MARK_FLAG )
  2975. // return;
  2976. // pArray->_uiRef |= MARK_FLAG;
  2977. //
  2978. // int len = pArray->_values.size();
  2979. // m_pBuffer->PutInt( len );
  2980. // for ( int i = 0; i < len; i++ )
  2981. // WriteObject( pArray->_values[i] );
  2982. // }
  2983. //
  2984. // //-------------------------------------------------------------
  2985. // //
  2986. // //-------------------------------------------------------------
  2987. // void WriteTable( SQTable *pTable )
  2988. // {
  2989. // m_pBuffer->PutInt( OT_TABLE );
  2990. // m_pBuffer->PutPtr( pTable );
  2991. //
  2992. // if ( pTable->_uiRef & MARK_FLAG )
  2993. // return;
  2994. // pTable->_uiRef |= MARK_FLAG;
  2995. //
  2996. // m_pBuffer->PutInt( pTable->_delegate != NULL );
  2997. // if ( pTable->_delegate )
  2998. // {
  2999. // WriteObject( pTable->_delegate );
  3000. // }
  3001. //
  3002. // int len = pTable->_numofnodes;
  3003. // m_pBuffer->PutInt( len );
  3004. // for(int i = 0; i < len; i++)
  3005. // {
  3006. // WriteObject( pTable->_nodes[i].key );
  3007. // WriteObject( pTable->_nodes[i].val );
  3008. // }
  3009. // }
  3010. //
  3011. // //-------------------------------------------------------------
  3012. // //
  3013. // //-------------------------------------------------------------
  3014. // void WriteClass( SQClass *pClass )
  3015. // {
  3016. // m_pBuffer->PutInt( OT_CLASS );
  3017. // m_pBuffer->PutPtr( pClass );
  3018. //
  3019. // if ( !pClass || ( pClass->_uiRef & MARK_FLAG ) )
  3020. // return;
  3021. // pClass->_uiRef |= MARK_FLAG;
  3022. //
  3023. // bool bIsNative = ( pClass->_typetag != NULL );
  3024. // unsigned i;
  3025. // if ( !bIsNative )
  3026. // {
  3027. // for( i = 0; i < pClass->_methods.size(); i++)
  3028. // {
  3029. // if ( sq_isnativeclosure( pClass->_methods[i].val ) )
  3030. // {
  3031. // bIsNative = true;
  3032. // break;
  3033. // }
  3034. // }
  3035. // }
  3036. // m_pBuffer->PutInt( bIsNative );
  3037. // if ( !bIsNative )
  3038. // {
  3039. // m_pBuffer->PutInt( pClass->_base != NULL );
  3040. // if ( pClass->_base )
  3041. // {
  3042. // WriteObject( pClass->_base );
  3043. // }
  3044. //
  3045. // WriteObject( pClass->_members );
  3046. // WriteObject( pClass->_attributes );
  3047. // m_pBuffer->PutInt( pClass->_defaultvalues.size() );
  3048. // for( i = 0; i< pClass->_defaultvalues.size(); i++)
  3049. // {
  3050. // WriteObject(pClass->_defaultvalues[i].val);
  3051. // WriteObject(pClass->_defaultvalues[i].attrs);
  3052. // }
  3053. // m_pBuffer->PutInt( pClass->_methods.size() );
  3054. // for( i = 0; i < pClass->_methods.size(); i++)
  3055. // {
  3056. // WriteObject(pClass->_methods[i].val);
  3057. // WriteObject(pClass->_methods[i].attrs);
  3058. // }
  3059. // m_pBuffer->PutInt( pClass->_metamethods.size() );
  3060. // for( i = 0; i < pClass->_metamethods.size(); i++)
  3061. // {
  3062. // WriteObject(pClass->_metamethods[i]);
  3063. // }
  3064. // }
  3065. // else
  3066. // {
  3067. // if ( pClass->_typetag )
  3068. // {
  3069. // if ( pClass->_typetag == TYPETAG_VECTOR )
  3070. // {
  3071. // m_pBuffer->PutString( "Vector" );
  3072. // }
  3073. // else
  3074. // {
  3075. // ScriptClassDesc_t *pDesc = (ScriptClassDesc_t *)pClass->_typetag;
  3076. // m_pBuffer->PutString( pDesc->m_pszScriptName );
  3077. // }
  3078. // }
  3079. // else
  3080. // {
  3081. // // Have to grovel for the name
  3082. // SQObjectPtr key;
  3083. // if ( FindKeyForObject( m_hVM->_roottable, pClass, key ) )
  3084. // {
  3085. // m_pBuffer->PutString( key._unVal.pString->_val );
  3086. // }
  3087. // else
  3088. // {
  3089. // Assert( 0 );
  3090. // m_pBuffer->PutString( "" );
  3091. // }
  3092. // }
  3093. // }
  3094. // }
  3095. //
  3096. // //-------------------------------------------------------------
  3097. // //
  3098. // //-------------------------------------------------------------
  3099. // void WriteInstance( SQInstance *pInstance )
  3100. // {
  3101. // m_pBuffer->PutInt( OT_INSTANCE );
  3102. // m_pBuffer->PutPtr( pInstance );
  3103. //
  3104. // if ( pInstance->_uiRef & MARK_FLAG )
  3105. // return;
  3106. // pInstance->_uiRef |= MARK_FLAG;
  3107. //
  3108. // WriteObject( pInstance->_class );
  3109. //
  3110. // unsigned nvalues = pInstance->_class->_defaultvalues.size();
  3111. // m_pBuffer->PutInt( nvalues );
  3112. // for ( unsigned i =0; i< nvalues; i++ )
  3113. // {
  3114. // WriteObject( pInstance->_values[i] );
  3115. // }
  3116. //
  3117. // m_pBuffer->PutPtr( pInstance->_class->_typetag );
  3118. //
  3119. // if ( pInstance->_class->_typetag )
  3120. // {
  3121. // if ( pInstance->_class->_typetag == TYPETAG_VECTOR )
  3122. // {
  3123. // Vector *pVector = (Vector *)pInstance->_userpointer;
  3124. // m_pBuffer->PutFloat( pVector->x );
  3125. // m_pBuffer->PutFloat( pVector->y );
  3126. // m_pBuffer->PutFloat( pVector->z );
  3127. // }
  3128. // else
  3129. // {
  3130. // InstanceContext_t *pContext = ((InstanceContext_t *)pInstance->_userpointer);
  3131. // WriteObject( pContext->name );
  3132. // m_pBuffer->PutPtr( pContext->pInstance );
  3133. // }
  3134. // }
  3135. // else
  3136. // {
  3137. // WriteUserPointer( NULL );
  3138. // }
  3139. // }
  3140. //
  3141. // //-------------------------------------------------------------
  3142. // //
  3143. // //-------------------------------------------------------------
  3144. // void WriteGenerator( SQGenerator *pGenerator )
  3145. // {
  3146. // ExecuteOnce( Msg( "Save load of generators not well tested. caveat emptor\n" ) );
  3147. // WriteObject(pGenerator->_closure);
  3148. //
  3149. // m_pBuffer->PutInt( OT_GENERATOR );
  3150. // m_pBuffer->PutPtr( pGenerator );
  3151. //
  3152. // if ( pGenerator->_uiRef & MARK_FLAG )
  3153. // return;
  3154. // pGenerator->_uiRef |= MARK_FLAG;
  3155. //
  3156. // WriteObject( pGenerator->_closure );
  3157. // m_pBuffer->PutInt( pGenerator->_stack.size() );
  3158. // for(SQUnsignedInteger i = 0; i < pGenerator->_stack.size(); i++) WriteObject(pGenerator->_stack[i]);
  3159. // m_pBuffer->PutInt( pGenerator->_vargsstack.size() );
  3160. // for(SQUnsignedInteger j = 0; j < pGenerator->_vargsstack.size(); j++) WriteObject(pGenerator->_vargsstack[j]);
  3161. // }
  3162. //
  3163. // //-------------------------------------------------------------
  3164. // //
  3165. // //-------------------------------------------------------------
  3166. // void WriteClosure( SQClosure *pClosure )
  3167. // {
  3168. // m_pBuffer->PutInt( OT_CLOSURE );
  3169. // m_pBuffer->PutPtr( pClosure );
  3170. // if ( pClosure->_uiRef & MARK_FLAG )
  3171. // return;
  3172. // pClosure->_uiRef |= MARK_FLAG;
  3173. //
  3174. // WriteObject( pClosure->_function );
  3175. // WriteObject( pClosure->_env );
  3176. //
  3177. // m_pBuffer->PutInt( pClosure->_outervalues.size() );
  3178. // for(SQUnsignedInteger i = 0; i < pClosure->_outervalues.size(); i++) WriteObject(pClosure->_outervalues[i]);
  3179. // m_pBuffer->PutInt( pClosure->_defaultparams.size() );
  3180. // for(SQUnsignedInteger i = 0; i < pClosure->_defaultparams.size(); i++) WriteObject(pClosure->_defaultparams[i]);
  3181. // }
  3182. //
  3183. // //-------------------------------------------------------------
  3184. // //
  3185. // //-------------------------------------------------------------
  3186. // void WriteNativeClosure( SQNativeClosure *pNativeClosure )
  3187. // {
  3188. // m_pBuffer->PutInt( OT_NATIVECLOSURE );
  3189. // m_pBuffer->PutPtr( pNativeClosure );
  3190. //
  3191. // if ( pNativeClosure->_uiRef & MARK_FLAG )
  3192. // return;
  3193. // pNativeClosure->_uiRef |= MARK_FLAG;
  3194. //
  3195. // WriteObject( pNativeClosure->_name );
  3196. // return;
  3197. // }
  3198. //
  3199. // //-------------------------------------------------------------
  3200. // //
  3201. // //-------------------------------------------------------------
  3202. // void WriteUserData( SQUserData *pUserData )
  3203. // {
  3204. // m_pBuffer->PutInt( OT_USERDATA );
  3205. // m_pBuffer->PutPtr( pUserData );
  3206. //
  3207. // if ( pUserData->_uiRef & MARK_FLAG )
  3208. // return;
  3209. // pUserData->_uiRef |= MARK_FLAG;
  3210. //
  3211. // // Need to call back or something. Unsure, TBD. [4/3/2008 tom]
  3212. // }
  3213. //
  3214. // //-------------------------------------------------------------
  3215. // //
  3216. // //-------------------------------------------------------------
  3217. // void WriteUserPointer( SQUserPointer pUserPointer )
  3218. // {
  3219. // m_pBuffer->PutInt( OT_USERPOINTER );
  3220. // // Need to call back or something. Unsure, TBD. [4/3/2008 tom]
  3221. // m_pBuffer->PutPtr( pUserPointer );
  3222. // }
  3223. //
  3224. // //-------------------------------------------------------------
  3225. // //
  3226. // //-------------------------------------------------------------
  3227. // static SQInteger SqWriteFunc(SQUserPointer up,SQUserPointer data, SQInteger size)
  3228. // {
  3229. // CPythonVM *pThis = (CPythonVM *)up;
  3230. // pThis->m_pBuffer->Put( data, size );
  3231. // return size;
  3232. // }
  3233. //
  3234. // void WriteFuncProto( SQFunctionProto *pFuncProto )
  3235. // {
  3236. // m_pBuffer->PutInt( OT_FUNCPROTO );
  3237. // m_pBuffer->PutPtr( pFuncProto );
  3238. //
  3239. // // Using the map to track these as they're not collectables
  3240. // if ( m_PtrMap.Find( pFuncProto ) != m_PtrMap.InvalidIndex() )
  3241. // {
  3242. // return;
  3243. // }
  3244. // m_PtrMap.Insert( pFuncProto, pFuncProto );
  3245. //
  3246. // pFuncProto->Save( m_hVM, this, &SqWriteFunc );
  3247. // }
  3248. //
  3249. // //-------------------------------------------------------------
  3250. // //
  3251. // //-------------------------------------------------------------
  3252. // void WriteWeakRef( SQWeakRef *pWeakRef )
  3253. // {
  3254. // m_pBuffer->PutInt( OT_WEAKREF );
  3255. // WriteObject( pWeakRef->_obj );
  3256. // }
  3257. //
  3258. // //--------------------------------------------------------
  3259. // template <typename T>
  3260. // bool BeginRead( T **ppOld, T **ppNew )
  3261. // {
  3262. // *ppOld = (T *)m_pBuffer->GetPtr();
  3263. // if ( *ppOld )
  3264. // {
  3265. // int iNew = m_PtrMap.Find( *ppOld );
  3266. // if ( iNew != m_PtrMap.InvalidIndex() )
  3267. // {
  3268. // *ppNew = (T*)m_PtrMap[iNew];
  3269. // return false;
  3270. // }
  3271. // }
  3272. // *ppNew = NULL;
  3273. // return true;
  3274. // }
  3275. //
  3276. // //-------------------------------------------------------------
  3277. // //
  3278. // //-------------------------------------------------------------
  3279. // void MapPtr( void *pOld, void *pNew )
  3280. // {
  3281. // Assert( m_PtrMap.Find( pOld ) == m_PtrMap.InvalidIndex() );
  3282. // m_PtrMap.Insert( pOld, pNew );
  3283. // }
  3284. //
  3285. // //-------------------------------------------------------------
  3286. // //
  3287. // //-------------------------------------------------------------
  3288. // bool ReadObject( SQObjectPtr &objectOut, const char *pszName = NULL )
  3289. // {
  3290. // SQObject object;
  3291. // bool bResult = true;
  3292. // object._type = (SQObjectType)m_pBuffer->GetInt();
  3293. // if ( _RAW_TYPE(object._type) < _RT_TABLE )
  3294. // {
  3295. // switch ( object._type )
  3296. // {
  3297. // case OT_NULL:
  3298. // object._unVal.pUserPointer = 0;
  3299. // break;
  3300. // case OT_INTEGER:
  3301. // object._unVal.nInteger = m_pBuffer->GetInt();
  3302. // break;
  3303. // case OT_FLOAT:
  3304. // object._unVal.fFloat = m_pBuffer->GetFloat();
  3305. // break;
  3306. // case OT_BOOL:
  3307. // object._unVal.nInteger = m_pBuffer->GetInt();
  3308. // break;
  3309. // case OT_STRING:
  3310. // {
  3311. // int len = m_pBuffer->GetInt();
  3312. // char *pString = (char *)stackalloc( len + 1 );
  3313. // m_pBuffer->GetString( pString, len + 1 );
  3314. // pString[len] = 0;
  3315. // object._unVal.pString = SQString::Create( m_hVM->_sharedstate, pString, len );
  3316. // break;
  3317. // }
  3318. // default:
  3319. // Assert( 0 );
  3320. // break;
  3321. // }
  3322. // }
  3323. // else
  3324. // {
  3325. // switch ( object._type )
  3326. // {
  3327. // case OT_TABLE:
  3328. // {
  3329. // object._unVal.pTable = ReadTable();
  3330. // break;
  3331. // }
  3332. // case OT_ARRAY:
  3333. // {
  3334. // object._unVal.pArray = ReadArray();
  3335. // break;
  3336. // }
  3337. // case OT_USERDATA:
  3338. // {
  3339. // object._unVal.pUserData = ReadUserData();
  3340. // break;
  3341. // }
  3342. // case OT_CLOSURE:
  3343. // {
  3344. // object._unVal.pClosure = ReadClosure();
  3345. // break;
  3346. // }
  3347. // case OT_NATIVECLOSURE:
  3348. // {
  3349. // object._unVal.pNativeClosure = ReadNativeClosure();
  3350. // break;
  3351. // }
  3352. // case OT_GENERATOR:
  3353. // {
  3354. // object._unVal.pGenerator = ReadGenerator();
  3355. // break;
  3356. // }
  3357. // case OT_USERPOINTER:
  3358. // {
  3359. // object._unVal.pUserPointer = ReadUserPointer();
  3360. // break;
  3361. // }
  3362. // case OT_THREAD:
  3363. // {
  3364. // object._unVal.pThread = ReadVM();
  3365. // break;
  3366. // }
  3367. // case OT_FUNCPROTO:
  3368. // {
  3369. // object._unVal.pFunctionProto = ReadFuncProto();
  3370. // break;
  3371. // }
  3372. // case OT_CLASS:
  3373. // {
  3374. // object._unVal.pClass = ReadClass();
  3375. // break;
  3376. // }
  3377. // case OT_INSTANCE:
  3378. // {
  3379. // object._unVal.pInstance = ReadInstance();
  3380. // if ( !object._unVal.pInstance )
  3381. // {
  3382. // // Look for a match in the current root table
  3383. // HPYOBJECT hExistingObject = LookupObject( pszName, NULL, false );
  3384. // if ( sq_isinstance( hExistingObject ) )
  3385. // {
  3386. // object._unVal.pInstance = hExistingObject._unVal.pInstance;
  3387. // }
  3388. // }
  3389. // break;
  3390. // }
  3391. // case OT_WEAKREF:
  3392. // {
  3393. // object._unVal.pWeakRef = ReadWeakRef();
  3394. // break;
  3395. // }
  3396. // default:
  3397. // {
  3398. // object._unVal.pUserPointer = NULL;
  3399. // Assert( 0 );
  3400. // }
  3401. // }
  3402. // if ( !object._unVal.pUserPointer )
  3403. // {
  3404. // DevMsg( "Failed to restore a Python object of type %s\n", SQTypeToString( object._type ) );
  3405. // object._type = OT_NULL;
  3406. // bResult = false;
  3407. // }
  3408. // }
  3409. //
  3410. //#ifdef VPYTHON_DEBUG_SERIALIZATION
  3411. // lastType = object._type;
  3412. // SQObjectPtr res;
  3413. // if ( ISREFCOUNTED(object._type) )
  3414. // object._unVal.pRefCounted->_uiRef++;
  3415. // m_hVM->ToString( object, res );
  3416. // if ( ISREFCOUNTED(object._type) )
  3417. // object._unVal.pRefCounted->_uiRef--;
  3418. // Msg( "%d: %s [%d]\n", m_pBuffer->TellGet(), res._unVal.pString->_val, ( ISREFCOUNTED(object._type) ) ? object._unVal.pRefCounted->_uiRef : -1 );
  3419. //#ifdef VPYTHON_DEBUG_SERIALIZATION_HEAPCHK
  3420. // _heapchk();
  3421. //#endif
  3422. //#endif
  3423. // objectOut = object;
  3424. // return bResult;
  3425. // }
  3426. //
  3427. // //-------------------------------------------------------------
  3428. // //
  3429. // //-------------------------------------------------------------
  3430. // PYVM *ReadVM()
  3431. // {
  3432. // PYVM *pVM = sq_newthread( m_hVM, MIN_STACK_OVERHEAD + 2 );
  3433. // m_hVM->Pop();
  3434. // return pVM;
  3435. // }
  3436. //
  3437. // //-------------------------------------------------------------
  3438. // //
  3439. // //-------------------------------------------------------------
  3440. // void ReadVM( PYVM *pVM )
  3441. // {
  3442. // unsigned i;
  3443. //
  3444. // ReadObject( pVM->_roottable );
  3445. // pVM->_top = m_pBuffer->GetInt();
  3446. // pVM->_stackbase = m_pBuffer->GetInt();
  3447. // unsigned stackSize = m_pBuffer->GetUnsignedInt();
  3448. // pVM->_stack.resize( stackSize );
  3449. // for( i = 0; i < pVM->_stack.size(); i++ )
  3450. // {
  3451. // ReadObject( pVM->_stack[i] );
  3452. // }
  3453. // stackSize = m_pBuffer->GetUnsignedInt();
  3454. // for( i = 0; i < pVM->_vargsstack.size(); i++ )
  3455. // {
  3456. // ReadObject( pVM->_vargsstack[i] );
  3457. // }
  3458. // }
  3459. //
  3460. // //-------------------------------------------------------------
  3461. // //
  3462. // //-------------------------------------------------------------
  3463. // SQTable *ReadTable()
  3464. // {
  3465. // SQTable *pOld;
  3466. // SQTable *pTable;
  3467. //
  3468. // if ( !BeginRead( &pOld, &pTable ) )
  3469. // {
  3470. // return pTable;
  3471. // }
  3472. //
  3473. // pTable = SQTable::Create(_ss(m_hVM), 0);
  3474. //
  3475. // MapPtr( pOld, pTable );
  3476. //
  3477. // if ( m_pBuffer->GetInt() )
  3478. // {
  3479. // SQObjectPtr delegate;
  3480. // ReadObject( delegate );
  3481. // pTable->SetDelegate( delegate._unVal.pTable );
  3482. // }
  3483. // else
  3484. // {
  3485. // pTable->_delegate = NULL;
  3486. // }
  3487. // int n = m_pBuffer->GetInt();
  3488. // while ( n-- )
  3489. // {
  3490. // SQObjectPtr key, value;
  3491. // ReadObject( key );
  3492. // if ( !ReadObject( value, ( key._type == OT_STRING ) ? key._unVal.pString->_val : NULL ) )
  3493. // {
  3494. // DevMsg( "Failed to read Python table entry %s", ( key._type == OT_STRING ) ? key._unVal.pString->_val : SQTypeToString( key._type ) );
  3495. // }
  3496. // if ( key._type != OT_NULL )
  3497. // {
  3498. // pTable->NewSlot( key, value );
  3499. // }
  3500. // }
  3501. // return pTable;
  3502. // }
  3503. //
  3504. // //-------------------------------------------------------------
  3505. // //
  3506. // //-------------------------------------------------------------
  3507. //SQArray *ReadArray()
  3508. //{
  3509. // SQArray *pOld;
  3510. // SQArray *pArray;
  3511. // if ( !BeginRead( &pOld, &pArray ) )
  3512. // {
  3513. // return pArray;
  3514. // }
  3515. // pArray = SQArray::Create(_ss(m_hVM), 0);
  3516. // MapPtr( pOld, pArray );
  3517. // int n = m_pBuffer->GetInt();
  3518. // pArray->Reserve( n );
  3519. // while ( n-- )
  3520. // {
  3521. // SQObjectPtr value;
  3522. // ReadObject( value );
  3523. // pArray->Append( value );
  3524. // }
  3525. // return pArray;
  3526. //}
  3527. ////-------------------------------------------------------------
  3528. ////
  3529. ////-------------------------------------------------------------
  3530. //SQClass *ReadClass()
  3531. //{
  3532. // SQClass *pOld;
  3533. // SQClass *pClass;
  3534. // if ( !BeginRead( &pOld, &pClass ) )
  3535. // {
  3536. // return pClass;
  3537. // }
  3538. // SQClass *pBase = NULL;
  3539. // bool bIsNative = !!m_pBuffer->GetInt();
  3540. // // If it's not a C++ defined type...
  3541. // if ( !bIsNative )
  3542. // {
  3543. // if ( m_pBuffer->GetInt() )
  3544. // {
  3545. // SQObjectPtr base;
  3546. // ReadObject( base );
  3547. // pBase = base._unVal.pClass;
  3548. // }
  3549. // SQClass *pClass = SQClass::Create( _ss(m_hVM), pBase );
  3550. // MapPtr( pOld, pClass );
  3551. // SQObjectPtr members;
  3552. // ReadObject( members );
  3553. // pClass->_members->Release();
  3554. // pClass->_members = members._unVal.pTable;
  3555. // __ObjAddRef( members._unVal.pTable );
  3556. // ReadObject( pClass->_attributes );
  3557. // unsigned i, n;
  3558. // n = m_pBuffer->GetUnsignedInt();
  3559. // pClass->_defaultvalues.resize( n );
  3560. // for ( i = 0; i < n; i++ )
  3561. // {
  3562. // ReadObject(pClass->_defaultvalues[i].val);
  3563. // ReadObject(pClass->_defaultvalues[i].attrs);
  3564. // }
  3565. // n = m_pBuffer->GetUnsignedInt();
  3566. // pClass->_methods.resize( n );
  3567. // for ( i = 0; i < n; i++ )
  3568. // {
  3569. // ReadObject(pClass->_methods[i].val);
  3570. // ReadObject(pClass->_methods[i].attrs);
  3571. // }
  3572. // n = m_pBuffer->GetUnsignedInt();
  3573. // pClass->_metamethods.resize( n );
  3574. // for ( i = 0; i < n; i++ )
  3575. // {
  3576. // ReadObject(pClass->_metamethods[i]);
  3577. // }
  3578. // return pClass;
  3579. // }
  3580. // else
  3581. // {
  3582. // char *pszName = (char *)stackalloc( 1024 );
  3583. // m_pBuffer->GetString( pszName, 1024 );
  3584. // pszName[1023] = 0;
  3585. // SQObjectPtr value;
  3586. // if ( m_hVM->_roottable._unVal.pTable->Get( SQString::Create( _ss(m_hVM ), pszName ), value ) && sq_isclass( value ) )
  3587. // {
  3588. // MapPtr( pOld, value._unVal.pClass );
  3589. // return value._unVal.pClass;
  3590. // }
  3591. // MapPtr( pOld, NULL );
  3592. // }
  3593. // return NULL;
  3594. //}
  3595. ////-------------------------------------------------------------
  3596. ////
  3597. ////-------------------------------------------------------------
  3598. //SQInstance *ReadInstance()
  3599. //{
  3600. // SQInstance *pOld;
  3601. // SQInstance *pInstance;
  3602. // if ( !BeginRead( &pOld, &pInstance ) )
  3603. // {
  3604. // return pInstance;
  3605. // }
  3606. // SQObjectPtr pClass;
  3607. // ReadObject( pClass );
  3608. // unsigned i, n;
  3609. // if ( pClass._unVal.pClass )
  3610. // {
  3611. // pInstance = SQInstance::Create( _ss(m_hVM), pClass._unVal.pClass );
  3612. // n = m_pBuffer->GetUnsignedInt();
  3613. // for ( i = 0; i < n; i++ )
  3614. // {
  3615. // ReadObject(pInstance->_values[i]);
  3616. // }
  3617. // m_pBuffer->GetPtr(); // ignored in this path
  3618. // if ( pInstance->_class->_typetag )
  3619. // {
  3620. // if ( pInstance->_class->_typetag == TYPETAG_VECTOR )
  3621. // {
  3622. // Vector *pValue = new Vector;
  3623. // pValue->x = m_pBuffer->GetFloat();
  3624. // pValue->y = m_pBuffer->GetFloat();
  3625. // pValue->z = m_pBuffer->GetFloat();
  3626. // pInstance->_userpointer = pValue;
  3627. // }
  3628. // else
  3629. // {
  3630. // InstanceContext_t *pContext = new InstanceContext_t;
  3631. // pContext->pInstance = NULL;
  3632. // ReadObject( pContext->name );
  3633. // pContext->pClassDesc = (ScriptClassDesc_t *)( pInstance->_class->_typetag );
  3634. // void *pOldInstance = m_pBuffer->GetPtr();
  3635. // if ( sq_isstring(pContext->name) )
  3636. // {
  3637. // char *pszName = pContext->name._unVal.pString->_val;
  3638. // if ( pContext->pClassDesc->pHelper )
  3639. // {
  3640. // HPYOBJECT *pInstanceHandle = new HPYOBJECT;
  3641. // pInstanceHandle->_type = OT_INSTANCE;
  3642. // pInstanceHandle->_unVal.pInstance = pInstance;
  3643. // pContext->pInstance = pContext->pClassDesc->pHelper->BindOnRead( (HSCRIPT)pInstanceHandle, pOldInstance, pszName );
  3644. // if ( pContext->pInstance )
  3645. // {
  3646. // pInstance->_uiRef++;
  3647. // sq_addref( m_hVM, pInstanceHandle );
  3648. // pInstance->_uiRef--;
  3649. // }
  3650. // else
  3651. // {
  3652. // delete pInstanceHandle;
  3653. // }
  3654. // }
  3655. // if ( !pContext->pInstance )
  3656. // {
  3657. // // Look for a match in the current root table
  3658. // HPYOBJECT hExistingObject = LookupObject( pszName, NULL, false );
  3659. // if ( sq_isinstance(hExistingObject) && hExistingObject._unVal.pInstance->_class == pInstance->_class )
  3660. // {
  3661. // delete pInstance;
  3662. // return hExistingObject._unVal.pInstance;
  3663. // }
  3664. // pContext->pInstance = NULL;
  3665. // }
  3666. // }
  3667. // pInstance->_userpointer = pContext;
  3668. // }
  3669. // }
  3670. // else
  3671. // {
  3672. // Verify( m_pBuffer->GetInt() == OT_USERPOINTER );
  3673. // pInstance->_userpointer = ReadUserPointer();
  3674. // Assert( pInstance->_userpointer == NULL );
  3675. // }
  3676. // MapPtr( pOld, pInstance );
  3677. // }
  3678. // else
  3679. // {
  3680. // MapPtr( pOld, NULL );
  3681. // n = m_pBuffer->GetUnsignedInt();
  3682. // for ( i = 0; i < n; i++ )
  3683. // {
  3684. // SQObjectPtr ignored;
  3685. // ReadObject(ignored);
  3686. // }
  3687. // void *pOldTypeTag = m_pBuffer->GetPtr(); // ignored in this path
  3688. // if ( pOldTypeTag )
  3689. // {
  3690. // if ( pOldTypeTag == TYPETAG_VECTOR )
  3691. // {
  3692. // m_pBuffer->GetFloat();
  3693. // m_pBuffer->GetFloat();
  3694. // m_pBuffer->GetFloat();
  3695. // }
  3696. // else
  3697. // {
  3698. // SQObjectPtr ignored;
  3699. // ReadObject( ignored );
  3700. // m_pBuffer->GetPtr();
  3701. // }
  3702. // }
  3703. // else
  3704. // {
  3705. // Verify( m_pBuffer->GetInt() == OT_USERPOINTER );
  3706. // ReadUserPointer();
  3707. // }
  3708. // pInstance = NULL;
  3709. // }
  3710. // return pInstance;
  3711. //}
  3712. ////-------------------------------------------------------------
  3713. ////
  3714. ////-------------------------------------------------------------
  3715. //SQGenerator *ReadGenerator()
  3716. //{
  3717. // SQGenerator *pOld;
  3718. // SQGenerator *pGenerator;
  3719. // if ( !BeginRead( &pOld, &pGenerator ) )
  3720. // {
  3721. // return pGenerator;
  3722. // }
  3723. // SQObjectPtr closure;
  3724. // ReadObject( closure );
  3725. // pGenerator = SQGenerator::Create( _ss(m_hVM), closure._unVal.pClosure );
  3726. // MapPtr( pOld, pGenerator );
  3727. // unsigned i, n;
  3728. // n = m_pBuffer->GetUnsignedInt();
  3729. // pGenerator->_stack.resize( n );
  3730. // for ( i = 0; i < n; i++ )
  3731. // {
  3732. // ReadObject(pGenerator->_stack[i]);
  3733. // }
  3734. // n = m_pBuffer->GetUnsignedInt();
  3735. // pGenerator->_vargsstack.resize( n );
  3736. // for ( i = 0; i < n; i++ )
  3737. // {
  3738. // ReadObject(pGenerator->_vargsstack[i]);
  3739. // }
  3740. // return pGenerator;
  3741. //}
  3742. ////-------------------------------------------------------------
  3743. ////
  3744. ////-------------------------------------------------------------
  3745. //SQClosure *ReadClosure()
  3746. //{
  3747. // SQClosure *pOld;
  3748. // SQClosure *pClosure;
  3749. // if ( !BeginRead( &pOld, &pClosure ) )
  3750. // {
  3751. // return pClosure;
  3752. // }
  3753. // SQObjectPtr proto;
  3754. // ReadObject( proto );
  3755. // pClosure = SQClosure::Create( _ss(m_hVM), proto._unVal.pFunctionProto );
  3756. // MapPtr( pOld, pClosure );
  3757. // ReadObject( pClosure->_env );
  3758. // unsigned i, n;
  3759. // n = m_pBuffer->GetUnsignedInt();
  3760. // pClosure->_outervalues.resize( n );
  3761. // for ( i = 0; i < n; i++ )
  3762. // {
  3763. // ReadObject(pClosure->_outervalues[i]);
  3764. // }
  3765. // n = m_pBuffer->GetUnsignedInt();
  3766. // pClosure->_defaultparams.resize( n );
  3767. // for ( i = 0; i < n; i++ )
  3768. // {
  3769. // ReadObject(pClosure->_defaultparams[i]);
  3770. // }
  3771. // return pClosure;
  3772. //}
  3773. ////-------------------------------------------------------------
  3774. ////
  3775. ////-------------------------------------------------------------
  3776. //SQNativeClosure *ReadNativeClosure()
  3777. //{
  3778. // SQNativeClosure *pOld;
  3779. // SQNativeClosure *pClosure;
  3780. // if ( !BeginRead( &pOld, &pClosure ) )
  3781. // {
  3782. // return pClosure;
  3783. // }
  3784. // SQObjectPtr name;
  3785. // ReadObject( name );
  3786. // SQObjectPtr value;
  3787. // if ( m_hVM->_roottable._unVal.pTable->Get( name, value ) && sq_isnativeclosure(value) )
  3788. // {
  3789. // MapPtr( pOld, value._unVal.pNativeClosure );
  3790. // return value._unVal.pNativeClosure;
  3791. // }
  3792. // MapPtr( pOld, NULL );
  3793. // return NULL; // @TBD [4/15/2008 tom]
  3794. //}
  3795. ////-------------------------------------------------------------
  3796. ////
  3797. ////-------------------------------------------------------------
  3798. //SQUserData *ReadUserData()
  3799. //{
  3800. // m_pBuffer->GetPtr();
  3801. // return NULL; // @TBD [4/15/2008 tom]
  3802. //}
  3803. ////-------------------------------------------------------------
  3804. ////
  3805. ////-------------------------------------------------------------
  3806. //SQUserPointer *ReadUserPointer()
  3807. //{
  3808. // m_pBuffer->GetPtr();
  3809. // return NULL; // @TBD [4/15/2008 tom]
  3810. //}
  3811. ////-------------------------------------------------------------
  3812. ////
  3813. ////-------------------------------------------------------------
  3814. //static SQInteger SqReadFunc(SQUserPointer up,SQUserPointer data, SQInteger size)
  3815. // {
  3816. // CPythonVM *pThis = (CPythonVM *)up;
  3817. // pThis->m_pBuffer->Get( data, size );
  3818. // return size;
  3819. // }
  3820. //
  3821. ////-------------------------------------------------------------
  3822. ////
  3823. ////-------------------------------------------------------------
  3824. //SQFunctionProto *ReadFuncProto()
  3825. //{
  3826. // SQFunctionProto *pOld;
  3827. // SQFunctionProto *pResult;
  3828. // if ( !BeginRead( &pOld, &pResult ) )
  3829. // {
  3830. // return pResult;
  3831. // }
  3832. // SQObjectPtr result;
  3833. // SQFunctionProto::Load( m_hVM, this, &SqReadFunc, result );
  3834. // pResult = result._unVal.pFunctionProto;
  3835. // pResult->_uiRef++;
  3836. // result.Null();
  3837. // pResult->_uiRef--;
  3838. // MapPtr( pOld, pResult );
  3839. // return pResult;
  3840. //}
  3841. ////-------------------------------------------------------------
  3842. ////
  3843. ////-------------------------------------------------------------
  3844. //SQWeakRef *ReadWeakRef( )
  3845. //{
  3846. // SQObjectPtr obj;
  3847. // ReadObject( obj );
  3848. // if ( !obj._unVal.pRefCounted )
  3849. // {
  3850. // return NULL;
  3851. // }
  3852. // // Need to up ref count if read order has weak ref loading first
  3853. // Assert( ISREFCOUNTED(obj._type) );
  3854. // SQRefCounted *pRefCounted = obj._unVal.pRefCounted;
  3855. // pRefCounted->_uiRef++;
  3856. // SQWeakRef *pResult = obj._unVal.pRefCounted->GetWeakRef( obj._type );
  3857. // obj.Null();
  3858. // pRefCounted->_uiRef--;
  3859. // return pResult;
  3860. //}
  3861. ////-------------------------------------------------------------
  3862. ////
  3863. ////-------------------------------------------------------------
  3864. //bool FindKeyForObject( const SQObjectPtr &table, void *p, SQObjectPtr &key )
  3865. //{
  3866. // SQTable *pTable = table._unVal.pTable;
  3867. // int len = pTable->_numofnodes;
  3868. // for(int i = 0; i < len; i++)
  3869. // {
  3870. // if ( pTable->_nodes[i].val._unVal.pUserPointer == p )
  3871. // {
  3872. // key = pTable->_nodes[i].key;
  3873. // return true;
  3874. // }
  3875. // if ( sq_istable( pTable->_nodes[i].val ) )
  3876. // {
  3877. // if ( FindKeyForObject( pTable->_nodes[i].val, p, key ) )
  3878. // {
  3879. // return true;
  3880. // }
  3881. // }
  3882. // }
  3883. // return false;
  3884. //}
  3885. // add instance object to consistency checker
  3886. void debugTrackObject( PyObject *pobj )
  3887. {
  3888. #ifdef DEBUG_PY
  3889. if (m_debugObjCount < 1000)
  3890. m_debugObjects[m_debugObjCount++] = pobj;
  3891. #endif // DEBUG_PY
  3892. }
  3893. void debugRemoveTrackedObject( PyObject *pobj )
  3894. {
  3895. #ifdef DEBUG_PY
  3896. for (int i = 0; i < m_debugObjCount; i++)
  3897. if ( m_debugObjects[i] == pobj )
  3898. m_debugObjects[i] = NULL;
  3899. #endif // DEBUG_PY
  3900. }
  3901. CPyScope *m_pRootScope; // __main__ module scope
  3902. CPyScope *m_pValveScope; // valve module scope
  3903. public:
  3904. int m_iMethodDef;
  3905. int m_iClassDef;
  3906. void *m_rgpMethodDefs[MAX_VALVE_FUNCTIONS_EXPORTED]; // array of pointers to fixed blocks of memory - passed to python, must not move!
  3907. void *m_rgpClassDefs[MAX_VALVE_CLASSES_EXPORTED];
  3908. bool m_bInitialized;
  3909. private:
  3910. char m_szScriptPath[MAX_PATH]; // full path to scripts/vscript directory
  3911. int64 m_iUniqueIdSerialNumber;
  3912. float m_TimeStartExecute;
  3913. int m_debugObjCount;
  3914. PyObject *m_debugObjects[1000];
  3915. #ifdef VPYTHON_TEST
  3916. ConVar developer;
  3917. #else
  3918. ConVarRef developer;
  3919. #endif
  3920. CUtlHashFast<PyTypeObject *, CUtlHashFastGenericHash> m_TypeMap; // map pClassDesc to PyTypeObject python type
  3921. CUtlHashFast<ScriptClassDesc_t *, CUtlHashFastGenericHash> m_ClassMap; // map PyTypeObject to pClassDesc
  3922. // friend class CVPythonSerializer;
  3923. // // Serialization support
  3924. // CUtlBuffer *m_pBuffer;
  3925. // CUtlMap<void *, void *> m_PtrMap;
  3926. };
  3927. //-------------------------------------------------------------------------
  3928. // Serialization and Debug Helpers
  3929. //-------------------------------------------------------------------------
  3930. //const char *FieldTypeToString( int type )
  3931. //{
  3932. // switch( type )
  3933. // {
  3934. // case FIELD_VOID: return "void";
  3935. // case FIELD_FLOAT: return "float";
  3936. // case FIELD_CSTRING: return "string";
  3937. // case FIELD_VECTOR: return "Vector";
  3938. // case FIELD_INTEGER: return "int";
  3939. // case FIELD_BOOLEAN: return "bool";
  3940. // case FIELD_CHARACTER: return "char";
  3941. // case FIELD_HSCRIPT: return "handle";
  3942. // default: return "<unknown>";
  3943. // }
  3944. //}
  3945. //static const char *SQTypeToString( SQObjectType sqType )
  3946. //{
  3947. // switch( sqType )
  3948. // {
  3949. // case OT_FLOAT: return "FLOAT";
  3950. // case OT_INTEGER: return "INTEGER";
  3951. // case OT_BOOL: return "BOOL";
  3952. // case OT_STRING: return "STRING";
  3953. // case OT_NULL: return "NULL";
  3954. // case OT_TABLE: return "TABLE";
  3955. // case OT_ARRAY: return "ARRAY";
  3956. // case OT_CLOSURE: return "CLOSURE";
  3957. // case OT_NATIVECLOSURE: return "NATIVECLOSURE";
  3958. // case OT_USERDATA: return "USERDATA";
  3959. // case OT_GENERATOR: return "GENERATOR";
  3960. // case OT_THREAD: return "THREAD";
  3961. // case OT_USERPOINTER: return "USERPOINTER";
  3962. // case OT_CLASS: return "CLASS";
  3963. // case OT_INSTANCE: return "INSTANCE";
  3964. // case OT_WEAKREF: return "WEAKREF";
  3965. // }
  3966. // return "<unknown>";
  3967. //}
  3968. //----------------------------------------------------------------------------------
  3969. // return true if interpreter init is finalized - block attempts at re-init.
  3970. //----------------------------------------------------------------------------------
  3971. inline bool VMInitFinalized( void )
  3972. {
  3973. return ((CPythonVM *)g_pVm)->m_bInitialized;
  3974. }
  3975. //----------------------------------------------------------------------------------
  3976. // create interpreter singleton and save pointer to interface in g_pVm
  3977. //----------------------------------------------------------------------------------
  3978. IScriptVM *ScriptCreatePythonVM()
  3979. {
  3980. if ( !g_pVm )
  3981. {
  3982. g_pVm = new CPythonVM;
  3983. }
  3984. else
  3985. {
  3986. // set semaphore to block more than one init of interpreter,
  3987. // this blocks registration of any more classes or functions, but not of instances
  3988. ((CPythonVM *)g_pVm)->m_bInitialized = true;
  3989. }
  3990. return (IScriptVM *)g_pVm;
  3991. }
  3992. //----------------------------------------------------------------------------------
  3993. // called after shutdown() on restart or level load or exit
  3994. // NOTE: we should not actually kill the interpreter unless it's a full game exit.
  3995. // UNDONE: we don't cleanly shut down the interpeter on game exit.
  3996. //----------------------------------------------------------------------------------
  3997. void ScriptDestroyPythonVM( IScriptVM *pVm )
  3998. {
  3999. // UNDONE: ivscript interface needs a flag to indicate game exit - the only case we should actually kill the interpreter
  4000. bool bGameExit = false;
  4001. if ( bGameExit )
  4002. {
  4003. // release memory associated with dynamically allocated data
  4004. CPythonVM *pPythonVM = assert_cast<CPythonVM *>( pVm );
  4005. if (1)
  4006. { // UNDONE: ONE shutdown per game session only!
  4007. // whether these are allocated using new/delete, python PyObject_Malloc/Free,
  4008. // this dealloc causes the next Py_Initialize/Py_Finalize to fail intermittently (ie on restart).
  4009. // Python documentation indicates that Py_Finalize does NOT reliably release all allocated resources,
  4010. // and users of various versions report problems with Py_Finalize followed by a subsequent
  4011. // Py_Initialize.
  4012. int i;
  4013. for (i = 0; i < pPythonVM->m_iMethodDef; i++)
  4014. {
  4015. PyMem_Free( pPythonVM->m_rgpMethodDefs[i] );
  4016. }
  4017. for (i = 0; i < pPythonVM->m_iClassDef; i++)
  4018. {
  4019. PyMem_Free( pPythonVM->m_rgpClassDefs[i] );
  4020. }
  4021. pPythonVM->m_iMethodDef = 0;
  4022. pPythonVM->m_iClassDef = 0;
  4023. }
  4024. if (1) // TEST2:
  4025. delete pPythonVM;
  4026. }
  4027. }
  4028. //-------------------------------------------------------------------
  4029. // C function & method call proxies:
  4030. // Do a bunch of proxy work to expose server-side functions/methods
  4031. // with their specific bindings to python.
  4032. //
  4033. // Since python does not support
  4034. // specifying user data along with c-defined function/method callbacks,
  4035. // and we need specific python->c binding data for each function/method callback,
  4036. // we have to create unique proxy functions for every callback.
  4037. //
  4038. // Each unique proxy gets the correct binding info for the function,
  4039. // then calls the general TranslateCall routine to do the dispatch.
  4040. //-------------------------------------------------------------------
  4041. //------------------------------------------------------------------
  4042. // define a static callback proxy - python calls this back to access
  4043. // a function or method definition of a valve class
  4044. //-----------------------------------------------------------------
  4045. #define DPX(N) \
  4046. static PyObject *Translate_##N( PyObject *pSelf, PyObject *pArgs ) \
  4047. { \
  4048. ScriptFunctionBinding_t *pBinding = GetProxyBinding( ##N ); \
  4049. return ( CPythonVM::TranslateCall( pBinding, (scriptClassInstance_t *)pSelf, pArgs ) ); \
  4050. } \
  4051. // set proxy definition
  4052. #define SPX(N) g_proxies[##N].pfn = Translate_##N;
  4053. static int g_proxyid = 0;
  4054. static int GetNewProxyId( void )
  4055. {
  4056. int proxyId = g_proxyid;
  4057. Assert ( proxyId < MAX_VALVE_FUNCTIONS_EXPORTED ); // if this fails, just need to bump up MAX_VALVE_FUNCTIONS_EXPORTED and add more DPX(n),SPX(n) entries
  4058. g_proxyid++;
  4059. return proxyId;
  4060. }
  4061. // associate the function and/or class binding with the proxy function id
  4062. static void SetProxyBinding( int proxyId, ScriptFunctionBinding_t *pBinding )
  4063. {
  4064. Assert( proxyId < MAX_VALVE_FUNCTIONS_EXPORTED ); // if this fails, just need to bump up MAX_VALVE_FUNCTIONS_EXPORTED and add more DPX(n) entries
  4065. g_proxies[proxyId].pBinding = pBinding;
  4066. }
  4067. static PyCFunction GetProxyFunction( int proxyId )
  4068. {
  4069. Assert( proxyId < MAX_VALVE_FUNCTIONS_EXPORTED ); // invalid proxyId
  4070. return g_proxies[proxyId].pfn;
  4071. }
  4072. // retrieve the function binding, given the proxy index
  4073. static ScriptFunctionBinding_t *GetProxyBinding( int proxyId )
  4074. {
  4075. Assert( proxyId < MAX_VALVE_FUNCTIONS_EXPORTED ); // invalid proxyId
  4076. return ( g_proxies[proxyId].pBinding );
  4077. }
  4078. DPX(0) DPX(1) DPX(2) DPX(3) DPX(4) DPX(5) DPX(6) DPX(7) DPX(8) DPX(9) DPX(10) DPX(11) DPX(12) DPX(13) DPX(14) DPX(15) DPX(16) DPX(17) DPX(18) DPX(19)
  4079. DPX(20) DPX(21) DPX(22) DPX(23) DPX(24) DPX(25) DPX(26) DPX(27) DPX(28) DPX(29) DPX(30) DPX(31) DPX(32) DPX(33) DPX(34) DPX(35) DPX(36) DPX(37) DPX(38) DPX(39)
  4080. DPX(40) DPX(41) DPX(42) DPX(43) DPX(44) DPX(45) DPX(46) DPX(47) DPX(48) DPX(49) DPX(50) DPX(51) DPX(52) DPX(53) DPX(54) DPX(55) DPX(56) DPX(57) DPX(58) DPX(59)
  4081. DPX(60) DPX(61) DPX(62) DPX(63) DPX(64) DPX(65) DPX(66) DPX(67) DPX(68) DPX(69) DPX(70) DPX(71) DPX(72) DPX(73) DPX(74) DPX(75) DPX(76) DPX(77) DPX(78) DPX(79)
  4082. DPX(80) DPX(81) DPX(82) DPX(83) DPX(84) DPX(85) DPX(86) DPX(87) DPX(88) DPX(89) DPX(90) DPX(91) DPX(92) DPX(93) DPX(94) DPX(95) DPX(96) DPX(97) DPX(98) DPX(99)
  4083. DPX(100) DPX(101) DPX(102) DPX(103) DPX(104) DPX(105) DPX(106) DPX(107) DPX(108) DPX(109) DPX(110) DPX(111) DPX(112) DPX(113) DPX(114) DPX(115) DPX(116) DPX(117) DPX(118) DPX(119)
  4084. DPX(120) DPX(121) DPX(122) DPX(123) DPX(124) DPX(125) DPX(126) DPX(127) DPX(128) DPX(129) DPX(130) DPX(131) DPX(132) DPX(133) DPX(134) DPX(135) DPX(136) DPX(137) DPX(138) DPX(139)
  4085. DPX(140) DPX(141) DPX(142) DPX(143) DPX(144) DPX(145) DPX(146) DPX(147) DPX(148) DPX(149) DPX(150) DPX(151) DPX(152) DPX(153) DPX(154) DPX(155) DPX(156) DPX(157) DPX(158) DPX(159)
  4086. DPX(160) DPX(161) DPX(162) DPX(163) DPX(164) DPX(165) DPX(166) DPX(167) DPX(168) DPX(169) DPX(170) DPX(171) DPX(172) DPX(173) DPX(174) DPX(175) DPX(176) DPX(177) DPX(178) DPX(179)
  4087. DPX(180) DPX(181) DPX(182) DPX(183) DPX(184) DPX(185) DPX(186) DPX(187) DPX(188) DPX(189) DPX(190) DPX(191) DPX(192) DPX(193) DPX(194) DPX(195) DPX(196) DPX(197) DPX(198) DPX(199)
  4088. DPX(200) DPX(201) DPX(202) DPX(203) DPX(204) DPX(205) DPX(206) DPX(207) DPX(208) DPX(209) DPX(210) DPX(211) DPX(212) DPX(213) DPX(214) DPX(215) DPX(216) DPX(217) DPX(218) DPX(219)
  4089. DPX(220) DPX(221) DPX(222) DPX(223) DPX(224) DPX(225) DPX(226) DPX(227) DPX(228) DPX(229) DPX(230) DPX(231) DPX(232) DPX(233) DPX(234) DPX(235) DPX(236) DPX(237) DPX(238) DPX(239)
  4090. DPX(240) DPX(241) DPX(242) DPX(243) DPX(244) DPX(245) DPX(246) DPX(247) DPX(248) DPX(249) DPX(250) DPX(251) DPX(252) DPX(253) DPX(254) DPX(255) DPX(256) DPX(257) DPX(258) DPX(259)
  4091. static void InitProxyTable( void )
  4092. {
  4093. g_proxyid = 0;
  4094. SPX(0) SPX(1) SPX(2) SPX(3) SPX(4) SPX(5) SPX(6) SPX(7) SPX(8) SPX(9) SPX(10) SPX(11) SPX(12) SPX(13) SPX(14) SPX(15) SPX(16) SPX(17) SPX(18) SPX(19)
  4095. SPX(20) SPX(21) SPX(22) SPX(23) SPX(24) SPX(25) SPX(26) SPX(27) SPX(28) SPX(29) SPX(30) SPX(31) SPX(32) SPX(33) SPX(34) SPX(35) SPX(36) SPX(37) SPX(38) SPX(39)
  4096. SPX(40) SPX(41) SPX(42) SPX(43) SPX(44) SPX(45) SPX(46) SPX(47) SPX(48) SPX(49) SPX(50) SPX(51) SPX(52) SPX(53) SPX(54) SPX(55) SPX(56) SPX(57) SPX(58) SPX(59)
  4097. SPX(60) SPX(61) SPX(62) SPX(63) SPX(64) SPX(65) SPX(66) SPX(67) SPX(68) SPX(69) SPX(70) SPX(71) SPX(72) SPX(73) SPX(74) SPX(75) SPX(76) SPX(77) SPX(78) SPX(79)
  4098. SPX(80) SPX(81) SPX(82) SPX(83) SPX(84) SPX(85) SPX(86) SPX(87) SPX(88) SPX(89) SPX(90) SPX(91) SPX(92) SPX(93) SPX(94) SPX(95) SPX(96) SPX(97) SPX(98) SPX(99)
  4099. SPX(100) SPX(101) SPX(102) SPX(103) SPX(104) SPX(105) SPX(106) SPX(107) SPX(108) SPX(109) SPX(110) SPX(111) SPX(112) SPX(113) SPX(114) SPX(115) SPX(116) SPX(117) SPX(118) SPX(119)
  4100. SPX(120) SPX(121) SPX(122) SPX(123) SPX(124) SPX(125) SPX(126) SPX(127) SPX(128) SPX(129) SPX(130) SPX(131) SPX(132) SPX(133) SPX(134) SPX(135) SPX(136) SPX(137) SPX(138) SPX(139)
  4101. SPX(140) SPX(141) SPX(142) SPX(143) SPX(144) SPX(145) SPX(146) SPX(147) SPX(148) SPX(149) SPX(150) SPX(151) SPX(152) SPX(153) SPX(154) SPX(155) SPX(156) SPX(157) SPX(158) SPX(159)
  4102. SPX(160) SPX(161) SPX(162) SPX(163) SPX(164) SPX(165) SPX(166) SPX(167) SPX(168) SPX(169) SPX(170) SPX(171) SPX(172) SPX(173) SPX(174) SPX(175) SPX(176) SPX(177) SPX(178) SPX(179)
  4103. SPX(180) SPX(181) SPX(182) SPX(183) SPX(184) SPX(185) SPX(186) SPX(187) SPX(188) SPX(189) SPX(190) SPX(191) SPX(192) SPX(193) SPX(194) SPX(195) SPX(196) SPX(197) SPX(198) SPX(199)
  4104. SPX(200) SPX(201) SPX(202) SPX(203) SPX(204) SPX(205) SPX(206) SPX(207) SPX(208) SPX(209) SPX(210) SPX(211) SPX(212) SPX(213) SPX(214) SPX(215) SPX(216) SPX(217) SPX(218) SPX(219)
  4105. SPX(220) SPX(221) SPX(222) SPX(223) SPX(224) SPX(225) SPX(226) SPX(227) SPX(228) SPX(229) SPX(230) SPX(231) SPX(232) SPX(233) SPX(234) SPX(235) SPX(236) SPX(237) SPX(238) SPX(239)
  4106. SPX(240) SPX(241) SPX(242) SPX(243) SPX(244) SPX(245) SPX(246) SPX(247) SPX(248) SPX(249) SPX(250) SPX(251) SPX(252) SPX(253) SPX(254) SPX(255) SPX(256) SPX(257) SPX(258) SPX(259)
  4107. }
  4108. #ifdef VPYTHON_TEST
  4109. CPythonVM g_PythonVM;
  4110. IScriptVM *g_pScriptVM = &g_PythonVM;
  4111. //-----------------------------------------------------------------------------
  4112. //
  4113. //-----------------------------------------------------------------------------
  4114. #include <time.h>
  4115. int main( int argc, const char **argv)
  4116. {
  4117. if ( argc < 2 )
  4118. {
  4119. printf( "No script specified" );
  4120. return 1;
  4121. }
  4122. g_pScriptVM->Init();
  4123. const char *pszbuild;
  4124. pszbuild = Py_GetVersion( ) ;
  4125. printf("You should be using python 2.5.x. You are using python \"%s\".\n", pszbuild);
  4126. // run a script without a source file - remote debugger will ask for a source file
  4127. g_pScriptVM->Run(
  4128. "import pydevd\n"
  4129. //"pydevd.settrace(stdoutToServer = True, stderrToServer = True, port = 5678, suspend = True)\n"
  4130. "from time import time,ctime\n"
  4131. "print 'Today is',ctime(time())\n"
  4132. );
  4133. //CCycleCount count;
  4134. //count.Sample();
  4135. //RandomSeed( time( NULL ) ^ count.GetMicroseconds() );
  4136. ScriptRegisterFunction( g_pScriptVM, RandomFloat, "" );
  4137. ScriptRegisterFunction( g_pScriptVM, RandomInt, "" );
  4138. if ( argc == 3 && *argv[2] == 'd' )
  4139. {
  4140. g_pScriptVM->ConnectDebugger();
  4141. // exec a script that invokes the remote python debugger in eclipse pydev
  4142. // NOTE: this is the only valid way to get an hFile to use with Py_ calls. FILE * returned from fopen is not compatible.
  4143. PyObject* pyfile = PyFile_FromString( "debug.py", "r");
  4144. FILE* hFile = PyFile_AsFile( pyfile);
  4145. int ret = PyRun_AnyFile(hFile, "debug.py");
  4146. Py_XDECREF(pyfile);
  4147. }
  4148. int key;
  4149. CScriptScope scope;
  4150. scope.Init( "TestScope" );
  4151. do
  4152. {
  4153. const char *pszScript = argv[1];
  4154. FILE *hFile = fopen( pszScript, "rb" );
  4155. if ( !hFile )
  4156. {
  4157. printf( "\"%s\" not found.\n", pszScript );
  4158. return 1;
  4159. }
  4160. int nFileLen = _filelength( _fileno( hFile ) );
  4161. char *pBuf = new char[nFileLen + 1];
  4162. fread( pBuf, 1, nFileLen, hFile );
  4163. pBuf[nFileLen] = 0;
  4164. fclose( hFile );
  4165. if (1)
  4166. {
  4167. printf( "Executing script \"%s\"\n----------------------------------------\n", pszScript );
  4168. HSCRIPT hScript = g_pScriptVM->CompileScript( pBuf, ( strrchr( pszScript, '\\' ) ? strrchr( pszScript, '\\' ) + 1 : pszScript ) );
  4169. if ( hScript )
  4170. {
  4171. if ( scope.Run( hScript ) != SCRIPT_ERROR )
  4172. {
  4173. printf( "----------------------------------------\n" );
  4174. printf("Script complete. Press q to exit, m to dump memory usage, enter to run again.\n");
  4175. }
  4176. else
  4177. {
  4178. printf( "----------------------------------------\n" );
  4179. printf("Script execution error. Press q to exit, m to dump memory usage, enter to run again.\n");
  4180. }
  4181. g_pScriptVM->ReleaseScript( hScript );
  4182. }
  4183. else
  4184. {
  4185. printf( "----------------------------------------\n" );
  4186. printf("Script failed to compile. Press q to exit, m to dump memory usage, enter to run again.\n");
  4187. }
  4188. }
  4189. key = _getch(); // Keypress before exit
  4190. if ( key == 'm' )
  4191. {
  4192. Msg( "%d\n", g_pMemAlloc->GetSize( NULL ) );
  4193. }
  4194. delete pBuf;
  4195. } while ( key != 'q' );
  4196. scope.Term();
  4197. g_pScriptVM->DisconnectDebugger();
  4198. g_pScriptVM->Shutdown();
  4199. return 0;
  4200. }
  4201. #endif