How to modify config vars correctly/permanently for later updating file on disk?

Hello,

I’m struggling with the configuration system. After reading this, I got half way there: Saving values to a prc file [SOLVED] - #7 by rdb

However, it seems when I change the value of a loaded variable, the change happens in memory but not to the underlying ConfigPage (or something), so it doesn’t get written to disk. Perhaps I’m approaching it completely wrong…I’m having a hard time following the docs, and apparently, I’m the only one who has ever had this problem, so that’s a great feeling…

A distilled version of my code is thus (comments explain the issue best):

from panda3d.core import loadPrcFile, OFileStream, ConfigVariableInt

config = loadPrcFile("myconfig.prc")

def test_write_config():
    s = ConfigVariableInt("mouse-sensitivity")
    print(s.value) # Correctly prints the value loaded from file
    s.setValue(42)
    print(s.value) # Correctly prints the new value just set

    for page in cpMgr.explicit_pages:
        print(page) # Fail: prints contents with old value
        fstream = OFileStream(page.name)
        page.write(fstream) # Fail: writes old contents
        fstream.close()

I guess the issue is going to be painfully obvious, and I’m sure in hindsight, I’ll realize I’ve looked right at the solution 20 times already…

Nevertheless, I’ve been stuck for the past two hours and I give up.

Thanks for reading!

EDIT: I discovered the .getLocalPage() method but it only shows the one modified line, not a complete config I can write out. Maybe there’s some way to write only the changes(s)?

I’m not terribly familiar with this system myself–I just use my own file-saving system to store game-specific data–but, looking around the docs, I think that it may be intended to work thusly:

To store a piece of data in the config, you first either get or make a “page” in the " ConfigPageManager" (“cpMgr”).

This page contains a number of “declarations”; your value should be either added, or, if already present, altered–this is done via the “makeDeclaration” and “modifyDeclaration” methods, respectively.

This should result in your variable being included in the data that will be saved with a write.

(That said, it’s not clear to me how one is intended to find the correct declaration to modify, when the value is present at startup.

Declarations appear to be only accessed via integer index–despite having string names–meaning, I suppose, that one would just… iterate through all of them until the correct one was found…?)

1 Like

Thanks for the reply!

This got me further, and I think from all the pieces, I should be able to hack together the output I want manually. I’ll post my final solution when I’m done. It’s not going to be pretty and feels like this is not the correct way…

Hope someone, some day, can chime in with the intended approach.

Cheers!

1 Like

Here’s what I ended up with:

def write_config():
    """Finalizes changes to explicit config pages loaded in cpMgr & writes them 
    back to their respective files on disk.
    """
    # https://discourse.panda3d.org/t/how-to-modify-config-vars-correctly-permanently-for-later-updating-file-on-disk/31301/2
    # https://discourse.panda3d.org/t/saving-values-to-a-prc-file-solved/7697/7
    for page in cpMgr.explicit_pages:
        for decl in page.declarations:
            decl.setStringValue(repr(decl.variable))

        ofstream = OFileStream(page.name)
        page.write(ofstream)
        ofstream.close()

Thankfully, not as messy as I thought it would be, and I don’t feel quite so bad, since the solution wasn’t terribly obvious.

Still feels like there has to be a better way, but if not, it would be great if a method for the “finalize” part could be added to the ConfigPage object, should anyone who knows how happen to see this. Maybe call it mergeLocalValues() or something.

Cheers!

1 Like

I’m glad that you found a solution that worked! :slight_smile:

As to the addition of a method to ConfigPage, you can always propose that on Panda’s GitHub “Issues” page–or even make the change and propose it as a Pull Request!

1 Like