static PyObject* Nonlocals_call( Nonlocals* self, PyObject* args, PyObject* kwargs ) { unsigned int level; static char* kwlist[] = { "level", 0 }; if( !PyArg_ParseTupleAndKeywords( args, kwargs, "I", kwlist, &level ) ) return 0; unsigned int offset = 0; PyObjectPtr parentptr; PyObjectPtr objptr( newref( self->owner ) ); while( offset != level ) { parentptr = PyObject_GetAttr( objptr.get(), parent_str ); if( !parentptr ) return 0; if( parentptr.get() == Py_None ) break; objptr = parentptr; ++offset; } if( offset != level ) { PyErr_Format( PyExc_ValueError, "Scope level %u is out of range", level ); return 0; } PyObject* res = PyType_GenericNew( self->ob_type, 0, 0 ); if( res ) { Nonlocals* nl = reinterpret_cast<Nonlocals*>( res ); nl->owner = objptr.newref(); nl->tracer = xnewref( self->tracer ); } return res; }
static int event_handler( Member* member, CAtom* atom, PyObject* value ) { PyObjectPtr valueptr( member->full_validate( atom, Py_None, value ) ); if( !valueptr ) return -1; if( atom->get_notifications_enabled() ) { PyObjectPtr argsptr; if( member->has_observers() ) { argsptr = event_args( atom, member, valueptr.get() ); if( !argsptr ) return -1; if( !member->notify( atom, argsptr.get(), 0 ) ) return -1; } if( atom->has_observers( member->name ) ) { if( !argsptr ) { argsptr = event_args( atom, member, valueptr.get() ); if( !argsptr ) return -1; } if( !atom->notify( member->name, argsptr.get(), 0 ) ) return -1; } } return 0; }
static PyObject* CAtom_observe( CAtom* self, PyObject* args ) { if( PyTuple_GET_SIZE( args ) != 2 ) return py_type_fail( "observe() takes exactly 2 arguments" ); PyObject* topic = PyTuple_GET_ITEM( args, 0 ); PyObject* callback = PyTuple_GET_ITEM( args, 1 ); if( PyString_Check( topic ) ) { if( !self->observe( topic, callback ) ) return 0; } else { PyObjectPtr iterator( PyObject_GetIter( topic ) ); if( !iterator ) return 0; PyObjectPtr topicptr; while( ( topicptr = PyIter_Next( iterator.get() ) ) ) { if( !self->observe( topicptr.get(), callback ) ) return 0; } if( PyErr_Occurred() ) return 0; } Py_RETURN_NONE; }
PyObjectPtr importModule(const std::string& module) { PyObjectPtr pyModuleName = String::make(module).obj; throwPythonException(); PyObjectPtr pyModule = makePyObjectPtr(PyImport_Import(pyModuleName.get())); throwPythonException(); return pyModule; }
bool EntityApp<E>::destroyEntity(ENTITY_ID entityID, bool callScript) { PyObjectPtr entity = pEntities_->erase(entityID); if(entity != NULL) { static_cast<E*>(entity.get())->destroy(callScript); return true; } ERROR_MSG(boost::format("EntityApp::destroyEntity: not found %1%!\n") % entityID); return false; }
PyObjectPtr getAttribute(PyObjectPtr obj, const std::string& attribute) { PyObjectPtr pyAttr = makePyObjectPtr(PyObject_GetAttrString( obj.get(), attribute.c_str())); throwPythonException(); return pyAttr; }
//------------------------------------------------------------------------------------- void Baseapp::_onCreateBaseAnywhereCallback(Mercury::Channel* pChannel, CALLBACK_ID callbackID, std::string& entityType, ENTITY_ID eid, COMPONENT_ID componentID) { if(callbackID == 0) return; PyObjectPtr pyCallback = callbackMgr().take(callbackID); PyObject* pyargs = PyTuple_New(1); if(pChannel != NULL) { ScriptDefModule* sm = EntityDef::findScriptModule(entityType.c_str()); if(sm == NULL) { ERROR_MSG("Baseapp::onCreateBaseAnywhereCallback: can't found entityType:%s.\n", entityType.c_str()); Py_DECREF(pyargs); return; } // 如果entity属于另一个baseapp创建则设置它的mailbox Mercury::Channel* pOtherBaseappChannel = Components::getSingleton().findComponent(componentID)->pChannel; KBE_ASSERT(pOtherBaseappChannel != NULL); PyObject* mb = static_cast<EntityMailbox*>(new EntityMailbox(sm, NULL, componentID, eid, MAILBOX_TYPE_BASE)); PyTuple_SET_ITEM(pyargs, 0, mb); PyObject_CallObject(pyCallback.get(), pyargs); //Py_DECREF(mb); int i=0; i++; } else { Base* base = pEntities_->find(eid); if(base == NULL) { ERROR_MSG("Baseapp::onCreateBaseAnywhereCallback: can't found entity:%ld.\n", eid); Py_DECREF(pyargs); return; } Py_INCREF(base); PyTuple_SET_ITEM(pyargs, 0, base); PyObject_CallObject(pyCallback.get(), pyargs); } SCRIPT_ERROR_CHECK(); Py_DECREF(pyargs); }
/*----------------------------------------------------------------------------- | Utilities |----------------------------------------------------------------------------*/ static int test_dynamic_attr( PyObject* obj, PyObject* name ) { PyTypeObject* tp; PyObject** dictptr; PyObjectPtr descr; descrgetfunc descr_f; PyObjectPtr objptr( newref( obj ) ); // The body of this loop is PyObject_GenericGetAttr, modified to // use smart pointers and _PyObject_GetDictPtr, and only test for // the presence of descriptors, not evaluate them. while( objptr.get() != Py_None ) { tp = Py_TYPE( objptr.get() ); // Data descriptor descr_f = 0; descr = xnewref( _PyType_Lookup( tp, name ) ); if( descr && PyType_HasFeature( descr.get()->ob_type, Py_TPFLAGS_HAVE_CLASS ) ) { descr_f = descr.get()->ob_type->tp_descr_get; if( descr_f && PyDescr_IsData( descr.get() ) ) return 1; } // Instance dictionary dictptr = _PyObject_GetDictPtr( objptr.get() ); if( dictptr && *dictptr ) { if( PyDict_GetItem( *dictptr, name ) ) return 1; } // Non-data descriptor if( descr_f || descr ) return 1; // Step up to the parent object objptr = PyObject_GetAttr( objptr.get(), parent_str ); if( !objptr ) return -1; } return 0; }
/** * Called when cloned to clear the cloned links. */ void EditorChunkItemLinkable::clearAllLinks() { // Clear from managers lists WorldManager::instance().linkerManager().removeFromLists(this); // Iterate through the properties of this linker int propCounter = propHelper()->propCount(); for (int i=0; i < propCounter; i++) { DataDescription* pDD = propHelper()->pType()->property( i ); if (!pDD->editable()) continue; // If this property is a linkable property if (propHelper()->isUserDataObjectLink( i )) { propHelper()->propSetToDefault(i); } // If this property is an array of linkable properties else if (propHelper()->isUserDataObjectLinkArray( i )) { PyObjectPtr ob ( propHelper()->propGetPy( i ), PyObjectPtr::STEAL_REFERENCE ); SequenceDataType* dataType = static_cast<SequenceDataType*>( pDD->dataType() ); ArrayPropertiesHelper propArray; propArray.init(chunkItem(), &(dataType->getElemType()), ob.getObject()); // Iterate through the array of links while (propArray.propCount()) { // Delete the link propArray.delItem(0); } } } // Save changes chunkItem()->edSave( chunkItem()->pOwnSect() ); if ( chunkItem()->chunk() != NULL ) WorldManager::instance().changedChunk( chunkItem()->chunk() ); }
static int slot_handler( Member* member, CAtom* atom ) { if( member->index >= atom->get_slot_count() ) { py_no_attr_fail( pyobject_cast( atom ), PyString_AsString( member->name ) ); return -1; } if( atom->is_frozen() ) { PyErr_SetString( PyExc_AttributeError, "can't delete attribute of frozen Atom" ); return -1; } PyObjectPtr valueptr( atom->get_slot( member->index ) ); if( !valueptr ) return 0; atom->set_slot( member->index, 0 ); if( atom->get_notifications_enabled() ) { PyObjectPtr argsptr; if( member->has_observers() ) { argsptr = deleted_args( atom, member, valueptr.get() ); if( !argsptr ) return -1; if( !member->notify( atom, argsptr.get(), 0 ) ) return -1; } if( atom->has_observers( member->name ) ) { if( !argsptr ) { argsptr = deleted_args( atom, member, valueptr.get() ); if( !argsptr ) return -1; } if( !atom->notify( member->name, argsptr.get(), 0 ) ) return -1; } } return 0; }
//------------------------------------------------------------------------------------- FileDataDownload::FileDataDownload(PyObjectPtr objptr, const std::string & descr, int16 id): DataDownload(objptr, descr, id) { wchar_t* PyUnicode_AsWideCharStringRet1 = PyUnicode_AsWideCharString(objptr.get(), NULL); char* pDescr = strutil::wchar2char(PyUnicode_AsWideCharStringRet1); PyMem_Free(PyUnicode_AsWideCharStringRet1); path_ = pDescr; free(pDescr); stream_ = new char[65537]; }
static PyObject* _BoundSignal_New( PyObject* owner, PyObject* objref ) { PyObjectPtr ownerptr( owner, true ); PyObjectPtr objrefptr( objref, true ); PyObjectPtr bsigptr; if( numfree > 0 ) { PyObject* o = reinterpret_cast<PyObject*>( freelist[ --numfree ] ); _Py_NewReference( o ); bsigptr = o; } else { bsigptr = PyType_GenericAlloc( &BoundSignal_Type, 0 ); if( !bsigptr ) return 0; } BoundSignal* bsig = reinterpret_cast<BoundSignal*>( bsigptr.get() ); bsig->owner = ownerptr.release(); bsig->objref = objrefptr.release(); return bsigptr.release(); }
static PyObject* _CAtom_unobserve_2( CAtom* self, PyObject* topic, PyObject* callback ) { if( PyString_Check( topic ) ) { if( !self->unobserve( topic, callback ) ) return 0; } else { PyObjectPtr iterator( PyObject_GetIter( topic ) ); if( !iterator ) return 0; PyObjectPtr topicptr; while( ( topicptr = PyIter_Next( iterator.get() ) ) ) { if( !self->unobserve( topicptr.get(), callback ) ) return 0; } if( PyErr_Occurred() ) return 0; } Py_RETURN_NONE; }
//------------------------------------------------------------------------------------- StringDataDownload::StringDataDownload(PyObjectPtr objptr, const std::string & descr, int16 id): DataDownload(objptr, descr, id) { PyObject* pyobj = PyUnicode_AsUTF8String(objptr.get()); if(pyobj == NULL) { SCRIPT_ERROR_CHECK(); error_ = true; } else { totalBytes_ = (uint32)PyBytes_GET_SIZE(pyobj); stream_ = new char[totalBytes_ + 1]; memcpy(getOutStream(), PyBytes_AS_STRING(pyobj), totalBytes_); Py_DECREF(pyobj); } }
static PyObject* SortedMap_new( PyTypeObject* type, PyObject* args, PyObject* kwargs ) { PyObject* map = 0; static char* kwlist[] = { "map", 0 }; if( !PyArg_ParseTupleAndKeywords( args, kwargs, "|O:__new__", kwlist, &map ) ) return 0; PyObject* self = PyType_GenericNew( type, 0, 0 ); if( !self ) return 0; SortedMap* cself = reinterpret_cast<SortedMap*>( self ); cself->m_items = new SortedMap::Items(); PyObjectPtr seq; if( map ) { if( PyDict_Check( map ) ) { seq = PyObject_GetIter( PyDict_Items( map ) ); if( !seq ) return 0; } else { seq = PyObject_GetIter( map ); if( !seq ) return 0; } } if( seq ) { PyObjectPtr item; while( (item = PyIter_Next( seq.get() )) ) { if( PySequence_Length( item.get() ) != 2) return py_expected_type_fail( item.get(), "pairs of objects" ); cself->setitem( PySequence_GetItem( item.get(), 0 ), PySequence_GetItem( item.get(), 1 ) ); } } return self; }
static int set_dynamic_attr( PyObject* obj, PyObject* name, PyObject* value ) { PyTypeObject* tp; PyObject* dict; PyObject** dictptr; PyObjectPtr descr; descrsetfunc descr_f; PyObjectPtr objptr( newref( obj ) ); // The body of this loop is PyObject_GenericGetAttr, modified to // use smart pointers. while( objptr.get() != Py_None ) { tp = Py_TYPE( objptr.get() ); // Data desciptor descr_f = 0; descr = xnewref( _PyType_Lookup( tp, name ) ); if( descr && PyType_HasFeature( descr.get()->ob_type, Py_TPFLAGS_HAVE_CLASS ) ) { descr_f = descr.get()->ob_type->tp_descr_set; if( descr_f && PyDescr_IsData( descr.get() ) ) return descr_f( descr.get(), objptr.get(), value ); } // Instance dictionary dict = 0; dictptr = _PyObject_GetDictPtr( obj ); if( dictptr ) { dict = *dictptr; if( !dict && value ) { dict = PyDict_New(); if( !dict ) return -1; *dictptr = dict; } } if( dict ) { if( value ) return PyDict_SetItem( dict, name, value ); if( PyDict_DelItem( dict, name ) == 0 ) return 0; if( !PyErr_ExceptionMatches( PyExc_KeyError ) ) return -1; PyErr_Clear(); } // Non-data descriptor if( descr_f ) return descr_f( descr.get(), objptr.get(), value ); // Read-only descriptor if( descr ) PyErr_Format( PyExc_AttributeError, "'%.50s' object attribute '%.400s' is read-only", tp->tp_name, PyString_AS_STRING( name ) ); // Step up to the parent object objptr = PyObject_GetAttr( objptr.get(), parent_str ); if( !objptr ) return -1; } return -1; }
static PyObject* load_dynamic_attr( PyObject* obj, PyObject* name, PyObject* tracer=0 ) { PyTypeObject* tp; PyObject** dictptr; PyObjectPtr descr; descrgetfunc descr_f; PyObjectPtr objptr( newref( obj ) ); // The body of this loop is PyObject_GenericGetAttr, modified to // use smart pointers and _PyObject_GetDictPtr, and run a tracer. while( objptr.get() != Py_None ) { tp = Py_TYPE( objptr.get() ); // Data descriptor descr_f = 0; descr = xnewref( _PyType_Lookup( tp, name ) ); if( descr && PyType_HasFeature( descr.get()->ob_type, Py_TPFLAGS_HAVE_CLASS ) ) { descr_f = descr.get()->ob_type->tp_descr_get; if( descr_f && PyDescr_IsData( descr.get() ) ) { PyObjectPtr res( descr_f( descr.get(), objptr.get(), pyobject_cast( tp ) ) ); if( !res ) maybe_translate_key_error(); else if( tracer && !run_tracer( tracer, objptr.get(), name, res.get() ) ) return 0; return res.release(); } } // Instance dictionary dictptr = _PyObject_GetDictPtr( objptr.get() ); if( dictptr && *dictptr ) { PyObject* item = PyDict_GetItem( *dictptr, name ); if( item ) { if( tracer && !run_tracer( tracer, objptr.get(), name, item ) ) return 0; return newref( item ); } } // Non-data descriptor if( descr_f ) { PyObjectPtr res( descr_f( descr.get(), objptr.get(), pyobject_cast( tp ) ) ); if( !res ) maybe_translate_key_error(); else if( tracer && !run_tracer( tracer, objptr.get(), name, res.get() ) ) return 0; return res.release(); } // Non-readable descriptor if( descr ) { if( tracer && !run_tracer( tracer, objptr.get(), name, descr.get() ) ) return 0; return descr.release(); } // Step up to the parent object objptr = PyObject_GetAttr( objptr.get(), parent_str ); if( !objptr ) return 0; } return 0; }
const double get(unsigned i) { return *((double*)PyArray_GETPTR1(obj.get(), (npy_intp)i)); }
const unsigned size() { return PyList_Size(obj.get()); }
const double get() { return (int)PyInt_AsLong(obj.get()); }
void throwPythonException() { PyObject* error = PyErr_Occurred(); // Borrowed reference if(error != NULL) { PyObject* ptype, * pvalue, * ptraceback; PyErr_Fetch(&ptype, &pvalue, &ptraceback); // Exception type PyObjectPtr pyexception = makePyObjectPtr(PyObject_GetAttrString( ptype, (char*)"__name__")); std::string type = PyString_AsString(pyexception.get()); // Message PyObjectPtr pymessage = makePyObjectPtr(PyObject_Str(pvalue)); std::string message = PyString_AsString(pymessage.get()); // Traceback PyObjectPtr tracebackModule = makePyObjectPtr(PyImport_ImportModule("traceback")); std::string traceback; if (tracebackModule != NULL) { PyObjectPtr tbList = makePyObjectPtr( PyObject_CallMethod( tracebackModule.get(), (char*)"format_exception", (char*)"OOO", ptype, pvalue == NULL ? Py_None : pvalue, ptraceback == NULL ? Py_None : ptraceback)); PyObjectPtr emptyString = makePyObjectPtr(PyString_FromString("")); PyObjectPtr strRetval = makePyObjectPtr( PyObject_CallMethod(emptyString.get(), (char*)"join", (char*)"O", tbList.get())); traceback = PyString_AsString(strRetval.get()); } else { traceback = "Empty traceback"; } Py_XDECREF(ptype); Py_XDECREF(pvalue); Py_XDECREF(ptraceback); std::string error_message = "Python exception (" + type + "): " + message; if(traceback != (type + ": " + message + "\n")) error_message += "\n" + traceback; throw std::runtime_error(error_message); } }
static const bool check(PyObjectPtr obj) { return PyTuple_Check(obj.get()); }
const unsigned size() { return PyTuple_Size(obj.get()); }
const bool get() { return (bool)PyObject_IsTrue(obj.get()); }
const double get() { return PyFloat_AsDouble(obj.get()); }
const bool isDouble() { return PyArray_TYPE(obj.get()) == NPY_DOUBLE; }
bool append(PyObjectPtr item) { return PyList_Append(obj.get(), item.get()) == 0; }
static int slot_handler( Member* member, CAtom* atom, PyObject* value ) { if( member->index >= atom->get_slot_count() ) { py_no_attr_fail( pyobject_cast( atom ), (char *)Py23Str_AS_STRING( member->name ) ); return -1; } if( atom->is_frozen() ) { PyErr_SetString( PyExc_AttributeError, "can't set attribute of frozen Atom" ); return -1; } PyObjectPtr oldptr( atom->get_slot( member->index ) ); PyObjectPtr newptr( newref( value ) ); if( oldptr == newptr ) return 0; bool valid_old = oldptr.get() != 0; if( !valid_old ) oldptr.set( newref( Py_None ) ); newptr = member->full_validate( atom, oldptr.get(), newptr.get() ); if( !newptr ) return -1; atom->set_slot( member->index, newptr.get() ); if( member->get_post_setattr_mode() ) { if( member->post_setattr( atom, oldptr.get(), newptr.get() ) < 0 ) return -1; } if( ( !valid_old || oldptr != newptr ) && atom->get_notifications_enabled() ) { PyObjectPtr argsptr; if( member->has_observers() ) { if( valid_old && oldptr.richcompare( newptr, Py_EQ ) ) return 0; if( valid_old ) argsptr = updated_args( atom, member, oldptr.get(), newptr.get() ); else argsptr = created_args( atom, member, newptr.get() ); if( !argsptr ) return -1; if( !member->notify( atom, argsptr.get(), 0 ) ) return -1; } if( atom->has_observers( member->name ) ) { if( !argsptr ) { if( valid_old && oldptr.richcompare( newptr, Py_EQ ) ) return 0; if( valid_old ) argsptr = updated_args( atom, member, oldptr.get(), newptr.get() ); else argsptr = created_args( atom, member, newptr.get() ); if( !argsptr ) return -1; } if( !atom->notify( member->name, argsptr.get(), 0 ) ) return -1; } } return 0; }
const std::string get() { return PyString_AsString(obj.get()); }
const bool isDouble(unsigned i) { return PyFloat_Check(PyTuple_GetItem(obj.get(), i)); }