Author Topic: Is it possible to have solarus functions in a module?  (Read 1771 times)

zutokaza

  • Full Member
  • ***
  • Posts: 146
  • Active - Making stories can take the most time.
    • View Profile
Is it possible to have solarus functions in a module?
« on: September 29, 2016, 03:56:37 am »
I want to make my code shorter because I basically have 3 long scripts in one lua file and it is a bit crazy.

For example,

Code: ( lua) [Select]

--mymodule.lua
local mymodule = {}
--variables

function mymodule.foo()

--solarus image function
blah blah
end

--solarus on_key_pressed function
blah blah
end

end

--map.lua

local mymodule = require "mymodule" -- Will it be out of scope if local?
 
--solarus on_key_pressed function
 mymodule.foo()
end
 

return mymodule
« Last Edit: September 29, 2016, 04:00:24 am by zutokaza »

llamazing

  • Full Member
  • ***
  • Posts: 198
    • View Profile
Re: Is it possible to have solarus functions in a module?
« Reply #1 on: September 29, 2016, 06:38:29 am »
Since your module has an on_key_pressed() function and image function (I'm assuming you mean on_draw()?), you probably want to use a menu. It works as just a simple table too if you don't need a menu.

Something like the following:
Code: (lua) [Select]
--mymodule.lua
local mymodule = {}
--variables

--called on sol.menu.start()
function mymodule:on_started() --only needed if menu
end

--called on sol.menu.stop()
function mymodule:on_finished() --only needed if menu
end

function mymodule:on_draw(dst_surface)
--blah blah
end

function mymodule:on_key_pressed(key, modifiers)
--blah blah
end

function mymodule.myfunction()
--blah blah
end

return mymodule


--map.lua
local mymodule = require "mymodule" --mymodule is a table

function map:on_started()
sol.menu.start(self, mymodule) --only needed if menu
end

function map:on_finished()
sol.menu.stop(mymodule) --only needed if menu
end

mymodule.myfunction() --normal function call

If you want the menu to be run for all maps you can use a metatable:
Code: (lua) [Select]
--you could put this code in mymodule.lua
local map_meta = sol.main.get_metatable"map"
function map_meta:on_started()
sol.menu.start(self, mymodule)
end

function map_meta:on_finished()
sol.menu.stop(mymodule)
end

If using the metatable method, having map:on_started() in an individual map overrides the metatable function.

Also see Christopho's require() tutorial:
https://www.youtube.com/watch?v=CUcfPYMlVs8
« Last Edit: September 29, 2016, 06:47:46 am by llamazing »

zutokaza

  • Full Member
  • ***
  • Posts: 146
  • Active - Making stories can take the most time.
    • View Profile
Re: Is it possible to have solarus functions in a module?
« Reply #2 on: September 29, 2016, 08:17:08 am »
I will go ahead and try it. Thank you llamazing!  :D

MetalZelda

  • Hero Member
  • *****
  • Posts: 551
    • View Profile
Re: Is it possible to have solarus functions in a module?
« Reply #3 on: September 29, 2016, 02:45:10 pm »
It depends on how and where and in which context you want to use your menu

Let's assume that your script and menu will belong to map and you start it from map:on_started()
llamazing example is correct, but if you want to make something special in your map script, let's say something like

function map:on_started(destination)
  blablabla coding stuff
end

the menu will not start because the function is overwritten by your map script (correct me if I'm wrong)

The other solution will be to add this module and start it in game:on_map_changed(map), it does the same thing, you don't even need to stop it as a menu with "map" as context is automatically stopped when the map it belongs no longer exist
« Last Edit: September 29, 2016, 02:49:36 pm by MetalZelda »

Diarandor

  • Hero Member
  • *****
  • Posts: 1047
  • Cats are cool! (ΦωΦ)
    • View Profile
Re: Is it possible to have solarus functions in a module?
« Reply #4 on: September 29, 2016, 02:57:58 pm »
Another solution is to use the function defined in the multi_events.lua script that Christopho made a few weeks ago:
https://github.com/christopho/solarus-alttp-pack/blob/dev/data/scripts/multi_events.lua
“If you make people think they're thinking, they'll love you. But if you really make them think, they'll hate you.”

llamazing

  • Full Member
  • ***
  • Posts: 198
    • View Profile
Re: Is it possible to have solarus functions in a module?
« Reply #5 on: September 29, 2016, 03:27:14 pm »
Another solution is to use the function defined in the multi_events.lua script that Christopho made a few weeks ago:
https://github.com/christopho/solarus-alttp-pack/blob/dev/data/scripts/multi_events.lua
How does the multi_events.lua script work in regard to map:on_started()? Correct me if I'm wrong, but you wouldn't want to do the following in a map script...
Code: (lua) [Select]
local map = ...

map:register_event("on_started", function()
--blah blah
end)

...because the map script gets executed every time the player enters the map, each time registering a new on_started function to the multi_events, and the on_started events registered from all the previous times the player entered the map would be undesirable.
« Last Edit: September 29, 2016, 03:34:13 pm by llamazing »

Diarandor

  • Hero Member
  • *****
  • Posts: 1047
  • Cats are cool! (ΦωΦ)
    • View Profile
Re: Is it possible to have solarus functions in a module?
« Reply #6 on: September 29, 2016, 03:50:25 pm »
When you leave a map, the engine destroys it (with all its code). So when you come back to the map, the code you have added before (with the register_event function) no longer exists and has to be added again. Only the code of the map metatable is kept when you leave a map.

The point is that you can avoid "overwriting" the event of your map script if you use that function, because the multi_events script just adds the new code at the end of the existing code of your event, without "overwriting" it.
« Last Edit: September 29, 2016, 03:52:05 pm by Diarandor »
“If you make people think they're thinking, they'll love you. But if you really make them think, they'll hate you.”

Christopho

  • Administrator
  • Hero Member
  • *****
  • Posts: 1176
    • View Profile
Re: Is it possible to have solarus functions in a module?
« Reply #7 on: September 29, 2016, 04:45:36 pm »
The "map" variable is a different one every time the players enters the map. It is true that the map script gets executed every time the player enters the map, but since the map variable is a new one, it will only have one on_started event. And the old map and its event will be garbage collected eventually (unless you keep references to them somewhere).

To sum up, if your project has the multi_events.lua script, then you have the choice between two approaches for all events:
Code: (lua) [Select]
local map = ...

-- The traditional way still works:
function map:on_started()
  -- blah blah
end


Code: (lua) [Select]
local map = ...

require("multi_events")

-- This approach allows to register several functions to the same event:
map:register_event("on_started", function()
        -- blah blah
end)

You can use the multi_events approach when you have the problem of several scripts that want to define the same event. For example, let's say that the dialog box script and the HUD scripts both want to do something in game:on_started().