JavaScript和Lua兩者分别調用Native OC接口通道,實作這兩個架構的協調工作。
H5+ SDK以插件的實作客戶化的調用Native OC,Lua則可以通過tolua工具實作。
開發H5+ SDK插件
插件名稱:PGPluginTest
PluginTest.h
@interfacePGPluginTest : PGPlugin
- (void)gotoMyGame:(PGMethod*)commands;
+ (void) back2App;
@end
PluginTest.mm
@implementationPGPluginTest
- (void)gotoMyGame:(PGMethod*)commands
{
NSString* cbId = [commands.argumentsobjectAtIndex:0];
// 使用者的參數會在第二個參數傳回
NSString* pArgument1 = [commands.argumentsobjectAtIndex:1];
NSLog(@"gotomygame>>>:%@",pArgument1);
NSString* pResultString = @"success";
// 運作Native代碼結果和預期相同,調用回調通知JS層運作成功并傳回結果
PDRPluginResult *result = [PDRPluginResultresultWithStatus:PDRCommandStatusOKmessageAsString:pResultString];
AppManager* mgr = [AppManagergetInstance];
mgr.gameName = [NSStringstringWithFormat:@"%@%@%@" ,@"games/",pArgument1,@"/src/main.lua" ];
mgr.ccView = [[CocosViewControlleralloc]init];
mgr.h5View = [[mgr.navigationControllerviewControllers]objectAtIndex:0];
[mgr.navigationController pushViewController:mgr.ccView animated:YES];
[self toCallback:cbId withReslut:[result toJSONString]];
}
+ (void) back2App
{
[[AppManager getInstance] releaseCocos];
}
實作C++ tolua
LuaHelper.mm
int LuaHelper::back2App()
{
CCLOG("LuaHelper back2App");
[PGPluginTest back2App];
return 1;
}
GameUtil.h
#ifndef __GAME_UTIL_H_
#define __GAME_UTIL_H_
extern "C" {
#include "lua.h"
#include "tolua++.h"
}
#include "tolua_fix.h"
TOLUA_API int luaopen_GameUtil_luabinding(lua_State* tolua_S);
#endif
GameUtil.cpp
#include "GameUtil.h"
#include "LuaHelper.h"
static void tolua_reg_types (lua_State* tolua_S)
{
tolua_usertype(tolua_S,"LuaHelper");
}
#ifndef TOLUA_DISABLE_tolua_HelperFunc_luabinding_HelperFunc_getFileData00
static int tolua_LuaHelper_luabinding_LuaHelper_back2App00(lua_State* tolua_S)
{
#if COCOS2D_DEBUG >= 1
tolua_Error tolua_err;
if (
!tolua_isusertable(tolua_S,1,"LuaHelper",0,&tolua_err) ||
!tolua_isstring(tolua_S,2,0,&tolua_err) ||
!tolua_isnoobj(tolua_S,3,&tolua_err)
)
goto tolua_lerror;
else
#endif
{
LuaHelper::back2App();
}
return 1;
#if COCOS2D_DEBUG >= 1
tolua_lerror:
tolua_error(tolua_S,"#ferror in function 'back2App'.",&tolua_err);
return 0;
#endif
}
#endif
TOLUA_API int tolua_GameUtil_luabinding_open (lua_State* tolua_S)
{
tolua_open(tolua_S);
tolua_reg_types(tolua_S);
tolua_cclass(tolua_S,"LuaHelper","LuaHelper","",NULL);
tolua_beginmodule(tolua_S,"LuaHelper");
tolua_function(tolua_S,"back2App",tolua_LuaHelper_luabinding_LuaHelper_back2App00);
tolua_endmodule(tolua_S);
return 1;
}
#if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM >=501
TOLUA_API int luaopen_GameUtil_luabinding (lua_State* tolua_S) {
return tolua_GameUtil_luabinding_open(tolua_S);
};
#endif
AppDelegate.mm
quick_module_register方法調用luaopen_GameUtil_luabinding(L)以便于Lua調用C++接口
視窗管理
關系圖如下:
AppManager.h:為了管理整個應用的所有UIWindow和UIController的加載和移除。
static AppManager *instance=nil;
@implementation AppManager
@synthesize gameName;
+ (AppManager*)getInstance{
static dispatch_once_tonceToken ;
dispatch_once(&onceToken, ^{
instance = [[superallocWithZone:NULL]init] ;
}) ;
return instance;
}
+(id) allocWithZone:(struct_NSZone *)zone
{
return [AppManagerinstance] ;
}
-(id) copyWithZone:(struct_NSZone *)zone
{
return [AppManagerinstance] ;
}
//釋放cocos所有變量
- (void)releaseCocos{
cocos2d::CCDirector* director =cocos2d::CCDirector::sharedDirector();
director->end();
[self.ccView.windowresignKeyWindow];
[self.ccView.windowremoveFromSuperview];
self.ccView.window.rootViewController =nil;
self.ccView.window.hidden=YES;
[self.ccView.windowrelease];
[self.navigationControllerpopToViewController:self.h5Viewanimated:YES];
self.ccView.window=nil;
self.ccView=nil;
[self performSelector:@selector(releaseLuaEngine)withObject:nilafterDelay:0.1];
// [self.navigationController.parentViewController makeKeyAndVisible];
}
- (void)releaseLuaEngine{
cocos2d::ScriptEngineManager::getInstance()->destroyInstance();
}
@end