]> git.tdb.fi Git - libs/game.git/commitdiff
Add import functionality for setup modules
authorMikko Rasa <tdb@tdb.fi>
Sun, 8 Jan 2023 12:53:07 +0000 (14:53 +0200)
committerMikko Rasa <tdb@tdb.fi>
Sun, 8 Jan 2023 12:53:07 +0000 (14:53 +0200)
Also install setup definition files so definitions from libraries can be
used.

tools/builder-plugin/gamesetupdefinitions.cpp
tools/builder-plugin/gamesetupdefinitions.h
tools/builder-plugin/gamesetupgenerator.cpp
tools/setupgen/setupgen.cpp
tools/setupgen/setupgen.h

index a6abd23ecda803966e7141d17ffeeb46019d72db..cf4f6cec24fbc97723ab49e3bb1c8d14bb906c72 100644 (file)
@@ -1,7 +1,57 @@
 #include "gamesetupdefinitions.h"
+#include <msp/builder/builder.h>
+#include <msp/builder/component.h>
+#include <msp/datafile/parser.h>
+#include <msp/fs/utils.h>
+#include <msp/io/file.h>
 
+using namespace std;
 using namespace Msp;
 
 GameSetupDefinitions::GameSetupDefinitions(Builder &b, const Component &c, const FS::Path &p):
        SourceFile(b, c, p)
-{ }
+{
+       install_location = "include";
+}
+
+void GameSetupDefinitions::find_dependencies()
+{
+       if(!mtime)
+               return;
+
+       vector<string> imports;
+
+       Cache &cache = package->get_cache();
+       if(mtime<cache.get_mtime() && cache.has_key(this, "imports"))
+               imports = cache.get_values(this, "imports");
+       else
+       {
+               builder.get_logger().log("files", "Reading imports from %s", path.str());
+
+               imports = parse_imports(path);
+               cache.set_values(this, "imports", imports);
+       }
+
+       Tool *generator = builder.get_toolchain().get_tool_for_suffix(FS::extpart(FS::basename(path)));
+
+       BuildInfo binfo = component->get_build_info_for_path(path);
+       for(const string &i: imports)
+               if(Target *imp = builder.get_vfs().find_header(i+".mgs", generator, binfo.incpath))
+                       add_dependency(*imp);
+}
+
+vector<string> GameSetupDefinitions::parse_imports(const FS::Path &fn)
+{
+       vector<string> imports;
+
+       IO::BufferedFile in_file(fn.str());
+       DataFile::Parser parser(in_file, fn.str());
+       while(parser)
+       {
+               DataFile::Statement st = parser.parse();
+               if(st.keyword=="import" && st.args.size()==1)
+                       imports.push_back(st.args.front().get<string>());
+       }
+
+       return imports;
+}
index 090b412a7cdf447e496593613442d3b4ecee66a7..f9e84fb954fe3e53d6acc2cb1a13202df03ba0be 100644 (file)
@@ -9,6 +9,10 @@ public:
        GameSetupDefinitions(Builder &, const Component &, const Msp::FS::Path &);
 
        const char *get_type() const override { return "GameSetupDefinitions"; }
+
+private:
+       void find_dependencies() override;
+       static std::vector<std::string> parse_imports(const Msp::FS::Path &);
 };
 
 #endif
index 3302c214d4cb9cf1f5aa4d02d641b72ced251936..e11355e7a74ee53d54343d8569d5595e38a4a868 100644 (file)
@@ -52,6 +52,12 @@ ExternalTask::Arguments GameSetupGenerator::_run(const CSourceFile &out_src, FS:
        ExternalTask::Arguments argv;
        argv.push_back(tool.get_executable()->get_path().str());
 
+       BuildInfo binfo;
+       out_src.collect_build_info(binfo);
+
+       for(const FS::Path &i: binfo.incpath)
+               argv.push_back("-I"+i.str());
+
        for(const Target *d: out_src.get_dependencies())
                if(const GameSetupDefinitions *defs = dynamic_cast<const GameSetupDefinitions *>(d))
                        argv.push_back(FS::relative(defs->get_path(), work_dir).str());
index 083fc8a96be3e6ec158d18e10de7ca993b2f0bb0..571396ff0cfad6dfe80a26a6e760327aa8a7acf6 100644 (file)
@@ -1,6 +1,8 @@
 #include "setupgen.h"
+#include <algorithm>
 #include <msp/core/getopt.h>
 #include <msp/core/maputils.h>
+#include <msp/fs/stat.h>
 #include <msp/fs/utils.h>
 #include <msp/io/console.h>
 #include <msp/io/print.h>
@@ -11,10 +13,15 @@ using namespace Msp;
 
 SetupGen::SetupGen(int argc, char **argv)
 {
+       vector<string> import_dirs;
+
        GetOpt getopt;
+       getopt.add_option('I', "importdir", import_dirs, GetOpt::REQUIRED_ARG);
        getopt.add_option('o', "output", out_fn, GetOpt::REQUIRED_ARG);
        getopt.add_argument("input_file", in_fn, GetOpt::REQUIRED_ARG);
        getopt(argc, argv);
+
+       import_path.insert(import_path.end(), import_dirs.begin(), import_dirs.end());
 }
 
 int SetupGen::main()
@@ -192,6 +199,7 @@ void SetupGen::Loader::init_actions()
        add("component", &Loader::struct_def, Struct::COMPONENT);
        add("entity", &Loader::struct_def, Struct::ENTITY);
        add("enum", &Loader::enum_def);
+       add("import", &Loader::import);
        add("namespace", &Loader::name_space);
 }
 
@@ -203,6 +211,20 @@ void SetupGen::Loader::enum_def(const DataFile::Symbol &n)
        type.set_enum(*mod.enums.emplace_back(make_unique<Enum>(move(en))));
 }
 
+void SetupGen::Loader::import(const string &n)
+{
+       string fn = n+".mgs";
+       FS::Path full_path;
+       if(!ranges::any_of(obj.import_path, [&full_path, &fn](const FS::Path &p){
+                       full_path = p/fn;
+                       return FS::exists(full_path);
+               }))
+               throw IO::file_not_found(fn);
+
+       obj.load(full_path);
+       obj.headers.insert(n+".h");
+}
+
 void SetupGen::Loader::name_space(const string &ns)
 {
        mod.name_space = ns;
index e4c1b333b2df110130c7ec203d58c3fcbba0839f..1ff2b8d9800af80d626803e4a6907eec25230e14 100644 (file)
@@ -35,12 +35,14 @@ private:
                void init_actions() override;
 
                void enum_def(const Msp::DataFile::Symbol &);
+               void import(const std::string &);
                void name_space(const std::string &);
                void struct_def(Struct::Kind, const Msp::DataFile::Symbol &);
        };
 
        std::string in_fn;
        std::string out_fn;
+       std::vector<Msp::FS::Path> import_path;
        std::list<Module> modules;
        std::map<std::string, Type> types;
        std::vector<std::unique_ptr<Enum>> enums;