Delta3D 自定义扩展actors 是怎样最终创建的

dtCore::LibraryManager 类是个单利,在创建LibraryManager实例的时候,会自动加载系统内部的三个角色插件:dtActors、dtAudio、dtAnim。

如下:

   static const std::string ACTOR_LIBRARY("dtActors");
   static const std::string AUDIO_ACTOR_LIBRARY("dtAudio");
   static const std::string ANIM_ACTOR_LIBRARY("dtAnim");

 LibraryManager::LibraryManager()
   {
      mLogger = &dtUtil::Log::GetInstance("librarymanager.cpp");
      mLogger->LogMessage(dtUtil::Log::LOG_INFO, __FUNCTION__, __LINE__, "Initializing actor library manager.");
      LoadActorRegistry(ACTOR_LIBRARY);

      //try to load some optional actor libraries that depend on optional
      //external dependencies.  If the file isn't found, don't try to load it.
      LoadOptionalActorRegistry(AUDIO_ACTOR_LIBRARY);
      LoadOptionalActorRegistry(ANIM_ACTOR_LIBRARY);
   }

在   LibraryManager中含有     typedef std::map<dtCore::RefPtr<const ActorType>, ActorPluginRegistry*, ActorType::RefPtrComp> ActorTypeMap;的一个容器。记录着所有actors类型和其对应创建actor的ActorPluginRegistry


在void MapContentHandler::EndLibraryElement()函数中会调用

 if (LibraryManager::GetInstance().GetRegistry(mLibName) == NULL)
   {
       LibraryManager::GetInstance().LoadActorRegistry(mLibName);//mLibName 比如是TutorialLibrary
   }


在void LibraryManager::LoadActorRegistry(const std::string& libName) 函数中,借用LibrarySharingManager来加载你的含有actors的dll库

  dtUtil::LibrarySharingManager& lsm = dtUtil::LibrarySharingManager::GetInstance();
      RegistryEntry newEntry;
      try
      {
         newEntry.lib = lsm.LoadSharedLibrary(libName);
      }  

      dtUtil::LibrarySharingManager::LibraryHandle::SYMBOL_ADDRESS createFn;
      dtUtil::LibrarySharingManager::LibraryHandle::SYMBOL_ADDRESS destroyFn;
      createFn = newEntry.lib->FindSymbol("CreatePluginRegistry");//就是在你兵力插件中的入口函数。
      destroyFn = newEntry.lib->FindSymbol("DestroyPluginRegistry");

     

      //Well we made it here so that means the plugin was loaded
      //successfully and the create and destroy functions were found.
      newEntry.createFn = (CreatePluginRegistryFn)createFn;
      newEntry.destroyFn = (DestroyPluginRegistryFun)destroyFn;
      newEntry.registry = newEntry.createFn();

      if (!AddRegistryEntry(libName,newEntry))
      {
         msg.clear();
         msg.str("");
         msg << "Can't add Registry Entry: " << libName << " to Registry. " <<
            "Possibly it might have been added already.";
         throw dtCore::ProjectResourceErrorException( msg.str(), __FILE__, __LINE__);
      }


接着进入AddRegistryEntry函数

 bool LibraryManager::AddRegistryEntry(const std::string& libName, const RegistryEntry& entry)
   {
      //Finally we can actually add the new registry to the library manager.
      //The map key is the system independent library name.
      bool inserted = mRegistries.insert(std::make_pair(libName,entry)).second;
      if (!inserted)
      {
         return false;
      }

      //Used to format log messages.
      std::ostringstream msg;

      //Second we map actor type to the registry that owns it.
      std::vector<dtCore::RefPtr<const ActorType> > actorTypes;
      entry.registry->RegisterActorTypes();//注册你的actorproxy到dtUtil::ObjectFactory中的objectTypeMap里面
      entry.registry->GetSupportedActorTypes(actorTypes);从dtUtil::ObjectFactory中的objectTypeMap里面取出

      dtCore::ActorPluginRegistry::ActorTypeReplacements replacements;
      entry.registry->GetReplacementActorTypes(replacements);//主要提供一些向后兼容的能力
      mReplacementActors.insert(mReplacementActors.end(), replacements.begin(), replacements.end());

      int numUniqueActors = 0;
      for (unsigned int i = 0; i < actorTypes.size(); ++i)
      {
         ActorTypeMapItor itor = mActors.find(dtCore::RefPtr<const ActorType>(actorTypes[i].get()));
         if (itor != mActors.end())
         {
            msg.clear();
            msg.str("");
            msg << "Duplicate actor type " << *actorTypes[i] << " found. Will not be added.";
            LOG_ERROR(msg.str());
         }
         else
         {//把actortype 和 对应ActorPluginRegistry 绑定到一起
            mActors.insert(std::make_pair(dtCore::RefPtr<const ActorType>(actorTypes[i].get()),entry.registry));
            ++numUniqueActors;
         }
      }

      msg.clear();
      msg.str("");
      msg << "Loaded actor plugin registry. (Name: " << libName <<
         ", Number of Actors: " << numUniqueActors << ")";
      LOG_INFO(msg.str());

      return true;
   }


------------------------------------------------------上面创建actor的准备工作完毕--------------------------------------------------------------------------------------


当读取map文件时,在函数 void MapContentHandler::ActorCharacters(const XMLCh* const chars)中  

  else if (topEl == MapXMLConstants::ACTOR_TYPE_ELEMENT)

{

  mBaseActorObject = LibraryManager::GetInstance().CreateActor(*actorType).get();

}


 dtCore::RefPtr<BaseActorObject> LibraryManager::CreateActor(const ActorType& actorType)
   {
      ActorPluginRegistry* apr = GetRegistryForType(actorType);//在上面的mActors中找到对应的actorPluginRegistry

      if (mLogger->IsLevelEnabled(dtUtil::Log::LOG_DEBUG))
      {
         mLogger->LogMessage(dtUtil::Log::LOG_DEBUG, __FUNCTION__, __LINE__,
            "Creating actor proxy of type \"%s\".",
            actorType.GetFullName().c_str());
      }

      //Now we know which registry to use, so tell the registry to
      //create the proxy object and return it.
      dtCore::RefPtr<BaseActorObject> proxy = apr->CreateActor(actorType).get();//创建actor
      return proxy;
   }
然后转到 ActorPluginRegistry::CreateActor(const ActorType& type)中

 dtCore::RefPtr<BaseActorObject> ActorPluginRegistry::CreateActor(const ActorType& type)
   {
      dtCore::RefPtr<BaseActorObject> proxy = mActorFactory->CreateObject(dtCore::RefPtr<const ActorType>(&type));
      proxy->Init(type);
      proxy->InitDefaults();
      return proxy;
   }
 OK,到此为止,我们看到,当创建一个兵力的时候,在外部会调用其内部的Init,和InitDefaults()两个方法。

void GameActorProxy::Init(const dtCore::ActorType& actorType)
{
   BaseClass::Init(actorType);
   BuildInvokables();//创建可调用体
   BuildActorComponents();

   // The actor components are stored on the game actor, unlike the other stuff
   GameActor &ga = GetGameActor();
   ga.BuildActorComponents();
}
 

 而在 BaseClass::Init(actorType);函数中

   void BaseActorObject::Init(const dtCore::ActorType& actorType)
   {
      SetActorType(actorType);//设置角色类型
      CreateDrawable();//创建角色
      // These are called to make it validate that they aren't Null
      // before proceeding.
      GetActorType();
      GetDrawable();
      BuildPropertyMap();//创建属性(暴露外边的属性)
   }


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值