<commit_before>////////////////////////////////////////////////////////////////////////////////
/// DISCLAIMER
///
/// Copyright 2014-2016 ArangoDB GmbH, Cologne, Germany
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
///
/// 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.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Michael Hackstein
////////////////////////////////////////////////////////////////////////////////

#include "Basics/VelocyPackHelper.h"
#include "Basics/conversions.h"
#include "Basics/Exceptions.h"
#include "Basics/logging.h"
#include "Basics/files.h"
#include "Basics/tri-strings.h"
#include "Basics/Utf8Helper.h"
#include "Basics/VPackStringBufferAdapter.h"

#include <velocypack/Collection.h>
#include <velocypack/Dumper.h>
#include <velocypack/velocypack-aliases.h>

using VelocyPackHelper = arangodb::basics::VelocyPackHelper;

struct AttributeSorter {
  bool operator() (std::string const& l, std::string const& r) const {
    return TRI_compare_utf8(l.c_str(), l.size(), r.c_str(), r.size()) < 0;
  }
};

static int TypeWeight(VPackSlice const& slice) {
  switch (slice.type()) {
    case VPackValueType::Bool:
      return 1;
    case VPackValueType::Double:
    case VPackValueType::Int:
    case VPackValueType::UInt:
    case VPackValueType::SmallInt:
      return 2;
    case VPackValueType::String:
      return 3;
    case VPackValueType::Array:
      return 4;
    case VPackValueType::Object:
      return 5;
    default:
      // All other values have equal weight
      return 0;
  }
}

////////////////////////////////////////////////////////////////////////////////
/// @brief returns a boolean sub-element, or a default if it is does not exist
////////////////////////////////////////////////////////////////////////////////

bool VelocyPackHelper::getBooleanValue(VPackSlice const& slice,
                                       char const* name, bool defaultValue) {
  VPackSlice const& sub = slice.get(name);

  if (sub.isBoolean()) {
    return sub.getBool();
  }

  return defaultValue;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief returns a string sub-element, or throws if <name> does not exist
/// or it is not a string
////////////////////////////////////////////////////////////////////////////////

std::string VelocyPackHelper::checkAndGetStringValue(VPackSlice const& slice,
                                                     char const* name) {
  TRI_ASSERT(slice.isObject());
  VPackSlice const sub = slice.get(name);
  if (!sub.isString()) {
    std::string msg = "The attribute '" + std::string(name) +
                      "' was not found or is not a string.";
    THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_BAD_PARAMETER, msg);
  }
  return sub.copyString();
}

////////////////////////////////////////////////////////////////////////////////
/// @brief returns a string sub-element, or the default value if it does not
/// exist
/// or it is not a string
////////////////////////////////////////////////////////////////////////////////

std::string VelocyPackHelper::getStringValue(VPackSlice const& slice,
                                             char const* name,
                                             std::string const& defaultValue) {
  TRI_ASSERT(slice.isObject());
  VPackSlice const sub = slice.get(name);
  if (!sub.isString()) {
    return defaultValue;
  }
  return sub.copyString();
}

uint64_t VelocyPackHelper::stringUInt64(VPackSlice const& slice) {
  if (slice.isString()) {
    std::string tmp = slice.copyString();
    return TRI_UInt64String(tmp.c_str());
  }
  if (slice.isNumber()) {
    return slice.getNumericValue<uint64_t>();
  }
  return 0;
}

TRI_json_t* VelocyPackHelper::velocyPackToJson(VPackSlice const& slice) {
  return JsonHelper::fromString(slice.toJson());
}

////////////////////////////////////////////////////////////////////////////////
/// @brief parses a json file to VelocyPack
//////////////////////////////////////////////////////////////////////////////////

std::shared_ptr<VPackBuilder> VelocyPackHelper::velocyPackFromFile(
    std::string const& path) {
  size_t length;
  char* content = TRI_SlurpFile(TRI_UNKNOWN_MEM_ZONE, path.c_str(), &length);
  if (content != nullptr) {
    // The Parser might THROW
    std::shared_ptr<VPackBuilder> b;
    try {
      auto b = VPackParser::fromJson(reinterpret_cast<uint8_t const*>(content),
                                     length);
      TRI_Free(TRI_UNKNOWN_MEM_ZONE, content);
      return b;
    } catch (...) {
      TRI_Free(TRI_UNKNOWN_MEM_ZONE, content);
      throw;
    }
  }
  THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
}

static bool PrintVelocyPack(int fd, VPackSlice const& slice,
                            bool appendNewline) {
  if (slice.isNone()) {
    // sanity check
    return false;
  }

  TRI_string_buffer_t buffer;
  TRI_InitStringBuffer(&buffer, TRI_UNKNOWN_MEM_ZONE);
  arangodb::basics::VPackStringBufferAdapter bufferAdapter(&buffer);
  try {
    VPackDumper dumper(&bufferAdapter);
    dumper.dump(slice);
  } catch (...) {
    // Writing failed
    TRI_AnnihilateStringBuffer(&buffer);
    return false;
  }

  if (TRI_LengthStringBuffer(&buffer) == 0) {
    // should not happen
    return false;
  }

  if (appendNewline) {
    // add the newline here so we only need one write operation in the ideal
    // case
    TRI_AppendCharStringBuffer(&buffer, '\n');
  }

  char const* p = TRI_BeginStringBuffer(&buffer);
  size_t n = TRI_LengthStringBuffer(&buffer);

  while (0 < n) {
    ssize_t m = TRI_WRITE(fd, p, (TRI_write_t)n);

    if (m <= 0) {
      TRI_AnnihilateStringBuffer(&buffer);
      return false;
    }

    n -= m;
    p += m;
  }

  TRI_AnnihilateStringBuffer(&buffer);
  return true;
}

//////////////////////////////////////////////////////////////////////////////
/// @brief writes a VelocyPack to a file
//////////////////////////////////////////////////////////////////////////////

bool VelocyPackHelper::velocyPackToFile(char const* filename,
                                        VPackSlice const& slice,
                                        bool syncFile) {
  char* tmp = TRI_Concatenate2String(filename, ".tmp");

  if (tmp == nullptr) {
    return false;
  }

  // remove a potentially existing temporary file
  if (TRI_ExistsFile(tmp)) {
    TRI_UnlinkFile(tmp);
  }

  int fd = TRI_CREATE(tmp, O_CREAT | O_TRUNC | O_EXCL | O_RDWR | TRI_O_CLOEXEC,
                      S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);

  if (fd < 0) {
    TRI_set_errno(TRI_ERROR_SYS_ERROR);
    LOG_ERROR("cannot create json file '%s': %s", tmp, TRI_LAST_ERROR_STR);
    TRI_FreeString(TRI_CORE_MEM_ZONE, tmp);
    return false;
  }

  if (!PrintVelocyPack(fd, slice, true)) {
    TRI_CLOSE(fd);
    TRI_set_errno(TRI_ERROR_SYS_ERROR);
    LOG_ERROR("cannot write to json file '%s': %s", tmp, TRI_LAST_ERROR_STR);
    TRI_UnlinkFile(tmp);
    TRI_FreeString(TRI_CORE_MEM_ZONE, tmp);
    return false;
  }

  if (syncFile) {
    LOG_TRACE("syncing tmp file '%s'", tmp);

    if (!TRI_fsync(fd)) {
      TRI_CLOSE(fd);
      TRI_set_errno(TRI_ERROR_SYS_ERROR);
      LOG_ERROR("cannot sync saved json '%s': %s", tmp, TRI_LAST_ERROR_STR);
      TRI_UnlinkFile(tmp);
      TRI_FreeString(TRI_CORE_MEM_ZONE, tmp);
      return false;
    }
  }

  int res = TRI_CLOSE(fd);

  if (res < 0) {
    TRI_set_errno(TRI_ERROR_SYS_ERROR);
    LOG_ERROR("cannot close saved file '%s': %s", tmp, TRI_LAST_ERROR_STR);
    TRI_UnlinkFile(tmp);
    TRI_FreeString(TRI_CORE_MEM_ZONE, tmp);
    return false;
  }

  res = TRI_RenameFile(tmp, filename);

  if (res != TRI_ERROR_NO_ERROR) {
    TRI_set_errno(res);
    LOG_ERROR("cannot rename saved file '%s' to '%s': %s", tmp, filename,
              TRI_LAST_ERROR_STR);
    TRI_UnlinkFile(tmp);
    TRI_FreeString(TRI_CORE_MEM_ZONE, tmp);

    return false;
  }

  TRI_FreeString(TRI_CORE_MEM_ZONE, tmp);

  return true;
}

int VelocyPackHelper::compare(VPackSlice const& lhs, VPackSlice const& rhs,
                              bool useUTF8) {
  {
    int lWeight = TypeWeight(lhs);
    int rWeight = TypeWeight(rhs);

    if (lWeight < rWeight) {
      return -1;
    }

    if (lWeight > rWeight) {
      return 1;
    }

    TRI_ASSERT_EXPENSIVE(lWeight == rWeight);
  }

  // lhs and rhs have equal weights
  if (lhs.isNone() || rhs.isNone()) {
    // either lhs or rhs is none. we cannot be sure here that both are
    // nones.
    // there can also exist the situation that lhs is a none and rhs is a
    // null value
    // (or vice versa). Anyway, the compare value is the same for both,
    return 0;
  }

  switch (lhs.type()) {
    case VPackValueType::None:
    case VPackValueType::Null:
      return 0;  // null == null;
    case VPackValueType::Bool: {
      bool left = lhs.getBoolean();
      bool right = rhs.getBoolean();
      if (left == right) {
        return 0;
      }
      if (!left && right) {
        return -1;
      }
      return 1;
    }
    case VPackValueType::Double:
    case VPackValueType::Int:
    case VPackValueType::UInt:
    case VPackValueType::SmallInt: {
      double left = lhs.getNumericValue<double>();
      double right = rhs.getNumericValue<double>();
      if (left == right) {
        return 0;
      }
      if (left < right) {
        return -1;
      }
      return 1;
    }
    case VPackValueType::String: {
      int res;
      VPackValueLength nl;
      VPackValueLength nr;
      char const* left = lhs.getString(nl);
      char const* right = rhs.getString(nr);
      if (useUTF8) {
        res = TRI_compare_utf8(left, nl, right, nr);
      } else {
        size_t len = static_cast<size_t>(nl < nr ? nl : nr);
        res = memcmp(left, right, len);
      }
      if (res < 0) {
        return -1;
      } else if (res > 0) {
        return 1;
      }
      // res == 0
      if (nl == nr) {
        return 0;
      }
      // res == 0, but different string lengths
      return nl < nr ? -1 : 1;
    }
    case VPackValueType::Array: {
      VPackValueLength const nl = lhs.length();
      VPackValueLength const nr = rhs.length();
      VPackValueLength const n = std::max(nr, nl);
      for (VPackValueLength i = 0; i < n; ++i) {
        VPackSlice lhsValue;
        if (i < nl) {
          lhsValue = lhs.at(i);
        }
        VPackSlice rhsValue;
        if (i < nr) {
          rhsValue = rhs.at(i);
        }

        int result = compare(lhsValue, rhsValue, useUTF8);
        if (result != 0) {
          return result;
        }
      }
      return 0;
    }
    case VPackValueType::Object: {
      std::set<std::string, AttributeSorter> keys;
      VPackCollection::keys(lhs, keys);
      VPackCollection::keys(rhs, keys);
      for (auto const& key : keys) {
        VPackSlice lhsValue = lhs.get(key);
        VPackSlice rhsValue = rhs.get(key);

        int result = compare(lhsValue, rhsValue, useUTF8);
        if (result != 0) {
          return result;
        }
      }

      return 0;
    }
    default:
      // Contains all other ValueTypes of VelocyPack.
      // They are not used in ArangoDB so this cannot occur
      TRI_ASSERT(false);
      return 0;
  }
}
<commit_msg>Fixed the most stupid thing ever found on windows yet. std::max forbidden trololololol<commit_after>////////////////////////////////////////////////////////////////////////////////
/// DISCLAIMER
///
/// Copyright 2014-2016 ArangoDB GmbH, Cologne, Germany
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
///
/// 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.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Michael Hackstein
////////////////////////////////////////////////////////////////////////////////

#include "Basics/VelocyPackHelper.h"
#include "Basics/conversions.h"
#include "Basics/Exceptions.h"
#include "Basics/logging.h"
#include "Basics/files.h"
#include "Basics/tri-strings.h"
#include "Basics/Utf8Helper.h"
#include "Basics/VPackStringBufferAdapter.h"

#include <velocypack/Collection.h>
#include <velocypack/Dumper.h>
#include <velocypack/velocypack-aliases.h>

using VelocyPackHelper = arangodb::basics::VelocyPackHelper;

struct AttributeSorter {
  bool operator() (std::string const& l, std::string const& r) const {
    return TRI_compare_utf8(l.c_str(), l.size(), r.c_str(), r.size()) < 0;
  }
};

static int TypeWeight(VPackSlice const& slice) {
  switch (slice.type()) {
    case VPackValueType::Bool:
      return 1;
    case VPackValueType::Double:
    case VPackValueType::Int:
    case VPackValueType::UInt:
    case VPackValueType::SmallInt:
      return 2;
    case VPackValueType::String:
      return 3;
    case VPackValueType::Array:
      return 4;
    case VPackValueType::Object:
      return 5;
    default:
      // All other values have equal weight
      return 0;
  }
}

////////////////////////////////////////////////////////////////////////////////
/// @brief returns a boolean sub-element, or a default if it is does not exist
////////////////////////////////////////////////////////////////////////////////

bool VelocyPackHelper::getBooleanValue(VPackSlice const& slice,
                                       char const* name, bool defaultValue) {
  VPackSlice const& sub = slice.get(name);

  if (sub.isBoolean()) {
    return sub.getBool();
  }

  return defaultValue;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief returns a string sub-element, or throws if <name> does not exist
/// or it is not a string
////////////////////////////////////////////////////////////////////////////////

std::string VelocyPackHelper::checkAndGetStringValue(VPackSlice const& slice,
                                                     char const* name) {
  TRI_ASSERT(slice.isObject());
  VPackSlice const sub = slice.get(name);
  if (!sub.isString()) {
    std::string msg = "The attribute '" + std::string(name) +
                      "' was not found or is not a string.";
    THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_BAD_PARAMETER, msg);
  }
  return sub.copyString();
}

////////////////////////////////////////////////////////////////////////////////
/// @brief returns a string sub-element, or the default value if it does not
/// exist
/// or it is not a string
////////////////////////////////////////////////////////////////////////////////

std::string VelocyPackHelper::getStringValue(VPackSlice const& slice,
                                             char const* name,
                                             std::string const& defaultValue) {
  TRI_ASSERT(slice.isObject());
  VPackSlice const sub = slice.get(name);
  if (!sub.isString()) {
    return defaultValue;
  }
  return sub.copyString();
}

uint64_t VelocyPackHelper::stringUInt64(VPackSlice const& slice) {
  if (slice.isString()) {
    std::string tmp = slice.copyString();
    return TRI_UInt64String(tmp.c_str());
  }
  if (slice.isNumber()) {
    return slice.getNumericValue<uint64_t>();
  }
  return 0;
}

TRI_json_t* VelocyPackHelper::velocyPackToJson(VPackSlice const& slice) {
  return JsonHelper::fromString(slice.toJson());
}

////////////////////////////////////////////////////////////////////////////////
/// @brief parses a json file to VelocyPack
//////////////////////////////////////////////////////////////////////////////////

std::shared_ptr<VPackBuilder> VelocyPackHelper::velocyPackFromFile(
    std::string const& path) {
  size_t length;
  char* content = TRI_SlurpFile(TRI_UNKNOWN_MEM_ZONE, path.c_str(), &length);
  if (content != nullptr) {
    // The Parser might THROW
    std::shared_ptr<VPackBuilder> b;
    try {
      auto b = VPackParser::fromJson(reinterpret_cast<uint8_t const*>(content),
                                     length);
      TRI_Free(TRI_UNKNOWN_MEM_ZONE, content);
      return b;
    } catch (...) {
      TRI_Free(TRI_UNKNOWN_MEM_ZONE, content);
      throw;
    }
  }
  THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
}

static bool PrintVelocyPack(int fd, VPackSlice const& slice,
                            bool appendNewline) {
  if (slice.isNone()) {
    // sanity check
    return false;
  }

  TRI_string_buffer_t buffer;
  TRI_InitStringBuffer(&buffer, TRI_UNKNOWN_MEM_ZONE);
  arangodb::basics::VPackStringBufferAdapter bufferAdapter(&buffer);
  try {
    VPackDumper dumper(&bufferAdapter);
    dumper.dump(slice);
  } catch (...) {
    // Writing failed
    TRI_AnnihilateStringBuffer(&buffer);
    return false;
  }

  if (TRI_LengthStringBuffer(&buffer) == 0) {
    // should not happen
    return false;
  }

  if (appendNewline) {
    // add the newline here so we only need one write operation in the ideal
    // case
    TRI_AppendCharStringBuffer(&buffer, '\n');
  }

  char const* p = TRI_BeginStringBuffer(&buffer);
  size_t n = TRI_LengthStringBuffer(&buffer);

  while (0 < n) {
    ssize_t m = TRI_WRITE(fd, p, (TRI_write_t)n);

    if (m <= 0) {
      TRI_AnnihilateStringBuffer(&buffer);
      return false;
    }

    n -= m;
    p += m;
  }

  TRI_AnnihilateStringBuffer(&buffer);
  return true;
}

//////////////////////////////////////////////////////////////////////////////
/// @brief writes a VelocyPack to a file
//////////////////////////////////////////////////////////////////////////////

bool VelocyPackHelper::velocyPackToFile(char const* filename,
                                        VPackSlice const& slice,
                                        bool syncFile) {
  char* tmp = TRI_Concatenate2String(filename, ".tmp");

  if (tmp == nullptr) {
    return false;
  }

  // remove a potentially existing temporary file
  if (TRI_ExistsFile(tmp)) {
    TRI_UnlinkFile(tmp);
  }

  int fd = TRI_CREATE(tmp, O_CREAT | O_TRUNC | O_EXCL | O_RDWR | TRI_O_CLOEXEC,
                      S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);

  if (fd < 0) {
    TRI_set_errno(TRI_ERROR_SYS_ERROR);
    LOG_ERROR("cannot create json file '%s': %s", tmp, TRI_LAST_ERROR_STR);
    TRI_FreeString(TRI_CORE_MEM_ZONE, tmp);
    return false;
  }

  if (!PrintVelocyPack(fd, slice, true)) {
    TRI_CLOSE(fd);
    TRI_set_errno(TRI_ERROR_SYS_ERROR);
    LOG_ERROR("cannot write to json file '%s': %s", tmp, TRI_LAST_ERROR_STR);
    TRI_UnlinkFile(tmp);
    TRI_FreeString(TRI_CORE_MEM_ZONE, tmp);
    return false;
  }

  if (syncFile) {
    LOG_TRACE("syncing tmp file '%s'", tmp);

    if (!TRI_fsync(fd)) {
      TRI_CLOSE(fd);
      TRI_set_errno(TRI_ERROR_SYS_ERROR);
      LOG_ERROR("cannot sync saved json '%s': %s", tmp, TRI_LAST_ERROR_STR);
      TRI_UnlinkFile(tmp);
      TRI_FreeString(TRI_CORE_MEM_ZONE, tmp);
      return false;
    }
  }

  int res = TRI_CLOSE(fd);

  if (res < 0) {
    TRI_set_errno(TRI_ERROR_SYS_ERROR);
    LOG_ERROR("cannot close saved file '%s': %s", tmp, TRI_LAST_ERROR_STR);
    TRI_UnlinkFile(tmp);
    TRI_FreeString(TRI_CORE_MEM_ZONE, tmp);
    return false;
  }

  res = TRI_RenameFile(tmp, filename);

  if (res != TRI_ERROR_NO_ERROR) {
    TRI_set_errno(res);
    LOG_ERROR("cannot rename saved file '%s' to '%s': %s", tmp, filename,
              TRI_LAST_ERROR_STR);
    TRI_UnlinkFile(tmp);
    TRI_FreeString(TRI_CORE_MEM_ZONE, tmp);

    return false;
  }

  TRI_FreeString(TRI_CORE_MEM_ZONE, tmp);

  return true;
}

int VelocyPackHelper::compare(VPackSlice const& lhs, VPackSlice const& rhs,
                              bool useUTF8) {
  {
    int lWeight = TypeWeight(lhs);
    int rWeight = TypeWeight(rhs);

    if (lWeight < rWeight) {
      return -1;
    }

    if (lWeight > rWeight) {
      return 1;
    }

    TRI_ASSERT_EXPENSIVE(lWeight == rWeight);
  }

  // lhs and rhs have equal weights
  if (lhs.isNone() || rhs.isNone()) {
    // either lhs or rhs is none. we cannot be sure here that both are
    // nones.
    // there can also exist the situation that lhs is a none and rhs is a
    // null value
    // (or vice versa). Anyway, the compare value is the same for both,
    return 0;
  }

  switch (lhs.type()) {
    case VPackValueType::None:
    case VPackValueType::Null:
      return 0;  // null == null;
    case VPackValueType::Bool: {
      bool left = lhs.getBoolean();
      bool right = rhs.getBoolean();
      if (left == right) {
        return 0;
      }
      if (!left && right) {
        return -1;
      }
      return 1;
    }
    case VPackValueType::Double:
    case VPackValueType::Int:
    case VPackValueType::UInt:
    case VPackValueType::SmallInt: {
      double left = lhs.getNumericValue<double>();
      double right = rhs.getNumericValue<double>();
      if (left == right) {
        return 0;
      }
      if (left < right) {
        return -1;
      }
      return 1;
    }
    case VPackValueType::String: {
      int res;
      VPackValueLength nl;
      VPackValueLength nr;
      char const* left = lhs.getString(nl);
      char const* right = rhs.getString(nr);
      if (useUTF8) {
        res = TRI_compare_utf8(left, nl, right, nr);
      } else {
        size_t len = static_cast<size_t>(nl < nr ? nl : nr);
        res = memcmp(left, right, len);
      }
      if (res < 0) {
        return -1;
      } else if (res > 0) {
        return 1;
      }
      // res == 0
      if (nl == nr) {
        return 0;
      }
      // res == 0, but different string lengths
      return nl < nr ? -1 : 1;
    }
    case VPackValueType::Array: {
      VPackValueLength const nl = lhs.length();
      VPackValueLength const nr = rhs.length();
      VPackValueLength const n = (std::max)(nr, nl);
      for (VPackValueLength i = 0; i < n; ++i) {
        VPackSlice lhsValue;
        if (i < nl) {
          lhsValue = lhs.at(i);
        }
        VPackSlice rhsValue;
        if (i < nr) {
          rhsValue = rhs.at(i);
        }

        int result = compare(lhsValue, rhsValue, useUTF8);
        if (result != 0) {
          return result;
        }
      }
      return 0;
    }
    case VPackValueType::Object: {
      std::set<std::string, AttributeSorter> keys;
      VPackCollection::keys(lhs, keys);
      VPackCollection::keys(rhs, keys);
      for (auto const& key : keys) {
        VPackSlice lhsValue = lhs.get(key);
        VPackSlice rhsValue = rhs.get(key);

        int result = compare(lhsValue, rhsValue, useUTF8);
        if (result != 0) {
          return result;
        }
      }

      return 0;
    }
    default:
      // Contains all other ValueTypes of VelocyPack.
      // They are not used in ArangoDB so this cannot occur
      TRI_ASSERT(false);
      return 0;
  }
}
<|endoftext|>


<commit_before>//
//  Created by 乔磊 on 15/4/24.
//  Copyright (c) 2015年 乔磊. All rights reserved.
//

#include <NSolver/Postprocessor.h>

namespace NSFEMSolver
{
  using namespace dealii;

  template <int dim>
  Postprocessor<dim>::
  Postprocessor (Parameters::AllParameters<dim>const *const para_ptr_in,
                 MMS<dim> const *const mms_ptr_in)
    :
    parameters (para_ptr_in),
    mms_x (mms_ptr_in),
    do_schlieren_plot (para_ptr_in->schlieren_plot),
    output_mms (para_ptr_in->n_mms == 1)
  {}

  // This is the only function worth commenting on. When generating graphical
  // output, the DataOut and related classes will call this function on each
  // cell, with values, gradients, Hessians, and normal vectors (in case we're
  // working on faces) at each quadrature point. Note that the data at each
  // quadrature point is itself vector-valued, namely the conserved
  // variables. What we're going to do here is to compute the quantities we're
  // interested in at each quadrature point. Note that for this we can ignore
  // the Hessians ("dduh") and normal vectors; to avoid compiler warnings
  // about unused variables, we comment out their names.
  template <int dim>
  void
  Postprocessor<dim>::
  compute_derived_quantities_vector (const std::vector<Vector<double> >              &uh,
                                     const std::vector<std::vector<Tensor<1,dim> > > &duh,
                                     const std::vector<std::vector<Tensor<2,dim> > > &/*dduh*/,
                                     const std::vector<Point<dim> >                  &/*normals*/,
                                     const std::vector<Point<dim> >                  &points,
                                     std::vector<Vector<double> >                    &computed_quantities) const
  {
    // At the beginning of the function, let us make sure that all variables
    // have the correct sizes, so that we can access individual vector
    // elements without having to wonder whether we might read or write
    // invalid elements; we also check that the duh vector only
    // contains data if we really need it (the system knows about this because
    // we say so in the get_needed_update_flags() function
    // below). For the inner vectors, we check that at least the first element
    // of the outer vector has the correct inner size:
    const unsigned int n_quadrature_points = static_cast<const unsigned int> (uh.size());

    if (do_schlieren_plot)
      {
        Assert (duh.size() == n_quadrature_points,ExcInternalError());
      }
    else
      {
        Assert (duh.size() == 0,ExcInternalError());
      }

    Assert (computed_quantities.size() == n_quadrature_points,ExcInternalError());
    Assert (uh[0].size() == EquationComponents<dim>::n_components,ExcInternalError());

    //MMS: Extra memory space
    Vector<double>::size_type expected_size = dim+2;
    if (do_schlieren_plot)
      {
        expected_size += 1;
      }
    if (output_mms)
      {
        expected_size += 3*EquationComponents<dim>::n_components;
      }
    Assert (computed_quantities[0].size() == expected_size, ExcInternalError());

    // Then loop over all quadrature points and do our work there. The code
    // should be pretty self-explanatory. The order of output variables is
    // first dim momentums, then the energy_density, and if so desired
    // the schlieren plot. Note that we try to be generic about the order of
    // variables in the input vector, using the
    // first_momentum_component and
    // density_component information:
    for (unsigned int q=0; q<n_quadrature_points; ++q)
      {
        int i_out = 0;
        const double density = uh[q][EquationComponents<dim>::density_component];

        for (unsigned int d=0; d<dim; ++d, ++i_out)
          computed_quantities[q][i_out]
            = uh[q][EquationComponents<dim>::first_momentum_component+d] * density;

        computed_quantities[q][i_out] = EulerEquations<dim>::compute_energy_density (uh[q]);
        ++i_out;
        computed_quantities[q][i_out] = EulerEquations<dim>::compute_velocity_magnitude (uh[q]) /
                                        EulerEquations<dim>::compute_sound_speed (uh[q]);
        ++i_out;

        if (do_schlieren_plot)
          {
            computed_quantities[q][i_out] = duh[q][EquationComponents<dim>::density_component] *
                                            duh[q][EquationComponents<dim>::density_component];
            ++i_out;
          }

        if (output_mms)
          {
            typename MMS<dim>::F_V sol;
            typename MMS<dim>::F_V src;
            typename MMS<dim>::F_T grad;
            mms_x->evaluate (points[q],sol,grad,src,true);

            for (unsigned int ic = 0; ic < EquationComponents<dim>::n_components; ++ic, ++i_out)
              {
                computed_quantities[q][i_out] = src[ic];
              }
            for (unsigned int ic = 0; ic < EquationComponents<dim>::n_components; ++ic, ++i_out)
              {
                computed_quantities[q][i_out] = sol[ic];
              }
            for (unsigned int ic = 0; ic < EquationComponents<dim>::n_components; ++ic, ++i_out)
              {
                computed_quantities[q][i_out] = sol[ic] - uh[q][ic];
              }
          } // End if (output_mms)
      }
  }

  template <int dim>
  std::vector<std::string>
  Postprocessor<dim>::
  get_names() const
  {
    std::vector<std::string> names;
    for (unsigned int d=0; d<dim; ++d)
      {
        names.push_back ("momentum");
      }
    names.push_back ("energy_density");
    names.push_back ("Mach");

    if (do_schlieren_plot)
      {
        names.push_back ("schlieren_plot");
      }

    //MMS: Exact output
    if (output_mms)
      {

        for (unsigned int d=0; d<dim; ++d)
          {
            names.push_back ("mms_src_momentum");
          }
        names.push_back ("mms_src_density");
        names.push_back ("mms_src_pressure");
        for (unsigned int d=0; d<dim; ++d)
          {
            names.push_back ("mms_exact_velocity");
          }
        names.push_back ("mms_exact_density");
        names.push_back ("mms_exact_pressure");
//    for (unsigned int d=0; d<dim; ++d)
//      {
        names.push_back ("mms_error_velocity_x");
        names.push_back ("mms_error_velocity_y");
        if (dim == 3)
          {
            names.push_back ("mms_error_velocity_z");
          }
//      }
        names.push_back ("mms_error_density");
        names.push_back ("mms_error_pressure");
      }// End MMS: Exact output

    return names;
  }

  template <int dim>
  std::vector<DataComponentInterpretation::DataComponentInterpretation>
  Postprocessor<dim>::
  get_data_component_interpretation() const
  {
    // "momentum"
    std::vector<DataComponentInterpretation::DataComponentInterpretation>
    interpretation (dim,
                    DataComponentInterpretation::component_is_part_of_vector);
    // "energy_density"
    interpretation.push_back (DataComponentInterpretation::
                              component_is_scalar);
    // "Mach"
    interpretation.push_back (DataComponentInterpretation::
                              component_is_scalar);

    if (do_schlieren_plot)
      interpretation.push_back (DataComponentInterpretation::
                                component_is_scalar);

    // MMS:
    if (output_mms)
      {
        for (unsigned int d=0; d<dim; ++d)
          {
            interpretation.push_back (DataComponentInterpretation::
                                      component_is_part_of_vector);
          }
        interpretation.push_back (DataComponentInterpretation::
                                  component_is_scalar);
        interpretation.push_back (DataComponentInterpretation::
                                  component_is_scalar);

        for (unsigned int d=0; d<dim; ++d)
          {
            interpretation.push_back (DataComponentInterpretation::
                                      component_is_part_of_vector);
          }
        interpretation.push_back (DataComponentInterpretation::
                                  component_is_scalar);
        interpretation.push_back (DataComponentInterpretation::
                                  component_is_scalar);

        for (unsigned int d=0; d<dim; ++d)
          {
            interpretation.push_back (DataComponentInterpretation::
                                      component_is_scalar);
          }
        interpretation.push_back (DataComponentInterpretation::
                                  component_is_scalar);
        interpretation.push_back (DataComponentInterpretation::
                                  component_is_scalar);
      }// END MMS:
    return interpretation;
  }

  template <int dim>
  UpdateFlags
  Postprocessor<dim>::
  get_needed_update_flags() const
  {
    UpdateFlags flags = update_values;
    // MMS : update_quadrature_points
    if (do_schlieren_plot)
      {
        flags |= update_gradients;
      }
    if (output_mms)
      {
        flags |= update_quadrature_points;
      }
    return (flags);
  }

  template class Postprocessor<2>;
  template class Postprocessor<3>;
}
<commit_msg>fix dimemsion check for 'do_schlieren_plot == false'<commit_after>//
//  Created by 乔磊 on 15/4/24.
//  Copyright (c) 2015年 乔磊. All rights reserved.
//

#include <NSolver/Postprocessor.h>

namespace NSFEMSolver
{
  using namespace dealii;

  template <int dim>
  Postprocessor<dim>::
  Postprocessor (Parameters::AllParameters<dim>const *const para_ptr_in,
                 MMS<dim> const *const mms_ptr_in)
    :
    parameters (para_ptr_in),
    mms_x (mms_ptr_in),
    do_schlieren_plot (para_ptr_in->schlieren_plot),
    output_mms (para_ptr_in->n_mms == 1)
  {}

  // This is the only function worth commenting on. When generating graphical
  // output, the DataOut and related classes will call this function on each
  // cell, with values, gradients, Hessians, and normal vectors (in case we're
  // working on faces) at each quadrature point. Note that the data at each
  // quadrature point is itself vector-valued, namely the conserved
  // variables. What we're going to do here is to compute the quantities we're
  // interested in at each quadrature point. Note that for this we can ignore
  // the Hessians ("dduh") and normal vectors; to avoid compiler warnings
  // about unused variables, we comment out their names.
  template <int dim>
  void
  Postprocessor<dim>::
  compute_derived_quantities_vector (const std::vector<Vector<double> >              &uh,
                                     const std::vector<std::vector<Tensor<1,dim> > > &duh,
                                     const std::vector<std::vector<Tensor<2,dim> > > &/*dduh*/,
                                     const std::vector<Point<dim> >                  &/*normals*/,
                                     const std::vector<Point<dim> >                  &points,
                                     std::vector<Vector<double> >                    &computed_quantities) const
  {
    // At the beginning of the function, let us make sure that all variables
    // have the correct sizes, so that we can access individual vector
    // elements without having to wonder whether we might read or write
    // invalid elements; we also check that the duh vector only
    // contains data if we really need it (the system knows about this because
    // we say so in the get_needed_update_flags() function
    // below). For the inner vectors, we check that at least the first element
    // of the outer vector has the correct inner size:
    const unsigned int n_quadrature_points = static_cast<const unsigned int> (uh.size());

    if (do_schlieren_plot)
      {
        Assert (duh.size() == n_quadrature_points, ExcInternalError());
      }
    Assert (computed_quantities.size() == n_quadrature_points, ExcInternalError());
    Assert (uh[0].size() == EquationComponents<dim>::n_components, ExcInternalError());

    //MMS: Extra memory space
    Vector<double>::size_type expected_size = dim+2;
    if (do_schlieren_plot)
      {
        expected_size += 1;
      }
    if (output_mms)
      {
        expected_size += 3*EquationComponents<dim>::n_components;
      }
    Assert (computed_quantities[0].size() == expected_size, ExcInternalError());

    // Then loop over all quadrature points and do our work there. The code
    // should be pretty self-explanatory. The order of output variables is
    // first dim momentums, then the energy_density, and if so desired
    // the schlieren plot. Note that we try to be generic about the order of
    // variables in the input vector, using the
    // first_momentum_component and
    // density_component information:
    for (unsigned int q=0; q<n_quadrature_points; ++q)
      {
        int i_out = 0;
        const double density = uh[q][EquationComponents<dim>::density_component];

        for (unsigned int d=0; d<dim; ++d, ++i_out)
          computed_quantities[q][i_out]
            = uh[q][EquationComponents<dim>::first_momentum_component+d] * density;

        computed_quantities[q][i_out] = EulerEquations<dim>::compute_energy_density (uh[q]);
        ++i_out;
        computed_quantities[q][i_out] = EulerEquations<dim>::compute_velocity_magnitude (uh[q]) /
                                        EulerEquations<dim>::compute_sound_speed (uh[q]);
        ++i_out;

        if (do_schlieren_plot)
          {
            computed_quantities[q][i_out] = duh[q][EquationComponents<dim>::density_component] *
                                            duh[q][EquationComponents<dim>::density_component];
            ++i_out;
          }

        if (output_mms)
          {
            typename MMS<dim>::F_V sol;
            typename MMS<dim>::F_V src;
            typename MMS<dim>::F_T grad;
            mms_x->evaluate (points[q],sol,grad,src,true);

            for (unsigned int ic = 0; ic < EquationComponents<dim>::n_components; ++ic, ++i_out)
              {
                computed_quantities[q][i_out] = src[ic];
              }
            for (unsigned int ic = 0; ic < EquationComponents<dim>::n_components; ++ic, ++i_out)
              {
                computed_quantities[q][i_out] = sol[ic];
              }
            for (unsigned int ic = 0; ic < EquationComponents<dim>::n_components; ++ic, ++i_out)
              {
                computed_quantities[q][i_out] = sol[ic] - uh[q][ic];
              }
          } // End if (output_mms)
      }
  }

  template <int dim>
  std::vector<std::string>
  Postprocessor<dim>::
  get_names() const
  {
    std::vector<std::string> names;
    for (unsigned int d=0; d<dim; ++d)
      {
        names.push_back ("momentum");
      }
    names.push_back ("energy_density");
    names.push_back ("Mach");

    if (do_schlieren_plot)
      {
        names.push_back ("schlieren_plot");
      }

    //MMS: Exact output
    if (output_mms)
      {

        for (unsigned int d=0; d<dim; ++d)
          {
            names.push_back ("mms_src_momentum");
          }
        names.push_back ("mms_src_density");
        names.push_back ("mms_src_pressure");
        for (unsigned int d=0; d<dim; ++d)
          {
            names.push_back ("mms_exact_velocity");
          }
        names.push_back ("mms_exact_density");
        names.push_back ("mms_exact_pressure");
//    for (unsigned int d=0; d<dim; ++d)
//      {
        names.push_back ("mms_error_velocity_x");
        names.push_back ("mms_error_velocity_y");
        if (dim == 3)
          {
            names.push_back ("mms_error_velocity_z");
          }
//      }
        names.push_back ("mms_error_density");
        names.push_back ("mms_error_pressure");
      }// End MMS: Exact output

    return names;
  }

  template <int dim>
  std::vector<DataComponentInterpretation::DataComponentInterpretation>
  Postprocessor<dim>::
  get_data_component_interpretation() const
  {
    // "momentum"
    std::vector<DataComponentInterpretation::DataComponentInterpretation>
    interpretation (dim,
                    DataComponentInterpretation::component_is_part_of_vector);
    // "energy_density"
    interpretation.push_back (DataComponentInterpretation::
                              component_is_scalar);
    // "Mach"
    interpretation.push_back (DataComponentInterpretation::
                              component_is_scalar);

    if (do_schlieren_plot)
      interpretation.push_back (DataComponentInterpretation::
                                component_is_scalar);

    // MMS:
    if (output_mms)
      {
        for (unsigned int d=0; d<dim; ++d)
          {
            interpretation.push_back (DataComponentInterpretation::
                                      component_is_part_of_vector);
          }
        interpretation.push_back (DataComponentInterpretation::
                                  component_is_scalar);
        interpretation.push_back (DataComponentInterpretation::
                                  component_is_scalar);

        for (unsigned int d=0; d<dim; ++d)
          {
            interpretation.push_back (DataComponentInterpretation::
                                      component_is_part_of_vector);
          }
        interpretation.push_back (DataComponentInterpretation::
                                  component_is_scalar);
        interpretation.push_back (DataComponentInterpretation::
                                  component_is_scalar);

        for (unsigned int d=0; d<dim; ++d)
          {
            interpretation.push_back (DataComponentInterpretation::
                                      component_is_scalar);
          }
        interpretation.push_back (DataComponentInterpretation::
                                  component_is_scalar);
        interpretation.push_back (DataComponentInterpretation::
                                  component_is_scalar);
      }// END MMS:
    return interpretation;
  }

  template <int dim>
  UpdateFlags
  Postprocessor<dim>::
  get_needed_update_flags() const
  {
    UpdateFlags flags = update_values;
    // MMS : update_quadrature_points
    if (do_schlieren_plot)
      {
        flags |= update_gradients;
      }
    if (output_mms)
      {
        flags |= update_quadrature_points;
      }
    return (flags);
  }

  template class Postprocessor<2>;
  template class Postprocessor<3>;
}
<|endoftext|>


<commit_before>#include <SFML/Graphics.hpp>
#include <iostream>
#include <fstream>
#include <string>
#include <stdio.h>

#include "renderer.h"
#include "player.h"
#include "coord.h"

GLuint Texture = 0;

GLdouble norm = 1 / sqrt( 3 );

GLdouble x = 0;
GLdouble y = 0;
GLdouble z = 0;
GLdouble radius = 1;
  GLdouble vertices[24] = { x - radius, y - radius, z + radius,
							x + radius, y - radius, z + radius,
							x + radius, y + radius, z + radius,
							x - radius, y + radius, z + radius,
							x - radius, y - radius, z - radius,
							x + radius, y - radius, z - radius,
							x + radius, y + radius, z - radius,
							x - radius, y + radius, z - radius };

  GLdouble normals[24] = { -norm, -norm,  norm,
						    norm, -norm,  norm,
						    norm,  norm,  norm,
						   -norm,  norm,  norm,
						   -norm, -norm, -norm,
						    norm, -norm, -norm,
						    norm,  norm, -norm,
						   -norm,  norm, -norm };

  GLdouble texcoords[24] = { 0.125, 0.0, 0.0,
						     0.0, 0.125, 0.0,
						     0.0, 0.0, 0.0,
						     0.125, 0.0, 0.0,
						     0.0, 0.125, 0.0,
						     0.0, 0.0, 0.0,
						     0.125, 0.0, 0.0,
						     0.0, 0.125, 0.0 };

  GLubyte indices[24] = { 7, 6, 5, 4,
						  5, 6, 2, 1,
						  4, 5, 1, 0,
						  1, 2, 3, 0,
						  3, 7, 4, 0,
						  6, 7, 3, 2 };

Renderer::Renderer(Terrain initterrain) : terrain(initterrain) {
    // Set color and depth clear value
    glClearDepth(1.f);
    glClearColor(0.f, 0.f, 0.f, 1.f); // black

    // Enable Z-buffer read and write
    glEnable(GL_DEPTH_TEST);
    glDepthMask(GL_TRUE);

    // Face culling to render half the polys
    glEnable(GL_CULL_FACE);

    // Lighting
    GLfloat LightAmbient[]  = { 0.5f, 0.5f, 0.5f, 1.0f }; // Ambient Light Values
    GLfloat LightDiffuse[]  = { 1.0f, 1.0f, 1.0f, 1.0f };	// Diffuse Light Values
    GLfloat LightPosition[] = { 0.0f, 0.0f, 2.0f, 1.0f };	// Light Position
    glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient);				// Setup The Ambient Light
    glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse);				// Setup The Diffuse Light
    glLightfv(GL_LIGHT1, GL_POSITION,LightPosition);			// Position The Light
    glEnable(GL_LIGHT1);							// Enable Light One

    //glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); // Let glcolor work with lighting
    //glEnable(GL_COLOR_MATERIAL); // Enable lighting colors
    //glEnable(GL_LIGHTING); // Enable lighting
    glEnable(GL_TEXTURE_2D); // Enable textures

    glShadeModel(GL_SMOOTH); // Enable Smooth Shading

    // Load texture
    sf::Image Image;
    if (!Image.LoadFromFile("data/tiles.png"))
        return;

    glGenTextures(1, &Texture);
    glBindTexture(GL_TEXTURE_2D, Texture);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
    gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, Image.GetWidth(), Image.GetHeight(), GL_RGBA, GL_UNSIGNED_BYTE, Image.GetPixelsPtr());
}

// Don't forget to destroy our texture
//glDeleteTextures(1, &Texture);

void drawCube(float x, float y, float z, float length) {
    float subsize = length / 2;

    glPushMatrix(); // Preserve world matrix

    // Apply some transformations
    glTranslatef(x + subsize, y + subsize, z + subsize);
    glScalef(subsize, subsize, subsize);

    glDrawElements( GL_QUADS, 24, GL_UNSIGNED_BYTE, indices );

    glPopMatrix(); // Undo the translations
}

void renderNode(Octree<bool> terrain, float x, float y, float z, float size) {
    if (terrain.hasChildren) {
        float subsize = size / 2;
        renderNode(terrain.children[0], x,         y,         z,         subsize);
        renderNode(terrain.children[1], x+subsize, y,         z,         subsize);
        renderNode(terrain.children[2], x,         y+subsize, z,         subsize);
        renderNode(terrain.children[3], x+subsize, y+subsize, z,         subsize);
        renderNode(terrain.children[4], x,         y,         z+subsize, subsize);
        renderNode(terrain.children[5], x+subsize, y,         z+subsize, subsize);
        renderNode(terrain.children[6], x,         y+subsize, z+subsize, subsize);
        renderNode(terrain.children[7], x+subsize, y+subsize, z+subsize, subsize);
    } else if (terrain.value) {
        drawCube(x, y, z, size);
    }
}

void Renderer::render(Player player) {

    // Clear color and depth buffer
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // Apply some transformations
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(90.f, 1.f, 1.f, 500.f);
    glRotatef(-90 + player.Yrot, 1.f, 0.f, 0.f);
    glRotatef(player.Zrot, 0.f, 0.f, 1.f);
    glTranslatef(-player.X, -player.Y, -player.Z);    // Translate The Scene Based On Player Position

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glBindTexture(GL_TEXTURE_2D, Texture);

    glEnableClientState( GL_VERTEX_ARRAY );
    glEnableClientState( GL_NORMAL_ARRAY );
    glEnableClientState( GL_TEXTURE_COORD_ARRAY );

    glVertexPointer( 3, GL_DOUBLE, 0, &vertices[0] );
    glNormalPointer( GL_DOUBLE, 0, &normals[0] );
    glTexCoordPointer( 3, GL_DOUBLE, 0, &texcoords[0] );

    // Loop through chunks and render them
    int i, j, k;
    for(i = 0; i < terrain.sizeX; i++)
        for(j = 0; j < terrain.sizeY; j++)
            for(k = 0; k < terrain.sizeZ; k++)
                renderNode(terrain.GeneratedTerrain[Coord(i,j,k)], i*terrain.chunkSize, j*terrain.chunkSize, k*terrain.chunkSize, terrain.chunkSize);

    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_NORMAL_ARRAY);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
<commit_msg>Instead of pushing and poping matrices now I can just reset the drawing matrix.<commit_after>#include <SFML/Graphics.hpp>
#include <iostream>
#include <fstream>
#include <string>
#include <stdio.h>

#include "renderer.h"
#include "player.h"
#include "coord.h"

GLuint Texture = 0;

GLdouble norm = 1 / sqrt( 3 );

GLdouble x = 0;
GLdouble y = 0;
GLdouble z = 0;
GLdouble radius = 1;
  GLdouble vertices[24] = { x - radius, y - radius, z + radius,
							x + radius, y - radius, z + radius,
							x + radius, y + radius, z + radius,
							x - radius, y + radius, z + radius,
							x - radius, y - radius, z - radius,
							x + radius, y - radius, z - radius,
							x + radius, y + radius, z - radius,
							x - radius, y + radius, z - radius };

  GLdouble normals[24] = { -norm, -norm,  norm,
						    norm, -norm,  norm,
						    norm,  norm,  norm,
						   -norm,  norm,  norm,
						   -norm, -norm, -norm,
						    norm, -norm, -norm,
						    norm,  norm, -norm,
						   -norm,  norm, -norm };

  GLdouble texcoords[24] = { 0.125, 0.0, 0.0,
						     0.0, 0.125, 0.0,
						     0.0, 0.0, 0.0,
						     0.125, 0.0, 0.0,
						     0.0, 0.125, 0.0,
						     0.0, 0.0, 0.0,
						     0.125, 0.0, 0.0,
						     0.0, 0.125, 0.0 };

  GLubyte indices[24] = { 7, 6, 5, 4,
						  5, 6, 2, 1,
						  4, 5, 1, 0,
						  1, 2, 3, 0,
						  3, 7, 4, 0,
						  6, 7, 3, 2 };

Renderer::Renderer(Terrain initterrain) : terrain(initterrain) {
    // Set color and depth clear value
    glClearDepth(1.f);
    glClearColor(0.f, 0.f, 0.f, 1.f); // black

    // Enable Z-buffer read and write
    glEnable(GL_DEPTH_TEST);
    glDepthMask(GL_TRUE);

    // Face culling to render half the polys
    glEnable(GL_CULL_FACE);

    // Lighting
    GLfloat LightAmbient[]  = { 0.5f, 0.5f, 0.5f, 1.0f }; // Ambient Light Values
    GLfloat LightDiffuse[]  = { 1.0f, 1.0f, 1.0f, 1.0f };	// Diffuse Light Values
    GLfloat LightPosition[] = { 0.0f, 0.0f, 2.0f, 1.0f };	// Light Position
    glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient);				// Setup The Ambient Light
    glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse);				// Setup The Diffuse Light
    glLightfv(GL_LIGHT1, GL_POSITION,LightPosition);			// Position The Light
    glEnable(GL_LIGHT1);							// Enable Light One

    //glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); // Let glcolor work with lighting
    //glEnable(GL_COLOR_MATERIAL); // Enable lighting colors
    //glEnable(GL_LIGHTING); // Enable lighting
    glEnable(GL_TEXTURE_2D); // Enable textures

    glShadeModel(GL_SMOOTH); // Enable Smooth Shading

    // Load texture
    sf::Image Image;
    if (!Image.LoadFromFile("data/tiles.png"))
        return;

    glGenTextures(1, &Texture);
    glBindTexture(GL_TEXTURE_2D, Texture);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
    gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, Image.GetWidth(), Image.GetHeight(), GL_RGBA, GL_UNSIGNED_BYTE, Image.GetPixelsPtr());
}

// Don't forget to destroy our texture
//glDeleteTextures(1, &Texture);

void drawCube(float x, float y, float z, float length) {
    float subsize = length / 2;

    // Apply some transformations
    glLoadIdentity();
    glTranslatef(x + subsize, y + subsize, z + subsize);
    glScalef(subsize, subsize, subsize);

    glDrawElements( GL_QUADS, 24, GL_UNSIGNED_BYTE, indices );
}

void renderNode(Octree<bool> terrain, float x, float y, float z, float size) {
    if (terrain.hasChildren) {
        float subsize = size / 2;
        renderNode(terrain.children[0], x,         y,         z,         subsize);
        renderNode(terrain.children[1], x+subsize, y,         z,         subsize);
        renderNode(terrain.children[2], x,         y+subsize, z,         subsize);
        renderNode(terrain.children[3], x+subsize, y+subsize, z,         subsize);
        renderNode(terrain.children[4], x,         y,         z+subsize, subsize);
        renderNode(terrain.children[5], x+subsize, y,         z+subsize, subsize);
        renderNode(terrain.children[6], x,         y+subsize, z+subsize, subsize);
        renderNode(terrain.children[7], x+subsize, y+subsize, z+subsize, subsize);
    } else if (terrain.value) {
        drawCube(x, y, z, size);
    }
}

void Renderer::render(Player player) {

    // Clear color and depth buffer
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // Apply some transformations
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(90.f, 1.f, 1.f, 500.f);
    glRotatef(-90 + player.Yrot, 1.f, 0.f, 0.f);
    glRotatef(player.Zrot, 0.f, 0.f, 1.f);
    glTranslatef(-player.X, -player.Y, -player.Z);    // Translate The Scene Based On Player Position

    glMatrixMode(GL_MODELVIEW);

    glBindTexture(GL_TEXTURE_2D, Texture);

    glEnableClientState( GL_VERTEX_ARRAY );
    glEnableClientState( GL_NORMAL_ARRAY );
    glEnableClientState( GL_TEXTURE_COORD_ARRAY );

    glVertexPointer( 3, GL_DOUBLE, 0, &vertices[0] );
    glNormalPointer( GL_DOUBLE, 0, &normals[0] );
    glTexCoordPointer( 3, GL_DOUBLE, 0, &texcoords[0] );

    // Loop through chunks and render them
    int i, j, k;
    for(i = 0; i < terrain.sizeX; i++)
        for(j = 0; j < terrain.sizeY; j++)
            for(k = 0; k < terrain.sizeZ; k++)
                renderNode(terrain.GeneratedTerrain[Coord(i,j,k)], i*terrain.chunkSize, j*terrain.chunkSize, k*terrain.chunkSize, terrain.chunkSize);

    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_NORMAL_ARRAY);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
<|endoftext|>


<commit_before>#include "gum/RenderContext.h"
#include "gum/RenderTargetMgr.h"

#include <unirender/gl/RenderContext.h>
#include <shaderlab/ShaderMgr.h>
#include <shaderlab/SubjectMVP2.h>
#include <sprite2/Blackboard.h>

#include <stddef.h>

namespace gum
{

CU_SINGLETON_DEFINITION(RenderContext)

static void flush_shader()
{
	sl::ShaderMgr::Instance()->FlushShader();
}

static void flush_render_shader()
{
	sl::ShaderMgr::Instance()->FlushRenderShader();
}

RenderContext::RenderContext()
	: m_width(0)
	, m_height(0)
{
	ur::gl::RenderContext::Callback cb;
	cb.flush_shader = flush_shader;
	cb.flush_render_shader = flush_render_shader;
#ifdef EASY_EDITOR
	m_rc = new ur::gl::RenderContext(cb, 4096);
#else
	m_rc = new ur::gl::RenderContext(cb, 1024);
#endif // S2_EDITOR
	m_rc->Init();

	sl::ShaderMgr::Instance()->SetContext(m_rc);
}

RenderContext::~RenderContext()
{
	delete m_rc;
}

void RenderContext::OnSize(int w, int h)
{
	if (m_width == w && m_height == h) {
		return;
	}

	m_width = w;
	m_height = h;

	RenderTargetMgr::Instance()->OnSize(w, h);

	s2::Blackboard::Instance()->SetScreenSize(w, h);
}

}<commit_msg>[CHANGED] rm render ctx's Init<commit_after>#include "gum/RenderContext.h"
#include "gum/RenderTargetMgr.h"

#include <unirender/gl/RenderContext.h>
#include <shaderlab/ShaderMgr.h>
#include <shaderlab/SubjectMVP2.h>
#include <sprite2/Blackboard.h>

#include <stddef.h>

namespace gum
{

CU_SINGLETON_DEFINITION(RenderContext)

static void flush_shader()
{
	sl::ShaderMgr::Instance()->FlushShader();
}

static void flush_render_shader()
{
	sl::ShaderMgr::Instance()->FlushRenderShader();
}

RenderContext::RenderContext()
	: m_width(0)
	, m_height(0)
{
	ur::gl::RenderContext::Callback cb;
	cb.flush_shader = flush_shader;
	cb.flush_render_shader = flush_render_shader;
#ifdef EASY_EDITOR
	m_rc = new ur::gl::RenderContext(cb, 4096);
#else
	m_rc = new ur::gl::RenderContext(cb, 1024);
#endif // S2_EDITOR

	sl::ShaderMgr::Instance()->SetContext(m_rc);
}

RenderContext::~RenderContext()
{
	delete m_rc;
}

void RenderContext::OnSize(int w, int h)
{
	if (m_width == w && m_height == h) {
		return;
	}

	m_width = w;
	m_height = h;

	RenderTargetMgr::Instance()->OnSize(w, h);

	s2::Blackboard::Instance()->SetScreenSize(w, h);
}

}<|endoftext|>


<commit_before>#include "DBAppMenu.h"

#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <vector>

using namespace std;

int main(int argc, char const *argv[])
{
	while(cin)
	{
		switch (menu)
		{
			case 0:		//main menu
				//link: 1,2,3,4,5, 9(back)
				cout << "<<<<< Main Menu >>>>> /n/n/n";
				cout << "Menu Options: /n
						1) Location table /n
						2) Sale table
						3) Employee table /n
						4) Role table /n
						5) Report functions /n
						9) Back/previous option/n "

				break;

			case 1:		//location
				//Link: 0,2,3,11, 9(back)

				switch(submenu)
				{
					case 0:	//main

					case 2: //sale

					case 3: //emp

					case 11: //locView
				}

			case 2:		//sale
				//Link: 0,1,3,21,22,23, 9(back)
				switch(submenu)
				{
					case 0:	//main

					case 1: //loc

					case 3: //emp

					case 21: //saleView

					case 22: //saleAdd

					case 23: //saleEdit
				}

			case 3:		//employee
				//Link: 0,1,2,31, 9(back)
				switch(submenu)
				{
					case 0:	//main

					case 1: //loc

					case 2: //sale

					case 31: //empView
				}

			case 4:		//role
				//Link: 0,41, 9(back)
				switch(submenu)
				{
					case 0:	//main

					case 41: //roleView
				}

			case 5:		//report
				//Link: 9(back)
				//functions: '-', '+', '*', select, project, back, exit

			case 9:		//back function
				//Back-step through stack
				//stack-1

			case 11:	//viewLoc
				//view: open, close, show, project, back, exit

			case 21:	//viewSale
				//view: open, close, show, project, back, exit

			case 22:	//addSale
				//add: write, createTable, update, back, exit

			case 23:	//editSale
				//edit: delete, insertInto, show, back, exit

			case 31:	//viewEmp
				//view: open, close, show, project, back, exit

			case 41: 	//viewRole
				//view: open, close, exit, show, project, back
		}
	}
}<commit_msg>Added some switch statement stuff<commit_after>#include "DBAppMenu.h"

#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <vector>

using namespace std;
int menu = 0;
int submenu = 0;

int main(int argc, char const *argv[])
{
	while(true)
	{
	cout << "<<<<< Main Menu >>>>> /n/n/n";
	cout << "Menu Options: /n
			1) Location table /n
			2) Sale table /n
			3) Employee table /n
			4) Role table /n
			5) Report functions /n
			99) EXIT /n";
	cin >> menu;
		switch (menu)
		{
			case 0:		//main menu
				//link: 1,2,3,4,5, 9(back)
				cout << "<<<<< Main Menu >>>>> /n/n/n";
				cout << "Menu Options: /n
						1) Location table /n
						2) Sale table /n
						3) Employee table /n
						4) Role table /n
						5) Report functions /n
						9) Back / Previous Option /n
						99) EXIT /n";
				cin >> menu;
				break;

			case 1:		//location
				//Link: 0,2,3,11, 9(back)
				cout << "<<<<< Location Sub-Menu >>>>> /n/n/n";
				cout << "Menu Options: /n
						0) Return to Main Menu /n
						1) Sale Table /n
						2) Employee Table /n
						11) Location View /n";
				cin >> submenu;
				break;
				switch(submenu)
				{
					case 0:	//main
						menu = submenu;
						break;
					case 2: //sale

					case 3: //emp

					case 11: //locView
				}

			case 2:		//sale
				//Link: 0,1,3,21,22,23, 9(back)
				switch(submenu)
				{
					case 0:	//main

					case 1: //loc

					case 3: //emp

					case 21: //saleView

					case 22: //saleAdd

					case 23: //saleEdit
				}

			case 3:		//employee
				//Link: 0,1,2,31, 9(back)
				switch(submenu)
				{
					case 0:	//main

					case 1: //loc

					case 2: //sale

					case 31: //empView
				}

			case 4:		//role
				//Link: 0,41, 9(back)
				switch(submenu)
				{
					case 0:	//main

					case 41: //roleView
				}

			case 5:		//report
				//Link: 9(back)
				//functions: '-', '+', '*', select, project, back, exit

			case 9:		//back function
				//Back-step through stack
				//stack-1

			case 11:	//viewLoc
				//view: open, close, show, project, back, exit

			case 21:	//viewSale
				//view: open, close, show, project, back, exit

			case 22:	//addSale
				//add: write, createTable, update, back, exit

			case 23:	//editSale
				//edit: delete, insertInto, show, back, exit

			case 31:	//viewEmp
				//view: open, close, show, project, back, exit

			case 41: 	//viewRole
				//view: open, close, exit, show, project, back
			case 99;
				return false;
				break;
		}
	}
}<|endoftext|>


<commit_before><commit_msg>Planning: minor fix on tensorRT inference<commit_after><|endoftext|>


<commit_before>#include "schedule.hpp"

#include <stdexcept>
#include <cassert>
#include <cmath>
#include <numeric>
#include <algorithm>
#include <iterator>
#include <vector>

void to_difficulty(std::vector<double>& perstage_avg)
{
  auto min = *std::min_element(perstage_avg.begin(), perstage_avg.end());
  for_each(perstage_avg.begin(), perstage_avg.end(),
    [min](double& x){x /= min;}
  );
}

std::vector<unsigned int> solve(unsigned int stages,
                                unsigned int nodes,
                                const std::vector<double>& difficulty_per_stage)
{
  assert(difficulty_per_stage.size() == stages);
  if (nodes < stages) {
    throw std::runtime_error{"Must have more or equal number of nodes than stages"};
  }

  std::vector<unsigned int> nodes_per_stage(stages);

  auto x1 = std::accumulate(difficulty_per_stage.begin(), difficulty_per_stage.end(), 0.0);
  x1 = static_cast<double>(nodes) / x1;

  for (size_t i = 0; i < stages; ++i) {
    nodes_per_stage[i] = ceil(difficulty_per_stage[i] * x1);
  }

  int off_by;

  while ( (off_by = std::accumulate(nodes_per_stage.begin(), nodes_per_stage.end(), 0) - nodes) ) {
    auto max_stage = std::max_element(nodes_per_stage.begin(), nodes_per_stage.end());
    if (off_by < 0) {
      *max_stage += 1;
    } else {
      *max_stage -= 1;
    }
  }

  return nodes_per_stage;
}

void assign(const int local_rank,
            std::vector<unsigned int>& nodes_per_stage,
            schedule_type& rank_assignm,
            int* local_stage)
{
  rank_assignm.clear();
  int rank = 0;
  for (size_t stage = 0; stage < nodes_per_stage.size(); ++stage) {
    auto nodes = nodes_per_stage[stage];
    rank_assignm.push_back(std::vector<int>(nodes));
    for (size_t j = 0; j < nodes; ++j) {
      rank_assignm.back()[j] = rank;
      if (local_rank == rank) {
        *local_stage = stage;
      }
      rank++;
    }
  }
}

void reassign(const int local_rank,
              std::vector<unsigned int>& nodes_per_stage,
              schedule_type& rank_assignm,
              int* local_stage)
{
  assert(nodes_per_stage.size() == rank_assignm.size());
  // extract ranks from stages that have too many
  std::vector<int> cut_ranks;
  for (size_t i = 0; i < nodes_per_stage.size(); ++i) {
    auto& cur_stage = rank_assignm[i];
    int to_rm = (int)cur_stage.size() - nodes_per_stage[i] ;
    auto rm_iter = cur_stage.end();
    for (; to_rm > 0; --to_rm) {
      --rm_iter;
      cut_ranks.push_back(*rm_iter);
    }
    cur_stage.erase(rm_iter, cur_stage.end());
  }

  // reassign them where they are needed
  auto copy_iter = cut_ranks.begin();
  for (size_t i = 0; i < nodes_per_stage.size(); ++i) {
    auto& cur_stage = rank_assignm[i];
    int to_add = (int)nodes_per_stage[i] - cur_stage.size();
    if (to_add > 0)
    {
      auto old_copy_iter = copy_iter;
      std::advance(copy_iter, to_add);
      for (; old_copy_iter != copy_iter; ++old_copy_iter) {
        int rank = *old_copy_iter;
        if (rank == local_rank) {
          *local_stage = i;
        }
        cur_stage.push_back(rank);
      }
    }
  }
}
<commit_msg>dirty not at all permanent solution to constraining the first and last stage to one mpi rank :squirrel:<commit_after>#include "schedule.hpp"

#include <stdexcept>
#include <cassert>
#include <cmath>
#include <numeric>
#include <algorithm>
#include <iterator>
#include <vector>

void to_difficulty(std::vector<double>& perstage_avg)
{
  auto min = *std::min_element(perstage_avg.begin(), perstage_avg.end());
  for_each(perstage_avg.begin(), perstage_avg.end(),
    [min](double& x){x /= min;}
  );
}

std::vector<unsigned int> solve(unsigned int stages,
                                unsigned int nodes,
                                const std::vector<double>& difficulty_per_stage)
{
  assert(difficulty_per_stage.size() == stages);
  if (nodes < stages) {
    throw std::runtime_error{"Must have more or equal number of nodes than stages"};
  }

  std::vector<unsigned int> nodes_per_stage(stages);

  // TODO for the record the following is ugly and I hate it
  auto constrained_begin = std::begin(difficulty_per_stage);
  // std::advance(constrained_begin, 1);
  auto constrained_end = std::end(difficulty_per_stage);
  // std::advance(constrained_end, -1);

  auto x1 = std::accumulate(constrained_begin, constrained_end, 0.0);
  x1 = static_cast<double>(nodes) / x1;

  for (size_t i = 0; i < stages; ++i) {
    if (i == 0 or i == stages - 1) {
      nodes_per_stage[i] = 1;
    } else {
      nodes_per_stage[i] = ceil(difficulty_per_stage[i] * x1);
    }
  }

  int off_by = 0;

  while ( (off_by = std::accumulate(nodes_per_stage.begin(), nodes_per_stage.end(), 0) - nodes) ) {
    auto max_stage = std::max_element(nodes_per_stage.begin(), nodes_per_stage.end());
    if (off_by < 0) {
      *max_stage += 1;
    } else {
      *max_stage -= 1;
    }
  }

  return nodes_per_stage;
}

void assign(const int local_rank,
            std::vector<unsigned int>& nodes_per_stage,
            schedule_type& rank_assignm,
            int* local_stage)
{
  rank_assignm.clear();
  int rank = 0;
  for (size_t stage = 0; stage < nodes_per_stage.size(); ++stage) {
    auto nodes = nodes_per_stage[stage];
    rank_assignm.push_back(std::vector<int>(nodes));
    for (size_t j = 0; j < nodes; ++j) {
      rank_assignm.back()[j] = rank;
      if (local_rank == rank) {
        *local_stage = stage;
      }
      rank++;
    }
  }
}

void reassign(const int local_rank,
              std::vector<unsigned int>& nodes_per_stage,
              schedule_type& rank_assignm,
              int* local_stage)
{
  assert(nodes_per_stage.size() == rank_assignm.size());
  // extract ranks from stages that have too many
  std::vector<int> cut_ranks;
  for (size_t i = 0; i < nodes_per_stage.size(); ++i) {
    auto& cur_stage = rank_assignm[i];
    int to_rm = (int)cur_stage.size() - nodes_per_stage[i] ;
    auto rm_iter = cur_stage.end();
    for (; to_rm > 0; --to_rm) {
      --rm_iter;
      cut_ranks.push_back(*rm_iter);
    }
    cur_stage.erase(rm_iter, cur_stage.end());
  }

  // reassign them where they are needed
  auto copy_iter = cut_ranks.begin();
  for (size_t i = 0; i < nodes_per_stage.size(); ++i) {
    auto& cur_stage = rank_assignm[i];
    int to_add = (int)nodes_per_stage[i] - cur_stage.size();
    if (to_add > 0)
    {
      auto old_copy_iter = copy_iter;
      std::advance(copy_iter, to_add);
      for (; old_copy_iter != copy_iter; ++old_copy_iter) {
        int rank = *old_copy_iter;
        if (rank == local_rank) {
          *local_stage = i;
        }
        cur_stage.push_back(rank);
      }
    }
  }
}
<|endoftext|>


<commit_before><commit_msg>Fixed deadlock on failed tunnel creation<commit_after><|endoftext|>


<commit_before>/*
 * Copyright (c) 2002-2005 The Regents of The University of Michigan
 * Copyright (c) 2011 Advanced Micro Devices
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Nathan Binkert
 *          Steve Reinhardt
 *          Gabe Black
 */

#include "base/misc.hh"
#include "sim/core.hh"
#include "sim/root.hh"

Root *Root::_root = NULL;

/*
 * This function is called periodically by an event in M5 and ensures that
 * at least as much real time has passed between invocations as simulated time.
 * If not, the function either sleeps, or if the difference is small enough
 * spin waits.
 */
void
Root::timeSync()
{
    Time cur_time, diff, period = timeSyncPeriod();

    do {
        cur_time.setTimer();
        diff = cur_time - lastTime;
        Time remainder = period - diff;
        if (diff < period && remainder > _spinThreshold) {
            DPRINTF(TimeSync, "Sleeping to sync with real time.\n");
            // Sleep until the end of the period, or until a signal.
            sleep(remainder);
            // Refresh the current time.
            cur_time.setTimer();
        }
    } while (diff < period);
    lastTime = cur_time;
    schedule(&syncEvent, curTick() + _periodTick);
}

void
Root::timeSyncEnable(bool en)
{
    if (en == _enabled)
        return;
    _enabled = en;
    if (_enabled) {
        // Get event going.
        Tick periods = ((curTick() + _periodTick - 1) / _periodTick);
        Tick nextPeriod = periods * _periodTick;
        schedule(&syncEvent, nextPeriod);
    } else {
        // Stop event.
        deschedule(&syncEvent);
    }
}

/// Configure the period for time sync events.
void
Root::timeSyncPeriod(Time newPeriod)
{
    bool en = timeSyncEnabled();
    _period = newPeriod;
    _periodTick = _period.nsec() * SimClock::Int::ns +
                  _period.sec() * SimClock::Int::s;
    timeSyncEnable(en);
}

/// Set the threshold for time remaining to spin wait.
void
Root::timeSyncSpinThreshold(Time newThreshold)
{
    bool en = timeSyncEnabled();
    _spinThreshold = newThreshold;
    timeSyncEnable(en);
}

Root::Root(RootParams *p) : SimObject(p), _enabled(false),
    _periodTick(p->time_sync_period), syncEvent(this)
{
    uint64_t nsecs = p->time_sync_period / SimClock::Int::ns;
    _period.set(nsecs / Time::NSEC_PER_SEC, nsecs % Time::NSEC_PER_SEC);
    nsecs = p->time_sync_spin_threshold / SimClock::Int::ns;
    _spinThreshold.set(nsecs / Time::NSEC_PER_SEC,
            nsecs % Time::NSEC_PER_SEC);

    assert(_root == NULL);
    _root = this;
    lastTime.setTimer();
    timeSyncEnable(p->time_sync_enable);
}

Root *
RootParams::create()
{
    static bool created = false;
    if (created)
        panic("only one root object allowed!");

    created = true;

    return new Root(this);
}
<commit_msg>TimeSync: Use the new setTick and getTick functions.<commit_after>/*
 * Copyright (c) 2002-2005 The Regents of The University of Michigan
 * Copyright (c) 2011 Advanced Micro Devices
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Nathan Binkert
 *          Steve Reinhardt
 *          Gabe Black
 */

#include "base/misc.hh"
#include "sim/root.hh"

Root *Root::_root = NULL;

/*
 * This function is called periodically by an event in M5 and ensures that
 * at least as much real time has passed between invocations as simulated time.
 * If not, the function either sleeps, or if the difference is small enough
 * spin waits.
 */
void
Root::timeSync()
{
    Time cur_time, diff, period = timeSyncPeriod();

    do {
        cur_time.setTimer();
        diff = cur_time - lastTime;
        Time remainder = period - diff;
        if (diff < period && remainder > _spinThreshold) {
            DPRINTF(TimeSync, "Sleeping to sync with real time.\n");
            // Sleep until the end of the period, or until a signal.
            sleep(remainder);
            // Refresh the current time.
            cur_time.setTimer();
        }
    } while (diff < period);
    lastTime = cur_time;
    schedule(&syncEvent, curTick() + _periodTick);
}

void
Root::timeSyncEnable(bool en)
{
    if (en == _enabled)
        return;
    _enabled = en;
    if (_enabled) {
        // Get event going.
        Tick periods = ((curTick() + _periodTick - 1) / _periodTick);
        Tick nextPeriod = periods * _periodTick;
        schedule(&syncEvent, nextPeriod);
    } else {
        // Stop event.
        deschedule(&syncEvent);
    }
}

/// Configure the period for time sync events.
void
Root::timeSyncPeriod(Time newPeriod)
{
    bool en = timeSyncEnabled();
    _period = newPeriod;
    _periodTick = _period.getTick();
    timeSyncEnable(en);
}

/// Set the threshold for time remaining to spin wait.
void
Root::timeSyncSpinThreshold(Time newThreshold)
{
    bool en = timeSyncEnabled();
    _spinThreshold = newThreshold;
    timeSyncEnable(en);
}

Root::Root(RootParams *p) : SimObject(p), _enabled(false),
    _periodTick(p->time_sync_period), syncEvent(this)
{
    _period.setTick(p->time_sync_period);
    _spinThreshold.setTick(p->time_sync_spin_threshold);

    assert(_root == NULL);
    _root = this;
    lastTime.setTimer();
    timeSyncEnable(p->time_sync_enable);
}

Root *
RootParams::create()
{
    static bool created = false;
    if (created)
        panic("only one root object allowed!");

    created = true;

    return new Root(this);
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: security.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 14:31:47 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library 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
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _OSL_SECURITY_HXX_
#define _OSL_SECURITY_HXX_

#ifndef _RTL_USTRING_HXX_
#include <rtl/ustring.hxx>
#endif

#ifndef _OSL_SECURITY_DECL_HXX
#   include <osl/security_decl.hxx>
#endif

namespace osl
{

inline Security::Security()
{
    m_handle = osl_getCurrentSecurity();
}

inline Security::~Security()
{
    osl_freeSecurityHandle(m_handle);
}

inline sal_Bool Security::logonUser(const rtl::OUString& strName,
                                    const rtl::OUString& strPasswd)
{
    osl_freeSecurityHandle(m_handle);

    m_handle = 0;

    return (osl_loginUser( strName.pData, strPasswd.pData, &m_handle)
            == osl_Security_E_None);
}

inline sal_Bool Security::logonUser( const rtl::OUString& strName,
                                      const rtl::OUString& strPasswd,
                                      const rtl::OUString& strFileServer )
{
    osl_freeSecurityHandle(m_handle);

    m_handle = NULL;

    return (osl_loginUserOnFileServer(strName.pData, strPasswd.pData, strFileServer.pData, &m_handle)
            == osl_Security_E_None);
}

inline sal_Bool Security::getUserIdent( rtl::OUString& strIdent) const
{
    return osl_getUserIdent( m_handle, &strIdent.pData );
}

inline sal_Bool Security::getUserName( rtl::OUString& strName ) const
{
    return osl_getUserName( m_handle, &strName.pData );
}

inline sal_Bool Security::getHomeDir( rtl::OUString& strDirectory) const
{
    return osl_getHomeDir(m_handle, &strDirectory.pData );
}

inline sal_Bool Security::getConfigDir( rtl::OUString& strDirectory ) const
{
    return osl_getConfigDir( m_handle, &strDirectory.pData );
}

inline sal_Bool Security::isAdministrator() const
{
    return osl_isAdministrator(m_handle);
}

inline oslSecurity Security::getHandle() const
{
    return m_handle;
}

}

#endif  // _OSL_SECURITY_HXX_

<commit_msg>INTEGRATION: CWS changefileheader (1.2.378); FILE MERGED 2008/04/01 12:34:02 thb 1.2.378.2: #i85898# Stripping all external header guards 2008/03/31 13:23:36 rt 1.2.378.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: security.hxx,v $
 * $Revision: 1.3 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef _OSL_SECURITY_HXX_
#define _OSL_SECURITY_HXX_

#include <rtl/ustring.hxx>

#ifndef _OSL_SECURITY_DECL_HXX
#   include <osl/security_decl.hxx>
#endif

namespace osl
{

inline Security::Security()
{
    m_handle = osl_getCurrentSecurity();
}

inline Security::~Security()
{
    osl_freeSecurityHandle(m_handle);
}

inline sal_Bool Security::logonUser(const rtl::OUString& strName,
                                    const rtl::OUString& strPasswd)
{
    osl_freeSecurityHandle(m_handle);

    m_handle = 0;

    return (osl_loginUser( strName.pData, strPasswd.pData, &m_handle)
            == osl_Security_E_None);
}

inline sal_Bool Security::logonUser( const rtl::OUString& strName,
                                      const rtl::OUString& strPasswd,
                                      const rtl::OUString& strFileServer )
{
    osl_freeSecurityHandle(m_handle);

    m_handle = NULL;

    return (osl_loginUserOnFileServer(strName.pData, strPasswd.pData, strFileServer.pData, &m_handle)
            == osl_Security_E_None);
}

inline sal_Bool Security::getUserIdent( rtl::OUString& strIdent) const
{
    return osl_getUserIdent( m_handle, &strIdent.pData );
}

inline sal_Bool Security::getUserName( rtl::OUString& strName ) const
{
    return osl_getUserName( m_handle, &strName.pData );
}

inline sal_Bool Security::getHomeDir( rtl::OUString& strDirectory) const
{
    return osl_getHomeDir(m_handle, &strDirectory.pData );
}

inline sal_Bool Security::getConfigDir( rtl::OUString& strDirectory ) const
{
    return osl_getConfigDir( m_handle, &strDirectory.pData );
}

inline sal_Bool Security::isAdministrator() const
{
    return osl_isAdministrator(m_handle);
}

inline oslSecurity Security::getHandle() const
{
    return m_handle;
}

}

#endif  // _OSL_SECURITY_HXX_

<|endoftext|>