Reloading a collection? (SOLVED)

What would be the easiest way to reload a gui collection without switching collections first?
Basically, I want to
msg.post("#mainScreen", “load”)
msg.post("#mainScreen", “unload”)
to reset the current gui to it’s original layout. But this throws an error “The collection ‘mainScreen’ could not be created since there is already a socket with the same name.”

Do I have to switch to a different collection first?

You need wait, until mainScreen have unloaded, and then load it.

function on_message(self, message_id, message, sender)
 if message_id == hash('reset') then
msg.post("#mainScreen", "unload")
elseif message_id == hash('proxy_unloaded') then
 msg.post("#mainScreen", "load")
elseif message_id == hash('proxy_loaded') then 
 msg.post(sender, 'enable')
end
end

Now, just send:

msg.post('.', 'reset')
3 Likes

What should I do if I want to combine this with loading other collections? this way, every time I want to unload something, mainScreen gets loaded.

Hello @ricardovandijke,

I would post a different message for every action I wanted, for example:

msg.post('.', 'reset')
msg.post('.', 'load_level')
msg.post('.', 'level_menu')
msg.post('.', 'win_screen')

And then I would have to listen to the messages:

function on_message(self, message_id, message, sender)
    if message_id == hash('reset') then
        -- reset code here
    elseif message_id == hash('load_level') then
        -- ...
    elseif message_id == hash('level_menu') then 
        -- ...
    elseif message_id == hash('win_screen') then 
        -- ...
    end
end
1 Like

Problem is, If I reload the mainscreen using

function on_message(self, message_id, message, sender)
    if message_id == hash('reset') then
        msg.post("#mainScreen", "unload")
    elseif message_id == hash('proxy_unloaded') then
         msg.post("#mainScreen", "load")
    elseif message_id == hash('proxy_loaded') then 
         msg.post(sender, 'enable')
     end
end

then it loads the main screen even if I want to switch to a different one.

The code you are posting will just exactly do that: load main screen

If you want it to load another collection, change the identifier, for example:

elseif message_id == hash('proxy_unloaded') then
         msg.post("#myOtherCollection", "load")

I shouldve been more clear.
I meant, If i want to add, for example, a Settings screen for my game, I can’t load it, because as soon as mainscreen has unloaded it immediately loads mainscreen again.
can I check which collection has unloaded with an if statement?

I believe the easiest option would be to check the sender to see what script the unload messages comes from.

I am not sure how this would be coded.

1 Like

Ok, as far as I know, the ‘proxy_unloaded’ message is generated automatically by the Defold messaging system, so it will fire every time a collection (any collection) unloads, so, if you don’t want main screen to load then, I guess you would have to remove those lines:

elseif message_id == hash('proxy_unloaded') then
         msg.post("#myOtherCollection", "load")

Although the question is for the Defold pros to answer, my best guess is that the parameter ‘sender’ will give you the identifier of the collection that just unloaded, but you could add a line (or two) to test if this is the case:

elseif message_id == hash('proxy_unloaded') then
    print(sender)
    pprint(message)

And that will hopefully point you in the direction of what you want to implement

Correct. sender is the collection that was unloaded.

I would recommend that you learn and understand how collection proxies work and how you load and unload them. It seems as though you are well underway and I believe the answers in the thread will help you understand them fully.

It can be a hassle to manage the loading and unloading of collections/screens and if you have many different proxies that you load and unload I’d recommend that you spend the time to write your own screen manager to take care of this. If you design it well it can be reused between your projects. You could also take a look at the routing library that was posted a while back. It’s well written and will take care of all your screen management problems.

1 Like

I already got loading and unloading working, but I’ve never tried to “reload” a collection.
If I print the sender I get some kind of url?

something like

elseif message_id == hash('proxy_unloaded') then
   if string.find(sender.path,'mainScreen') then
      load_main(self)
   end
end

doesn’t work because sender is userdata, not a string.
even though

print(sender)

results in ‘url: [main:/loader#mainScreen]’

You should never try to perform string manipulation on userdata or hash since the format of these aren’t guaranteed to stay the same. There’s an excellent post by @jakob.pogulis describing why reverse hashing isn’t even available in release builds.

What you want to do is to compare actual URLs (because that is the kind of userdata object sender is):

  elseif message_id == hash('proxy_unloaded') then
     if sender == msg.url("main:/loader#mainScreen") then
        load_main(self)
     end
  end
4 Likes

Ah, that works perfectly. Thank you!

1 Like