#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;
+}
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
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());
#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>
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()
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);
}
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;
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;