From d1eb133ab529cdae131be7b150209f03189248f3 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Thu, 22 Dec 2022 16:01:43 +0200 Subject: [PATCH] Refactor InternalTask to take a functor This way the tools don't all have to implement the same worker thread boilerplate. --- source/androidmanifestgenerator.cpp | 9 ++++----- source/androidmanifestgenerator.h | 17 +++-------------- source/compilecommandsgenerator.cpp | 15 +++++++-------- source/compilecommandsgenerator.h | 17 +++-------------- source/copy.cpp | 18 ++++++++---------- source/copy.h | 21 +++------------------ source/internaltask.cpp | 16 ++++++++++++---- source/internaltask.h | 18 +++++++++++------- source/pkgconfiggenerator.cpp | 17 ++++++++--------- source/pkgconfiggenerator.h | 20 ++++---------------- source/tar.cpp | 18 ++++++------------ source/tar.h | 20 ++++---------------- source/vcxprojectgenerator.cpp | 15 +++++++-------- source/vcxprojectgenerator.h | 17 +++-------------- source/vssolutiongenerator.cpp | 15 +++++++-------- source/vssolutiongenerator.h | 17 +++-------------- 16 files changed, 93 insertions(+), 177 deletions(-) diff --git a/source/androidmanifestgenerator.cpp b/source/androidmanifestgenerator.cpp index 8268bb8..70b1e20 100644 --- a/source/androidmanifestgenerator.cpp +++ b/source/androidmanifestgenerator.cpp @@ -3,6 +3,7 @@ #include "androidmanifestfile.h" #include "androidmanifestgenerator.h" #include "component.h" +#include "internaltask.h" #include "sharedlibrary.h" #include "sourcepackage.h" @@ -17,12 +18,10 @@ Target *AndroidManifestGenerator::create_target(const vector &, const Task *AndroidManifestGenerator::run(const Target &target) const { const AndroidManifestFile &manifest = dynamic_cast(target); - Worker *worker = new Worker(manifest); - return new InternalTask(worker); + return new InternalTask([&manifest]{ return _run(manifest); }); } - -void AndroidManifestGenerator::Worker::main() +bool AndroidManifestGenerator::_run(const AndroidManifestFile &manifest) { const Component &comp = *manifest.get_component(); const SourcePackage &pkg = comp.get_package(); @@ -56,5 +55,5 @@ void AndroidManifestGenerator::Worker::main() IO::print(out, "\t\n", p); out.write("\n"); - status = Task::SUCCESS; + return true; } diff --git a/source/androidmanifestgenerator.h b/source/androidmanifestgenerator.h index 630eb7c..6013c5f 100644 --- a/source/androidmanifestgenerator.h +++ b/source/androidmanifestgenerator.h @@ -1,31 +1,20 @@ #ifndef ANDROIDMANIFESTGENERATOR_H_ #define ANDROIDMANIFESTGENERATOR_H_ -#include "internaltask.h" #include "tool.h" class AndroidManifestFile; class AndroidManifestGenerator: public Tool { -private: - class Worker: public InternalTask::Worker - { - private: - const AndroidManifestFile &manifest; - - public: - Worker(const AndroidManifestFile &m): manifest(m) { } - - private: - void main() override; - }; - public: AndroidManifestGenerator(Builder &b): Tool(b, "AMG") { } Target *create_target(const std::vector &, const std::string &) override; Task *run(const Target &) const override; + +private: + static bool _run(const AndroidManifestFile &); }; #endif diff --git a/source/compilecommandsgenerator.cpp b/source/compilecommandsgenerator.cpp index 8e3947d..855a80a 100644 --- a/source/compilecommandsgenerator.cpp +++ b/source/compilecommandsgenerator.cpp @@ -4,6 +4,7 @@ #include "builder.h" #include "compilecommandsgenerator.h" #include "compilecommandsjson.h" +#include "internaltask.h" #include "objectfile.h" #include "sourcefile.h" @@ -18,18 +19,16 @@ Target *CompileCommandsGenerator::create_target(const vector &, const Task *CompileCommandsGenerator::run(const Target &target) const { const CompileCommandsJson &cmds = dynamic_cast(target); - Worker *worker = new Worker(cmds); - return new InternalTask(worker); + return new InternalTask([&cmds]{ return _run(cmds); }); } - -void CompileCommandsGenerator::Worker::main() +bool CompileCommandsGenerator::_run(const CompileCommandsJson &cmds) { - Builder &builder = target.get_package()->get_builder(); - const SourcePackage &spkg = *target.get_package(); + Builder &builder = cmds.get_package()->get_builder(); + const SourcePackage &spkg = *cmds.get_package(); string work_dir = c_escape(spkg.get_source_directory().str()); - IO::BufferedFile out(target.get_path().str(), IO::M_WRITE); + IO::BufferedFile out(cmds.get_path().str(), IO::M_WRITE); IO::print(out, "["); bool first = true; @@ -52,5 +51,5 @@ void CompileCommandsGenerator::Worker::main() IO::print(out, "\n]\n"); - status = Task::SUCCESS; + return true; } diff --git a/source/compilecommandsgenerator.h b/source/compilecommandsgenerator.h index a655d94..e3116f9 100644 --- a/source/compilecommandsgenerator.h +++ b/source/compilecommandsgenerator.h @@ -1,31 +1,20 @@ #ifndef COMPILECOMMANDSGENERATOR_H_ #define COMPILECOMMANDSGENERATOR_H_ -#include "internaltask.h" #include "tool.h" class CompileCommandsJson; class CompileCommandsGenerator: public Tool { -private: - class Worker: public InternalTask::Worker - { - private: - const CompileCommandsJson ⌖ - - public: - Worker(const CompileCommandsJson &t): target(t) { } - - private: - void main() override; - }; - public: CompileCommandsGenerator(Builder &b): Tool(b, "CCJG") { } Target *create_target(const std::vector &, const std::string &) override; Task *run(const Target &) const override; + +private: + static bool _run(const CompileCommandsJson &); }; #endif diff --git a/source/copy.cpp b/source/copy.cpp index 45c5a81..31e6210 100644 --- a/source/copy.cpp +++ b/source/copy.cpp @@ -10,6 +10,7 @@ #include "builder.h" #include "copy.h" #include "installedfile.h" +#include "internaltask.h" using namespace std; using namespace Msp; @@ -25,19 +26,17 @@ Target *Copy::create_target(const vector &sources, const string &arg) Task *Copy::run(const Target &target) const { const InstalledFile &install = dynamic_cast(target); - Worker *worker = new Worker(install); - InternalTask *task = new InternalTask(worker); + InternalTask *task = new InternalTask([&install]{ return _run(install); }); task->add_file(install.get_path()); task->set_unlink(); return task; } - -void Copy::Worker::main() +bool Copy::_run(const InstalledFile &install) { - const FileTarget &source = target.get_source(); + const FileTarget &source = install.get_source(); const FS::Path &src_path = source.get_path(); - const FS::Path &dst_path = target.get_path(); + const FS::Path &dst_path = install.get_path(); try { @@ -55,8 +54,7 @@ void Copy::Worker::main() catch(const exception &e) { IO::print(IO::cerr, "%s\n", e.what()); - status = Task::ERROR; - return; + return false; } #ifndef _WIN32 @@ -65,7 +63,7 @@ void Copy::Worker::main() if(stat(src_path.str().c_str(), &st)==0) chmod(dst_path.str().c_str(), st.st_mode&0777); - const FS::Path &link = target.get_symlink(); + const FS::Path &link = install.get_symlink(); if(!link.empty()) { FS::Path relpath = FS::relative(dst_path, FS::dirname(link)); @@ -75,5 +73,5 @@ void Copy::Worker::main() } #endif - status = Task::SUCCESS; + return true; } diff --git a/source/copy.h b/source/copy.h index a5044d8..c0a4339 100644 --- a/source/copy.h +++ b/source/copy.h @@ -1,9 +1,6 @@ #ifndef COPY_H_ #define COPY_H_ -#include -#include -#include "internaltask.h" #include "tool.h" class InstalledFile; @@ -13,26 +10,14 @@ Copies a file to another place. Used by the InstalledFile target. */ class Copy: public Tool { -private: - /** - A worker thread that actually does the data transfer. - */ - class Worker: public InternalTask::Worker - { - private: - const InstalledFile ⌖ - - public: - Worker(const InstalledFile &t): target(t) { } - private: - void main() override; - }; - public: Copy(Builder &b): Tool(b, "CP") { } Target *create_target(const std::vector &, const std::string &) override; Task *run(const Target &) const override; + +private: + static bool _run(const InstalledFile &); }; #endif diff --git a/source/internaltask.cpp b/source/internaltask.cpp index 5810be1..fc929ce 100644 --- a/source/internaltask.cpp +++ b/source/internaltask.cpp @@ -2,19 +2,18 @@ InternalTask::~InternalTask() { - worker->join(); - delete worker; + worker.join(); } void InternalTask::start() { prepare(); - worker->launch(); + worker.launch(); } Task::Status InternalTask::check() { - Status result = worker->get_status(); + Status result = worker.get_status(); if(result!=RUNNING) signal_finished.emit(result==SUCCESS); return result; @@ -26,3 +25,12 @@ Task::Status InternalTask::wait() while((result = check())==RUNNING) ; return result; } + + +void InternalTask::Worker::main() +{ + if(func()) + status = Task::SUCCESS; + else + status = Task::ERROR; +} diff --git a/source/internaltask.h b/source/internaltask.h index 5954519..608ea96 100644 --- a/source/internaltask.h +++ b/source/internaltask.h @@ -1,6 +1,7 @@ #ifndef INTERNALTASK_H_ #define INTERNALTASK_H_ +#include #include #include "task.h" @@ -11,25 +12,28 @@ or ERROR before terminating. */ class InternalTask: public Task { -public: +private: class Worker: public Msp::Thread { friend class InternalTask; - protected: + private: + std::function func; volatile Status status = Task::RUNNING; - Worker() = default; - public: + Worker(std::function f): func(f) { } + Status get_status() const { return status; } + + private: + void main() override; }; -private: - Worker *worker; + Worker worker; public: - InternalTask(Worker *w): worker(w) { } + InternalTask(std::function f): worker(f) { } ~InternalTask(); std::string get_command() const override { return ""; } diff --git a/source/pkgconfiggenerator.cpp b/source/pkgconfiggenerator.cpp index 02f1423..a6178a7 100644 --- a/source/pkgconfiggenerator.cpp +++ b/source/pkgconfiggenerator.cpp @@ -2,6 +2,7 @@ #include #include #include "builder.h" +#include "internaltask.h" #include "pkgconfigfile.h" #include "pkgconfiggenerator.h" @@ -16,17 +17,15 @@ Target *PkgConfigGenerator::create_target(const vector &, const string Task *PkgConfigGenerator::run(const Target &target) const { const PkgConfigFile &pkgc = dynamic_cast(target); - Worker *worker = new Worker(pkgc); - return new InternalTask(worker); + return new InternalTask([&pkgc]{ return _run(pkgc); }); } - -void PkgConfigGenerator::Worker::main() +bool PkgConfigGenerator::_run(const PkgConfigFile &pkgc) { - Builder &builder = target.get_package()->get_builder(); - const SourcePackage &spkg = *target.get_package(); + Builder &builder = pkgc.get_package()->get_builder(); + const SourcePackage &spkg = *pkgc.get_package(); - IO::BufferedFile out(target.get_path().str(), IO::M_WRITE); + IO::BufferedFile out(pkgc.get_path().str(), IO::M_WRITE); IO::print(out, "prefix=%s\n", builder.get_prefix().str()); IO::print(out, "source=%s\n\n", spkg.get_source_directory()); @@ -60,10 +59,10 @@ void PkgConfigGenerator::Worker::main() IO::print(out, " -D%s=%s", kvp.first, kvp.second); out.put('\n'); - status = Task::SUCCESS; + return true; } -string PkgConfigGenerator::Worker::prefixify(const FS::Path &path, const FS::Path &prefix) +string PkgConfigGenerator::prefixify(const FS::Path &path, const FS::Path &prefix) { if(FS::descendant_depth(path, prefix)>=0) { diff --git a/source/pkgconfiggenerator.h b/source/pkgconfiggenerator.h index 727b3e2..0f0886b 100644 --- a/source/pkgconfiggenerator.h +++ b/source/pkgconfiggenerator.h @@ -1,33 +1,21 @@ #ifndef PKGCONFIGGENERATOR_H_ #define PKGCONFIGGENERATOR_H_ -#include "internaltask.h" #include "tool.h" class PkgConfigFile; class PkgConfigGenerator: public Tool { -private: - class Worker: public InternalTask::Worker - { - private: - const PkgConfigFile ⌖ - - public: - Worker(const PkgConfigFile &t): target(t) { } - - private: - void main() override; - - std::string prefixify(const Msp::FS::Path &, const Msp::FS::Path &); - }; - public: PkgConfigGenerator(Builder &b): Tool(b, "PCG") { } Target *create_target(const std::vector &, const std::string &) override; Task *run(const Target &) const override; + +private: + static bool _run(const PkgConfigFile &); + static std::string prefixify(const Msp::FS::Path &, const Msp::FS::Path &); }; #endif diff --git a/source/tar.cpp b/source/tar.cpp index 8de76fe..446aa92 100644 --- a/source/tar.cpp +++ b/source/tar.cpp @@ -4,6 +4,7 @@ #include #include #include "builder.h" +#include "internaltask.h" #include "sourcepackage.h" #include "tar.h" #include "tarball.h" @@ -34,16 +35,10 @@ Target *Tar::create_target(const vector &sources, const string &arg) Task *Tar::run(const Target &target) const { const TarBall &tarball = dynamic_cast(target); - Worker *worker = new Worker(tarball); - return new InternalTask(worker); + return new InternalTask([&tarball]{ return _run(tarball); }); } - -Tar::Worker::Worker(const TarBall &tb): - tarball(tb) -{ } - -void Tar::Worker::main() +bool Tar::_run(const TarBall &tarball) { const FS::Path &pkg_src = tarball.get_package()->get_source_directory(); FS::Path basedir = FS::basepart(FS::basename(tarball.get_path())); @@ -62,8 +57,7 @@ void Tar::Worker::main() if(rel_path.size()>99) { IO::print("Can't store %s in tar archive - too long name\n", rel_path); - status = Task::ERROR; - return; + return false; } memcpy(buf, rel_path.data(), rel_path.size()); @@ -93,10 +87,10 @@ void Tar::Worker::main() } } - status = Task::SUCCESS; + return true; } -void Tar::Worker::store_number(char *buf, unsigned value, unsigned length) +void Tar::store_number(char *buf, unsigned value, unsigned length) { for(unsigned i=length; i--;) { diff --git a/source/tar.h b/source/tar.h index d0240d9..fa4a4d6 100644 --- a/source/tar.h +++ b/source/tar.h @@ -1,33 +1,21 @@ #ifndef TAR_H_ #define TAR_H_ -#include -#include "internaltask.h" #include "tool.h" class TarBall; class Tar: public Tool { -private: - class Worker: public InternalTask::Worker - { - private: - const TarBall &tarball; - - public: - Worker(const TarBall &); - - private: - void main() override; - void store_number(char *, unsigned, unsigned); - }; - public: Tar(Builder &); Target *create_target(const std::vector &, const std::string &) override; Task *run(const Target &) const override; + +private: + static bool _run(const TarBall &); + static void store_number(char *, unsigned, unsigned); }; #endif diff --git a/source/vcxprojectgenerator.cpp b/source/vcxprojectgenerator.cpp index 1528802..bafa8d9 100644 --- a/source/vcxprojectgenerator.cpp +++ b/source/vcxprojectgenerator.cpp @@ -5,6 +5,7 @@ #include "builder.h" #include "csourcefile.h" #include "executable.h" +#include "internaltask.h" #include "sourcepackage.h" #include "vcxprojectfile.h" #include "vcxprojectgenerator.h" @@ -20,17 +21,15 @@ Target *VcxProjectGenerator::create_target(const vector &, const strin Task *VcxProjectGenerator::run(const Target &target) const { const VcxProjectFile &project = dynamic_cast(target); - Worker *worker = new Worker(project); - return new InternalTask(worker); + return new InternalTask([&project]{ return _run(project); }); } - -void VcxProjectGenerator::Worker::main() +bool VcxProjectGenerator::_run(const VcxProjectFile &project) { - const SourcePackage &spkg = *target.get_package(); + const SourcePackage &spkg = *project.get_package(); Builder &builder = spkg.get_builder(); - IO::BufferedFile out(target.get_path().str(), IO::M_WRITE); + IO::BufferedFile out(project.get_path().str(), IO::M_WRITE); IO::print(out, "\n"); IO::print(out, "\t\n"); @@ -49,7 +48,7 @@ void VcxProjectGenerator::Worker::main() IO::print(out, "\t\n"); IO::print(out, "\t\t15.0\n"); IO::print(out, "\t\tMakeFileProj\n"); - IO::print(out, "\t\t{%s}\n", target.get_guid()); + IO::print(out, "\t\t{%s}\n", project.get_guid()); IO::print(out, "\t\n"); IO::print(out, "\t\n"); @@ -134,5 +133,5 @@ void VcxProjectGenerator::Worker::main() IO::print(out, "\t\n"); IO::print(out, "\n"); - status = Task::SUCCESS; + return true; } diff --git a/source/vcxprojectgenerator.h b/source/vcxprojectgenerator.h index bf06f40..05f7401 100644 --- a/source/vcxprojectgenerator.h +++ b/source/vcxprojectgenerator.h @@ -1,31 +1,20 @@ #ifndef VCXPROJECTGENERATOR_H_ #define VCXPROJECTGENERATOR_H_ -#include "internaltask.h" #include "tool.h" class VcxProjectFile; class VcxProjectGenerator: public Tool { -private: - class Worker: public InternalTask::Worker - { - private: - const VcxProjectFile ⌖ - - public: - Worker(const VcxProjectFile &t): target(t) { } - - private: - void main() override; - }; - public: VcxProjectGenerator(Builder &b): Tool(b, "VCXG") { } Target *create_target(const std::vector &, const std::string &) override; Task *run(const Target &) const override; + +private: + static bool _run(const VcxProjectFile &); }; #endif diff --git a/source/vssolutiongenerator.cpp b/source/vssolutiongenerator.cpp index 9f8a7ab..5fd8e4d 100644 --- a/source/vssolutiongenerator.cpp +++ b/source/vssolutiongenerator.cpp @@ -2,6 +2,7 @@ #include #include #include "builder.h" +#include "internaltask.h" #include "sourcepackage.h" #include "vcxprojectfile.h" #include "vssolutionfile.h" @@ -18,22 +19,20 @@ Target *VsSolutionGenerator::create_target(const vector &, const strin Task *VsSolutionGenerator::run(const Target &target) const { const VsSolutionFile &solution = dynamic_cast(target); - Worker *worker = new Worker(solution); - return new InternalTask(worker); + return new InternalTask([&solution]{ return _run(solution); }); } - -void VsSolutionGenerator::Worker::main() +bool VsSolutionGenerator::_run(const VsSolutionFile &solution) { - const SourcePackage &spkg = *target.get_package(); + const SourcePackage &spkg = *solution.get_package(); Builder &builder = spkg.get_builder(); - IO::BufferedFile out(target.get_path().str(), IO::M_WRITE); + IO::BufferedFile out(solution.get_path().str(), IO::M_WRITE); IO::print(out, "Microsoft Visual Studio Solution File, Format Version 12.00\n"); IO::print(out, "MinimumVisualStudioVersion = 10.0.40219.1\n"); vector projects; - for(const Target *t: target.get_dependencies()) + for(const Target *t: solution.get_dependencies()) if(const VcxProjectFile *project = dynamic_cast(t)) projects.push_back(project); @@ -66,5 +65,5 @@ void VsSolutionGenerator::Worker::main() IO::print(out, "\tEndGlobalSection\n"); IO::print(out, "EndGlobal\n"); - status = Task::SUCCESS; + return true; } diff --git a/source/vssolutiongenerator.h b/source/vssolutiongenerator.h index 68d581f..b7eaf31 100644 --- a/source/vssolutiongenerator.h +++ b/source/vssolutiongenerator.h @@ -1,31 +1,20 @@ #ifndef VSSOLUTIONGENERATOR_H_ #define VSSOLUTIONGENERATOR_H_ -#include "internaltask.h" #include "tool.h" class VsSolutionFile; class VsSolutionGenerator: public Tool { -private: - class Worker: public InternalTask::Worker - { - private: - const VsSolutionFile ⌖ - - public: - Worker(const VsSolutionFile &t): target(t) { } - - private: - void main() override; - }; - public: VsSolutionGenerator(Builder &b): Tool(b, "VSSG") { } Target *create_target(const std::vector &, const std::string &) override; Task *run(const Target &) const override; + +private: + static bool _run(const VsSolutionFile &); }; #endif -- 2.45.2