<commit_before>#include <functional> // hash

template <typename Key, typename T, int INIT_CAP, int CAP_MULT>
HashMap<Key, T, INIT_CAP, CAP_MULT>::Bucket::Bucket(const Key &key, const T &value) : key_(key) {
  setValue(value);
}

template <typename Key, typename T, int INIT_CAP, int CAP_MULT>
void HashMap<Key, T, INIT_CAP, CAP_MULT>::Bucket::setValue(const T &value) {
  if (values_.size() == 0) {
    values_ << value;
  }
  else {
    values_[0] = value;
  }
}

template <typename Key, typename T, int INIT_CAP, int CAP_MULT>
void HashMap<Key, T, INIT_CAP, CAP_MULT>::Bucket::addValue(const T &value) {
  values_.prepend(value);
}

template <typename Key, typename T, int INIT_CAP, int CAP_MULT>
const Key &HashMap<Key, T, INIT_CAP, CAP_MULT>::Bucket::key() const {
  return key_;
}

template <typename Key, typename T, int INIT_CAP, int CAP_MULT>
T &HashMap<Key, T, INIT_CAP, CAP_MULT>::Bucket::value() {
  return values_[0];
}

template <typename Key, typename T, int INIT_CAP, int CAP_MULT>
const T &HashMap<Key, T, INIT_CAP, CAP_MULT>::Bucket::value() const {
  return values_[0];
}

template <typename Key, typename T, int INIT_CAP, int CAP_MULT>
const Vector<T> &HashMap<Key, T, INIT_CAP, CAP_MULT>::Bucket::values() const {
  return values_;
}

template <typename Key, typename T, int INIT_CAP, int CAP_MULT>
HashMap<Key, T, INIT_CAP, CAP_MULT>::HashMap()
  : buckets(), items(0)
{
  for (int i = 0; i < INIT_CAP; i++) {
    buckets << nullptr;
  }
}

template <typename Key, typename T, int INIT_CAP, int CAP_MULT>
HashMap<Key, T, INIT_CAP, CAP_MULT>::HashMap(const HashMap &other)
  : buckets(other.buckets), items(other.items)
{ }

template <typename Key, typename T, int INIT_CAP, int CAP_MULT>
HashMap<Key, T, INIT_CAP, CAP_MULT>::HashMap(HashMap &&other)
  : buckets(std::move(other.buckets)), items(other.items)
{
  // Clear the other instance.
  other.items = 0;
}

template <typename Key, typename T, int INIT_CAP, int CAP_MULT>
bool HashMap<Key, T, INIT_CAP, CAP_MULT>::isEmpty() const {
  return items == 0;
}

template <typename Key, typename T, int INIT_CAP, int CAP_MULT>
int HashMap<Key, T, INIT_CAP, CAP_MULT>::size() const {
  return items;
}

template <typename Key, typename T, int INIT_CAP, int CAP_MULT>
int HashMap<Key, T, INIT_CAP, CAP_MULT>::capacity() const {
  return buckets.capacity();
}

template <typename Key, typename T, int INIT_CAP, int CAP_MULT>
void HashMap<Key, T, INIT_CAP, CAP_MULT>::insert(const Key &key, const T &value) {
  _insert(key, value);
}

template <typename Key, typename T, int INIT_CAP, int CAP_MULT>
void HashMap<Key, T, INIT_CAP, CAP_MULT>::insertMulti(const Key &key, const T &value) {
  _insert(key, value, true);
}

template <typename Key, typename T, int INIT_CAP, int CAP_MULT>
void HashMap<Key, T, INIT_CAP, CAP_MULT>::remove(const Key &key) {
  if (contains(key)) {
    buckets[hashIndex(key)] = nullptr;
    items--;
  }
}

template <typename Key, typename T, int INIT_CAP, int CAP_MULT>
Key HashMap<Key, T, INIT_CAP, CAP_MULT>::key(const T &value) const {
  return key(value, Key());
}

template <typename Key, typename T, int INIT_CAP, int CAP_MULT>
Key HashMap<Key, T, INIT_CAP, CAP_MULT>::key(const T &value, const Key &defaultKey) const {
  for (const auto &bucket : buckets) {
    if (bucket && bucket->values().contains(value)) {
      return bucket->key();
    }
  }
  return defaultKey;
}

template <typename Key, typename T, int INIT_CAP, int CAP_MULT>
Vector<Key> HashMap<Key, T, INIT_CAP, CAP_MULT>::keys() const {
  Vector<Key> res;
  for (const auto *bucket : buckets) {
    if (bucket) {
      res << bucket->key();
    }
  }
  return res;
}

template <typename Key, typename T, int INIT_CAP, int CAP_MULT>
T HashMap<Key, T, INIT_CAP, CAP_MULT>::value(const Key &key) const {
  return buckets[hashIndex(key)]->value();
}

template <typename Key, typename T, int INIT_CAP, int CAP_MULT>
T HashMap<Key, T, INIT_CAP, CAP_MULT>::value(const Key &key,
                                             const T &defaultValue) const {
  if (!contains(key)) {
    return defaultValue;
  }
  return buckets[hashIndex(key)]->value();
}

template <typename Key, typename T, int INIT_CAP, int CAP_MULT>
Vector<T> HashMap<Key, T, INIT_CAP, CAP_MULT>::values() const {
  Vector<T> res;
  for (const auto *bucket : buckets) {
    if (bucket) {
      res << bucket->values();
    }
  }
  return res;
}

template <typename Key, typename T, int INIT_CAP, int CAP_MULT>
Vector<T> HashMap<Key, T, INIT_CAP, CAP_MULT>::values(const Key &key) const {
  return buckets[hashIndex(key)]->values();
}

template <typename Key, typename T, int INIT_CAP, int CAP_MULT>
bool HashMap<Key, T, INIT_CAP, CAP_MULT>::contains(const Key &key) const {
  return buckets[hashIndex(key)];
}

template <typename Key, typename T, int INIT_CAP, int CAP_MULT>
void HashMap<Key, T, INIT_CAP, CAP_MULT>::clear() {
  buckets.clear();
  items = 0;
}

template <typename Key, typename T, int INIT_CAP, int CAP_MULT>
void HashMap<Key, T, INIT_CAP, CAP_MULT>::reserve(int cap_) {
  buckets.reserve(cap_);
}

template <typename Key, typename T, int INIT_CAP, int CAP_MULT>
void HashMap<Key, T, INIT_CAP, CAP_MULT>::shrinkToFit() {
  // Remove any unused buckets so the vector can shrink as much as possible.
  buckets.remove(nullptr);
  buckets.shrinkToFit();
}

template <typename Key, typename T, int INIT_CAP, int CAP_MULT>
T &HashMap<Key, T, INIT_CAP, CAP_MULT>::operator[](const Key &key) {
  if (!contains(key)) {
    insert(key, T());
  }
  return buckets[hashIndex(key)]->value();
}

template <typename Key, typename T, int INIT_CAP, int CAP_MULT>
T HashMap<Key, T, INIT_CAP, CAP_MULT>::operator[](const Key &key) const {
  return value(key);
}

template <typename Key, typename T, int INIT_CAP, int CAP_MULT>
bool HashMap<Key, T, INIT_CAP, CAP_MULT>::operator==(const HashMap &other) const {
  auto ourKeys = keys();
  auto theirKeys = other.keys();
  if (ourKeys.size() != theirKeys.size()) {
    return false;
  }

  for (const auto &key : ourKeys) {
    if (!theirKeys.contains(key)) {
      return false;
    }
  }

  auto ourValues = values();
  auto theirValues = other.values();
  if (ourValues.size() != theirValues.size()) {
    return false;
  }

  for (const auto &value : ourValues) {
    if (!theirValues.contains(value)) {
      return false;
    }
  }
  return true;
}

template <typename Key, typename T, int INIT_CAP, int CAP_MULT>
bool HashMap<Key, T, INIT_CAP, CAP_MULT>::operator!=(const HashMap &other) const {
  return !(*this == other);
}

template <typename Key, typename T, int INIT_CAP, int CAP_MULT>
std::size_t HashMap<Key, T, INIT_CAP, CAP_MULT>::hashIndex(const Key &key) const {
  return std::hash<Key>()(key) % buckets.size();
}

template <typename Key, typename T, int INIT_CAP, int CAP_MULT>
void HashMap<Key, T, INIT_CAP, CAP_MULT>::checkRehash() {
  // If next item fits then stop.
  if (items + 1 <= buckets.capacity()) {
    return;
  }

  // Force growing!
  buckets.append(nullptr);

  int i = 0;
  for (auto *bucket : buckets) {
    if (bucket) {
      buckets[hashIndex(bucket->key())] = bucket;
      buckets[i] = nullptr; // Clear old index.
    }
    i++;
  }
}

template <typename Key, typename T, int INIT_CAP, int CAP_MULT>
void HashMap<Key, T, INIT_CAP, CAP_MULT>::_insert(const Key &key, const T &value, bool multi) {
  // If there is a collision on a key then either override or prepend if multi mode. Otherwise, if
  // the keys are different then make room for the new one and rehash.
  for (;;) {
    auto *bucket = buckets[hashIndex(key)];
    if (!bucket) break;

    if (bucket->key() == key) {
      if (!multi) {
        bucket->setValue(value);
      }
      else {
        bucket->addValue(value);
        items++;
      }
      return;
    }

    buckets.append(nullptr);
  }

  checkRehash();
  buckets[hashIndex(key)] = new Bucket(key, value);
  items++;
}
<commit_msg>HashMap: Use pointer instead of reference.<commit_after>#include <functional> // hash

template <typename Key, typename T, int INIT_CAP, int CAP_MULT>
HashMap<Key, T, INIT_CAP, CAP_MULT>::Bucket::Bucket(const Key &key, const T &value) : key_(key) {
  setValue(value);
}

template <typename Key, typename T, int INIT_CAP, int CAP_MULT>
void HashMap<Key, T, INIT_CAP, CAP_MULT>::Bucket::setValue(const T &value) {
  if (values_.size() == 0) {
    values_ << value;
  }
  else {
    values_[0] = value;
  }
}

template <typename Key, typename T, int INIT_CAP, int CAP_MULT>
void HashMap<Key, T, INIT_CAP, CAP_MULT>::Bucket::addValue(const T &value) {
  values_.prepend(value);
}

template <typename Key, typename T, int INIT_CAP, int CAP_MULT>
const Key &HashMap<Key, T, INIT_CAP, CAP_MULT>::Bucket::key() const {
  return key_;
}

template <typename Key, typename T, int INIT_CAP, int CAP_MULT>
T &HashMap<Key, T, INIT_CAP, CAP_MULT>::Bucket::value() {
  return values_[0];
}

template <typename Key, typename T, int INIT_CAP, int CAP_MULT>
const T &HashMap<Key, T, INIT_CAP, CAP_MULT>::Bucket::value() const {
  return values_[0];
}

template <typename Key, typename T, int INIT_CAP, int CAP_MULT>
const Vector<T> &HashMap<Key, T, INIT_CAP, CAP_MULT>::Bucket::values() const {
  return values_;
}

template <typename Key, typename T, int INIT_CAP, int CAP_MULT>
HashMap<Key, T, INIT_CAP, CAP_MULT>::HashMap()
  : buckets(), items(0)
{
  for (int i = 0; i < INIT_CAP; i++) {
    buckets << nullptr;
  }
}

template <typename Key, typename T, int INIT_CAP, int CAP_MULT>
HashMap<Key, T, INIT_CAP, CAP_MULT>::HashMap(const HashMap &other)
  : buckets(other.buckets), items(other.items)
{ }

template <typename Key, typename T, int INIT_CAP, int CAP_MULT>
HashMap<Key, T, INIT_CAP, CAP_MULT>::HashMap(HashMap &&other)
  : buckets(std::move(other.buckets)), items(other.items)
{
  // Clear the other instance.
  other.items = 0;
}

template <typename Key, typename T, int INIT_CAP, int CAP_MULT>
bool HashMap<Key, T, INIT_CAP, CAP_MULT>::isEmpty() const {
  return items == 0;
}

template <typename Key, typename T, int INIT_CAP, int CAP_MULT>
int HashMap<Key, T, INIT_CAP, CAP_MULT>::size() const {
  return items;
}

template <typename Key, typename T, int INIT_CAP, int CAP_MULT>
int HashMap<Key, T, INIT_CAP, CAP_MULT>::capacity() const {
  return buckets.capacity();
}

template <typename Key, typename T, int INIT_CAP, int CAP_MULT>
void HashMap<Key, T, INIT_CAP, CAP_MULT>::insert(const Key &key, const T &value) {
  _insert(key, value);
}

template <typename Key, typename T, int INIT_CAP, int CAP_MULT>
void HashMap<Key, T, INIT_CAP, CAP_MULT>::insertMulti(const Key &key, const T &value) {
  _insert(key, value, true);
}

template <typename Key, typename T, int INIT_CAP, int CAP_MULT>
void HashMap<Key, T, INIT_CAP, CAP_MULT>::remove(const Key &key) {
  if (contains(key)) {
    buckets[hashIndex(key)] = nullptr;
    items--;
  }
}

template <typename Key, typename T, int INIT_CAP, int CAP_MULT>
Key HashMap<Key, T, INIT_CAP, CAP_MULT>::key(const T &value) const {
  return key(value, Key());
}

template <typename Key, typename T, int INIT_CAP, int CAP_MULT>
Key HashMap<Key, T, INIT_CAP, CAP_MULT>::key(const T &value, const Key &defaultKey) const {
  for (const auto *bucket : buckets) {
    if (bucket && bucket->values().contains(value)) {
      return bucket->key();
    }
  }
  return defaultKey;
}

template <typename Key, typename T, int INIT_CAP, int CAP_MULT>
Vector<Key> HashMap<Key, T, INIT_CAP, CAP_MULT>::keys() const {
  Vector<Key> res;
  for (const auto *bucket : buckets) {
    if (bucket) {
      res << bucket->key();
    }
  }
  return res;
}

template <typename Key, typename T, int INIT_CAP, int CAP_MULT>
T HashMap<Key, T, INIT_CAP, CAP_MULT>::value(const Key &key) const {
  return buckets[hashIndex(key)]->value();
}

template <typename Key, typename T, int INIT_CAP, int CAP_MULT>
T HashMap<Key, T, INIT_CAP, CAP_MULT>::value(const Key &key,
                                             const T &defaultValue) const {
  if (!contains(key)) {
    return defaultValue;
  }
  return buckets[hashIndex(key)]->value();
}

template <typename Key, typename T, int INIT_CAP, int CAP_MULT>
Vector<T> HashMap<Key, T, INIT_CAP, CAP_MULT>::values() const {
  Vector<T> res;
  for (const auto *bucket : buckets) {
    if (bucket) {
      res << bucket->values();
    }
  }
  return res;
}

template <typename Key, typename T, int INIT_CAP, int CAP_MULT>
Vector<T> HashMap<Key, T, INIT_CAP, CAP_MULT>::values(const Key &key) const {
  return buckets[hashIndex(key)]->values();
}

template <typename Key, typename T, int INIT_CAP, int CAP_MULT>
bool HashMap<Key, T, INIT_CAP, CAP_MULT>::contains(const Key &key) const {
  return buckets[hashIndex(key)];
}

template <typename Key, typename T, int INIT_CAP, int CAP_MULT>
void HashMap<Key, T, INIT_CAP, CAP_MULT>::clear() {
  buckets.clear();
  items = 0;
}

template <typename Key, typename T, int INIT_CAP, int CAP_MULT>
void HashMap<Key, T, INIT_CAP, CAP_MULT>::reserve(int cap_) {
  buckets.reserve(cap_);
}

template <typename Key, typename T, int INIT_CAP, int CAP_MULT>
void HashMap<Key, T, INIT_CAP, CAP_MULT>::shrinkToFit() {
  // Remove any unused buckets so the vector can shrink as much as possible.
  buckets.remove(nullptr);
  buckets.shrinkToFit();
}

template <typename Key, typename T, int INIT_CAP, int CAP_MULT>
T &HashMap<Key, T, INIT_CAP, CAP_MULT>::operator[](const Key &key) {
  if (!contains(key)) {
    insert(key, T());
  }
  return buckets[hashIndex(key)]->value();
}

template <typename Key, typename T, int INIT_CAP, int CAP_MULT>
T HashMap<Key, T, INIT_CAP, CAP_MULT>::operator[](const Key &key) const {
  return value(key);
}

template <typename Key, typename T, int INIT_CAP, int CAP_MULT>
bool HashMap<Key, T, INIT_CAP, CAP_MULT>::operator==(const HashMap &other) const {
  auto ourKeys = keys();
  auto theirKeys = other.keys();
  if (ourKeys.size() != theirKeys.size()) {
    return false;
  }

  for (const auto &key : ourKeys) {
    if (!theirKeys.contains(key)) {
      return false;
    }
  }

  auto ourValues = values();
  auto theirValues = other.values();
  if (ourValues.size() != theirValues.size()) {
    return false;
  }

  for (const auto &value : ourValues) {
    if (!theirValues.contains(value)) {
      return false;
    }
  }
  return true;
}

template <typename Key, typename T, int INIT_CAP, int CAP_MULT>
bool HashMap<Key, T, INIT_CAP, CAP_MULT>::operator!=(const HashMap &other) const {
  return !(*this == other);
}

template <typename Key, typename T, int INIT_CAP, int CAP_MULT>
std::size_t HashMap<Key, T, INIT_CAP, CAP_MULT>::hashIndex(const Key &key) const {
  return std::hash<Key>()(key) % buckets.size();
}

template <typename Key, typename T, int INIT_CAP, int CAP_MULT>
void HashMap<Key, T, INIT_CAP, CAP_MULT>::checkRehash() {
  // If next item fits then stop.
  if (items + 1 <= buckets.capacity()) {
    return;
  }

  // Force growing!
  buckets.append(nullptr);

  int i = 0;
  for (auto *bucket : buckets) {
    if (bucket) {
      buckets[hashIndex(bucket->key())] = bucket;
      buckets[i] = nullptr; // Clear old index.
    }
    i++;
  }
}

template <typename Key, typename T, int INIT_CAP, int CAP_MULT>
void HashMap<Key, T, INIT_CAP, CAP_MULT>::_insert(const Key &key, const T &value, bool multi) {
  // If there is a collision on a key then either override or prepend if multi mode. Otherwise, if
  // the keys are different then make room for the new one and rehash.
  for (;;) {
    auto *bucket = buckets[hashIndex(key)];
    if (!bucket) break;

    if (bucket->key() == key) {
      if (!multi) {
        bucket->setValue(value);
      }
      else {
        bucket->addValue(value);
        items++;
      }
      return;
    }

    buckets.append(nullptr);
  }

  checkRehash();
  buckets[hashIndex(key)] = new Bucket(key, value);
  items++;
}
<|endoftext|>


<commit_before>// Copyright 2015 MongoDB Inc.
//
// 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.

#pragma once

#include <bsoncxx/config/prelude.hpp>

#include <type_traits>

#include <bsoncxx/stdx/optional.hpp>

namespace bsoncxx {
BSONCXX_INLINE_NAMESPACE_BEGIN

///
/// Class representing a view-or-value variant type.
///
template <typename View, typename Value>
class view_or_value {
   public:
    using view_type = View;
    using value_type = Value;

    ///
    /// Class View must be constructible from an instance of class Value.
    ///
    static_assert(std::is_constructible<View, Value>::value,
                  "View type must be constructible from a Value");

    ///
    /// Class View must be default constructible.
    ///
    static_assert(std::is_default_constructible<View>::value,
                  "View type must be default constructible");

    ///
    /// Default-constructs a view_or_value. This is equivalent to constructing a
    /// view_or_value with a default-constructed View.
    ///
    BSONCXX_INLINE view_or_value() = default;

    ///
    /// Construct a view_or_value from a View. When constructed with a View,
    /// this object is non-owning. The Value underneath the given View must outlive this object.
    ///
    /// @param view
    ///   A non-owning View.
    ///
    BSONCXX_INLINE view_or_value(View view) : _view{view} {
    }

    ///
    /// Constructs a view_or_value from a Value type. This object owns the passed-in Value.
    ///
    /// @param value
    ///   A Value type.
    ///
    BSONCXX_INLINE view_or_value(Value&& value) : _value{std::move(value)}, _view{_value->view()} {
    }

    ///
    /// Construct a view_or_value from a copied view_or_value.
    ///
    BSONCXX_INLINE view_or_value(const view_or_value& other)
        : _value{other._value}, _view{_value ? _value->view() : other._view} {
    }

    ///
    /// Assign to this view_or_value from a copied view_or_value.
    ///
    BSONCXX_INLINE view_or_value& operator=(const view_or_value& other) {
        _value = other._value;
        _view = _value ? _value->view() : other._view;
        return *this;
    }

    ///
    /// Construct a view_or_value from a moved-in view_or_value.
    ///
    BSONCXX_INLINE view_or_value(view_or_value&& other)
        : _value{std::move(other._value)}, _view{_value ? _value->view() : std::move(other._view)} {
        other._view = View();
        other._value = stdx::nullopt;
    }

    ///
    /// Assign to this view_or_value from a moved-in view_or_value.
    ///
    BSONCXX_INLINE view_or_value& operator=(view_or_value&& other) {
        _value = std::move(other._value);
        _view = _value ? _value->view() : std::move(other._view);
        other._view = View();
        other._value = stdx::nullopt;
        return *this;
    }

    ///
    /// This type may be used as a View.
    ///
    /// @return a View into this view_or_value.
    ///
    BSONCXX_INLINE operator View() const {
        return _view;
    }

    BSONCXX_INLINE const View& view() const {
        return _view;
    }

   private:
    stdx::optional<Value> _value;
    View _view;
};

///
/// Equality operators for comparison with plain Views.
///

template <typename View, typename Value>
BSONCXX_INLINE bool operator==(view_or_value<View, Value> lhs, View rhs) {
    return lhs.view() == rhs;
}

template <typename View, typename Value>
BSONCXX_INLINE bool operator==(View lhs, view_or_value<View, Value> rhs) {
    return rhs == lhs;
}

template <typename View, typename Value>
BSONCXX_INLINE bool operator!=(view_or_value<View, Value> lhs, View rhs) {
    return !(lhs == rhs);
}

template <typename View, typename Value>
BSONCXX_INLINE bool operator!=(View lhs, view_or_value<View, Value> rhs) {
    return !(rhs == lhs);
}

BSONCXX_INLINE_NAMESPACE_END
}  // namespace bsoncxx

#include <bsoncxx/config/postlude.hpp>
<commit_msg>Minor: comparison operators take view_or_value by const&<commit_after>// Copyright 2015 MongoDB Inc.
//
// 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.

#pragma once

#include <bsoncxx/config/prelude.hpp>

#include <type_traits>

#include <bsoncxx/stdx/optional.hpp>

namespace bsoncxx {
BSONCXX_INLINE_NAMESPACE_BEGIN

///
/// Class representing a view-or-value variant type.
///
template <typename View, typename Value>
class view_or_value {
   public:
    using view_type = View;
    using value_type = Value;

    ///
    /// Class View must be constructible from an instance of class Value.
    ///
    static_assert(std::is_constructible<View, Value>::value,
                  "View type must be constructible from a Value");

    ///
    /// Class View must be default constructible.
    ///
    static_assert(std::is_default_constructible<View>::value,
                  "View type must be default constructible");

    ///
    /// Default-constructs a view_or_value. This is equivalent to constructing a
    /// view_or_value with a default-constructed View.
    ///
    BSONCXX_INLINE view_or_value() = default;

    ///
    /// Construct a view_or_value from a View. When constructed with a View,
    /// this object is non-owning. The Value underneath the given View must outlive this object.
    ///
    /// @param view
    ///   A non-owning View.
    ///
    BSONCXX_INLINE view_or_value(View view) : _view{view} {
    }

    ///
    /// Constructs a view_or_value from a Value type. This object owns the passed-in Value.
    ///
    /// @param value
    ///   A Value type.
    ///
    BSONCXX_INLINE view_or_value(Value&& value) : _value{std::move(value)}, _view{_value->view()} {
    }

    ///
    /// Construct a view_or_value from a copied view_or_value.
    ///
    BSONCXX_INLINE view_or_value(const view_or_value& other)
        : _value{other._value}, _view{_value ? _value->view() : other._view} {
    }

    ///
    /// Assign to this view_or_value from a copied view_or_value.
    ///
    BSONCXX_INLINE view_or_value& operator=(const view_or_value& other) {
        _value = other._value;
        _view = _value ? _value->view() : other._view;
        return *this;
    }

    ///
    /// Construct a view_or_value from a moved-in view_or_value.
    ///
    BSONCXX_INLINE view_or_value(view_or_value&& other)
        : _value{std::move(other._value)}, _view{_value ? _value->view() : std::move(other._view)} {
        other._view = View();
        other._value = stdx::nullopt;
    }

    ///
    /// Assign to this view_or_value from a moved-in view_or_value.
    ///
    BSONCXX_INLINE view_or_value& operator=(view_or_value&& other) {
        _value = std::move(other._value);
        _view = _value ? _value->view() : std::move(other._view);
        other._view = View();
        other._value = stdx::nullopt;
        return *this;
    }

    ///
    /// This type may be used as a View.
    ///
    /// @return a View into this view_or_value.
    ///
    BSONCXX_INLINE operator View() const {
        return _view;
    }

    BSONCXX_INLINE const View& view() const {
        return _view;
    }

   private:
    stdx::optional<Value> _value;
    View _view;
};

///
/// Equality operators for comparison with plain Views.
///

template <typename View, typename Value>
BSONCXX_INLINE bool operator==(const view_or_value<View, Value>& lhs, View rhs) {
    return lhs.view() == rhs;
}

template <typename View, typename Value>
BSONCXX_INLINE bool operator==(View lhs, const view_or_value<View, Value>& rhs) {
    return rhs == lhs;
}

template <typename View, typename Value>
BSONCXX_INLINE bool operator!=(const view_or_value<View, Value>& lhs, View rhs) {
    return !(lhs == rhs);
}

template <typename View, typename Value>
BSONCXX_INLINE bool operator!=(View lhs, const view_or_value<View, Value>& rhs) {
    return !(rhs == lhs);
}

BSONCXX_INLINE_NAMESPACE_END
}  // namespace bsoncxx

#include <bsoncxx/config/postlude.hpp>
<|endoftext|>


<commit_before>/*
 * This file is part of TelepathyQt4
 *
 * Copyright (C) 2009-2010 Collabora Ltd. <http://www.collabora.co.uk/>
 * Copyright (C) 2009-2010 Nokia Corporation
 *
 * 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 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include <TelepathyQt4/ContactCapabilities>

#include <TelepathyQt4/Types>

namespace Tp
{

/**
 * \class ContactCapabilities
 * \ingroup clientconn
 * \headerfile TelepathyQt4/contact-capabilities.h <TelepathyQt4/ContactCapabilities>
 *
 * \brief The ContactCapabilities class provides an object representing the
 * capabilities of a Contact.
 */

/**
 * Construct a new ContactCapabilities object.
 */
ContactCapabilities::ContactCapabilities()
    : CapabilitiesBase()
{
}

/**
 * Construct a new ContactCapabilities object.
 */
ContactCapabilities::ContactCapabilities(bool specificToContact)
    : CapabilitiesBase(specificToContact)
{
}

/**
 * Construct a new ContactCapabilities object using the give \a rccs.
 *
 * \param rccs RequestableChannelClassList representing the capabilities of a
 *             contact.
 */
ContactCapabilities::ContactCapabilities(const RequestableChannelClassList &rccs,
        bool specificToContact)
    : CapabilitiesBase(rccs, specificToContact)
{
}

/**
 * Construct a new ContactCapabilities object using the give \a rccSpecs.
 *
 * \param rccSpecs RequestableChannelClassList representing the capabilities of a
 *                 contact.
 */
ContactCapabilities::ContactCapabilities(const RequestableChannelClassSpecList &rccSpecs,
        bool specificToContact)
    : CapabilitiesBase(rccSpecs, specificToContact)
{
}

/**
 * Class destructor.
 */
ContactCapabilities::~ContactCapabilities()
{
}

/**
 * Return whether creating a StreamTube channel, using the given \a service, by providing a
 * contact identifier is supported.
 *
 * \return \c true if supported, \c false otherwise.
 */
bool ContactCapabilities::streamTubes(const QString &service) const
{
    RequestableChannelClassSpec streamTubeSpec = RequestableChannelClassSpec::streamTube(service);
    RequestableChannelClassSpecList rccSpecs = allClassSpecs();
    foreach (const RequestableChannelClassSpec &rccSpec, rccSpecs) {
        if (rccSpec.supports(streamTubeSpec)) {
            return true;
        }
    }
    return false;
}

/**
 * Return the supported StreamTube services.
 *
 * \return A list of supported StreamTube services.
 */
QStringList ContactCapabilities::streamTubeServices() const
{
    QSet<QString> ret;

    RequestableChannelClassSpecList rccSpecs = allClassSpecs();
    foreach (const RequestableChannelClassSpec &rccSpec, rccSpecs) {
        if (rccSpec.hasFixedProperty(
                    TP_QT4_IFACE_CHANNEL_TYPE_STREAM_TUBE + QLatin1String(".Service"))) {
            ret << rccSpec.fixedProperty(
                    TP_QT4_IFACE_CHANNEL_TYPE_STREAM_TUBE + QLatin1String(".Service")).toString();
        }
    }

    return ret.toList();
}

} // Tp
<commit_msg>ContactCapabilities: Also check for channel type and target handle type in streamTubeServices().<commit_after>/*
 * This file is part of TelepathyQt4
 *
 * Copyright (C) 2009-2010 Collabora Ltd. <http://www.collabora.co.uk/>
 * Copyright (C) 2009-2010 Nokia Corporation
 *
 * 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 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include <TelepathyQt4/ContactCapabilities>

#include <TelepathyQt4/Types>

namespace Tp
{

/**
 * \class ContactCapabilities
 * \ingroup clientconn
 * \headerfile TelepathyQt4/contact-capabilities.h <TelepathyQt4/ContactCapabilities>
 *
 * \brief The ContactCapabilities class provides an object representing the
 * capabilities of a Contact.
 */

/**
 * Construct a new ContactCapabilities object.
 */
ContactCapabilities::ContactCapabilities()
    : CapabilitiesBase()
{
}

/**
 * Construct a new ContactCapabilities object.
 */
ContactCapabilities::ContactCapabilities(bool specificToContact)
    : CapabilitiesBase(specificToContact)
{
}

/**
 * Construct a new ContactCapabilities object using the give \a rccs.
 *
 * \param rccs RequestableChannelClassList representing the capabilities of a
 *             contact.
 */
ContactCapabilities::ContactCapabilities(const RequestableChannelClassList &rccs,
        bool specificToContact)
    : CapabilitiesBase(rccs, specificToContact)
{
}

/**
 * Construct a new ContactCapabilities object using the give \a rccSpecs.
 *
 * \param rccSpecs RequestableChannelClassList representing the capabilities of a
 *                 contact.
 */
ContactCapabilities::ContactCapabilities(const RequestableChannelClassSpecList &rccSpecs,
        bool specificToContact)
    : CapabilitiesBase(rccSpecs, specificToContact)
{
}

/**
 * Class destructor.
 */
ContactCapabilities::~ContactCapabilities()
{
}

/**
 * Return whether creating a StreamTube channel, using the given \a service, by providing a
 * contact identifier is supported.
 *
 * \return \c true if supported, \c false otherwise.
 */
bool ContactCapabilities::streamTubes(const QString &service) const
{
    RequestableChannelClassSpec streamTubeSpec = RequestableChannelClassSpec::streamTube(service);
    RequestableChannelClassSpecList rccSpecs = allClassSpecs();
    foreach (const RequestableChannelClassSpec &rccSpec, rccSpecs) {
        if (rccSpec.supports(streamTubeSpec)) {
            return true;
        }
    }
    return false;
}

/**
 * Return the supported StreamTube services.
 *
 * \return A list of supported StreamTube services.
 */
QStringList ContactCapabilities::streamTubeServices() const
{
    QSet<QString> ret;

    RequestableChannelClassSpecList rccSpecs = allClassSpecs();
    foreach (const RequestableChannelClassSpec &rccSpec, rccSpecs) {
        if (rccSpec.channelType() == TP_QT4_IFACE_CHANNEL_TYPE_STREAM_TUBE &&
            rccSpec.targetHandleType() == HandleTypeContact &&
            rccSpec.hasFixedProperty(
                    TP_QT4_IFACE_CHANNEL_TYPE_STREAM_TUBE + QLatin1String(".Service"))) {
            ret << rccSpec.fixedProperty(
                    TP_QT4_IFACE_CHANNEL_TYPE_STREAM_TUBE + QLatin1String(".Service")).toString();
        }
    }

    return ret.toList();
}

} // Tp
<|endoftext|>


<commit_before>#include "mono_develop.hpp"

#include <bacs/system/file.hpp>
#include <bacs/system/process.hpp>

#include <boost/assert.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/format.hpp>
#include <boost/regex.hpp>

namespace bacs{namespace system{namespace builders
{
    namespace
    {
        struct invalid_lang_error: virtual invalid_argument_error {};
    }

    const bool mono_develop::factory_reg_hook = builder::register_new(
        "mono_develop",
        [](const std::vector<std::string> &arguments)
        {
            builder_ptr tmp(new mono_develop(arguments));
            return tmp;
        });

    static const boost::regex positional("[^=]+"), key_value("([^=]+)=(.*)");

    mono_develop::mono_develop(const std::vector<std::string> &arguments):
        m_configuration("Release")
    {
        for (const std::string &arg: arguments)
        {
            boost::smatch match;
            if (boost::regex_match(arg, match, key_value))
            {
                BOOST_ASSERT(match.size() == 3);
                const std::string key = match[1].str(), value = match[2].str();
                if (key == "configuration")
                {
                    m_configuration = value;
                }
                else
                {
                    BOOST_THROW_EXCEPTION(
                        invalid_argument_error() <<
                        invalid_argument_error::argument(arg));
                }
            }
            else
            {
                BOOST_THROW_EXCEPTION(
                    invalid_argument_error() <<
                    invalid_argument_error::argument(arg));
            }
        }
    }

    static const std::string sln_builder = R"EOF(
import argparse
from os.path import abspath, join, basename, dirname, isfile
import xml.etree.ElementTree as etree
import os
import subprocess
import shutil
import shlex

def getprojectinfo(csproj):
    tree = etree.parse(csproj)
    schema = tree.getroot().tag.strip('Project')
    for prop in tree.getroot().findall(schema + 'PropertyGroup'):
        outputtypeprop = prop.find(schema + 'OutputType')
        if outputtypeprop is not None:
            outtype = outputtypeprop.text
        name = prop.find(schema + 'AssemblyName')
        if name is not None:
            projName = name.text
    return (projName, outtype)

def GetExecutableProjectPath(solution, configuration):
    with open(solution, 'r') as f:
        for line in f:
            if line.startswith('Project'):
                words = [x.strip().strip('"') for x in line.split(',')]
                csproj = join(dirname(solution), words[1].replace('\\', '/'))
                proj = dirname(csproj)
                projname, projtype = getprojectinfo(csproj)
                if projtype == 'Exe':
                    return join(
                        proj,
                        'bin',
                        configuration,
                        projname + '.' + 'exe'
                    )
        return None

if __name__ == '__main__':
    parser = argparse.ArgumentParser(
        description='Extracts executable name from *.sln'
    )
    parser.add_argument('solution',
                        help='Solution file (*.sln)')
    parser.add_argument('-c', '--configuration',
                        default='Release',
                        help='Configuration')
    parser.add_argument('-o', '--output',
                        required=True,
                        help='Output file')
    args = parser.parse_args()

    subprocess.check_call([
        'xbuild',
        '/property:Configuration={}'.format(args.configuration),
        args.solution
    ])
    exe = GetExecutableProjectPath(args.solution, args.configuration)
    with open(args.output, 'w') as out:
        print('#!/bin/sh -e', file=out)
        print('exec', shlex.quote(abspath(exe)), '"$@"', file=out)
    os.chmod(args.output, 0o777)
)EOF";

    static boost::filesystem::path executable_path = "executable";

    executable_ptr mono_develop::build_extracted(
        const ContainerPointer &container,
        const unistd::access::Id &owner_id,
        bunsan::tempfile &&tmpdir,
        const boost::filesystem::path &source,
        const bacs::process::ResourceLimits &resource_limits,
        bacs::process::BuildResult &result)
    {
        using boost::filesystem::recursive_directory_iterator;

        const boost::filesystem::path root =
            container->filesystem().containerPath(tmpdir.path());

        bool found = false;
        boost::filesystem::path solution;
        const boost::filesystem::path abs_source =
            container->filesystem().keepInRoot(source);
        for (recursive_directory_iterator i(abs_source),
                                          end;
             i != end;
             ++i)
        {
            if (boost::filesystem::is_regular_file(*i) &&
                i->path().extension() == ".sln")
            {
                if (found)
                {
                    result.set_status(bacs::process::BuildResult::FAILED);
                    result.set_output(str(
                        boost::format("Multiple solutions found: %1% and %2%") %
                        solution %
                        i->path()
                    ));
                    return executable_ptr();
                }
                else
                {
                    found = true;
                    solution = i->path();
                }
            }
        }
        solution = container->filesystem().containerPath(solution);

        const boost::filesystem::path executable = root / executable_path;
        const ProcessGroupPointer process_group = container->createProcessGroup();
        const ProcessPointer process = process_group->createProcess("python3");
        process->setArguments(
            process->executable(),
            "-c", sln_builder,
            "--configuration", m_configuration,
            "--output", executable,
            source);
        process::setup(process_group, process, resource_limits);
        process->setCurrentPath(root);
        process->setOwnerId(owner_id);
        process->setStream(2, FdAlias(1));
        process->setStream(1, File("log", AccessMode::WRITE_ONLY));
        const ProcessGroup::Result process_group_result =
            process_group->synchronizedCall();
        const Process::Result process_result = process->result();
        const bool success = process::parse_result(
            process_group_result, process_result, *result.mutable_execution());
        result.set_output(file::read_first(tmpdir.path() / "log", 4096));
        if (success)
        {
            executable_ptr tmp(new project_executable(
                container,
                std::move(tmpdir),
                executable
            ));
            return tmp;
        }
        else
        {
            return executable_ptr();
        }
    }
}}}
<commit_msg>builders::mono_develop::build_extracted() bug fix.<commit_after>#include "mono_develop.hpp"

#include <bacs/system/file.hpp>
#include <bacs/system/process.hpp>

#include <boost/assert.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/format.hpp>
#include <boost/regex.hpp>

namespace bacs{namespace system{namespace builders
{
    namespace
    {
        struct invalid_lang_error: virtual invalid_argument_error {};
    }

    const bool mono_develop::factory_reg_hook = builder::register_new(
        "mono_develop",
        [](const std::vector<std::string> &arguments)
        {
            builder_ptr tmp(new mono_develop(arguments));
            return tmp;
        });

    static const boost::regex positional("[^=]+"), key_value("([^=]+)=(.*)");

    mono_develop::mono_develop(const std::vector<std::string> &arguments):
        m_configuration("Release")
    {
        for (const std::string &arg: arguments)
        {
            boost::smatch match;
            if (boost::regex_match(arg, match, key_value))
            {
                BOOST_ASSERT(match.size() == 3);
                const std::string key = match[1].str(), value = match[2].str();
                if (key == "configuration")
                {
                    m_configuration = value;
                }
                else
                {
                    BOOST_THROW_EXCEPTION(
                        invalid_argument_error() <<
                        invalid_argument_error::argument(arg));
                }
            }
            else
            {
                BOOST_THROW_EXCEPTION(
                    invalid_argument_error() <<
                    invalid_argument_error::argument(arg));
            }
        }
    }

    static const std::string sln_builder = R"EOF(
import argparse
from os.path import abspath, join, basename, dirname, isfile
import xml.etree.ElementTree as etree
import os
import subprocess
import shutil
import shlex

def getprojectinfo(csproj):
    tree = etree.parse(csproj)
    schema = tree.getroot().tag.strip('Project')
    for prop in tree.getroot().findall(schema + 'PropertyGroup'):
        outputtypeprop = prop.find(schema + 'OutputType')
        if outputtypeprop is not None:
            outtype = outputtypeprop.text
        name = prop.find(schema + 'AssemblyName')
        if name is not None:
            projName = name.text
    return (projName, outtype)

def GetExecutableProjectPath(solution, configuration):
    with open(solution, 'r') as f:
        for line in f:
            if line.startswith('Project'):
                words = [x.strip().strip('"') for x in line.split(',')]
                csproj = join(dirname(solution), words[1].replace('\\', '/'))
                proj = dirname(csproj)
                projname, projtype = getprojectinfo(csproj)
                if projtype == 'Exe':
                    return join(
                        proj,
                        'bin',
                        configuration,
                        projname + '.' + 'exe'
                    )
        return None

if __name__ == '__main__':
    parser = argparse.ArgumentParser(
        description='Extracts executable name from *.sln'
    )
    parser.add_argument('solution',
                        help='Solution file (*.sln)')
    parser.add_argument('-c', '--configuration',
                        default='Release',
                        help='Configuration')
    parser.add_argument('-o', '--output',
                        required=True,
                        help='Output file')
    args = parser.parse_args()

    subprocess.check_call([
        'xbuild',
        '/property:Configuration={}'.format(args.configuration),
        args.solution
    ])
    exe = GetExecutableProjectPath(args.solution, args.configuration)
    with open(args.output, 'w') as out:
        print('#!/bin/sh -e', file=out)
        print('exec', shlex.quote(abspath(exe)), '"$@"', file=out)
    os.chmod(args.output, 0o777)
)EOF";

    static boost::filesystem::path executable_path = "executable";

    executable_ptr mono_develop::build_extracted(
        const ContainerPointer &container,
        const unistd::access::Id &owner_id,
        bunsan::tempfile &&tmpdir,
        const boost::filesystem::path &source,
        const bacs::process::ResourceLimits &resource_limits,
        bacs::process::BuildResult &result)
    {
        using boost::filesystem::recursive_directory_iterator;

        const boost::filesystem::path root =
            container->filesystem().containerPath(tmpdir.path());

        bool found = false;
        boost::filesystem::path solution;
        const boost::filesystem::path abs_source =
            container->filesystem().keepInRoot(source);
        for (recursive_directory_iterator i(abs_source),
                                          end;
             i != end;
             ++i)
        {
            if (boost::filesystem::is_regular_file(*i) &&
                i->path().extension() == ".sln")
            {
                if (found)
                {
                    result.set_status(bacs::process::BuildResult::FAILED);
                    result.set_output(str(
                        boost::format("Multiple solutions found: %1% and %2%") %
                        solution %
                        i->path()
                    ));
                    return executable_ptr();
                }
                else
                {
                    found = true;
                    solution = i->path();
                }
            }
        }
        solution = container->filesystem().containerPath(solution);

        const boost::filesystem::path executable = root / executable_path;
        const ProcessGroupPointer process_group = container->createProcessGroup();
        const ProcessPointer process = process_group->createProcess("python3");
        process->setArguments(
            process->executable(),
            "-c", sln_builder,
            "--configuration", m_configuration,
            "--output", executable,
            source);
        process::setup(process_group, process, resource_limits);
        process->setCurrentPath(root);
        process->setOwnerId(owner_id);
        process->setStream(2, FdAlias(1));
        process->setStream(1, File("log", AccessMode::WRITE_ONLY));
        const ProcessGroup::Result process_group_result =
            process_group->synchronizedCall();
        const Process::Result process_result = process->result();
        const bool success = process::parse_result(
            process_group_result, process_result, *result.mutable_execution());
        result.set_output(file::read_first(tmpdir.path() / "log", 4096));
        if (success)
        {
            result.set_status(bacs::process::BuildResult::OK);
            executable_ptr tmp(new project_executable(
                container,
                std::move(tmpdir),
                executable
            ));
            return tmp;
        }
        else
        {
            result.set_status(bacs::process::BuildResult::FAILED);
            return executable_ptr();
        }
    }
}}}
<|endoftext|>


<commit_before>/*
 * BgLayer.cpp
 *
 *  Created on: Aug 31, 2014
 *      Author: zhangchen
 */

#include "BgLayer.h"
#include "Counter.h"
#include "AppMacros.h"

BgLayer::BgLayer()
{
	// TODO Auto-generated constructor stub

}

BgLayer::~BgLayer()
{
	// TODO Auto-generated destructor stub
}

bool BgLayer::init()
{
	if (CCLayer::init())
	{
		CCSize s = CCDirector::sharedDirector()->getWinSize();
		this->ignoreAnchorPointForPosition(true);
		setAnchorPoint(ccp(0.5f, 0.5f));
		this->setContentSize(s);
		setPosition(ccp(s.width / 2, s.height / 2));
		CCSize vsize = CCDirector::sharedDirector()->getVisibleSize();
		float width = vsize.width / 2;
		float height = vsize.height / 2;
		/* initialize the counter */
		Counter *counter = Counter::sharedCounter();
		CCTextureCache *cache = CCTextureCache::sharedTextureCache();
		/*-- 背景 --*/
		CCSprite *bg = CCSprite::createWithTexture(
				cache->textureForKey(("background.png")));
		this->addChild(bg, 0);

		CCSprite *bridge = CCSprite::createWithTexture(
				cache->textureForKey(("bg_bridge.png")));
		bridge->setPosition(ccp(0, -height));
		bridge->setAnchorPoint(ccp(0.5, 0));
		this->addChild(bridge, 1);

		/*-- 小鸟 --*/
		CCSprite *bird = CCSprite::createWithSpriteFrameName("bird_1.png");
		bird->setPosition(ccp(150, 180));
		this->addChild(bird, 1);
		CCAnimation *birdAnimation =
				CCAnimationCache::sharedAnimationCache()->animationByName(
						"bird");
		bird->runAction(
				CCRepeatForever::create(CCAnimate::create(birdAnimation)));

		/*-- 飞机 --*/
		CCSprite *plane = CCSprite::createWithSpriteFrameName("plane_1.png");
		plane->setPosition(ccp(260, 180));
		this->addChild(plane, 1);
		CCAnimation *planeAnimation =
				CCAnimationCache::sharedAnimationCache()->animationByName(
						"plane");
		plane->runAction(
				CCRepeatForever::create(CCAnimate::create(planeAnimation)));

		/*-- 计分 --*/
		//当前得分
		CCSprite *title = CCLabelTTF::createWithTexture(
				cache->textureForKey(("bg_score.png")));
		title->setPosition(ccp(0, height - 30));
		title->setAnchorPoint(ccp(0.5, 1));
		this->addChild(title);
		return true;
	}
	else
	{
		return false;
	}
}
<commit_msg>bird and plane moving<commit_after>/*
 * BgLayer.cpp
 *
 *  Created on: Aug 31, 2014
 *      Author: zhangchen
 */

#include "BgLayer.h"
#include "Counter.h"
#include "AppMacros.h"

BgLayer::BgLayer()
{
	// TODO Auto-generated constructor stub

}

BgLayer::~BgLayer()
{
	// TODO Auto-generated destructor stub
}

bool BgLayer::init()
{
	if (CCLayer::init())
	{
		CCSize s = CCDirector::sharedDirector()->getWinSize();
		this->ignoreAnchorPointForPosition(true);
		setAnchorPoint(ccp(0.5f, 0.5f));
		this->setContentSize(s);
		setPosition(ccp(s.width / 2, s.height / 2));
		CCSize vsize = CCDirector::sharedDirector()->getVisibleSize();
		float width = vsize.width / 2;
		float height = vsize.height / 2;
		/* initialize the counter */
		Counter *counter = Counter::sharedCounter();
		CCTextureCache *cache = CCTextureCache::sharedTextureCache();
		/*-- 背景 --*/
		CCSprite *bg = CCSprite::createWithTexture(
				cache->textureForKey(("background.png")));
		this->addChild(bg, 0);

		CCSprite *bridge = CCSprite::createWithTexture(
				cache->textureForKey(("bg_bridge.png")));
		bridge->setPosition(ccp(0, -height));
		bridge->setAnchorPoint(ccp(0.5, 0));
		this->addChild(bridge, 1);

		/*-- 小鸟 --*/
		CCSprite *bird = CCSprite::createWithSpriteFrameName("bird_1.png");
		bird->setPosition(ccp(width + bird->getContentSize().width, 180));
		this->addChild(bird, 1);
		CCAnimation *birdAnimation =
				CCAnimationCache::sharedAnimationCache()->animationByName(
						"bird");
		bird->runAction(
				CCRepeatForever::create(CCAnimate::create(birdAnimation)));
		bird->runAction(
				CCRepeatForever::create(
						CCSequence::create(
								CCMoveTo::create(2,
										ccp(
												-width
														- bird->getContentSize().width,
												bird->getPositionY())),
								CCFlipX::create(true),
								CCDelayTime::create(1.0f),
								CCMoveTo::create(2,
										ccp(
												width
														+ bird->getContentSize().width,
												bird->getPositionY())),
								CCFlipX::create(false),
								NULL)));

		/*-- 飞机 --*/
		CCSprite *plane = CCSprite::createWithSpriteFrameName("plane_1.png");
		plane->setPosition(ccp(width + plane->getContentSize().width, 180));
		this->addChild(plane, 1);
		CCAnimation *planeAnimation =
				CCAnimationCache::sharedAnimationCache()->animationByName(
						"plane");
		plane->runAction(
				CCRepeatForever::create(CCAnimate::create(planeAnimation)));

		plane->runAction(
				CCRepeatForever::create(
						CCSequence::create(CCDelayTime::create(0.5f),
								CCMoveTo::create(2,
										ccp(
												-width
														- plane->getContentSize().width,
												plane->getPositionY())),
								CCFlipX::create(true),
								CCMoveTo::create(2,
										ccp(
												width
														+ plane->getContentSize().width,
												plane->getPositionY())),
								CCFlipX::create(false),
								CCDelayTime::create(0.5f),
								NULL)));

		/*-- 计分 --*/
		//当前得分
		CCSprite *title = CCLabelTTF::createWithTexture(
				cache->textureForKey(("bg_score.png")));
		title->setPosition(ccp(0, height - 30));
		title->setAnchorPoint(ccp(0.5, 1));
		this->addChild(title);
		return true;
	}
	else
	{
		return false;
	}
}
<|endoftext|>


<commit_before>#include <ostream>
#include <string>

#include <ppl.h>
#include <boost/filesystem.hpp>
#include <boost/program_options.hpp>

#include <common/CapricaConfig.h>

#include <papyrus/PapyrusResolutionContext.h>
#include <papyrus/PapyrusScript.h>
#include <papyrus/parser/PapyrusParser.h>

#include <pex/PexAsmWriter.h>
#include <pex/PexReader.h>
#include <pex/PexWriter.h>
#include <pex/parser/PexAsmParser.h>

void compileScript(std::string filename) {
  std::cout << "Compiling " << filename << std::endl;
  auto path = boost::filesystem::path(filename);
  auto baseName = boost::filesystem::basename(path.filename());
  auto ext = boost::filesystem::extension(filename);
  if (!_stricmp(ext.c_str(), ".psc")) {
    auto parser = new caprica::papyrus::parser::PapyrusParser(filename);
    auto a = parser->parseScript();
    caprica::CapricaError::exitIfErrors();
    delete parser;
    auto ctx = new caprica::papyrus::PapyrusResolutionContext();
    a->semantic(ctx);
    caprica::CapricaError::exitIfErrors();
    auto pex = a->buildPex();
    caprica::CapricaError::exitIfErrors();
    delete ctx;
    delete a;
    std::ofstream strm(caprica::CapricaConfig::outputDirectory + baseName + ".pex", std::ofstream::binary);
    caprica::pex::PexWriter wtr(strm);
    pex->write(wtr);

    if (caprica::CapricaConfig::dumpPexAsm) {
      std::ofstream asmStrm(caprica::CapricaConfig::outputDirectory + baseName + ".pas", std::ofstream::binary);
      caprica::pex::PexAsmWriter asmWtr(asmStrm);
      pex->writeAsm(asmWtr);
    }

    delete pex;
  } else if (!_stricmp(ext.c_str(), ".pas")) {
    auto parser = new caprica::pex::parser::PexAsmParser(filename);
    auto pex = parser->parseFile();
    caprica::CapricaError::exitIfErrors();
    delete parser;
    std::ofstream strm(caprica::CapricaConfig::outputDirectory + baseName + ".pex", std::ofstream::binary);
    caprica::pex::PexWriter wtr(strm);
    pex->write(wtr);
    delete pex;
  } else if (!_stricmp(ext.c_str(), ".pex")) {
    caprica::pex::PexReader rdr(filename);
    auto pex = caprica::pex::PexFile::read(rdr);
    caprica::CapricaError::exitIfErrors();
    std::ofstream asmStrm(caprica::CapricaConfig::outputDirectory + baseName + ".pas", std::ofstream::binary);
    caprica::pex::PexAsmWriter asmWtr(asmStrm);
    pex->writeAsm(asmWtr);
    delete pex;
  } else {
    std::cout << "Don't know how to compile " << filename << "!" << std::endl;
  }
}

std::pair<std::string, std::string> parseOddArguments(const std::string& str) {
  if (str == "WE")
    return std::make_pair("all-warnings-as-errors", "");
  else if (str.find("we") == 0)
    return std::make_pair("warning-as-error", str.substr(2));
  else if (str.find("wd") == 0)
    return std::make_pair("disable-warning", str.substr(2));
  else
    return std::make_pair(std::string(), std::string());
}

bool parseArgs(int argc, char* argv[], std::vector<std::string>& filesToCompile) {
  namespace po = boost::program_options;
  namespace conf = caprica::CapricaConfig;

  try {
    po::options_description desc("General");
    desc.add_options()
      ("help,h", "Print usage information.")
      ("import,i", po::value<std::vector<std::string>>(&conf::importDirectories), "Set the compiler's import directories.")
      ("optimize,O", po::bool_switch(&conf::enableOptimizations)->default_value(false), "Enable optimizations.")
      ("output,o", po::value<std::string>(&conf::outputDirectory)->default_value(boost::filesystem::absolute("./").string()), "Set the directory to save compiler output to.")
      ("parallel-compile,p", po::bool_switch(&conf::compileInParallel)->default_value(false), "Compile files in parallel.")
      ("dump-asm", po::bool_switch(&conf::dumpPexAsm)->default_value(false), "Dump the PEX assembly code for the input files.")
      ("all-warnings-as-errors", po::bool_switch(&conf::treatWarningsAsErrors)->default_value(false), "Treat all warnings as if they were errors.")
      ("warning-as-error", po::value<std::vector<size_t>>(), "Treat a specific warning as an error.")
      ("disable-warning", po::value<std::vector<size_t>>(), "Disable a specific warning.")
    ;

    po::options_description champollionCompatDesc("Champollion Compatibility");
    champollionCompatDesc.add_options()
      ("champollion-compat", po::value<bool>()->default_value(true)->implicit_value(true), "Enable a few options that make it easier to compile Papyrus code decompiled by Champollion.")
      ("allow-compiler-identifiers", po::bool_switch(&conf::allowCompilerIdentifiers)->default_value(false), "Allow identifiers to be prefixed with ::, which is normally reserved for compiler identifiers.")
      ("allow-decompiled-struct-references", po::bool_switch(&conf::allowDecompiledStructNameRefs)->default_value(false), "Allow the name of structs to be prefixed with the containing object name, followed by a #, then the name of the struct.")
    ;

    po::options_description advancedDesc("Advanced");
    advancedDesc.add_options()
      ("enable-ck-optimizations", po::value<bool>(&conf::enableCKOptimizations)->default_value(true), "Enable optimizations that the CK compiler normally does regardless of the -optimize switch.")
      ("enable-debug-info", po::value<bool>(&conf::emitDebugInfo)->default_value(true), "Enable the generation of debug info. Disabling this will result in Property Groups not showing up in the Creation Kit for the compiled script. This also removes the line number and struct order information.")
      ("enable-language-extensions", po::value<bool>(&conf::enableLanguageExtensions)->default_value(true), "Enable Caprica's extensions to the Papyrus language.")
      ("enable-speculative-syntax", po::value<bool>(&conf::enableSpeculativeSyntax)->default_value(true), "Enable the speculated syntax for the new Papyrus features in Fallout 4.")
    ;

    po::options_description hiddenDesc("");
    hiddenDesc.add_options()
      ("input-file", po::value<std::vector<std::string>>(), "The input file.")
    ;

    po::positional_options_description p;
    p.add("input-file", -1);

    po::options_description visibleDesc("Caprica Papyrus Compiler v0.0.8\nUsage: Caprica <sourceFile/directory>\nNote that when passing a directory, only Papyrus script files (*.psc) in it will be compiled. Pex (*.pex) and Pex assembly (*.pas) files will be ignored.");
    visibleDesc.add(desc).add(champollionCompatDesc).add(advancedDesc);

    po::options_description commandLineDesc("");
    commandLineDesc.add(visibleDesc).add(hiddenDesc);

    po::variables_map vm;
    po::store(po::command_line_parser(argc, argv)
              .options(commandLineDesc)
              .extra_parser(parseOddArguments)
              .positional(p)
              .run(), vm);
    po::notify(vm);

    if (vm.count("help") || !vm.count("input-file")) {
      std::cout << visibleDesc << std::endl;
      return false;
    }

    if (vm["champollion-compat"].as<bool>()) {
      conf::allowCompilerIdentifiers = true;
      conf::allowDecompiledStructNameRefs = true;
    }

    if (vm.count("warning-as-error")) {
      auto warnsAsErrs = vm["warning-as-error"].as<std::vector<size_t>>();
      conf::warningsToHandleAsErrors.reserve(warnsAsErrs.size());
      for (auto f : warnsAsErrs) {
        if (conf::warningsToHandleAsErrors.count(f)) {
          std::cout << "Warning " << f << " was already marked as an error." << std::endl;
          return false;
        }
        conf::warningsToHandleAsErrors.insert(f);
      }
    }

    if (vm.count("disable-warning")) {
      auto warnsIgnored = vm["disable-warning"].as<std::vector<size_t>>();
      conf::warningsToIgnore.reserve(warnsIgnored.size());
      for (auto f : warnsIgnored) {
        if (conf::warningsToIgnore.count(f)) {
          std::cout << "Warning " << f << " was already disabled." << std::endl;
          return false;
        }
        conf::warningsToIgnore.insert(f);
      }
    }

    auto filesPassed = vm["input-file"].as<std::vector<std::string>>();
    filesToCompile.reserve(filesPassed.size());
    for (auto f : filesPassed) {
      if (!boost::filesystem::exists(f)) {
        std::cout << "Unable to locate input file '" << f << "'." << std::endl;
        return false;
      }
      if (boost::filesystem::is_directory(f)) {
        boost::system::error_code ec;
        for (auto e : boost::filesystem::directory_iterator(f, ec)) {
          if (e.path().extension().string() == ".psc")
            filesToCompile.push_back(e.path().string());
        }
      } else {
        auto ext = boost::filesystem::extension(f);
        if (_stricmp(ext.c_str(), ".psc") && _stricmp(ext.c_str(), ".pas") && _stricmp(ext.c_str(), ".pex")) {
          std::cout << "Don't know how to handle input file '" << f << "'!" << std::endl;
          std::cout << "Expected either a Papyrus file (*.psc), Pex assembly file (*.pas), or a Pex file (*.pex)!" << std::endl;
          return false;
        }
        filesToCompile.push_back(f);
      }
    }
  } catch (const std::exception& ex) {
    std::cout << ex.what() << std::endl;
    return false;
  }

  return true;
}

int main(int argc, char* argv[])
{
  std::vector<std::string> filesToCompile;
  if (!parseArgs(argc, argv, filesToCompile)) {
    __debugbreak();
    return -1;
  }

  try {
    if (caprica::CapricaConfig::compileInParallel) {
      concurrency::parallel_for_each(filesToCompile.begin(), filesToCompile.end(), [](std::string fl) {
        compileScript(fl);
      });
    } else {
      for (auto& file : filesToCompile)
        compileScript(file);
    }
  } catch (const std::runtime_error& err) {
    err;
    //std::cout << err.what() << std::endl;
    __debugbreak();
  }

  return 0;
}

<commit_msg>Bump version to v0.0.9<commit_after>#include <ostream>
#include <string>

#include <ppl.h>
#include <boost/filesystem.hpp>
#include <boost/program_options.hpp>

#include <common/CapricaConfig.h>

#include <papyrus/PapyrusResolutionContext.h>
#include <papyrus/PapyrusScript.h>
#include <papyrus/parser/PapyrusParser.h>

#include <pex/PexAsmWriter.h>
#include <pex/PexReader.h>
#include <pex/PexWriter.h>
#include <pex/parser/PexAsmParser.h>

void compileScript(std::string filename) {
  std::cout << "Compiling " << filename << std::endl;
  auto path = boost::filesystem::path(filename);
  auto baseName = boost::filesystem::basename(path.filename());
  auto ext = boost::filesystem::extension(filename);
  if (!_stricmp(ext.c_str(), ".psc")) {
    auto parser = new caprica::papyrus::parser::PapyrusParser(filename);
    auto a = parser->parseScript();
    caprica::CapricaError::exitIfErrors();
    delete parser;
    auto ctx = new caprica::papyrus::PapyrusResolutionContext();
    a->semantic(ctx);
    caprica::CapricaError::exitIfErrors();
    auto pex = a->buildPex();
    caprica::CapricaError::exitIfErrors();
    delete ctx;
    delete a;
    std::ofstream strm(caprica::CapricaConfig::outputDirectory + baseName + ".pex", std::ofstream::binary);
    caprica::pex::PexWriter wtr(strm);
    pex->write(wtr);

    if (caprica::CapricaConfig::dumpPexAsm) {
      std::ofstream asmStrm(caprica::CapricaConfig::outputDirectory + baseName + ".pas", std::ofstream::binary);
      caprica::pex::PexAsmWriter asmWtr(asmStrm);
      pex->writeAsm(asmWtr);
    }

    delete pex;
  } else if (!_stricmp(ext.c_str(), ".pas")) {
    auto parser = new caprica::pex::parser::PexAsmParser(filename);
    auto pex = parser->parseFile();
    caprica::CapricaError::exitIfErrors();
    delete parser;
    std::ofstream strm(caprica::CapricaConfig::outputDirectory + baseName + ".pex", std::ofstream::binary);
    caprica::pex::PexWriter wtr(strm);
    pex->write(wtr);
    delete pex;
  } else if (!_stricmp(ext.c_str(), ".pex")) {
    caprica::pex::PexReader rdr(filename);
    auto pex = caprica::pex::PexFile::read(rdr);
    caprica::CapricaError::exitIfErrors();
    std::ofstream asmStrm(caprica::CapricaConfig::outputDirectory + baseName + ".pas", std::ofstream::binary);
    caprica::pex::PexAsmWriter asmWtr(asmStrm);
    pex->writeAsm(asmWtr);
    delete pex;
  } else {
    std::cout << "Don't know how to compile " << filename << "!" << std::endl;
  }
}

std::pair<std::string, std::string> parseOddArguments(const std::string& str) {
  if (str == "WE")
    return std::make_pair("all-warnings-as-errors", "");
  else if (str.find("we") == 0)
    return std::make_pair("warning-as-error", str.substr(2));
  else if (str.find("wd") == 0)
    return std::make_pair("disable-warning", str.substr(2));
  else
    return std::make_pair(std::string(), std::string());
}

bool parseArgs(int argc, char* argv[], std::vector<std::string>& filesToCompile) {
  namespace po = boost::program_options;
  namespace conf = caprica::CapricaConfig;

  try {
    po::options_description desc("General");
    desc.add_options()
      ("help,h", "Print usage information.")
      ("import,i", po::value<std::vector<std::string>>(&conf::importDirectories), "Set the compiler's import directories.")
      ("optimize,O", po::bool_switch(&conf::enableOptimizations)->default_value(false), "Enable optimizations.")
      ("output,o", po::value<std::string>(&conf::outputDirectory)->default_value(boost::filesystem::absolute("./").string()), "Set the directory to save compiler output to.")
      ("parallel-compile,p", po::bool_switch(&conf::compileInParallel)->default_value(false), "Compile files in parallel.")
      ("dump-asm", po::bool_switch(&conf::dumpPexAsm)->default_value(false), "Dump the PEX assembly code for the input files.")
      ("all-warnings-as-errors", po::bool_switch(&conf::treatWarningsAsErrors)->default_value(false), "Treat all warnings as if they were errors.")
      ("warning-as-error", po::value<std::vector<size_t>>(), "Treat a specific warning as an error.")
      ("disable-warning", po::value<std::vector<size_t>>(), "Disable a specific warning.")
    ;

    po::options_description champollionCompatDesc("Champollion Compatibility");
    champollionCompatDesc.add_options()
      ("champollion-compat", po::value<bool>()->default_value(true)->implicit_value(true), "Enable a few options that make it easier to compile Papyrus code decompiled by Champollion.")
      ("allow-compiler-identifiers", po::bool_switch(&conf::allowCompilerIdentifiers)->default_value(false), "Allow identifiers to be prefixed with ::, which is normally reserved for compiler identifiers.")
      ("allow-decompiled-struct-references", po::bool_switch(&conf::allowDecompiledStructNameRefs)->default_value(false), "Allow the name of structs to be prefixed with the containing object name, followed by a #, then the name of the struct.")
    ;

    po::options_description advancedDesc("Advanced");
    advancedDesc.add_options()
      ("enable-ck-optimizations", po::value<bool>(&conf::enableCKOptimizations)->default_value(true), "Enable optimizations that the CK compiler normally does regardless of the -optimize switch.")
      ("enable-debug-info", po::value<bool>(&conf::emitDebugInfo)->default_value(true), "Enable the generation of debug info. Disabling this will result in Property Groups not showing up in the Creation Kit for the compiled script. This also removes the line number and struct order information.")
      ("enable-language-extensions", po::value<bool>(&conf::enableLanguageExtensions)->default_value(true), "Enable Caprica's extensions to the Papyrus language.")
      ("enable-speculative-syntax", po::value<bool>(&conf::enableSpeculativeSyntax)->default_value(true), "Enable the speculated syntax for the new Papyrus features in Fallout 4.")
    ;

    po::options_description hiddenDesc("");
    hiddenDesc.add_options()
      ("input-file", po::value<std::vector<std::string>>(), "The input file.")
    ;

    po::positional_options_description p;
    p.add("input-file", -1);

    po::options_description visibleDesc("Caprica Papyrus Compiler v0.0.9\nUsage: Caprica <sourceFile/directory>\nNote that when passing a directory, only Papyrus script files (*.psc) in it will be compiled. Pex (*.pex) and Pex assembly (*.pas) files will be ignored.");
    visibleDesc.add(desc).add(champollionCompatDesc).add(advancedDesc);

    po::options_description commandLineDesc("");
    commandLineDesc.add(visibleDesc).add(hiddenDesc);

    po::variables_map vm;
    po::store(po::command_line_parser(argc, argv)
              .options(commandLineDesc)
              .extra_parser(parseOddArguments)
              .positional(p)
              .run(), vm);
    po::notify(vm);

    if (vm.count("help") || !vm.count("input-file")) {
      std::cout << visibleDesc << std::endl;
      return false;
    }

    if (vm["champollion-compat"].as<bool>()) {
      conf::allowCompilerIdentifiers = true;
      conf::allowDecompiledStructNameRefs = true;
    }

    if (vm.count("warning-as-error")) {
      auto warnsAsErrs = vm["warning-as-error"].as<std::vector<size_t>>();
      conf::warningsToHandleAsErrors.reserve(warnsAsErrs.size());
      for (auto f : warnsAsErrs) {
        if (conf::warningsToHandleAsErrors.count(f)) {
          std::cout << "Warning " << f << " was already marked as an error." << std::endl;
          return false;
        }
        conf::warningsToHandleAsErrors.insert(f);
      }
    }

    if (vm.count("disable-warning")) {
      auto warnsIgnored = vm["disable-warning"].as<std::vector<size_t>>();
      conf::warningsToIgnore.reserve(warnsIgnored.size());
      for (auto f : warnsIgnored) {
        if (conf::warningsToIgnore.count(f)) {
          std::cout << "Warning " << f << " was already disabled." << std::endl;
          return false;
        }
        conf::warningsToIgnore.insert(f);
      }
    }

    auto filesPassed = vm["input-file"].as<std::vector<std::string>>();
    filesToCompile.reserve(filesPassed.size());
    for (auto f : filesPassed) {
      if (!boost::filesystem::exists(f)) {
        std::cout << "Unable to locate input file '" << f << "'." << std::endl;
        return false;
      }
      if (boost::filesystem::is_directory(f)) {
        boost::system::error_code ec;
        for (auto e : boost::filesystem::directory_iterator(f, ec)) {
          if (e.path().extension().string() == ".psc")
            filesToCompile.push_back(e.path().string());
        }
      } else {
        auto ext = boost::filesystem::extension(f);
        if (_stricmp(ext.c_str(), ".psc") && _stricmp(ext.c_str(), ".pas") && _stricmp(ext.c_str(), ".pex")) {
          std::cout << "Don't know how to handle input file '" << f << "'!" << std::endl;
          std::cout << "Expected either a Papyrus file (*.psc), Pex assembly file (*.pas), or a Pex file (*.pex)!" << std::endl;
          return false;
        }
        filesToCompile.push_back(f);
      }
    }
  } catch (const std::exception& ex) {
    std::cout << ex.what() << std::endl;
    return false;
  }

  return true;
}

int main(int argc, char* argv[])
{
  std::vector<std::string> filesToCompile;
  if (!parseArgs(argc, argv, filesToCompile)) {
    __debugbreak();
    return -1;
  }

  try {
    if (caprica::CapricaConfig::compileInParallel) {
      concurrency::parallel_for_each(filesToCompile.begin(), filesToCompile.end(), [](std::string fl) {
        compileScript(fl);
      });
    } else {
      for (auto& file : filesToCompile)
        compileScript(file);
    }
  } catch (const std::runtime_error& err) {
    err;
    //std::cout << err.what() << std::endl;
    __debugbreak();
  }

  return 0;
}

<|endoftext|>


<commit_before>// -------------------------------------------------------------------------
//    @FileName      :    NFCActorManager.cpp
//    @Author           :    LvSheng.Huang
//    @Date             :    2012-12-15
//    @Module           :    NFCActorManager
//
// -------------------------------------------------------------------------

#include "NFCActorManager.h"
#include "NFCPluginManager.h"

bool NFCActorManager::Init()
{
#ifdef NF_USE_ACTOR
    m_pFramework = new Theron::Framework();
#endif
    //׸߳
    //mActorVec.push_back(new NFCPluginManager(*m_pFramework, this, EACTOR::EACTOR_MAIN));

	for (int i = EACTOR::EACTOR_MAIN; i < EACTOR::EACTOR_END; ++i)
	{
#ifdef NF_USE_ACTOR
		mActorVec.push_back(new NFCPluginManager(*m_pFramework, this, (EACTOR)i));
#else
		mActorVec.push_back(new NFCPluginManager(this));
#endif
	}

	std::vector<NFIActor*>::iterator it = mActorVec.begin();
	for (; it != mActorVec.end(); ++it)
	{
		NFIActor* pActor = *it;

#ifdef NF_USE_ACTOR
		Theron::Receiver receiver;
		NFIActorMessage xMessage;
		xMessage.eType = NFIActorMessage::EACTOR_INIT;
		m_pFramework->Send(xMessage, receiver.GetAddress(), pActor->GetAddress());

		receiver.Wait();
#else
		pActor->Init();
#endif

	}

	return true;
}

bool NFCActorManager::AfterInit()
{
	std::vector<NFIActor*>::iterator it = mActorVec.begin();
	for (; it != mActorVec.end(); ++it)
	{
		NFIActor* pActor = *it;

#ifdef NF_USE_ACTOR

		Theron::Receiver xReceiver;
		NFIActorMessage xMessage;
		xMessage.eType = NFIActorMessage::EACTOR_AFTER_INIT;
		m_pFramework->Send(xMessage, xReceiver.GetAddress(), pActor->GetAddress());

		xReceiver.Wait();
#else
		pActor->AfterInit();
#endif
	}
	return true;
}

bool NFCActorManager::CheckConfig()
{
    std::vector<NFIActor*>::iterator it = mActorVec.begin();
    for (; it != mActorVec.end(); ++it)
    {
		NFIActor* pActor = *it;

#ifdef NF_USE_ACTOR

        Theron::Receiver xReceiver;
        NFIActorMessage xMessage;
        xMessage.eType = NFIActorMessage::EACTOR_CHECKCONFIG;
        m_pFramework->Send(xMessage, xReceiver.GetAddress(), (*it)->GetAddress());

        xReceiver.Wait();
#else
		pActor->CheckConfig();
#endif
    }
    return true;
}

bool NFCActorManager::BeforeShut()
{
	std::vector<NFIActor*>::iterator it = mActorVec.begin();
	for (; it != mActorVec.end(); ++it)
	{
		NFIActor* pActor = *it;

#ifdef NF_USE_ACTOR

		Theron::Receiver xReceiver;
		NFIActorMessage xMessage;
		xMessage.eType = NFIActorMessage::EACTOR_BEFORE_SHUT;
		m_pFramework->Send(xMessage, xReceiver.GetAddress(), (*it)->GetAddress());

		xReceiver.Wait();
#else
		pActor->BeforeShut();
#endif
	}
	return true;
}

bool NFCActorManager::Shut()
{
	std::vector<NFIActor*>::iterator it = mActorVec.begin();
	for (; it != mActorVec.end(); ++it)
	{
		NFIActor* pActor = *it;

#ifdef NF_USE_ACTOR

		Theron::Receiver xReceiver;
		NFIActorMessage xMessage;
		xMessage.eType = NFIActorMessage::EACTOR_SHUT;
		m_pFramework->Send(xMessage, xReceiver.GetAddress(), (*it)->GetAddress());

		xReceiver.Wait();
#else
		pActor->Shut();
#endif
	}

	it = mActorVec.begin();
	for (; it != mActorVec.end(); ++it)
	{
		delete *it;
	}

	mActorVec.clear();

#ifdef NF_USE_ACTOR
    delete m_pFramework;
    m_pFramework = NULL;
#endif
	return true;
}

bool NFCActorManager::Execute( const float fLasFrametime, const float fStartedTime )
{
	std::vector<NFIActor*>::iterator it = mActorVec.begin();
	for (; it != mActorVec.end(); ++it)
	{
        NFIActor* pActor = *it;

#ifdef NF_USE_ACTOR

        const int nMsgCount = pActor->GetNumQueuedMessages();
        if (nMsgCount <= 10)
        {
            NFIActorMessage xMessage;
            xMessage.eType = NFIActorMessage::EACTOR_EXCUTE;

			//if only one actor, then use synchronous mode, other use  asynchronous mode.
			//at the same,it's use synchronous mode in the same actor.
			if (NFIActorManager::EACTOR_END - NFIActorManager::EACTOR_MAIN == 1)
			{
// 				Theron::Receiver xReceiver;
// 				m_pFramework->Send(xMessage, xReceiver.GetAddress(), pActor->GetAddress());
// 				xReceiver.Wait();
				m_pFramework->Send(xMessage, Theron::Address(), pActor->GetAddress());
			}
			else if (NFIActorManager::EACTOR_END - NFIActorManager::EACTOR_MAIN > 1)
			{
				m_pFramework->Send(xMessage, Theron::Address(), pActor->GetAddress());
			}
        }
#else
		pActor->Execute(fLasFrametime, fStartedTime);
#endif
	}

	return true;
}

#ifdef NF_USE_ACTOR
const Theron::Address NFCActorManager::GetAddress( NFIActorManager::EACTOR eActor )
{
	if (eActor >= NFIActorManager::EACTOR_MAIN
		&& eActor < NFIActorManager::EACTOR_END)
	{
		return mActorVec[eActor]->GetAddress();
	}

	return Theron::Address();
}
#else
#endif
<commit_msg>only one thread<commit_after>// -------------------------------------------------------------------------
//    @FileName      :    NFCActorManager.cpp
//    @Author           :    LvSheng.Huang
//    @Date             :    2012-12-15
//    @Module           :    NFCActorManager
//
// -------------------------------------------------------------------------

#include "NFCActorManager.h"
#include "NFCPluginManager.h"

bool NFCActorManager::Init()
{
#ifdef NF_USE_ACTOR
    m_pFramework = new Theron::Framework(1);
#endif
    //׸߳
    //mActorVec.push_back(new NFCPluginManager(*m_pFramework, this, EACTOR::EACTOR_MAIN));

	for (int i = EACTOR::EACTOR_MAIN; i < EACTOR::EACTOR_END; ++i)
	{
#ifdef NF_USE_ACTOR
		mActorVec.push_back(new NFCPluginManager(*m_pFramework, this, (EACTOR)i));
#else
		mActorVec.push_back(new NFCPluginManager(this));
#endif
	}

	std::vector<NFIActor*>::iterator it = mActorVec.begin();
	for (; it != mActorVec.end(); ++it)
	{
		NFIActor* pActor = *it;

#ifdef NF_USE_ACTOR
		Theron::Receiver receiver;
		NFIActorMessage xMessage;
		xMessage.eType = NFIActorMessage::EACTOR_INIT;
		m_pFramework->Send(xMessage, receiver.GetAddress(), pActor->GetAddress());

		receiver.Wait();
#else
		pActor->Init();
#endif

	}

	return true;
}

bool NFCActorManager::AfterInit()
{
	std::vector<NFIActor*>::iterator it = mActorVec.begin();
	for (; it != mActorVec.end(); ++it)
	{
		NFIActor* pActor = *it;

#ifdef NF_USE_ACTOR

		Theron::Receiver xReceiver;
		NFIActorMessage xMessage;
		xMessage.eType = NFIActorMessage::EACTOR_AFTER_INIT;
		m_pFramework->Send(xMessage, xReceiver.GetAddress(), pActor->GetAddress());

		xReceiver.Wait();
#else
		pActor->AfterInit();
#endif
	}
	return true;
}

bool NFCActorManager::CheckConfig()
{
    std::vector<NFIActor*>::iterator it = mActorVec.begin();
    for (; it != mActorVec.end(); ++it)
    {
		NFIActor* pActor = *it;

#ifdef NF_USE_ACTOR

        Theron::Receiver xReceiver;
        NFIActorMessage xMessage;
        xMessage.eType = NFIActorMessage::EACTOR_CHECKCONFIG;
        m_pFramework->Send(xMessage, xReceiver.GetAddress(), (*it)->GetAddress());

        xReceiver.Wait();
#else
		pActor->CheckConfig();
#endif
    }
    return true;
}

bool NFCActorManager::BeforeShut()
{
	std::vector<NFIActor*>::iterator it = mActorVec.begin();
	for (; it != mActorVec.end(); ++it)
	{
		NFIActor* pActor = *it;

#ifdef NF_USE_ACTOR

		Theron::Receiver xReceiver;
		NFIActorMessage xMessage;
		xMessage.eType = NFIActorMessage::EACTOR_BEFORE_SHUT;
		m_pFramework->Send(xMessage, xReceiver.GetAddress(), (*it)->GetAddress());

		xReceiver.Wait();
#else
		pActor->BeforeShut();
#endif
	}
	return true;
}

bool NFCActorManager::Shut()
{
	std::vector<NFIActor*>::iterator it = mActorVec.begin();
	for (; it != mActorVec.end(); ++it)
	{
		NFIActor* pActor = *it;

#ifdef NF_USE_ACTOR

		Theron::Receiver xReceiver;
		NFIActorMessage xMessage;
		xMessage.eType = NFIActorMessage::EACTOR_SHUT;
		m_pFramework->Send(xMessage, xReceiver.GetAddress(), (*it)->GetAddress());

		xReceiver.Wait();
#else
		pActor->Shut();
#endif
	}

	it = mActorVec.begin();
	for (; it != mActorVec.end(); ++it)
	{
		delete *it;
	}

	mActorVec.clear();

#ifdef NF_USE_ACTOR
    delete m_pFramework;
    m_pFramework = NULL;
#endif
	return true;
}

bool NFCActorManager::Execute( const float fLasFrametime, const float fStartedTime )
{
	std::vector<NFIActor*>::iterator it = mActorVec.begin();
	for (; it != mActorVec.end(); ++it)
	{
        NFIActor* pActor = *it;

#ifdef NF_USE_ACTOR

        const int nMsgCount = pActor->GetNumQueuedMessages();
        if (nMsgCount <= 10)
        {
            NFIActorMessage xMessage;
            xMessage.eType = NFIActorMessage::EACTOR_EXCUTE;

			//if only one actor, then use synchronous mode, other use  asynchronous mode.
			//at the same,it's use synchronous mode in the same actor.
			if (NFIActorManager::EACTOR_END - NFIActorManager::EACTOR_MAIN == 1)
			{
// 				Theron::Receiver xReceiver;
// 				m_pFramework->Send(xMessage, xReceiver.GetAddress(), pActor->GetAddress());
// 				xReceiver.Wait();
				m_pFramework->Send(xMessage, Theron::Address(), pActor->GetAddress());
			}
			else if (NFIActorManager::EACTOR_END - NFIActorManager::EACTOR_MAIN > 1)
			{
				m_pFramework->Send(xMessage, Theron::Address(), pActor->GetAddress());
			}
        }
#else
		pActor->Execute(fLasFrametime, fStartedTime);
#endif
	}

	return true;
}

#ifdef NF_USE_ACTOR
const Theron::Address NFCActorManager::GetAddress( NFIActorManager::EACTOR eActor )
{
	if (eActor >= NFIActorManager::EACTOR_MAIN
		&& eActor < NFIActorManager::EACTOR_END)
	{
		return mActorVec[eActor]->GetAddress();
	}

	return Theron::Address();
}
#else
#endif
<|endoftext|>