-
Notifications
You must be signed in to change notification settings - Fork 26
grammar
支持所有C基础数据类型
char, bool, byte, short, ushort, wchar, int, uint, float, int64, uint64, double
支持所有C操作符
++, --, +, -, *, /, %, ?, (), =, +=, -=, *=, /=, >>, <<, >>=, <<=, >, <, ==, >=, <=, &&, ||, &, |, ^, !, ~, ->, . ,
对于int数据类型,操作符运算有额外的优化,运算效率最高,建议尽量使用int数据类型
可表示自定义类的类型或跨平台导入类的类型
FCType类接口FCType nType = typeof(CTest)
通用的class指针,可指向自定义的或外部导入的类
FCObject类接口跨平台的指针,可以将脚本的字符串对象,或数组的数据转换成IntPtr, 传递给宿主语言,用于高效的数据传输
StringA utf8编码的字符串
StringW utf16编码的字符串
StringA 与 StringW 可以相互赋值
字符串类接口数组不分动态与固定,都是动态数据,不管是new出来的, 都是数组对象,都可以调用数组的接口方法
初始化方法一
char []array = new char[100];
初始化方法二
List <char> array = new List <char>();
初始化方法三
int []array = {1, 2, 3, 5, 8, 9};
数组的显式释放
array = NULL;
List模板接口List不支持List或map的嵌套
map <key, value>
map模板接口map不支持List或map的嵌套
list, map为什么不支持嵌套,主要是为了性能,也是为了简化VM的代码
系统函数接口 序列化接口语法与C, C++, C#语法完全一致
if(exp){}
if(exp1) exp2;
if(exp1) ...
else if(exp2) ...
else ...
例:
if(n1 + 3 < n2) n1 += 5;
if((n1 + 3 < n2) && (n2 > 8)) { n1 += 5; n2 += 3;}
if(n1 > 50) n2 = 1;
else if(n1 > 40) n2 = 2;
else n2 = 3;
语法与C, C++, C#语法完全一致
for( ;exp; ) exp2;
简单的自增或自减的for循环有特殊的优化,性能更优
for(int i = 0; i<count; ++i) exp2
for(int i = size; i>min; --i) exp2
语法与C, C++, C#语法完全一致
while(exp){...}
语法与C, C++, C#语法完全一致
do{exp}while(exp2);
支持整数,UTF8字符串,区段;
整数的switch, 与C, C++, C#语法一致;
字符串的switch, 与C#语法一致;
switch(str)
{
case "a1":
return 1;
case "a2":
return 2;
case "a3":
return 3;
default:
break;
}
区段switch是这里独创的,语法示例如下:
switch(n1)
{
case [0, 100): // 如果 n1 >= 0 && n1 < 100
return 1;
case [150, 200): // 如果 n1 >= 150 && n1 < 200
return 2;
case [350, 400): // 如果 n1 >= 350 && n1 < 400
return 3;
default:
break;
}
语法与C, C++, C#语法完全一致, 可以返回基础数据类型,自定义数据类型(class), 数组, map对象
例: this.m_value = 1; 或 this->m_value = 1;
this.func(...); 或 this->func(...);
做参数传递, 如:func(this, p1);
支持,语法与C++, C#语法完全一致
特性:
单继承与多继承 -- 支持
虚函数(多态) -- 支持
运行时转换 -- 支持
权限控制(public,private) -- 可支持, 目前全为public
属性方法(get,set) -- 可支持, 目前暂不支持
类成员变量支持定义时初始化,但只支持常数,这个初始化更高效。如:
class CTest
{
int m_nValue = 10;
};
支持
Delegate
{
public Delegate(AnyType obj, funcname(param1, param2, param3...)); // func_name 是 AnyType的成员函数
public Delegate(AnyType obj, funcname, param1, param2, param3...);
public void Call(); // 调用委托的方法
public void SetParam(int nIndex, AnyType param); // 修改委托函数的第N个参数
}
创建方式
Delegate ptr = new Delegate(obj, func_name(param1, param2, param3, ...)); // 方式1
Delegate ptr = new Delegate(obj, func_name, param1, param2, param3, ...); // 方式2
ptr.Call(); // 启动委托函数的调用
不支持严格意义上的反射,但支持Serialize类序列化一个类, 这个主要用于网络消息传输。
说明:这个序列化不支持版本兼容,是一个二进制流的有序读写,所以不要用这个来做持久化。
当然了,你也可以自己负责版本兼容的代码。
目前对XML的读取是比较友好的,只需要一行代码,就可以将XML读取对应的数据结构中。
扩展了XML的功能,比C#都还要好用,真的,你用了就会喜欢它的。
扩展特性:
支持List的读写,支持自定义的class类型的List
支持map的读写,支持自定义的class类型的map
数组使用 value 关键字读取属性
map使用 key, value 关键字读取key与value
只需要在自定义的类成员变量前面添加[XmlElementAttribute]标签就可以了
XML代码与配置示例支持Json的读写,接口在os类中
public static bool ReadJson<_Ty>(_Ty pJsonRoot, StringA szJson)
public static StringA WriteJson<_Ty>(_Ty pJsonRoot)
例:
bool bSuc = os.ReadJson(msg, szJson);
支持C++关键字inline, 标记inline的函数,调用时会内嵌到调用处,可以省去函数调用的开销,是优化的神器
好处:减少函数调用开销,提升性能
坏处:会增加代码长度,字节码变大
当然了,如果函数很简单,增加的长度可以忽略不计。
构造函数不支持 inline
递归函数,调用深度超过6层,就执行普通调用,不再内联, 所以递归就不要使用inline了。
在类外声明的,目前都是全局变量,支持跨文件访问。
不需要static声明。
与C, C++语法一致, 但比C++灵活。为什么?因为可以不分顺序,可以乱序啊。
示例:
typedef int64 long
typedef map<int, CStringA> ID2Name;
typedef StringA CStringA; // CStringA 这个在ID2Name后声明
typedef map<int, ID2Name> IDArray; // 这个是错误的声明,因为目前map的key, value不支持模板
class A{ ID2Name id2Name;};
typedef map<int, A> IDArray;// 这个是合法的
支持全局的 enum 与类内 enum, enum 的语法与C#一致
示例:
enum NUMB_VALUE{ NUMB1 = 1, NUMB2, NUMB3 = NUMB1 + 10, NUMB4};
int n1 = NUMB_VALUE.NUMB1;
class CTest
{
enum { NUMB1, NUMB2, NUMB3 };
};
const 常量可以是类外声明,也可以是类内声明
支持const常量,支持 const常量的运算, const常量的引用不分顺序,可以是乱序的
class CTest
{
const int NUMB_MAX = NUMB1;
};
const int NUMB1 = NUMB2 + 10;
const int NUMB2 = NUMB3 + 10;
const int NUMB3 = 100;
const StringA TEST_STR1 = TEST_STR2 + "ABC"; // 编译时合并成一个字符串 "CC_ABC"
const StringA TEST_STR2 = "CC_";
const 字段会有额外的编译优化,请尽量使用
仅C基础数据类型支持强转, 大部分情况并不需要强制转换, 因为数据类型都是自动转换的
int64 i = 999999999999;
int k = (int)i + 10; // 等价于 int k = i + 10;
StringA str = (StringA)i + "__test"; // 等价于 str = i + "__test";
尽量不要强制转换,这有可能会导致额外的指令, 从而降低性能
注意:强制转换使用(), 并不是staic_cast
支持以下图形对象
Vector2, Vector3, Vector4, Plane, Matrix, BoundBox, Ray, Bounds, Sphere, IntRect, Rect, Color, Color32, Bezier2D, Bezier3D, Quaternion
接口文档因为与C#中IEnumerator名字冲突,也可以用FCEnumerator来替代
class IEnumerator // 这个类似于Delegate
{
// 功能:启动协程
public void Start();
// 功能:停止协程;
public void Stop();
// 功能:唤醒wait的协程
public void Wakeup();
以下是兼容C#的接口,因为C#不能有全局函数
public static FCEnumerator StartCoroutine(Object obj, param Object []params);
public static FCEnumerator StartCoroutine(FCEnumerator ins);
public static FCEnumerator StopCoroutine(FCEnumerator ins);
按函数名停止协程,szFuncName必须是字符串常量
public static FCEnumerator StopCoroutine(StringA szFuncName);
按类名与成员函数名停止协程,szClassName, szFuncName必须是字符串常量
public static FCEnumerator StopCoroutine(StringA szClassName, StringA szFuncName);
public static FCEnumerator StopAllCoroutine();
};
协程对象是IEnumerator, 基本功能与API与c#基本一样
协程启动接口StartCoroutine
IEnumerator StartCoroutine(obj, 函数名称(参数1, 参数2, 参数3, ..., 参数N));
启动一个协程方式1:
IEnumerator coroutine = new IEnumerator(target, 函数名称(参数1, 参数2, 参数3, ..., 参数N));
coroutine.Start();
启动一个协程方式2:
IEnumerator coroutine = StartCoroutine(target, 函数名称(参数1, 参数2, 参数3, ..., 参数N));
停止一个协程:
方法1:通过IEnumerator参数停止
StopCoroutine(coroutine);
方法2:通过成员函数名字停止
如果当前函数不是类的成员函数,就按全局函数名搜索
StopCoroutine(函数名);
方法3:通过类名 + 函数名的方式
如果指定类名,不存在,就默认是全局函数
StopCoroutine(类名, 类成员函数名);
停止所有的协程
StopAllCoroutine();
支持awit异步接口,语法参考C#的await
Unity中的导出插件会自动生成带Task返回值的wrap接口
如下接口:
public static Task LoadResource(string szName)
其他平台需要调用脚本的接口,需要先将脚本内的类名或函数名添加export或internal标记
例:
export void main()
{
}
export class TestA
{
export void Func()
{
}
void HideFunc() // 这个没有export导出,不可以在其他平台调用
{
}
}
详细调用参考Demo
目前已经实现的功能有:
(1), 远程调试(可以调试真机代码)
(2), 支持单步调试
(3), 支持条件断点(暂未实现)
(4), 支持运行时修改变量,内存数据
(5), 支持断住后,代码跳转的功能,可以在当前函数内任意位置跳转,像VC++调试器一样
(6), 可以运行时切换调试与非调试的功能,优化性能。
(7), 支持局部变量,全局变量,this成员变量的控制台显示与修改
案例代码你可以对全局函数或类的成员函数添加一个标签[Boardcast]
格式如:[Boardcast("GroupName",Level)]
GroupName是函数的分组的名字,Level是调用的先后顺序
如:[Boardcast("OnEnterGame",1000)]
利用这个功能,可以将不同模块的代码解耦,各个模块不需要互相引用
只需要调用System.Broadcast(分组名,参数1,参数2,...),就可以实现模块之间的通信
最大的好外,上层不需要再使用一个管理器去转发事件通知,也不需要维护这些对象的生命周期
返回主页