/// <summary>
        /// 从一条row反序列化gobj对象
        /// </summary>
        /// <param name="gobj"></param>
        /// <param name="row"></param>
        void Deserialize(IGObject gobj, DataRow row)
        {
            var fields = GTypeInfo.Get(gobj.GetType()).Fields;

            var columns = row.Table.Columns;

            for (int columIndex = 0; columIndex < columns.Count; columIndex++)
            {
                if (row[columIndex] == DBNull.Value)
                {
                    continue;
                }

                if (columIndex < fields.Length && columns[columIndex].ColumnName == fields[columIndex].Name) //根据columIndex快速匹配
                {
                    var field = fields[columIndex];
                    SetValue(gobj, field, row[columIndex]);
                }
                else
                {
                    for (int fieldIndex = 0; fieldIndex < fields.Length; fieldIndex++)
                    {
                        if (fields[fieldIndex].Name == columns[columIndex].ColumnName)
                        {
                            var field = fields[fieldIndex];
                            SetValue(gobj, fields[fieldIndex], row[columIndex]);
                        }
                    }
                }
            }

            if (gobj is IGCollectionBase)
            {
                var collection = gobj as IGCollectionBase;
                var str        = row["innerList"].ToString();
                if (str.Length == 0)
                {
                    return;
                }
                var arr = str.Split('|');
                for (int i = 0; i < arr.Length; i++)
                {
                    int id = Convert.ToInt32(arr[i]);
                    foreach (IGObject obj in loadedObj)
                    {
                        if (obj.GID == id)
                        {
                            collection.InnerList.Add(obj);
                            break;
                        }
                    }
                }
            }
        }
        /// <summary>
        /// 序列化obj及其所有相关的可序列化对象到文件
        /// </summary>
        /// <param name="obj"></param>
        public void Serialize(IGObject obj)
        {
            currentVisited++;                        //更新对象目标访问次数
            sqliteHelper.BeginTransaction();         //开始事务
            savedObj.Clear();                        //清空保存的对象
            InnerSerialize(obj);                     //序列化对象
            var delObj = loadedObj.Except(savedObj); //获取需要删除的对象

            foreach (IGObject o in delObj)
            {
                sqliteHelper.Execute(GTypeInfo.Get(o.GetType()).DeleteSql, new SQLiteParameter("@gid", o.GID));
            }
            sqliteHelper.Commit();              //提交事务
            loadedObj = savedObj;               //更新以保存对象列表
            var dirties = loadedObj.Where(m => m.GDirty).ToList();

            isDirty = false;
        }
 public void Execute(Collider2D collider, IGObject obj)
 {
     obj.Collider2DEnter(collider);
 }
        /// <summary>
        /// 设置gobj对象field字段的值value
        /// </summary>
        /// <param name="gobj"></param>
        /// <param name="field"></param>
        /// <param name="value"></param>
        void SetValue(IGObject gobj, FieldInfo field, object value)
        {
            Type fieldType = field.FieldType;

            if (fieldType == value.GetType())
            {
                field.SetValue(gobj, value);
                return;
            }

            if (fieldType == typeof(bool))
            {
                field.SetValue(gobj, Convert.ToBoolean(value));
            }
            else if (fieldType == typeof(Int16))
            {
                field.SetValue(gobj, Convert.ToInt16(value));
            }
            else if (fieldType == typeof(Int32))
            {
                field.SetValue(gobj, Convert.ToInt32(value));
            }
            else if (fieldType == typeof(Int64))
            {
                field.SetValue(gobj, Convert.ToInt64(value));
            }
            else if (fieldType == typeof(UInt16))
            {
                field.SetValue(gobj, Convert.ToUInt16(value));
            }
            else if (fieldType == typeof(UInt32))
            {
                field.SetValue(gobj, Convert.ToUInt32(value));
            }
            else if (fieldType == typeof(UInt64))
            {
                field.SetValue(gobj, Convert.ToUInt64(value));
            }
            else if (fieldType == typeof(string))
            {
                field.SetValue(gobj, Convert.ToString(value));
            }
            else if (fieldType == typeof(Point))
            {
                var arr = value.ToString().Split(',');
                field.SetValue(gobj, new Point(Convert.ToInt32(arr[0]), Convert.ToInt32(arr[1])));
            }
            else if (fieldType == typeof(Size))
            {
                var arr = value.ToString().Split(',');
                field.SetValue(gobj, new Size(Convert.ToInt32(arr[0]), Convert.ToInt32(arr[1])));
            }
            else if (fieldType == typeof(Rectangle))
            {
                var arr = value.ToString().Split(',');
                field.SetValue(gobj, new Rectangle(Convert.ToInt32(arr[0]), Convert.ToInt32(arr[1]), Convert.ToInt32(arr[2]), Convert.ToInt32(arr[3])));
            }

            /*
             * else if (fieldType == typeof(Image))
             * {
             * MemoryStream stream = new MemoryStream((byte[])value);
             * field.SetValue(gobj, Image.FromStream(stream));
             * }
             * */
            //else if (fieldType == typeof(Image))
            //{
            //    MemoryStream stream = new MemoryStream((byte[])value);
            //    BinaryFormatter b = new BinaryFormatter();
            //    var ddd = b.Deserialize(stream);
            //    field.SetValue(gobj, ddd);
            //    stream.Close();
            //}
            //else if (fieldType == typeof(System.Drawing.Imaging.Metafile))
            //{
            //    MemoryStream stream = new MemoryStream((byte[])value);
            //    BinaryFormatter b = new BinaryFormatter();
            //    var ddd = b.Deserialize(stream);
            //    field.SetValue(gobj, ddd);
            //    stream.Close();
            //}
            else if ((typeof(IGObject)).IsAssignableFrom(fieldType)) //GObject派生类
            {
                int gid = Convert.ToInt32(value);
                //检查引用类型是否正确
                if (linkArr[gid] != null)
                {
                    if (fieldType.IsAssignableFrom(linkArr[gid].GetType()))
                    {
                        field.SetValue(gobj, linkArr[gid]);
                    }
                    else
                    {
                        throw new Exception(string.Format("{0}[gid={1}]{2}字段指向了一个错误的引用{3}[gid={4}]", gobj.GetType().Name, gobj.GID, field.Name, linkArr[gid].GetType(), gid));
                    }
                }
            }
            else if (fieldType.IsEnum)
            {
                field.SetValue(gobj, Convert.ToInt32(value));
            }
        }
        void InnerSerialize(IGObject obj)
        {
            if (obj.GVisitCount == currentVisited)
            {
                return;
            }
            obj.GVisitCount = currentVisited;
            savedObj.Add(obj);
            bool create = obj.GID == -1;

            if (create)
            {
                obj.GID = GetGID();
            }
            var typeInfo = GTypeInfo.Get(obj.GetType());
            //获取字段值
            bool isCollection = obj is IGCollectionBase;

            SQLiteParameter[] pts = new SQLiteParameter[typeInfo.Fields.Length + (isCollection ? 1 : 0)];

            //为每个字段值转换成数据库能接受的值
            for (int i = 0; i < typeInfo.Fields.Length; i++)
            {
                var    field        = typeInfo.Fields[i];
                var    fieldType    = field.FieldType;
                var    fieldValue   = field.GetValue(obj);
                object dbFieldValue = null;

                #region 值转换
                if (fieldValue == null)
                {
                    dbFieldValue = DBNull.Value;
                }
                else if (fieldType == typeof(UInt16))
                {
                    dbFieldValue = fieldValue;
                }
                else if (fieldType == typeof(UInt32))
                {
                    dbFieldValue = fieldValue;
                }
                else if (fieldType == typeof(UInt64))
                {
                    dbFieldValue = fieldValue;
                }
                else if (fieldType == typeof(Int16))
                {
                    dbFieldValue = fieldValue;
                }
                else if (fieldType == typeof(Int32))
                {
                    dbFieldValue = fieldValue;
                }
                else if (fieldType == typeof(Int64))
                {
                    dbFieldValue = fieldValue;
                }
                else if (fieldType == typeof(bool))
                {
                    dbFieldValue = fieldValue;
                }
                else if (fieldType.IsEnum)
                {
                    dbFieldValue = fieldValue;
                }
                else if (typeof(IGObject).IsAssignableFrom(fieldType))
                {
                    var gitem = fieldValue as IGObject;
                    if (gitem.GVisitCount < currentVisited)
                    {
                        InnerSerialize(gitem);
                    }
                    dbFieldValue = gitem.GID;
                }
                else if (fieldType == typeof(string))
                {
                    dbFieldValue = fieldValue;
                }
                else if (fieldType == typeof(Single) || fieldType == typeof(Double) || fieldType == typeof(Decimal))
                {
                    dbFieldValue = fieldValue;
                }
                else if (fieldType == typeof(Point))
                {
                    Point p = (Point)fieldValue; dbFieldValue = string.Format("{0},{1}", p.X, p.Y);
                }
                else if (fieldType == typeof(Size))
                {
                    Size s = (Size)fieldValue; dbFieldValue = string.Format("{0},{1}", s.Width, s.Height);
                }
                else if (fieldType == typeof(Rectangle))
                {
                    Rectangle r = (Rectangle)fieldValue; dbFieldValue = string.Format("{0},{1},{2},{3}", r.X, r.Y, r.Width, r.Height);
                }
                //else if (fieldValue is Image)
                //{
                //    MemoryStream ms = new MemoryStream();
                //    BinaryFormatter b = new BinaryFormatter();
                //    b.Serialize(ms, fieldValue);
                //    dbFieldValue = ms.GetBuffer();
                //    ms.Close();
                //}
                #endregion
                pts[i] = new SQLiteParameter("@" + typeInfo.Fields[i].Name, dbFieldValue);
            }
            //如果是集合则额外添加一个字段
            if (isCollection)
            {
                IGCollectionBase collection = obj as IGCollectionBase;
                StringBuilder    strBuilder = new StringBuilder(collection.InnerList.Count * 2);
                foreach (object item in collection.InnerList)
                {
                    IGObject gitem = item as IGObject;
                    if (gitem == null)
                    {
                        continue;
                    }
                    if (gitem.GVisitCount < currentVisited)
                    {
                        InnerSerialize(gitem);
                    }
                    strBuilder.Append(gitem.GID);
                    strBuilder.Append('|');
                }
                if (strBuilder.Length > 0)
                {
                    strBuilder.Remove(strBuilder.Length - 1, 1);
                }
                pts[pts.Length - 1] = new SQLiteParameter("@innerList", strBuilder.ToString());
            }
            //添加或者修改记录
            if (create)
            {
                if (!dataTables.Contains(typeInfo.FullName))
                {
                    sqliteHelper.Execute(typeInfo.CreateTableSql);
                    dataTables.Add(typeInfo.FullName);
                }
                sqliteHelper.Execute(typeInfo.InsertSql, pts);
                obj.GDirty = false;
            }
            else if (obj.GDirty)
            {
                sqliteHelper.Execute(typeInfo.UpdateSql, pts);
                obj.GDirty = false;
            }
        }