LuaFramework 学习

摘要:
“);}}Common/LuaBehaviorusingUnityEngine;usingSystem.Collections;usingSystem.IO;usingLuaInterface;namespaceLuaFramework{/////从LuaFileUtils集成,重写其中的ReadFile,//publicclassLuaLoader:LuaFileUtils{privateResourceManagerm_resMgr;ResourceManagersMgr{获取{ifm_resMgr=AppFacade.Instance.GetManager<ResourceManager>;returnm_resManager;}//使用thisforinitializationpublicLuaLoader(){instance=this;beZip=AppConst.LuaBundleMode;}//////将输入的AssetBundle添加到Lua代码//////publicvoid AddBundle{stringurl=Util.DataPath+bundleName.ToLower();如果{varbytes=File.ReadAllBytes;//已对其进行注释。CreateFromMemoryImmediate已从5.3更改为LoadFromMember。如有必要,请自行取消注释~//AssetBundlebundle=AssetBuddle.CreateFromMemoryImmedia;AssetBund le=AssetBundle.LoadFrom;if(bundle!

LuaFramework_UGUI_V2  https://github.com/jarjin/LuaFramework_UGUI_V2

LuaFramework 学习第1张

usingUnityEngine;
usingLuaInterface;
usingSystem.Collections;
usingSystem.Collections.Generic;
usingSystem;
usingUnityEngine.UI;
namespaceLuaFramework {
    public classLuaBehaviour : View {
        private string data = null;
        private Dictionary<string, LuaFunction> buttons = new Dictionary<string, LuaFunction>();
        protected voidAwake() {
            Util.CallMethod(name, "Awake", gameObject);
        }
        protected voidStart() {
            Util.CallMethod(name, "Start");
        }
        protected voidOnClick() {
            Util.CallMethod(name, "OnClick");
        }
        protected voidOnClickEvent(GameObject go) {
            Util.CallMethod(name, "OnClick", go);
        }
        /// <summary>
        ///添加单击事件
        /// </summary>
        public voidAddClick(GameObject go, LuaFunction luafunc) {
            if (go == null || luafunc == null) return;
            buttons.Add(go.name, luafunc);
            go.GetComponent<Button>().onClick.AddListener(
                delegate() {
                    luafunc.Call(go);
                }
            );
        }
        /// <summary>
        ///删除单击事件
        /// </summary>
        /// <param name="go"></param>
        public voidRemoveClick(GameObject go) {
            if (go == null) return;
            LuaFunction luafunc = null;
            if (buttons.TryGetValue(go.name, outluafunc)) {
                luafunc.Dispose();
                luafunc = null;
                buttons.Remove(go.name);
            }
        }
        /// <summary>
        ///清除单击事件
        /// </summary>
        public voidClearClick() {
            foreach (var de inbuttons) {
                if (de.Value != null) {
                    de.Value.Dispose();
                }
            }
            buttons.Clear();
        }
        //-----------------------------------------------------------------
        protected voidOnDestroy() {
            ClearClick();
#if ASYNC_MODE
            string abName = name.ToLower().Replace("panel", "");
            ResManager.UnloadAssetBundle(abName +AppConst.ExtName);
#endif
            Util.ClearMemory();
            Debug.Log("~" + name + "was destroy!");
        }
    }
}
Common/LuaBehaviour
usingUnityEngine;
usingSystem.Collections;
usingSystem.IO;
usingLuaInterface;
namespaceLuaFramework {
    /// <summary>
    ///集成自LuaFileUtils,重写里面的ReadFile,
    /// </summary>
    public classLuaLoader : LuaFileUtils {
        privateResourceManager m_resMgr;
        ResourceManager resMgr {
            get{ 
                if (m_resMgr == null)
                    m_resMgr = AppFacade.Instance.GetManager<ResourceManager>(ManagerName.Resource);
                returnm_resMgr;
            }
        }
        //Use this for initialization
        publicLuaLoader() {
            instance = this;
            beZip =AppConst.LuaBundleMode;
        }
        /// <summary>
        ///添加打入Lua代码的AssetBundle
        /// </summary>
        /// <param name="bundle"></param>
        public void AddBundle(stringbundleName) {
            string url = Util.DataPath +bundleName.ToLower();
            if(File.Exists(url)) {
                var bytes =File.ReadAllBytes(url);
                //已注释, CreateFromMemoryImmediate从5.3开始改为LoadFromMemory,需要用的请自行取消注释~
                //AssetBundle bundle = AssetBundle.CreateFromMemoryImmediate(bytes);
                AssetBundle bundle =AssetBundle.LoadFromMemory(bytes);
                if (bundle != null)
                {
                    bundleName = bundleName.Replace("lua/", "").Replace(".unity3d", "");
                    base.AddSearchBundle(bundleName.ToLower(), bundle);
                }
            }
        }
        /// <summary>
        ///当LuaVM加载Lua文件的时候,这里就会被调用,
        ///用户可以自定义加载行为,只要返回byte[]即可。
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public override byte[] ReadFile(stringfileName) {
            return base.ReadFile(fileName);     
        }
    }
}
Common/LuaLoader
usingUnityEngine;
usingSystem;
usingSystem.Collections;
usingSystem.Collections.Generic;
namespaceLuaFramework {
    public classAppConst {
        public const bool DebugMode = false;                       //调试模式-用于内部测试
        /// <summary>
        ///如果想删掉框架自带的例子,那这个例子模式必须要
        ///关闭,否则会出现一些错误。
        /// </summary>
        public const bool ExampleMode = true;                       //例子模式 
        /// <summary>
        ///如果开启更新模式,前提必须启动框架自带服务器端。
        ///否则就需要自己将StreamingAssets里面的所有内容
        ///复制到自己的Webserver上面,并修改下面的WebUrl。
        /// </summary>
        public const bool UpdateMode = false;                       //更新模式-默认关闭 
        public const bool LuaByteMode = false;                       //Lua字节码模式-默认关闭 
        public const bool LuaBundleMode = true;                    //Lua代码AssetBundle模式
        public const int TimerInterval = 1;
        public const int GameFrameRate = 30;                        //游戏帧频
        public const string AppName = "LuaFramework";               //应用程序名称
        public const string LuaTempDir = "Lua/";                    //临时目录
        public const string AppPrefix = AppName + "_";              //应用程序前缀
        public const string ExtName = ".unity3d";                   //素材扩展名
        public const string AssetDir = "StreamingAssets";           //素材目录 
        public const string WebUrl = "http://localhost:6688/";      //测试更新地址
        public static string UserId = string.Empty;                 //用户ID
        public static int SocketPort = 0;                           //Socket服务器端口
        public static string SocketAddress = string.Empty;          //Socket服务器地址
        public static stringFrameworkRoot {
            get{
                return Application.dataPath + "/" +AppName;
            }
        }
    }
}
ConstDefine/AppConst
usingUnityEngine;
usingSystem.Collections;
namespaceLuaFramework {
    public classManagerName {
        public const string Lua = "LuaManager";
        public const string Game = "GameManager";
        public const string Timer = "TimeManager";
        public const string Sound = "SoundManager";
        public const string Panel = "PanelManager";
        public const string Network = "NetworkManager";
        public const string Resource = "ResourceManager";
        public const string Thread = "ThreadManager";
        public const string ObjectPool = "ObjectPoolManager";
    }
}
ConstDefine/ManagerName
usingUnityEngine;
usingSystem.Collections;
public classNotiConst
{
    /// <summary>
    ///Controller层消息通知
    /// </summary>
    public const string START_UP = "StartUp";                       //启动框架
    public const string DISPATCH_MESSAGE = "DispatchMessage";       //派发信息
    /// <summary>
    ///View层消息通知
    /// </summary>
    public const string UPDATE_MESSAGE = "UpdateMessage";           //更新消息
    public const string UPDATE_EXTRACT = "UpdateExtract";           //更新解包
    public const string UPDATE_DOWNLOAD = "UpdateDownload";         //更新下载
    public const string UPDATE_PROGRESS = "UpdateProgress";         //更新进度
}
ConstDefine/NotiConst
usingUnityEngine;
usingSystem.Collections;
usingSystem.Collections.Generic;
usingLuaFramework;
public classSocketCommand : ControllerCommand {
    public override voidExecute(IMessage message) {
        object data =message.Body;
        if (data == null) return;
        KeyValuePair<int, ByteBuffer> buffer = (KeyValuePair<int, ByteBuffer>)data;
        switch(buffer.Key) {
            default: Util.CallMethod("Network", "OnSocket", buffer.Key, buffer.Value); break;
        }
    }
}
Controller/Command/SocketCommand
usingUnityEngine;
usingSystem.Collections;
usingLuaFramework;
public classStartUpCommand : ControllerCommand {
    public override voidExecute(IMessage message) {
        if (!Util.CheckEnvironment()) return;
        GameObject gameMgr = GameObject.Find("GlobalGenerator");
        if (gameMgr != null) {
            AppView appView = gameMgr.AddComponent<AppView>();
        }
        //-----------------关联命令-----------------------
        AppFacade.Instance.RegisterCommand(NotiConst.DISPATCH_MESSAGE, typeof(SocketCommand));
        //-----------------初始化管理器-----------------------
        AppFacade.Instance.AddManager<LuaManager>(ManagerName.Lua);
        AppFacade.Instance.AddManager<PanelManager>(ManagerName.Panel);
        AppFacade.Instance.AddManager<SoundManager>(ManagerName.Sound);
        AppFacade.Instance.AddManager<TimerManager>(ManagerName.Timer);
        AppFacade.Instance.AddManager<NetworkManager>(ManagerName.Network);
        AppFacade.Instance.AddManager<ResourceManager>(ManagerName.Resource);
        AppFacade.Instance.AddManager<ThreadManager>(ManagerName.Thread);
        AppFacade.Instance.AddManager<ObjectPoolManager>(ManagerName.ObjectPool);
        AppFacade.Instance.AddManager<GameManager>(ManagerName.Game);
    }
}
Controller/Command/StartUpCommand
usingUnityEngine;
usingSystem.Collections;
usingLuaFramework;
usingSystem.Collections.Generic;
public classBase : MonoBehaviour {
    privateAppFacade m_Facade;
    privateLuaManager m_LuaMgr;
    privateResourceManager m_ResMgr;
    privateNetworkManager m_NetMgr;
    privateSoundManager m_SoundMgr;
    privateTimerManager m_TimerMgr;
    privateThreadManager m_ThreadMgr;
    privateObjectPoolManager m_ObjectPoolMgr;
    /// <summary>
    ///注册消息
    /// </summary>
    /// <param name="view"></param>
    /// <param name="messages"></param>
    protected void RegisterMessage(IView view, List<string>messages) {
        if (messages == null || messages.Count == 0) return;
        Controller.Instance.RegisterViewCommand(view, messages.ToArray());
    }
    /// <summary>
    ///移除消息
    /// </summary>
    /// <param name="view"></param>
    /// <param name="messages"></param>
    protected void RemoveMessage(IView view, List<string>messages) {
        if (messages == null || messages.Count == 0) return;
        Controller.Instance.RemoveViewCommand(view, messages.ToArray());
    }
    protectedAppFacade facade {
        get{
            if (m_Facade == null) {
                m_Facade =AppFacade.Instance;
            }
            returnm_Facade;
        }
    }
    protectedLuaManager LuaManager {
        get{
            if (m_LuaMgr == null) {
                m_LuaMgr = facade.GetManager<LuaManager>(ManagerName.Lua);
            }
            returnm_LuaMgr;
        }
    }
    protectedResourceManager ResManager {
        get{
            if (m_ResMgr == null) {
                m_ResMgr = facade.GetManager<ResourceManager>(ManagerName.Resource);
            }
            returnm_ResMgr;
        }
    }
    protectedNetworkManager NetManager {
        get{
            if (m_NetMgr == null) {
                m_NetMgr = facade.GetManager<NetworkManager>(ManagerName.Network);
            }
            returnm_NetMgr;
        }
    }
    protectedSoundManager SoundManager {
        get{
            if (m_SoundMgr == null) {
                m_SoundMgr = facade.GetManager<SoundManager>(ManagerName.Sound);
            }
            returnm_SoundMgr;
        }
    }
    protectedTimerManager TimerManager {
        get{
            if (m_TimerMgr == null) {
                m_TimerMgr = facade.GetManager<TimerManager>(ManagerName.Timer);
            }
            returnm_TimerMgr;
        }
    }
    protectedThreadManager ThreadManager {
        get{
            if (m_ThreadMgr == null) {
                m_ThreadMgr = facade.GetManager<ThreadManager>(ManagerName.Thread);
            }
            returnm_ThreadMgr;
        }
    }
    protectedObjectPoolManager ObjPoolManager {
        get{
            if (m_ObjectPoolMgr == null) {
                m_ObjectPoolMgr = facade.GetManager<ObjectPoolManager>(ManagerName.ObjectPool);
            }
            returnm_ObjectPoolMgr;
        }
    }
}
Framework/Core/Base
/*
    LuaFramework Code By Jarjin lee
*/
usingSystem;
usingSystem.Collections.Generic;
usingUnityEngine;
/// <summary>
///事件命令
/// </summary>
public classControllerCommand : ICommand {
    public virtual voidExecute(IMessage message) {
    }
}
public classFacade {
    protectedIController m_controller;
    staticGameObject m_GameManager;
    static Dictionary<string, object> m_Managers = new Dictionary<string, object>();
    GameObject AppGameManager {
        get{
            if (m_GameManager == null) {
                m_GameManager = GameObject.Find("GameManager");
            }
            returnm_GameManager;
        }
    }
    protectedFacade() {
        InitFramework();
    }
    protected virtual voidInitFramework() {
        if (m_controller != null) return;
        m_controller =Controller.Instance;
    }
    public virtual void RegisterCommand(stringcommandName, Type commandType) {
        m_controller.RegisterCommand(commandName, commandType);
    }
    public virtual void RemoveCommand(stringcommandName) {
        m_controller.RemoveCommand(commandName);
    }
    public virtual bool HasCommand(stringcommandName) {
        returnm_controller.HasCommand(commandName);
    }
    public void RegisterMultiCommand(Type commandType, params string[] commandNames) {
        int count =commandNames.Length;
        for (int i = 0; i < count; i++) {
            RegisterCommand(commandNames[i], commandType);
        }
    }
    public void RemoveMultiCommand(params string[] commandName) {
        int count =commandName.Length;
        for (int i = 0; i < count; i++) {
            RemoveCommand(commandName[i]);
        }
    }
    public void SendMessageCommand(string message, object body = null) {
        m_controller.ExecuteCommand(newMessage(message, body));
    }
    /// <summary>
    ///添加管理器
    /// </summary>
    public void AddManager(string typeName, objectobj) {
        if (!m_Managers.ContainsKey(typeName)) {
            m_Managers.Add(typeName, obj);
        }
    }
    /// <summary>
    ///添加Unity对象
    /// </summary>
    public T AddManager<T>(string typeName) whereT : Component {
        object result = null;
        m_Managers.TryGetValue(typeName, outresult);
        if (result != null) {
            return(T)result;
        }
        Component c = AppGameManager.AddComponent<T>();
        m_Managers.Add(typeName, c);
        return default(T);
    }
    /// <summary>
    ///获取系统管理器
    /// </summary>
    public T GetManager<T>(string typeName) where T : class{
        if (!m_Managers.ContainsKey(typeName)) {
            return default(T);
        }
        object manager = null;
        m_Managers.TryGetValue(typeName, outmanager);
        return(T)manager;
    }
    /// <summary>
    ///删除管理器
    /// </summary>
    public void RemoveManager(stringtypeName) {
        if (!m_Managers.ContainsKey(typeName)) {
            return;
        }
        object manager = null;
        m_Managers.TryGetValue(typeName, outmanager);
        Type type =manager.GetType();
        if (type.IsSubclassOf(typeof(MonoBehaviour))) {
            GameObject.Destroy((Component)manager);
        }
        m_Managers.Remove(typeName);
    }
}
Framework/Core/ControllerCommand, Facade
usingUnityEngine;
usingSystem.Collections;
usingLuaFramework;
public classManager : Base, IManager {
    //Use this for initialization
    voidStart () {
    }
    //Update is called once per frame
    voidUpdate () {
    }
}
Framework/Core/Manager
/*
 LuaFramework Code By Jarjin lee
*/
usingSystem;
public classMessage : IMessage
{
    public Message(stringname)
        : this(name, null, null)
    { }
    public Message(string name, objectbody)
        : this(name, body, null)
    { }
    public Message(string name, object body, stringtype)
    {
        m_name =name;
        m_body =body;
        m_type =type;
    }
    /// <summary>
    ///Get the string representation of the <c>Notification instance</c>
    /// </summary>
    /// <returns>The string representation of the <c>Notification</c>instance</returns>
    public override stringToString()
    {
        string msg = "Notification Name: " +Name;
        msg += "Body:" + ((Body == null) ? "null": Body.ToString());
        msg += "Type:" + ((Type == null) ? "null": Type);
        returnmsg;
    }
    /// <summary>
    ///The name of the <c>Notification</c>instance
    /// </summary>
    public virtual stringName
    {
        get { returnm_name; }
    }
    /// <summary>
    ///The body of the <c>Notification</c>instance
    /// </summary>
    /// <remarks>This accessor is thread safe</remarks>
    public virtual objectBody
    {
        get
        {
            //Setting and getting of reference types is atomic, no need to lock here
            returnm_body;
        }
        set
        {
            //Setting and getting of reference types is atomic, no need to lock here
            m_body =value;
        }
    }
    /// <summary>
    ///The type of the <c>Notification</c>instance
    /// </summary>
    /// <remarks>This accessor is thread safe</remarks>
    public virtual stringType
    {
        get
        {
            //Setting and getting of reference types is atomic, no need to lock here
            returnm_type;
        }
        set
        {
            //Setting and getting of reference types is atomic, no need to lock here
            m_type =value;
        }
    }
    /// <summary>
    ///The name of the notification instance 
    /// </summary>
    private stringm_name;
    /// <summary>
    ///The type of the notification instance
    /// </summary>
    private stringm_type;
    /// <summary>
    ///The body of the notification instance
    /// </summary>
    private objectm_body;
}
Framework/Core/Message
usingUnityEngine;
usingSystem;
usingSystem.Collections;
usingSystem.Collections.Generic;
usingLuaInterface;
usingLuaFramework;
public classView : Base, IView {
    public virtual voidOnMessage(IMessage message) {
    }
}
Framework/Core/View
/*
 LuaFramework Code By Jarjin lee
*/
usingSystem;
public interfaceICommand {
    voidExecute(IMessage message);
}
Framework/Interface/ICommand
/*
 LuaFramework Code By Jarjin leeibution 3.0 License 
*/
usingSystem;
usingSystem.Collections.Generic;
public interfaceIController
{
    void RegisterCommand(stringmessageName, Type commandType);
    void RegisterViewCommand(IView view, string[] commandNames);
    voidExecuteCommand(IMessage message);
    void RemoveCommand(stringmessageName);
    void RemoveViewCommand(IView view, string[] commandNames);
    bool HasCommand(stringmessageName);
}
Framework/Interface/IController
/*
 LuaFramework Code By Jarjin leeibution 3.0 License 
*/
usingUnityEngine;
usingSystem.Collections;
public interfaceIManager {
}
Framework/Interface/IManager
/*
 LuaFramework Code By Jarjin lee 
*/
usingSystem;
public interfaceIMessage
{
    string Name { get; }
    object Body { get; set; }
    string Type { get; set; }
    stringToString();
}
Framework/Interface/IMessage
usingSystem;
public interfaceIView {
    voidOnMessage(IMessage message);
}
Framework/Interface/IView
usingUnityEngine;
usingSystem;
usingSystem.Collections;
usingSystem.Collections.Generic;
public classAppFacade : Facade
{
    private staticAppFacade _instance;
    public AppFacade() : base()
    {
    }
    public staticAppFacade Instance
    {
        get{
            if (_instance == null) {
                _instance = newAppFacade();
            }
            return_instance;
        }
    }
    override protected voidInitFramework()
    {
        base.InitFramework();
        RegisterCommand(NotiConst.START_UP, typeof(StartUpCommand));
    }
    /// <summary>
    ///启动框架
    /// </summary>
    public voidStartUp() {
        SendMessageCommand(NotiConst.START_UP);
        RemoveMultiCommand(NotiConst.START_UP);
    }
}
Framework/AppFacade
usingSystem;
usingSystem.Collections;
namespaceLuaFramework {
    public interfaceITimerBehaviour {
        voidTimerUpdate();
    }
}
Manager/Interface
usingUnityEngine;
usingSystem;
usingSystem.Collections;
usingSystem.Collections.Generic;
usingLuaInterface;
usingSystem.Reflection;
usingSystem.IO;
namespaceLuaFramework {
    public classGameManager : Manager {
        protected static bool initialize = false;
        private List<string> downloadFiles = new List<string>();
        /// <summary>
        ///初始化游戏管理器
        /// </summary>
        voidAwake() {
            Init();
        }
        /// <summary>
        ///初始化
        /// </summary>
        voidInit() {
            DontDestroyOnLoad(gameObject);  //防止销毁自己

            CheckExtractResource(); //释放资源
            Screen.sleepTimeout =SleepTimeout.NeverSleep;
            Application.targetFrameRate =AppConst.GameFrameRate;
        }
        /// <summary>
        ///释放资源
        /// </summary>
        public voidCheckExtractResource() {
            bool isExists = Directory.Exists(Util.DataPath) &&
              Directory.Exists(Util.DataPath + "lua/") && File.Exists(Util.DataPath + "files.txt");
            if (isExists ||AppConst.DebugMode) {
                StartCoroutine(OnUpdateResource());
                return;   //文件已经解压过了,自己可添加检查文件列表逻辑
}
            StartCoroutine(OnExtractResource());    //启动释放协成 
}
        IEnumerator OnExtractResource() {
            string dataPath = Util.DataPath;  //数据目录
            string resPath = Util.AppContentPath(); //游戏包资源目录
            if (Directory.Exists(dataPath)) Directory.Delete(dataPath, true);
            Directory.CreateDirectory(dataPath);
            string infile = resPath + "files.txt";
            string outfile = dataPath + "files.txt";
            if(File.Exists(outfile)) File.Delete(outfile);
            string message = "正在解包文件:>files.txt";
            Debug.Log(infile);
            Debug.Log(outfile);
            if (Application.platform ==RuntimePlatform.Android) {
                WWW www = newWWW(infile);
                yield returnwww;
                if(www.isDone) {
                    File.WriteAllBytes(outfile, www.bytes);
                }
                yield return 0;
            } else File.Copy(infile, outfile, true);
            yield return newWaitForEndOfFrame();
            //释放所有文件到数据目录
            string[] files =File.ReadAllLines(outfile);
            foreach (var file infiles) {
                string[] fs = file.Split('|');
                infile = resPath + fs[0];  //
                outfile = dataPath + fs[0];
                message = "正在解包文件:>" + fs[0];
                Debug.Log("正在解包文件:>" +infile);
                facade.SendMessageCommand(NotiConst.UPDATE_MESSAGE, message);
                string dir =Path.GetDirectoryName(outfile);
                if (!Directory.Exists(dir)) Directory.CreateDirectory(dir);
                if (Application.platform ==RuntimePlatform.Android) {
                    WWW www = newWWW(infile);
                    yield returnwww;
                    if(www.isDone) {
                        File.WriteAllBytes(outfile, www.bytes);
                    }
                    yield return 0;
                } else{
                    if(File.Exists(outfile)) {
                        File.Delete(outfile);
                    }
                    File.Copy(infile, outfile, true);
                }
                yield return newWaitForEndOfFrame();
            }
            message = "解包完成!!!";
            facade.SendMessageCommand(NotiConst.UPDATE_MESSAGE, message);
            yield return new WaitForSeconds(0.1f);
            message = string.Empty;
            //释放完成,开始启动更新资源
StartCoroutine(OnUpdateResource());
        }
        /// <summary>
        ///启动更新下载,这里只是个思路演示,此处可启动线程下载更新
        /// </summary>
IEnumerator OnUpdateResource() {
            if (!AppConst.UpdateMode) {
                OnResourceInited();
                yield break;
            }
            string dataPath = Util.DataPath;  //数据目录
            string url =AppConst.WebUrl;
            string message = string.Empty;
            string random = DateTime.Now.ToString("yyyymmddhhmmss");
            string listUrl = url + "files.txt?v=" +random;
            Debug.LogWarning("LoadUpdate---->>>" +listUrl);
            WWW www = new WWW(listUrl); yield returnwww;
            if (www.error != null) {
                OnUpdateFailed(string.Empty);
                yield break;
            }
            if (!Directory.Exists(dataPath)) {
                Directory.CreateDirectory(dataPath);
            }
            File.WriteAllBytes(dataPath + "files.txt", www.bytes);
            string filesText =www.text;
            string[] files = filesText.Split('');
            for (int i = 0; i < files.Length; i++) {
                if (string.IsNullOrEmpty(files[i])) continue;
                string[] keyValue = files[i].Split('|');
                string f = keyValue[0];
                string localfile = (dataPath +f).Trim();
                string path =Path.GetDirectoryName(localfile);
                if (!Directory.Exists(path)) {
                    Directory.CreateDirectory(path);
                }
                string fileUrl = url + f + "?v=" +random;
                bool canUpdate = !File.Exists(localfile);
                if (!canUpdate) {
                    string remoteMd5 = keyValue[1].Trim();
                    string localMd5 =Util.md5file(localfile);
                    canUpdate = !remoteMd5.Equals(localMd5);
                    if(canUpdate) File.Delete(localfile);
                }
                if (canUpdate) {   //本地缺少文件
Debug.Log(fileUrl);
                    message = "downloading>>" +fileUrl;
                    facade.SendMessageCommand(NotiConst.UPDATE_MESSAGE, message);
                    /*
                    www = new WWW(fileUrl); yield return www;
                    if (www.error != null) {
                        OnUpdateFailed(path);   //
                        yield break;
                    }
                    File.WriteAllBytes(localfile, www.bytes);
                     */
                    //这里都是资源文件,用线程下载
BeginDownload(fileUrl, localfile);
                    while (!(IsDownOK(localfile))) { yield return newWaitForEndOfFrame(); }
                }
            }
            yield return newWaitForEndOfFrame();
            message = "更新完成!!";
            facade.SendMessageCommand(NotiConst.UPDATE_MESSAGE, message);
            OnResourceInited();
        }
        void OnUpdateFailed(stringfile) {
            string message = "更新失败!>" +file;
            facade.SendMessageCommand(NotiConst.UPDATE_MESSAGE, message);
        }
        /// <summary>
        ///是否下载完成
        /// </summary>
        bool IsDownOK(stringfile) {
            returndownloadFiles.Contains(file);
        }
        /// <summary>
        ///线程下载
        /// </summary>
        void BeginDownload(string url, string file) {     //线程下载
            object[] param = new object[2] { url, file };
            ThreadEvent ev = newThreadEvent();
            ev.Key =NotiConst.UPDATE_DOWNLOAD;
            ev.evParams.AddRange(param);
            ThreadManager.AddEvent(ev, OnThreadCompleted);   //线程下载
}
        /// <summary>
        ///线程完成
        /// </summary>
        /// <param name="data"></param>
        voidOnThreadCompleted(NotiData data) {
            switch(data.evName) {
                case NotiConst.UPDATE_EXTRACT:  //解压一个完成
                //
                break;
                case NotiConst.UPDATE_DOWNLOAD: //下载一个完成
downloadFiles.Add(data.evParam.ToString());
                break;
            }
        }
        /// <summary>
        ///资源初始化结束
        /// </summary>
        public voidOnResourceInited() {
#if ASYNC_MODE
            ResManager.Initialize(AppConst.AssetDir, delegate() {
                Debug.Log("Initialize OK!!!");
                this.OnInitialize();
            });
#else
            ResManager.Initialize();
            this.OnInitialize();
#endif
        }
        voidOnInitialize() {
            LuaManager.InitStart();
            LuaManager.DoFile("Logic/Game");         //加载游戏
            LuaManager.DoFile("Logic/Network");      //加载网络
            NetManager.OnInit();                     //初始化网络
            Util.CallMethod("Game", "OnInitOK");     //初始化完成

            initialize = true;
            //类对象池测试
            var classObjPool = ObjPoolManager.CreatePool<TestObjectClass>(OnPoolGetElement, OnPoolPushElement);
            //方法1
            //objPool.Release(new TestObjectClass("abcd", 100, 200f));
            //var testObj1 = objPool.Get();
            //方法2
            ObjPoolManager.Release<TestObjectClass>(new TestObjectClass("abcd", 100, 200f));
            var testObj1 = ObjPoolManager.Get<TestObjectClass>();
            Debugger.Log("TestObjectClass--->>>" +testObj1.ToString());
            //游戏对象池测试
            var prefab = Resources.Load("TestGameObjectPrefab", typeof(GameObject)) asGameObject;
            var gameObjPool = ObjPoolManager.CreatePool("TestGameObject", 5, 10, prefab);
            var gameObj = Instantiate(prefab) asGameObject;
            gameObj.name = "TestGameObject_01";
            gameObj.transform.localScale =Vector3.one;
            gameObj.transform.localPosition =Vector3.zero;
            ObjPoolManager.Release("TestGameObject", gameObj);
            var backObj = ObjPoolManager.Get("TestGameObject");
            backObj.transform.SetParent(null);
            Debug.Log("TestGameObject--->>>" +backObj);
        }
        /// <summary>
        ///当从池子里面获取时
        /// </summary>
        /// <param name="obj"></param>
        voidOnPoolGetElement(TestObjectClass obj) {
            Debug.Log("OnPoolGetElement--->>>" +obj);
        }
        /// <summary>
        ///当放回池子里面时
        /// </summary>
        /// <param name="obj"></param>
        voidOnPoolPushElement(TestObjectClass obj) {
            Debug.Log("OnPoolPushElement--->>>" +obj);
        }
        /// <summary>
        ///析构函数
        /// </summary>
        voidOnDestroy() {
            if (NetManager != null) {
                NetManager.Unload();
            }
            if (LuaManager != null) {
                LuaManager.Close();
            }
            Debug.Log("~GameManager was destroyed");
        }
    }
}
Manager/GameManager
usingUnityEngine;
usingSystem.Collections;
usingLuaInterface;
namespaceLuaFramework {
    public classLuaManager : Manager {
        privateLuaState lua;
        privateLuaLoader loader;
        private LuaLooper loop = null;
        //Use this for initialization
        voidAwake() {
            loader = newLuaLoader();
            lua = newLuaState();
            this.OpenLibs();
            lua.LuaSetTop(0);
            LuaBinder.Bind(lua);
            DelegateFactory.Init();
            LuaCoroutine.Register(lua, this);
        }
        public voidInitStart() {
            InitLuaPath();
            InitLuaBundle();
            this.lua.Start();    //启动LUAVM
            this.StartMain();
            this.StartLooper();
        }
        voidStartLooper() {
            loop = gameObject.AddComponent<LuaLooper>();
            loop.luaState =lua;
        }
        //cjson 比较特殊,只new了一个table,没有注册库,这里注册一下
        protected voidOpenCJson() {
            lua.LuaGetField(LuaIndexes.LUA_REGISTRYINDEX, "_LOADED");
            lua.OpenLibs(LuaDLL.luaopen_cjson);
            lua.LuaSetField(-2, "cjson");
            lua.OpenLibs(LuaDLL.luaopen_cjson_safe);
            lua.LuaSetField(-2, "cjson.safe");
        }
        voidStartMain() {
            lua.DoFile("Main.lua");
            LuaFunction main = lua.GetFunction("Main");
            main.Call();
            main.Dispose();
            main = null;    
        }
        /// <summary>
        ///初始化加载第三方库
        /// </summary>
        voidOpenLibs() {
            lua.OpenLibs(LuaDLL.luaopen_pb);      
            lua.OpenLibs(LuaDLL.luaopen_sproto_core);
            lua.OpenLibs(LuaDLL.luaopen_protobuf_c);
            lua.OpenLibs(LuaDLL.luaopen_lpeg);
            lua.OpenLibs(LuaDLL.luaopen_bit);
            lua.OpenLibs(LuaDLL.luaopen_socket_core);
            this.OpenCJson();
        }
        /// <summary>
        ///初始化Lua代码加载路径
        /// </summary>
        voidInitLuaPath() {
            if(AppConst.DebugMode) {
                string rootPath =AppConst.FrameworkRoot;
                lua.AddSearchPath(rootPath + "/Lua");
                lua.AddSearchPath(rootPath + "/ToLua/Lua");
            } else{
                lua.AddSearchPath(Util.DataPath + "lua");
            }
        }
        /// <summary>
        ///初始化LuaBundle
        /// </summary>
        voidInitLuaBundle() {
            if(loader.beZip) {
                loader.AddBundle("lua/lua.unity3d");
                loader.AddBundle("lua/lua_math.unity3d");
                loader.AddBundle("lua/lua_system.unity3d");
                loader.AddBundle("lua/lua_system_reflection.unity3d");
                loader.AddBundle("lua/lua_unityengine.unity3d");
                loader.AddBundle("lua/lua_common.unity3d");
                loader.AddBundle("lua/lua_logic.unity3d");
                loader.AddBundle("lua/lua_view.unity3d");
                loader.AddBundle("lua/lua_controller.unity3d");
                loader.AddBundle("lua/lua_misc.unity3d");
                loader.AddBundle("lua/lua_protobuf.unity3d");
                loader.AddBundle("lua/lua_3rd_cjson.unity3d");
                loader.AddBundle("lua/lua_3rd_luabitop.unity3d");
                loader.AddBundle("lua/lua_3rd_pbc.unity3d");
                loader.AddBundle("lua/lua_3rd_pblua.unity3d");
                loader.AddBundle("lua/lua_3rd_sproto.unity3d");
            }
        }
        public void DoFile(stringfilename) {
            lua.DoFile(filename);
        }
        //Update is called once per frame
        public object[] CallFunction(string funcName, params object[] args) {
            LuaFunction func =lua.GetFunction(funcName);
            if (func != null) {
                returnfunc.LazyCall(args);
            }
            return null;
        }
        public voidLuaGC() {
            lua.LuaGC(LuaGCOptions.LUA_GCCOLLECT);
        }
        public voidClose() {
            loop.Destroy();
            loop = null;
            lua.Dispose();
            lua = null;
            loader = null;
        }
    }
}
Manager/LuaManager
usingUnityEngine;
usingSystem;
usingSystem.Collections;
usingSystem.Collections.Generic;
usingLuaInterface;
namespaceLuaFramework {
    public classNetworkManager : Manager {
        privateSocketClient socket;
        static readonly object m_lockObject = new object();
        static Queue<KeyValuePair<int, ByteBuffer>> mEvents = new Queue<KeyValuePair<int, ByteBuffer>>();
        SocketClient SocketClient {
            get{ 
                if (socket == null)
                    socket = newSocketClient();
                returnsocket;                    
            }
        }
        voidAwake() {
            Init();
        }
        voidInit() {
            SocketClient.OnRegister();
        }
        public voidOnInit() {
            CallMethod("Start");
        }
        public voidUnload() {
            CallMethod("Unload");
        }
        /// <summary>
        ///执行Lua方法
        /// </summary>
        public object[] CallMethod(string func, params object[] args) {
            return Util.CallMethod("Network", func, args);
        }
        ///------------------------------------------------------------------------------------
        public static void AddEvent(int_event, ByteBuffer data) {
            lock(m_lockObject) {
                mEvents.Enqueue(new KeyValuePair<int, ByteBuffer>(_event, data));
            }
        }
        /// <summary>
        ///交给Command,这里不想关心发给谁。
        /// </summary>
        voidUpdate() {
            if (mEvents.Count > 0) {
                while (mEvents.Count > 0) {
                    KeyValuePair<int, ByteBuffer> _event =mEvents.Dequeue();
                    facade.SendMessageCommand(NotiConst.DISPATCH_MESSAGE, _event);
                }
            }
        }
        /// <summary>
        ///发送链接请求
        /// </summary>
        public voidSendConnect() {
            SocketClient.SendConnect();
        }
        /// <summary>
        ///发送SOCKET消息
        /// </summary>
        public voidSendMessage(ByteBuffer buffer) {
            SocketClient.SendMessage(buffer);
        }
        /// <summary>
        ///析构函数
        /// </summary>
        new voidOnDestroy() {
            SocketClient.OnRemove();
            Debug.Log("~NetworkManager was destroy");
        }
    }
}
Manager/NetworkManager
usingUnityEngine;
usingSystem.Collections;
usingSystem.Collections.Generic;
usingUnityEngine.Events;
namespaceLuaFramework {
    /// <summary>
    ///对象池管理器,分普通类对象池+资源游戏对象池
    /// </summary>
    public classObjectPoolManager : Manager {
        private Transform m_PoolRootObject = null;
        private Dictionary<string, object> m_ObjectPools = new Dictionary<string, object>();
        private Dictionary<string, GameObjectPool> m_GameObjectPools = new Dictionary<string, GameObjectPool>();
        Transform PoolRootObject {
            get{
                if (m_PoolRootObject == null) {
                    var objectPool = new GameObject("ObjectPool");
                    objectPool.transform.SetParent(transform);
                    objectPool.transform.localScale =Vector3.one;
                    objectPool.transform.localPosition =Vector3.zero;
                    m_PoolRootObject =objectPool.transform;
                }
                returnm_PoolRootObject;
            }
        }
        public GameObjectPool CreatePool(string poolName, int initSize, intmaxSize, GameObject prefab) {
            var pool = newGameObjectPool(poolName, prefab, initSize, maxSize, PoolRootObject);
            m_GameObjectPools[poolName] =pool;
            returnpool;
        }
        public GameObjectPool GetPool(stringpoolName) {
            if(m_GameObjectPools.ContainsKey(poolName)) {
                returnm_GameObjectPools[poolName];
            }
            return null;
        }
        public GameObject Get(stringpoolName) {
            GameObject result = null;
            if(m_GameObjectPools.ContainsKey(poolName)) {
                GameObjectPool pool =m_GameObjectPools[poolName];
                result =pool.NextAvailableObject();
                if (result == null) {
                    Debug.LogWarning("No object available in pool. Consider setting fixedSize to false.: " +poolName);
                }
            } else{
                Debug.LogError("Invalid pool name specified: " +poolName);
            }
            returnresult;
        }
        public void Release(stringpoolName, GameObject go) {
            if(m_GameObjectPools.ContainsKey(poolName)) {
                GameObjectPool pool =m_GameObjectPools[poolName];
                pool.ReturnObjectToPool(poolName, go);
            } else{
                Debug.LogWarning("No pool available with name: " +poolName);
            }
        }
        ///-----------------------------------------------------------------------------------------------
        public ObjectPool<T> CreatePool<T>(UnityAction<T> actionOnGet, UnityAction<T> actionOnRelease) where T : class{
            var type = typeof(T);
            var pool = new ObjectPool<T>(actionOnGet, actionOnRelease);
            m_ObjectPools[type.Name] =pool;
            returnpool;
        }
        public ObjectPool<T> GetPool<T>() where T : class{
            var type = typeof(T);
            ObjectPool<T> pool = null;
            if(m_ObjectPools.ContainsKey(type.Name)) {
                pool = m_ObjectPools[type.Name] as ObjectPool<T>;
            }
            returnpool;
        }
        public T Get<T>() where T : class{
            var pool = GetPool<T>();
            if (pool != null) {
                returnpool.Get();
            }
            return default(T);
        }
        public void Release<T>(T obj) where T : class{
            var pool = GetPool<T>();
            if (pool != null) {
                pool.Release(obj);
            }
        }
    }
}
Manager/ObjectPoolManager
usingUnityEngine;
usingSystem.Collections;
usingSystem.Collections.Generic;
usingUnityEngine.UI;
usingLuaInterface;
namespaceLuaFramework {
    public classPanelManager : Manager {
        privateTransform parent;
        Transform Parent {
            get{
                if (parent == null) {
                    GameObject go = GameObject.FindWithTag("GuiCamera");
                    if (go != null) parent =go.transform;
                }
                returnparent;
            }
        }
        /// <summary>
        ///������壬������Դ������
        /// </summary>
        /// <param name="type"></param>
        public void CreatePanel(string name, LuaFunction func = null) {
            string assetName = name + "Panel";
            string abName = name.ToLower() +AppConst.ExtName;
            if (Parent.Find(name) != null) return;
#if ASYNC_MODE
            ResManager.LoadPrefab(abName, assetName, delegate(UnityEngine.Object[] objs) {
                if (objs.Length == 0) return;
                GameObject prefab = objs[0] asGameObject;
                if (prefab == null) return;
                GameObject go = Instantiate(prefab) asGameObject;
                go.name =assetName;
                go.layer = LayerMask.NameToLayer("Default");
                go.transform.SetParent(Parent);
                go.transform.localScale =Vector3.one;
                go.transform.localPosition =Vector3.zero;
                go.AddComponent<LuaBehaviour>();
                if (func != null) func.Call(go);
                Debug.LogWarning("CreatePanel::>> " + name + " " +prefab);
            });
#else
            GameObject prefab = ResManager.LoadAsset<GameObject>(name, assetName);
            if (prefab == null) return;
            GameObject go = Instantiate(prefab) asGameObject;
            go.name =assetName;
            go.layer = LayerMask.NameToLayer("Default");
            go.transform.SetParent(Parent);
            go.transform.localScale =Vector3.one;
            go.transform.localPosition =Vector3.zero;
            go.AddComponent<LuaBehaviour>();
            if (func != null) func.Call(go);
            Debug.LogWarning("CreatePanel::>> " + name + " " +prefab);
#endif
        }
        /// <summary>
        ///�ر����
        /// </summary>
        /// <param name="name"></param>
        public void ClosePanel(stringname) {
            var panelName = name + "Panel";
            var panelObj =Parent.Find(panelName);
            if (panelObj == null) return;
            Destroy(panelObj.gameObject);
        }
    }
}
Manager/PanelManager
#if ASYNC_MODE
usingUnityEngine;
usingSystem.Collections;
usingSystem.Collections.Generic;
usingSystem;
usingSystem.IO;
usingLuaInterface;
using UObject =UnityEngine.Object;
public classAssetBundleInfo {
    publicAssetBundle m_AssetBundle;
    public intm_ReferencedCount;
    publicAssetBundleInfo(AssetBundle assetBundle) {
        m_AssetBundle =assetBundle;
        m_ReferencedCount = 0;
    }
}
namespaceLuaFramework {
    public classResourceManager : Manager {
        string m_BaseDownloadingURL = "";
        string[] m_AllManifest = null;
        AssetBundleManifest m_AssetBundleManifest = null;
        Dictionary<string, string[]> m_Dependencies = new Dictionary<string, string[]>();
        Dictionary<string, AssetBundleInfo> m_LoadedAssetBundles = new Dictionary<string, AssetBundleInfo>();
        Dictionary<string, List<LoadAssetRequest>> m_LoadRequests = new Dictionary<string, List<LoadAssetRequest>>();
        classLoadAssetRequest {
            publicType assetType;
            public string[] assetNames;
            publicLuaFunction luaFunc;
            public Action<UObject[]>sharpFunc;
        }
        //Load AssetBundleManifest.
        public void Initialize(stringmanifestName, Action initOK) {
            m_BaseDownloadingURL =Util.GetRelativePath();
            LoadAsset<AssetBundleManifest>(manifestName, new string[] { "AssetBundleManifest" }, delegate(UObject[] objs) {
                if (objs.Length > 0) {
                    m_AssetBundleManifest = objs[0] asAssetBundleManifest;
                    m_AllManifest =m_AssetBundleManifest.GetAllAssetBundles();
                }
                if (initOK != null) initOK();
            });
        }
        public void LoadPrefab(string abName, string assetName, Action<UObject[]>func) {
            LoadAsset<GameObject>(abName, new string[] { assetName }, func);
        }
        public void LoadPrefab(string abName, string[] assetNames, Action<UObject[]>func) {
            LoadAsset<GameObject>(abName, assetNames, func);
        }
        public void LoadPrefab(string abName, string[] assetNames, LuaFunction func) {
            LoadAsset<GameObject>(abName, assetNames, null, func);
        }
        string GetRealAssetPath(stringabName) {
            if(abName.Equals(AppConst.AssetDir)) {
                returnabName;
            }
            abName =abName.ToLower();
            if (!abName.EndsWith(AppConst.ExtName)) {
                abName +=AppConst.ExtName;
            }
            if (abName.Contains("/")) {
                returnabName;
            }
            //string[] paths = m_AssetBundleManifest.GetAllAssetBundles();  产生GC,需要缓存结果
            for (int i = 0; i < m_AllManifest.Length; i++) {
                int index = m_AllManifest[i].LastIndexOf('/');  
                string path = m_AllManifest[i].Remove(0, index + 1);    //字符串操作函数都会产生GC
                if(path.Equals(abName)) {
                    returnm_AllManifest[i];
                }
            }
            Debug.LogError("GetRealAssetPath Error:>>" +abName);
            return null;
        }
        /// <summary>
        ///载入素材
        /// </summary>
        void LoadAsset<T>(string abName, string[] assetNames, Action<UObject[]> action = null, LuaFunction func = null) whereT : UObject {
            abName =GetRealAssetPath(abName);
            LoadAssetRequest request = newLoadAssetRequest();
            request.assetType = typeof(T);
            request.assetNames =assetNames;
            request.luaFunc =func;
            request.sharpFunc =action;
            List<LoadAssetRequest> requests = null;
            if (!m_LoadRequests.TryGetValue(abName, outrequests)) {
                requests = new List<LoadAssetRequest>();
                requests.Add(request);
                m_LoadRequests.Add(abName, requests);
                StartCoroutine(OnLoadAsset<T>(abName));
            } else{
                requests.Add(request);
            }
        }
        IEnumerator OnLoadAsset<T>(string abName) whereT : UObject {
            Debug.Log(abName);
            AssetBundleInfo bundleInfo =GetLoadedAssetBundle(abName);
            if (bundleInfo == null) {
                yield return StartCoroutine(OnLoadAssetBundle(abName, typeof(T)));
                bundleInfo =GetLoadedAssetBundle(abName);
                if (bundleInfo == null) {
                    m_LoadRequests.Remove(abName);
                    Debug.LogError("OnLoadAsset--->>>" +abName);
                    yield break;
                }
            }
            List<LoadAssetRequest> list = null;
            if (!m_LoadRequests.TryGetValue(abName, outlist)) {
                m_LoadRequests.Remove(abName);
                yield break;
            }
            for (int i = 0; i < list.Count; i++) {
                string[] assetNames =list[i].assetNames;
                List<UObject> result = new List<UObject>();
                AssetBundle ab =bundleInfo.m_AssetBundle;
                for (int j = 0; j < assetNames.Length; j++) {
                    string assetPath =assetNames[j];
                    AssetBundleRequest request =ab.LoadAssetAsync(assetPath, list[i].assetType);
                    yield returnrequest;
                    result.Add(request.asset);
                    //T assetObj = ab.LoadAsset<T>(assetPath);
                    //result.Add(assetObj);
}
                if (list[i].sharpFunc != null) {
                    list[i].sharpFunc(result.ToArray());
                    list[i].sharpFunc = null;
                }
                if (list[i].luaFunc != null) {
                    list[i].luaFunc.Call((object)result.ToArray());
                    list[i].luaFunc.Dispose();
                    list[i].luaFunc = null;
                }
                bundleInfo.m_ReferencedCount++;
            }
            m_LoadRequests.Remove(abName);
        }
        IEnumerator OnLoadAssetBundle(stringabName, Type type) {
            string url = m_BaseDownloadingURL +abName;
            WWW download = null;
            if (type == typeof(AssetBundleManifest))
                download = newWWW(url);
            else{
                string[] dependencies =m_AssetBundleManifest.GetAllDependencies(abName);
                if (dependencies.Length > 0) {
                    m_Dependencies.Add(abName, dependencies);
                    for (int i = 0; i < dependencies.Length; i++) {
                        string depName =dependencies[i];
                        AssetBundleInfo bundleInfo = null;
                        if (m_LoadedAssetBundles.TryGetValue(depName, outbundleInfo)) {
                            bundleInfo.m_ReferencedCount++;
                        } else if (!m_LoadRequests.ContainsKey(depName)) {
                            yield returnStartCoroutine(OnLoadAssetBundle(depName, type));
                        }
                    }
                }
                download = WWW.LoadFromCacheOrDownload(url, m_AssetBundleManifest.GetAssetBundleHash(abName), 0);
            }
            yield returndownload;
            AssetBundle assetObj =download.assetBundle;
            if (assetObj != null) {
                m_LoadedAssetBundles.Add(abName, newAssetBundleInfo(assetObj));
            }
        }
        AssetBundleInfo GetLoadedAssetBundle(stringabName) {
            AssetBundleInfo bundle = null;
            m_LoadedAssetBundles.TryGetValue(abName, outbundle);
            if (bundle == null) return null;
            //No dependencies are recorded, only the bundle itself is required.
            string[] dependencies = null;
            if (!m_Dependencies.TryGetValue(abName, outdependencies))
                returnbundle;
            //Make sure all dependencies are loaded
            foreach (var dependency independencies) {
                AssetBundleInfo dependentBundle;
                m_LoadedAssetBundles.TryGetValue(dependency, outdependentBundle);
                if (dependentBundle == null) return null;
            }
            returnbundle;
        }
        /// <summary>
        ///此函数交给外部卸载专用,自己调整是否需要彻底清除AB
        /// </summary>
        /// <param name="abName"></param>
        /// <param name="isThorough"></param>
        public void UnloadAssetBundle(string abName, bool isThorough = false) {
            abName =GetRealAssetPath(abName);
            Debug.Log(m_LoadedAssetBundles.Count + "assetbundle(s) in memory before unloading " +abName);
            UnloadAssetBundleInternal(abName, isThorough);
            UnloadDependencies(abName, isThorough);
            Debug.Log(m_LoadedAssetBundles.Count + "assetbundle(s) in memory after unloading " +abName);
        }
        void UnloadDependencies(string abName, boolisThorough) {
            string[] dependencies = null;
            if (!m_Dependencies.TryGetValue(abName, outdependencies))
                return;
            //Loop dependencies.
            foreach (var dependency independencies) {
                UnloadAssetBundleInternal(dependency, isThorough);
            }
            m_Dependencies.Remove(abName);
        }
        void UnloadAssetBundleInternal(string abName, boolisThorough) {
            AssetBundleInfo bundle =GetLoadedAssetBundle(abName);
            if (bundle == null) return;
            if (--bundle.m_ReferencedCount <= 0) {
                if(m_LoadRequests.ContainsKey(abName)) {
                    return;     //如果当前AB处于Async Loading过程中,卸载会崩溃,只减去引用计数即可
}
                bundle.m_AssetBundle.Unload(isThorough);
                m_LoadedAssetBundles.Remove(abName);
                Debug.Log(abName + "has been unloaded successfully");
            }
        }
    }
}
#else
usingUnityEngine;
usingSystem.Collections;
usingSystem.Collections.Generic;
usingSystem.IO;
usingLuaFramework;
usingLuaInterface;
using UObject =UnityEngine.Object;
namespaceLuaFramework {
    public classResourceManager : Manager {
        private string[] m_Variants ={ };
        privateAssetBundleManifest manifest;
        privateAssetBundle shared, assetbundle;
        private Dictionary<string, AssetBundle>bundles;
        voidAwake() {
        }
        /// <summary>
        ///初始化
        /// </summary>
        public voidInitialize() {
            byte[] stream = null;
            string uri = string.Empty;
            bundles = new Dictionary<string, AssetBundle>();
            uri = Util.DataPath +AppConst.AssetDir;
            if (!File.Exists(uri)) return;
            stream =File.ReadAllBytes(uri);
            assetbundle =AssetBundle.CreateFromMemoryImmediate(stream);
            manifest = assetbundle.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
        }
        /// <summary>
        ///载入素材
        /// </summary>
        public T LoadAsset<T>(string abname, string assetname) whereT : UnityEngine.Object {
            abname =abname.ToLower();
            AssetBundle bundle =LoadAssetBundle(abname);
            return bundle.LoadAsset<T>(assetname);
        }
        public void LoadPrefab(string abName, string[] assetNames, LuaFunction func) {
            abName =abName.ToLower();
            List<UObject> result = new List<UObject>();
            for (int i = 0; i < assetNames.Length; i++) {
                UObject go = LoadAsset<UObject>(abName, assetNames[i]);
                if (go != null) result.Add(go);
            }
            if (func != null) func.Call((object)result.ToArray());
        }
        /// <summary>
        ///载入AssetBundle
        /// </summary>
        /// <param name="abname"></param>
        /// <returns></returns>
        public AssetBundle LoadAssetBundle(stringabname) {
            if (!abname.EndsWith(AppConst.ExtName)) {
                abname +=AppConst.ExtName;
            }
            AssetBundle bundle = null;
            if (!bundles.ContainsKey(abname)) {
                byte[] stream = null;
                string uri = Util.DataPath +abname;
                Debug.LogWarning("LoadFile::>> " +uri);
                LoadDependencies(abname);
                stream =File.ReadAllBytes(uri);
                bundle = AssetBundle.CreateFromMemoryImmediate(stream); //关联数据的素材绑定
bundles.Add(abname, bundle);
            } else{
                bundles.TryGetValue(abname, outbundle);
            }
            returnbundle;
        }
        /// <summary>
        ///载入依赖
        /// </summary>
        /// <param name="name"></param>
        void LoadDependencies(stringname) {
            if (manifest == null) {
                Debug.LogError("Please initialize AssetBundleManifest by calling AssetBundleManager.Initialize()");
                return;
            }
            //Get dependecies from the AssetBundleManifest object..
            string[] dependencies =manifest.GetAllDependencies(name);
            if (dependencies.Length == 0) return;
            for (int i = 0; i < dependencies.Length; i++)
                dependencies[i] =RemapVariantName(dependencies[i]);
            //Record and load all dependencies.
            for (int i = 0; i < dependencies.Length; i++) {
                LoadAssetBundle(dependencies[i]);
            }
        }
        //Remaps the asset bundle name to the best fitting asset bundle variant.
        string RemapVariantName(stringassetBundleName) {
            string[] bundlesWithVariant =manifest.GetAllAssetBundlesWithVariant();
            //If the asset bundle doesn't have variant, simply return.
            if (System.Array.IndexOf(bundlesWithVariant, assetBundleName) < 0)
                returnassetBundleName;
            string[] split = assetBundleName.Split('.');
            int bestFit = int.MaxValue;
            int bestFitIndex = -1;
            //Loop all the assetBundles with variant to find the best fit variant assetBundle.
            for (int i = 0; i < bundlesWithVariant.Length; i++) {
                string[] curSplit = bundlesWithVariant[i].Split('.');
                if (curSplit[0] != split[0])
                    continue;
                int found = System.Array.IndexOf(m_Variants, curSplit[1]);
                if (found != -1 && found <bestFit) {
                    bestFit =found;
                    bestFitIndex =i;
                }
            }
            if (bestFitIndex != -1)
                returnbundlesWithVariant[bestFitIndex];
            else
                returnassetBundleName;
        }
        /// <summary>
        ///销毁资源
        /// </summary>
        voidOnDestroy() {
            if (shared != null) shared.Unload(true);
            if (manifest != null) manifest = null;
            Debug.Log("~ResourceManager was destroy!");
        }
    }
}
#endif
Manager/ResourceManager, AssetBundleInfo
usingUnityEngine;
usingSystem.Collections;
usingSystem.Collections.Generic;
namespaceLuaFramework {
    public classSoundManager : Manager {
        privateAudioSource audio;
        private Hashtable sounds = newHashtable();
        voidStart() {
            audio = GetComponent<AudioSource>();
        }
        /// <summary>
        ///添加一个声音
        /// </summary>
        void Add(stringkey, AudioClip value) {
            if (sounds[key] != null || value == null) return;
            sounds.Add(key, value);
        }
        /// <summary>
        ///获取一个声音
        /// </summary>
        AudioClip Get(stringkey) {
            if (sounds[key] == null) return null;
            return sounds[key] asAudioClip;
        }
        /// <summary>
        ///载入一个音频
        /// </summary>
        public AudioClip LoadAudioClip(stringpath) {
            AudioClip ac =Get(path);
            if (ac == null) {
                ac = (AudioClip)Resources.Load(path, typeof(AudioClip));
                Add(path, ac);
            }
            returnac;
        }
        /// <summary>
        ///是否播放背景音乐,默认是1:播放
        /// </summary>
        /// <returns></returns>
        public boolCanPlayBackSound() {
            string key = AppConst.AppPrefix + "BackSound";
            int i = PlayerPrefs.GetInt(key, 1);
            return i == 1;
        }
        /// <summary>
        ///播放背景音乐
        /// </summary>
        /// <param name="canPlay"></param>
        public void PlayBacksound(string name, boolcanPlay) {
            if (audio.clip != null) {
                if (name.IndexOf(audio.clip.name) > -1) {
                    if (!canPlay) {
                        audio.Stop();
                        audio.clip = null;
                        Util.ClearMemory();
                    }
                    return;
                }
            }
            if(canPlay) {
                audio.loop = true;
                audio.clip =LoadAudioClip(name);
                audio.Play();
            } else{
                audio.Stop();
                audio.clip = null;
                Util.ClearMemory();
            }
        }
        /// <summary>
        ///是否播放音效,默认是1:播放
        /// </summary>
        /// <returns></returns>
        public boolCanPlaySoundEffect() {
            string key = AppConst.AppPrefix + "SoundEffect";
            int i = PlayerPrefs.GetInt(key, 1);
            return i == 1;
        }
        /// <summary>
        ///播放音频剪辑
        /// </summary>
        /// <param name="clip"></param>
        /// <param name="position"></param>
        public voidPlay(AudioClip clip, Vector3 position) {
            if (!CanPlaySoundEffect()) return;
            AudioSource.PlayClipAtPoint(clip, position); 
        }
    }
}
Manager/SoundManager
usingSystem.Collections;
usingSystem.Threading;
usingSystem.Collections.Generic;
usingSystem.IO;
usingSystem.Diagnostics;
usingSystem.Net;
usingSystem;
public classThreadEvent {
    public stringKey;
    public List<object> evParams = new List<object>();
}
public classNotiData {
    public stringevName;
    public objectevParam;
    public NotiData(string name, objectparam) {
        this.evName =name;
        this.evParam =param;
    }
}
namespaceLuaFramework {
    /// <summary>
    ///当前线程管理器,同时只能做一个任务
    /// </summary>
    public classThreadManager : Manager {
        privateThread thread;
        private Action<NotiData>func;
        private Stopwatch sw = newStopwatch();
        private string currDownFile = string.Empty;
        static readonly object m_lockObject = new object();
        static Queue<ThreadEvent> events = new Queue<ThreadEvent>();
        delegate voidThreadSyncEvent(NotiData data);
        privateThreadSyncEvent m_SyncEvent;
        voidAwake() {
            m_SyncEvent =OnSyncEvent;
            thread = newThread(OnUpdate);
        }
        //Use this for initialization
        voidStart() {
            thread.Start();
        }
        /// <summary>
        ///添加到事件队列
        /// </summary>
        public void AddEvent(ThreadEvent ev, Action<NotiData>func) {
            lock(m_lockObject) {
                this.func =func;
                events.Enqueue(ev);
            }
        }
        /// <summary>
        ///通知事件
        /// </summary>
        /// <param name="state"></param>
        private voidOnSyncEvent(NotiData data) {
            if (this.func != null) func(data);  //回调逻辑层
            facade.SendMessageCommand(data.evName, data.evParam); //通知View层
}
        //Update is called once per frame
        voidOnUpdate() {
            while (true) {
                lock(m_lockObject) {
                    if (events.Count > 0) {
                        ThreadEvent e =events.Dequeue();
                        try{
                            switch(e.Key) {
                                case NotiConst.UPDATE_EXTRACT: {     //解压文件
OnExtractFile(e.evParams);
                                }
                                break;
                                case NotiConst.UPDATE_DOWNLOAD: {    //下载文件
OnDownloadFile(e.evParams);
                                }
                                break;
                            }
                        } catch(System.Exception ex) {
                            UnityEngine.Debug.LogError(ex.Message);
                        }
                    }
                }
                Thread.Sleep(1);
            }
        }
        /// <summary>
        ///下载文件
        /// </summary>
        void OnDownloadFile(List<object>evParams) {
            string url = evParams[0].ToString();    
            currDownFile = evParams[1].ToString();
            using (WebClient client = newWebClient()) {
                sw.Start();
                client.DownloadProgressChanged += newDownloadProgressChangedEventHandler(ProgressChanged);
                client.DownloadFileAsync(newSystem.Uri(url), currDownFile);
            }
        }
        private void ProgressChanged(objectsender, DownloadProgressChangedEventArgs e) {
            //UnityEngine.Debug.Log(e.ProgressPercentage);
            /*
            UnityEngine.Debug.Log(string.Format("{0} MB's / {1} MB's",
                (e.BytesReceived / 1024d / 1024d).ToString("0.00"),
                (e.TotalBytesToReceive / 1024d / 1024d).ToString("0.00")));
            */
            //float value = (float)e.ProgressPercentage / 100f;
            string value = string.Format("{0} kb/s", (e.BytesReceived / 1024d / sw.Elapsed.TotalSeconds).ToString("0.00"));
            NotiData data = newNotiData(NotiConst.UPDATE_PROGRESS, value);
            if (m_SyncEvent != null) m_SyncEvent(data);
            if (e.ProgressPercentage == 100 && e.BytesReceived ==e.TotalBytesToReceive) {
                sw.Reset();
                data = newNotiData(NotiConst.UPDATE_DOWNLOAD, currDownFile);
                if (m_SyncEvent != null) m_SyncEvent(data);
            }
        }
        /// <summary>
        ///调用方法
        /// </summary>
        void OnExtractFile(List<object>evParams) {
            UnityEngine.Debug.LogWarning("Thread evParams: >>" +evParams.Count);
            ///------------------通知更新面板解压完成--------------------
            NotiData data = new NotiData(NotiConst.UPDATE_DOWNLOAD, null);
            if (m_SyncEvent != null) m_SyncEvent(data);
        }
        /// <summary>
        ///应用程序退出
        /// </summary>
        voidOnDestroy() {
            thread.Abort();
        }
    }
}
Manager/ThreadManager, ThreadEvent, NotiData
usingUnityEngine;
usingSystem.Collections;
usingSystem.Collections.Generic;
namespaceLuaFramework {
    public classTimerInfo {
        public longtick;
        public boolstop;
        public booldelete;
        publicObject target;
        public stringclassName;
        public TimerInfo(stringclassName, Object target) {
            this.className =className;
            this.target =target;
            delete = false;
        }
    }
    public classTimerManager : Manager {
        private float interval = 0;
        private List<TimerInfo> objects = new List<TimerInfo>();
        public floatInterval {
            get { returninterval; }
            set { interval =value; }
        }
        //Use this for initialization
        voidStart() {
            StartTimer(AppConst.TimerInterval);
        }
        /// <summary>
        ///启动计时器
        /// </summary>
        /// <param name="interval"></param>
        public void StartTimer(floatvalue) {
            interval =value;
            InvokeRepeating("Run", 0, interval);
        }
        /// <summary>
        ///停止计时器
        /// </summary>
        public voidStopTimer() {
            CancelInvoke("Run");
        }
        /// <summary>
        ///添加计时器事件
        /// </summary>
        /// <param name="name"></param>
        /// <param name="o"></param>
        public voidAddTimerEvent(TimerInfo info) {
            if (!objects.Contains(info)) {
                objects.Add(info);
            }
        }
        /// <summary>
        ///删除计时器事件
        /// </summary>
        /// <param name="name"></param>
        public voidRemoveTimerEvent(TimerInfo info) {
            if (objects.Contains(info) && info != null) {
                info.delete = true;
            }
        }
        /// <summary>
        ///停止计时器事件
        /// </summary>
        /// <param name="info"></param>
        public voidStopTimerEvent(TimerInfo info) {
            if (objects.Contains(info) && info != null) {
                info.stop = true;
            }
        }
        /// <summary>
        ///继续计时器事件
        /// </summary>
        /// <param name="info"></param>
        public voidResumeTimerEvent(TimerInfo info) {
            if (objects.Contains(info) && info != null) {
                info.delete = false;
            }
        }
        /// <summary>
        ///计时器运行
        /// </summary>
        voidRun() {
            if (objects.Count == 0) return;
            for (int i = 0; i < objects.Count; i++) {
                TimerInfo o =objects[i];
                if (o.delete || o.stop) { continue; }
                ITimerBehaviour timer = o.target asITimerBehaviour;
                timer.TimerUpdate();
                o.tick++;
            }
            /////////////////////////清除标记为删除的事件///////////////////////////
            for (int i = objects.Count - 1; i >= 0; i--) {
                if(objects[i].delete) { objects.Remove(objects[i]); }
            }
        }
    }
}
Manager/TimerManager, TimerInfo
usingUnityEngine;
usingSystem.Collections;
usingSystem.IO;
usingSystem.Text;
usingSystem;
usingLuaInterface;
namespaceLuaFramework {
    public classByteBuffer {
        MemoryStream stream = null;
        BinaryWriter writer = null;
        BinaryReader reader = null;
        publicByteBuffer() {
            stream = newMemoryStream();
            writer = newBinaryWriter(stream);
        }
        public ByteBuffer(byte[] data) {
            if (data != null) {
                stream = newMemoryStream(data);
                reader = newBinaryReader(stream);
            } else{
                stream = newMemoryStream();
                writer = newBinaryWriter(stream);
            }
        }
        public voidClose() {
            if (writer != null) writer.Close();
            if (reader != null) reader.Close();
            stream.Close();
            writer = null;
            reader = null;
            stream = null;
        }
        public void WriteByte(bytev) {
            writer.Write(v);
        }
        public void WriteInt(intv) {
            writer.Write((int)v);
        }
        public void WriteShort(ushortv) {
            writer.Write((ushort)v);
        }
        public void WriteLong(longv) {
            writer.Write((long)v);
        }
        public void WriteFloat(floatv) {
            byte[] temp =BitConverter.GetBytes(v);
            Array.Reverse(temp);
            writer.Write(BitConverter.ToSingle(temp, 0));
        }
        public void WriteDouble(doublev) {
            byte[] temp =BitConverter.GetBytes(v);
            Array.Reverse(temp);
            writer.Write(BitConverter.ToDouble(temp, 0));
        }
        public void WriteString(stringv) {
            byte[] bytes =Encoding.UTF8.GetBytes(v);
            writer.Write((ushort)bytes.Length);
            writer.Write(bytes);
        }
        public void WriteBytes(byte[] v) {
            writer.Write((int)v.Length);
            writer.Write(v);
        }
        public voidWriteBuffer(LuaByteBuffer strBuffer) {
            WriteBytes(strBuffer.buffer);
        }
        public byteReadByte() {
            returnreader.ReadByte();
        }
        public intReadInt() {
            return (int)reader.ReadInt32();
        }
        public ushortReadShort() {
            return (ushort)reader.ReadInt16();
        }
        public longReadLong() {
            return (long)reader.ReadInt64();
        }
        public floatReadFloat() {
            byte[] temp =BitConverter.GetBytes(reader.ReadSingle());
            Array.Reverse(temp);
            return BitConverter.ToSingle(temp, 0);
        }
        public doubleReadDouble() {
            byte[] temp =BitConverter.GetBytes(reader.ReadDouble());
            Array.Reverse(temp);
            return BitConverter.ToDouble(temp, 0);
        }
        public stringReadString() {
            ushort len =ReadShort();
            byte[] buffer = new byte[len];
            buffer =reader.ReadBytes(len);
            returnEncoding.UTF8.GetString(buffer);
        }
        public byte[] ReadBytes() {
            int len =ReadInt();
            returnreader.ReadBytes(len);
        }
        publicLuaByteBuffer ReadBuffer() {
            byte[] bytes =ReadBytes();
            return newLuaByteBuffer(bytes);
        }
        public byte[] ToBytes() {
            writer.Flush();
            returnstream.ToArray();
        }
        public voidFlush() {
            writer.Flush();
        }
    }
}
Network/ByteBuffer
/*
*  Copyright (c) 2008 Jonathan Wagner
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
usingSystem;
namespaceLuaFramework {
    public classConverter {
        public staticInt32 GetBigEndian(Int32 value) {
            if(BitConverter.IsLittleEndian) {
                returnswapByteOrder(value);
            } else{
                returnvalue;
            }
        }
        public staticUInt16 GetBigEndian(UInt16 value) {
            if(BitConverter.IsLittleEndian) {
                returnswapByteOrder(value);
            } else{
                returnvalue;
            }
        }
        public staticUInt32 GetBigEndian(UInt32 value) {
            if(BitConverter.IsLittleEndian) {
                returnswapByteOrder(value);
            } else{
                returnvalue;
            }
        }
        public staticInt64 GetBigEndian(Int64 value) {
            if(BitConverter.IsLittleEndian) {
                returnswapByteOrder(value);
            } else{
                returnvalue;
            }
        }
        public staticDouble GetBigEndian(Double value) {
            if(BitConverter.IsLittleEndian) {
                returnswapByteOrder(value);
            } else{
                returnvalue;
            }
        }
        public static float GetBigEndian(floatvalue) {
            if(BitConverter.IsLittleEndian) {
                return swapByteOrder((int)value);
            } else{
                returnvalue;
            }
        }
        public staticInt32 GetLittleEndian(Int32 value) {
            if(BitConverter.IsLittleEndian) {
                returnvalue;
            } else{
                returnswapByteOrder(value);
            }
        }
        public staticUInt32 GetLittleEndian(UInt32 value) {
            if(BitConverter.IsLittleEndian) {
                returnvalue;
            } else{
                returnswapByteOrder(value);
            }
        }
        public staticUInt16 GetLittleEndian(UInt16 value) {
            if(BitConverter.IsLittleEndian) {
                returnvalue;
            } else{
                returnswapByteOrder(value);
            }
        }
        public staticDouble GetLittleEndian(Double value) {
            if(BitConverter.IsLittleEndian) {
                returnvalue;
            } else{
                returnswapByteOrder(value);
            }
        }
        private staticInt32 swapByteOrder(Int32 value) {
            Int32 swap = (Int32)((0x000000FF) & (value >> 24)
                | (0x0000FF00) & (value >> 8)
                | (0x00FF0000) & (value << 8)
                | (0xFF000000) & (value << 24));
            returnswap;
        }
        private staticInt64 swapByteOrder(Int64 value) {
            UInt64 uvalue =(UInt64)value;
            UInt64 swap = ((0x00000000000000FF) & (uvalue >> 56)
            | (0x000000000000FF00) & (uvalue >> 40)
            | (0x0000000000FF0000) & (uvalue >> 24)
            | (0x00000000FF000000) & (uvalue >> 8)
            | (0x000000FF00000000) & (uvalue << 8)
            | (0x0000FF0000000000) & (uvalue << 24)
            | (0x00FF000000000000) & (uvalue << 40)
            | (0xFF00000000000000) & (uvalue << 56));
            return(Int64)swap;
        }
        private staticUInt16 swapByteOrder(UInt16 value) {
            return (UInt16)((0x00FF & (value >> 8))
                | (0xFF00 & (value << 8)));
        }
        private staticUInt32 swapByteOrder(UInt32 value) {
            UInt32 swap = ((0x000000FF) & (value >> 24)
                | (0x0000FF00) & (value >> 8)
                | (0x00FF0000) & (value << 8)
                | (0xFF000000) & (value << 24));
            returnswap;
        }
        private staticDouble swapByteOrder(Double value) {
            Byte[] buffer =BitConverter.GetBytes(value);
            Array.Reverse(buffer, 0, buffer.Length);
            return BitConverter.ToDouble(buffer, 0);
        }
    }
}
Network/Converter
namespaceLuaFramework {
    public classProtocal {
        ///BUILD TABLE
        public const int Connect = 101;     //连接服务器
        public const int Exception = 102;     //异常掉线
        public const int Disconnect = 103;     //正常断线   
}
}
Network/Protocal
usingUnityEngine;
usingSystem;
usingSystem.IO;
usingSystem.Net;
usingSystem.Net.Sockets;
usingSystem.Collections;
usingSystem.Collections.Generic;
usingLuaFramework;
public enumDisType {
    Exception,
    Disconnect,
}
public classSocketClient {
    private TcpClient client = null;
    private NetworkStream outStream = null;
    privateMemoryStream memStream;
    privateBinaryReader reader;
    private const int MAX_READ = 8192;
    private byte[] byteBuffer = new byte[MAX_READ];
    public static bool loggedIn = false;
    //Use this for initialization
    publicSocketClient() {
    }
    /// <summary>
    ///注册代理
    /// </summary>
    public voidOnRegister() {
        memStream = newMemoryStream();
        reader = newBinaryReader(memStream);
    }
    /// <summary>
    ///移除代理
    /// </summary>
    public voidOnRemove() {
        this.Close();
        reader.Close();
        memStream.Close();
    }
    /// <summary>
    ///连接服务器
    /// </summary>
    void ConnectServer(string host, intport) {
        client = null;
        try{
            IPAddress[] address =Dns.GetHostAddresses(host);
            if (address.Length == 0) {
                Debug.LogError("host invalid");
                return;
            }
            if (address[0].AddressFamily ==AddressFamily.InterNetworkV6) {
                client = newTcpClient(AddressFamily.InterNetworkV6);
            }
            else{
                client = newTcpClient(AddressFamily.InterNetwork);
            }
            client.SendTimeout = 1000;
            client.ReceiveTimeout = 1000;
            client.NoDelay = true;
            client.BeginConnect(host, port, new AsyncCallback(OnConnect), null);
        } catch(Exception e) {
            Close(); Debug.LogError(e.Message);
        }
    }
    /// <summary>
    ///连接上服务器
    /// </summary>
    voidOnConnect(IAsyncResult asr) {
        outStream =client.GetStream();
        client.GetStream().BeginRead(byteBuffer, 0, MAX_READ, new AsyncCallback(OnRead), null);
        NetworkManager.AddEvent(Protocal.Connect, newByteBuffer());
    }
    /// <summary>
    ///写数据
    /// </summary>
    void WriteMessage(byte[] message) {
        MemoryStream ms = null;
        using (ms = newMemoryStream()) {
            ms.Position = 0;
            BinaryWriter writer = newBinaryWriter(ms);
            ushort msglen = (ushort)message.Length;
            writer.Write(msglen);
            writer.Write(message);
            writer.Flush();
            if (client != null &&client.Connected) {
                //NetworkStream stream = client.GetStream();
                byte[] payload =ms.ToArray();
                outStream.BeginWrite(payload, 0, payload.Length, new AsyncCallback(OnWrite), null);
            } else{
                Debug.LogError("client.connected----->>false");
            }
        }
    }
    /// <summary>
    ///读取消息
    /// </summary>
    voidOnRead(IAsyncResult asr) {
        int bytesRead = 0;
        try{
            lock (client.GetStream()) {         //读取字节流到缓冲区
                bytesRead =client.GetStream().EndRead(asr);
            }
            if (bytesRead < 1) {                //包尺寸有问题,断线处理
                OnDisconnected(DisType.Disconnect, "bytesRead < 1");
                return;
            }
            OnReceive(byteBuffer, bytesRead);   //分析数据包内容,抛给逻辑层
            lock (client.GetStream()) {         //分析完,再次监听服务器发过来的新消息
                Array.Clear(byteBuffer, 0, byteBuffer.Length);   //清空数组
                client.GetStream().BeginRead(byteBuffer, 0, MAX_READ, new AsyncCallback(OnRead), null);
            }
        } catch(Exception ex) {
            //PrintBytes();
OnDisconnected(DisType.Exception, ex.Message);
        }
    }
    /// <summary>
    ///丢失链接
    /// </summary>
    void OnDisconnected(DisType dis, stringmsg) {
        Close();   //关掉客户端链接
        int protocal = dis == DisType.Exception ?
        Protocal.Exception : Protocal.Disconnect;
        ByteBuffer buffer = newByteBuffer();
        buffer.WriteShort((ushort)protocal);
        NetworkManager.AddEvent(protocal, buffer);
        Debug.LogError("Connection was closed by the server:>" + msg + "Distype:>" +dis);
    }
    /// <summary>
    ///打印字节
    /// </summary>
    /// <param name="bytes"></param>
    voidPrintBytes() {
        string returnStr = string.Empty;
        for (int i = 0; i < byteBuffer.Length; i++) {
            returnStr += byteBuffer[i].ToString("X2");
        }
        Debug.LogError(returnStr);
    }
    /// <summary>
    ///向链接写入数据流
    /// </summary>
    voidOnWrite(IAsyncResult r) {
        try{
            outStream.EndWrite(r);
        } catch(Exception ex) {
            Debug.LogError("OnWrite--->>>" +ex.Message);
        }
    }
    /// <summary>
    ///接收到消息
    /// </summary>
    void OnReceive(byte[] bytes, intlength) {
        memStream.Seek(0, SeekOrigin.End);
        memStream.Write(bytes, 0, length);
        //Reset to beginning
        memStream.Seek(0, SeekOrigin.Begin);
        while (RemainingBytes() > 2) {
            ushort messageLen =reader.ReadUInt16();
            if (RemainingBytes() >=messageLen) {
                MemoryStream ms = newMemoryStream();
                BinaryWriter writer = newBinaryWriter(ms);
                writer.Write(reader.ReadBytes(messageLen));
                ms.Seek(0, SeekOrigin.Begin);
                OnReceivedMessage(ms);
            } else{
                //Back up the position two bytes
                memStream.Position = memStream.Position - 2;
                break;
            }
        }
        //Create a new stream with any leftover bytes
        byte[] leftover = reader.ReadBytes((int)RemainingBytes());
        memStream.SetLength(0);     //Clear
        memStream.Write(leftover, 0, leftover.Length);
    }
    /// <summary>
    ///剩余的字节
    /// </summary>
    private longRemainingBytes() {
        return memStream.Length -memStream.Position;
    }
    /// <summary>
    ///接收到消息
    /// </summary>
    /// <param name="ms"></param>
    voidOnReceivedMessage(MemoryStream ms) {
        BinaryReader r = newBinaryReader(ms);
        byte[] message = r.ReadBytes((int)(ms.Length -ms.Position));
        //int msglen = message.Length;

        ByteBuffer buffer = newByteBuffer(message);
        int mainId =buffer.ReadShort();
        NetworkManager.AddEvent(mainId, buffer);
    }
    /// <summary>
    ///会话发送
    /// </summary>
    void SessionSend(byte[] bytes) {
        WriteMessage(bytes);
    }
    /// <summary>
    ///关闭链接
    /// </summary>
    public voidClose() {
        if (client != null) {
            if(client.Connected) client.Close();
            client = null;
        }
        loggedIn = false;
    }
    /// <summary>
    ///发送连接请求
    /// </summary>
    public voidSendConnect() {
        ConnectServer(AppConst.SocketAddress, AppConst.SocketPort);
    }
    /// <summary>
    ///发送消息
    /// </summary>
    public voidSendMessage(ByteBuffer buffer) {
        SessionSend(buffer.ToBytes());
        buffer.Close();
    }
}
Network/SocketClient, DisType
usingUnityEngine;
usingSystem;
usingSystem.Collections;
usingSystem.Collections.Generic;
namespaceLuaFramework {
    [Serializable]
    public classPoolInfo {
        public stringpoolName;
        publicGameObject prefab;
        public intpoolSize;
        public boolfixedSize;
    }
    public classGameObjectPool {
        private intmaxSize;
        private intpoolSize;
        private stringpoolName;
        privateTransform poolRoot;
        privateGameObject poolObjectPrefab;
        private Stack<GameObject> availableObjStack = new Stack<GameObject>();
        public GameObjectPool(string poolName, GameObject poolObjectPrefab, int initCount, intmaxSize, Transform pool) {
            this.poolName =poolName;
            this.poolSize =initCount;
            this.maxSize =maxSize;
            this.poolRoot =pool;
            this.poolObjectPrefab =poolObjectPrefab;
            //populate the pool
            for(int index = 0; index < initCount; index++) {
                AddObjectToPool(NewObjectInstance());
            }
        }
        //o(1)
        private voidAddObjectToPool(GameObject go) {
            //add to pool
            go.SetActive(false);
            availableObjStack.Push(go);
            go.transform.SetParent(poolRoot, false);
        }
        privateGameObject NewObjectInstance() {
            return GameObject.Instantiate(poolObjectPrefab) asGameObject;
        }
        publicGameObject NextAvailableObject() {
            GameObject go = null;
            if(availableObjStack.Count > 0) {
                go =availableObjStack.Pop();
            } else{
                Debug.LogWarning("No object available & cannot grow pool: " +poolName);
            }
            go.SetActive(true);
            returngo;
        } 
        //o(1)
        public void ReturnObjectToPool(stringpool, GameObject po) {
            if(poolName.Equals(pool)) {
                AddObjectToPool(po);
            } else{
                Debug.LogError(string.Format("Trying to add object to incorrect pool {0} ", poolName));
            }
        }
    }
}
ObjectPool/GameObjectPool, PoolInfo
usingSystem.Collections.Generic;
usingUnityEngine;
usingUnityEngine.Events;
namespaceLuaFramework
{
    public class ObjectPool<T> where T : class
    {
        private readonly Stack<T> m_Stack = new Stack<T>();
        private readonly UnityAction<T>m_ActionOnGet;
        private readonly UnityAction<T>m_ActionOnRelease;
        public int countAll { get; private set; }
        public int countActive { get { return countAll -countInactive; } }
        public int countInactive { get { returnm_Stack.Count; } }
        public ObjectPool(UnityAction<T> actionOnGet, UnityAction<T>actionOnRelease)
        {
            m_ActionOnGet =actionOnGet;
            m_ActionOnRelease =actionOnRelease;
        }
        publicT Get()
        {
            T element =m_Stack.Pop();
            if (m_ActionOnGet != null)
                m_ActionOnGet(element);
            returnelement;
        }
        public voidRelease(T element)
        {
            if (m_Stack.Count > 0 &&ReferenceEquals(m_Stack.Peek(), element))
                Debug.LogError("Internal error. Trying to destroy object that is already released to pool.");
            if (m_ActionOnRelease != null)
                m_ActionOnRelease(element);
            m_Stack.Push(element);
        }
    }
}
ObjectPool/ObjectPool
usingUnityEngine;
usingSystem.Collections;
namespaceLuaFramework {
    public classTestObjectClass {
        public stringname;
        public intvalue1;
        public floatvalue2;
        //Use this for initialization
        public TestObjectClass(string name, int value1, floatvalue2) {
            this.name =name;
            this.value1 =value1;
            this.value2 =value2;
        }
        public stringToString() {
            return string.Format("name={0} value1={1} = value2={2}", name, value1, value2);
        }
    }
}
ObjectPool/TestObjectClass
usingUnityEngine;
usingSystem.Collections.Generic;
usingSystem.Reflection;
usingLuaInterface;
usingSystem;
namespaceLuaFramework {
    public static classLuaHelper {
        /// <summary>
        ///getType
        /// </summary>
        /// <param name="classname"></param>
        /// <returns></returns>
        public static System.Type GetType(stringclassname) {
            Assembly assb = Assembly.GetExecutingAssembly();  //.GetExecutingAssembly();
            System.Type t = null;
            t =assb.GetType(classname); ;
            if (t == null) {
                t =assb.GetType(classname);
            }
            returnt;
        }
        /// <summary>
        ///面板管理器
        /// </summary>
        public staticPanelManager GetPanelManager() {
            return AppFacade.Instance.GetManager<PanelManager>(ManagerName.Panel);
        }
        /// <summary>
        ///资源管理器
        /// </summary>
        public staticResourceManager GetResManager() {
            return AppFacade.Instance.GetManager<ResourceManager>(ManagerName.Resource);
        }
        /// <summary>
        ///网络管理器
        /// </summary>
        public staticNetworkManager GetNetManager() {
            return AppFacade.Instance.GetManager<NetworkManager>(ManagerName.Network);
        }
        /// <summary>
        ///音乐管理器
        /// </summary>
        public staticSoundManager GetSoundManager() {
            return AppFacade.Instance.GetManager<SoundManager>(ManagerName.Sound);
        }
        /// <summary>
        ///pbc/pblua函数回调
        /// </summary>
        /// <param name="func"></param>
        public static voidOnCallLuaFunc(LuaByteBuffer data, LuaFunction func) {
            if (func != null) func.Call(data);
            Debug.LogWarning("OnCallLuaFunc length:>>" +data.buffer.Length);
        }
        /// <summary>
        ///cjson函数回调
        /// </summary>
        /// <param name="data"></param>
        /// <param name="func"></param>
        public static void OnJsonCallFunc(stringdata, LuaFunction func) {
            Debug.LogWarning("OnJsonCallback data:>>" + data + "lenght:>>" +data.Length);
            if (func != null) func.Call(data);
        }
    }
}
Utility/LuaHelper
usingUnityEngine;
usingSystem;
usingSystem.IO;
usingSystem.Text;
usingSystem.Collections;
usingSystem.Collections.Generic;
usingSystem.Security.Cryptography;
usingSystem.Text.RegularExpressions;
usingLuaInterface;
usingLuaFramework;
#if UNITY_EDITOR
usingUnityEditor;
#endif
namespaceLuaFramework {
    public classUtil {
        private static List<string> luaPaths = new List<string>();
        public static int Int(objecto) {
            returnConvert.ToInt32(o);
        }
        public static float Float(objecto) {
            return (float)Math.Round(Convert.ToSingle(o), 2);
        }
        public static long Long(objecto) {
            returnConvert.ToInt64(o);
        }
        public static int Random(int min, intmax) {
            returnUnityEngine.Random.Range(min, max);
        }
        public static float Random(float min, floatmax) {
            returnUnityEngine.Random.Range(min, max);
        }
        public static string Uid(stringuid) {
            int position = uid.LastIndexOf('_');
            return uid.Remove(0, position + 1);
        }
        public static longGetTime() {
            TimeSpan ts = new TimeSpan(DateTime.UtcNow.Ticks - new DateTime(1970, 1, 1, 0, 0, 0).Ticks);
            return (long)ts.TotalMilliseconds;
        }
        /// <summary>
        ///搜索子物体组件-GameObject版
        /// </summary>
        public static T Get<T>(GameObject go, string subnode) whereT : Component {
            if (go != null) {
                Transform sub =go.transform.Find(subnode);
                if (sub != null) return sub.GetComponent<T>();
            }
            return null;
        }
        /// <summary>
        ///搜索子物体组件-Transform版
        /// </summary>
        public static T Get<T>(Transform go, string subnode) whereT : Component {
            if (go != null) {
                Transform sub =go.Find(subnode);
                if (sub != null) return sub.GetComponent<T>();
            }
            return null;
        }
        /// <summary>
        ///搜索子物体组件-Component版
        /// </summary>
        public static T Get<T>(Component go, string subnode) whereT : Component {
            return go.transform.Find(subnode).GetComponent<T>();
        }
        /// <summary>
        ///添加组件
        /// </summary>
        public static T Add<T>(GameObject go) whereT : Component {
            if (go != null) {
                T[] ts = go.GetComponents<T>();
                for (int i = 0; i < ts.Length; i++) {
                    if (ts[i] != null) GameObject.Destroy(ts[i]);
                }
                return go.gameObject.AddComponent<T>();
            }
            return null;
        }
        /// <summary>
        ///添加组件
        /// </summary>
        public static T Add<T>(Transform go) whereT : Component {
            return Add<T>(go.gameObject);
        }
        /// <summary>
        ///查找子对象
        /// </summary>
        public static GameObject Child(GameObject go, stringsubnode) {
            returnChild(go.transform, subnode);
        }
        /// <summary>
        ///查找子对象
        /// </summary>
        public static GameObject Child(Transform go, stringsubnode) {
            Transform tran =go.Find(subnode);
            if (tran == null) return null;
            returntran.gameObject;
        }
        /// <summary>
        ///取平级对象
        /// </summary>
        public static GameObject Peer(GameObject go, stringsubnode) {
            returnPeer(go.transform, subnode);
        }
        /// <summary>
        ///取平级对象
        /// </summary>
        public static GameObject Peer(Transform go, stringsubnode) {
            Transform tran =go.parent.Find(subnode);
            if (tran == null) return null;
            returntran.gameObject;
        }
        /// <summary>
        ///计算字符串的MD5值
        /// </summary>
        public static string md5(stringsource) {
            MD5CryptoServiceProvider md5 = newMD5CryptoServiceProvider();
            byte[] data =System.Text.Encoding.UTF8.GetBytes(source);
            byte[] md5Data = md5.ComputeHash(data, 0, data.Length);
            md5.Clear();
            string destString = "";
            for (int i = 0; i < md5Data.Length; i++) {
                destString += System.Convert.ToString(md5Data[i], 16).PadLeft(2, '0');
            }
            destString = destString.PadLeft(32, '0');
            returndestString;
        }
        /// <summary>
        ///计算文件的MD5值
        /// </summary>
        public static string md5file(stringfile) {
            try{
                FileStream fs = newFileStream(file, FileMode.Open);
                System.Security.Cryptography.MD5 md5 = newSystem.Security.Cryptography.MD5CryptoServiceProvider();
                byte[] retVal =md5.ComputeHash(fs);
                fs.Close();
                StringBuilder sb = newStringBuilder();
                for (int i = 0; i < retVal.Length; i++) {
                    sb.Append(retVal[i].ToString("x2"));
                }
                returnsb.ToString();
            } catch(Exception ex) {
                throw new Exception("md5file() fail, error:" +ex.Message);
            }
        }
        /// <summary>
        ///清除所有子节点
        /// </summary>
        public static voidClearChild(Transform go) {
            if (go == null) return;
            for (int i = go.childCount - 1; i >= 0; i--) {
                GameObject.Destroy(go.GetChild(i).gameObject);
            }
        }
        /// <summary>
        ///清理内存
        /// </summary>
        public static voidClearMemory() {
            GC.Collect(); Resources.UnloadUnusedAssets();
            LuaManager mgr = AppFacade.Instance.GetManager<LuaManager>(ManagerName.Lua);
            if (mgr != null) mgr.LuaGC();
        }
        /// <summary>
        ///取得数据存放目录
        /// </summary>
        public static stringDataPath {
            get{
                string game =AppConst.AppName.ToLower();
                if(Application.isMobilePlatform) {
                    return Application.persistentDataPath + "/" + game + "/";
                }
                if(AppConst.DebugMode) {
                    return Application.dataPath + "/" + AppConst.AssetDir + "/";
                }
                if (Application.platform ==RuntimePlatform.OSXEditor) {
                    int i = Application.dataPath.LastIndexOf('/');
                    return Application.dataPath.Substring(0, i + 1) + game + "/";
                }
                return "c:/" + game + "/";
            }
        }
        public static stringGetRelativePath() {
            if(Application.isEditor)
                return "file://" + System.Environment.CurrentDirectory.Replace("\", "/") + "/Assets/" + AppConst.AssetDir + "/";
            else if (Application.isMobilePlatform ||Application.isConsolePlatform)
                return "file:///" +DataPath;
            else //For standalone player.
                return "file://" + Application.streamingAssetsPath + "/";
        }
        /// <summary>
        ///取得行文本
        /// </summary>
        public static string GetFileText(stringpath) {
            returnFile.ReadAllText(path);
        }
        /// <summary>
        ///网络可用
        /// </summary>
        public static boolNetAvailable {
            get{
                return Application.internetReachability !=NetworkReachability.NotReachable;
            }
        }
        /// <summary>
        ///是否是无线
        /// </summary>
        public static boolIsWifi {
            get{
                return Application.internetReachability ==NetworkReachability.ReachableViaLocalAreaNetwork;
            }
        }
        /// <summary>
        ///应用程序内容路径
        /// </summary>
        public static stringAppContentPath() {
            string path = string.Empty;
            switch(Application.platform) {
                caseRuntimePlatform.Android:
                    path = "jar:file://" + Application.dataPath + "!/assets/";
                break;
                caseRuntimePlatform.IPhonePlayer:
                    path = Application.dataPath + "/Raw/";
                break;
                default:
                    path = Application.dataPath + "/" + AppConst.AssetDir + "/";
                break;
            }
            returnpath;
        }
        public static void Log(stringstr) {
            Debug.Log(str);
        }
        public static void LogWarning(stringstr) {
            Debug.LogWarning(str);
        }
        public static void LogError(stringstr) {
            Debug.LogError(str);
        }
        /// <summary>
        ///防止初学者不按步骤来操作
        /// </summary>
        /// <returns></returns>
        public static intCheckRuntimeFile() {
            if (!Application.isEditor) return 0;
            string streamDir = Application.dataPath + "/StreamingAssets/";
            if (!Directory.Exists(streamDir)) {
                return -1;
            } else{
                string[] files =Directory.GetFiles(streamDir);
                if (files.Length == 0) return -1;
                if (!File.Exists(streamDir + "files.txt")) {
                    return -1;
                }
            }
            string sourceDir = AppConst.FrameworkRoot + "/ToLua/Source/Generate/";
            if (!Directory.Exists(sourceDir)) {
                return -2;
            } else{
                string[] files =Directory.GetFiles(sourceDir);
                if (files.Length == 0) return -2;
            }
            return 0;
        }
        /// <summary>
        ///执行Lua方法
        /// </summary>
        public static object[] CallMethod(string module, string func, params object[] args) {
            LuaManager luaMgr = AppFacade.Instance.GetManager<LuaManager>(ManagerName.Lua);
            if (luaMgr == null) return null;
            return luaMgr.CallFunction(module + "." +func, args);
        }
                /// <summary>
        ///检查运行环境
        /// </summary>
        public static boolCheckEnvironment() {
#if UNITY_EDITOR
            int resultId =Util.CheckRuntimeFile();
            if (resultId == -1) {
                Debug.LogError("没有找到框架所需要的资源,单击Game菜单下Build xxx Resource生成!!");
                EditorApplication.isPlaying = false;
                return false;
            } else if (resultId == -2) {
                Debug.LogError("没有找到Wrap脚本缓存,单击Lua菜单下Gen Lua Wrap Files生成脚本!!");
                EditorApplication.isPlaying = false;
                return false;
            }
            if (Application.loadedLevelName == "Test" && !AppConst.DebugMode) {
                Debug.LogError("测试场景,必须打开调试模式,AppConst.DebugMode = true!!");
                EditorApplication.isPlaying = false;
                return false;
            }
#endif
            return true;
        }
    }
}
Utility/Util
usingUnityEngine;
usingLuaFramework;
usingSystem.Collections.Generic;
public classAppView : View {
    private stringmessage;
    ///<summary>
    ///监听的消息
    ///</summary>
    List<string>MessageList {
        get{
            return new List<string>()
            { 
                NotiConst.UPDATE_MESSAGE,
                NotiConst.UPDATE_EXTRACT,
                NotiConst.UPDATE_DOWNLOAD,
                NotiConst.UPDATE_PROGRESS,
            };
        }
    }
    voidAwake() {
        RemoveMessage(this, MessageList);
        RegisterMessage(this, MessageList);
    }
    /// <summary>
    ///处理View消息
    /// </summary>
    /// <param name="message"></param>
    public override voidOnMessage(IMessage message) {
        string name =message.Name;
        object body =message.Body;
        switch(name) {
            case NotiConst.UPDATE_MESSAGE:      //更新消息
UpdateMessage(body.ToString());
            break;
            case NotiConst.UPDATE_EXTRACT:      //更新解压
UpdateExtract(body.ToString());
            break;
            case NotiConst.UPDATE_DOWNLOAD:     //更新下载
UpdateDownload(body.ToString());
            break;
            case NotiConst.UPDATE_PROGRESS:     //更新下载进度
UpdateProgress(body.ToString());
            break;
        }
    }
    public void UpdateMessage(stringdata) {
        this.message =data;
    }
    public void UpdateExtract(stringdata) {
        this.message =data;
    }
    public void UpdateDownload(stringdata) {
        this.message =data;
    }
    public void UpdateProgress(stringdata) {
        this.message =data;
    }
    voidOnGUI() {
        GUI.Label(new Rect(10, 120, 960, 50), message);
        GUI.Label(new Rect(10, 0, 500, 50), "(1) 单击 "Lua/Gen Lua Wrap Files"。");
        GUI.Label(new Rect(10, 20, 500, 50), "(2) 运行Unity游戏");
        GUI.Label(new Rect(10, 40, 500, 50), "PS: 清除缓存,单击"Lua/Clear LuaBinder File + Wrap Files"。");
        GUI.Label(new Rect(10, 60, 900, 50), "PS: 若运行到真机,请设置Const.DebugMode=false,本地调试请设置Const.DebugMode=true");
        GUI.Label(new Rect(10, 80, 500, 50), "PS: 加Unity+ulua技术讨论群:>>341746602");
    }
}
View/AppView
usingUnityEngine;
usingSystem.Collections;
namespaceLuaFramework {
    /// <summary>
    /// </summary>
    public classMain : MonoBehaviour {
        voidStart() {
            AppFacade.Instance.StartUp();   //启动游戏
}
    }
}
Main

免责声明:文章转载自《LuaFramework 学习》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇三角函数初步贪念下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

随便看看

双向认证

证书携带公钥信息,用于验证服务器端,加密/解密数据,并作为OSI五类服务的认证(认证)服务和保密服务。这种双重认证是在线银行系统安全的关键!有关单向身份验证,请参阅Java加密技术(X)。双向身份验证要求CA授权机构颁发此类客户端和服务器端证书。首先,CA机构需要构建根证书。我们在linux下直接使用openssl来完成CA。我们需要修改openssl.cn...

flutter Radio单选框

单选框,允许用户从一组中选择一个选项。...

SqlServer数据库存入decimal类型数据注意事项

对于sqlserver,Decimal可用于存储具有小数点和固定值的值。与浮点和实数不同,十进制用于存储近似值。目的是满足精确数学运算的需要。它是最大和最精确的浮点数字类型。对于十进制类型,请注意必须指定精度;否则,十进制只能存储为整数,就像int一样。例如,十进制是存储长度为18位和小数点后2位的数据。...

input框输入金额处理的解决办法

最近,已经启动的项目在删除输入输入量时突然出现问题。各种在线搜索都没有找到你想要的。今天,我将以react框架为例进行代码贡献。我会写下需求和解决方案,希望对我的朋友有用。如果有更好的方法实现它,请给我一些建议!”在“:”下;n=数学。防抱死制动系统;vars=“”;对于{s+=.replace;}S=S||“整数”;n=数学。地板对于{varp=“”;对于...

ios 苹果和百度地图的相关使用

同时由于苹果使用的是高德,不会像谷歌地图一样在国内乌龟一样的访问速度,确实做一些地图相关的东西,非常有吸引力。只是实现了显示一个百度地图的view。百度地图使用的是Objective-C++,这意味这必须要有一个.mm文件。...

uniapp之页面间传递和接收数组

uni-app如何在页面之前发送和传递数组?如果阵列是直接发送和传递的,则收到的消息如下所示。无法获取更多的对象值。接收数组对象的参数。您可以首先将数组转换为JSON字符串,然后在将其传递到页面后将其解析为JavaScript对象。...