Scaleform结合C++编程
几个月前公司准备将我们的UI系统从CEGUI换到Scaleform上,因此我也积累了些Scaleform结合C++编程的经验,在这里简单记录一下。
Scaleform实现了用硬件加速渲染flash的功能,利用flash的强大功能可以使游戏的界面看起来更酷炫一些。对于程序员来说,我最关心的就是Scaleform如何跟C/C++通讯。
从编程角度来讲Scalefrom和C/C++通讯还是比较简单的,其实就是C/C++和ActionScript的通讯。Scaleform已经提供了一些简便的接口让我们来使用。在AS中可以用fscommand或者ExternalInterface发出一个事件,这个事件包含了一个字符串和参数。字符串表示事件的名字,其实就是被调用C函数的名字,参数可以是多个。当Scaleform收到这样的事件后会通过callback的方式通知C/C++,在这个callback里包含了AS发出的字符串和参数。我们可以在这个callback里根据字符串调用相应的C函数。因此注册一个C函数给AS用,其实就是将函数名和函数地址存储在一个map里,等到收到Scaleform的通知(callback)时再查询map找到对应的C函数地址,然后调用之。这里跟C和lua的通讯不一样,lua是自身管理注册的C函数。
因此我为我们的UI管理模块设计的二个接口如下:
void RegsiterASFunc(const char* szFuncName, AS_FUNCTION pFunc);
void CallASFunc(const char* szFuncName,Variant* pRetValue);
这里的AS_FUNCTION是一个函数类型,用于给AS调用的C函数原型,声明如下:
typedef void (*AS_FUNCTION)(as_State*)
其中的as_State是我模仿着Lua的lua_State来处理C++和AS之间函数调用时参数传递问题的。其定义如下:
structas_State{
Variant* pArgs;
Int nArgs;
Variant Return;
}
其中的pArgs代表C函数的所需的参数列表,即AS传出来的参数,nArgs表示参数个数。和Lua一样你无法保证参数的正确性。Return表示C函数的返回值,用于返回给AS用。可以调用GFxMovieView对象的SetExternalInterfaceRetVal来通知AS这个返回值。Variant是封装不同原始类型为同一个对象,其实就是一个union,不懂的同学可以google。CallASFunc用于调用一个AS函数,pRetValue用于接收这个AS函数的返回值,内部是调用GFxMovieView的InvokeArgs来调用AS函数。
这里还有一个要注意的问题,以往我们在C里调用Lua函数往往是全局的lua函数,但是在flash里一个函数是属于某个影片的,即一个swf文件的。因此调用一个AS函数需要指明是那个swf文件中的,Scaleform用GFxMovieView来表示一个正在播放的影片,对AS的调用也是通过GFxMovieView的方法来实现的。