<commit_before>#include <argtable3/argtable3.h>

#include <sstream>

#include <babylon/babylon_version.h>
#include <babylon/core/delegates/delegate.h>
#include <babylon/core/logging.h>
#include <babylon/core/string.h>
#include <babylon/samples/sample_launcher.h>
#include <babylon/samples/samples_index.h>

#if _MSC_VER
#include <windows.h>
#endif

struct ConsoleLogger {

  using log_message_t = SA::delegate<void(const BABYLON::LogMessage&)>;

  static void onLogMessage(const BABYLON::LogMessage& logMessage)
  {
    printf("%s\n", logMessage.toString().c_str());
#if _MSC_VER
    OutputDebugString(logMessage.toString().c_str());
#endif
  }

  static log_message_t logListenerDelegate;

}; // end of struct ConsoleLogger

ConsoleLogger::log_message_t ConsoleLogger::logListenerDelegate
  = SA::delegate<void(
    const BABYLON::LogMessage&)>::create<&ConsoleLogger::onLogMessage>();

/**
 * @brief Initializes the logging.
 */
void initializeLogging()
{
  static_assert(
    std::is_same<SA::delegate<void(const BABYLON::LogMessage&)>,
                 decltype(ConsoleLogger::logListenerDelegate)>::value,
    "!");
  // Intialize log levels
  std::vector<std::pair<unsigned int, std::string>> _logLevels;
  for (auto& logLevel : BABYLON::LogLevels::Levels) {
    unsigned int logType = logLevel.first;
    if ((logType != BABYLON::LogLevels::LEVEL_QUIET)
        && (logType != BABYLON::LogLevels::LEVEL_TRACE)) {
      _logLevels.emplace_back(logLevel);
    }
  }
  // Subscribe to channels
  for (auto& logLevel : _logLevels) {
    unsigned int logType = logLevel.first;
    if (logType != BABYLON::LogLevels::LEVEL_QUIET) {
      BABYLON::Logger::Instance().registerLogMessageListener(
        logType, ConsoleLogger::logListenerDelegate);
    }
  }
}

/**
 * @brief Runs a sample with the specified name
 * @param samples list with available samples
 * @param sampleName name of the sample to run
 * @param showInspectorWindow whether or not to shoz the inspector window
 * @return exit code
 */
int runSample(const BABYLON::Samples::SamplesIndex& samples,
              const std::string& sampleName, bool showInspectorWindow,
              long runTimeMillis = 0)
{
  using namespace BABYLON::Samples;
  int exitcode = 0;
  // Create the sample launcher
  SampleLauncherOptions options;
  options.showInspectorWindow = showInspectorWindow;
  SampleLauncher sampleLauncher{options};
  if (sampleLauncher.intialize()) {
    // Create the renderable scene
    auto canvas = sampleLauncher.getRenderCanvas();
    auto scene  = samples.createRenderableScene(sampleName, canvas);
    sampleLauncher.setRenderableScene(scene);
    // Run the example
    exitcode = sampleLauncher.run(runTimeMillis);
  }
  return exitcode;
}

/**
 * @brief The sample launcher.
 * @param l list samples if l > 0
 * @param v enable verbose mode if v > 0
 * @param sample name of the sample to run
 * @return exit code
 */
int sampleLauncherMain(int l, int v, int i, const char* sampleGroup,
                       const char* sample)
{
  using namespace BABYLON::Samples;
  SamplesIndex samples;
  int exitcode = 0;
  if (l > 0) {
    std::ostringstream oss;
    // Get sample names and category names
    auto sampleNames   = samples.getSampleNames();
    auto categoryNames = samples.getCategoryNames();
    oss << "Found " << sampleNames.size() << " in " << categoryNames.size()
        << " categories:\n";
    // Print categorized samples
    for (const auto& categoryName : categoryNames) {
      sampleNames = samples.getSampleNamesInCategory(categoryName);
      oss << "       |- ";
      if (sampleNames.size() < 10) {
        oss << " " << sampleNames.size();
      }
      else if (sampleNames.size() < 100) {
        oss << sampleNames.size();
      }
      oss << " sample(s) in category \"" << categoryName.c_str() << "\"\n";
      for (const auto& sampleName : sampleNames) {
        oss << "           |- " << sampleName.c_str() << "\n";
      }
    }
    printf("%s", oss.str().c_str());
  }
  else {
    if (v > 0) {
      // Enable console logging
      initializeLogging();
    }
    // Check for rendering of sample group
    const std::string categoryName{sampleGroup};
    if (!categoryName.empty()
        && (samples.categoryExists(categoryName) || categoryName == "All")) {
      std::vector<std::string> categoryNames;
      if (categoryName == "All") {
        categoryNames = samples.getCategoryNames();
      }
      else {
        categoryNames = {categoryName};
      }
      for (const auto& _categoryName : categoryNames) {
        const auto sampleNames
          = samples.getSampleNamesInCategory(_categoryName);
        for (const auto& sampleName : sampleNames) {
          exitcode = runSample(samples, sampleName, i > 0, 10000);
          if (exitcode == 0) {
            break;
          }
        }
      }
    }
    else {
      // Check for rendering of sample
      const std::string sampleName{sample};
      if (!samples.sampleExists(sampleName)) {
        printf("Sample with name \"%s\" does not exists.\n", sample);
        return 1;
      }
      if (!samples.isSampleEnabled(sampleName)) {
        printf("Sample with name \"%s\" is not enabled.\n", sample);
        return 1;
      }
      // Run the sample
      exitcode = runSample(samples, sampleName, i > 0);
    }
  }
  return exitcode;
}

int main(int argc, char** argv)
{
  /** Program arguments definition **/
  struct arg_lit* list   = arg_lit0("lL", NULL, "list samples");
  struct arg_str* sample = arg_str0(
    "S", "sample", "<SAMPE>", "sample to launch (default is \"BasicScene\")");
  struct arg_str* sampleGroup = arg_str0(
    "G", "sample-group", "<SAMPE-GROUP>",
    "sample group to launch (sample-group \"All\" contains all samples)");
  struct arg_lit* verbose = arg_lit0("v", "verbose,debug", "verbose messages");
  struct arg_lit* inspector
    = arg_lit0("i", "inspector", "show inspector window");<commit_msg>main.cpp: ChdirToExePath under windows<commit_after>#include <argtable3/argtable3.h>

#include <filesystem>
#include <sstream>

#include <babylon/babylon_version.h>
#include <babylon/core/delegates/delegate.h>
#include <babylon/core/logging.h>
#include <babylon/core/string.h>
#include <babylon/samples/sample_launcher.h>
#include <babylon/samples/samples_index.h>

#if _MSC_VER
#include <windows.h>
#include <direct.h>
#endif

struct ConsoleLogger {

  using log_message_t = SA::delegate<void(const BABYLON::LogMessage&)>;

  static void onLogMessage(const BABYLON::LogMessage& logMessage)
  {
    printf("%s\n", logMessage.toString().c_str());
#if _MSC_VER
    OutputDebugString(logMessage.toString().c_str());
#endif
  }

  static log_message_t logListenerDelegate;

}; // end of struct ConsoleLogger

ConsoleLogger::log_message_t ConsoleLogger::logListenerDelegate
  = SA::delegate<void(
    const BABYLON::LogMessage&)>::create<&ConsoleLogger::onLogMessage>();

/**
 * @brief Initializes the logging.
 */
void initializeLogging()
{
  static_assert(
    std::is_same<SA::delegate<void(const BABYLON::LogMessage&)>,
                 decltype(ConsoleLogger::logListenerDelegate)>::value,
    "!");
  // Intialize log levels
  std::vector<std::pair<unsigned int, std::string>> _logLevels;
  for (auto& logLevel : BABYLON::LogLevels::Levels) {
    unsigned int logType = logLevel.first;
    if ((logType != BABYLON::LogLevels::LEVEL_QUIET)
        && (logType != BABYLON::LogLevels::LEVEL_TRACE)) {
      _logLevels.emplace_back(logLevel);
    }
  }
  // Subscribe to channels
  for (auto& logLevel : _logLevels) {
    unsigned int logType = logLevel.first;
    if (logType != BABYLON::LogLevels::LEVEL_QUIET) {
      BABYLON::Logger::Instance().registerLogMessageListener(
        logType, ConsoleLogger::logListenerDelegate);
    }
  }
}

/**
 * @brief Runs a sample with the specified name
 * @param samples list with available samples
 * @param sampleName name of the sample to run
 * @param showInspectorWindow whether or not to shoz the inspector window
 * @return exit code
 */
int runSample(const BABYLON::Samples::SamplesIndex& samples,
              const std::string& sampleName, bool showInspectorWindow,
              long runTimeMillis = 0)
{
  using namespace BABYLON::Samples;
  int exitcode = 0;
  // Create the sample launcher
  SampleLauncherOptions options;
  options.showInspectorWindow = showInspectorWindow;
  SampleLauncher sampleLauncher{options};
  if (sampleLauncher.intialize()) {
    // Create the renderable scene
    auto canvas = sampleLauncher.getRenderCanvas();
    auto scene  = samples.createRenderableScene(sampleName, canvas);
    sampleLauncher.setRenderableScene(scene);
    // Run the example
    exitcode = sampleLauncher.run(runTimeMillis);
  }
  return exitcode;
}

/**
 * @brief The sample launcher.
 * @param l list samples if l > 0
 * @param v enable verbose mode if v > 0
 * @param sample name of the sample to run
 * @return exit code
 */
int sampleLauncherMain(int l, int v, int i, const char* sampleGroup,
                       const char* sample)
{
  using namespace BABYLON::Samples;
  SamplesIndex samples;
  int exitcode = 0;
  if (l > 0) {
    std::ostringstream oss;
    // Get sample names and category names
    auto sampleNames   = samples.getSampleNames();
    auto categoryNames = samples.getCategoryNames();
    oss << "Found " << sampleNames.size() << " in " << categoryNames.size()
        << " categories:\n";
    // Print categorized samples
    for (const auto& categoryName : categoryNames) {
      sampleNames = samples.getSampleNamesInCategory(categoryName);
      oss << "       |- ";
      if (sampleNames.size() < 10) {
        oss << " " << sampleNames.size();
      }
      else if (sampleNames.size() < 100) {
        oss << sampleNames.size();
      }
      oss << " sample(s) in category \"" << categoryName.c_str() << "\"\n";
      for (const auto& sampleName : sampleNames) {
        oss << "           |- " << sampleName.c_str() << "\n";
      }
    }
    printf("%s", oss.str().c_str());
  }
  else {
    if (v > 0) {
      // Enable console logging
      initializeLogging();
    }
    // Check for rendering of sample group
    const std::string categoryName{sampleGroup};
    if (!categoryName.empty()
        && (samples.categoryExists(categoryName) || categoryName == "All")) {
      std::vector<std::string> categoryNames;
      if (categoryName == "All") {
        categoryNames = samples.getCategoryNames();
      }
      else {
        categoryNames = {categoryName};
      }
      for (const auto& _categoryName : categoryNames) {
        const auto sampleNames
          = samples.getSampleNamesInCategory(_categoryName);
        for (const auto& sampleName : sampleNames) {
          exitcode = runSample(samples, sampleName, i > 0, 10000);
          if (exitcode == 0) {
            break;
          }
        }
      }
    }
    else {
      // Check for rendering of sample
      const std::string sampleName{sample};
      if (!samples.sampleExists(sampleName)) {
        printf("Sample with name \"%s\" does not exists.\n", sample);
        return 1;
      }
      if (!samples.isSampleEnabled(sampleName)) {
        printf("Sample with name \"%s\" is not enabled.\n", sample);
        return 1;
      }
      // Run the sample
      exitcode = runSample(samples, sampleName, i > 0);
    }
  }
  return exitcode;
}

void ChdirToExePath(char *argv0)
{
  std::filesystem::path exeFolder = std::filesystem::weakly_canonical(std::filesystem::path(argv0)).parent_path();
#ifdef _WIN32
  _chdir(exeFolder.string().c_str());
#else
  chdir(exeFolder.string().c_str());
#endif
}

int main(int argc, char** argv)
{
#ifdef _MSC_VER
  ChdirToExePath(argv[0]);
#endif
  /** Program arguments definition **/
  struct arg_lit* list   = arg_lit0("lL", NULL, "list samples");
  struct arg_str* sample = arg_str0(
    "S", "sample", "<SAMPE>", "sample to launch (default is \"BasicScene\")");
  struct arg_str* sampleGroup = arg_str0(
    "G", "sample-group", "<SAMPE-GROUP>",
    "sample group to launch (sample-group \"All\" contains all samples)");
  struct arg_lit* verbose = arg_lit0("v", "verbose,debug", "verbose messages");
  struct arg_lit* inspector
    = arg_lit0("i", "inspector", "show inspector window");
{'fraction_non_alphanumeric': 0.13254292722812755, 'fraction_numerical': 0.005151267375306623, 'mean_word_length': 3.263157894736842, 'pattern_counts': {'":': 0, '<': 107, '<?xml version=': 0, '>': 55, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '795585', 'n_tokens_mistral': 3885, 'n_tokens_neox': 3725, 'n_words': 926}