U3D客户端框架之基于类对象池的可回收变量代码实现

简介: 可回收变量 是基于引用计数去做的管理,基类实现了引用计数增加,和释放功能,当调用引用计数增加函数时,引用计数+1;当调用释放函数时候,引用计数-1,当引用计数==0的时候,类对象池会把该可回收变量对象回收。

1 类对象池介绍


因为原先已经写过一篇文章了,里面已经写明白了类对象池是什么?具体特征是什么?优缺点都有什么?大家如果有兴趣可以点下面的文章去细看一下。如果懂原理直接看代码即可。


类对象池设计思想与代码实现:


类对象池设计:Unity3d框架搭建 使用 类对象池技术 优化 C#语言 GC_天才小熊猫oo的博客-CSDN博客


2.基于类对象池的可回收变量设计


可回收变量 是基于引用计数去做的管理,基类实现了引用计数增加,和释放功能,当调用引用计数增加函数时,引用计数+1;当调用释放函数时候,引用计数-1,当引用计数==0的时候,类对象池会把该可回收变量对象回收。


2.1已支持的类型


目前一共封装了一些常用的类型:bool、byte、byte[]、float、gameobject、int、long、string、transform。这个如果有新的常用数据结构也可以自行封装。


2.2 函数设计


每个封装的变量内都有无参Alloc构造函数,这个构造主要是从类对象池取出对象并且重置具体数据,引用计数+1。有参Alloc构造函数,这个函数会调用无参Alloc构造函数,取出池中的数据后,会将传入的数据赋值给封装变量的真实数据。隐式类型转换,使用c#中的operator关键字和 implicit关键字,可以直接将等号右边的封装结构,直接转换成真实数据类型。


3.代码设计实现


VariableBase.cs代码实现


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using YouYou;
namespace Myh
{
    //变量基类
    public abstract class VariableBase
    {
        public abstract Type Type
        {
            get;
        }
        //引用计数
        public byte ReferenceCount
        {
            private set;
            get;
        }
        //保留对象(引用计数+1)
        public void Retain() 
        {
            ++ReferenceCount;
        }
        //释放对象(如果引用的对象数量==0,则把this回池)
        public void Release()
        {
            --ReferenceCount;
            if (ReferenceCount < 1)
            {
                //回池,入队列
                GameEntry.Pool.EnqueueVarObject(this);
            }
        }
    }
}


Variable.cs代码实现


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using YouYou;
namespace Myh
{
    public class Variable<T>:VariableBase
    {
        //当前存储的实例的类型(T类型的实例)
        public T Value;
        //变量类型
        public override Type Type
        {
            get 
            {
                return typeof(T);
            }
        }
    }
}


VarByte.cs 代码实现


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using YouYou;
namespace Myh
{
    //byte变量
    public class VarByte:Variable<byte>
    {
        //分配一个对象
        public static VarByte Alloc()
        {
            VarByte var = GameEntry.Pool.DequeueVarObject<VarByte>();
            var.Value = 0;
            var.Retain();
            return var;
        }
        //分配一个对象 根据传入的byte 
        public static VarByte Alloc(byte value)
        {
            VarByte var = Alloc();
            var.Value = value;
            return var;
        }
        //VarByte->byte 声明隐式转换,编译期间编译器忽视这种类型的隐式转换
        public static implicit operator byte(VarByte value)
        {
            return value.Value;
        }
    }
}


VarByte.cs 代码实现


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using YouYou;
namespace Myh
{
    //bool变量
    public class VarBool : Variable<bool>
    {
        //分配一个对象
        public static VarBool Alloc()
        {
            VarBool var = GameEntry.Pool.DequeueVarObject<VarBool>();
            var.Value = false;
            //持有数量+1,+1+1+1~
            var.Retain();
            return var;
        }
        //分配一个对象
        public static VarBool Alloc(bool value)
        {
            VarBool var = Alloc();
            var.Value = value;
            return var;
        }
        //声明的隐式转换,如果这样写编译期间就不会对转换的类型进行检查
        public static implicit operator bool(VarBool value)
        {
            return value.Value;
        }
        //还缺一个直接把VarBool赋值成具体值的函数
    }
}


VarBytes.cs代码实现


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using YouYou;
namespace Myh
{
    //byte[] 变量
    public class VarBytes : Variable<byte[]>
    {
        //分配一个对象
        public static VarBytes Alloc()
        {
            //从类对象池里取出varBytes对象
            VarBytes var = GameEntry.Pool.DequeueVarObject<VarBytes>();
            //初始值为null
            var.Value = null;
            var.Retain();
            return var;
        }
        //分配一个对象(by 传入的 byte[])
        public static VarBytes Alloc(byte[] value)
        {
            VarBytes var = Alloc();
            var.Value = value;
            return var;
        }
        //Varbytes->byte[]
        //把真实数据的指着赋给byte[] ,赋值完之后,回收也没关系,因为下一次Alloc的时候会把Value赋值成null
        public static implicit operator byte[](VarBytes value)
        {
            return value.Value;
        }
    }
}


VarFloat.cs代码实现


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using YouYou;
namespace Myh
{
    //float变量
    public class VarFloat:Variable<float>
    {
        //分配一个对象
        public static VarFloat Alloc()
        {
            VarFloat var = GameEntry.Pool.DequeueVarObject<VarFloat>();
            var.Value = 0f;
            var.Retain();
            return var;
        }
        //分配一个对象(value使用传入的float值)
        public static VarFloat Alloc(float value)
        {
            VarFloat var = Alloc();
            var.Value = value;
            return var;
        }
        //VarFloat -> float
        public static implicit operator float(VarFloat value)
        {
            return value.Value;
        }
    }
}


VarGameObject.cs代码实现


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using YouYou;
using UnityEngine;
namespace Myh
{
    //GameObject
    public class VarGameObject:Variable<GameObject>
    {
        //分配一个GameObject对象
        public static VarGameObject Alloc()
        {
            VarGameObject var = GameEntry.Pool.DequeueVarObject<VarGameObject>();
            var.Value = null;
            var.Retain();
            return var;
        }
        //分配一个GameObject对象
        public static VarGameObject Alloc(GameObject value)
        {
            VarGameObject var = Alloc();
            var.Value = value;
            return var;
        }
        public static implicit operator GameObject(VarGameObject value)
        {
            return value.Value;
        }
    }
}


VarInt代码实现


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using YouYou;
namespace Myh
{
    //int变量
    public class VarInt:Variable<int>
    {
        //分配一个对象
        public static VarInt Alloc()
        {
            VarInt var = GameEntry.Pool.DequeueVarObject<VarInt>();
            var.Value = 0;
            var.Retain();
            return var;
        }
        //分配一个对象(value使用传入的int值)
        public static VarInt Alloc(int value)
        {
            VarInt var = Alloc();
            var.Value = value;
            return var;
        }
        //VarInt -> int
        public static implicit operator int(VarInt value)
        {
            return value.Value;
        }
    }
}


VarLong.cs代码实现


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using YouYou;
namespace Myh
{
    //int变量
    public class VarInt:Variable<int>
    {
        //分配一个对象
        public static VarInt Alloc()
        {
            VarInt var = GameEntry.Pool.DequeueVarObject<VarInt>();
            var.Value = 0;
            var.Retain();
            return var;
        }
        //分配一个对象(value使用传入的int值)
        public static VarInt Alloc(int value)
        {
            VarInt var = Alloc();
            var.Value = value;
            return var;
        }
        //VarInt -> int
        public static implicit operator int(VarInt value)
        {
            return value.Value;
        }
    }
}


VarString.cs代码实现


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using YouYou;
namespace Myh
{
    public class VarString : Variable<string>
    {
        //分配一个对象
        public static VarString Alloc()
        {
            VarString var = GameEntry.Pool.DequeueVarObject<VarString>();
            var.Value = string.Empty;
            var.Retain();
            return var;
        }
        //分配一个对象(value使用传入的int值)
        public static VarString Alloc(string value)
        {
            VarString var = Alloc();
            var.Value = value;
            return var;
        }
        //VarString -> string
        public static implicit operator string(VarString value)
        {
            return value.Value;
        }
    }
}


VarTransform.cs代码实现


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using YouYou;
namespace Myh
{
    public class VarTransform : Variable<Transform>
    {
        //分配一个对象
        public static VarTransform Alloc()
        {
            VarTransform var = GameEntry.Pool.DequeueVarObject<VarTransform>();
            var.Value = null;
            var.Retain();
            return var;
        }
        //分配一个对象(value使用传入的float值)
        public static VarTransform Alloc(Transform value)
        {
            VarTransform var = Alloc();
            var.Value = value;
            return var;
        }
        //VarTransform -> Transform
        public static implicit operator Transform(VarTransform value)
        {
            return value.Value;
        }
    }
}


相关文章
|
1月前
|
Java
【专栏】Java反射机制,该机制允许程序在运行时获取类信息、动态创建对象、调用方法和访问属性
【4月更文挑战第27天】本文探讨了Java反射机制,该机制允许程序在运行时获取类信息、动态创建对象、调用方法和访问属性。反射通过Class、Constructor、Method和Field类实现。文中列举了反射的应用场景,如动态创建对象、调用方法、访问属性和处理注解,并提供了相关实例代码演示。
|
1月前
|
存储 安全 Java
Python中的引用和赋值机制允许变量引用内存中的对象,并通过引用计数来管理对象的生命周期
【5月更文挑战第14天】Python中的变量是对象引用,不存储数据,而是在内存中创建对象。赋值操作创建新变量并使其指向已有对象。引用计数用于管理对象生命周期,引用数为0时对象被回收。理解这些机制对编写高效Python代码很重要。
37 6
|
1月前
|
编译器 数据安全/隐私保护 C++
【类与对象】封装&对象的初始化及清理
【类与对象】封装&对象的初始化及清理
|
1月前
|
设计模式 算法 编译器
【C++入门到精通】特殊类的设计 |只能在堆 ( 栈 ) 上创建对象的类 |禁止拷贝和继承的类 [ C++入门 ]
【C++入门到精通】特殊类的设计 |只能在堆 ( 栈 ) 上创建对象的类 |禁止拷贝和继承的类 [ C++入门 ]
22 0
|
1月前
|
前端开发 JavaScript
怎样使用接口引用数据
怎样使用接口引用数据
|
1月前
|
安全 编译器 C++
C++类与对象【对象的初始化和清理】
C++类与对象【对象的初始化和清理】
C++类与对象【对象的初始化和清理】
|
12月前
|
程序员 编译器 数据安全/隐私保护
内存、引用、封装、函数
内存、引用、封装、函数
58 0
|
算法 Java 编译器
如何理解对象赋值给接口的操作(关键在对象!)
如何理解对象赋值给接口的操作(关键在对象!)
如何理解对象赋值给接口的操作(关键在对象!)
|
Java Scala 开发者
对象创建和对象内存布局图|学习笔记
快速学习对象创建和对象内存布局图。
80 0
对象创建和对象内存布局图|学习笔记