Advertisement
C0BRA

Untitled

Dec 14th, 2012
77
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.87 KB | None | 0 0
  1. local tinsert = table.insert
  2. local tremove = table.remove
  3. local tostring = tostring
  4. local setmetatable = setmetatable
  5. local getmetatable = getmetatable
  6. local next = next
  7.  
  8. local _G = _G
  9.  
  10. function super(obj)
  11. local new = {}
  12. for k, v in next, obj do
  13. new[k] = v
  14. end
  15. return setmetatable(new, getmetatable(obj).super)
  16. end
  17.  
  18.  
  19. function class(name, statics, methodes, parentClass, metaBase)
  20. local classTbl = {__parentClass = parentClass}--The actual class table
  21.  
  22. if(parentClass) then--we require a reference to the parent class
  23. classTbl.super = parentClass.__methodes
  24. end
  25.  
  26. if(not methodes.__tostring) then--implementing tostring if not existant
  27. methodes.__tostring = function(self)
  28. return name
  29. end
  30. end
  31.  
  32. if(methodes[name]) then
  33. methodes.__construct = methodes[name]
  34. end
  35.  
  36. assert(methodes.__construct, "No constructor defined for :"..name)
  37.  
  38.  
  39.  
  40. if(parentClass) then
  41. for k, v in next, parentClass.__methodes do--copying methodes from superclass
  42. if(not methodes[k]) then
  43. methodes[k] = v
  44. end
  45. end
  46. end
  47.  
  48. if(methodes.__call) then
  49. methodes.__call = nil
  50. end
  51.  
  52. classTbl.__methodes = methodes--needed for later access
  53.  
  54. methodes.__classTbl = classTbl
  55.  
  56. classTbl.__methodes.__index = methodes--Required
  57.  
  58. local ClassMeta = {--Class metatable needed to "call" the class itself
  59. __call = function(self, ...)--constructor
  60. local instance = setmetatable({}, methodes)--required
  61. if(self ~= classTbl) then
  62. instance = self--allow call override
  63. else
  64. instance = {}
  65. end
  66.  
  67. if(parentClass and self == classTbl) then
  68. local currParent = parentClass
  69. local constructorStack = {instance.__construct}--the constructors need to be called in the opposite inheritance order
  70. while currParent do
  71. if(not currParent.__methodes.__construct) then--If we have a superclass
  72. break
  73. end
  74. tinsert(constructorStack, currParent.__methodes.__construct)--pushing the function onto the stack
  75.  
  76. currParent = currParent.__parentClass
  77. end
  78.  
  79. while(constructorStack[1]) do--calling all constructors
  80. tremove(constructorStack)(instance, ...)--hacky :3
  81. end
  82. elseif(self == classTbl) then
  83. instance:__construct(...)
  84. end
  85. return instance
  86. end
  87. }
  88.  
  89. for k, v in next, statics do--copy statics into our table
  90. ClassMeta[k] = v
  91. end
  92. _G["Is"..name] = function(obj)
  93. local meta = getmetatable(obj).__classTbl
  94. while(meta.__classTbl.__parentClass) do
  95. if(meta.__classTbl.__parentClass == classTbl) then
  96. return true
  97. end
  98. meta = meta.__parentClass
  99. end
  100. return false
  101. end
  102.  
  103. if(parentClass) then--copying statics
  104. for k, v in next, getmetatable(parentClass) do
  105. if(not ClassMeta[k]) then
  106. ClassMeta[k] = v
  107. end
  108. end
  109. end
  110.  
  111. ClassMeta.__index = ClassMeta--required
  112. setmetatable(classTbl, ClassMeta)--required
  113. return classTbl
  114. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement