metaforce/hecl/lib/Project.cpp

580 lines
16 KiB
C++
Raw Normal View History

2015-05-21 02:33:05 +00:00
#include <sys/stat.h>
2017-12-29 07:56:31 +00:00
#include <cerrno>
#include <cstdio>
#include <cstring>
2015-05-21 02:33:05 +00:00
#include <system_error>
2015-06-10 23:34:14 +00:00
#if _WIN32
#else
#include <unistd.h>
#endif
2016-03-04 23:02:44 +00:00
#include "hecl/Database.hpp"
2017-12-29 07:56:31 +00:00
#include "hecl/Blender/Connection.hpp"
2017-10-25 07:46:32 +00:00
#include "hecl/ClientProcess.hpp"
2015-05-21 02:33:05 +00:00
2017-12-29 07:56:31 +00:00
namespace hecl::Database
2015-05-21 02:33:05 +00:00
{
2016-09-25 01:57:43 +00:00
logvisor::Module LogModule("hecl::Database");
static const hecl::FourCC HECLfcc("HECL");
2015-06-09 23:21:45 +00:00
/**********************************************
* Project::ConfigFile
**********************************************/
2015-06-09 22:19:59 +00:00
static inline bool CheckNewLineAdvance(std::string::const_iterator& it)
{
2015-06-10 23:34:14 +00:00
if (*it == '\n')
2015-06-09 22:19:59 +00:00
{
it += 1;
return true;
}
else if (*it == '\r')
{
if (*(it+1) == '\n')
{
it += 2;
return true;
}
2015-06-10 23:34:14 +00:00
it += 1;
return true;
2015-06-09 22:19:59 +00:00
}
return false;
}
2017-11-13 06:13:53 +00:00
Project::ConfigFile::ConfigFile(const Project& project, SystemStringView name,
SystemStringView subdir)
2015-05-21 02:33:05 +00:00
{
2017-11-13 06:13:53 +00:00
m_filepath = SystemString(project.m_rootPath.getAbsolutePath()) + subdir.data() + name.data();
2015-06-09 22:57:21 +00:00
}
2015-06-09 22:19:59 +00:00
2015-10-04 04:35:18 +00:00
std::vector<std::string>& Project::ConfigFile::lockAndRead()
2015-06-09 22:57:21 +00:00
{
2015-06-10 23:34:14 +00:00
if (m_lockedFile)
return m_lines;
2016-03-04 23:02:44 +00:00
m_lockedFile = hecl::Fopen(m_filepath.c_str(), _S("a+"), FileLockType::Write);
2017-10-25 07:46:32 +00:00
hecl::FSeek(m_lockedFile, 0, SEEK_SET);
2015-06-09 22:19:59 +00:00
2015-06-09 22:57:21 +00:00
std::string mainString;
char readBuf[1024];
size_t readSz;
2015-06-10 23:34:14 +00:00
while ((readSz = fread(readBuf, 1, 1024, m_lockedFile)))
2015-06-09 22:57:21 +00:00
mainString += std::string(readBuf, readSz);
2015-06-09 22:19:59 +00:00
2015-06-09 22:57:21 +00:00
std::string::const_iterator begin = mainString.begin();
std::string::const_iterator end = mainString.begin();
2015-06-09 22:19:59 +00:00
2015-06-10 23:34:14 +00:00
m_lines.clear();
2015-06-09 22:57:21 +00:00
while (end != mainString.end())
{
std::string::const_iterator origEnd = end;
if (*end == '\0')
break;
else if (CheckNewLineAdvance(end))
2015-06-09 22:19:59 +00:00
{
2015-06-09 22:57:21 +00:00
if (begin != origEnd)
2015-06-10 23:34:14 +00:00
m_lines.push_back(std::string(begin, origEnd));
2015-06-09 22:57:21 +00:00
begin = end;
continue;
2015-06-09 22:19:59 +00:00
}
2015-06-09 22:57:21 +00:00
++end;
}
if (begin != end)
2015-06-10 23:34:14 +00:00
m_lines.push_back(std::string(begin, end));
2015-06-09 22:19:59 +00:00
2015-06-10 23:34:14 +00:00
return m_lines;
2015-06-09 22:57:21 +00:00
}
2015-06-09 22:19:59 +00:00
2017-11-13 06:13:53 +00:00
void Project::ConfigFile::addLine(std::string_view line)
2015-06-09 22:57:21 +00:00
{
2015-06-10 23:34:14 +00:00
if (!checkForLine(line))
2017-11-13 06:13:53 +00:00
m_lines.emplace_back(line);
2015-06-09 22:57:21 +00:00
}
2015-05-21 02:33:05 +00:00
2017-11-13 06:13:53 +00:00
void Project::ConfigFile::removeLine(std::string_view refLine)
2015-06-09 22:57:21 +00:00
{
2015-06-10 23:34:14 +00:00
if (!m_lockedFile)
{
2016-03-04 23:02:44 +00:00
LogModule.reportSource(logvisor::Fatal, __FILE__, __LINE__,
2015-07-18 04:35:01 +00:00
"Project::ConfigFile::lockAndRead not yet called");
return;
}
2015-05-21 02:33:05 +00:00
2015-06-11 09:41:10 +00:00
for (auto it = m_lines.begin();
2015-06-13 20:10:37 +00:00
it != m_lines.end();)
2015-05-21 02:33:05 +00:00
{
2015-06-10 23:34:14 +00:00
if (!(*it).compare(refLine))
2015-06-13 20:10:37 +00:00
{
2015-06-10 23:34:14 +00:00
it = m_lines.erase(it);
2015-06-13 20:10:37 +00:00
continue;
}
++it;
2015-05-21 02:33:05 +00:00
}
2015-06-09 22:57:21 +00:00
}
2015-05-21 02:33:05 +00:00
2017-11-13 06:13:53 +00:00
bool Project::ConfigFile::checkForLine(std::string_view refLine)
2015-06-09 22:57:21 +00:00
{
2015-06-10 23:34:14 +00:00
if (!m_lockedFile)
{
2016-03-04 23:02:44 +00:00
LogModule.reportSource(logvisor::Fatal, __FILE__, __LINE__,
2015-07-18 04:35:01 +00:00
"Project::ConfigFile::lockAndRead not yet called");
return false;
}
2015-06-10 23:34:14 +00:00
for (const std::string& line : m_lines)
2015-06-09 22:57:21 +00:00
if (!line.compare(refLine))
return true;
return false;
}
2015-05-21 02:33:05 +00:00
2015-06-10 23:34:14 +00:00
void Project::ConfigFile::unlockAndDiscard()
{
if (!m_lockedFile)
{
2016-03-04 23:02:44 +00:00
LogModule.reportSource(logvisor::Fatal, __FILE__, __LINE__,
2015-07-18 04:35:01 +00:00
"Project::ConfigFile::lockAndRead not yet called");
return;
}
2015-06-10 23:34:14 +00:00
m_lines.clear();
fclose(m_lockedFile);
m_lockedFile = NULL;
}
2015-06-11 09:41:10 +00:00
bool Project::ConfigFile::unlockAndCommit()
2015-06-10 23:34:14 +00:00
{
if (!m_lockedFile)
{
2016-03-04 23:02:44 +00:00
LogModule.reportSource(logvisor::Fatal, __FILE__, __LINE__,
2015-07-18 04:35:01 +00:00
"Project::ConfigFile::lockAndRead not yet called");
return false;
}
2015-06-10 23:34:14 +00:00
2015-06-11 09:41:10 +00:00
SystemString newPath = m_filepath + _S(".part");
2016-03-04 23:02:44 +00:00
FILE* newFile = hecl::Fopen(newPath.c_str(), _S("w"), FileLockType::Write);
2015-06-11 09:41:10 +00:00
bool fail = false;
2015-06-10 23:34:14 +00:00
for (const std::string& line : m_lines)
{
2015-06-11 09:41:10 +00:00
if (fwrite(line.c_str(), 1, line.size(), newFile) != line.size())
{
fail = true;
break;
}
if (fwrite("\n", 1, 1, newFile) != 1)
{
fail = true;
break;
}
2015-06-10 23:34:14 +00:00
}
m_lines.clear();
2015-06-11 09:41:10 +00:00
fclose(newFile);
2015-06-10 23:34:14 +00:00
fclose(m_lockedFile);
m_lockedFile = NULL;
2015-06-11 09:41:10 +00:00
if (fail)
{
2015-07-22 19:14:50 +00:00
#if HECL_UCS2
_wunlink(newPath.c_str());
#else
2015-06-11 09:41:10 +00:00
unlink(newPath.c_str());
2015-07-22 19:14:50 +00:00
#endif
2015-06-11 09:41:10 +00:00
return false;
}
else
{
2015-07-22 19:14:50 +00:00
#if HECL_UCS2
2017-10-30 07:29:07 +00:00
//_wrename(newPath.c_str(), m_filepath.c_str());
2017-11-06 06:56:17 +00:00
MoveFileExW(newPath.c_str(), m_filepath.c_str(), MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH);
2015-07-22 19:14:50 +00:00
#else
2015-06-11 09:41:10 +00:00
rename(newPath.c_str(), m_filepath.c_str());
2015-07-22 19:14:50 +00:00
#endif
2015-06-11 09:41:10 +00:00
return true;
}
2015-06-10 23:34:14 +00:00
}
2015-06-09 23:21:45 +00:00
/**********************************************
* Project
**********************************************/
2015-06-10 02:40:03 +00:00
Project::Project(const ProjectRootPath& rootPath)
2015-06-11 04:55:06 +00:00
: m_rootPath(rootPath),
2015-09-30 06:23:07 +00:00
m_workRoot(*this, _S("")),
m_dotPath(m_workRoot, _S(".hecl")),
2015-07-18 04:35:01 +00:00
m_cookedRoot(m_dotPath, _S("cooked")),
2015-06-11 04:55:06 +00:00
m_specs(*this, _S("specs")),
m_paths(*this, _S("paths")),
2015-06-12 04:02:23 +00:00
m_groups(*this, _S("groups"))
2015-06-09 22:57:21 +00:00
{
/* Stat for existing project directory (must already exist) */
2015-07-22 19:14:50 +00:00
Sstat myStat;
2017-11-13 06:13:53 +00:00
if (hecl::Stat(m_rootPath.getAbsolutePath().data(), &myStat))
2015-07-26 02:52:02 +00:00
{
2017-11-13 06:13:53 +00:00
LogModule.report(logvisor::Error, _S("unable to stat %s"), m_rootPath.getAbsolutePath().data());
2015-07-26 02:52:02 +00:00
return;
}
2015-05-21 02:33:05 +00:00
2015-06-09 22:57:21 +00:00
if (!S_ISDIR(myStat.st_mode))
2015-07-26 02:52:02 +00:00
{
2017-11-13 06:13:53 +00:00
LogModule.report(logvisor::Error, _S("provided path must be a directory; '%s' isn't"),
m_rootPath.getAbsolutePath().data());
2015-07-26 02:52:02 +00:00
return;
}
2015-05-21 02:33:05 +00:00
2015-06-09 22:57:21 +00:00
/* Create project directory structure */
2015-07-18 04:35:01 +00:00
m_dotPath.makeDir();
m_cookedRoot.makeDir();
2015-06-11 09:41:10 +00:00
2015-06-12 04:02:23 +00:00
/* Ensure beacon is valid or created */
2015-07-18 04:35:01 +00:00
ProjectPath beaconPath(m_dotPath, _S("beacon"));
2017-11-13 06:13:53 +00:00
FILE* bf = hecl::Fopen(beaconPath.getAbsolutePath().data(), _S("a+b"));
2015-06-12 04:02:23 +00:00
struct BeaconStruct
{
2016-03-04 23:02:44 +00:00
hecl::FourCC magic;
2015-06-12 04:02:23 +00:00
uint32_t version;
} beacon;
#define DATA_VERSION 1
if (fread(&beacon, 1, sizeof(beacon), bf) != sizeof(beacon))
{
fseek(bf, 0, SEEK_SET);
2015-07-11 22:42:40 +00:00
beacon.magic = HECLfcc;
2015-06-12 04:02:23 +00:00
beacon.version = SBig(DATA_VERSION);
fwrite(&beacon, 1, sizeof(beacon), bf);
}
fclose(bf);
2015-07-11 22:42:40 +00:00
if (beacon.magic != HECLfcc ||
2015-06-12 04:02:23 +00:00
SBig(beacon.version) != DATA_VERSION)
{
2016-03-04 23:02:44 +00:00
LogModule.report(logvisor::Fatal, "incompatible project version");
return;
}
2015-06-12 04:02:23 +00:00
/* Compile current dataspec */
rescanDataSpecs();
2016-01-04 05:25:00 +00:00
m_valid = true;
2015-06-09 22:57:21 +00:00
}
2015-05-21 02:33:05 +00:00
const ProjectPath& Project::getProjectCookedPath(const DataSpecEntry& spec) const
{
for (const ProjectDataSpec& sp : m_compiledSpecs)
if (&sp.spec == &spec)
return sp.cookedPath;
2017-11-14 03:34:05 +00:00
LogModule.report(logvisor::Fatal, "Unable to find spec '%s'", spec.m_name.data());
return m_cookedRoot;
}
2015-06-10 02:40:03 +00:00
bool Project::addPaths(const std::vector<ProjectPath>& paths)
2015-06-09 22:57:21 +00:00
{
2015-06-11 09:41:10 +00:00
m_paths.lockAndRead();
for (const ProjectPath& path : paths)
m_paths.addLine(path.getRelativePathUTF8());
return m_paths.unlockAndCommit();
2015-06-09 22:57:21 +00:00
}
2015-06-09 22:19:59 +00:00
2015-06-10 02:40:03 +00:00
bool Project::removePaths(const std::vector<ProjectPath>& paths, bool recursive)
2015-06-09 22:57:21 +00:00
{
2015-10-04 04:35:18 +00:00
std::vector<std::string>& existingPaths = m_paths.lockAndRead();
2015-06-11 09:41:10 +00:00
if (recursive)
{
for (const ProjectPath& path : paths)
{
2017-11-13 06:13:53 +00:00
auto recursiveBase = path.getRelativePathUTF8();
2015-06-11 09:41:10 +00:00
for (auto it = existingPaths.begin();
2015-06-13 20:12:55 +00:00
it != existingPaths.end();)
2015-06-11 09:41:10 +00:00
{
if (!(*it).compare(0, recursiveBase.size(), recursiveBase))
2015-06-13 20:10:37 +00:00
{
2015-06-11 09:41:10 +00:00
it = existingPaths.erase(it);
2015-06-13 20:10:37 +00:00
continue;
}
++it;
2015-06-11 09:41:10 +00:00
}
}
}
else
for (const ProjectPath& path : paths)
m_paths.removeLine(path.getRelativePathUTF8());
return m_paths.unlockAndCommit();
2015-06-09 22:57:21 +00:00
}
2015-05-21 02:33:05 +00:00
2016-03-04 23:02:44 +00:00
bool Project::addGroup(const hecl::ProjectPath& path)
2015-06-09 22:57:21 +00:00
{
2015-06-11 09:41:10 +00:00
m_groups.lockAndRead();
m_groups.addLine(path.getRelativePathUTF8());
return m_groups.unlockAndCommit();
2015-06-09 22:57:21 +00:00
}
2015-05-21 02:33:05 +00:00
2015-06-10 02:40:03 +00:00
bool Project::removeGroup(const ProjectPath& path)
2015-06-09 22:57:21 +00:00
{
2015-06-11 09:41:10 +00:00
m_groups.lockAndRead();
m_groups.removeLine(path.getRelativePathUTF8());
return m_groups.unlockAndCommit();
2015-06-09 22:57:21 +00:00
}
2015-05-21 02:33:05 +00:00
2015-06-12 04:02:23 +00:00
void Project::rescanDataSpecs()
{
m_compiledSpecs.clear();
m_specs.lockAndRead();
2015-07-01 23:53:05 +00:00
for (const DataSpecEntry* spec : DATA_SPEC_REGISTRY)
2015-06-12 04:02:23 +00:00
{
2016-03-04 23:02:44 +00:00
hecl::SystemString specStr(spec->m_name);
2017-11-13 06:13:53 +00:00
SystemUTF8Conv specUTF8(specStr);
2016-03-04 23:02:44 +00:00
m_compiledSpecs.push_back({*spec, ProjectPath(m_cookedRoot, hecl::SystemString(spec->m_name) + _S(".spec")),
2017-11-13 06:13:53 +00:00
m_specs.checkForLine(specUTF8.str())});
2015-06-12 04:02:23 +00:00
}
m_specs.unlockAndDiscard();
}
2015-06-11 09:41:10 +00:00
bool Project::enableDataSpecs(const std::vector<SystemString>& specs)
2015-06-09 22:57:21 +00:00
{
2015-06-11 09:41:10 +00:00
m_specs.lockAndRead();
for (const SystemString& spec : specs)
2015-07-22 19:14:50 +00:00
{
2017-11-13 06:13:53 +00:00
SystemUTF8Conv specView(spec);
m_specs.addLine(specView.str());
2015-07-22 19:14:50 +00:00
}
2015-07-18 04:35:01 +00:00
bool result = m_specs.unlockAndCommit();
rescanDataSpecs();
return result;
2015-06-09 22:57:21 +00:00
}
2015-06-11 09:41:10 +00:00
bool Project::disableDataSpecs(const std::vector<SystemString>& specs)
2015-06-09 22:57:21 +00:00
{
2015-06-11 09:41:10 +00:00
m_specs.lockAndRead();
for (const SystemString& spec : specs)
2015-07-22 19:14:50 +00:00
{
2017-11-13 06:13:53 +00:00
SystemUTF8Conv specView(spec);
m_specs.removeLine(specView.str());
2015-07-22 19:14:50 +00:00
}
2015-07-18 04:35:01 +00:00
bool result = m_specs.unlockAndCommit();
rescanDataSpecs();
return result;
2015-06-09 22:57:21 +00:00
}
2015-10-04 04:35:18 +00:00
class CookProgress
{
FProgress& m_progFunc;
const SystemChar* m_dir = nullptr;
const SystemChar* m_file = nullptr;
int lidx = 0;
float m_prog = 0.0;
public:
CookProgress(FProgress& progFunc) : m_progFunc(progFunc) {}
void changeDir(const SystemChar* dir) {m_dir = dir; ++lidx;}
void changeFile(const SystemChar* file, float prog) {m_file = file; m_prog = prog;}
void reportFile(const DataSpecEntry* specEnt)
{
SystemString submsg(m_file);
submsg += _S(" (");
2017-11-14 03:34:05 +00:00
submsg += specEnt->m_name.data();
2015-10-04 04:35:18 +00:00
submsg += _S(')');
2017-10-25 07:46:32 +00:00
if (m_progFunc)
m_progFunc(m_dir, submsg.c_str(), lidx, m_prog);
2015-10-04 04:35:18 +00:00
}
2015-10-22 02:01:08 +00:00
void reportFile(const DataSpecEntry* specEnt, const SystemChar* extra)
{
SystemString submsg(m_file);
submsg += _S(" (");
2017-11-14 03:34:05 +00:00
submsg += specEnt->m_name.data();
2015-10-22 02:01:08 +00:00
submsg += _S(", ");
submsg += extra;
submsg += _S(')');
2017-10-25 07:46:32 +00:00
if (m_progFunc)
m_progFunc(m_dir, submsg.c_str(), lidx, m_prog);
}
void reportDirComplete()
{
if (m_progFunc)
m_progFunc(m_dir, nullptr, lidx, 1.0);
2015-10-22 02:01:08 +00:00
}
2015-10-04 04:35:18 +00:00
};
2015-10-22 02:01:08 +00:00
static void VisitFile(const ProjectPath& path, bool force, bool fast,
2017-10-25 07:46:32 +00:00
std::vector<std::unique_ptr<IDataSpec>>& specInsts,
CookProgress& progress, ClientProcess* cp)
2015-06-09 22:57:21 +00:00
{
2017-10-25 07:46:32 +00:00
for (auto& spec : specInsts)
2015-09-30 06:23:07 +00:00
{
2017-12-29 07:56:31 +00:00
if (spec->canCook(path, hecl::blender::SharedBlenderToken))
2015-09-30 06:23:07 +00:00
{
2017-10-25 07:46:32 +00:00
if (cp)
{
cp->addCookTransaction(path, spec.get());
}
else
2015-10-04 04:35:18 +00:00
{
2017-10-25 07:46:32 +00:00
const DataSpecEntry* override = spec->overrideDataSpec(path, spec->getDataSpecEntry(),
2017-12-29 07:56:31 +00:00
hecl::blender::SharedBlenderToken);
2017-10-25 07:46:32 +00:00
if (!override)
continue;
ProjectPath cooked = path.getCookedPath(*override);
if (fast)
cooked = cooked.getWithExtension(_S(".fast"));
if (force || cooked.getPathType() == ProjectPath::Type::None ||
path.getModtime() > cooked.getModtime())
2015-10-22 02:01:08 +00:00
{
2017-10-25 07:46:32 +00:00
progress.reportFile(override);
2017-12-29 07:56:31 +00:00
spec->doCook(path, cooked, fast, hecl::blender::SharedBlenderToken,
2017-10-25 07:46:32 +00:00
[&](const SystemChar* extra)
{
progress.reportFile(override, extra);
});
}
2015-10-04 04:35:18 +00:00
}
2015-09-30 06:23:07 +00:00
}
}
}
2015-10-22 02:01:08 +00:00
static void VisitDirectory(const ProjectPath& dir,
bool recursive, bool force, bool fast,
2017-10-25 07:46:32 +00:00
std::vector<std::unique_ptr<IDataSpec>>& specInsts,
CookProgress& progress, ClientProcess* cp)
2015-09-30 06:23:07 +00:00
{
2017-12-02 05:49:45 +00:00
if (dir.getLastComponent().size() > 1 && dir.getLastComponent()[0] == _S('.'))
2017-10-25 07:46:32 +00:00
return;
2015-10-14 23:06:47 +00:00
std::map<SystemString, ProjectPath> children;
2015-09-30 06:23:07 +00:00
dir.getDirChildren(children);
2015-10-04 04:35:18 +00:00
/* Pass 1: child file count */
int childFileCount = 0;
2015-10-14 23:06:47 +00:00
for (auto& child : children)
2016-03-01 03:05:42 +00:00
if (child.second.getPathType() == ProjectPath::Type::File)
2015-10-04 04:35:18 +00:00
++childFileCount;
/* Pass 2: child files */
int progNum = 0;
float progDenom = childFileCount;
2017-11-13 06:13:53 +00:00
progress.changeDir(dir.getLastComponent().data());
2015-10-14 23:06:47 +00:00
for (auto& child : children)
2015-10-04 04:35:18 +00:00
{
2016-03-01 03:05:42 +00:00
if (child.second.getPathType() == ProjectPath::Type::File)
2015-10-04 04:35:18 +00:00
{
2015-10-14 23:06:47 +00:00
progress.changeFile(child.first.c_str(), progNum++/progDenom);
2017-10-25 07:46:32 +00:00
VisitFile(child.second, force, fast, specInsts, progress, cp);
2015-09-30 06:23:07 +00:00
}
}
2015-10-04 04:35:18 +00:00
progress.reportDirComplete();
/* Pass 3: child directories */
if (recursive)
{
2015-10-14 23:06:47 +00:00
for (auto& child : children)
2015-10-04 04:35:18 +00:00
{
2015-10-14 23:06:47 +00:00
switch (child.second.getPathType())
2015-10-04 04:35:18 +00:00
{
2015-11-21 01:13:06 +00:00
case ProjectPath::Type::Directory:
2015-10-04 04:35:18 +00:00
{
2017-10-25 07:46:32 +00:00
VisitDirectory(child.second, recursive, force, fast, specInsts, progress, cp);
2015-10-04 04:35:18 +00:00
break;
}
default: break;
}
}
}
2015-09-30 06:23:07 +00:00
}
2015-10-22 02:01:08 +00:00
bool Project::cookPath(const ProjectPath& path, FProgress progress,
2017-10-25 07:46:32 +00:00
bool recursive, bool force, bool fast, ClientProcess* cp)
2015-10-04 04:35:18 +00:00
{
/* Construct DataSpec instances for cooking */
2017-10-25 07:46:32 +00:00
if (m_cookSpecs.empty())
{
m_cookSpecs.reserve(m_compiledSpecs.size());
for (const ProjectDataSpec& spec : m_compiledSpecs)
if (spec.active && spec.spec.m_factory)
m_cookSpecs.push_back(std::unique_ptr<IDataSpec>(spec.spec.m_factory(*this, DataSpecTool::Cook)));
}
2015-10-04 04:35:18 +00:00
/* Iterate complete directory/file/glob list */
CookProgress cookProg(progress);
switch (path.getPathType())
2015-09-30 06:23:07 +00:00
{
2015-11-21 01:13:06 +00:00
case ProjectPath::Type::File:
2017-10-25 07:46:32 +00:00
case ProjectPath::Type::Glob:
2015-10-04 04:35:18 +00:00
{
2017-11-13 06:13:53 +00:00
cookProg.changeFile(path.getLastComponent().data(), 0.0);
2017-10-25 07:46:32 +00:00
VisitFile(path, force, fast, m_cookSpecs, cookProg, cp);
2015-10-04 04:35:18 +00:00
break;
}
2015-11-21 01:13:06 +00:00
case ProjectPath::Type::Directory:
2015-10-04 04:35:18 +00:00
{
2017-10-25 07:46:32 +00:00
VisitDirectory(path, recursive, force, fast, m_cookSpecs, cookProg, cp);
2015-10-04 04:35:18 +00:00
break;
}
default: break;
2015-09-30 06:23:07 +00:00
}
return true;
2015-06-09 22:57:21 +00:00
}
2017-10-25 07:46:32 +00:00
bool Project::packagePath(const ProjectPath& path, FProgress progress, bool fast, ClientProcess* cp)
{
/* Construct DataSpec instance for packaging */
const DataSpecEntry* specEntry = nullptr;
bool foundPC = false;
for (const ProjectDataSpec& spec : m_compiledSpecs)
{
if (spec.active && spec.spec.m_factory)
{
if (hecl::StringUtils::EndsWith(spec.spec.m_name, _S("-PC")))
{
foundPC = true;
specEntry = &spec.spec;
}
else if (!foundPC)
{
specEntry = &spec.spec;
}
}
}
2017-10-30 07:29:07 +00:00
if (!specEntry)
LogModule.report(logvisor::Fatal, "No matching DataSpec");
if (!m_lastPackageSpec || m_lastPackageSpec->getDataSpecEntry() != specEntry)
2017-10-25 07:46:32 +00:00
m_lastPackageSpec = std::unique_ptr<IDataSpec>(specEntry->m_factory(*this, DataSpecTool::Package));
if (m_lastPackageSpec->canPackage(path))
{
2017-12-29 07:56:31 +00:00
m_lastPackageSpec->doPackage(path, specEntry, fast, hecl::blender::SharedBlenderToken, progress, cp);
2017-10-25 07:46:32 +00:00
return true;
}
return false;
}
2015-06-09 22:57:21 +00:00
void Project::interruptCook()
{
}
2015-06-10 02:40:03 +00:00
bool Project::cleanPath(const ProjectPath& path, bool recursive)
2015-06-09 22:57:21 +00:00
{
2015-07-22 19:14:50 +00:00
return false;
2015-06-09 22:57:21 +00:00
}
2015-05-21 02:33:05 +00:00
2015-06-11 04:55:06 +00:00
PackageDepsgraph Project::buildPackageDepsgraph(const ProjectPath& path)
2015-05-21 02:33:05 +00:00
{
2015-07-22 19:14:50 +00:00
return PackageDepsgraph();
2015-05-21 02:33:05 +00:00
}
void Project::addBridgePathToCache(uint64_t id, const ProjectPath& path)
{
m_bridgePathCache[id] = path;
}
void Project::clearBridgePathCache()
{
m_bridgePathCache.clear();
}
const ProjectPath* Project::lookupBridgePath(uint64_t id) const
{
auto search = m_bridgePathCache.find(id);
if (search == m_bridgePathCache.cend())
return nullptr;
return &search->second;
}
2015-05-21 02:33:05 +00:00
}