unity里c# gc优化 -字符串

1使用unsafe,直接修改字符串

public static class UnsafeString
{
    public static unsafe void Copy(this string str, LuaString luastr)
    {
        if (luastr.ptr == IntPtr.Zero)
            Clear( str );
        fixed (char* pstr = str)
        {
            var dest = (char*)luastr.ptr.ToPointer();
            var len = luastr.len;
            for (int i = 0; i < len; i++)
                *(pstr + i) = *(dest + i);
            *(pstr + len) = '\0';
            int* strlen = (int*)pstr - 1;
            *strlen = len;
        }
    }

    public static unsafe void Clear(this string str)
    {
        fixed (char* ptr = str)
        {
            int* iptr = (int*)ptr - 1;
            *iptr = 0;
        }
    }
}

修改text部分

 if (txt.text.Length * 2 >= _str.len)//c#是ucs2编码,一个字符是2个字节
                {
                    txt.text.Copy(_str);
                    txt.cachedTextGenerator.Invalidate();
                    txt.SetVerticesDirty();
                }
                else
                    txt.text = _str.ToString();

但是有个坑,lua是utf8编码,而c#里是ucs2b编码,所以需要做个转换,明天补上

需要2个方法,一个是获取utf8编码个数

  public unsafe int ulen()
    {
        if (len <= 0) return 0;
        if (utf8len > 0) return utf8len;
        var str = (byte*)(strdata().ToPointer());
        int n = 0;
        for (int i = 0; i < len; i++)
        {
            var c = str[i];
            //short c = (short) s;
            i += c >= 0xfc ? 5 : (c >= 0xf8 ? 4 : (c >= 0xf0 ? 3 : (c >= 0xe0 ? 2 : (c >= 0xc0 ? 1 : 0))));
            n++;
        }
        utf8len = n;
        return utf8len;
    }

一个是从utf8转到unicode(utf16)

public static unsafe void CopyAnsi(this string str, LuaString luastr)
    {
        if (luastr.ptr == IntPtr.Zero)
            Clear(str);
        fixed (char* pstr = str)
        {
            var dest = (byte*)luastr.strdata().ToPointer();
            var len = luastr.len;
            var pstrn = 0;
            int oldlen = *((int*)pstr - 1);
            for (int i = 0; i < len; i++)
            {
                var c = *(dest + i);
                if (c >= 0xfc)
                {

                }
                else if (c >= 0xf8)
                {

                }
                else if (c >= 0xf0)
                {

                }
                else if (c >= 0xe0)
                {
                    var c1 = * (dest + i + 1);
                    var c2 = * (dest + i + 2);
                    *(pstr + pstrn) = (char)(((c & 0x1f) << 12) + ((c1 & 0x3f) << 6)+ (c2 & 0x3f));
                    i += 2;
                }
                else if (c >= 0xc0)
                {
                    var c1 = *(dest + i + 1);
                    *(pstr + pstrn) = (char)(((c & 0x3c) << 6) + (c1 & 0x3f));
                    i++;
                }
                else
                {
                   * (pstr + pstrn) = (char)c;
                }
                pstrn++;
            }
            //*(pstr + pstrn) = (byte)0;
            int* strlen = (int*)pstr - 1;
            *strlen = pstrn;
        }
    }

修改text部分

 set {
            if(!(c is Text) && !(c is InputField)) Log.Assert((c is Text), "the component name {0} is not a Text or InputField", c.name);
            if (c is Text)
            {
                if (_str.ptr == value.str.ptr) return;
                unrefString(_str);
                _str = value.str;
                var txt = (c as Text);
                if (txt.text.Length >= _str.ulen())
                {
                    //txt.text.Copy(_str);
                    txt.text.CopyAnsi(_str);
                    txt.cachedTextGenerator.Invalidate();
                    txt.SetVerticesDirty();
                }
                else
                    txt.text = _str.ToString();
                refString(_str);
                
            }
            if (c is InputField) (c as InputField).text = (string)value;
        }

 

posted on 2018-09-04 22:02  marcher  阅读(416)  评论(0编辑  收藏  举报

导航