转让lua性能executeGlobalFunction

没有其他的,搞搞cocos2dx的lua文字,话lua这件事情在几年前学过一段时间。还曾对自己c++介面,我已经做了一些小东西。只是时间的流逝,模糊记忆。

拿起点功夫和成本。下面是我的一些经验。

cocos2dx运用tolua++来制作的lua接口,tolua++文档不多,网上的一些文章也是答非所问,所以自己看代码是最佳学习途径。

cocos2dx操作lua的类是CCLuaEngine,当中实现了载入与实行lua脚本。以及操作lua stack。

LuaCocos2d.cpp非常主要,文件的开头凝视也说明其是由tolua++自己主动生成的,我们想在lua中操作自定义的类就是通过改动此文件实现的,两个重要函数是void tolua_reg_types (lua_State* tolua_S)与int tolua_Cocos2d_open (lua_State* tolua_S),前者是注冊自定义类型,后者是定义其接口,调用关系是tolua_Cocos2d_open调用tolua_reg_types,而tolua_Cocos2d_open是在CCLuaEngine的init中调用的。

如果我要向lua注冊新类。那么首先我要在tolua_reg_types中加入一行注冊代码,然后在tolua_Cocos2d_open加入其接口说明。我将这两个步骤定义成两个函数,单独在一个文件里实现。文件名称为cwLuaReg.cpp,内容为:

#include "cwLuaReg.h"

#include "cwGameObject.h"

#include "cwCollisionObject.h"

#include "cwGravityObject.h"

#ifdef __cplusplus

static int tolua_collect_cwGameObject(lua_State* tolua_S)

{

cwGameObject* self = (cwGameObject*) tolua_tousertype(tolua_S,1,0);

delete self;

return 0;

}

static int tolua_collect_cwGravityObject(lua_State* tolua_S)

{

cwGravityObject* self = (cwGravityObject*) tolua_tousertype(tolua_S,1,0);

delete self;

return 0;

}

#ifndef TOLUA_DISABLE_tolua_cw_GameObject_create00

static int tolua_cw_GameObject_create00(lua_State* tolua_S)

{

tolua_Error tolua_err;

if(!tolua_isusertable(tolua_S,1,"cwGameObject",0,&tolua_err) ||

!tolua_isnoobj(tolua_S,2,&tolua_err))

goto tolua_lerror;

else

{

{

cwGameObject* tolua_ret = (cwGameObject*)  cwGameObject::create();

int nID = (tolua_ret) ? (int)tolua_ret->m_uID : -1;

int* pLuaID = (tolua_ret) ?

&tolua_ret->m_nLuaID : NULL;

toluafix_pushusertype_ccobject(tolua_S, nID, pLuaID, (void*)tolua_ret,"cwGameObject");

}

}

return 1;

tolua_lerror:

return 0;

}

#endif //#ifndef TOLUA_DISABLE

#ifndef TOLUA_DISABLE_tolua_cw_GameObject_getSpeed00

static int tolua_cw_GameObject_getSpeed00(lua_State* tolua_S)

{

#ifndef TOLUA_RELEASE

tolua_Error tolua_err;

if (!tolua_isusertype(tolua_S,1,"cwGameObject",0,&tolua_err) ||

!tolua_isnoobj(tolua_S,2,&tolua_err))

goto tolua_lerror;

else

#endif

{

cwGameObject* self = (cwGameObject*)  tolua_tousertype(tolua_S,1,0);

#ifndef TOLUA_RELEASE

if (!self) tolua_error(tolua_S,"invalid ‘self‘ in function ‘speed‘", NULL);

#endif

{

float tolua_ret = (float)  self->speed();

tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);

}

}

return 1;

#ifndef TOLUA_RELEASE

tolua_lerror:

tolua_error(tolua_S,"#ferror in function ‘speed‘.",&tolua_err);

return 0;

#endif

}

#endif

#ifndef TOLUA_DISABLE_tolua_cw_GameObject_setSpeed00

static int tolua_cw_GameObject_setSpeed00(lua_State* tolua_S)

{

#ifndef TOLUA_RELEASE

tolua_Error tolua_err;

if (!tolua_isusertype(tolua_S,1,"cwGameObject",0,&tolua_err) ||

!tolua_isnumber(tolua_S,2,0,&tolua_err) ||

!tolua_isnoobj(tolua_S,3,&tolua_err))

goto tolua_lerror;

else

#endif

{

cwGameObject* self = (cwGameObject*)  tolua_tousertype(tolua_S,1,0);

float speed = ((float)  tolua_tonumber(tolua_S,2,0));

#ifndef TOLUA_RELEASE

if (!self) tolua_error(tolua_S,"invalid ‘self‘ in function ‘setSpeed‘", NULL);

#endif

{

self->setSpeed(speed);

}

}

return 0;

#ifndef TOLUA_RELEASE

tolua_lerror:

tolua_error(tolua_S,"#ferror in function ‘setSpeed‘.",&tolua_err);

return 0;

#endif

}

#endif

#ifndef TOLUA_DISABLE_tolua_cw_GameObject_getMoveDir00

static int tolua_cw_GameObject_getMoveDir00(lua_State* tolua_S)

{

#ifndef TOLUA_RELEASE

tolua_Error tolua_err;

if (!tolua_isusertype(tolua_S,1,"cwGameObject",0,&tolua_err) ||

!tolua_isnoobj(tolua_S,2,&tolua_err))

goto tolua_lerror;

else

#endif

{

cwGameObject* self = (cwGameObject*)  tolua_tousertype(tolua_S,1,0);

#ifndef TOLUA_RELEASE

if (!self) tolua_error(tolua_S,"invalid ‘self‘ in function ‘getMoveDir‘", NULL);

#endif

cwVector2D& dir = self->moveDir();

tolua_pushnumber(tolua_S,(lua_Number)dir.x);

tolua_pushnumber(tolua_S,(lua_Number)dir.y);

}

return 2;

#ifndef TOLUA_RELEASE

tolua_lerror:

tolua_error(tolua_S,"#ferror in function ‘getMoveDir‘.",&tolua_err);

return 0;

#endif

}

#endif

#ifndef TOLUA_DISABLE_tolua_cw_GameObject_setMoveDir00

static int tolua_cw_GameObject_setMoveDir00(lua_State* tolua_S)

{

#ifndef TOLUA_RELEASE

tolua_Error tolua_err;

if (!tolua_isusertype(tolua_S,1,"cwGameObject",0,&tolua_err) ||

!tolua_isnumber(tolua_S,2,0,&tolua_err) ||

!tolua_isnumber(tolua_S,3,0,&tolua_err) ||

!tolua_isnoobj(tolua_S,4,&tolua_err))

goto tolua_lerror;

else

#endif

{

cwGameObject* self = (cwGameObject*)  tolua_tousertype(tolua_S,1,0);

float dirX = ((float)  tolua_tonumber(tolua_S,2,0));

float dirY = ((float)  tolua_tonumber(tolua_S,3,0));

#ifndef TOLUA_RELEASE

if (!self) tolua_error(tolua_S,"invalid ‘self‘ in function ‘setMoveDir‘", NULL);

#endif

self->setMoveDir(dirX, dirY);

}

return 0;

#ifndef TOLUA_RELEASE

tolua_lerror:

tolua_error(tolua_S,"#ferror in function ‘getMoveDir‘.",&tolua_err);

return 0;

#endif

}

#endif

#endif

TOLUA_API int tolua_cwLua_reg_types(lua_State* tolua_S)

{

//add by sunny

tolua_usertype(tolua_S,"cwGameObject");

tolua_usertype(tolua_S,"cwGravityObject");

//end sunny

return 1;

}

TOLUA_API int tolua_cwLua_reg(lua_State* tolua_S)

{

#ifdef __cplusplus

tolua_cclass(tolua_S,"cwGameObject","cwGameObject","CCSprite",tolua_collect_cwGameObject);

#else

tolua_cclass(tolua_S,"cwGameObject","cwGameObject","CCSprite",NULL);

#endif

tolua_beginmodule(tolua_S,"cwGameObject");

tolua_function(tolua_S,"create",tolua_cw_GameObject_create00);

tolua_function(tolua_S,"speed",tolua_cw_GameObject_getSpeed00);

tolua_function(tolua_S,"setSpeed",tolua_cw_GameObject_setSpeed00);

tolua_function(tolua_S,"moveDir",tolua_cw_GameObject_getMoveDir00);

tolua_function(tolua_S,"setMoveDir",tolua_cw_GameObject_setMoveDir00);

tolua_endmodule(tolua_S);

#ifdef __cplusplus

tolua_cclass(tolua_S,"cwGravityObject","cwGravityObject","cwGameObject",tolua_collect_cwGravityObject);

#else

tolua_cclass(tolua_S,"cwGravityObject","cwGravityObject","cwGameObject",NULL);

#endif

tolua_beginmodule(tolua_S,"cwGravityObject");

tolua_endmodule(tolua_S);

return 1;

}

将tolua_cwLua_reg_types和tolua_cwLua_reg分别加到LuaCocos2d.cpp相应函数末尾。这样两个类cwGameObject与cwGravityObject就能够在lua中使用了。

做到这还不能达到我的期望,原因是cocos2d的luaproject里。在AppDelegate::applicationDidFinishLaunching函数中仅仅是载入并运行了hello.lua脚本文件。然后一切就都交给lua了,而我仅仅是想使用lua实现一些AI方面的功能,即cwGameObject在须要运行AI时。调用lua中的一个函数。所以我须要的是一个能够调用lua函数的功能,查看了一下CCLuaEngine类。貌似没有我想要的。仅仅能自己添了个函数:

virtual int executeGlobalFunction(const char* functionName, float dt, CCObject* pObject, const char* typeName);

functionName:被调lua函数名;dt:帧时间间隔。pObject:调用lua的对象;typeName:pObject对象类型

实现例如以下:

int CCLuaEngine::executeGlobalFunction(const char* functionName, float dt, CCObject* pObject, const char* typeName)

{

lua_getglobal(m_state, functionName);

if (!lua_isfunction(m_state, -1))

{

CCLOG("[LUA ERROR] name ‘%s‘ does not represent a Lua function", functionName);

lua_pop(m_state, 1);

return 0;

}

pushFloat(dt);

pushCCObject(pObject, typeName);

int error = lua_pcall(m_state, 2, 1, 0);

if (error)

{

CCLOG("[LUA ERROR] %s", lua_tostring(m_state, - 1));

lua_pop(m_state, 1); // clean error message

return 0;

}

// get return value

if (!lua_isnumber(m_state, -1))

{

lua_pop(m_state, 1);

return 0;

}

int ret = lua_tointeger(m_state, -1);

lua_pop(m_state, 1);

return ret;

}

基本上是照着其它函数扒下来的,不同之处就是加了两个push。

函数写的比較死。能够写一个接受可变參数的函数,做的通用些。

如果我要在cwGameObject的upadte函数中调用“do_obj_update”lua函数,写法例如以下:

void cwGameObject::update(float dt)

{

CCLuaEngine::defaultEngine()->executeGlobalFunction("do_obj_update", dt, this,"cwGameObject");

}

这样在创建cwGameObject时scheduleUpdate一下就能够了。

lua脚本:

-- for CCLuaEngine traceback

function __G__TRACKBACK__(msg)

print("----------------------------------------")

print("LUA ERROR: " .. tostring(msg) .. "\n")

print(debug.traceback())

print("----------------------------------------")

end

winSize = CCDirector:sharedDirector():getWinSize()

-- avoid memory leak

collectgarbage("setpause", 100)

collectgarbage("setstepmul", 5000)

function do_obj_update(dt, obj)

local x, y = obj:getPosition()

local vx, vy = obj:moveDir()

x = x + vx*dt*obj:speed()

y = y + vy*dt*obj:speed()

if x < 0 then

x = 0

obj:setMoveDir(-vx, vy)

end

if x > winSize.width then

x = winSize.width

obj:setMoveDir(-vx, vy)

end

if y < 0 then

y = 0

obj:setMoveDir(vx, -vy)

end

if y > winSize.height then

y = winSize.height

obj:setMoveDir(vx, -vy)

end

obj:setPosition(x, y)

end

print("test.lua loaded.")

脚本非常easy,do_obj_update函数仅仅是做了一些边框推断。

别忘了改动AppDelegate::applicationDidFinishLaunching加载脚本文件名~~

cocos2dx版本号:cocos2d-2.0-x-2.0.3

http://blog.csdn.net/honghaier/article/details/8700574

时间: 2024-12-25 18:41:12

转让lua性能executeGlobalFunction的相关文章

Lua Profiler——快速定位Lua性能问题

导读 随着Lua在项目中的大量使用,它所带来的性能问题也逐步成为了项目运行时的重大性能瓶颈之一.特别是内存相关的性能问题,无论是内存分配过大还是内存泄露无法回收,目前都已经在不少研发项目中集中爆发. UWA推出的GOT Online中的Lua模式已经慢慢成为研发团队对Lua进行日常性能监控的有效手段.因此,也有越来越多的团队反馈,在监控到table数持续上涨,引用Mono对象持续增多等等问题时,应该如何快速地解决? 本次博物纳新推荐的开源库项目:LuaProfiler-For-Unity,相信可

Lua性能优化

原文:Lua Performance Tips 偶然找到<Lua Performance Tips>这篇关于Lua的优化文章,个人认为相较于多数泛泛而谈要好不少.尽管Lua已经到5.2版本了,但里面的技术依然能用到,通过翻译自己也能更深入的去了解文中提到技巧.第一次翻译,错误及不当之处自然不会少,欢迎指正,谢谢--以下为正文 基础实例 关于表 关于字符串 简化,复用,再生 后记 像其他任何编程语言一样,在Lua中,我们也要遵守以下两条优化程序的规则: 规则1:不要优化. 规则2:仍然不要优化(

Lua 性能相关笔记

1.创建一个闭合函数要比创建一个table更廉价,访问非局部的变量也比table字段更快. 2.访问局部变量要比全局变量更快,尽可能的使用局部变量,可以避免无用的名称引入全局环境. 3.do-end语句块能提高lua运行效率,lua运行一行代码就会开启新的程序块,而do-end只有在遇到end时才会算做一个程序块. 4.正确的尾调用不耗费任何栈空间,特别是递归时不会造成栈溢出. 5.循环中使用无状态的迭代器,可以避免每次创建新的闭合函数而产生开销. 6.多重赋值解决声明多个变量时的运行效率. 7

lua性能篇,还没时间看,先保存一下

https://www.owent.net/2014/12/lua%E6%80%A7%E8%83%BD%E5%88%86%E6%9E%90.html http://www.cnblogs.com/zwywilliam/p/5999980.html

使用Lua 局部变量来优化性能,同时比较局部变量和全局变量

在竞争激烈的游戏行业中,尤其页游,面对策划复杂和频繁的需求,使用脚本可以降低难度和成本.在使用Lua的过程中,会经常访问全局变量来作为配置文件. 在访问全局变量时,可以通过局部变量引用全局变量来优化.当然,这样的优化毫无意义. Locals Vs Globals  from  http://lua-users.org/wiki/LocalsVsGlobals Comparison between local and global variables: Implementation: Locals

使用Lua 局部变量来优化性能,同一时候比較局部变量和全局变量

在竞争激烈的游戏行业中,尤其页游,面对策划复杂和频繁的需求,使用脚本能够减少难度和成本.在使用Lua的过程中,会常常訪问全局变量来作为配置文件. 在訪问全局变量时,能够通过局部变量引用全局变量来优化.当然,这种优化毫无意义. Locals Vs Globals  from  http://lua-users.org/wiki/LocalsVsGlobals Comparison between local and global variables: Implementation: Locals

Lua 架构 The Lua Architecture

转载自:http://magicpanda.net/2010/10/lua%E6%9E%B6%E6%9E%84%E6%96%87%E6%A1%A3/ Lua架构文档(翻译) 十 102010 前段时间翻译了lua官方关于lua5架构设计的一份文档,现在分享给大家. 注意:所有版权都归lua官方所有,本人仅将其翻译为中文,以方便中文阅读者.翻译中出现任何错误导致的结果,本人不负任何责任. 如果有任何翻译错误,以及意见与建议,请email本人.邮件地址:[email protected]. 转载请注

nginx和lua

lua作为嵌入式脚本,在目前所有的脚本引擎中速度是最快的.它由标准C编写而成,几乎在所有操作系统和平台都可以编译运行. 我们为什么要用nginx+lua呢? 我们来比较下nginx+lua和nginx+php: nginx+php之间是要有进程通信的,因此性能开销很大:而lua是嵌在nginx进程内部的,它不需要有两套进程独立工作,因此从接口上就有决定性的优势:再加上线程之间通讯的时候需要大量的反序列化和序列化的工作,让后两套进程带来的额外情况是更多的进程和更多的切换开销,所以nginx+lua

大佬带你深入浅出Lua虚拟机

欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由鹅厂优文发表于云+社区专栏 作者:郑小辉 | 腾讯 游戏客户端开发高级工程师 写在前面:本文所有的文字都是我手工一个一个敲的,以及本文后面分享的Demo代码都是我一行一行码的,在我之前已经有非常多的前辈研究过Lua虚拟机了,所以本文很多思想必然是踏在这些巨人的肩膀上的. ? 本文标题是"深入浅出Lua虚拟机",其实重点在浅出这两字上.毕竟作者的技术水平有限.但是听说名字要起的屌一点文章才有人看,故而得名. ? 谨以此文奉