Posted 14 January 2014 - 12:56 PM
The Class API, an API designed to make OOP far easier in computercraft / Lua.
A class is essentially a way of creating objects with certain values, some can be extendable and some can extend other classes.
This API allows you to create a class object that can extend other classes and create static or normal objects.
The main function in this API is
The other function is
To set a class parent, use
An example of this is shown in the explanation of Class:newObject
To get the class parent, use
To change the class name, use
To get the class name, use
To add a child class to a class, use
To create a normal object, use
For example
You can also call Class( ) to create a new object of that class
i.e. Class( ) is the same as
To create a static class, use
A static object basically makes it impossible to change any of the variables in the object. However this is not the same for indexes in tables because of how metatables work.
Example:
However, if you had a table with stringValue in it, you would then be able to change [table].stringValue
This can be useful, however it would be very awkward to use if you could not define any variables when you create an object
To run some code when an object is created, you need to define the Class.new function
An example is below:
This could be useful in a vector class, i.e.
There are also some functions that objects get and have no way of changing ( without modifying the metatable ( which is impossible with a static class with no Class:new( ) function ) )
returns the object type including all parents concatenated with a "." i.e. "Drawable.Shape.Triangle"
otherwise
returns the object type i.e. "Triangle"
returns whether the object type is equal to type i.e. Object:typeOf( "Drawable", true ) = false
otherwise
returns whether any of the object's parents type is equal to type i.e. Object:typeOf( "Drawable" ) = true
i.e. Object:getRootClass( ) = Drawable [Class Object]
using
Some tips/pointers:
If you have a class with a table value in it, any modifications to indexes in that table will change the class data not the object data. This is something that is possible to fix but would require a lot of work and would most probably break a lot of other things, so don't expect a fix any time soon.
However it is possible to fix this yourself using a couple of techniques.
Method one: In Class:new( ) use this code for all the tables in the class
Any classes I have made so far use this second method ( defining the table in Class:new( ) ) which is just as simple as copying and pasting some code if you have written it already.
Pastebin link: pastebin get 9bg8Fuje class
If you choose to use this API, you should know that rather than using os.loadAPI( ) you should just run it. It will return a table with the api
For example
For example if you have a class called "MyClass" you could call new.MyClass( … ) to create an object of MyClass
Thanks for reading
A class is essentially a way of creating objects with certain values, some can be extendable and some can extend other classes.
This API allows you to create a class object that can extend other classes and create static or normal objects.
The main function in this API is
class:create( name [,data] )
this will return a class object, that allows you to set/get parents, set the data and meta values for the class, and obviously create objectsThe other function is
class:getClass( name )
This will return a class that has been created with the name [name] or false if it doesn't existTo set a class parent, use
Class:setParentClass( parent )
The use of is that values from the parent class will be accessible in objects unless the class redefines themAn example of this is shown in the explanation of Class:newObject
To get the class parent, use
Class:getParentClass( )
To get the root class, use Class:getRootParentClass( )
To change the class name, use
Class:setType( name )
This will change the class name, kind of obviously…To get the class name, use
Class:getType( )
To add a child class to a class, use
Class:newChildClass( name, data )
This is the same as doing
local myclass = class:create( name, data )
myclass:setParentClass( Class )
To get all child classes, ( including those defined with Class:setParent ), use Class:getChildClasses( )
To create a normal object, use
Class:newObject( ... )
This will create an object that has all the values from the parent class, and all the classes that parent the parent classFor example
Spoiler
drawable = class:create( "Drawable", {
name = "Random string";
render = function( self )
print( self.name )
end;
} )
picture = drawable:newChildClass( "Picture", {
name = "Other random string";
} )
object = picture:newObject( )
object:render( )
-- > Other random string
i.e. Class( ) is the same as
Class:newObject( )
To create a static class, use
Class:newStaticObject( ... )
( You can also make Class:newObject( ) create a static object by default if you set Class.static to true. This will not affect previously created objects. )A static object basically makes it impossible to change any of the variables in the object. However this is not the same for indexes in tables because of how metatables work.
Example:
Spoiler
myclass = class:create( "MyClass", {
stringValue = "Hello World";
} )
local myobject = myclass:newStaticObject( )
print( myobject.stringValue )
--> Hello World
myobject.stringValue = "Another String Value" -- this is ignored
print( myobject.stringValue )
--> Hello World
This can be useful, however it would be very awkward to use if you could not define any variables when you create an object
To run some code when an object is created, you need to define the Class.new function
An example is below:
Spoiler
myclass = class:create( "MyClass", { } )
function myclass:new( object, meta, data, args )
-- self would be the class
-- object would be the thing that is going to be returned
-- meta is the metatable for the object, with some functions in it and a __index pointing to data
-- data is the private table holding all the values for the object
-- in a non static object, if you did object.newValue = "value" then it would go into the data table
-- there is no way to access the data table past this point unless you make a copy of it in this function
-- args is the table of arguments passed in by Class:newObject( ... )
data.randomValue = args[1] or "Something"
end
local object = myclass( )
print( object.randomValue )
--> Something
local object2 = myclass( "Hello World" )
print( object.randomValue )
--> Hello World
myvector = Vector( x, y )
There are also some functions that objects get and have no way of changing ( without modifying the metatable ( which is impossible with a static class with no Class:new( ) function ) )
Object:type( full )
if full is true thenreturns the object type including all parents concatenated with a "." i.e. "Drawable.Shape.Triangle"
otherwise
returns the object type i.e. "Triangle"
Object:typeOf( type, single )
if single is true thenreturns whether the object type is equal to type i.e. Object:typeOf( "Drawable", true ) = false
otherwise
returns whether any of the object's parents type is equal to type i.e. Object:typeOf( "Drawable" ) = true
Object:getClass( )
returns the object class Object:getRootClass( )
returns the root object classi.e. Object:getRootClass( ) = Drawable [Class Object]
Object:getValues( )
returns a table of all the values an object hasusing
for k, v in pairs( Object ) do
will not work, however using for k, v in pairs( Object:getValues( ) ) do
will workSome tips/pointers:
If you have a class with a table value in it, any modifications to indexes in that table will change the class data not the object data. This is something that is possible to fix but would require a lot of work and would most probably break a lot of other things, so don't expect a fix any time soon.
However it is possible to fix this yourself using a couple of techniques.
Method one: In Class:new( ) use this code for all the tables in the class
data[table_name_as_string] = { }
for k, v in pairs( self[table_name_as_string] ) do
data[table_name_as_string][k] = v
end
An alternative is to define the table in the Class:new( ) functionAny classes I have made so far use this second method ( defining the table in Class:new( ) ) which is just as simple as copying and pasting some code if you have written it already.
Pastebin link: pastebin get 9bg8Fuje class
If you choose to use this API, you should know that rather than using os.loadAPI( ) you should just run it. It will return a table with the api
For example
local classAPIUnloaded = loadfile( "ClassAPI" )
if classAPIUnloaded then
classAPILoaded = classAPIUnloaded( )
end
The API also creates a table "new" which can be used to create objectsFor example if you have a class called "MyClass" you could call new.MyClass( … ) to create an object of MyClass
Thanks for reading
Edited on 14 January 2014 - 01:25 PM