There are few positive and less positive things about it.
The name you chose is too technical and I don't think that you can tell what it is just by hearing the name so if you already went for a technical name, make sure that it's easy to understand.
I'm all for introducing new styles, concepts and patterns to existing programming languages but you did something that in my opinion you didn't fully understand.
One of the fundamental things in a framework is a theme and a well defined structure that is easy to follow, I'm sorry but I can see it here.
The learning curve with Ace is flat once you understand the concept you can start working with any of the Ace libraries, at least in my experience, in your case, I can't really see, I can't vision myself changing things nor extending them, I can't see any of the OO principles standing out in your framework.
I checked the code and I mean I don't mind having one file containing 4k of lines, however, I do care for comments, documentation and conventions.
Before you make classes and interfaces you probably want to create a well defined type system, in fact, you need to learn the theory behind anything you implement.
I understand that you wanted to simplify things but in my opinion you were too focus on bringing the development on par with all kind of existing solutions that doesn't work well for Lua.
You can build a library that add existing features to the language that it lacks but personally I'm really skeptical to libraries that are trying to change the language to another thing, blending is so much better than changing something that you can't change and it has the advantage that things that previously worked will continue to work.
I'd expect tests and benchmarks but you didn't provide it and I can't really trust your code.
With that said, I'm not against you or your framework, I just think that building something like this requires a lot of designing and planning and this goes with the 80/20 rule, spend more time engineering, less time coding.
A document system is working on for comments and quick document view now.
The basic system may not be good for learning, I try to build a system from the basic, so many things in the root part has no meanings for addon development.
Making addon doesn't mean to build classes and others yourself, there is no class definition in the Addon Cube, and some other my addons.
To build a Form contains a editor can just use the build-in widget classes such like :
import "System"
local form = System.Widget.Form("MyForm")
local editor = System.Widget.CodeEditor("MyEditor", form)
editor:SetPoint("TOPLEFT", 4, -26)
editor:SetPoint("BOTTOMRIGHT", -4, 26)
What a System.Widget.Form class done, is like the acegui to provide a well designed ui element for using. For normal authors, there is no need to make their classes. At first time, IGAS is designed to build these ui element prototypes in an easy way.
The complex part is only about how to create an object, but since an object only will be created once, the cost could be ignored.
About the usage , I can't give you a benchmark, but a simple test, run in lua 5.1(mac) :
About the cpu usage :
require "igas"
pow = math.pow
-- Use this to increase the usage of the function body
MultiCount = 100
-- Normal function the same with class Multi's Result method
function Result(value)
for i = 1, MultiCount do
value = pow(value, 2)
end
return value
end
do
class "Multi"
-- Method
function Result(self)
local value = self.Value
for i = 1, _G.MultiCount do
value = pow(value, 2)
end
return value
end
function Multi(self, value)
self.Value = value or 0
end
endclass "Multi"
end
function a(count)
local time = os.clock()
for i = 1, count do
r = Result(i)
end
print("Finish for normal", os.clock() - time)
o = Multi(count)
time = os.clock()
for i = 1, count do
o.Value = i
r = o:Result()
end
print("Finish for one object", os.clock() - time)
time = os.clock()
for i = 1, count do
r = Multi(i):Result()
end
print("Finish for multi objects", os.clock() - time)
end
This is a simple test, there is a normal function Result, and a method function object:Result(), they do the same thing.
And using 'MultiCount' to control the usage of the function (method) body, the function body is normal lua code too, as you see.
A test function a() receive a count variable to control the repeat time. The first part for a() is normal lua code, just call the Result function, the second part, using one object call it's Result method, the last part is create one object each time and then call their Result method.
For MultiCount = 100
> MultiCount = 100
> collectgarbage()
> a(10)
Finish for normal 0.00041199999998298
Finish for one object 0.000419000000079
Finish for multi objects 0.00057400000002872
> a(100)
Finish for normal 0.003039000000058
Finish for one object 0.0025710000001027
Finish for multi objects 0.0029170000000249
> a(1000)
Finish for normal 0.018779000000109
Finish for one object 0.014499999999998
Finish for multi objects 0.018570999999952
> a(10000)
Finish for normal 0.14042199999994
Finish for one object 0.14425199999994
Finish for multi objects 0.18008999999995
> a(100000)
Finish for normal 1.4045729999999
Finish for one object 1.460615
Finish for multi objects 1.827017
For MultiCount = 1000
> MultiCount = 1000
> collectgarbage()
> a(10)
Finish for normal 0.002837999999997
Finish for one object 0.0022279999999455
Finish for multi objects 0.0023069999999734
> a(100)
Finish for normal 0.017513000000008
Finish for one object 0.012967000000003
Finish for multi objects 0.014123999999924
> a(1000)
Finish for normal 0.13638000000003
Finish for one object 0.133734
aFinish for multi objects 0.13705099999993
> a(10000)
Finish for normal 1.317129
Finish for one object 1.321518
Finish for multi objects 1.3520689999999
It's interesting when repeat times is 10 - 1000, the method cost is lower than the normal function?that's because the api the method need is stored in the class's environment, and the access speed is a little quick than in _G.
And above 10000, the method cost more than the normal function, there is one more function call when object find it's method, that's the cost the oop system must pay.
The most cost for the oop system is in the object's creation, but for most development, the objects only will be created once.
And about the memory usage.
For a light-weighted oop system, class will fill it's method to their objects like :
do
-- a light-weighted class
myclass = {}
function myclass:methodA()
end
function createObject()
local obj = {}
for i, v in pairs(myclass) do
obj[i] = v
end
return obj
end
-- we create 1000 object
collectgarbage()
collectgarbage('stop')
memory = collectgarbage('count')
for i = 1, 10000 do
obj = createObject()
end
print(collectgarbage('count') - memory)
collectgarbage('restart')
end
The result is 1015.625
And for the IGAS's class
require "igas"
do
class "MyObject"
-- Method
function Result(self)
end
endclass "MyObject"
collectgarbage()
collectgarbage('stop')
memory = collectgarbage('count')
for i = 1, 10000 do
obj = MyObject()
end
print(collectgarbage('count') - memory)
collectgarbage('restart')
end
The result is 625.
Don't forget a table stored others should require some memory for it's indexes.
your first code block is returning 625 for me as well (haven't run the second one).
But since you are trying to do a simple oop system, you should use metatables:
do
-- a light-weighted class
myclass = {}
function myclass:methodA()
end
myclass_mt = {__index = myclass}
function createObject()
local obj = setmetatable({}, myclass_mt)
return obj
end
-- we create 1000 object
collectgarbage()
collectgarbage('stop')
memory = collectgarbage('count')
for i = 1, 10000 do
obj = createObject()
end
print(collectgarbage('count') - memory)
collectgarbage('restart')end
do
-- a light-weighted class
myclass = {}
function myclass:methodA()
end
meta = {__index = myclass}
function createObject()
return setmetatable({}, meta)
end
-- we create 1000 object
collectgarbage()
collectgarbage('stop')
memory = collectgarbage('count')
for i = 1, 10000 do
obj = createObject()
end
print(collectgarbage('count') - memory)
collectgarbage('restart')
end
Well, I run that code in the osx, it's also 625, maybe for 64 bit version.
The example I used before, is for a light-weighted inheritance design, so class B inherit from class A, you can't just set the metatable from A to B. The best way is just store the class's method into it, or you may need a complex metatable system like IGAS.
So, the memory cost is not the problem, IGAS's object would cost a little more cpu usage, but I don't think it's a real problem.
There are few positive and less positive things about it.
The name you chose is too technical and I don't think that you can tell what it is just by hearing the name so if you already went for a technical name, make sure that it's easy to understand.
I'm all for introducing new styles, concepts and patterns to existing programming languages but you did something that in my opinion you didn't fully understand.
One of the fundamental things in a framework is a theme and a well defined structure that is easy to follow, I'm sorry but I can see it here.
The learning curve with Ace is flat once you understand the concept you can start working with any of the Ace libraries, at least in my experience, in your case, I can't really see, I can't vision myself changing things nor extending them, I can't see any of the OO principles standing out in your framework.
I checked the code and I mean I don't mind having one file containing 4k of lines, however, I do care for comments, documentation and conventions.
Before you make classes and interfaces you probably want to create a well defined type system, in fact, you need to learn the theory behind anything you implement.
I understand that you wanted to simplify things but in my opinion you were too focus on bringing the development on par with all kind of existing solutions that doesn't work well for Lua.
You can build a library that add existing features to the language that it lacks but personally I'm really skeptical to libraries that are trying to change the language to another thing, blending is so much better than changing something that you can't change and it has the advantage that things that previously worked will continue to work.
I'd expect tests and benchmarks but you didn't provide it and I can't really trust your code.
With that said, I'm not against you or your framework, I just think that building something like this requires a lot of designing and planning and this goes with the 80/20 rule, spend more time engineering, less time coding.
The basic system may not be good for learning, I try to build a system from the basic, so many things in the root part has no meanings for addon development.
Making addon doesn't mean to build classes and others yourself, there is no class definition in the Addon Cube, and some other my addons.
To build a Form contains a editor can just use the build-in widget classes such like :
What a System.Widget.Form class done, is like the acegui to provide a well designed ui element for using. For normal authors, there is no need to make their classes. At first time, IGAS is designed to build these ui element prototypes in an easy way.
The complex part is only about how to create an object, but since an object only will be created once, the cost could be ignored.
About the usage , I can't give you a benchmark, but a simple test, run in lua 5.1(mac) :
About the cpu usage :
This is a simple test, there is a normal function Result, and a method function object:Result(), they do the same thing.
And using 'MultiCount' to control the usage of the function (method) body, the function body is normal lua code too, as you see.
A test function a() receive a count variable to control the repeat time. The first part for a() is normal lua code, just call the Result function, the second part, using one object call it's Result method, the last part is create one object each time and then call their Result method.
For MultiCount = 100
For MultiCount = 1000
It's interesting when repeat times is 10 - 1000, the method cost is lower than the normal function?that's because the api the method need is stored in the class's environment, and the access speed is a little quick than in _G.
And above 10000, the method cost more than the normal function, there is one more function call when object find it's method, that's the cost the oop system must pay.
The most cost for the oop system is in the object's creation, but for most development, the objects only will be created once.
And about the memory usage.
For a light-weighted oop system, class will fill it's method to their objects like :
The result is 1015.625
And for the IGAS's class
The result is 625.
Don't forget a table stored others should require some memory for it's indexes.
But since you are trying to do a simple oop system, you should use metatables:
This results in 312.5 for me...
Well, I run that code in the osx, it's also 625, maybe for 64 bit version.
The example I used before, is for a light-weighted inheritance design, so class B inherit from class A, you can't just set the metatable from A to B. The best way is just store the class's method into it, or you may need a complex metatable system like IGAS.
So, the memory cost is not the problem, IGAS's object would cost a little more cpu usage, but I don't think it's a real problem.