Lua string hash 算法
我在前一篇文章介绍过下面这 3 个字符串拥有相同的 hash,会导致 Hash Dos 问题:
"0000000000000000000000000000000000"
"f0l0l0w0m0e0n0t0w0i0t0t0e0r0?0:0)0"
"x0x0x0x0x0x0x0x0x0x0x0x0x0x0x0x0x0"
但是 Lua 并没有将自己的 string hash 算法暴露出来,那应该怎么验证呢?其实翻看 Lua 5.1.4 源码,lstring.c 中关于 string hash 是这么定义的:
TString *luaS_newlstr (lua_State *L, const char *str, size_t l) {
GCObject *o;
unsigned int h = cast(unsigned int, l); /* seed */
size_t step = (l>>5)+1; /* if string is too long, don't hash all its ...
cocos2dx lua cc ccs ccui区别和使用
最近遇到一个问题,网上一些教程,或者官方的一些教程,在对应使用cc,ccs ,ccui的时候,导致我这边没有提示,开始以为是编辑器的问题,然后硬写上去之后,在调试的时候直接报错,经过多次查看Api文档发现,我使用的Api中,并没有这个方法,那么问题来了!
我应该怎么去调用这个对应的Api呢?
如何验证使用cocos2dx lua调用Api是正常的呢?
遇到一个功能或者一个需求,应该如何查找对应的Api呢?
网上有个朋友说了这么一段原话:
同一个框架里Api名字大小不统一我也就忍了(setBackGround…和setBackground…),可是同一个类名却表达两个不同的东西这个实在让我非常气愤,刚才瞎研究半天ScrollView才发现我程序里用的是ccui.ScrollView对象,而我盯着cc.ScrollView看了半天,我说怎么Api对不上号!
其实大概的意思就是cocos2dx lua对应Api版本号的问题,因为以前cocos用cocos2d-lua写,后来带领大家往quick转,现在合并之后,又带领大家回到cocos2d-lua,所以必定会产生一些规范和版本号的区别。 ...
Lua作图教程之lua基础
一、什么是Lua?Lua 是一个小巧的脚本语言,巴西里约热内卢天主教大学里的一个研究小组于1993年开发,其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。Lua由标准C编写而成,几乎在所有操作系统和平台上都可以编译,运行。一个完整的Lua解释器不过200k,在目前所有脚本引擎中,Lua的速度是最快的。这一切都决定了Lua是作为嵌入式脚本的最佳选择。相比Python和Per的内核,Lua的内核小于120KB,而Python的内核大约860KB,Perl的内核大约1.1MB。Lua语言支持面向对象编程和函数式编程,它提供了一个通用类型的表table,可以实现数组、哈希表、集合、对象的功能。Lua支持协同进程机制。作为一门可扩展的语言,Lua提供简单而稳定的交互接口,如Lua和C程序可通过一个堆栈交换数据,这使得Lua语言可以快速地和其它语言实现整合。总体来说,Lua语言具备以下优点:(1)语言优美、轻巧 (2)性能优良、速度快 (3)可扩展性强。正因为Lua语言具备了这样的特点,使得它能和游戏开发领域的需求完美地结合起来,因为我们需要这样的一门语言,它能够和C/ ...
Lua元表 · 花生肉泥
Metatable元表lua中的每个值都可以用一个metatable
两个table类型的变量,你是无法直接用 + 操作的,如果你定义了一个指定的函数,就可以进行了
setmetatable(table,metatable):对指定table设置元表(metatable),如果元表中存在__metatable键值,setmetatable会失败
getmetatable(table):返回对象的元表
元表创建lua在创建新的table时不会创建元表12local t = {1,2}print(getmetatable(t))
使用getmetatable来获取一个table或userdata类型变量的元表,当创建新的table变量时,使用getmetatable去获得元表,将返回nil,同理,我们也可以使用setmetatable去设置一个table或者userdata类型变量的元表
lua代码中,只能设置table元表1234567891011121314local t = {}setmetatable(t,t1)assert(getmetatable(t) == t1)p ...
Lua string 哈希碰撞
Lua 中 40 字节以下的字符串会被内部化到一张表中(Lua 5.3),这张表挂在 global state 结构下。对于短字符串,相同的串在同一虚拟机上只会存在一份,这被称为字符串的内部化。
其实字符串在 Lua VM 中是以两种内部形式保存的:短字符串及长字符串。其界限默认设置为40(字节)
对于比较长的字符串(32字节以上),为了加快哈希过程,计算字符串哈希值是跳跃进行的(并没有 hash 全部的位)。
Lua Wiki 上列出了各个版本的 Lua 对于 string 没有计算 hash 的长度:
Hash algorithm analysis
-- number of bytes not used in hash function
==============================================================
String length < 15, 15-20 , 20-32 , 32-64
-------------------------------------------- ...
Lua
table 操作
函数
解释
table.concat (table [, step [, start [, end]]])
函数列出参数中指定table的数组部分从start位置到end位置的所有元素, 元素间以指定的分隔符(step)隔开
table.insert (table, [pos,] value)
在table的数组部分指定位置(pos)插入值为value的一个元素. pos参数可选, 默认为数组部分末尾
table.maxn(table)
指定table中所有正数key值中最大的key值. 如果不存在key值为正数的元素, 则返回0。(Lua5.2之后该方法已经不存在了)
table.remove (table [, pos])
返回table数组部分位于pos位置的元素. 其后的元素会被前移. pos参数可选, 默认为table长度, 即从最后一个元素删起。
table.sort (table [, comp])
对给定的table进行升序排序。
操作示例
table.concat
123456789fruits = {"ban ...
Lua语法基础 · 花生肉泥
词法约定标识符标识符可以是任意非数字开头的字母、数字、下划线组成的字符串
标识符用来命名变量,或作为表的域名
Lua是一个大小写敏感的语言
1234andAndAND三者不一样
关键字一下列出了lua的保留关键字。保留关键字不能作为常量或者变量或者其他用户自定义标识符123456and break do elseelseif end false forfunction in localnil not or repeatreturn then true until while
一般约定,以下划线开头连接一串大写字母的名字(比如_WERSION)被保留用于Lua内部全局变量
字符串与引号字符串既可以用一堆单引号引起,也可以是双引号12print("hello")print('world')
注释单行注释 – 作用范围直到行末
多行注释 ...
cocos2dx lua TableView(ScrollView, ListView)介绍与使用实战
在众多移动应用中,能看到各式各样的列表/表格数据
不管是iOS中的UITableView/UICollectionView/UIScrollView,还是Android中的ListView/CircleView,都是实际项目开发中使用最平凡,也是最重要的功能。
为了用户考虑,也为了性能考虑, 我们一般都会重复利用所创建的列表项,这样就避免了界面卡顿。cocos2dx lua 3.x中有一个TabeView,效果和上面列举的那些做列表的一样,尤其与iOS中UITableView方法属性,使用方式都有很多相似的地方。
游戏开发中,虽然没有和普通应用那么多列表,但是也会有些消息列表,用户,排行榜等,所以,这篇我们就来看看如何用TableView以及解决在实际开发中的一些问题。
TableView使用直接上代码,这里我们使用cocos2dx lua提供TableView实现水平和垂直的列表,基本满足常见功能,具体细节,可以根据注释或者代码逻辑,结合实际需求进行调整和优化
local TableScene = class("TableScene")
TableScene. ...
一个简单的Lua (Memory) Profiler
Lua没有内置的Profiler,但是提供了一些相关的接口,可以用来实现一个简单的Lua Profiler。
一个Profiler至少需要统计以下信息, 用函数名+调用位置(保留一层堆栈信息)作为key:
执行次数
总时间
单次最大时间
尚未gc的内存数量
分配内存的最大值
二、基础
出发点是LuaProfiler,结构比较合理,但是有一些小问题:
统计数据应该驻留在内存中,不能写log,太卡。
time()的精度太低,换成PerformanceCounter(windows)。
lua5.3和5.1的lua_Hook处理tail call的接口不一样,需要转换一下。
coroutine相关的处理。
三、Memory
通过以下方式可以获取每个函数分配内存的数据:
启动Profiler时执行一次full gc
重载lua_Alloc,按下列三种情况统计数据:
分配新的内存:建立内存指针与当前函数数据的对应关系,如果新内存大小为size, 当前函数的内存数量+=size,同时检查更新内存最大值。
释放内 ...
Programming in Lua(Thrid Edition)笔记
13 Metatables and Metamethods
metatable和metamethod可以允许我们对一个值做未定义的操作,Lua中的每个值都可以有一个metatable,table和userdata有自己的metatable,其他类型的值对于本类型的所有值共享一个metatable,Lua创建的表默认无metatable。12t = {}print(getmetatable(t))
用setmetatable()改变table的metatable:123t1 = {}setmetatable(t, t1)print(getmetatable(t) == t1) --> true
一个table可以是任何值的metatable,一组相关的table可以共享一个公共的metatable来描述它们公共的行为,一个table也可以做自己的metatable来描述自己的行为。
用算术metamethod对集合求并、求交
1234567891011121314151617181920212223242526272829303132333435363738394041 ...