metaforce/hecl/driver/ToolCook.hpp

182 lines
8.0 KiB
C++
Raw Normal View History

2018-10-07 03:38:44 +00:00
#pragma once
2015-06-10 02:40:03 +00:00
#include "ToolBase.hpp"
2017-12-29 07:56:31 +00:00
#include <cstdio>
2017-10-25 07:46:32 +00:00
#include "hecl/ClientProcess.hpp"
2015-06-10 02:40:03 +00:00
class ToolCook final : public ToolBase
{
2016-03-04 23:02:44 +00:00
std::vector<hecl::ProjectPath> m_selectedItems;
std::unique_ptr<hecl::Database::Project> m_fallbackProj;
hecl::Database::Project* m_useProj;
2018-03-23 21:40:12 +00:00
const hecl::Database::DataSpecEntry* m_spec = nullptr;
2015-09-30 06:23:07 +00:00
bool m_recursive = false;
2015-10-22 02:01:08 +00:00
bool m_fast = false;
2015-06-10 02:40:03 +00:00
public:
ToolCook(const ToolPassInfo& info)
2015-09-30 06:23:07 +00:00
: ToolBase(info), m_useProj(info.project)
2015-06-10 02:40:03 +00:00
{
2015-10-16 00:34:47 +00:00
/* Check for recursive flag */
2016-03-04 23:02:44 +00:00
for (hecl::SystemChar arg : info.flags)
2018-10-14 20:09:15 +00:00
if (arg == _SYS_STR('r'))
2015-10-16 00:34:47 +00:00
m_recursive = true;
2015-09-30 06:23:07 +00:00
/* Scan args */
if (info.args.size())
{
/* See if project path is supplied via args and use that over the getcwd one */
2015-10-04 04:35:18 +00:00
m_selectedItems.reserve(info.args.size());
2016-03-04 23:02:44 +00:00
for (const hecl::SystemString& arg : info.args)
2015-09-30 06:23:07 +00:00
{
if (arg.empty())
continue;
2018-10-14 20:09:15 +00:00
else if (!arg.compare(_SYS_STR("--fast")))
2015-10-22 02:01:08 +00:00
{
m_fast = true;
continue;
}
2018-10-14 20:09:15 +00:00
else if (arg.size() >= 8 && !arg.compare(0, 7, _SYS_STR("--spec=")))
2018-03-23 21:40:12 +00:00
{
hecl::SystemString specName(arg.begin() + 7, arg.end());
for (const hecl::Database::DataSpecEntry* spec : hecl::Database::DATA_SPEC_REGISTRY)
{
if (!hecl::StrCaseCmp(spec->m_name.data(), specName.c_str()))
{
m_spec = spec;
break;
}
}
if (!m_spec)
LogModule.report(logvisor::Fatal, "unable to find data spec '%s'", specName.c_str());
continue;
}
2018-10-14 20:09:15 +00:00
else if (arg.size() >= 2 && arg[0] == _SYS_STR('-') && arg[1] == _SYS_STR('-'))
2015-10-22 02:01:08 +00:00
continue;
2016-03-04 23:02:44 +00:00
hecl::SystemString subPath;
hecl::ProjectRootPath root = hecl::SearchForProject(MakePathArgAbsolute(arg, info.cwd), subPath);
2015-09-30 06:23:07 +00:00
if (root)
{
if (!m_fallbackProj)
{
2016-03-04 23:02:44 +00:00
m_fallbackProj.reset(new hecl::Database::Project(root));
2015-09-30 06:23:07 +00:00
m_useProj = m_fallbackProj.get();
}
else if (m_fallbackProj->getProjectRootPath() != root)
2016-03-04 23:02:44 +00:00
LogModule.report(logvisor::Fatal,
2018-10-14 20:09:15 +00:00
_SYS_STR("hecl cook can only process multiple items in the same project; ")
_SYS_STR("'%s' and '%s' are different projects"),
2017-11-13 06:13:53 +00:00
m_fallbackProj->getProjectRootPath().getAbsolutePath().data(),
root.getAbsolutePath().data());
2015-09-30 06:23:07 +00:00
m_selectedItems.emplace_back(*m_useProj, subPath);
}
}
}
if (!m_useProj)
2016-03-04 23:02:44 +00:00
LogModule.report(logvisor::Fatal,
2015-09-30 06:23:07 +00:00
"hecl cook must be ran within a project directory or "
"provided a path within a project");
2015-06-10 02:40:03 +00:00
2015-09-30 06:23:07 +00:00
/* Default case: recursive at root */
if (m_selectedItems.empty())
2015-10-04 04:35:18 +00:00
{
m_selectedItems.reserve(1);
2018-10-14 20:09:15 +00:00
m_selectedItems.push_back({hecl::ProjectPath(*m_useProj, _SYS_STR(""))});
2015-10-04 04:35:18 +00:00
m_recursive = true;
}
2015-06-10 02:40:03 +00:00
}
static void Help(HelpOutput& help)
{
2018-10-14 20:09:15 +00:00
help.secHead(_SYS_STR("NAME"));
2015-06-10 02:40:03 +00:00
help.beginWrap();
2018-10-14 20:09:15 +00:00
help.wrap(_SYS_STR("hecl-cook - Cook objects within the project database\n"));
2015-06-10 02:40:03 +00:00
help.endWrap();
2018-10-14 20:09:15 +00:00
help.secHead(_SYS_STR("SYNOPSIS"));
2015-06-10 02:40:03 +00:00
help.beginWrap();
2018-10-14 20:09:15 +00:00
help.wrap(_SYS_STR("hecl cook [-rf] [--fast] [--spec=<spec>] [<pathspec>...]\n"));
2015-06-10 02:40:03 +00:00
help.endWrap();
2018-10-14 20:09:15 +00:00
help.secHead(_SYS_STR("DESCRIPTION"));
2015-06-10 02:40:03 +00:00
help.beginWrap();
2018-10-14 20:09:15 +00:00
help.wrap(_SYS_STR("This command initiates a cooking pass on the project database. Cooking ")
_SYS_STR("is analogous to compiling in software development. The resulting object buffers ")
_SYS_STR("are cached within the project database. HECL performs the following ")
_SYS_STR("tasks for each object during the cook process:\n\n"));
help.wrapBold(_SYS_STR("- Object Gather: "));
help.wrap(_SYS_STR("Files added with "));
help.wrapBold(_SYS_STR("hecl add"));
help.wrap(_SYS_STR(" are queried for their dependent files (e.g. "));
help.wrapBold(_SYS_STR(".blend"));
help.wrap(_SYS_STR(" files return any linked "));
help.wrapBold(_SYS_STR(".png"));
help.wrap(_SYS_STR(" images). If the dependent files are unable to be found, the cook process aborts.\n\n"));
help.wrapBold(_SYS_STR("- Modtime Comparison: "));
help.wrap(_SYS_STR("Files that have previously finished a cook pass are inspected for their time of ")
_SYS_STR("last modification. If the file hasn't changed since its previous cook-pass, the ")
_SYS_STR("process is skipped. If the file has been moved or deleted, the object is automatically ")
_SYS_STR("removed from the project database.\n\n"));
help.wrapBold(_SYS_STR("- Cook: "));
help.wrap(_SYS_STR("A type-specific procedure compiles the file's contents into an efficient format ")
_SYS_STR("for use by the runtime. A data-buffer is provided to HECL.\n\n"));
help.wrapBold(_SYS_STR("- Hash and Compress: "));
help.wrap(_SYS_STR("The data-buffer is hashed and compressed before being cached in the object database.\n\n"));
2015-06-10 02:40:03 +00:00
help.endWrap();
2018-10-14 20:09:15 +00:00
help.secHead(_SYS_STR("OPTIONS"));
help.optionHead(_SYS_STR("<pathspec>..."), _SYS_STR("input file(s)"));
2015-06-10 02:40:03 +00:00
help.beginWrap();
2018-10-14 20:09:15 +00:00
help.wrap(_SYS_STR("Specifies working file(s) containing production data to be cooked by HECL. ")
_SYS_STR("Glob-strings may be specified (e.g. "));
help.wrapBold(_SYS_STR("*.blend"));
help.wrap(_SYS_STR(") to automatically cook all matching current-directory files in the project database. ")
_SYS_STR("If no path specified, all files in the project database are cooked.\n"));
2015-06-10 02:40:03 +00:00
help.endWrap();
2018-10-14 20:09:15 +00:00
help.optionHead(_SYS_STR("-r"), _SYS_STR("recursion"));
2015-06-10 02:40:03 +00:00
help.beginWrap();
2018-10-14 20:09:15 +00:00
help.wrap(_SYS_STR("Enables recursive file-matching for cooking entire directories of working files.\n"));
2015-06-10 02:40:03 +00:00
help.endWrap();
2018-10-14 20:09:15 +00:00
help.optionHead(_SYS_STR("-f"), _SYS_STR("force"));
2015-10-16 00:34:47 +00:00
help.beginWrap();
2018-10-14 20:09:15 +00:00
help.wrap(_SYS_STR("Forces cooking of all matched files, ignoring timestamp differences.\n"));
2015-10-16 00:34:47 +00:00
help.endWrap();
2018-10-14 20:09:15 +00:00
help.optionHead(_SYS_STR("--fast"), _SYS_STR("fast cook"));
2015-10-22 02:01:08 +00:00
help.beginWrap();
2018-10-14 20:09:15 +00:00
help.wrap(_SYS_STR("Performs draft-optimization cooking for supported data types.\n"));
2015-10-22 02:01:08 +00:00
help.endWrap();
2018-03-23 21:40:12 +00:00
2018-10-14 20:09:15 +00:00
help.optionHead(_SYS_STR("--spec=<spec>"), _SYS_STR("data specification"));
2018-03-23 21:40:12 +00:00
help.beginWrap();
2018-10-14 20:09:15 +00:00
help.wrap(_SYS_STR("Specifies a DataSpec to use when cooking. ")
_SYS_STR("This build of hecl supports the following values of <spec>:\n"));
2018-03-23 21:40:12 +00:00
for (const hecl::Database::DataSpecEntry* spec : hecl::Database::DATA_SPEC_REGISTRY)
{
if (!spec->m_factory)
continue;
2018-10-14 20:09:15 +00:00
help.wrap(_SYS_STR(" "));
2018-03-23 21:40:12 +00:00
help.wrapBold(spec->m_name.data());
2018-10-14 20:09:15 +00:00
help.wrap(_SYS_STR("\n"));
2018-03-23 21:40:12 +00:00
}
2015-06-10 02:40:03 +00:00
}
2018-10-14 20:09:15 +00:00
hecl::SystemString toolName() const {return _SYS_STR("cook");}
2015-06-10 02:40:03 +00:00
int run()
{
2018-03-23 21:40:12 +00:00
hecl::MultiProgressPrinter printer(true);
2018-05-25 06:34:58 +00:00
hecl::ClientProcess cp(&printer);
2018-06-16 02:26:30 +00:00
for (const hecl::ProjectPath& path : m_selectedItems)
m_useProj->cookPath(path, printer, m_recursive, m_info.force, m_fast, m_spec, &cp);
2017-10-25 07:46:32 +00:00
cp.waitUntilComplete();
2015-06-10 02:40:03 +00:00
return 0;
}
void cancel()
{
m_useProj->interruptCook();
}
2015-06-10 02:40:03 +00:00
};