【Cocos2d-x】Lua 资源热更新

【Cocos2d-x】Lua 资源热更新,第1张

概述前面2篇分别简单介绍 手动bind C++ 类和lua;http://blog.csdn.net/chenee543216/article/details/12074771 使用tolua++简化工作:http://blog.csdn.net/chenee543216/article/details/12172563 这篇简单聊聊 cocos2dx。 一、基本概念 所谓的lua绑定,其实目的就是导

前面2篇分别简单介绍

手动bind C++ 类和lua;http://blog.csdn.net/chenee543216/article/details/12074771

使用tolua++简化工作:http://blog.csdn.net/chenee543216/article/details/12172563

这篇简单聊聊 cocos2dx。

一、基本概念

所谓的lua绑定,其实目的就是导出C++的接口给lua,使得在lua中可以 *** 作C++;

而lua和C/C++的唯一官方接口是stack。so,所谓的binding,就是C++,lua双方通过stack交换信息,然后对stack中信息进行解释,并执行相关动作的过程。

1 、

比如lua想生成一个dog 类,则在lua端: local d = Dog:creat(); 这个只是书面形式,其实lua解释器会自动填充stack。

比如,假设这个时候stack内容变成

"creat"

"Dog"

......... -- stack bottom

就是说,lua把2个标志入栈,一个是函数名,一个是类名;

在C/C++端,负责绑定的辅助代码(tolua++生成代码+libtolua++,或者我们第一篇文章中的LuaAnimal类)会根据 “Dog"生成一个类,并且根据某个表(见第一篇文章)去调用这个类中于”create“函数对应的函数。

OK,到这里,lua已经调用C、C++完成,并且生成相应的东西。

下面C/C++会把lua需要的返回值再压入stack。

lua端从stack中取出这个值,保留后面使用。

到这里一个完整过程over。

2、

lua端,再次调用 d:sound();

看官大概已经知道了。lua解释器会把相关信息压入stack,我们可以用第一篇中提供的函数stackDump()来展示stack内容。假设如下:

”sound"

"d"

在C++端,取出类实例地址 d,然后根据sound找对应类函数。比如sound00();然后调用d.sound00();

并且将相关返回值入栈,返回给lua。

3、用完以后gc,大家可以给Dog写个 Dog::~Dog()来看gc信息。

具体过程,给~Dog()下个断点,看C/C++ call stack即可。(我自己偷懒了~)

二、cocos2dx

1、

其实lua和cocos2dx木有啥关系,和cocos2dx sdk发生关系的是tolua++ 生成的C++代码而已。

lua是通过这个中间代码去 *** 作cocos2dx的sdk的。

你实现一个功能,可能要写10几个class,还要调用native code,比如OC、或者java层代码。

但是一旦封装好以后,你使用这个功能只要一个简单调用而已。比如在C++端。我们调用 Money *m = Money::create();

我们最多只要用到几个public的函数,或者变量。并不关心private的函数和变量,和具体实现。

这个和tolua++的pkg文件编写规则一致。

再啰嗦一点:

比如上面Money类,我们只要 create,count 。。。 几个函数。那么tolua++生成的中间C++代码也只引用到这几个函数。

class MMM{

public:

int v00001;

int v00002;

....

int V99999;

voID f00001();

voID f00002()

.....

voID f99999();

};

如果,我们在lua中只要调用v0001;和f00001;那么我们的tolua++的pkg只要包括

class MMM{

int v00001;

voID f00001;

};

即可,大可不必管其它的东西。

2、cocos2dx自己的lua封装,可以到cocos2dx源码目录下面的tools/tolua++去看。

是官方提炼好的pkg,这些pkg最终都被include到Cocos2d.pkg,然后生成一个LuaCocos2d.cpp (见Makefile文件中描述)

这个LuaCocos2d.cpp就是整个cocos2dx中需要被lua使用的接口函数。

二、动手

我们自己写个练手

其实前面都已经写过了:见第二篇文章。唯一不同的是这里新的代码使用到cocos2dx sdk;

如下:

NativeHelper.h

#ifndef __NativeHelper_H__#define __NativeHelper_H__#include "cocos2d.h"USING_NS_CC;class NativeHelper : public cocos2d::cclayer{public:    virtual bool init();    voID openURL(std::string url,bool forceCheck=false);        CREATE_FUNC(NativeHelper);private:    };#endif

NativeHelper.cpp
#ifdef ANDROID#include "NativeHelper.h"#include <jni.h>#include "platform/androID/jni/JniHelper.h"bool NativeHelper::init(){        return true;}voID NativeHelper::openURL(std::string url,bool forceCheck){    JniMethodInfo jmi;  if(JniHelper::getStaticmethodInfo(jmi,"org/cocos2dx/lib/Cocos2dxActivity","openUrl","([Ljava/lang/String;)V")){    jclass str_cls = jmi.env->FindClass("java/lang/String");            Jstring str1 = jmi.env->NewStringUTF(url.c_str());    Jstring str2 = jmi.env->NewStringUTF("nothing ...");        jobjectArray arrs = jmi.env->NewObjectArray(2,str_cls,0);    jmi.env->SetobjectArrayElement(arrs,0,str1);    jmi.env->SetobjectArrayElement(arrs,1,str2);    jmi.env->CallStaticVoIDMethod(jmi.classID,jmi.methodID,arrs);          }}#endif

#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)#include "NativeHelper.h"bool NativeHelper::init(){        return true;}#define kTextFIEldTagOfForumPassword 100//====================================//typedef voID(^AlertBlock)(NSInteger);@interface BlockUIAlertVIEw : UIAlertVIEw{    Nsstring *url;}//@property(nonatomic,copy)AlertBlock block;@property(nonatomic,copy)Nsstring *url;- (ID)initWithTitle:(Nsstring *)Title            message:(Nsstring *)message  cancelbuttonTitle:(Nsstring *)cancelbuttonTitle//        clickbutton:(AlertBlock)_block  otherbuttonTitles:(Nsstring *)otherbuttonTitles;//-(voID)setURL:(Nsstring*)url;@end@implementation BlockUIAlertVIEw//@synthesize block;@synthesize url;- (ID)initWithTitle:(Nsstring *)Title            message:(Nsstring *)message  cancelbuttonTitle:(Nsstring *)cancelbuttonTitle//        clickbutton:(AlertBlock)_block  otherbuttonTitles:(Nsstring *)otherbuttonTitles {        self = [super initWithTitle:Title message:message delegate:self cancelbuttonTitle:cancelbuttonTitle otherbuttonTitles:otherbuttonTitles,nil];        //    if (self) {    //        self.block = _block;    //    }        return self;}- (voID)alertVIEw:(UIAlertVIEw *)alertVIEw clickedbuttonAtIndex:(NSInteger)buttonIndex {    //    self.block(buttonIndex);        if (buttonIndex == 1) {        cclOG("------------button canceled");        return;    }        UITextFIEld *pwdTextFIEld = (UITextFIEld *)[alertVIEw vIEwWithTag:kTextFIEldTagOfForumPassword];    Nsstring *pwd = [pwdTextFIEld.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];    cclOG("--------------%s",[pwd UTF8String]);        if ([pwd caseInsensitiveCompare:@"iamadult"] == NSOrderedSame) {        if ([url length]>[@"http://www.1.com" length]) {            [[UIApplication sharedApplication]openURL:[NSURL URLWithString:url]];        }    }    }@end//====================================voID NativeHelper::openURL(std::string url,bool forceCheck){    if (!forceCheck) {        Nsstring * nsurl = [Nsstring stringWithCString:url.c_str()                                              enCoding:[Nsstring defaultCStringEnCoding]];                [[UIApplication sharedApplication]openURL:[NSURL URLWithString:nsurl]];                return;    }        BlockUIAlertVIEw *alertVIEw = [[BlockUIAlertVIEw alloc]                                   initWithTitle:@"请输入字符: iamadult"                                   message:@"\n\n"                                   cancelbuttonTitle:@"确认"                                   //                                   clickbutton:^(NSInteger indexbutton){                                   //        if (indexbutton == 0) {                                   //            cclOG("You press btn 0");                                   //        }else if(indexbutton == 1){                                   //            cclOG("You press btn 1");                                   //        }                                   //    }                                   otherbuttonTitles:@"取消"];            [alertVIEw setUrl:[Nsstring stringWithCString:url.c_str()                                         enCoding:[Nsstring defaultCStringEnCoding]]];        UITextFIEld *textFIEldPwd = [[UITextFIEld alloc] initWithFrame:CGRectMake(27.0,60.0,230.0,25.0)];    [textFIEldPwd setBackgroundcolor:[UIcolor whitecolor]];    [textFIEldPwd setTag:kTextFIEldTagOfForumPassword];    [textFIEldPwd setPlaceholder:@"请输入密码"];    [alertVIEw addSubvIEw:textFIEldPwd];    [textFIEldPwd release];        [alertVIEw show];    [alertVIEw release];    }#endif

这3个文件实现一个NativeHelper类,这个类只干一件事:调用系统web浏览器打开一个URL。通过宏定义来控制androID和ios的独立实现。(ios端和androID端的区别是:ios端打开URL之前会d出一个对话框,让用户输入验证字符。 just for parent protect )

我们调用方式简单如下:

NativeHelper *nhelper = NativeHelper::create();        const std::string strPrivacy = "http://http://blog.csdn.net/chenee543216/article/details/12172563";        nhelper->openURL(strPrivacy,true);

现在,我们把调用需要的2个函数用tolua++导出给lua,there are create() and openURL()

toluaNativeHelper.pkg

12 $#include "cocos2d.h"  3 $#include "NativeHelper.h"                                                                                             4 class NativeHelper : public cocos2d::cclayer  5 {  6     voID openURL(std::string url,bool forceCheck=false);  7     static NativeHelper* create();  8 };  9

生成的命令为: tolua++ -o toluaNativeHelper.cpp toluaNativeHelper.pkg 生成如下cpp文件。
/*** Lua binding: toluaNavIEHelper** Generated automatically by tolua++-1.0.92 on Mon Sep 30 16:21:12 2013.*/#ifndef __cplusplus#include "stdlib.h"#endif#include "string.h"#include "tolua++.h"/* Exported function */TolUA_API int  tolua_toluaNavIEHelper_open (lua_State* tolua_S);#include "cocos2d.h"#include "NativeHelper.h"/* function to register type */static voID tolua_reg_types (lua_State* tolua_S){ tolua_usertype(tolua_S,"NativeHelper"); tolua_usertype(tolua_S,"cocos2d::cclayer");}/* method: openURL of class  NativeHelper */#ifndef TolUA_disABLE_tolua_toluaNavIEHelper_NativeHelper_openURL00static int tolua_toluaNavIEHelper_NativeHelper_openURL00(lua_State* tolua_S){#ifndef TolUA_RELEASE tolua_Error tolua_err; if (     !tolua_isusertype(tolua_S,"NativeHelper",&tolua_err) ||     !tolua_iscppstring(tolua_S,2,&tolua_err) ||     !tolua_isboolean(tolua_S,3,&tolua_err) ||     !tolua_isnoobj(tolua_S,4,&tolua_err) )  goto tolua_lerror; else#endif {  NativeHelper* self = (NativeHelper*)  tolua_tousertype(tolua_S,0);  std::string url = ((std::string)  tolua_tocppstring(tolua_S,0));  bool forceCheck = ((bool)  tolua_toboolean(tolua_S,false));#ifndef TolUA_RELEASE  if (!self) tolua_error(tolua_S,"invalID 'self' in function 'openURL'",NulL);#endif  {   self->openURL(url,forceCheck);  } } return 0;#ifndef TolUA_RELEASE tolua_lerror: tolua_error(tolua_S,"#ferror in function 'openURL'.",&tolua_err); return 0;#endif}#endif //#ifndef TolUA_disABLE/* method: create of class  NativeHelper */#ifndef TolUA_disABLE_tolua_toluaNavIEHelper_NativeHelper_create00static int tolua_toluaNavIEHelper_NativeHelper_create00(lua_State* tolua_S){#ifndef TolUA_RELEASE tolua_Error tolua_err; if (     !tolua_isusertable(tolua_S,&tolua_err) )  goto tolua_lerror; else#endif {  {   NativeHelper* tolua_ret = (NativeHelper*)  NativeHelper::create();    tolua_pushusertype(tolua_S,(voID*)tolua_ret,"NativeHelper");  } } return 1;#ifndef TolUA_RELEASE tolua_lerror: tolua_error(tolua_S,"#ferror in function 'create'.",&tolua_err); return 0;#endif}#endif //#ifndef TolUA_disABLE/* Open function */TolUA_API int tolua_toluaNavIEHelper_open (lua_State* tolua_S){ tolua_open(tolua_S); tolua_reg_types(tolua_S); tolua_module(tolua_S,NulL,0); tolua_beginmodule(tolua_S,NulL);  tolua_cclass(tolua_S,"cocos2d::cclayer",NulL);  tolua_beginmodule(tolua_S,"NativeHelper");   tolua_function(tolua_S,"openURL",tolua_toluaNavIEHelper_NativeHelper_openURL00);   tolua_function(tolua_S,"create",tolua_toluaNavIEHelper_NativeHelper_create00);  tolua_endmodule(tolua_S); tolua_endmodule(tolua_S); return 1;}#if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM >= 501 TolUA_API int luaopen_toluaNavIEHelper (lua_State* tolua_S) { return tolua_toluaNavIEHelper_open(tolua_S);};#endif

自己添加到cocos2dx工程的class目录即可。

然后在

AppDelegate.cpp 中加入

文件开始部位:

extern int tolua_toluaNavIEHelper_open ( lua_State * tolua_S);


调用lua环境初始化之后

ccluaEngine * pEngine = ccluaEngine :: defaultEngine ();

ccScriptEngineManager :: sharedManager ()-> setScriptEngine (pEngine);

tolua_toluaNavIEHelper_open (pEngine-> getLuaStack ()-> getLuaState ());


ok;

现在你只要在lua文件中直接调用NativeHelper相关即可。如下

local nativehelper = NativeHelper:create()

nativehelper:openURL("http://www.sina.com",true)

写那那么多,也不知道说清楚了没有,有问题留言吧。

有错误,也欢迎留言指点。

参考:

http://blog.csdn.net/chenee543216/article/details/12172563

http://blog.csdn.net/chenee543216/article/details/12074771

http://www.himigame.com/lua-game/1259.HTML

http://blog.csdn.net/musicvs/article/details/8166655

tolua++官网各种文档

lua官网各种文档

总结

以上是内存溢出为你收集整理的【Cocos2d-x】Lua 资源热更新全部内容,希望文章能够帮你解决【Cocos2d-x】Lua 资源热更新所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1026301.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-23
下一篇 2022-05-23

发表评论

登录后才能评论

评论列表(0条)

保存