Skip to content

Commit

Permalink
[refactor] command line arguments parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
TzuChieh committed Sep 3, 2019
1 parent 2f0639b commit e9cde65
Show file tree
Hide file tree
Showing 7 changed files with 354 additions and 285 deletions.
261 changes: 33 additions & 228 deletions PhotonCLI/CommandLineArguments.cpp
Original file line number Diff line number Diff line change
@@ -1,254 +1,59 @@
#include "CommandLineArguments.h"
#include "util.h"

#include <utility>
#include <iostream>
#include <string_view>
#include <limits>

PH_CLI_NAMESPACE_BEGIN

namespace
CommandLineArguments::CommandLineArguments(int argc, char* argv[]) :
m_programName(),
m_arguments()
{
constexpr std::string_view DEFAULT_SCENE_FILE_PATH = "./scene.p2";
constexpr std::string_view DEFAULT_DEFAULT_IMAGE_FILE_PATH = "./rendered_scene.png";
}

CommandLineArguments::CommandLineArguments(const std::vector<std::string>& argv) :
m_sceneFilePath (DEFAULT_SCENE_FILE_PATH),
m_imageFilePath (DEFAULT_DEFAULT_IMAGE_FILE_PATH),
m_numRenderThreads (1),
m_isPostProcessRequested (true),
m_isHelpMessageRequested (false),
m_isImageSeriesRequested (false),
m_wildcardStart (""),
m_wildcardFinish (""),
m_outputPercentageProgress(std::numeric_limits<float>::max()),

m_isFrameDiagRequested(false)
{
std::string imageFileFormat;
for(std::size_t i = 1; i < argv.size(); i++)
if(argc >= 1)
{
if(argv[i] == "-s")
{
i++;
if(i < argv.size())
{
m_sceneFilePath = argv[i];
}
}
else if(argv[i] == "-o")
{
i++;
if(i < argv.size())
{
m_imageFilePath = argv[i];
}
}
else if(argv[i] == "-of")
{
i++;
if(i < argv.size())
{
imageFileFormat = argv[i];
}
}
else if(argv[i] == "-t")
{
i++;
if(i < argv.size())
{
const int numRenderThreads = std::stoi(argv[i]);
if(numRenderThreads > 0)
{
m_numRenderThreads = numRenderThreads;
}
else
{
std::cerr << "warning: bad number of threads <" << argv[i] << ">" << std::endl;
std::cerr << "use " << m_numRenderThreads << " instead" << std::endl;
}
}
}
else if(argv[i] == "-p")
{
i++;
if(i < argv.size())
{
const float outputPercentageProgress = std::stof(argv[i]);
if(0 < outputPercentageProgress && outputPercentageProgress < 100)
{
m_outputPercentageProgress = outputPercentageProgress;
}
else
{
std::cerr << "warning: intermediate output percentage specified <"
<< outputPercentageProgress << "> is not sensible" << std::endl;
}
}
}
else if(argv[i] == "--raw")
{
m_isPostProcessRequested = false;
}
else if(argv[i] == "--help")
{
m_isHelpMessageRequested = true;
}
else if(argv[i] == "--series")
{
m_isImageSeriesRequested = true;
}
else if(argv[i] == "--start")
{
i++;
if(i < argv.size())
{
m_wildcardStart = argv[i];
}
else
{
std::cerr << "warning: no wildcard string specified for --start" << std::endl;
}
}
else if(argv[i] == "--finish")
{
i++;
if(i < argv.size())
{
m_wildcardFinish = argv[i];
}
else
{
std::cerr << "warning: no wildcard string specified for --finish" << std::endl;
}
}
else if(argv[i] == "-fd")
{
i++;
if(i + 1 < argv.size())
{
m_framePathA = argv[i++];
m_framePathB = argv[i];
m_isFrameDiagRequested = true;
}
else
{
std::cerr << "warning: bad frame diag format" << std::endl;
}
}
else
{
std::cerr << "warning: unknown command <" << argv[i] << ">" << std::endl;
std::cerr << "ignored" << std::endl;
}
}// end for each argument
m_programName = argv[0];
}

// possibly override image format if a more specific order is given
if(!imageFileFormat.empty())
for(int i = 1; i < argc; ++i)
{
m_imageFilePath += "." + imageFileFormat;
m_arguments.push(argv[i]);
}

// TODO: check arguments
}

std::string CommandLineArguments::getSceneFilePath() const
{
return m_sceneFilePath;
}

std::string CommandLineArguments::getImageFilePath() const
{
return m_imageFilePath;
}

int CommandLineArguments::getNumRenderThreads() const
{
return m_numRenderThreads;
}

bool CommandLineArguments::isPostProcessRequested() const
{
return m_isPostProcessRequested;
}

bool CommandLineArguments::isHelpMessageRequested() const
std::string CommandLineArguments::retrieveOne(const std::string& defaultValue)
{
return m_isHelpMessageRequested;
}

bool CommandLineArguments::isImageSeriesRequested() const
{
return m_isImageSeriesRequested;
}
if(isEmpty())
{
std::cerr << "warning: retrieving a nonexistent argument, "
<< "defaulted to " << defaultValue << std::endl;
return defaultValue;
}

std::string CommandLineArguments::wildcardStart() const
{
return m_wildcardStart;
std::string argument = m_arguments.front();
m_arguments.pop();
return std::move(argument);
}

std::string CommandLineArguments::wildcardFinish() const
std::vector<std::string> CommandLineArguments::retrieveMultiple(const std::size_t numValues)
{
return m_wildcardFinish;
std::vector<std::string> arguments;
for(std::size_t i = 0; i < numValues; ++i)
{
arguments.push_back(retrieveOne());
}
return std::move(arguments);
}

float CommandLineArguments::getOutputPercentageProgress() const
int CommandLineArguments::retrieveOneInt(const int defaultValue)
{
return m_outputPercentageProgress;
const auto argument = retrieveOne();
return !argument.empty() ? std::stoi(argument) : defaultValue;
}

void CommandLineArguments::printHelpMessage()
float CommandLineArguments::retrieveOneFloat(const float defaultValue)
{
std::cout << R"(
===============================================================================
-s <path>
Specify path to scene file. To render an image series, you can specify
"myScene*.p2" as <path> where * is a wildcard for any string (--series is
required in this case). (default path: "./scene.p2")
===============================================================================
-o <path>
Specify image output path. This should be a filename for single image and a
directory for image series. (default path: "./rendered_scene.png")
===============================================================================
-of <format>
Specify the format of output image. Supported formats are: png, jpg, bmp, tga,
hdr, exr. If this option is omitted, format is deduced from filename extension.
===============================================================================
-t <number>
Set number of threads used for rendering. (default: single thread)
===============================================================================
-p <number>
Output an intermediate image whenever the render has progressed <number>%.
(default: never output intermediate image)
===============================================================================
--raw
Do not perform any post-processing. (default: perform post-processing)
===============================================================================
--help
Print this help message then exit.
===============================================================================
--series
Render an image series. The order for rendering will be lexicographical order
of the wildcarded string. Currently only .png is supported.
===============================================================================
--start <*>
Render image series starting from a specific wildcarded string.
===============================================================================
--finish <*>
Render image series until a specific wildcarded string is matched. (inclusive)
===============================================================================
)" << std::endl;
const auto argument = retrieveOne();
return !argument.empty() ? std::stof(argument) : defaultValue;
}

PH_CLI_NAMESPACE_END
PH_CLI_NAMESPACE_END
66 changes: 24 additions & 42 deletions PhotonCLI/CommandLineArguments.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,57 +3,39 @@
#include "util.h"

#include <string>
#include <queue>
#include <vector>
#include <cstddef>

PH_CLI_NAMESPACE_BEGIN

class CommandLineArguments final
class CommandLineArguments
{
public:
static void printHelpMessage();
CommandLineArguments(int argc, char* argv[]);

public:
explicit CommandLineArguments(const std::vector<std::string>& argv);

std::string getSceneFilePath() const;
std::string getImageFilePath() const;
int getNumRenderThreads() const;
bool isPostProcessRequested() const;
bool isHelpMessageRequested() const;
bool isImageSeriesRequested() const;
std::string wildcardStart() const;
std::string wildcardFinish() const;
float getOutputPercentageProgress() const;

bool isFrameDiagRequested() const
{
return m_isFrameDiagRequested;
}

std::string getFramePathA() const
{
return m_framePathA;
}
std::string getFramePathB() const
{
return m_framePathB;
}
std::string getProgramName() const;
bool isEmpty() const;
std::string retrieveOne(const std::string& defaultValue = "");
std::vector<std::string> retrieveMultiple(std::size_t numValues);
int retrieveOneInt(int defaultValue = 0);
float retrieveOneFloat(float defaultValue = 0.0f);

private:
std::string m_sceneFilePath;
std::string m_imageFilePath;
std::string m_intermediateImageFileFormat;
int m_numRenderThreads;// FIXME: use unsigned integer
bool m_isPostProcessRequested;
bool m_isHelpMessageRequested;
bool m_isImageSeriesRequested;
std::string m_wildcardStart;
std::string m_wildcardFinish;
float m_outputPercentageProgress;

bool m_isFrameDiagRequested;
std::string m_framePathA;
std::string m_framePathB;
std::string m_programName;
std::queue<std::string> m_arguments;
};

// In-header Implementations:

inline std::string CommandLineArguments::getProgramName() const
{
return m_programName;
}

inline bool CommandLineArguments::isEmpty() const
{
return m_arguments.empty();
}

PH_CLI_NAMESPACE_END

0 comments on commit e9cde65

Please sign in to comment.