The latest version (v1.4.3) of Codea introduced the concept of Dependencies. This feature is used to address the problem that over time there are certain functions or classes that you use again and again but you don't want to have to re-type these in each project.
Prior to version 1.4.3 the answer was to copy and paste the relevant bits from one project to another. This works ok but it is a bit slow, breaks up your workflow and can lead to version problems if you forget where the master copy is located.
A better solution is to have a library which contains all of these functions and classes which you can then "include" in your projects as required. If you select the library as a dependency to your project then all of the code (outside the Main tab) within the library becomes accessible to that project.
You don't have to create a specific Library to use dependencies, any project can be selected as a dependancy, but to address the version control issue it is better to keep this code in a consistent location. We haven't worked out if it is better to have many small libraries or one big one. Our guess is that it won't make a difference as the compiler will just lift out the code it needs and a large library won't create unnecessarily bloated byte-code.
A Library is just another project. There are no rules or guidelines as to what a Library should look like so we are just going to do what seems sensible and allow it to evolve over time. To provide something to talk about we created the (Reefwing Software) RSLibrary which is a collection of code which we have found useful but isn't currently available within the Codea framework.
We have structured the Library with the Main tab containing metadata (contents, version, date, etc.) and which if run, will demonstrate the main functionality of the code in the Library. Each subsequent tab contains the code we want to share grouped in what we think is a logical fashion.
Over time we suspect that people will tailor there own libraries using the best of breed from other shared code. Feel free to adopt some or any of the code in RSLibrary. We have freely borrowed from other contributors on the Codea Forum such as Two Lives Left, Vega and Bri_G.
You can download the entire RSLibrary v1.1 in one file or tab by tab:
1. Main.lua v1.1 - metadata and demonstration of the library functionality. 2. Math.lua v1.0 - math.hypot(x, y), math.hypot2(x,y), math.polar(x,y,originX,originY), math.constrain(value,min,max), math.pi(), and math.round(value). 3. Collisions.lua v1.0 - pointInCircle(pointX, pointY, centreX, centreY, radius), pointInRect(pointX, pointY, x, y, w, h). 4. Colors v1.0 - Definitions of the 17 predefined colours from UIColor. 5. Button v1.2 - Modified Vega mesh Button Class. 6. RoundRect v1.0 - Modified Bri_G Rounded Rectangle Class. 7. TextBox v1.0 - Two Lives Left TextBox Class (from Spritely example project).
So you have created your shiny new Library, how do you make this a dependency of your project. The process is very simple.
3 Not surprisingly the section called Dependencies is where you select your library. Tap it to select and it will indicate the available tabs (6 for RSLibrary).
And that's it. You can remove a dependency using the same process.
As the idea of Libraries and Dependencies is evolving we would welcome thoughts and observations on the best structure or alternate approaches, so that we can share them here.
Here is a copy of the Main Class so you can see how RSLibrary is structured.
--# Main -- RSLibrary by Reefwing Software (www.reefwing.com.au) -- This Library contains functions and definitions which are commonly used -- but not currently available in the Codea framework. -- It includes code from: Two Lives Left -- Vega -- Bri_G -- -- CONTENTS -- -- Math Extensions: -- 1. math.round(value) -- 2. math.hypot(x, y) -- 3. math.hypot2(x, y) -- 4. math.polar(x, y) or math.polar(x, y, originX, originY) -- 5. math.pi() -- 6. math.constrain(value, min, max) -- -- Collision Detection Functions: -- 1. pointInCircle(pointX, pointY, centreX, centreY, radius) -- 2. pointInRect(pointX, pointY, x, y, width, height) -- -- Color Extensions: UIColor Predefined Colors -- 1. blackColor 10. yellowColor -- 2. darkGrayColor 11. magentaColor -- 3. lightGrayColor 12. orangeColor -- 4. whiteColor 13. purpleColor -- 5. grayColor 14. brownColor -- 6. redColor 15. clearColor -- 7. greenColor 16. lightTextColor -- 8. blueColor 17. darkTextColor -- 9. cyanColor -- -- Classes: -- 1. Vega Modified Mesh Button Class v1.2 -- 2. Two Lives Left TextBox Class v1.0 -- 3. Bri_G Modified RoundRect Class v1.0 -- -- Note the Main class of the Library is just used to demonstrate the Library -- functionality. Nothing defined here is available using dependancies. function setup() -- Library Metadata version = 1.1 saveProjectInfo("Description", "Reefwing Software Library v"..version) saveProjectInfo("Author", "Reefwing Software") saveProjectInfo("Date", "26th July 2012") saveProjectInfo("Version", version) print("RSLibrary v"..version.."\n") -- Parameters to demonstrate the RoundRect Class parameter("cr",0,2,1) iparameter("border",0,4,2) iparameter("x",0,WIDTH - 200,275) iparameter("y",0,HEIGHT - 40,350) iparameter("w",100,WIDTH,200) iparameter("h",0,HEIGHT,40) -- Construct the rounded rectangle roundRect = RoundRect(x, y, w, h, border, "test", cr) -- Construct a TextBox textBox = TextBox(WIDTH / 2 - 100, HEIGHT - 120, 200, "Enter your name!") showTextBox = false end function draw() -- This sets the background color to black background(blackColor) -- Update our roundRect with the latest parameter values (not required if they -- don't change). The larger the width and height the smaller cr needs to be -- otherwise you will end up with an ellipse. roundRect.x = x roundRect.y = y roundRect.w = w roundRect.h = h roundRect.cr = cr roundRect.border = border -- Set the rectangle fill and border colours. Text colour is also available. roundRect.fillColor = blueColor roundRect.borderColor = redColor -- call the roundRect draw() function roundRect:draw() -- If tap is not on the rectangle then draw the textBox if showTextBox then textBox:draw() end end function touched(touch) -- Use this method to demonstrate the pointInRect() collision detection function if touch.state == BEGAN and pointInRect(touch.x, touch.y, x, y, w, h) then showTextBox = false print("Rounded Rectangle Tapped.") elseif touch.state == ENDED and not pointInRect(touch.x, touch.y, x, y, w, h) then showTextBox = true showKeyboard() end end -- KeyBoard handling function -- Used to enter name if touch is not on the rounded rectangle function keyboard(key) if key ~= nil then if string.byte(key) == 10 then -- <RETURN> Key pressed print("Hello "..textBox.text) showTextBox = false hideKeyboard() elseif string.byte(key) ~= 44 then -- e.g. filter out commas textBox:acceptKey(key) end end end