GameFramework源码分析(三)- 数据表模块与读取解析

数据表模块

在GF中,只提供了数据表的数据结构,以及数据表管理器和数据解析前的流程。具体的解析操作,没有实现。

先看看解析前的整个流程:

创建表对象

dataTable = m_DataTableManager.CreateDataTable ->

        /// <summary>
        /// 创建数据表。
        /// </summary>
        /// <param name="dataRowType">数据表行的类型。</param>
        /// <param name="name">数据表名称。</param>
        /// <returns>要创建的数据表。</returns>
        public DataTableBase CreateDataTable(Type dataRowType, string name)
        {
            if (m_ResourceManager == null)
            {
                throw new GameFrameworkException("You must set resource manager first.");
            }

            if (m_DataProviderHelper == null)
            {
                throw new GameFrameworkException("You must set data provider helper first.");
            }

            if (dataRowType == null)
            {
                throw new GameFrameworkException("Data row type is invalid.");
            }

            if (!typeof(IDataRow).IsAssignableFrom(dataRowType))
            {
                throw new GameFrameworkException(Utility.Text.Format("Data row type '{0}' is invalid.", dataRowType.FullName));
            }

            TypeNamePair typeNamePair = new TypeNamePair(dataRowType, name);
            if (HasDataTable(dataRowType, name))
            {
                throw new GameFrameworkException(Utility.Text.Format("Already exist data table '{0}'.", typeNamePair));
            }

            Type dataTableType = typeof(DataTable<>).MakeGenericType(dataRowType);
            DataTableBase dataTable = (DataTableBase)Activator.CreateInstance(dataTableType, name);
            dataTable.SetResourceManager(m_ResourceManager);
            dataTable.SetDataProviderHelper(m_DataProviderHelper);
            m_DataTables.Add(typeNamePair, dataTable);
            return dataTable;
        }
......
......

 

 

 

读取数据

dataTable.ReadData -> DataProvider.ReadData ->resource.loadAsset ->

        /// <summary>
        /// 读取数据表。
        /// </summary>
        /// <param name="dataTableAssetName">数据表资源名称。</param>
        public void ReadData(string dataTableAssetName)
        {
            m_DataProvider.ReadData(dataTableAssetName);
        }

        /// <summary>
        /// 读取数据表。
        /// </summary>
        /// <param name="dataTableAssetName">数据表资源名称。</param>
        /// <param name="priority">加载数据表资源的优先级。</param>
        public void ReadData(string dataTableAssetName, int priority)
        {
            m_DataProvider.ReadData(dataTableAssetName, priority);
        }

       ......
       ......

 

[在Unity端实现]读取数据

DataTableHelperBase.ReadData ->

        /// <summary>
        /// 读取数据表。
        /// </summary>
        /// <param name="dataTable">数据表。</param>
        /// <param name="dataTableAssetName">数据表资源名称。</param>
        /// <param name="dataTableAsset">数据表资源。</param>
        /// <param name="userData">用户自定义数据。</param>
        /// <returns>是否读取数据表成功。</returns>
        public abstract bool ReadData(DataTableBase dataTable, string dataTableAssetName, object dataTableAsset, object userData);

        /// <summary>
        /// 读取数据表。
        /// </summary>
        /// <param name="dataTable">数据表。</param>
        /// <param name="dataTableAssetName">数据表资源名称。</param>
        /// <param name="dataTableBytes">数据表二进制流。</param>
        /// <param name="startIndex">数据表二进制流的起始位置。</param>
        /// <param name="length">数据表二进制流的长度。</param>
        /// <param name="userData">用户自定义数据。</param>
        /// <returns>是否读取数据表成功。</returns>
        public abstract bool ReadData(DataTableBase dataTable, string dataTableAssetName, byte[] dataTableBytes, int startIndex, int length, object userData);

        /// <summary>
        /// 解析数据表。
        /// </summary>
        /// <param name="dataTable">数据表。</param>
        /// <param name="dataTableString">要解析的数据表字符串。</param>
        /// <param name="userData">用户自定义数据。</param>
        /// <returns>是否解析数据表成功。</returns>
        public abstract bool ParseData(DataTableBase dataTable, string dataTableString, object userData);

 

 

解析数据表

DataTableBase.ParseData ->DataProvider.ParseData ->

        /// <summary>
        /// 解析数据表。
        /// </summary>
        /// <param name="dataTableString">要解析的数据表字符串。</param>
        /// <returns>是否解析数据表成功。</returns>
        public bool ParseData(string dataTableString)
        {
            return m_DataProvider.ParseData(dataTableString);
        }

        /// <summary>
        /// 解析数据表。
        /// </summary>
        /// <param name="dataTableString">要解析的数据表字符串。</param>
        /// <param name="userData">用户自定义数据。</param>
        /// <returns>是否解析数据表成功。</returns>
        public bool ParseData(string dataTableString, object userData)
        {
            return m_DataProvider.ParseData(dataTableString, userData);
        }
......
......

 [在Unity端实现]解析数据表

DataTableHelperBase.ParseData ->

       /// <summary>
        /// 解析数据表。
        /// </summary>
        /// <param name="dataTable">数据表。</param>
        /// <param name="dataTableString">要解析的数据表字符串。</param>
        /// <param name="userData">用户自定义数据。</param>
        /// <returns>是否解析数据表成功。</returns>
        public abstract bool ParseData(DataTableBase dataTable, string dataTableString, object userData);

        /// <summary>
        /// 解析数据表。
        /// </summary>
        /// <param name="dataTable">数据表。</param>
        /// <param name="dataTableBytes">要解析的数据表二进制流。</param>
        /// <param name="startIndex">数据表二进制流的起始位置。</param>
        /// <param name="length">数据表二进制流的长度。</param>
        /// <param name="userData">用户自定义数据。</param>
        /// <returns>是否解析数据表成功。</returns>
        public abstract bool ParseData(DataTableBase dataTable, byte[] dataTableBytes, int startIndex, int length, object userData);

 向数据结构追加行

 

DataTableBase.AddDataRow ->

        /// <summary>
        /// 增加数据表行。
        /// </summary>
        /// <param name="dataRowString">要解析的数据表行字符串。</param>
        /// <param name="userData">用户自定义数据。</param>
        /// <returns>是否增加数据表行成功。</returns>
        public abstract bool AddDataRow(string dataRowString, object userData);

        /// <summary>
        /// 增加数据表行。
        /// </summary>
        /// <param name="dataRowBytes">要解析的数据表行二进制流。</param>
        /// <param name="startIndex">数据表行二进制流的起始位置。</param>
        /// <param name="length">数据表行二进制流的长度。</param>
        /// <param name="userData">用户自定义数据。</param>
        /// <returns>是否增加数据表行成功。</returns>
        public abstract bool AddDataRow(byte[] dataRowBytes, int startIndex, int length, object userData);

 

 

 

解析行

IDataRow.ParseDataRow ->

        /// <summary>
        /// 解析数据表行。
        /// </summary>
        /// <param name="dataRowString">要解析的数据表行字符串。</param>
        /// <param name="userData">用户自定义数据。</param>
        /// <returns>是否解析数据表行成功。</returns>
        bool ParseDataRow(string dataRowString, object userData);

        /// <summary>
        /// 解析数据表行。
        /// </summary>
        /// <param name="dataRowBytes">要解析的数据表行二进制流。</param>
        /// <param name="startIndex">数据表行二进制流的起始位置。</param>
        /// <param name="length">数据表行二进制流的长度。</param>
        /// <param name="userData">用户自定义数据。</param>
        /// <returns>是否解析数据表行成功。</returns>
        bool ParseDataRow(byte[] dataRowBytes, int startIndex, int length, object userData);

 

 

[在Unity端实现] 解析行

DataRowBase.ParseDataRow

        /// <summary>
        /// 解析数据表行。
        /// </summary>
        /// <param name="dataRowString">要解析的数据表行字符串。</param>
        /// <param name="userData">用户自定义数据。</param>
        /// <returns>是否解析数据表行成功。</returns>
        public virtual bool ParseDataRow(string dataRowString, object userData)
        {
            Log.Warning("Not implemented ParseDataRow(string dataRowString, object userData).");
            return false;
        }

        /// <summary>
        /// 解析数据表行。
        /// </summary>
        /// <param name="dataRowBytes">要解析的数据表行二进制流。</param>
        /// <param name="startIndex">数据表行二进制流的起始位置。</param>
        /// <param name="length">数据表行二进制流的长度。</param>
        /// <param name="userData">用户自定义数据。</param>
        /// <returns>是否解析数据表行成功。</returns>
        public virtual bool ParseDataRow(byte[] dataRowBytes, int startIndex, int length, object userData)
        {
            Log.Warning("Not implemented ParseDataRow(byte[] dataRowBytes, int startIndex, int length, object userData).");
            return false;
        }

 

 

m_DataSet更新

private sealed class DataTable<T> : DataTableBase, IDataTable<T> where T : class, IDataRow, new()
        {
            private readonly Dictionary<int, T> m_DataSet;
            ......
            ......
            private void InternalAddDataRow(T dataRow)
            {
                if (m_DataSet.ContainsKey(dataRow.Id))
                {
                    throw new GameFrameworkException(Utility.Text.Format("Already exist '{0}' in data table '{1}'.", dataRow.Id, new TypeNamePair(typeof(T), Name)));
                }

                m_DataSet.Add(dataRow.Id, dataRow);

                if (m_MinIdDataRow == null || m_MinIdDataRow.Id > dataRow.Id)
                {
                    m_MinIdDataRow = dataRow;
                }

                if (m_MaxIdDataRow == null || m_MaxIdDataRow.Id < dataRow.Id)
                {
                    m_MaxIdDataRow = dataRow;
                }
            }
        }

 

 

以上的流程中,读取和解析工作由DataProvider与DataTableHelperBase实现类共同来完成。其中引入DataTableHelperBase(IDataProviderHelp)的原因可能是需要使用到unity端的接口。

获取数据

dataTable = datamgr.GetDataTable<T>

datas = dataTable.GetDataAllRow()

读取与解析

很多模块都涉及到数据读取与处理,而他们所作的工作可能都有所不同,比如处理的格式。

GF抽象出了IDataProvider接口,就用于负责数据读取与解析。这样通过实现重写IDataProvider接口,模块只需要接入IDataProvider的实现,就可以完成不同的具体工作。所有读取操作,不仅是IDataProvider,在进行读取前都需要将文件部分内容载入内存读写,这部分是高度可抽象的。因此这部分又可以抽象为IResourceManager。

读取过程大体如下:

模块->IDataProvider.ReadData -> IResourceManager.Load ->(也可能用到IDataProviderHelper,基本都会用到,大多数都用Helper再去发起解析) ->
IDataProviderHelper.ReadData->模块.ParseData -> IDataProvider.ParseData -> IDataProviderHelper.ParseData。

作者:Miracle
来源:麦瑞克博客
链接:https://www.playcreator.cn/archives/unity/4351/
本博客所有文章除特别声明外,均采用CC BY-NC-SA 4.0许可协议,转载请注明!
THE END
分享
打赏
海报
GameFramework源码分析(三)- 数据表模块与读取解析
数据表模块 在GF中,只提供了数据表的数据结构,以及数据表管理器和数据解析前的流程。具体的解析操作,没有实现。 先看看解析前的整个流程: 创建表对象 data……
<<上一篇
下一篇>>
文章目录
关闭
目 录