// 功能:根据脚本所传的参数,动态获取或创建一个关联的委托对象 public T GetDelegate <T>(long L, int nIndex = 0) where T : FCDelegateBase, new() { long pDelegatePtr = FCLibHelper.fc_get_param_ptr(L, nIndex); // 得到脚本委托参数(临时的,不可保留) long VM = FCLibHelper.fc_get_vm_ptr(L); long nObjPtr = FCLibHelper.fc_inport_delegate_get_obj_ptr(VM, pDelegatePtr); // 得到脚本对象地址 int nClassNameID = FCLibHelper.fc_inport_delegate_get_class_name_id(VM, pDelegatePtr); // 类名 int nFuncNameID = FCLibHelper.fc_inport_delegate_get_func_name_id(VM, pDelegatePtr); // 函数名 if (0 == nObjPtr && 0 == nClassNameID && 0 == nFuncNameID) { return(default(T)); // 返回空指针 } FCDelegateKey key = new FCDelegateKey(); key.nVMPtr = VM; key.nThisPtr = nObjPtr; key.nClassName = nClassNameID; key.nFuncName = nFuncNameID; // -- 这个地方有必要加锁,如果不加锁的话,多线程执行脚本,并在脚本中使用委托,就会导致这里线程冲突 if (VM != FCDll.GetMainVMPtr()) { Debug.LogError("请注意多线程冲突的问题, 不可以在多线程中使用委托"); } FCDelegateBase obj = null; if (m_Delegates.TryGetValue(key, out obj)) { if (key.nVMPtr != VM) { Debug.LogError("多线程冲突, 记录有误,请检查对应的委托用法"); } return((T)obj); } T pObj = new T(); pObj.m_VMPtr = VM; pObj.m_nThisPtr = nObjPtr; pObj.m_szFuncName = GetDelegateFuncName(VM, pDelegatePtr); pObj.m_nClassName = nClassNameID; pObj.m_nFuncName = nFuncNameID; m_Delegates[key] = pObj; return(pObj); }
void CreateScript() { if (0 != m_nScriptInsPtr) { return; } m_VMPtr = FCDll.GetMainVMPtr(); // 创建一个脚本 if (string.IsNullOrEmpty(ScripClassName)) { m_nScriptInsPtr = 0; } else { m_nScriptInsPtr = FCLibHelper.fc_instance(m_VMPtr, ScripClassName); } // 必要的话,调用下脚本中的Start函数 if (m_nScriptInsPtr != 0) { // 假设存在transform变量 SetScriptValue("transform", transform); } try { OnCreateScript(); } catch (Exception e) { Debug.LogException(e); } if (m_nScriptInsPtr != 0) { FCLibHelper.fc_call(m_VMPtr, m_nScriptInsPtr, "Start"); } }