<commit_before>//===--- TestOptions.cpp --------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#include "TestOptions.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Option/Arg.h"
#include "llvm/Option/ArgList.h"
#include "llvm/Option/Option.h"
#include "llvm/Support/raw_ostream.h"

using namespace sourcekitd_test;
using llvm::StringRef;

namespace {

// Create enum with OPT_xxx values for each option in Options.td.
enum Opt {
  OPT_INVALID = 0,
#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM,  \
               HELP, META, VALUES)                                             \
  OPT_##ID,
#include "Options.inc"
  LastOption
#undef OPTION
};

// Create prefix string literals used in Options.td.
#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;
#include "Options.inc"
#undef PREFIX

// Create table mapping all options defined in Options.td.
static const llvm::opt::OptTable::Info InfoTable[] = {
#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM,  \
               HELPTEXT, METAVAR, VALUES)                                      \
  {PREFIX,      NAME,      HELPTEXT,                                           \
   METAVAR,     OPT_##ID,  llvm::opt::Option::KIND##Class,                     \
   PARAM,       FLAGS,     OPT_##GROUP,                                        \
   OPT_##ALIAS, ALIASARGS, VALUES},
#include "Options.inc"
#undef OPTION
};

// Create OptTable class for parsing actual command line arguments
class TestOptTable : public llvm::opt::OptTable {
public:
  TestOptTable() : OptTable(InfoTable, llvm::array_lengthof(InfoTable)){}
};

} // end anonymous namespace

static std::pair<unsigned, unsigned> parseLineCol(StringRef LineCol) {
  unsigned Line, Col;
  size_t ColonIdx = LineCol.find(':');
  if (ColonIdx == StringRef::npos) {
    llvm::errs() << "wrong pos format, it should be '<line>:<column>'\n";
    exit(1);
  }
  if (LineCol.substr(0, ColonIdx).getAsInteger(10, Line)) {
    llvm::errs() << "wrong pos format, it should be '<line>:<column>'\n";
    exit(1);
  }
  if (LineCol.substr(ColonIdx+1).getAsInteger(10, Col)) {
    llvm::errs() << "wrong pos format, it should be '<line>:<column>'\n";
    exit(1);
  }

  if (Line == 0 || Col == 0) {
    llvm::errs() << "wrong pos format, line/col should start from 1\n";
    exit(1);
  }

  return { Line, Col };
}

bool TestOptions::parseArgs(llvm::ArrayRef<const char *> Args) {
  if (Args.empty())
    return false;

  // Parse command line options using Options.td
  TestOptTable Table;
  unsigned MissingIndex;
  unsigned MissingCount;
  llvm::opt::InputArgList ParsedArgs =
      Table.ParseArgs(Args, MissingIndex, MissingCount);
  if (MissingCount) {
    llvm::errs() << "error: missing argument value for '"
        << ParsedArgs.getArgString(MissingIndex) << "', expected "
        << MissingCount << " argument(s)\n";
    return true;
  }

  for (auto InputArg : ParsedArgs) {
    switch (InputArg->getOption().getID()) {
    case OPT_req:
      Request = llvm::StringSwitch<SourceKitRequest>(InputArg->getValue())
        .Case("version", SourceKitRequest::ProtocolVersion)
        .Case("demangle", SourceKitRequest::DemangleNames)
        .Case("mangle", SourceKitRequest::MangleSimpleClasses)
        .Case("index", SourceKitRequest::Index)
        .Case("complete", SourceKitRequest::CodeComplete)
        .Case("complete.open", SourceKitRequest::CodeCompleteOpen)
        .Case("complete.close", SourceKitRequest::CodeCompleteClose)
        .Case("complete.update", SourceKitRequest::CodeCompleteUpdate)
        .Case("complete.cache.ondisk", SourceKitRequest::CodeCompleteCacheOnDisk)
        .Case("complete.setpopularapi", SourceKitRequest::CodeCompleteSetPopularAPI)
        .Case("typecontextinfo", SourceKitRequest::TypeContextInfo)
        .Case("cursor", SourceKitRequest::CursorInfo)
        .Case("related-idents", SourceKitRequest::RelatedIdents)
        .Case("syntax-map", SourceKitRequest::SyntaxMap)
        .Case("syntax-tree", SourceKitRequest::SyntaxTree)
        .Case("structure", SourceKitRequest::Structure)
        .Case("format", SourceKitRequest::Format)
        .Case("expand-placeholder", SourceKitRequest::ExpandPlaceholder)
        .Case("doc-info", SourceKitRequest::DocInfo)
        .Case("sema", SourceKitRequest::SemanticInfo)
        .Case("interface-gen", SourceKitRequest::InterfaceGen)
        .Case("interface-gen-open", SourceKitRequest::InterfaceGenOpen)
        .Case("find-usr", SourceKitRequest::FindUSR)
        .Case("find-interface", SourceKitRequest::FindInterfaceDoc)
        .Case("open", SourceKitRequest::Open)
        .Case("close", SourceKitRequest::Close)
        .Case("edit", SourceKitRequest::Edit)
        .Case("print-annotations", SourceKitRequest::PrintAnnotations)
        .Case("print-diags", SourceKitRequest::PrintDiags)
        .Case("extract-comment", SourceKitRequest::ExtractComment)
        .Case("module-groups", SourceKitRequest::ModuleGroups)
        .Case("range", SourceKitRequest::RangeInfo)
        .Case("syntactic-rename", SourceKitRequest::SyntacticRename)
        .Case("find-rename-ranges", SourceKitRequest::FindRenameRanges)
        .Case("find-local-rename-ranges", SourceKitRequest::FindLocalRenameRanges)
        .Case("translate", SourceKitRequest::NameTranslation)
        .Case("local-rename", SourceKitRequest::LocalRename)
        .Case("extract-expr", SourceKitRequest::ExtractExpr)
        .Case("extract-repeated", SourceKitRequest::ExtractRepeatedExpr)
        .Case("extract-func", SourceKitRequest::ExtractFunction)
        .Case("fill-stub", SourceKitRequest::FillProtocolStub)
        .Case("expand-default", SourceKitRequest::ExpandDefault)
        .Case("localize-string", SourceKitRequest::LocalizeString)
        .Case("markup-xml", SourceKitRequest::MarkupToXML)
        .Case("stats", SourceKitRequest::Statistics)
        .Case("track-compiles", SourceKitRequest::EnableCompileNotifications)
        .Default(SourceKitRequest::None);

      if (Request == SourceKitRequest::None) {
        llvm::errs() << "error: invalid request '" << InputArg->getValue()
            << "'\nexpected one of "
            << "version/demangle/mangle/index/complete/complete.open/complete.cursor/"
               "complete.update/complete.cache.ondisk/complete.cache.setpopularapi/"
               "cursor/related-idents/syntax-map/structure/format/expand-placeholder/"
               "doc-info/sema/interface-gen/interface-gen-openfind-usr/find-interface/"
               "open/close/edit/print-annotations/print-diags/extract-comment/module-groups/"
               "range/syntactic-rename/find-rename-ranges/translate/markup-xml/stats/"
               "track-compiles\n";
        return true;
      }
      break;

    case OPT_help: {
      printHelp(false);
      return true;
    }

    case OPT_offset:
      if (StringRef(InputArg->getValue()).getAsInteger(10, Offset)) {
        llvm::errs() << "error: expected integer for 'offset'\n";
        return true;
      }
      break;

    case OPT_length:
      if (StringRef(InputArg->getValue()).getAsInteger(10, Length)) {
        llvm::errs() << "error: expected integer for 'length'\n";
        return true;
      }
      break;

    case OPT_pos: {
      auto linecol = parseLineCol(InputArg->getValue());
      Line = linecol.first;
      Col = linecol.second;
      break;
    }

    case OPT_end_pos: {
      auto linecol = parseLineCol(InputArg->getValue());
      EndLine = linecol.first;
      EndCol = linecol.second;
      break;
    }

    case OPT_using_swift_args: {
      UsingSwiftArgs = true;
      break;
    }

    case OPT_swift_version:
      SwiftVersion = InputArg->getValue();
      break;

    case OPT_pass_version_as_string:
      PassVersionAsString = true;
      break;

    case OPT_line:
      if (StringRef(InputArg->getValue()).getAsInteger(10, Line)) {
        llvm::errs() << "error: expected integer for 'line'\n";
        return true;
      }
      Col = 1;
      break;

    case OPT_replace:
      ReplaceText = InputArg->getValue();
      break;

    case OPT_module:
      ModuleName = InputArg->getValue();
      break;

    case OPT_group_name:
      ModuleGroupName = InputArg->getValue();
      break;

    case OPT_interested_usr:
      InterestedUSR = InputArg->getValue();
      break;

    case OPT_header:
      HeaderPath = InputArg->getValue();
      break;

    case OPT_text_input:
      TextInputFile = InputArg->getValue();
      break;

    case OPT_usr:
      USR = InputArg->getValue();
      break;

    case OPT_pass_as_sourcetext:
      PassAsSourceText = true;
      break;

    case OPT_cache_path:
      CachePath = InputArg->getValue();
      break;

    case OPT_req_opts:
      for (auto item : InputArg->getValues())
        RequestOptions.push_back(item);
      break;

    case OPT_check_interface_is_ascii:
      CheckInterfaceIsASCII = true;
      break;

    case OPT_dont_print_request:
      PrintRequest = false;
      break;

    case OPT_print_response_as_json:
      PrintResponseAsJSON = true;
      break;

    case OPT_print_raw_response:
      PrintRawResponse = true;
      break;

    case OPT_dont_print_response:
      PrintResponse = false;
      break;

    case OPT_INPUT:
      SourceFile = InputArg->getValue();
      SourceText = llvm::None;
      Inputs.push_back(InputArg->getValue());
      break;

    case OPT_rename_spec:
      RenameSpecPath = InputArg->getValue();
      break;

    case OPT_json_request_path:
      JsonRequestPath = InputArg->getValue();
      break;

    case OPT_simplified_demangling:
      SimplifiedDemangling = true;
      break;

    case OPT_synthesized_extension:
      SynthesizedExtensions = true;
      break;

    case OPT_async:
      isAsyncRequest = true;
      break;

    case OPT_cursor_action:
      CollectActionables = true;
      break;

    case OPT_swift_name:
      SwiftName = InputArg->getValue();
      break;

    case OPT_objc_name:
      ObjCName = InputArg->getValue();
      break;

    case OPT_objc_selector:
      ObjCSelector = InputArg->getValue();
      break;

    case OPT_name:
      Name = InputArg->getValue();
      break;

    case OPT_cancel_on_subsequent_request:
      unsigned Cancel;
      if (StringRef(InputArg->getValue()).getAsInteger(10, Cancel)) {
        llvm::errs() << "error: expected integer for 'cancel-on-subsequent-request'\n";
        return true;
      }
      CancelOnSubsequentRequest = Cancel;
      break;

    case OPT_time_request:
      timeRequest = true;
      break;

    case OPT_repeat_request:
      if (StringRef(InputArg->getValue()).getAsInteger(10, repeatRequest)) {
        llvm::errs() << "error: expected integer for 'cancel-on-subsequent-request'\n";
        return true;
      } else if (repeatRequest < 1) {
        llvm::errs() << "error: repeat-request must be >= 1\n";
        return true;
      }
      break;

    case OPT_UNKNOWN:
      llvm::errs() << "error: unknown argument: "
                   << InputArg->getAsString(ParsedArgs) << '\n'
                   << "Use -h or -help for assistance" << '\n';
      return true;
    }
  }

  if (Request == SourceKitRequest::InterfaceGenOpen && isAsyncRequest) {
    llvm::errs()
        << "error: cannot use -async with interface-gen-open request\n";
    return true;
  }

  return false;
}

void TestOptions::printHelp(bool ShowHidden) const {

  // Based off of swift/lib/Driver/Driver.cpp, at Driver::printHelp
  //FIXME: should we use IncludedFlagsBitmask and ExcludedFlagsBitmask?
  // Maybe not for modes such as Interactive, Batch, AutolinkExtract, etc,
  // as in Driver.cpp. But could be useful for extra info, like HelpHidden.

  TestOptTable Table;

  Table.PrintHelp(llvm::outs(), "sourcekitd-test", "SourceKit Testing Tool",
                      ShowHidden);
}
<commit_msg>[master-next] Adjust sourcekitd-test PrintHelp call for LLVM r344097<commit_after>//===--- TestOptions.cpp --------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#include "TestOptions.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Option/Arg.h"
#include "llvm/Option/ArgList.h"
#include "llvm/Option/Option.h"
#include "llvm/Support/raw_ostream.h"

using namespace sourcekitd_test;
using llvm::StringRef;

namespace {

// Create enum with OPT_xxx values for each option in Options.td.
enum Opt {
  OPT_INVALID = 0,
#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM,  \
               HELP, META, VALUES)                                             \
  OPT_##ID,
#include "Options.inc"
  LastOption
#undef OPTION
};

// Create prefix string literals used in Options.td.
#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;
#include "Options.inc"
#undef PREFIX

// Create table mapping all options defined in Options.td.
static const llvm::opt::OptTable::Info InfoTable[] = {
#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM,  \
               HELPTEXT, METAVAR, VALUES)                                      \
  {PREFIX,      NAME,      HELPTEXT,                                           \
   METAVAR,     OPT_##ID,  llvm::opt::Option::KIND##Class,                     \
   PARAM,       FLAGS,     OPT_##GROUP,                                        \
   OPT_##ALIAS, ALIASARGS, VALUES},
#include "Options.inc"
#undef OPTION
};

// Create OptTable class for parsing actual command line arguments
class TestOptTable : public llvm::opt::OptTable {
public:
  TestOptTable() : OptTable(InfoTable, llvm::array_lengthof(InfoTable)){}
};

} // end anonymous namespace

static std::pair<unsigned, unsigned> parseLineCol(StringRef LineCol) {
  unsigned Line, Col;
  size_t ColonIdx = LineCol.find(':');
  if (ColonIdx == StringRef::npos) {
    llvm::errs() << "wrong pos format, it should be '<line>:<column>'\n";
    exit(1);
  }
  if (LineCol.substr(0, ColonIdx).getAsInteger(10, Line)) {
    llvm::errs() << "wrong pos format, it should be '<line>:<column>'\n";
    exit(1);
  }
  if (LineCol.substr(ColonIdx+1).getAsInteger(10, Col)) {
    llvm::errs() << "wrong pos format, it should be '<line>:<column>'\n";
    exit(1);
  }

  if (Line == 0 || Col == 0) {
    llvm::errs() << "wrong pos format, line/col should start from 1\n";
    exit(1);
  }

  return { Line, Col };
}

bool TestOptions::parseArgs(llvm::ArrayRef<const char *> Args) {
  if (Args.empty())
    return false;

  // Parse command line options using Options.td
  TestOptTable Table;
  unsigned MissingIndex;
  unsigned MissingCount;
  llvm::opt::InputArgList ParsedArgs =
      Table.ParseArgs(Args, MissingIndex, MissingCount);
  if (MissingCount) {
    llvm::errs() << "error: missing argument value for '"
        << ParsedArgs.getArgString(MissingIndex) << "', expected "
        << MissingCount << " argument(s)\n";
    return true;
  }

  for (auto InputArg : ParsedArgs) {
    switch (InputArg->getOption().getID()) {
    case OPT_req:
      Request = llvm::StringSwitch<SourceKitRequest>(InputArg->getValue())
        .Case("version", SourceKitRequest::ProtocolVersion)
        .Case("demangle", SourceKitRequest::DemangleNames)
        .Case("mangle", SourceKitRequest::MangleSimpleClasses)
        .Case("index", SourceKitRequest::Index)
        .Case("complete", SourceKitRequest::CodeComplete)
        .Case("complete.open", SourceKitRequest::CodeCompleteOpen)
        .Case("complete.close", SourceKitRequest::CodeCompleteClose)
        .Case("complete.update", SourceKitRequest::CodeCompleteUpdate)
        .Case("complete.cache.ondisk", SourceKitRequest::CodeCompleteCacheOnDisk)
        .Case("complete.setpopularapi", SourceKitRequest::CodeCompleteSetPopularAPI)
        .Case("typecontextinfo", SourceKitRequest::TypeContextInfo)
        .Case("cursor", SourceKitRequest::CursorInfo)
        .Case("related-idents", SourceKitRequest::RelatedIdents)
        .Case("syntax-map", SourceKitRequest::SyntaxMap)
        .Case("syntax-tree", SourceKitRequest::SyntaxTree)
        .Case("structure", SourceKitRequest::Structure)
        .Case("format", SourceKitRequest::Format)
        .Case("expand-placeholder", SourceKitRequest::ExpandPlaceholder)
        .Case("doc-info", SourceKitRequest::DocInfo)
        .Case("sema", SourceKitRequest::SemanticInfo)
        .Case("interface-gen", SourceKitRequest::InterfaceGen)
        .Case("interface-gen-open", SourceKitRequest::InterfaceGenOpen)
        .Case("find-usr", SourceKitRequest::FindUSR)
        .Case("find-interface", SourceKitRequest::FindInterfaceDoc)
        .Case("open", SourceKitRequest::Open)
        .Case("close", SourceKitRequest::Close)
        .Case("edit", SourceKitRequest::Edit)
        .Case("print-annotations", SourceKitRequest::PrintAnnotations)
        .Case("print-diags", SourceKitRequest::PrintDiags)
        .Case("extract-comment", SourceKitRequest::ExtractComment)
        .Case("module-groups", SourceKitRequest::ModuleGroups)
        .Case("range", SourceKitRequest::RangeInfo)
        .Case("syntactic-rename", SourceKitRequest::SyntacticRename)
        .Case("find-rename-ranges", SourceKitRequest::FindRenameRanges)
        .Case("find-local-rename-ranges", SourceKitRequest::FindLocalRenameRanges)
        .Case("translate", SourceKitRequest::NameTranslation)
        .Case("local-rename", SourceKitRequest::LocalRename)
        .Case("extract-expr", SourceKitRequest::ExtractExpr)
        .Case("extract-repeated", SourceKitRequest::ExtractRepeatedExpr)
        .Case("extract-func", SourceKitRequest::ExtractFunction)
        .Case("fill-stub", SourceKitRequest::FillProtocolStub)
        .Case("expand-default", SourceKitRequest::ExpandDefault)
        .Case("localize-string", SourceKitRequest::LocalizeString)
        .Case("markup-xml", SourceKitRequest::MarkupToXML)
        .Case("stats", SourceKitRequest::Statistics)
        .Case("track-compiles", SourceKitRequest::EnableCompileNotifications)
        .Default(SourceKitRequest::None);

      if (Request == SourceKitRequest::None) {
        llvm::errs() << "error: invalid request '" << InputArg->getValue()
            << "'\nexpected one of "
            << "version/demangle/mangle/index/complete/complete.open/complete.cursor/"
               "complete.update/complete.cache.ondisk/complete.cache.setpopularapi/"
               "cursor/related-idents/syntax-map/structure/format/expand-placeholder/"
               "doc-info/sema/interface-gen/interface-gen-openfind-usr/find-interface/"
               "open/close/edit/print-annotations/print-diags/extract-comment/module-groups/"
               "range/syntactic-rename/find-rename-ranges/translate/markup-xml/stats/"
               "track-compiles\n";
        return true;
      }
      break;

    case OPT_help: {
      printHelp(false);
      return true;
    }

    case OPT_offset:
      if (StringRef(InputArg->getValue()).getAsInteger(10, Offset)) {
        llvm::errs() << "error: expected integer for 'offset'\n";
        return true;
      }
      break;

    case OPT_length:
      if (StringRef(InputArg->getValue()).getAsInteger(10, Length)) {
        llvm::errs() << "error: expected integer for 'length'\n";
        return true;
      }
      break;

    case OPT_pos: {
      auto linecol = parseLineCol(InputArg->getValue());
      Line = linecol.first;
      Col = linecol.second;
      break;
    }

    case OPT_end_pos: {
      auto linecol = parseLineCol(InputArg->getValue());
      EndLine = linecol.first;
      EndCol = linecol.second;
      break;
    }

    case OPT_using_swift_args: {
      UsingSwiftArgs = true;
      break;
    }

    case OPT_swift_version:
      SwiftVersion = InputArg->getValue();
      break;

    case OPT_pass_version_as_string:
      PassVersionAsString = true;
      break;

    case OPT_line:
      if (StringRef(InputArg->getValue()).getAsInteger(10, Line)) {
        llvm::errs() << "error: expected integer for 'line'\n";
        return true;
      }
      Col = 1;
      break;

    case OPT_replace:
      ReplaceText = InputArg->getValue();
      break;

    case OPT_module:
      ModuleName = InputArg->getValue();
      break;

    case OPT_group_name:
      ModuleGroupName = InputArg->getValue();
      break;

    case OPT_interested_usr:
      InterestedUSR = InputArg->getValue();
      break;

    case OPT_header:
      HeaderPath = InputArg->getValue();
      break;

    case OPT_text_input:
      TextInputFile = InputArg->getValue();
      break;

    case OPT_usr:
      USR = InputArg->getValue();
      break;

    case OPT_pass_as_sourcetext:
      PassAsSourceText = true;
      break;

    case OPT_cache_path:
      CachePath = InputArg->getValue();
      break;

    case OPT_req_opts:
      for (auto item : InputArg->getValues())
        RequestOptions.push_back(item);
      break;

    case OPT_check_interface_is_ascii:
      CheckInterfaceIsASCII = true;
      break;

    case OPT_dont_print_request:
      PrintRequest = false;
      break;

    case OPT_print_response_as_json:
      PrintResponseAsJSON = true;
      break;

    case OPT_print_raw_response:
      PrintRawResponse = true;
      break;

    case OPT_dont_print_response:
      PrintResponse = false;
      break;

    case OPT_INPUT:
      SourceFile = InputArg->getValue();
      SourceText = llvm::None;
      Inputs.push_back(InputArg->getValue());
      break;

    case OPT_rename_spec:
      RenameSpecPath = InputArg->getValue();
      break;

    case OPT_json_request_path:
      JsonRequestPath = InputArg->getValue();
      break;

    case OPT_simplified_demangling:
      SimplifiedDemangling = true;
      break;

    case OPT_synthesized_extension:
      SynthesizedExtensions = true;
      break;

    case OPT_async:
      isAsyncRequest = true;
      break;

    case OPT_cursor_action:
      CollectActionables = true;
      break;

    case OPT_swift_name:
      SwiftName = InputArg->getValue();
      break;

    case OPT_objc_name:
      ObjCName = InputArg->getValue();
      break;

    case OPT_objc_selector:
      ObjCSelector = InputArg->getValue();
      break;

    case OPT_name:
      Name = InputArg->getValue();
      break;

    case OPT_cancel_on_subsequent_request:
      unsigned Cancel;
      if (StringRef(InputArg->getValue()).getAsInteger(10, Cancel)) {
        llvm::errs() << "error: expected integer for 'cancel-on-subsequent-request'\n";
        return true;
      }
      CancelOnSubsequentRequest = Cancel;
      break;

    case OPT_time_request:
      timeRequest = true;
      break;

    case OPT_repeat_request:
      if (StringRef(InputArg->getValue()).getAsInteger(10, repeatRequest)) {
        llvm::errs() << "error: expected integer for 'cancel-on-subsequent-request'\n";
        return true;
      } else if (repeatRequest < 1) {
        llvm::errs() << "error: repeat-request must be >= 1\n";
        return true;
      }
      break;

    case OPT_UNKNOWN:
      llvm::errs() << "error: unknown argument: "
                   << InputArg->getAsString(ParsedArgs) << '\n'
                   << "Use -h or -help for assistance" << '\n';
      return true;
    }
  }

  if (Request == SourceKitRequest::InterfaceGenOpen && isAsyncRequest) {
    llvm::errs()
        << "error: cannot use -async with interface-gen-open request\n";
    return true;
  }

  return false;
}

void TestOptions::printHelp(bool ShowHidden) const {

  // Based off of swift/lib/Driver/Driver.cpp, at Driver::printHelp
  //FIXME: should we use IncludedFlagsBitmask and ExcludedFlagsBitmask?
  // Maybe not for modes such as Interactive, Batch, AutolinkExtract, etc,
  // as in Driver.cpp. But could be useful for extra info, like HelpHidden.

  TestOptTable Table;

  Table.PrintHelp(llvm::outs(), "sourcekitd-test [options] <inputs>",
                  "SourceKit Testing Tool", ShowHidden);
}
<|endoftext|>


<commit_before>#include "gtest/gtest.h"

#include "lib/sql_util.h"
#include "lib/file_replace.h"

using hawq::test::SQLUtility;
using hawq::test::FileReplace;

class TestExternalTable : public ::testing::Test {
 public:
  TestExternalTable() {}
  ~TestExternalTable() {}
};

TEST_F(TestExternalTable, TestExternalTableAll) {
  SQLUtility util;
  auto test_root = util.getTestRootPath();
  auto replace_lambda = [&] () {
    FileReplace frep;
    std::unordered_map<std::string, std::string> D;
    D["@hostname@"] = std::string("localhost");
    D["@abs_srcdir@"] = test_root + "/ExternalSource";
    D["@gpwhich_gpfdist@"] = std::string(std::string(getenv("GPHOME")) + "/bin/gpfdist");
    frep.replace(test_root + "/ExternalSource/sql/exttab1.sql.source",
                 test_root + "/ExternalSource/sql/exttab1.sql",
                 D);
    frep.replace(test_root + "/ExternalSource/ans/exttab1.ans.source",
                 test_root + "/ExternalSource/ans/exttab1.ans",
                 D);
  };

  replace_lambda();
  util.execSQLFile("ExternalSource/sql/exttab1.sql",
                   "ExternalSource/ans/exttab1.ans");
}
<commit_msg>HAWQ-1126. Disable feature test case of ExternalTable temporarily<commit_after>#include "gtest/gtest.h"

#include "lib/sql_util.h"
#include "lib/file_replace.h"

using hawq::test::SQLUtility;
using hawq::test::FileReplace;

class TestExternalTable : public ::testing::Test {
 public:
  TestExternalTable() {}
  ~TestExternalTable() {}
};

TEST_F(TestExternalTable, DISABLED_TestExternalTableAll) {
  SQLUtility util;
  auto test_root = util.getTestRootPath();
  auto replace_lambda = [&] () {
    FileReplace frep;
    std::unordered_map<std::string, std::string> D;
    D["@hostname@"] = std::string("localhost");
    D["@abs_srcdir@"] = test_root + "/ExternalSource";
    D["@gpwhich_gpfdist@"] = std::string(std::string(getenv("GPHOME")) + "/bin/gpfdist");
    frep.replace(test_root + "/ExternalSource/sql/exttab1.sql.source",
                 test_root + "/ExternalSource/sql/exttab1.sql",
                 D);
    frep.replace(test_root + "/ExternalSource/ans/exttab1.ans.source",
                 test_root + "/ExternalSource/ans/exttab1.ans",
                 D);
  };

  replace_lambda();
  util.execSQLFile("ExternalSource/sql/exttab1.sql",
                   "ExternalSource/ans/exttab1.ans");
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2008-2013 The Communi Project
 *
 * This test is free, and not covered by the LGPL license. There is no
 * restriction applied to their modification, redistribution, using and so on.
 * You can study them, modify them, use them in your own program - either
 * completely or partially.
 */

#include "irc.h"
#include "irctextformat.h"
#include <QtTest/QtTest>

class tst_IrcTextFormat : public QObject
{
    Q_OBJECT

private slots:
    void testDefaults();
    void testColorName();
    void testPlainText_data();
    void testPlainText();
};

void tst_IrcTextFormat::testDefaults()
{
    IrcTextFormat format;
    QVERIFY(!format.urlPattern().isEmpty());
    for (int i = Irc::White; i <= Irc::LightGray; ++i)
        QVERIFY(!format.colorName(i).isEmpty());
    QCOMPARE(format.colorName(-1, "fallback"), QString("fallback"));
}

void tst_IrcTextFormat::testColorName()
{
    IrcTextFormat format;
    for (int i = -1; i <= 123; ++i) {
        format.setColorName(i, QString::number(i));
        QCOMPARE(format.colorName(i), QString::number(i));
    }
}

void tst_IrcTextFormat::testPlainText_data()
{
    QTest::addColumn<QString>("input");
    QTest::addColumn<QString>("output");

    QTest::newRow("bold") << "\02bold\x0f" << "bold";
    QTest::newRow("strike-through") << "\x13strike-through\x0f" << "strike-through";
    QTest::newRow("underline") << "\x15underline\x0f" << "underline";
    QTest::newRow("inverse") << "\x16inverse\x0f" << "inverse";
    QTest::newRow("italic") << "\x1ditalic\x0f" << "italic";
    QTest::newRow("underline") << "\x1funderline\x0f" << "underline";

    IrcTextFormat format;
    for (int i = Irc::White; i <= Irc::LightGray; ++i) {
        QString color = format.colorName(i);
        QTest::newRow(color.toUtf8()) << QString("\x03%1%2\x0f").arg(i).arg(color) << color;
    }
}

void tst_IrcTextFormat::testPlainText()
{
    QFETCH(QString, input);
    QFETCH(QString, output);

    IrcTextFormat format;
    QCOMPARE(format.toPlainText(input), output);
}

QTEST_MAIN(tst_IrcTextFormat)

#include "tst_irctextformat.moc"
<commit_msg>Extend IrcTextFormat auto test<commit_after>/*
 * Copyright (C) 2008-2013 The Communi Project
 *
 * This test is free, and not covered by the LGPL license. There is no
 * restriction applied to their modification, redistribution, using and so on.
 * You can study them, modify them, use them in your own program - either
 * completely or partially.
 */

#include "irc.h"
#include "irctextformat.h"
#include <QtTest/QtTest>

class tst_IrcTextFormat : public QObject
{
    Q_OBJECT

private slots:
    void testDefaults();
    void testColorName();
    void testPlainText_data();
    void testPlainText();
    void testHtml_data();
    void testHtml();
    void testUrls_data();
    void testUrls();
};

void tst_IrcTextFormat::testDefaults()
{
    IrcTextFormat format;
    QVERIFY(!format.urlPattern().isEmpty());
    for (int i = Irc::White; i <= Irc::LightGray; ++i)
        QVERIFY(!format.colorName(i).isEmpty());
    QCOMPARE(format.colorName(-1, "fallback"), QString("fallback"));
}

void tst_IrcTextFormat::testColorName()
{
    IrcTextFormat format;
    for (int i = -1; i <= 123; ++i) {
        format.setColorName(i, QString::number(i));
        QCOMPARE(format.colorName(i), QString::number(i));
    }
}

void tst_IrcTextFormat::testPlainText_data()
{
    QTest::addColumn<QString>("input");
    QTest::addColumn<QString>("output");

    QTest::newRow("bold") << "\02bold\x0f" << "bold";
    QTest::newRow("strike-through") << "\x13strike-through\x0f" << "strike-through";
    QTest::newRow("underline") << "\x15underline\x0f" << "underline";
    QTest::newRow("inverse") << "\x16inverse\x0f" << "inverse";
    QTest::newRow("italic") << "\x1ditalic\x0f" << "italic";
    QTest::newRow("underline") << "\x1funderline\x0f" << "underline";

    IrcTextFormat format;
    for (int i = Irc::White; i <= Irc::LightGray; ++i) {
        QString color = format.colorName(i);
        QTest::newRow(color.toUtf8()) << QString("\x03%1%2\x0f").arg(i).arg(color) << color;
    }
}

void tst_IrcTextFormat::testPlainText()
{
    QFETCH(QString, input);
    QFETCH(QString, output);

    IrcTextFormat format;
    QCOMPARE(format.toPlainText(input), output);
}

void tst_IrcTextFormat::testHtml_data()
{
    QTest::addColumn<QString>("input");
    QTest::addColumn<QString>("output");

    QTest::newRow("bold") << "\02bold\x0f" << "bold";
    QTest::newRow("strike-through") << "\x13strike-through\x0f" << "strike-through";
    QTest::newRow("underline") << "\x15underline\x0f" << "underline";
    //TODO: QTest::newRow("inverse") << "\x16inverse\x0f" << "inverse";
    QTest::newRow("italic") << "\x1ditalic\x0f" << "italic";
    QTest::newRow("underline") << "\x1funderline\x0f" << "underline";

    IrcTextFormat format;
    for (int i = Irc::White; i <= Irc::LightGray; ++i) {
        QString color = format.colorName(i);
        QTest::newRow(color.toUtf8()) << QString("\x03%1%2\x0f").arg(i).arg(color) << QString("%1").arg(color);
    }
}

void tst_IrcTextFormat::testHtml()
{
    QFETCH(QString, input);
    QFETCH(QString, output);

    IrcTextFormat format;
    QCOMPARE(format.toHtml(input), output);
}

void tst_IrcTextFormat::testUrls_data()
{
    QTest::addColumn<QString>("input");
    QTest::addColumn<QString>("output");

    QTest::newRow("www.fi") << "www.fi" << "www.fi";
    QTest::newRow("ftp.funet.fi") << "ftp.funet.fi" << "ftp.funet.fi";
    QTest::newRow("jpnurmi@gmail.com") << "jpnurmi@gmail.com" << "jpnurmi@gmail.com";
    QTest::newRow("github commits") << "https://github.com/communi/libcommuni/compare/ebf3c8ea47dc...19d66ddcb122" << "https://github.com/communi/libcommuni/compare/ebf3c8ea47dc...19d66ddcb122";
}

void tst_IrcTextFormat::testUrls()
{
    QFETCH(QString, input);
    QFETCH(QString, output);

    IrcTextFormat format;
    QCOMPARE(format.toHtml(input), output);
}

QTEST_MAIN(tst_IrcTextFormat)

#include "tst_irctextformat.moc"
<|endoftext|>


<commit_before>/*
 * dis.cpp
 *
 *  Created on: Sep 20, 2015
 *      Author: anon
 */

#include "arm/ARMDisassembler.h"

#include <memory>
#include <string>
#include <cstdint>
#include <iostream>

using namespace std;
using namespace Disassembler;

int main(int argc, char **argv) {
    if (argc < 2) {
        cerr << "Usage: ./%s [thumb|arm] <hex_opcode>" << endl;
        return -1;
    }

    string arg_mode { argv[1] };
    string arg_opcode { argv[2] };

    ARMMode mode = (arg_mode == "thumb") ? ARMMode_Thumb : ARMMode_ARM;
    uint32_t opcode = std::stoul(arg_opcode, nullptr, 16);

    ARMDisassembler dis;
    shared_ptr<ARMInstruction> ins = dis.disassemble(opcode, mode);
    cout << "Disassembled instruction: " << (void *) opcode << " -> " << ins->toString() << endl;

    return 0;
}
<commit_msg>Make sure we invert the thumb2 opcodes.<commit_after>/*
 * dis.cpp
 *
 *  Created on: Sep 20, 2015
 *      Author: anon
 */

#include "arm/ARMDisassembler.h"

#include <memory>
#include <string>
#include <cstdint>
#include <iostream>

using namespace std;
using namespace Disassembler;

int main(int argc, char **argv) {
    if (argc < 2) {
        cerr << "Usage: ./%s [thumb|arm] <hex_opcode>" << endl;
        return -1;
    }

    string arg_mode { argv[1] };
    string arg_opcode { argv[2] };

    uint32_t opcode = std::stoul(arg_opcode, nullptr, 16);

    ARMMode mode;
    if (arg_mode == "thumb") {
        mode = ARMMode_Thumb;
        cout << "Using mode THUMB" << endl;

        if (opcode > 0xffff) {
            opcode = (opcode >> 16) | ((opcode << 16) & 0xffffffff);
        }
    } else {
        mode = ARMMode_ARM;
        cout << "Using mode THUMB" << endl;
    }

    ARMDisassembler dis { ARMv7All };
    shared_ptr<ARMInstruction> ins = dis.disassemble(opcode, mode);
    cout << "Disassembled instruction: " << (void *) opcode << " -> " << ins->toString() << endl;

    return 0;
}
<|endoftext|>


<commit_before>/* Copyright 2016 The TensorFlow Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/

#include "tensorflow/cc/saved_model/loader.h"

#include <unordered_set>

#include "tensorflow/cc/saved_model/constants.h"
#include "tensorflow/core/lib/io/path.h"
#include "tensorflow/core/lib/monitoring/counter.h"
#include "tensorflow/core/platform/env.h"
#include "tensorflow/core/platform/protobuf_internal.h"
#include "tensorflow/core/protobuf/saved_model.pb.h"
#include "tensorflow/core/public/session.h"
#include "tensorflow/core/public/session_options.h"
#include "tensorflow/core/util/tensor_bundle/naming.h"

namespace tensorflow {
namespace {

auto* load_attempt_count = monitoring::Counter<2>::New(
    "/tensorflow/cc/saved_model/load_attempt_count", "model_path", "status",
    "The number of times a SavedModel was successfully loaded.");
auto* load_latency = monitoring::Counter<1>::New(
    "/tensorflow/cc/saved_model/load_latency", "model_path",
    "Latency in microseconds for SavedModels that were succesfully loaded.");
constexpr char kLoadAttemptFail[] = "fail";
constexpr char kLoadAttemptSuccess[] = "success";

Status ReadSavedModel(const string& export_dir, SavedModel* saved_model_proto) {
  const string saved_model_pb_path =
      io::JoinPath(export_dir, kSavedModelFilenamePb);
  if (Env::Default()->FileExists(saved_model_pb_path).ok()) {
    return ReadBinaryProto(Env::Default(), saved_model_pb_path,
                           saved_model_proto);
  }
  const string saved_model_pbtxt_path =
      io::JoinPath(export_dir, kSavedModelFilenamePbTxt);
  if (Env::Default()->FileExists(saved_model_pbtxt_path).ok()) {
    return ReadTextProto(Env::Default(), saved_model_pbtxt_path,
                         saved_model_proto);
  }
  return Status(error::Code::NOT_FOUND,
                "Could not find SavedModel .pb or .pbtxt at supplied export "
                "directory path: " +
                    export_dir);
}

Status FindMetaGraphDefToLoad(const SavedModel& saved_model_proto,
                              const std::unordered_set<string>& tags,
                              MetaGraphDef* meta_graph_def_to_load) {
  for (const MetaGraphDef& meta_graph_def : saved_model_proto.meta_graphs()) {
    // Get tags from the meta_graph_def.
    std::unordered_set<string> graph_tags;
    for (const string& tag : meta_graph_def.meta_info_def().tags()) {
      graph_tags.insert(tag);
    }
    // Match with the set of tags provided.
    if (graph_tags == tags) {
      *meta_graph_def_to_load = meta_graph_def;
      return Status::OK();
    }
  }
  return Status(error::Code::NOT_FOUND,
                "Could not find meta graph def matching supplied tags.");
}

Status LoadMetaGraphIntoSession(const MetaGraphDef& meta_graph_def,
                                const SessionOptions& session_options,
                                std::unique_ptr<Session>* session) {
  session->reset(NewSession(session_options));
  return (*session)->Create(meta_graph_def.graph_def());
}

Tensor CreateStringTensor(const string& value) {
  Tensor tensor(DT_STRING, TensorShape({}));
  tensor.scalar<string>()() = value;
  return tensor;
}

void AddAssetsTensorsToInputs(const StringPiece export_dir,
                              const std::vector<AssetFileDef>& asset_file_defs,
                              std::vector<std::pair<string, Tensor>>* inputs) {
  if (asset_file_defs.empty()) {
    return;
  }
  for (auto& asset_file_def : asset_file_defs) {
    Tensor assets_file_path_tensor = CreateStringTensor(io::JoinPath(
        export_dir, kSavedModelAssetsDirectory, asset_file_def.filename()));
    inputs->push_back(
        {asset_file_def.tensor_info().name(), assets_file_path_tensor});
  }
}

Status RunRestore(const RunOptions& run_options, const string& export_dir,
                  const StringPiece restore_op_name,
                  const StringPiece variable_filename_const_op_name,
                  const std::vector<AssetFileDef>& asset_file_defs,
                  Session* session) {
  LOG(INFO) << "Restoring SavedModel bundle.";
  // Find path to variables to be restored in export directory.
  const string variables_directory =
      io::JoinPath(export_dir, kSavedModelVariablesDirectory);
  // Check for saver checkpoints in v2 format. Models exported in the checkpoint
  // v2 format will have a variables.index file. The corresponding
  // variables are stored in the variables.data-?????-of-????? files.
  const string variables_index_path = io::JoinPath(
      variables_directory, MetaFilename(kSavedModelVariablesFilename));
  if (!Env::Default()->FileExists(variables_index_path).ok()) {
    return errors::NotFound(
        "Checkpoint index file not found in SavedModel directory.");
  }
  const string variables_path =
      io::JoinPath(variables_directory, kSavedModelVariablesFilename);

  // Add variables to the graph.
  Tensor variables_path_tensor(DT_STRING, TensorShape({}));
  variables_path_tensor.scalar<string>()() = variables_path;

  std::vector<std::pair<string, Tensor>> inputs = {
      {variable_filename_const_op_name.ToString(), variables_path_tensor}};

  AddAssetsTensorsToInputs(export_dir, asset_file_defs, &inputs);

  RunMetadata run_metadata;
  return session->Run(run_options, inputs, {}, {restore_op_name.ToString()},
                      nullptr /* outputs */, &run_metadata);
}

Status RunLegacyInitOp(const RunOptions& run_options, const string& export_dir,
                       const MetaGraphDef& meta_graph_def,
                       const std::vector<AssetFileDef>& asset_file_defs,
                       Session* session) {
  LOG(INFO) << "Running LegacyInitOp on SavedModel bundle.";
  const auto& collection_def_map = meta_graph_def.collection_def();
  const auto init_op_it = collection_def_map.find(kSavedModelLegacyInitOpKey);
  if (init_op_it != collection_def_map.end()) {
    if (init_op_it->second.node_list().value_size() != 1) {
      return errors::FailedPrecondition(strings::StrCat(
          "Expected exactly one serving init op in : ", export_dir));
    }
    std::vector<std::pair<string, Tensor>> inputs;
    AddAssetsTensorsToInputs(export_dir, asset_file_defs, &inputs);
    RunMetadata run_metadata;
    const StringPiece legacy_init_op_name =
        init_op_it->second.node_list().value(0);
    return session->Run(run_options, inputs, {},
                        {legacy_init_op_name.ToString()}, nullptr /* outputs */,
                        &run_metadata);
  }
  return Status::OK();
}

Status GetAssetFileDefs(const MetaGraphDef& meta_graph_def,
                        std::vector<AssetFileDef>* asset_file_defs) {
  const auto& collection_def_map = meta_graph_def.collection_def();
  const auto assets_it = collection_def_map.find(kSavedModelAssetsKey);
  if (assets_it == collection_def_map.end()) {
    return Status::OK();
  }
  const auto& any_assets = assets_it->second.any_list().value();
  for (const auto& any_asset : any_assets) {
    AssetFileDef asset_file_def;
    TF_RETURN_IF_ERROR(
        ParseAny(any_asset, &asset_file_def, "tensorflow.AssetFileDef"));
    asset_file_defs->push_back(asset_file_def);
  }
  return Status::OK();
}

Status LoadSavedModelInternal(const SessionOptions& session_options,
                              const RunOptions& run_options,
                              const string& export_dir,
                              const std::unordered_set<string>& tags,
                              SavedModelBundle* const bundle) {
  if (!MaybeSavedModelDirectory(export_dir)) {
    return Status(error::Code::NOT_FOUND,
                  "SavedModel not found in export directory: " + export_dir);
  }
  LOG(INFO) << "Loading SavedModel from: " << export_dir;

  SavedModel saved_model_proto;
  TF_RETURN_IF_ERROR(ReadSavedModel(export_dir, &saved_model_proto));

  TF_RETURN_IF_ERROR(
      FindMetaGraphDefToLoad(saved_model_proto, tags, &bundle->meta_graph_def));

  TF_RETURN_IF_ERROR(LoadMetaGraphIntoSession(
      bundle->meta_graph_def, session_options, &bundle->session));

  std::vector<AssetFileDef> asset_file_defs;
  TF_RETURN_IF_ERROR(
      GetAssetFileDefs(bundle->meta_graph_def, &asset_file_defs));
  TF_RETURN_IF_ERROR(
      RunRestore(run_options, export_dir,
                 bundle->meta_graph_def.saver_def().restore_op_name(),
                 bundle->meta_graph_def.saver_def().filename_tensor_name(),
                 asset_file_defs, bundle->session.get()));
  // TODO(sukritiramesh): Add support for a single main op to run upon load,
  // which will supersede the legacy_init_op and separate RunRestore.
  TF_RETURN_IF_ERROR(RunLegacyInitOp(run_options, export_dir,
                                     bundle->meta_graph_def, asset_file_defs,
                                     bundle->session.get()));
  return Status::OK();
}

}  // namespace

Status LoadSavedModel(const SessionOptions& session_options,
                      const RunOptions& run_options, const string& export_dir,
                      const std::unordered_set<string>& tags,
                      SavedModelBundle* const bundle) {
  // TODO(robson): Add tests for the counters.
  const uint64 start_microseconds = Env::Default()->NowMicros();
  const Status status = LoadSavedModelInternal(session_options, run_options,
                                               export_dir, tags, bundle);
  const uint64 load_latency_microsecs = [&]() -> uint64 {
    const uint64 end_microseconds = Env::Default()->NowMicros();
    // Avoid clock skew.
    if (end_microseconds < start_microseconds) return 0;
    return end_microseconds - start_microseconds;
  }();
  auto log_and_count = [&](const string& status_str) {
    LOG(INFO) << "Loading SavedModel: " << status_str << ". Took "
              << load_latency_microsecs << " microseconds.";
    load_attempt_count->GetCell(export_dir, status_str)->IncrementBy(1);
  };
  if (status.ok()) {
    log_and_count(kLoadAttemptSuccess);
  } else {
    log_and_count(kLoadAttemptFail);
  }
  load_latency->GetCell(export_dir)->IncrementBy(load_latency_microsecs);
  return status;
}

bool MaybeSavedModelDirectory(const string& export_dir) {
  const string saved_model_pb_path =
      io::JoinPath(export_dir, kSavedModelFilenamePb);
  const string saved_model_pbtxt_path =
      io::JoinPath(export_dir, kSavedModelFilenamePbTxt);
  return Env::Default()->FileExists(saved_model_pb_path).ok() ||
         Env::Default()->FileExists(saved_model_pbtxt_path).ok();
}

}  // namespace tensorflow
<commit_msg>Fix metric definitions in SavedModel. Change: 140854331<commit_after>/* Copyright 2016 The TensorFlow Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/

#include "tensorflow/cc/saved_model/loader.h"

#include <unordered_set>

#include "tensorflow/cc/saved_model/constants.h"
#include "tensorflow/core/lib/io/path.h"
#include "tensorflow/core/lib/monitoring/counter.h"
#include "tensorflow/core/platform/env.h"
#include "tensorflow/core/platform/protobuf_internal.h"
#include "tensorflow/core/protobuf/saved_model.pb.h"
#include "tensorflow/core/public/session.h"
#include "tensorflow/core/public/session_options.h"
#include "tensorflow/core/util/tensor_bundle/naming.h"

namespace tensorflow {
namespace {

auto* load_attempt_count = monitoring::Counter<2>::New(
    "/tensorflow/cc/saved_model/load_attempt_count",
    "The number of times a SavedModel was successfully loaded.", "model_path",
    "status");
auto* load_latency = monitoring::Counter<1>::New(
    "/tensorflow/cc/saved_model/load_latency",
    "Latency in microseconds for SavedModels that were succesfully loaded.",
    "model_path");
constexpr char kLoadAttemptFail[] = "fail";
constexpr char kLoadAttemptSuccess[] = "success";

Status ReadSavedModel(const string& export_dir, SavedModel* saved_model_proto) {
  const string saved_model_pb_path =
      io::JoinPath(export_dir, kSavedModelFilenamePb);
  if (Env::Default()->FileExists(saved_model_pb_path).ok()) {
    return ReadBinaryProto(Env::Default(), saved_model_pb_path,
                           saved_model_proto);
  }
  const string saved_model_pbtxt_path =
      io::JoinPath(export_dir, kSavedModelFilenamePbTxt);
  if (Env::Default()->FileExists(saved_model_pbtxt_path).ok()) {
    return ReadTextProto(Env::Default(), saved_model_pbtxt_path,
                         saved_model_proto);
  }
  return Status(error::Code::NOT_FOUND,
                "Could not find SavedModel .pb or .pbtxt at supplied export "
                "directory path: " +
                    export_dir);
}

Status FindMetaGraphDefToLoad(const SavedModel& saved_model_proto,
                              const std::unordered_set<string>& tags,
                              MetaGraphDef* meta_graph_def_to_load) {
  for (const MetaGraphDef& meta_graph_def : saved_model_proto.meta_graphs()) {
    // Get tags from the meta_graph_def.
    std::unordered_set<string> graph_tags;
    for (const string& tag : meta_graph_def.meta_info_def().tags()) {
      graph_tags.insert(tag);
    }
    // Match with the set of tags provided.
    if (graph_tags == tags) {
      *meta_graph_def_to_load = meta_graph_def;
      return Status::OK();
    }
  }
  return Status(error::Code::NOT_FOUND,
                "Could not find meta graph def matching supplied tags.");
}

Status LoadMetaGraphIntoSession(const MetaGraphDef& meta_graph_def,
                                const SessionOptions& session_options,
                                std::unique_ptr<Session>* session) {
  session->reset(NewSession(session_options));
  return (*session)->Create(meta_graph_def.graph_def());
}

Tensor CreateStringTensor(const string& value) {
  Tensor tensor(DT_STRING, TensorShape({}));
  tensor.scalar<string>()() = value;
  return tensor;
}

void AddAssetsTensorsToInputs(const StringPiece export_dir,
                              const std::vector<AssetFileDef>& asset_file_defs,
                              std::vector<std::pair<string, Tensor>>* inputs) {
  if (asset_file_defs.empty()) {
    return;
  }
  for (auto& asset_file_def : asset_file_defs) {
    Tensor assets_file_path_tensor = CreateStringTensor(io::JoinPath(
        export_dir, kSavedModelAssetsDirectory, asset_file_def.filename()));
    inputs->push_back(
        {asset_file_def.tensor_info().name(), assets_file_path_tensor});
  }
}

Status RunRestore(const RunOptions& run_options, const string& export_dir,
                  const StringPiece restore_op_name,
                  const StringPiece variable_filename_const_op_name,
                  const std::vector<AssetFileDef>& asset_file_defs,
                  Session* session) {
  LOG(INFO) << "Restoring SavedModel bundle.";
  // Find path to variables to be restored in export directory.
  const string variables_directory =
      io::JoinPath(export_dir, kSavedModelVariablesDirectory);
  // Check for saver checkpoints in v2 format. Models exported in the checkpoint
  // v2 format will have a variables.index file. The corresponding
  // variables are stored in the variables.data-?????-of-????? files.
  const string variables_index_path = io::JoinPath(
      variables_directory, MetaFilename(kSavedModelVariablesFilename));
  if (!Env::Default()->FileExists(variables_index_path).ok()) {
    return errors::NotFound(
        "Checkpoint index file not found in SavedModel directory.");
  }
  const string variables_path =
      io::JoinPath(variables_directory, kSavedModelVariablesFilename);

  // Add variables to the graph.
  Tensor variables_path_tensor(DT_STRING, TensorShape({}));
  variables_path_tensor.scalar<string>()() = variables_path;

  std::vector<std::pair<string, Tensor>> inputs = {
      {variable_filename_const_op_name.ToString(), variables_path_tensor}};

  AddAssetsTensorsToInputs(export_dir, asset_file_defs, &inputs);

  RunMetadata run_metadata;
  return session->Run(run_options, inputs, {}, {restore_op_name.ToString()},
                      nullptr /* outputs */, &run_metadata);
}

Status RunLegacyInitOp(const RunOptions& run_options, const string& export_dir,
                       const MetaGraphDef& meta_graph_def,
                       const std::vector<AssetFileDef>& asset_file_defs,
                       Session* session) {
  LOG(INFO) << "Running LegacyInitOp on SavedModel bundle.";
  const auto& collection_def_map = meta_graph_def.collection_def();
  const auto init_op_it = collection_def_map.find(kSavedModelLegacyInitOpKey);
  if (init_op_it != collection_def_map.end()) {
    if (init_op_it->second.node_list().value_size() != 1) {
      return errors::FailedPrecondition(strings::StrCat(
          "Expected exactly one serving init op in : ", export_dir));
    }
    std::vector<std::pair<string, Tensor>> inputs;
    AddAssetsTensorsToInputs(export_dir, asset_file_defs, &inputs);
    RunMetadata run_metadata;
    const StringPiece legacy_init_op_name =
        init_op_it->second.node_list().value(0);
    return session->Run(run_options, inputs, {},
                        {legacy_init_op_name.ToString()}, nullptr /* outputs */,
                        &run_metadata);
  }
  return Status::OK();
}

Status GetAssetFileDefs(const MetaGraphDef& meta_graph_def,
                        std::vector<AssetFileDef>* asset_file_defs) {
  const auto& collection_def_map = meta_graph_def.collection_def();
  const auto assets_it = collection_def_map.find(kSavedModelAssetsKey);
  if (assets_it == collection_def_map.end()) {
    return Status::OK();
  }
  const auto& any_assets = assets_it->second.any_list().value();
  for (const auto& any_asset : any_assets) {
    AssetFileDef asset_file_def;
    TF_RETURN_IF_ERROR(
        ParseAny(any_asset, &asset_file_def, "tensorflow.AssetFileDef"));
    asset_file_defs->push_back(asset_file_def);
  }
  return Status::OK();
}

Status LoadSavedModelInternal(const SessionOptions& session_options,
                              const RunOptions& run_options,
                              const string& export_dir,
                              const std::unordered_set<string>& tags,
                              SavedModelBundle* const bundle) {
  if (!MaybeSavedModelDirectory(export_dir)) {
    return Status(error::Code::NOT_FOUND,
                  "SavedModel not found in export directory: " + export_dir);
  }
  LOG(INFO) << "Loading SavedModel from: " << export_dir;

  SavedModel saved_model_proto;
  TF_RETURN_IF_ERROR(ReadSavedModel(export_dir, &saved_model_proto));

  TF_RETURN_IF_ERROR(
      FindMetaGraphDefToLoad(saved_model_proto, tags, &bundle->meta_graph_def));

  TF_RETURN_IF_ERROR(LoadMetaGraphIntoSession(
      bundle->meta_graph_def, session_options, &bundle->session));

  std::vector<AssetFileDef> asset_file_defs;
  TF_RETURN_IF_ERROR(
      GetAssetFileDefs(bundle->meta_graph_def, &asset_file_defs));
  TF_RETURN_IF_ERROR(
      RunRestore(run_options, export_dir,
                 bundle->meta_graph_def.saver_def().restore_op_name(),
                 bundle->meta_graph_def.saver_def().filename_tensor_name(),
                 asset_file_defs, bundle->session.get()));
  // TODO(sukritiramesh): Add support for a single main op to run upon load,
  // which will supersede the legacy_init_op and separate RunRestore.
  TF_RETURN_IF_ERROR(RunLegacyInitOp(run_options, export_dir,
                                     bundle->meta_graph_def, asset_file_defs,
                                     bundle->session.get()));
  return Status::OK();
}

}  // namespace

Status LoadSavedModel(const SessionOptions& session_options,
                      const RunOptions& run_options, const string& export_dir,
                      const std::unordered_set<string>& tags,
                      SavedModelBundle* const bundle) {
  // TODO(robson): Add tests for the counters.
  const uint64 start_microseconds = Env::Default()->NowMicros();
  const Status status = LoadSavedModelInternal(session_options, run_options,
                                               export_dir, tags, bundle);
  const uint64 load_latency_microsecs = [&]() -> uint64 {
    const uint64 end_microseconds = Env::Default()->NowMicros();
    // Avoid clock skew.
    if (end_microseconds < start_microseconds) return 0;
    return end_microseconds - start_microseconds;
  }();
  auto log_and_count = [&](const string& status_str) {
    LOG(INFO) << "Loading SavedModel: " << status_str << ". Took "
              << load_latency_microsecs << " microseconds.";
    load_attempt_count->GetCell(export_dir, status_str)->IncrementBy(1);
  };
  if (status.ok()) {
    log_and_count(kLoadAttemptSuccess);
  } else {
    log_and_count(kLoadAttemptFail);
  }
  load_latency->GetCell(export_dir)->IncrementBy(load_latency_microsecs);
  return status;
}

bool MaybeSavedModelDirectory(const string& export_dir) {
  const string saved_model_pb_path =
      io::JoinPath(export_dir, kSavedModelFilenamePb);
  const string saved_model_pbtxt_path =
      io::JoinPath(export_dir, kSavedModelFilenamePbTxt);
  return Env::Default()->FileExists(saved_model_pb_path).ok() ||
         Env::Default()->FileExists(saved_model_pbtxt_path).ok();
}

}  // namespace tensorflow
<|endoftext|>


<commit_before>#include <Internal/PhysicsModuleImplementation.hpp>

namespace DoremiEngine
{
    namespace Physics
    {
        PhysicsModuleImplementation::PhysicsModuleImplementation(const Core::SharedContext& p_sharedContext) : m_sharedContext(p_sharedContext) {}
        PhysicsModuleImplementation::~PhysicsModuleImplementation() {}

        void PhysicsModuleImplementation::Startup()
        {
            // Start physX
            m_utils.m_foundation = PxCreateFoundation(PX_PHYSICS_VERSION, m_utils.m_allocator, m_utils.m_errorCallback);
            PxProfileZoneManager* profileZoneManager = &PxProfileZoneManager::createProfileZoneManager(m_utils.m_foundation);
            m_utils.m_physics = PxCreatePhysics(PX_PHYSICS_VERSION, *m_utils.m_foundation, PxTolerancesScale(), true, profileZoneManager);

            // Create world scene TODOJB create scene handler for this kind of job
            CreateWorldScene();

            // Create sub modules
            m_utils.m_rigidBodyManager = new RigidBodyManagerImpl(m_utils);
            m_utils.m_physicsMaterialManager = new PhysicsMaterialManagerImpl(m_utils);
            m_utils.m_characterControlManager = new CharacterControlManagerImpl(m_utils);
            m_utils.m_fluidManager = new FluidManagerImpl(m_utils);
            m_utils.m_rayCastManager = new RayCastManagerImpl(m_utils);

            // Make some other important thingies
            m_utils.m_characterControlManager->SetCallbackClass(this);

            if(m_utils.m_physics->getPvdConnectionManager() == NULL)
            {
                int failed = 1;
            }
            PxVisualDebuggerConnection* theConnection =
                PxVisualDebuggerExt::createConnection(m_utils.m_physics->getPvdConnectionManager(), "127.0.0.1", 5425, 100,
                                                      PxVisualDebuggerExt::getAllConnectionFlags());
            if(theConnection) theConnection->release();
        }

        void PhysicsModuleImplementation::Shutdown() {}

        void PhysicsModuleImplementation::Update(float p_dt)
        {
            // Start by clearing the list of collision pairs (WARNING potentially bad idea)
            m_collisionPairs.clear();
            m_triggerPairs.clear();
            m_utils.m_fluidManager->Update(p_dt);
            m_utils.m_worldScene->simulate(p_dt);
            m_utils.m_worldScene->fetchResults(true);
        }

        RigidBodyManager& PhysicsModuleImplementation::GetRigidBodyManager() { return *m_utils.m_rigidBodyManager; }
        PhysicsMaterialManager& PhysicsModuleImplementation::GetPhysicsMaterialManager() { return *m_utils.m_physicsMaterialManager; }
        CharacterControlManager& PhysicsModuleImplementation::GetCharacterControlManager() { return *m_utils.m_characterControlManager; }
        FluidManager& PhysicsModuleImplementation::GetFluidManager() { return *m_utils.m_fluidManager; }
        RayCastManager& PhysicsModuleImplementation::GetRayCastManager() { return *m_utils.m_rayCastManager; };

        vector<CollisionPair> PhysicsModuleImplementation::GetCollisionPairs() { return m_collisionPairs; }
        vector<CollisionPair> PhysicsModuleImplementation::GetTriggerPairs() { return m_triggerPairs; }

        // Custom collision filter shader
        PxFilterFlags TestFilter(PxFilterObjectAttributes attributes0, PxFilterData filterData0, PxFilterObjectAttributes attributes1,
                                 PxFilterData filterData1, PxPairFlags& pairFlags, const void* constantBlock, PxU32 constantBlockSize)
        {
            // Rigid bodies collisions
            if(PxFilterObjectIsTrigger(attributes0) || PxFilterObjectIsTrigger(attributes1))
            {
                pairFlags = PxPairFlag::eTRIGGER_DEFAULT;
                pairFlags |= PxPairFlag::eNOTIFY_TOUCH_PERSISTS;
                pairFlags |= PxPairFlag::eNOTIFY_TOUCH_FOUND;
                pairFlags |= PxPairFlag::eNOTIFY_TOUCH_LOST;
                return PxFilterFlag::eDEFAULT;
            }

            // controller vs. controller collisions
            bool kinematic0 = PxFilterObjectIsKinematic(attributes0);
            bool kinematic1 = PxFilterObjectIsKinematic(attributes1);

            if(kinematic0 && kinematic1)
            {
                pairFlags = PxPairFlag::eTRIGGER_DEFAULT;
                return PxFilterFlag::eDEFAULT;
            }

            // generate contacts for all that were not filtered above
            pairFlags = PxPairFlag::eCONTACT_DEFAULT;

            // trigger the contact callback for pairs (A,B) where
            // the filtermask of A contains the ID of B and vice versa.
            if((filterData0.word0 & filterData1.word1) && (filterData1.word0 & filterData0.word1))
            {
                pairFlags |= PxPairFlag::eNOTIFY_TOUCH_FOUND;
            }

            return PxFilterFlag::eDEFAULT;
        }

        void PhysicsModuleImplementation::CreateWorldScene()
        {
            /// Create the scene
            // No idea what the "tolerances" is
            PxSceneDesc sceneDesc(m_utils.m_physics->getTolerancesScale());
            // Gravity sounds straight forward
            sceneDesc.gravity = PxVec3(0.0f, -9.8f, 0.0f);
            // Not too sure what this is. Probably related to how threads work
            m_utils.m_dispatcher = PxDefaultCpuDispatcherCreate(2);
            sceneDesc.cpuDispatcher = m_utils.m_dispatcher;
            // Some way of filtering collisions. Use default shaders since we cba to write our own
            sceneDesc.filterShader = TestFilter;
            // Notify PhysX that we want callbacks to be called here
            sceneDesc.simulationEventCallback = this;

            // Create the scene
            m_utils.m_worldScene = m_utils.m_physics->createScene(sceneDesc);

            // Assign stuff to the global material (again, probably stupid to have this here)
            PxMaterial* groundMaterial = m_utils.m_physics->createMaterial(0.5, 0.5, 0.5);

            // Create the ground on which everything stands on. Possibly shouldn't here (member varialbe? Separate class?)
            PxPlane groundPlane = PxPlane(0, 1, 0, 10); // change last digit for distance from origo

            PxRigidStatic* worldGround = PxCreatePlane(*m_utils.m_physics, groundPlane, *groundMaterial);
            // Add the ground plane to the scene. Apparently it's this easy
            m_utils.m_worldScene->addActor(*worldGround);
            // Not sure what this does... Desperate try maybe?
            m_utils.m_worldScene->setFlag(PxSceneFlag::eENABLE_KINEMATIC_PAIRS, true);

            // m_utils.m_worldScene->setFlag(PxSceneFlag::eENABLE_KINEMATIC_STATIC_PAIRS, true);

            /*
            And we now have a simple scene with gravity and the ground as a plane*/
        }

        void PhysicsModuleImplementation::onContact(const PxContactPairHeader& pairHeader, const PxContactPair* pairs, PxU32 nbPairs)
        {
            m_utils.m_rigidBodyManager->GetIDsByBodies();
            for(size_t i = 0; i < nbPairs; i++)
            {
                const PxContactPair& cp = pairs[i];
                CollisionPair collisionPair;
                // collisionPair.firstID = m_utils.m_rigidBodyManager->GetIDsByBodies()[pairHeader.actors[0]];
                // collisionPair.secondID = m_utils.m_rigidBodyManager->GetIDsByBodies()[pairHeader.actors[1]];
                collisionPair.firstID = m_utils.m_rigidBodyManager->GetIDsByBodies().find(pairHeader.actors[0])->second;
                collisionPair.secondID = m_utils.m_rigidBodyManager->GetIDsByBodies().find(pairHeader.actors[1])->second;
                m_collisionPairs.push_back(collisionPair);
            }
        }

        void PhysicsModuleImplementation::onTrigger(PxTriggerPair* pairs, PxU32 count)
        {
            for(size_t i = 0; i < count; i++)
            {
                const PxTriggerPair& cp = pairs[i];
                CollisionPair collisionPair;
                collisionPair.firstID = m_utils.m_rigidBodyManager->GetIDsByBodies().find(pairs->triggerActor)->second;
                collisionPair.secondID = m_utils.m_rigidBodyManager->GetIDsByBodies().find(pairs->otherActor)->second;
                m_triggerPairs.push_back(collisionPair);
            }
        }

        void PhysicsModuleImplementation::onShapeHit(const PxControllerShapeHit& hit)
        {
            // TODOJB implement
        }
        PxUserControllerHitReport* derp;

        void PhysicsModuleImplementation::onControllerHit(const PxControllersHit& hit)
        {
            CollisionPair collisionPair;
            unordered_map<PxController*, int> idsByControllers = m_utils.m_characterControlManager->GetIdsByControllers();
            PxController* firstActor = hit.controller;
            PxController* secondActor = hit.other;
            int first = idsByControllers[firstActor];
            int second = idsByControllers[secondActor];

            collisionPair.firstID = m_utils.m_characterControlManager->GetIdsByControllers().find(hit.controller)->second;
            collisionPair.secondID = m_utils.m_characterControlManager->GetIdsByControllers().find(hit.other)->second;
            m_collisionPairs.push_back(collisionPair);
        }
    }
}

DoremiEngine::Physics::PhysicsModule* CreatePhysicsModule(const DoremiEngine::Core::SharedContext& p_sharedContext)
{
    DoremiEngine::Physics::PhysicsModule* physics = new DoremiEngine::Physics::PhysicsModuleImplementation(p_sharedContext);
    return physics;
}<commit_msg>Fix in physics<commit_after>#include <Internal/PhysicsModuleImplementation.hpp>

namespace DoremiEngine
{
    namespace Physics
    {
        PhysicsModuleImplementation::PhysicsModuleImplementation(const Core::SharedContext& p_sharedContext) : m_sharedContext(p_sharedContext) {}
        PhysicsModuleImplementation::~PhysicsModuleImplementation() {}

        void PhysicsModuleImplementation::Startup()
        {
            // Start physX
            m_utils.m_foundation = PxCreateFoundation(PX_PHYSICS_VERSION, m_utils.m_allocator, m_utils.m_errorCallback);
            PxProfileZoneManager* profileZoneManager = &PxProfileZoneManager::createProfileZoneManager(m_utils.m_foundation);
            m_utils.m_physics = PxCreatePhysics(PX_PHYSICS_VERSION, *m_utils.m_foundation, PxTolerancesScale(), true, profileZoneManager);

            // Create world scene TODOJB create scene handler for this kind of job
            CreateWorldScene();

            // Create sub modules
            m_utils.m_rigidBodyManager = new RigidBodyManagerImpl(m_utils);
            m_utils.m_physicsMaterialManager = new PhysicsMaterialManagerImpl(m_utils);
            m_utils.m_characterControlManager = new CharacterControlManagerImpl(m_utils);
            m_utils.m_fluidManager = new FluidManagerImpl(m_utils);
            m_utils.m_rayCastManager = new RayCastManagerImpl(m_utils);

            // Make some other important thingies
            m_utils.m_characterControlManager->SetCallbackClass(this);

            if(m_utils.m_physics->getPvdConnectionManager() == NULL)
            {
                int failed = 1;
            }
            PxVisualDebuggerConnection* theConnection =
                PxVisualDebuggerExt::createConnection(m_utils.m_physics->getPvdConnectionManager(), "127.0.0.1", 5425, 100,
                                                      PxVisualDebuggerExt::getAllConnectionFlags());
            if(theConnection) theConnection->release();
        }

        void PhysicsModuleImplementation::Shutdown() {}

        void PhysicsModuleImplementation::Update(float p_dt)
        {
            // Start by clearing the list of collision pairs (WARNING potentially bad idea)
            m_collisionPairs.clear();
            m_triggerPairs.clear();
            m_utils.m_fluidManager->Update(p_dt);
            m_utils.m_worldScene->simulate(p_dt);
            m_utils.m_worldScene->fetchResults(true);
        }

        RigidBodyManager& PhysicsModuleImplementation::GetRigidBodyManager() { return *m_utils.m_rigidBodyManager; }
        PhysicsMaterialManager& PhysicsModuleImplementation::GetPhysicsMaterialManager() { return *m_utils.m_physicsMaterialManager; }
        CharacterControlManager& PhysicsModuleImplementation::GetCharacterControlManager() { return *m_utils.m_characterControlManager; }
        FluidManager& PhysicsModuleImplementation::GetFluidManager() { return *m_utils.m_fluidManager; }
        RayCastManager& PhysicsModuleImplementation::GetRayCastManager() { return *m_utils.m_rayCastManager; };

        vector<CollisionPair> PhysicsModuleImplementation::GetCollisionPairs() { return m_collisionPairs; }
        vector<CollisionPair> PhysicsModuleImplementation::GetTriggerPairs() { return m_triggerPairs; }

        // Custom collision filter shader
        PxFilterFlags TestFilter(PxFilterObjectAttributes attributes0, PxFilterData filterData0, PxFilterObjectAttributes attributes1,
                                 PxFilterData filterData1, PxPairFlags& pairFlags, const void* constantBlock, PxU32 constantBlockSize)
        {
            // Rigid bodies collisions
            if(PxFilterObjectIsTrigger(attributes0) || PxFilterObjectIsTrigger(attributes1))
            {
                pairFlags = PxPairFlag::eTRIGGER_DEFAULT;
                pairFlags |= PxPairFlag::eNOTIFY_TOUCH_PERSISTS;
                pairFlags |= PxPairFlag::eNOTIFY_TOUCH_FOUND;
                pairFlags |= PxPairFlag::eNOTIFY_TOUCH_LOST;
                return PxFilterFlag::eDEFAULT;
            }

            // controller vs. controller collisions
            bool kinematic0 = PxFilterObjectIsKinematic(attributes0);
            bool kinematic1 = PxFilterObjectIsKinematic(attributes1);

            if(kinematic0 && kinematic1)
            {
                pairFlags = PxPairFlag::eTRIGGER_DEFAULT;
                return PxFilterFlag::eDEFAULT;
            }

            // generate contacts for all that were not filtered above
            pairFlags = PxPairFlag::eCONTACT_DEFAULT;

            // trigger the contact callback for pairs (A,B) where
            // the filtermask of A contains the ID of B and vice versa.
            if((filterData0.word0 & filterData1.word1) && (filterData1.word0 & filterData0.word1))
            {
                pairFlags |= PxPairFlag::eNOTIFY_TOUCH_FOUND;
            }

            return PxFilterFlag::eDEFAULT;
        }

        void PhysicsModuleImplementation::CreateWorldScene()
        {
            /// Create the scene
            // No idea what the "tolerances" is
            PxSceneDesc sceneDesc(m_utils.m_physics->getTolerancesScale());
            // Gravity sounds straight forward
            sceneDesc.gravity = PxVec3(0.0f, -9.8f, 0.0f);
            // Not too sure what this is. Probably related to how threads work
            m_utils.m_dispatcher = PxDefaultCpuDispatcherCreate(2);
            sceneDesc.cpuDispatcher = m_utils.m_dispatcher;
            // Some way of filtering collisions. Use default shaders since we cba to write our own
            sceneDesc.filterShader = TestFilter;
            // Notify PhysX that we want callbacks to be called here
            sceneDesc.simulationEventCallback = this;

            // Create the scene
            m_utils.m_worldScene = m_utils.m_physics->createScene(sceneDesc);

            // Assign stuff to the global material (again, probably stupid to have this here)
            PxMaterial* groundMaterial = m_utils.m_physics->createMaterial(0.5, 0.5, 0.5);

            // Create the ground on which everything stands on. Possibly shouldn't here (member varialbe? Separate class?)
            PxPlane groundPlane = PxPlane(0, 1, 0, 10); // change last digit for distance from origo

            PxRigidStatic* worldGround = PxCreatePlane(*m_utils.m_physics, groundPlane, *groundMaterial);
            // Add the ground plane to the scene. Apparently it's this easy
            m_utils.m_worldScene->addActor(*worldGround);
            // Not sure what this does... Desperate try maybe?
            m_utils.m_worldScene->setFlag(PxSceneFlag::eENABLE_KINEMATIC_PAIRS, true);

            // m_utils.m_worldScene->setFlag(PxSceneFlag::eENABLE_KINEMATIC_STATIC_PAIRS, true);

            /*
            And we now have a simple scene with gravity and the ground as a plane*/
        }

        void PhysicsModuleImplementation::onContact(const PxContactPairHeader& pairHeader, const PxContactPair* pairs, PxU32 nbPairs)
        {
            m_utils.m_rigidBodyManager->GetIDsByBodies();
            for(size_t i = 0; i < nbPairs; i++)
            {
                const PxContactPair& cp = pairs[i];
                CollisionPair collisionPair;

                if(m_utils.m_rigidBodyManager->GetIDsByBodies().find(pairHeader.actors[0]) != m_utils.m_rigidBodyManager->GetIDsByBodies().end())
                {
                    collisionPair.firstID = m_utils.m_rigidBodyManager->GetIDsByBodies().find(pairHeader.actors[0])->second;
                }
                else
                {
                    // Probably hit a controller. TODOJB solve some time
                }

                if (m_utils.m_rigidBodyManager->GetIDsByBodies().find(pairHeader.actors[1]) != m_utils.m_rigidBodyManager->GetIDsByBodies().end())
                {
                    collisionPair.secondID = m_utils.m_rigidBodyManager->GetIDsByBodies().find(pairHeader.actors[1])->second;
                }
                else
                {
                    // Probably hit a controller. TODOJB solve some time
                }

                m_collisionPairs.push_back(collisionPair);
            }
        }

        void PhysicsModuleImplementation::onTrigger(PxTriggerPair* pairs, PxU32 count)
        {
            for(size_t i = 0; i < count; i++)
            {
                const PxTriggerPair& cp = pairs[i];
                CollisionPair collisionPair;
                collisionPair.firstID = m_utils.m_rigidBodyManager->GetIDsByBodies().find(pairs->triggerActor)->second;
                collisionPair.secondID = m_utils.m_rigidBodyManager->GetIDsByBodies().find(pairs->otherActor)->second;
                m_triggerPairs.push_back(collisionPair);
            }
        }

        void PhysicsModuleImplementation::onShapeHit(const PxControllerShapeHit& hit)
        {
            // TODOJB implement
        }
        PxUserControllerHitReport* derp;

        void PhysicsModuleImplementation::onControllerHit(const PxControllersHit& hit)
        {
            CollisionPair collisionPair;
            unordered_map<PxController*, int> idsByControllers = m_utils.m_characterControlManager->GetIdsByControllers();
            PxController* firstActor = hit.controller;
            PxController* secondActor = hit.other;
            int first = idsByControllers[firstActor];
            int second = idsByControllers[secondActor];

            collisionPair.firstID = m_utils.m_characterControlManager->GetIdsByControllers().find(hit.controller)->second;
            collisionPair.secondID = m_utils.m_characterControlManager->GetIdsByControllers().find(hit.other)->second;
            m_collisionPairs.push_back(collisionPair);
        }
    }
}

DoremiEngine::Physics::PhysicsModule* CreatePhysicsModule(const DoremiEngine::Core::SharedContext& p_sharedContext)
{
    DoremiEngine::Physics::PhysicsModule* physics = new DoremiEngine::Physics::PhysicsModuleImplementation(p_sharedContext);
    return physics;
}<|endoftext|>


<commit_before>/*
   Copyright (C) 2010  Marco Ballesio <gibrovacco@gmail.com>

   This library is free software; you can redistribute it and/or modify
   it under the terms of the GNU Lesser General Public License as published
   by the Free Software Foundation; either version 2.1 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU Lesser General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "player.h"
#include <iostream>
#include <QtCore/QTime>
#include <QtCore/QDir>
#include <QtGui/QApplication>
#include <QGlib/Signal>
#include <QGst/Global>
#include <QGst/Pipeline>
#include <QGst/ElementFactory>
#include <QGst/XOverlay>
#include <QGst/Bus>
#include <QGst/Message>
#include <QGst/Query>
#include <QGst/Clock>
#include <QGst/Event>

/* This is a simple example of a command-line player. It accepts the URI of
 * a media file as the first command line argument and then constructs a pipeline
 * that uses playbin2 to decode the stream. */

Player::Player(QWidget *parent)
    : QGst::Ui::VideoWidget(parent) {
        connect(&m_positionTimer, SIGNAL(timeout()), this, SLOT(updatePosition()));
        setMouseTracking(true);
    }

void Player::setUri(const QString & uri) {
    QString realUri = uri;

    if(uri.indexOf("://") < 0){
        if(realUri[0] != '/'){
            realUri = QDir::current().path() + "/" + realUri;
        }
        realUri = "file://" + realUri;
    }

    if(!m_pipeline){
        QGst::ElementPtr playbin = QGst::ElementFactory::make("playbin2");
        if(playbin) {
            m_pipeline = playbin.dynamicCast<QGst::Pipeline>();
            QGst::BusPtr bus = m_pipeline->bus();
            QGlib::Signal::connect(bus, "message", this, &Player::busMessage);
            bus->addSignalWatch();
        }
    }

    if(m_pipeline){
        m_pipeline->setProperty("uri", realUri);
    }
}

Player::~Player() {
    if(m_pipeline)
        m_pipeline->setState(QGst::StateNull);
}

void Player::updatePosition() {
    Q_EMIT positionChanged(position());
}

void Player::play() {
    if(m_pipeline){
        m_pipeline->setState(QGst::StatePlaying);
    }
}

void Player::pause( ){
    if(m_pipeline){
        m_pipeline->setState(QGst::StatePaused);
    }
}

void Player::stop() {
    if(m_pipeline){
        m_pipeline->setState(QGst::StateReady);
    }
}

void Player::setPosition(QTime pos) {
    QGst::SeekEventPtr evt = QGst::SeekEvent::create(
            1.0, QGst::FormatTime, QGst::SeekFlagFlush,
            QGst::SeekTypeSet, QGst::Clock::clockTimeFromTime(pos),
            QGst::SeekTypeNone, -1);

    m_pipeline.dynamicCast<QGst::Element>()->sendEvent(evt);
}

QTime Player::position() {
    if(m_pipeline){
        QGst::PositionQueryPtr query = QGst::PositionQuery::create(QGst::FormatTime);
        m_pipeline.dynamicCast<QGst::Element>()->query(query);
        return QGst::Clock::timeFromClockTime(query->position());
    }
    return QTime(0, 0, 0, 0);
}

QTime Player::length() {
    if(m_pipeline){
        QGst::DurationQueryPtr query = QGst::DurationQuery::create(QGst::FormatTime);
        m_pipeline->query(query);
        return QGst::Clock::timeFromClockTime(query->duration());
    }
    return QTime(0, 0, 0, 0);
}

QGst::State Player::state() {
    QGst::State state;
    if(!m_pipeline ||
        m_pipeline.dynamicCast<QGst::Element>()->getState(&state, NULL, 1e9) !=
        QGst::StateChangeSuccess)
    {
        state = QGst::StateNull;
    }
    return state;
}

void Player::handleStateChange(QGst::StateChangedMessagePtr scm) {
    switch(scm->newState()){
        case QGst::StatePlaying:
            Q_EMIT positionChanged(position());
            m_positionTimer.start(500);
            break;
        case QGst::StatePaused:
            if(scm->oldState() == QGst::StateReady){
                QGst::ElementPtr sink =
                    m_pipeline->property("video-sink").get<QGst::ElementPtr>();
                if(sink){
                    setVideoSink(sink);
                    QGst::ChildProxyPtr proxy = sink.dynamicCast<QGst::ChildProxy>();
                    proxy->childByIndex(0)->setProperty("force-aspect-ratio", true);
                }
            } else
                m_positionTimer.stop();
            break;
        case QGst::StateReady:
            if(scm->oldState() == QGst::StatePaused)
                /* Remove the sink now to avoid inter-thread issues with Qt
                   for the next time the pipeline goes to StatePlaying */
                setVideoSink(QGst::ElementPtr());
        break;
        default:
        break;
    }
}

void Player::busMessage(const QGst::MessagePtr & message) {
    switch(message->type()) {
        case QGst::MessageEos: //End of stream. We reached the end of the file.
            qDebug() << "got eos";
            m_pipeline->setState(QGst::StateReady);
            break;
        case QGst::MessageError: //Some error occurred.
            /*TODO: send a message to UI */
            break;
        case QGst::MessageAsyncDone:
            {
                //File prerolled, queries the pipeline to get the file duration
                QGst::DurationQueryPtr query = QGst::DurationQuery::create(QGst::FormatTime);
                //This will create a temporary (cast to query).
                m_pipeline->query(query);
            }
            break;
        case QGst::MessageStateChanged:
            if(QGlib::Type::fromInstance(message->source()).
                    isA(QGlib::GetType<QGst::Pipeline>()))
            {
                QGst::StateChangedMessagePtr scm =
                    message.dynamicCast<QGst::StateChangedMessage>();
                handleStateChange(scm);
                Q_EMIT stateChanged(scm->newState());
            }

            break;
        default:
            break;
    }
}

<commit_msg>Removed unneeded dynamic casts<commit_after>/*
   Copyright (C) 2010  Marco Ballesio <gibrovacco@gmail.com>

   This library is free software; you can redistribute it and/or modify
   it under the terms of the GNU Lesser General Public License as published
   by the Free Software Foundation; either version 2.1 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU Lesser General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "player.h"
#include <iostream>
#include <QtCore/QTime>
#include <QtCore/QDir>
#include <QtGui/QApplication>
#include <QGlib/Signal>
#include <QGst/Global>
#include <QGst/Pipeline>
#include <QGst/ElementFactory>
#include <QGst/XOverlay>
#include <QGst/Bus>
#include <QGst/Message>
#include <QGst/Query>
#include <QGst/Clock>
#include <QGst/Event>

/* This is a simple example of a command-line player. It accepts the URI of
 * a media file as the first command line argument and then constructs a pipeline
 * that uses playbin2 to decode the stream. */

Player::Player(QWidget *parent)
    : QGst::Ui::VideoWidget(parent) {
        connect(&m_positionTimer, SIGNAL(timeout()), this, SLOT(updatePosition()));
        setMouseTracking(true);
    }

void Player::setUri(const QString & uri) {
    QString realUri = uri;

    if(uri.indexOf("://") < 0){
        if(realUri[0] != '/'){
            realUri = QDir::current().path() + "/" + realUri;
        }
        realUri = "file://" + realUri;
    }

    if(!m_pipeline){
        QGst::ElementPtr playbin = QGst::ElementFactory::make("playbin2");
        if(playbin) {
            m_pipeline = playbin.dynamicCast<QGst::Pipeline>();
            QGst::BusPtr bus = m_pipeline->bus();
            QGlib::Signal::connect(bus, "message", this, &Player::busMessage);
            bus->addSignalWatch();
        }
    }

    if(m_pipeline){
        m_pipeline->setProperty("uri", realUri);
    }
}

Player::~Player() {
    if(m_pipeline)
        m_pipeline->setState(QGst::StateNull);
}

void Player::updatePosition() {
    Q_EMIT positionChanged(position());
}

void Player::play() {
    if(m_pipeline){
        m_pipeline->setState(QGst::StatePlaying);
    }
}

void Player::pause( ){
    if(m_pipeline){
        m_pipeline->setState(QGst::StatePaused);
    }
}

void Player::stop() {
    if(m_pipeline){
        m_pipeline->setState(QGst::StateReady);
    }
}

void Player::setPosition(QTime pos) {
    QGst::SeekEventPtr evt = QGst::SeekEvent::create(
            1.0, QGst::FormatTime, QGst::SeekFlagFlush,
            QGst::SeekTypeSet, QGst::Clock::clockTimeFromTime(pos),
            QGst::SeekTypeNone, -1);

    m_pipeline->sendEvent(evt);
}

QTime Player::position() {
    if(m_pipeline){
        QGst::PositionQueryPtr query = QGst::PositionQuery::create(QGst::FormatTime);
        m_pipeline->query(query);
        return QGst::Clock::timeFromClockTime(query->position());
    }
    return QTime(0, 0, 0, 0);
}

QTime Player::length() {
    if(m_pipeline){
        QGst::DurationQueryPtr query = QGst::DurationQuery::create(QGst::FormatTime);
        m_pipeline->query(query);
        return QGst::Clock::timeFromClockTime(query->duration());
    }
    return QTime(0, 0, 0, 0);
}

QGst::State Player::state() {
    QGst::State state;
    if(!m_pipeline ||
        m_pipeline->getState(&state, NULL, 1e9) != QGst::StateChangeSuccess)
    {
        state = QGst::StateNull;
    }
    return state;
}

void Player::handleStateChange(QGst::StateChangedMessagePtr scm) {
    switch(scm->newState()){
        case QGst::StatePlaying:
            Q_EMIT positionChanged(position());
            m_positionTimer.start(500);
            break;
        case QGst::StatePaused:
            if(scm->oldState() == QGst::StateReady){
                QGst::ElementPtr sink =
                    m_pipeline->property("video-sink").get<QGst::ElementPtr>();
                if(sink){
                    setVideoSink(sink);
                    QGst::ChildProxyPtr proxy = sink.dynamicCast<QGst::ChildProxy>();
                    if (proxy)
                        proxy->childByIndex(0)->setProperty("force-aspect-ratio", true);
                }
            } else
                m_positionTimer.stop();
            break;
        case QGst::StateReady:
            if(scm->oldState() == QGst::StatePaused)
                /* Remove the sink now to avoid inter-thread issues with Qt
                   for the next time the pipeline goes to StatePlaying */
                setVideoSink(QGst::ElementPtr());
        break;
        default:
        break;
    }
}

void Player::busMessage(const QGst::MessagePtr & message) {
    switch(message->type()) {
        case QGst::MessageEos: //End of stream. We reached the end of the file.
            qDebug() << "got eos";
            m_pipeline->setState(QGst::StateReady);
            break;
        case QGst::MessageError: //Some error occurred.
            /*TODO: send a message to UI */
            break;
        case QGst::MessageAsyncDone:
            {
                //File prerolled, queries the pipeline to get the file duration
                QGst::DurationQueryPtr query = QGst::DurationQuery::create(QGst::FormatTime);
                //This will create a temporary (cast to query).
                m_pipeline->query(query);
            }
            break;
        case QGst::MessageStateChanged:
            if(QGlib::Type::fromInstance(message->source()).
                    isA(QGlib::GetType<QGst::Pipeline>()))
            {
                QGst::StateChangedMessagePtr scm =
                    message.dynamicCast<QGst::StateChangedMessage>();
                handleStateChange(scm);
                Q_EMIT stateChanged(scm->newState());
            }

            break;
        default:
            break;
    }
}

<|endoftext|>


<commit_before><commit_msg>add sirikata setup<commit_after><|endoftext|>