Synodic-Software / Soul-Engine

Physically based renderer and simulation engine for real-time applications.
GNU General Public License v3.0
42 stars 24 forks source link

Separate Settings into Multiple Files #82

Closed Behemyth closed 7 years ago

Behemyth commented 7 years ago

The settings files were moved to Source Files/Transput as the realization that the module for writing to/from the hard disk will more comprehensive than a simple utility. Serialization and program configuration will use some of the same functions, but will end up doing different tasks. For the initial work, A FileManager.cpp and .h as a namespace for file system and general needs shared by both the serialization and config modules. Archive.h and ArchiveBase.h and their .cpp files can be used for the different formats to write/read. The code currently in Settings.h/.cpp can be initially moved to separate files for this task, but can be further broken up over the next month. Settings.cpp and .h will then be an offshoot that makes use of the Archive and the FileManager utilities to provide human readable and editable format. Moving forward many of these functions can be wrappers around boost and c++ functions to provide a cleaner interface to code with. INI Example

aferritto commented 7 years ago

So what kind of functions would FileManager, Archive, and ArchiveBase have? @Behemyth Archiving seems to be for serialization, but I'm not sure how your envisioning Archive to differ from ArchiveBase.

Behemyth commented 7 years ago

The Base would be the abstract template. If you want to archive to an XML or a Binary file, the actual archive class would be a derived implementation. At this point is would be handling Boost only code, but it could also expand in the future.

Behemyth commented 7 years ago

For instance, the Settings files can override a virtual function Write that ArchiveBase defines, but ArchiveText would write it to text instead of XML

aferritto commented 7 years ago

Okay, thanks. I have a basic layout for the class working. Are you ok with having to #include <boost/serialization/vector.hpp> for the archive to serialize vectors for example? I tried to put all the possible includes in ArchiveBase, but it created some nasty errors.

aferritto commented 7 years ago

So for example, serializing vector as text would be:

#include "ArchiveText.h"
#include <vector>
#include <iostream>
#include <boost/serialization/vector.hpp>

int main() {
    std::string fname = "a.txt";
    std::vector<double> val = { 0.14, 3.33, 66.666, 77.77777, 444. };

    {
        FileSystem::ArchiveText<std::vector<double> > ar(fname, &val);
        ar.Write();
    }

    std::vector<double> val2;
    {
        FileSystem::ArchiveText<std::vector<double> > ar(fname, &val2);
        ar.Read();
    }

    for (auto tmp : val2) {
        std::cout << tmp << " ";
    }
    std::cout << std::endl;

    return 0;
}
Behemyth commented 7 years ago

Yes, I think that for the initial implementation that should work fine. As it is used more and more, includes may need to be cleaned up, but for now it does the job. On a off hand note, is there an /all.hpp include?

aferritto commented 7 years ago

I have not made an all.hpp file. I tried to include all the boost/serialization/*.hpp in ArchiveBase but that created some really messy errors. What would you want in an all.hpp file?

aferritto commented 7 years ago

I have archive functionality split from settings now. Do you still want the API to be

Settings::Read/Write();

instead of instantiating some object like

Settings::Table table;
table.Read/Write();

?

It's currently running as

#include "ArchiveText.h"
#include <iostream>
#include "Settings.h"

int main() {
    Settings::detail::Table table;
    table.Set<int>("answer", 42);

    FileSystem::ArchiveText<Settings::detail::Table> rAR("answer-archive.txt", &table);
    rAR.Write();

    Settings::detail::Table table2;
    FileSystem::ArchiveText<Settings::detail::Table> wAR("answer-archive.txt", &table2);
    wAR.Read();

    std::cout << table2.Get<int>("answer", -1) << std::endl; // this prints 42 to terminal
        return 0;
}

but that was just temporary to get the core functionality working.

aferritto commented 7 years ago

I can also keep the Settings API functions for Read/Write and use polymorphism with ArchiveBase pointers under the hood if you want me to so that the API reamins completely the same.

Behemyth commented 7 years ago

Keeping the Read/Write would keep the external API minimal. A good design choice. Boost libraries usually have an all.hpp file so you do not have to include all the subfiles directly. I don't see one in serialization/ though, my mistake.