Advertisement
Kernell

Lua Class implement

Feb 9th, 2012
287
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 10.36 KB | None | 0 0
  1. --[[
  2.   class.lua
  3.   version: 2.05
  4.   2011-11-05
  5.   update by Kernell (Multi Theft Auto adaptation, new syntax)
  6. ]]
  7.  
  8. --[[
  9.   class.lua
  10.   version: 2.04
  11.   2009-05-20
  12.   update by Setuper
  13. ]]
  14.  
  15. -- PRIVATE
  16.  
  17. --[[
  18.   Define unique value for identifying ambiguous base objects and inherited
  19.   attributes. Ambiguous values are normally removed from classes and objects,
  20.   but if keep_ambiguous == true they are left there and the ambiguous value
  21.   is made to behave in a way useful for debugging.
  22. ]]
  23.  
  24. local ambiguous = { __type = 'ambiguous' };
  25. local remove_ambiguous;
  26.  
  27. if keep_ambiguous then
  28.     -- Make ambiguous complain about everything except tostring()
  29.     local function invalid( operation )
  30.         return function()
  31.             error( 'Invalid ' .. operation .. ' on ambiguous' );
  32.         end
  33.     end
  34.    
  35.     local ambiguous_mt =
  36.     {
  37.         __add       = invalid( 'addition' ),
  38.         __sub       = invalid( 'substraction' ),
  39.         __mul       = invalid( 'multiplication' ),
  40.         __div       = invalid( 'division' ),
  41.         __mod       = invalid( 'modulus operation' ),
  42.         __pow       = invalid( 'exponentiation' ),
  43.         __unm       = invalid( 'unary minus' ),
  44.         __concat    = invalid( 'concatenation' ),
  45.         __len       = invalid( 'length operation' ),
  46.         __eq        = invalid( 'equality comparison' ),
  47.         __lt        = invalid( 'less than' ),
  48.         __le        = invalid( 'less or equal' ),
  49.         __index     = invalid( 'indexing' ),
  50.         __newindex  = invalid( 'new indexing' ),
  51.         __call      = invalid( 'call' ),
  52.         __tostring  = function() return 'ambiguous' end,
  53.         __tonumber  = invalid( 'conversion to number' )
  54.     };
  55.    
  56.     setmetatable( ambiguous, ambiguous_mt );
  57.  
  58.     -- Don't remove ambiguous values from classes and objects
  59.     remove_ambiguous = function() end;
  60. else
  61.     -- Remove ambiguous values from classes and objects
  62.     remove_ambiguous = function( t )
  63.         for k, v in pairs( t ) do
  64.             if v == ambiguous then
  65.                 t[ k ] = nil;
  66.             end
  67.         end
  68.     end
  69. end
  70.  
  71.  
  72. --[[
  73.   Reserved attribute names.
  74. ]]
  75.  
  76. local reserved      =
  77. {
  78.     __index         = true;
  79.     __newindex      = true;
  80.     __type          = true;
  81.     __class         = true;
  82.     __bases         = true;
  83.     __inherited     = true;
  84.     __from          = true;
  85.     __virtual       = true;
  86.     __user_init     = true;
  87.     __name          = true;
  88.     __initialized   = true;
  89. }
  90.  
  91. --[[
  92.   Some special user-set attributes are renamed.
  93. ]]
  94.  
  95. local rename =
  96. {
  97.     __init  = '__user_init';
  98.     __set   = '__user_set';
  99.     __get   = '__user_get';
  100. };
  101.  
  102. --[[
  103.   The metatable of all classes, containing:
  104.  
  105.   To be used by the classes:
  106.    __call()    for creating instances
  107.    __init()     default constructor
  108.    is_a()      for checking object and class types
  109.   implements()  for checking interface support
  110.  
  111.   For internal use:
  112.   __newindex()  for controlling class population
  113. ]]
  114.  
  115. local class_mt = {};
  116. class_mt.__index = class_mt;
  117.  
  118. --[[
  119.   This controls class population.
  120.   Here 'self' is a class being populated by inheritance or by the user.
  121. ]]
  122.  
  123. function class_mt:__newindex( name, value )
  124.     if rename[ name ]       then name = rename[ name ] end -- Rename special user-set attributes
  125.  
  126.     if name == '__user_get' then -- __user_get() needs an __index() handler
  127.         self.__index = value and function( obj, k )
  128.             local v = self[ k ];
  129.            
  130.             if v == nil and not reserved[ k ] then
  131.                 v = value( obj, k );
  132.             end
  133.            
  134.             return v;
  135.         end or self;
  136.     elseif name == '__user_set' then -- __user_set() needs a __newindex() handler
  137.         self.__newindex = value and function( obj, k, v )
  138.             if reserved[ k ] or not value( obj, k, v ) then
  139.                 rawset( obj, k, v );
  140.             end
  141.         end or nil;
  142.     end
  143.    
  144.     rawset( self, name, value ); -- Assign the attribute
  145. end
  146.  
  147. --[[
  148.   This function creates an object of a certain class and calls itself
  149.   recursively to create one child object for each base class. Base objects
  150.   of unnamed base classes are accessed by using the base class as an index
  151.   into the object, base objects of named base classes are accessed as fields
  152.   of the object with the names of their respective base classes.
  153.   Classes derived in virtual mode will create only a single base object.
  154.   Unambiguous grandchildren are inherited by the parent if they do not
  155.   collide with direct children.
  156. ]]
  157.  
  158. local function build( class, virtual_objs, is_virtual )
  159.     virtual_objs = virtual_objs or {};
  160.  
  161.     if is_virtual and virtual_objs[ class ] then
  162.         return virtual_objs[ class ];
  163.     end
  164.  
  165.     local obj = { __type = 'object' };
  166.     local inherited = {}
  167.  
  168.     for i, base in ipairs( class.__bases ) do
  169.         local child = build( base, virtual_objs, class.__virtual[ base ] );
  170.         obj[ base.__name ] = child;
  171.  
  172.         for c, grandchild in pairs( child ) do
  173.             if not inherited[c] then
  174.                 inherited[ c ] = grandchild;
  175.             elseif inherited[ c ] ~= grandchild then
  176.                 inherited[ c ] = ambiguous;
  177.             end
  178.         end
  179.     end
  180.  
  181.     for k, v in pairs( inherited ) do
  182.         if not obj[ k ] then
  183.             obj[ k ] = v;
  184.         end
  185.     end
  186.  
  187.     remove_ambiguous( obj );
  188.  
  189.     setmetatable( obj, class );
  190.  
  191.     if is_virtual then virtual_objs[ class ] = obj end
  192.  
  193.     return obj;
  194. end
  195.  
  196. --[[
  197.   The __call() operator creates an instance of the class and initializes it.
  198. ]]
  199.  
  200. function class_mt:__call( ... )
  201.     local this = build( self );
  202.  
  203.     this:__init( ... );
  204.    
  205.     return this;
  206. end
  207.  
  208. function class_mt:__init( ...)
  209.     if self.__initialized then
  210.         return;
  211.     end
  212.    
  213.     if self[ self.__name ] then
  214.         self[ self.__name ]( self, ... );
  215.     end
  216.    
  217.     for _, base in ipairs( self.__bases ) do
  218.         self[ base.__name ]:__init( ... );
  219.     end
  220.    
  221.     self.__initialized = true;
  222. end
  223.  
  224. --[[
  225.   The implements() method checks that an object or class supports the
  226.   interface of a target class. This means it can be passed as an argument to
  227.   any function that expects the target class. We consider only functions
  228.   and callable objects to be part of the interface of a class.
  229. ]]
  230.  
  231. function class_mt:implements( class )
  232.     local function is_callable( v )
  233.         if v == ambiguous then return false end
  234.         if type( v ) == 'function' then return true end
  235.        
  236.         local mt = getmetatable( v );
  237.        
  238.         return mt and type( mt.__call ) == 'function';
  239.     end
  240.  
  241.     for k, v in pairs( class ) do
  242.         if not reserved[ k ] and is_callable( v ) and not is_callable( self[ k ] ) then
  243.             return false;
  244.         end
  245.     end
  246.  
  247.     return true;
  248. end
  249.  
  250. --[[
  251.   The is_a() method checks the type of an object or class starting from
  252.   its class and following the derivation chain upwards looking for
  253.   the target class. If the target class is found, it checks that its
  254.   interface is supported (this may fail in multiple inheritance because
  255.   of ambiguities).
  256. ]]
  257.  
  258. function class_mt:is_a( class )
  259.     if self.__class == class then return true end
  260.  
  261.     local function find( target, classlist )
  262.         for i, class in ipairs( classlist ) do
  263.             if class == target or find( target, class.__bases ) then
  264.                 return true;
  265.             end
  266.         end
  267.        
  268.         return false;
  269.     end
  270.  
  271.     if not find( class, self.__bases ) then return false end
  272.  
  273.     return self:implements( class );
  274. end
  275.  
  276. -- PUBLIC
  277.  
  278. --[[
  279.   Utility type and interface checking functions
  280. ]]
  281.  
  282. function typeof( value )
  283.     return type( value ) =='table' and value.__type or type( value );
  284. end
  285.  
  286. function classof( value )
  287.     return type( value ) == 'table' and value.__class or nil;
  288. end
  289.  
  290. function classname( value )
  291.     if not classof( value ) then return nil end
  292.    
  293.     local name = value.__name;
  294.    
  295.     return type( name ) == 'string' and name or nil;
  296. end
  297.  
  298. function implements( value, class )
  299.     return classof( value ) and value:implements( class ) or false
  300. end
  301.  
  302. function is_a( value, class )
  303.     return classof( value ) and value:is_a( class ) or false
  304. end
  305.  
  306. --[[
  307.   Use a table to control class creation and naming.
  308. ]]
  309.  
  310. class = {};
  311. local mt = {};
  312.  
  313. setmetatable( class, mt );
  314.  
  315. function mt:__newindex()
  316.     return nil;
  317. end
  318.  
  319. --[[
  320.   Create a named or unnamed class by calling class([name, ] ...).
  321.   Arguments are an optional string to set the class name and the classes or
  322.   virtual classes to be derived from.
  323. ]]
  324.  
  325. function mt:__call( name )
  326.     _G[ name ] = make_class( self, name );
  327.    
  328.     return function( ... )
  329.         _G[ name ] = make_class( self, name, ... );
  330.     end
  331. end
  332.  
  333. function make_class( this, ... )
  334.     local arg, last = { ... }, {};
  335.     local argn = #arg;
  336.    
  337.     if argn ~= 0 then
  338.         local l = arg[ argn ];
  339.        
  340.         if typeof( l ) == "table" then
  341.             last = l;
  342.             table.remove( arg, argn );
  343.         end
  344.     end
  345.  
  346.     local c =
  347.     {
  348.         __type      = 'class',
  349.         __bases     = {},
  350.         __virtual   = {}
  351.     };
  352.    
  353.     c.__class = c;
  354.     c.__index = c;
  355.  
  356.     if type( arg[ 1 ] ) == 'string' then
  357.         c.__name = arg [ 1 ];
  358.        
  359.         table.remove( arg, 1 );
  360.     else
  361.         c.__name = tostring( c );
  362.     end
  363.  
  364.     local inherited = {};
  365.     local from = {};
  366.  
  367.     for i, base in ipairs( arg ) do
  368.         local basetype = typeof( base );
  369.         local is_virtual = basetype == 'virtual_class';
  370.        
  371.         assert( basetype == 'class' or is_virtual, 'Base ' .. i .. ' is not a class or virtual class' );
  372.        
  373.         if is_virtual then
  374.             base = base.__classl;
  375.         end
  376.  
  377.         assert( c.__virtual[ base ] == nil, 'Base ' .. i .. ' is duplicated' );
  378.  
  379.         c.__bases[ i ] = base;
  380.         c.__virtual[ base ] = is_virtual;
  381.  
  382.         for k, v in pairs( base ) do
  383.             if not reserved[k] and v ~= ambiguous and inherited[k] ~= ambiguous then
  384.                 local new_from;
  385.  
  386.                 local base_inherited = base.__inherited[ k ];
  387.                
  388.                 if base_inherited then
  389.                     if base_inherited ~= v then
  390.                         base.__inherited[ k ] = nil;
  391.                         base.__from[ k ] = nil;
  392.  
  393.                     else
  394.                         new_from = base.__from[ k ];
  395.                     end
  396.                 end
  397.  
  398.                 new_from = new_from or { class = base, virtual = is_virtual }
  399.  
  400.                 local current_from = from[ k ];
  401.                
  402.                 if not current_from then
  403.                     from[ k ] = new_from;
  404.  
  405.                     if type( v ) == 'function' then
  406.                         local origin = new_from.class;
  407.                        
  408.                         inherited[ k ] = function( this, ... )
  409.                             return origin[ k ]( this[ origin.__name ], ... );
  410.                         end
  411.  
  412.                     else
  413.                         inherited[ k ] = v;
  414.                     end
  415.                    
  416.                 elseif current_from.class ~= new_from.class or not current_from.virtual or not new_from.virtual then
  417.                     inherited[ k ] = ambiguous;
  418.                     from[ k ] = nil;
  419.                 end
  420.             end
  421.         end
  422.     end
  423.  
  424.     remove_ambiguous( inherited );
  425.  
  426.     setmetatable( c, class_mt );
  427.  
  428.     for k, v in pairs( inherited ) do c[ k ] = v end
  429.    
  430.     c.__inherited = inherited;
  431.     c.__from = from;
  432.  
  433.     for k, v in pairs( last ) do c[ k ] = v end
  434.  
  435.     return c;
  436. end
  437.  
  438. function mt:__index( name )
  439.     return function( ... )
  440.         local c = class( name )( ... );
  441.        
  442.         _G[ name ] = c;
  443.        
  444.         return c;
  445.     end
  446. end
  447.  
  448. --[[
  449.   Wrap a class for virtualization of the class.
  450. ]]
  451.  
  452. function virtual( class )
  453.     assert( typeof( class ) == 'class', 'Argument is not a class' );
  454.    
  455.     return { __type = 'virtual_class', __class = class };
  456. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement