// Because we might reload/destroy the factory in python, we need to deinstall the factory from the dict PyEntityFactory::~PyEntityFactory() { // Only remove the installed factory if we are the installed factory // Another new factory might already be installed. When a python module gets reloaded // the new factory might be created first. Afterwards the old one is dereferenced and // destroyed. if( EntityFactoryDictionary()->FindFactory( m_ClassName ) == this ) EntityFactoryDictionary()->RemoveFactory( m_ClassName ); // Unlink if( this == g_pPyEntityFactoryHead ) { g_pPyEntityFactoryHead = g_pPyEntityFactoryHead->m_pPyNext; } else { PyEntityFactory *p = g_pPyEntityFactoryHead->m_pPyNext; PyEntityFactory *prev = g_pPyEntityFactoryHead; while( p ) { if( p == this ) { prev->m_pPyNext = p->m_pPyNext; break; } prev = p; p = p->m_pPyNext; } } }
PyEntityFactory::PyEntityFactory( const char *pClassName, boost::python::object PyClass ) { m_pPyNext = NULL; m_ClassName[0] = 0; if( !pClassName ) { PyErr_SetString(PyExc_ValueError, "EntityFactory must have a valid name"); throw boost::python::error_already_set(); return; } V_strncpy( m_ClassName, pClassName, sizeof( m_ClassName ) ); m_PyClass = PyClass; // Remove old factory if any if( EntityFactoryDictionary()->FindFactory( m_ClassName ) ) EntityFactoryDictionary()->RemoveFactory( m_ClassName ); // Install new factory EntityFactoryDictionary()->InstallFactory( this, m_ClassName ); // Link m_pPyNext = g_pPyEntityFactoryHead; g_pPyEntityFactoryHead = this; // Init if( g_bDoNotInitPythonClasses == false) InitPyClass(); CheckEntities(); }
void RegisterScriptedEntity( const char *className ) { #ifdef CLIENT_DLL if ( GetClassMap().FindFactory( className ) ) { return; } GetClassMap().Add( className, "CBaseScripted", sizeof( CBaseScripted ), &CCBaseScriptedFactory, true ); #else if ( EntityFactoryDictionary()->FindFactory( className ) ) { return; } unsigned short lookup = m_EntityFactoryDatabase.Find( className ); if ( lookup != m_EntityFactoryDatabase.InvalidIndex() ) { return; } CEntityFactory<CBaseScripted> *pFactory = new CEntityFactory<CBaseScripted>( className ); lookup = m_EntityFactoryDatabase.Insert( className, pFactory ); Assert( lookup != m_EntityFactoryDatabase.InvalidIndex() ); #endif }
void RegisterScriptedWeapon( const char *className ) { #ifdef CLIENT_DLL if ( GetClassMap().FindFactory( className ) ) { return; } GetClassMap().Add( className, "CHL2MPScriptedWeapon", sizeof( CHL2MPScriptedWeapon ), &CCHL2MPScriptedWeaponFactory, true ); #else if ( EntityFactoryDictionary()->FindFactory( className ) ) { return; } unsigned short lookup = m_WeaponFactoryDatabase.Find( className ); if ( lookup != m_WeaponFactoryDatabase.InvalidIndex() ) { return; } // Andrew; This fixes months worth of pain and anguish. CEntityFactory<CHL2MPScriptedWeapon> *pFactory = new CEntityFactory<CHL2MPScriptedWeapon>( className ); lookup = m_WeaponFactoryDatabase.Insert( className, pFactory ); Assert( lookup != m_WeaponFactoryDatabase.InvalidIndex() ); #endif // BUGBUG: When attempting to precache weapons registered during runtime, // they don't appear as valid registered entities. // static CPrecacheRegister precache_weapon_(&CPrecacheRegister::PrecacheFn_Other, className); }
CBaseNetworkable *CreateNetworkableByName( const char *className ) { IServerNetworkable *pNetwork = EntityFactoryDictionary()->Create( className ); if ( !pNetwork ) return NULL; CBaseNetworkable *pNetworkable = pNetwork->GetBaseNetworkable(); Assert( pNetworkable ); return pNetworkable; }
//----------------------------------------------------------------------------- // Expose CEntityFactoryDictionary. //----------------------------------------------------------------------------- void export_entity_factory_dictionary(scope _factories) { class_<CEntityFactoryDictionary, CEntityFactoryDictionary *, bases<IEntityFactoryDictionary>, boost::noncopyable> EntityFactoryDictionary("EntityFactoryDictionary", no_init); // Special methods... EntityFactoryDictionary.def("__getitem__",&EntityFactoryDictionarySharedExt::__getitem__); // Engine specific stuff... export_engine_specific_entity_factory_dictionary(_factories, EntityFactoryDictionary); // Add memory tools... EntityFactoryDictionary ADD_MEM_TOOLS(CEntityFactoryDictionary); }
bp::list PyGetAllClassnames() { bp::list l; PyEntityFactory *p = g_pPyEntityFactoryHead; while( p ) { // Filter non linked factories (undestroyed python instances) if( EntityFactoryDictionary()->FindFactory( p->GetClassname() ) == p ) { l.append( bp::object( p->GetClassname() ) ); } p = p->m_pPyNext; } return l; }
void RegisterScriptedTrigger( const char *className ) { if ( EntityFactoryDictionary()->FindFactory( className ) ) { return; } unsigned short lookup = m_TriggerFactoryDatabase.Find( className ); if ( lookup != m_TriggerFactoryDatabase.InvalidIndex() ) { return; } CEntityFactory<CBaseScriptedTrigger> *pFactory = new CEntityFactory<CBaseScriptedTrigger>( className ); lookup = m_TriggerFactoryDatabase.Insert( className, pFactory ); Assert( lookup != m_TriggerFactoryDatabase.InvalidIndex() ); }
// creates an entity by string name, but does not spawn it CBaseEntity *CreateEntityByName( const char *className, int iForceEdictIndex ) { if ( iForceEdictIndex != -1 ) { g_pForceAttachEdict = engine->CreateEdict( iForceEdictIndex ); if ( !g_pForceAttachEdict ) Error( "CreateEntityByName( %s, %d ) - CreateEdict failed.", className, iForceEdictIndex ); } IServerNetworkable *pNetwork = EntityFactoryDictionary()->Create( className ); g_pForceAttachEdict = NULL; if ( !pNetwork ) return NULL; CBaseEntity *pEntity = pNetwork->GetBaseEntity(); Assert( pEntity ); return pEntity; }