]> git.tdb.fi Git - libs/game.git/blobdiff - tools/setupgen/enum.cpp
Add a tool for generating setup structs and loaders for them
[libs/game.git] / tools / setupgen / enum.cpp
diff --git a/tools/setupgen/enum.cpp b/tools/setupgen/enum.cpp
new file mode 100644 (file)
index 0000000..b6a40c2
--- /dev/null
@@ -0,0 +1,76 @@
+#include "enum.h"
+#include <msp/io/print.h>
+
+using namespace std;
+using namespace Msp;
+
+Enum::Enum(const string &n):
+       name(n)
+{ }
+
+void Enum::define_type(IO::Base &out) const
+{
+       IO::print(out, "enum class %s\n{\n", name);
+       for(auto i=values.begin();; )
+       {
+               IO::print(out, "\t%s", i->name);
+               if(i->value)
+                       IO::print(out, " = %d", i->value.value());
+               ++i;
+               if(i==values.end())
+                       break;
+               IO::print(out, ",\n");
+       }
+       IO::print(out, "\n};\n");
+}
+
+void Enum::declare_conversions(IO::Base &out) const
+{
+       IO::print(out, "void operator>>(const Msp::LexicalConverter &, %s &);\n", name);
+       IO::print(out, "void operator<<(Msp::LexicalConverter &, %s);\n", name);
+}
+
+void Enum::define_conversions(IO::Base &out) const
+{
+       IO::print(out, "void operator>>(const Msp::LexicalConverter &conv, %s &_e)\n{\n", name);
+       IO::print(out, "\tconst std::string &str = conv.get();\n\t");
+       for(auto i=values.begin(); i!=values.end(); ++i)
+       {
+               if(i!=values.begin())
+                       IO::print(out, "else ");
+               IO::print(out, "if(str==\"%s\")\n\t\t_e = %s::%s;\n\t", i->name, name, i->name);
+       }
+       IO::print(out, "else\n\t\tthrow Msp::lexical_error(Msp::format(\"conversion of '%%s' to %s\", str));\n", name);
+       IO::print(out, "}\n");
+
+       IO::print(out, "\nvoid operator<<(Msp::LexicalConverter &conv, %s _e)\n{\n", name);
+       IO::print(out, "\tswitch(_e)\n\t{\n");
+       for(const Value &v: values)
+               IO::print(out, "\tcase %s::%s: conv.result(\"%s\"); break;\n", name, v.name, v.name);
+       IO::print(out, "\tdefault: conv.result(Msp::format(\"%s(%%#x)\", static_cast<int>(_e)));\n", name);
+       IO::print(out, "\t}\n}\n");
+}
+
+
+Enum::Loader::Loader(Enum &e):
+       ObjectLoader<Enum>(e)
+{
+       static ActionMap shared_actions;
+       set_actions(shared_actions);
+}
+
+void Enum::Loader::init_actions()
+{
+       add("value", &Loader::value);
+       add("value", &Loader::value_auto);
+}
+
+void Enum::Loader::value(const DataFile::Symbol &n, int v)
+{
+       obj.values.emplace_back(n.name, v);
+}
+
+void Enum::Loader::value_auto(const DataFile::Symbol &n)
+{
+       obj.values.emplace_back(n.name);
+}