cocos2d-x中class的定义

撰写于 2016-12-14 修改于 2016-12-19 分类 游戏开发 标签 cocos2d-x

最近想自己做一个游戏,一直用的是cocos2d-x,不过用的版本比较老,down了一个官网的最新包(3.13.1),发现有点不适应,搞了一个什么mvc的东西,一直认为cocos2d-x不适用mvc,既然官网想让用,那就尝试一下,不过先要看看class函数有没有变化。

源码

好像hexo不能解析lua代码,那就先用c++就将一下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
function class(classname, ...)
local cls = {__cname = classname}

local supers = {...}
for _, super in ipairs(supers) do
local superType = type(super)
assert(superType == "nil" or superType == "table" or superType == "function",
string.format("class() - create class \"%s\" with invalid super class type \"%s\"",
classname, superType))

if superType == "function" then
assert(cls.__create == nil,
string.format("class() - create class \"%s\" with more than one creating function",
classname));
-- if super is function, set it to __create
cls.__create = super
elseif superType == "table" then
if super[".isclass"] then
-- super is native class
assert(cls.__create == nil,
string.format("class() - create class \"%s\" with more than one creating function or native class",
classname));
cls.__create = function() return super:create() end
else
-- super is pure lua class
cls.__supers = cls.__supers or {}
cls.__supers[#cls.__supers + 1] = super
if not cls.super then
-- set first super pure lua class as class.super
cls.super = super
end
end
else
error(string.format("class() - create class \"%s\" with invalid super type",
classname), 0)
end
end

cls.__index = cls
if not cls.__supers or #cls.__supers == 1 then
setmetatable(cls, {__index = cls.super})
else
setmetatable(cls, {__index = function(_, key)
local supers = cls.__supers
for i = 1, #supers do
local super = supers[i]
if super[key] then return super[key] end
end
end})
end

if not cls.ctor then
-- add default constructor
cls.ctor = function() end
end
cls.new = function(...)
local instance
if cls.__create then
instance = cls.__create(...)
else
instance = {}
end
setmetatableindex(instance, cls)
instance.class = cls
instance:ctor(...)
return instance
end
cls.create = function(_, ...)
return cls.new(...)
end

return cls
end

解析

下面逐行解析一下:

1
2
local cls = {__cname = classname}
local supers = {...}

首先,生成一个表cls(也就是子类),确保每一个子类都是自主完整的,设置__cname = classname。然后生成一个表supers(暂且成为父类),把传入的父类放入表中。
接着下边,就是一个for循环,处理每一个父类:

1
2
3
4
5
6
if superType == "function" then
assert(cls.__create == nil,
string.format("class() - create class \"%s\" with more than one creating function",
classname));
-- if super is function, set it to __create
cls.__create = super

如果父类是一个函数,则cls中必须没有create函数(没有必要去检查),且cls的create函数就是该父类(即传入的函数)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
elseif superType == "table" then
if super[".isclass"] then
-- super is native class
assert(cls.__create == nil,
string.format("class() - create class \"%s\" with more than one creating function or native class",
classname));
cls.__create = function() return super:create() end
--如果父类就是个纯lua class
--子类的__super会记录所有的父类,并把第一个父类设置给cls.super
else
-- super is pure lua class
cls.__supers = cls.__supers or {}
cls.__supers[#cls.__supers + 1] = super
if not cls.super then
-- set first super pure lua class as class.super
cls.super = super
end
end
else
error(string.format("class() - create class \"%s\" with invalid super type",
classname), 0)
end

如果父类是一个table,且父类中有.isclass成员,则说明该父类是一个native class,简单说明一下什么是native class,个人理解:该父类中有非lua代码的接口(如c或c++)。子类中__create方法,会调用父类中create()方法(父类中一定会有create())

如果父类是一个纯lua类,子类cls的__supers会记录所有传入的父类,并把第一父类设置为cls.super

如果既不是一个table,也不是一个function,则报错。

到目前为止,cls中的内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
local cls = {

__cname = classname;

--如果是function
__create = super;

--如果是native class
__create = function ( ... )
return super:create()
end

--如果是纯lua table
__supers = {
supers[1],
supers[2],
...
}
super = supers[1]
}

接着解读

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
cls.__index = cls
if not cls.__supers or #cls.__supers == 1 then
setmetatable(cls, {__index = cls.super})
else
setmetatable(cls, {__index = function(_, key)
local supers = cls.__supers
for i = 1, #supers do
local super = supers[i]
if super[key] then return super[key] end
end
end})
end
if not cls.ctor then
-- add default constructor
cls.ctor = function() end
end

第一句,cls.__index = cls,稍微知道lua的都应该清楚这句话什么意思。不再赘述了。如果不清楚,可以看这里
如果传入的父类只有一个,直接设置

目录

  1. 源码
  2. 解析
Site by ZHJ using Hexo & Random

Hide