Director class - check this out!

Hey everybody!!!

I’m so pleased to show you something that I’m working on, the Director class (module)!!

With this class, everyone can easily create transitions between scenes (lua files) and make the work easier then ever!

Ex: You have a main.lua and need 50 other lua files each one for a totally different thing. With director class, all you need to do is this command:

director.loadScene("settings","moveFromLeft")

It will animate the transition and allocate/free memory and graphics!

Check this out: http://bit.ly/ayCHAb

When I finish it, I will send to Ansca to put on “Code” page! [import]uid: 8556 topic_id: 2447 reply_id: 302447[/import]

Excellent news for a much wanted feature!

I am looking forward to your Director class. Is it going to handle (remove from memory) tables, listeners and other data-related memory consumers created inside the lua files?

Many thanks! [import]uid: 7356 topic_id: 2447 reply_id: 7211[/import]

Thanks Magenda!

For now, I’m using the “tab bar” example for controlling that. Each lua file must have a display group and the functions new() and cleanUp() that are called from director. [import]uid: 8556 topic_id: 2447 reply_id: 7212[/import]

Nice - seems cool - looking forward to the finished project.

Thanks for sharing! [import]uid: 4621 topic_id: 2447 reply_id: 7213[/import]

Very nice. Looking forward when you share it. let us know too so we can post it and blog about it.

c [import]uid: 24 topic_id: 2447 reply_id: 7214[/import]

Finished!

http://developer.anscamobile.com/code/director-class-10

Please do some feedback! [import]uid: 8556 topic_id: 2447 reply_id: 7229[/import]

Ricardo, thanks for sharing! Excellent set of transitions…

Some notes:
Why don’t you replace the multiple fxEnded local functions with a single one out of the “if then elseif” statement.

Also, inside that fxEnded function you only remove the previous display group.
Consider adding a child=nil assignment in order to also delete other data the user has attached to the display group’s table. Same applies for the group’s object, so I would firstly cycle through the child’s children and remove + nulify them.
Thanks again [import]uid: 7356 topic_id: 2447 reply_id: 7253[/import]

Magenda,

Each effect has it’s own logic, so I decided to create that fxEnded to personalize them. The fade effect, for example, is not like moveFromLeft.

For the child display groups is a good idea to make a recursive function, I will work on it!

Thanks a lot! [import]uid: 8556 topic_id: 2447 reply_id: 7257[/import]

Ricardo, from what I see you use fxEnded for two things:
a) reset vars
b) removals

So, b) could be isolated and delivered from a function outside your “if” statement. This would make the code cleaner and your future work on improving the function simpler, as you would only change it in one point instead of 10.

Having said that, I like your project very much. What I think is missing for consider it perfect is a better memory cleaner that would automate the whole process of “deleting” the previous screen and all of its memory consumers. I am a newbie in lua, but I am going to try helping on that…

Thanks for sharing your work with us!

[import]uid: 7356 topic_id: 2447 reply_id: 7258[/import]

Ricardo,
Thanks for sharing this utility!!! It looks very nice. [import]uid: 8194 topic_id: 2447 reply_id: 7272[/import]

Ok, let’s improve that! I putted the fxEnded out of the changeScene function, it’s now like this:

local function fxEnded ( event )  
  
 currentView.x = 0  
 currentView.y = 0  
 currentView.xScale = 1  
 currentView.yScale = 1  
 --  
 while (currentView.numChildren \> 0) do  
 currentView[currentView.numChildren] = nil  
 currentView:remove(currentView.numChildren)  
 end  
 --  
 currentScreen = nextScreen  
 currentView:insert(currentScreen)  
 nextView.x = display.contentWidth  
 nextView.y = 0  
 nextView.xScale = 1  
 nextView.yScale = 1  
  
end  

The problem is that because of that currentView[currentView.numChildren] = nil assignment, I’m getting the message WARNING: Attempting to set property(1) with nil at the Terminal. Is that right? Carlos? [import]uid: 8556 topic_id: 2447 reply_id: 7273[/import]

I suppose it doesn’t compile properly (not at home right now), but I would make it this way:
[lua]for child=currentView.numChildren,1,-1 do

for childofchild=currentView[child].numChildren,1,-1 do
currentView[child]:remove(childofchild)
currentView[child][childofchild] = nil
end

currentView:remove(child)
currentView[child] = nil

end[/lua] [import]uid: 7356 topic_id: 2447 reply_id: 7275[/import]

In this case you can only clean 2 levels. I’m thinking in something to go into the entire tree.

Imagine this:

local g1 = display.newGroup()  
local g2 = display.newGroup()  
local g3 = display.newGroup()  
local g4 = display.newGroup()  
  
g1:insert(g2)  
g2:insert(g3)  
g3:insert(g4)  
  
local q1 = display.newImage("logo.png",100,100)  
local q2 = display.newImage("logo.png",300,100)  
local q3 = display.newImage("logo.png",100,300)  
local q4 = display.newImage("logo.png",300,300)  
  
g1:insert(q1)  
g2:insert(q2)  
g3:insert(q3)  
g4:insert(q4)  

How can I go though all four groups and clean them? [import]uid: 8556 topic_id: 2447 reply_id: 7276[/import]

You have right!

Ok, I would first go deep inside the levels checking for the existance of .numChildren with an assert and increasing a “levelsnum” var by +1.

Then I would construct a while loop using .parent to climb up the levels removing+nulifying whatever exists.

Tricky! (but not impossible)
The biggest problem, however, is how to find where listeners and timers are stored to delete them too, climbing all the way up.

I am going to work on it tomorrow… [import]uid: 7356 topic_id: 2447 reply_id: 7278[/import]

Got it!

Check this out:

[code]
local g1 = display.newGroup()
local g2 = display.newGroup()
local g3 = display.newGroup()
local g4 = display.newGroup()

g1:insert(g2)
g2:insert(g3)
g3:insert(g4)

local q1 = display.newImage(“logo.png”,100,100)
local q2 = display.newImage(“logo.png”,300,100)
local q3 = display.newImage(“logo.png”,100,300)
local q4 = display.newImage(“logo.png”,300,300)

g1:insert(q1)
g2:insert(q2)
g3:insert(q3)
g4:insert(q4)

print ("g1.numChildren: " … g1.numChildren)
print ("g2.numChildren: " … g2.numChildren)
print (“g3.numChildren: " … g3.numChildren)
print (“g4.numChildren: " … g4.numChildren)
print (”-----------------------”)

g1.name = “g1”
g2.name = “g2”
g3.name = “g3”
g4.name = “g4”
q1.name = “q1”
q2.name = “q2”
q3.name = “q3”
q4.name = “q4”

print ("g1.name: "…g1.name)
print ("g2.name: "…g2.name)
print ("g3.name: "…g3.name)
print ("g4.name: "…g4.name)
print ("q1.name: "…q1.name)
print ("q2.name: "…q2.name)
print ("q3.name: "…q3.name)
print (“q4.name: “…q4.name)
print (”-----------------------”)

local function cleanGroups ( curGroup )
print ("curGroup = " … tostring(curGroup.name) … " - children = " … tostring(curGroup.numChildren))
if curGroup.numChildren then
while curGroup.numChildren > 0 do
cleanGroups ( curGroup[curGroup.numChildren] )
end
curGroup:removeSelf()
else
curGroup:removeSelf()
curGroup = nil
return
end
end

cleanGroups(g1)

print ("-----------------------")
print ("g1.numChildren: " … tostring(g1.numChildren))
print ("g2.numChildren: " … tostring(g2.numChildren))
print ("g3.numChildren: " … tostring(g3.numChildren))
print ("g4.numChildren: " … tostring(g4.numChildren))
[/code] [import]uid: 8556 topic_id: 2447 reply_id: 7280[/import]

Version 1.1 deployed!

I made some changes to make it better!

  • Best memory clean up
  • Best organization
  • Only one group is needed to insert in main.lua

http://developer.anscamobile.com/code/director-class-10 [import]uid: 8556 topic_id: 2447 reply_id: 7319[/import]

Cleaning up doesn’t seem to work properly.
Try this, for two screens (“p1”,“p2”) that return a “lg” group

[lua]director:changeScene(“p1”,“moveFromRight”)
print(p1.lg==nil) – lg is the returning (global) group of p1 screen

local function onTap(event)
if “began” == event.phase then
director:changeScene(“p2”,“moveFromRight”)
print(p1.lg==nil) --should be nil, but it isn’t
end
end
Runtime:addEventListener(“touch”, onTap) – LISTENER --[/lua]

[import]uid: 7356 topic_id: 2447 reply_id: 7328[/import]

I don’t know exactly what you are trying to do but I’m always getting true using version 1.1 of director class.

[code]
display.setStatusBar( display.HiddenStatusBar )

– Import director class
local director = require(“director”)

– Create a main group
local mainGroup = display.newGroup()

– Main function
local function main()

– Add the group from director class
mainGroup:insert(director.directorView)

– Change scene without effects
director:changeScene(“screen1”)
print(screen1.lg==nil)
local function onTap(event)
if “began” == event.phase then
director:changeScene(“screen2”,“moveFromRight”)
print(screen1.lg==nil) --should be nil, but it isn’t
end
end
Runtime:addEventListener(“touch”, onTap) – LISTENER –

return true
end

– Begin
main()

– It’s that easy! :slight_smile:
[/code] [import]uid: 8556 topic_id: 2447 reply_id: 7330[/import]

Ricardo, you get always true (object==nil) because you have (properly) set your objects as *locals*, so you can not see them from main.lua. You would also get true if you checked for a non-existent variable (because it doesn’t exist, it is “nil”).

Try to set your returning group as a *global* one for it to be accessible from main. You will get false (group table exists after screen change!)

For some reason, function cleanGroups removes the display objects from screen but *do not* nullify the objects as tables. To understand why the latter is essential, imagine a module in which you download 5mb of data from the web and attach this data as a property to the group (group.data), so it can be deleted on screen change. If the group is removed graphically but not deleted as a table, there is no memory management at all. Display objects removal is just the first step. The hard part is tables, timers, listeners etc…
PS: How can I access the current screen’s name from main.lua? Thanks! [import]uid: 7356 topic_id: 2447 reply_id: 7335[/import]

Some variables aren’t accessible programmatically, like timers. I tried to clean all but for some you have to do it manually. If there’s a way to clean up this kind of variables, I will put it into the cleanGroups function! I’m not an expert, I’m still learning how to use Corona.

For now, use can this:

myVar = nil changeScene("scene","effect") [import]uid: 8556 topic_id: 2447 reply_id: 7341[/import]