Jump to content

Help With a Dilemma


Nycidian

Recommended Posts

In my new submod AManager I am trying to make accessing the components within as similar to a regular component as possible but I am running into an issue.

 

As each version of the main component has to have a new name for example amanager_1.lua then amanager_2.lua etc. (this is the only way I was able to figure out how to make sure only the highest version was being loaded by a different versions of the sub mod) accessing the correct component requires either knowing which version will be installed (impossible to know as version in different mods will change) or a a secondary function to retrieve the correct component.

 

Currently I am using a secondary function to do this to show what I mean an normal component call might look like this...

GetPlayer().components.amanager_1:OnSave()

but since you don't know if it will be that version currently it will need to be this...

GetPlayer().components.amanager:Get():OnSave()

...where the amanager:Get() function returns the correct version of the possible amanager_# components.

 

However what I would really like to do is figure out a way to assign that function to a components variable like so

GetPlayer().components.<some name> = amanager:Get()

So then I could rename my helper function something other than amanager and assign it to GetPlayer().components.amanager allowing people using the submod to call the correct version in a manner that look like the normal method.

 

Here is the current working module with the submod installed and a test example of another mod with a older version of the submod which does not get loaded.

 

Amanager_multimod_test.zip

 

 

I would like to add this functionality if possible and I can't figure out how to do it yet I have tried multiple ways and none of them work the only methods I have found that worked other than the one I am using currently require assigning variables at the modmain level which won't work for how I want this to function. This isn't all that important as it works as is but If anyone has any ideas I would be grateful.

 

Link to comment
Share on other sites

First thing that popped in my mind:

Have a base components/amanager.lua that never changes from v1.0. Also have a separate file that holds the version of the amanager component and simply returns it (a file with just

return "1.0"
in it, basically). For each subsequent version, add code in a separate file like this:

 

-- upgrade from version 1.0 to 1.1local current_version = require "amanager_version"if current_version <= "1.0" then	local AManager = require "components/amanager"	function AManager:FuncName()		-- overwrite FuncName	end	-- remove function	AManager.BadFunc = nil	-- bump up the current version	current_version = "1.1"end
and then load each of these types of upgrade files (in ascending order by version number) from modmain using modimport/require. This should make it so that the amanager component is always upgraded to the latest version; you'd just have to make sure that all your upgrades leave everything backwards-compatible.

Note: current_version might not be updated in this case, because I'm not sure that you'd get a reference to the string that's returned from require. Mind is blanking on that at the moment; might need to wrap amanager_version.lua's return in a table.

EDIT: Also make sure to require "amanager_version" from modmain in all versions, so that the initial value gets cached.

Link to comment
Share on other sites

EDIT: Also make sure to require "amanager_version" from modmain in all versions, so that the initial value gets cached.

 

 

That right there won't work for I want to do as what I want is for the only thing another person using this sub mod to have to do is add the following to the top of there modmain.

modimport("amanager/start.lua")

As it is it works they just have to access the changing component through a function which is somewhat annoying but works how it should.

 

Although if I can add the require at the top of start.lua file and have it work it would work. 

 

I'm not entirely sure how the import is working I thought originally it was basically writing the imported file as code into the file but the variables don't work exactly like that.

Link to comment
Share on other sites

Although if I can add the require at the top of start.lua file and have it work it would work.

Yep, that'd work. It just needs to be required before upgrade scripts run. For example, let's say a mod with version 1.0 runs start.lua and no upgrade scripts are run. Afterwards, a mod with version 1.1 runs start.lua, so it'd run the 1.0 -> 1.1 upgrade script, but in the upgrade script it'd actaully require its own amanager_version (since it's the first time it's been required) and get back 1.1 so it wouldn't upgrade (even though the current component is actually version 1.0).

I believe you could do something like this:

<modfolder>/amanager/start.lua:

GLOBAL.require "amanager_version"GLOBAL.require "amanager_upgrade"-- rest of the startup stuff

<modfolder>/scripts/amanager_version.lua:

return "1.1"

<modfolder>/scripts/amanager_upgrade.lua:

require "amanager_upgrade/1_0_to_1_1"-- add more requires here for each upgrade script

<modfolder>/scripts/amanager_upgrade/1_0_to_1_1.lua:

-- upgrade from version 1.0 to 1.1local current_version = require "amanager_version"if current_version <= "1.0" then    local AManager = require "components/amanager"     function AManager:FuncName()        -- overwrite FuncName    end    -- bump up the current version    current_version = "1.1"end

EDIT: This forum is literally the worst at formatting. I don't even use the WYSIWYG editor and yet it insists that it knows better than me about where I intend newlines to go.

Link to comment
Share on other sites

Actually, amanager_upgrade.lua shouldn't be required, it should be loaded without caching (forget the function for doing that; something like kleiloadfile and then pcall?).

 

While I appreciate the help I will admit at this point I am lost with what you are trying to show me I'm debating if its worth it for this as it will work now and the only reason to change it is to make it simpler for moders to use my submod but to be honest the only people who might use my mod honestly probably don't need it to be as simple as I am making it.

 

I am tempted to put this on the back burner except for the fact that once I release the first version of this submod because of how it works allot of it I won't be able to change and have it compatible with the older versions.

 

 

What I would really like is some secondary opinions on whether it significant if you have to call the functions through amanager:Get():functionName() vs.  just amanager:functionName()?

Link to comment
Share on other sites

While I appreciate the help I will admit at this point I am lost with what you are trying to show me I'm debating if its worth it for this as it will work now and the only reason to change it is to make it simpler for moders to use my submod but to be honest the only people who might use my mod honestly probably don't need it to be as simple as I am making it.

No worries, I'll try to write up a test to see if it'd actually function the way I think it would and post it here with the results when I'm done.

Link to comment
Share on other sites

@Nycidian

I was making things way more complicated than they needed to be. Here's a test using 3 mods with 3 different AManager versions:

AManager_testmods.zip

I tried to explain things in the comments, but let me know if you have any questions about how anything works. If you're unfamiliar with require, this and/or this may help explain it.

Also note that this:

	-- load the local version in its place	AManager = require "components/amanager"
only gets the local version because when each mod is loaded, <modfolder>/scripts/?.lua gets added to the front of the search paths (the package.path variable), meaning whichever mod is currently being loaded will have their files take precedence when require is called (but only if there is no entry in package.loaded for that module).
Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

Please be aware that the content of this thread may be outdated and no longer applicable.

×
  • Create New...