<commit_before>// Copyright 2008 the V8 project authors. 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 Google Inc. 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.

#include "v8.h"

#include "compilation-cache.h"

namespace v8 {
namespace internal {

enum {
  // The number of script generations tell how many GCs a script can
  // survive in the compilation cache, before it will be flushed if it
  // hasn't been used.
  NUMBER_OF_SCRIPT_GENERATIONS = 8,

  // The compilation cache consists of tables - one for each entry
  // kind plus extras for the script generations.
  NUMBER_OF_TABLE_ENTRIES =
      CompilationCache::LAST_ENTRY + NUMBER_OF_SCRIPT_GENERATIONS
};

// Current enable state of the compilation cache.
static bool enabled = true;
static inline bool IsEnabled() {
  return FLAG_compilation_cache && enabled;
}

// Keep separate tables for the different entry kinds.
static Object* tables[NUMBER_OF_TABLE_ENTRIES] = { 0, };

static Handle<CompilationCacheTable> AllocateTable(int size) {
  CALL_HEAP_FUNCTION(CompilationCacheTable::Allocate(size),
                     CompilationCacheTable);
}

static Handle<CompilationCacheTable> GetTable(int index) {
  ASSERT(index >= 0 && index < NUMBER_OF_TABLE_ENTRIES);
  Handle<CompilationCacheTable> result;
  if (tables[index]->IsUndefined()) {
    static const int kInitialCacheSize = 64;
    result = AllocateTable(kInitialCacheSize);
    tables[index] = *result;
  } else {
    CompilationCacheTable* table = CompilationCacheTable::cast(tables[index]);
    result = Handle<CompilationCacheTable>(table);
  }
  return result;
}

static Handle<JSFunction> Lookup(Handle<String> source,
                                 Handle<Context> context,
                                 CompilationCache::Entry entry) {
  // Make sure not to leak the table into the surrounding handle
  // scope. Otherwise, we risk keeping old tables around even after
  // having cleared the cache.
  Object* result;
  { HandleScope scope;
    Handle<CompilationCacheTable> table = GetTable(entry);
    result = table->LookupEval(*source, *context);
  }
  if (result->IsJSFunction()) {
    return Handle<JSFunction>(JSFunction::cast(result));
  } else {
    return Handle<JSFunction>::null();
  }
}

static Handle<FixedArray> Lookup(Handle<String> source,
                                 JSRegExp::Flags flags) {
  // Make sure not to leak the table into the surrounding handle
  // scope. Otherwise, we risk keeping old tables around even after
  // having cleared the cache.
  Object* result;
  { HandleScope scope;
    Handle<CompilationCacheTable> table = GetTable(CompilationCache::REGEXP);
    result = table->LookupRegExp(*source, flags);
  }
  if (result->IsFixedArray()) {
    return Handle<FixedArray>(FixedArray::cast(result));
  } else {
    return Handle<FixedArray>::null();
  }
}

// We only re-use a cached function for some script source code if the
// script originates from the same place. This is to avoid issues
// when reporting errors, etc.
static bool HasOrigin(Handle<JSFunction> boilerplate,
                      Handle<Object> name,
                      int line_offset,
                      int column_offset) {
  Handle<Script> script =
      Handle<Script>(Script::cast(boilerplate->shared()->script()));
  // If the script name isn't set, the boilerplate script should have
  // an undefined name to have the same origin.
  if (name.is_null()) {
    return script->name()->IsUndefined();
  }
  // Do the fast bailout checks first.
  if (line_offset != script->line_offset()->value()) return false;
  if (column_offset != script->column_offset()->value()) return false;
  // Check that both names are strings. If not, no match.
  if (!name->IsString() || !script->name()->IsString()) return false;
  // Compare the two name strings for equality.
  return String::cast(*name)->Equals(String::cast(script->name()));
}

// TODO(245): Need to allow identical code from different contexts to
// be cached in the same script generation. Currently the first use
// will be cached, but subsequent code from different source / line
// won't.
Handle<JSFunction> CompilationCache::LookupScript(Handle<String> source,
                                                  Handle<Object> name,
                                                  int line_offset,
                                                  int column_offset) {
  if (!IsEnabled()) {
    return Handle<JSFunction>::null();
  }

  // Use an int for the generation index, so value range propagation
  // in gcc 4.3+ won't assume it can only go up to LAST_ENTRY when in
  // fact it can go up to SCRIPT + NUMBER_OF_SCRIPT_GENERATIONS.
  int generation = SCRIPT;
  Object* result = NULL;

  // Probe the script generation tables. Make sure not to leak handles
  // into the caller's handle scope.
  { HandleScope scope;
    while (generation < SCRIPT + NUMBER_OF_SCRIPT_GENERATIONS) {
      Handle<CompilationCacheTable> table = GetTable(generation);
      Handle<Object> probe(table->Lookup(*source));
      if (probe->IsJSFunction()) {
        Handle<JSFunction> boilerplate = Handle<JSFunction>::cast(probe);
        // Break when we've found a suitable boilerplate function that
        // matches the origin.
        if (HasOrigin(boilerplate, name, line_offset, column_offset)) {
          result = *boilerplate;
          break;
        }
      }
      // Go to the next generation.
      generation++;
    }
  }

  static void* script_histogram = StatsTable::CreateHistogram(
      "V8.ScriptCache",
      0,
      NUMBER_OF_SCRIPT_GENERATIONS,
      NUMBER_OF_SCRIPT_GENERATIONS + 1);

  if (script_histogram != NULL) {
    // The level NUMBER_OF_SCRIPT_GENERATIONS is equivalent to a cache miss.
    StatsTable::AddHistogramSample(script_histogram, generation - SCRIPT);
  }

  // Once outside the manacles of the handle scope, we need to recheck
  // to see if we actually found a cached script. If so, we return a
  // handle created in the caller's handle scope.
  if (result != NULL) {
    Handle<JSFunction> boilerplate(JSFunction::cast(result));
    ASSERT(HasOrigin(boilerplate, name, line_offset, column_offset));
    // If the script was found in a later generation, we promote it to
    // the first generation to let it survive longer in the cache.
    if (generation != SCRIPT) PutScript(source, boilerplate);
    Counters::compilation_cache_hits.Increment();
    return boilerplate;
  } else {
    Counters::compilation_cache_misses.Increment();
    return Handle<JSFunction>::null();
  }
}

Handle<JSFunction> CompilationCache::LookupEval(Handle<String> source,
                                                Handle<Context> context,
                                                Entry entry) {
  if (!IsEnabled()) {
    return Handle<JSFunction>::null();
  }

  ASSERT(entry == EVAL_GLOBAL || entry == EVAL_CONTEXTUAL);
  Handle<JSFunction> result = Lookup(source, context, entry);
  if (result.is_null()) {
    Counters::compilation_cache_misses.Increment();
  } else {
    Counters::compilation_cache_hits.Increment();
  }
  return result;
}

Handle<FixedArray> CompilationCache::LookupRegExp(Handle<String> source,
                                                  JSRegExp::Flags flags) {
  if (!IsEnabled()) {
    return Handle<FixedArray>::null();
  }

  Handle<FixedArray> result = Lookup(source, flags);
  if (result.is_null()) {
    Counters::compilation_cache_misses.Increment();
  } else {
    Counters::compilation_cache_hits.Increment();
  }
  return result;
}

void CompilationCache::PutScript(Handle<String> source,
                                 Handle<JSFunction> boilerplate) {
  if (!IsEnabled()) {
    return;
  }

  HandleScope scope;
  ASSERT(boilerplate->IsBoilerplate());
  Handle<CompilationCacheTable> table = GetTable(SCRIPT);
  CALL_HEAP_FUNCTION_VOID(table->Put(*source, *boilerplate));
}

void CompilationCache::PutEval(Handle<String> source,
                               Handle<Context> context,
                               Entry entry,
                               Handle<JSFunction> boilerplate) {
  if (!IsEnabled()) {
    return;
  }

  HandleScope scope;
  ASSERT(boilerplate->IsBoilerplate());
  Handle<CompilationCacheTable> table = GetTable(entry);
  CALL_HEAP_FUNCTION_VOID(table->PutEval(*source, *context, *boilerplate));
}

void CompilationCache::PutRegExp(Handle<String> source,
                                 JSRegExp::Flags flags,
                                 Handle<FixedArray> data) {
  if (!IsEnabled()) {
    return;
  }

  HandleScope scope;
  Handle<CompilationCacheTable> table = GetTable(REGEXP);
  CALL_HEAP_FUNCTION_VOID(table->PutRegExp(*source, flags, *data));
}

void CompilationCache::Clear() {
  for (int i = 0; i < NUMBER_OF_TABLE_ENTRIES; i++) {
    tables[i] = Heap::undefined_value();
  }
}

void CompilationCache::Iterate(ObjectVisitor* v) {
  v->VisitPointers(&tables[0], &tables[NUMBER_OF_TABLE_ENTRIES]);
}

void CompilationCache::MarkCompactPrologue() {
  ASSERT(LAST_ENTRY == SCRIPT);
  for (int i = NUMBER_OF_TABLE_ENTRIES - 1; i > SCRIPT; i--) {
    tables[i] = tables[i - 1];
  }
  for (int j = 0; j <= LAST_ENTRY; j++) {
    tables[j] = Heap::undefined_value();
  }
}

void CompilationCache::Enable() {
  enabled = true;
}

void CompilationCache::Disable() {
  enabled = false;
  Clear();
}

} }  // namespace v8::internal
<commit_msg>Lower the number of generations in the script compilation cache to 5 (down from 8). Generations 5, 6, and 7 are  rarely hit in real browsing sessions (~2% in the best case) so it seems better to lower the size to avoid carrying around  too many compiled scripts in the cache. Review URL: http://codereview.chromium.org/119301<commit_after>// Copyright 2008 the V8 project authors. 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 Google Inc. 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.

#include "v8.h"

#include "compilation-cache.h"

namespace v8 {
namespace internal {

enum {
  // The number of script generations tell how many GCs a script can
  // survive in the compilation cache, before it will be flushed if it
  // hasn't been used.
  NUMBER_OF_SCRIPT_GENERATIONS = 5,

  // The compilation cache consists of tables - one for each entry
  // kind plus extras for the script generations.
  NUMBER_OF_TABLE_ENTRIES =
      CompilationCache::LAST_ENTRY + NUMBER_OF_SCRIPT_GENERATIONS
};

// Current enable state of the compilation cache.
static bool enabled = true;
static inline bool IsEnabled() {
  return FLAG_compilation_cache && enabled;
}

// Keep separate tables for the different entry kinds.
static Object* tables[NUMBER_OF_TABLE_ENTRIES] = { 0, };

static Handle<CompilationCacheTable> AllocateTable(int size) {
  CALL_HEAP_FUNCTION(CompilationCacheTable::Allocate(size),
                     CompilationCacheTable);
}

static Handle<CompilationCacheTable> GetTable(int index) {
  ASSERT(index >= 0 && index < NUMBER_OF_TABLE_ENTRIES);
  Handle<CompilationCacheTable> result;
  if (tables[index]->IsUndefined()) {
    static const int kInitialCacheSize = 64;
    result = AllocateTable(kInitialCacheSize);
    tables[index] = *result;
  } else {
    CompilationCacheTable* table = CompilationCacheTable::cast(tables[index]);
    result = Handle<CompilationCacheTable>(table);
  }
  return result;
}

static Handle<JSFunction> Lookup(Handle<String> source,
                                 Handle<Context> context,
                                 CompilationCache::Entry entry) {
  // Make sure not to leak the table into the surrounding handle
  // scope. Otherwise, we risk keeping old tables around even after
  // having cleared the cache.
  Object* result;
  { HandleScope scope;
    Handle<CompilationCacheTable> table = GetTable(entry);
    result = table->LookupEval(*source, *context);
  }
  if (result->IsJSFunction()) {
    return Handle<JSFunction>(JSFunction::cast(result));
  } else {
    return Handle<JSFunction>::null();
  }
}

static Handle<FixedArray> Lookup(Handle<String> source,
                                 JSRegExp::Flags flags) {
  // Make sure not to leak the table into the surrounding handle
  // scope. Otherwise, we risk keeping old tables around even after
  // having cleared the cache.
  Object* result;
  { HandleScope scope;
    Handle<CompilationCacheTable> table = GetTable(CompilationCache::REGEXP);
    result = table->LookupRegExp(*source, flags);
  }
  if (result->IsFixedArray()) {
    return Handle<FixedArray>(FixedArray::cast(result));
  } else {
    return Handle<FixedArray>::null();
  }
}

// We only re-use a cached function for some script source code if the
// script originates from the same place. This is to avoid issues
// when reporting errors, etc.
static bool HasOrigin(Handle<JSFunction> boilerplate,
                      Handle<Object> name,
                      int line_offset,
                      int column_offset) {
  Handle<Script> script =
      Handle<Script>(Script::cast(boilerplate->shared()->script()));
  // If the script name isn't set, the boilerplate script should have
  // an undefined name to have the same origin.
  if (name.is_null()) {
    return script->name()->IsUndefined();
  }
  // Do the fast bailout checks first.
  if (line_offset != script->line_offset()->value()) return false;
  if (column_offset != script->column_offset()->value()) return false;
  // Check that both names are strings. If not, no match.
  if (!name->IsString() || !script->name()->IsString()) return false;
  // Compare the two name strings for equality.
  return String::cast(*name)->Equals(String::cast(script->name()));
}

// TODO(245): Need to allow identical code from different contexts to
// be cached in the same script generation. Currently the first use
// will be cached, but subsequent code from different source / line
// won't.
Handle<JSFunction> CompilationCache::LookupScript(Handle<String> source,
                                                  Handle<Object> name,
                                                  int line_offset,
                                                  int column_offset) {
  if (!IsEnabled()) {
    return Handle<JSFunction>::null();
  }

  // Use an int for the generation index, so value range propagation
  // in gcc 4.3+ won't assume it can only go up to LAST_ENTRY when in
  // fact it can go up to SCRIPT + NUMBER_OF_SCRIPT_GENERATIONS.
  int generation = SCRIPT;
  Object* result = NULL;

  // Probe the script generation tables. Make sure not to leak handles
  // into the caller's handle scope.
  { HandleScope scope;
    while (generation < SCRIPT + NUMBER_OF_SCRIPT_GENERATIONS) {
      Handle<CompilationCacheTable> table = GetTable(generation);
      Handle<Object> probe(table->Lookup(*source));
      if (probe->IsJSFunction()) {
        Handle<JSFunction> boilerplate = Handle<JSFunction>::cast(probe);
        // Break when we've found a suitable boilerplate function that
        // matches the origin.
        if (HasOrigin(boilerplate, name, line_offset, column_offset)) {
          result = *boilerplate;
          break;
        }
      }
      // Go to the next generation.
      generation++;
    }
  }

  static void* script_histogram = StatsTable::CreateHistogram(
      "V8.ScriptCache",
      0,
      NUMBER_OF_SCRIPT_GENERATIONS,
      NUMBER_OF_SCRIPT_GENERATIONS + 1);

  if (script_histogram != NULL) {
    // The level NUMBER_OF_SCRIPT_GENERATIONS is equivalent to a cache miss.
    StatsTable::AddHistogramSample(script_histogram, generation - SCRIPT);
  }

  // Once outside the manacles of the handle scope, we need to recheck
  // to see if we actually found a cached script. If so, we return a
  // handle created in the caller's handle scope.
  if (result != NULL) {
    Handle<JSFunction> boilerplate(JSFunction::cast(result));
    ASSERT(HasOrigin(boilerplate, name, line_offset, column_offset));
    // If the script was found in a later generation, we promote it to
    // the first generation to let it survive longer in the cache.
    if (generation != SCRIPT) PutScript(source, boilerplate);
    Counters::compilation_cache_hits.Increment();
    return boilerplate;
  } else {
    Counters::compilation_cache_misses.Increment();
    return Handle<JSFunction>::null();
  }
}

Handle<JSFunction> CompilationCache::LookupEval(Handle<String> source,
                                                Handle<Context> context,
                                                Entry entry) {
  if (!IsEnabled()) {
    return Handle<JSFunction>::null();
  }

  ASSERT(entry == EVAL_GLOBAL || entry == EVAL_CONTEXTUAL);
  Handle<JSFunction> result = Lookup(source, context, entry);
  if (result.is_null()) {
    Counters::compilation_cache_misses.Increment();
  } else {
    Counters::compilation_cache_hits.Increment();
  }
  return result;
}

Handle<FixedArray> CompilationCache::LookupRegExp(Handle<String> source,
                                                  JSRegExp::Flags flags) {
  if (!IsEnabled()) {
    return Handle<FixedArray>::null();
  }

  Handle<FixedArray> result = Lookup(source, flags);
  if (result.is_null()) {
    Counters::compilation_cache_misses.Increment();
  } else {
    Counters::compilation_cache_hits.Increment();
  }
  return result;
}

void CompilationCache::PutScript(Handle<String> source,
                                 Handle<JSFunction> boilerplate) {
  if (!IsEnabled()) {
    return;
  }

  HandleScope scope;
  ASSERT(boilerplate->IsBoilerplate());
  Handle<CompilationCacheTable> table = GetTable(SCRIPT);
  CALL_HEAP_FUNCTION_VOID(table->Put(*source, *boilerplate));
}

void CompilationCache::PutEval(Handle<String> source,
                               Handle<Context> context,
                               Entry entry,
                               Handle<JSFunction> boilerplate) {
  if (!IsEnabled()) {
    return;
  }

  HandleScope scope;
  ASSERT(boilerplate->IsBoilerplate());
  Handle<CompilationCacheTable> table = GetTable(entry);
  CALL_HEAP_FUNCTION_VOID(table->PutEval(*source, *context, *boilerplate));
}

void CompilationCache::PutRegExp(Handle<String> source,
                                 JSRegExp::Flags flags,
                                 Handle<FixedArray> data) {
  if (!IsEnabled()) {
    return;
  }

  HandleScope scope;
  Handle<CompilationCacheTable> table = GetTable(REGEXP);
  CALL_HEAP_FUNCTION_VOID(table->PutRegExp(*source, flags, *data));
}

void CompilationCache::Clear() {
  for (int i = 0; i < NUMBER_OF_TABLE_ENTRIES; i++) {
    tables[i] = Heap::undefined_value();
  }
}

void CompilationCache::Iterate(ObjectVisitor* v) {
  v->VisitPointers(&tables[0], &tables[NUMBER_OF_TABLE_ENTRIES]);
}

void CompilationCache::MarkCompactPrologue() {
  ASSERT(LAST_ENTRY == SCRIPT);
  for (int i = NUMBER_OF_TABLE_ENTRIES - 1; i > SCRIPT; i--) {
    tables[i] = tables[i - 1];
  }
  for (int j = 0; j <= LAST_ENTRY; j++) {
    tables[j] = Heap::undefined_value();
  }
}

void CompilationCache::Enable() {
  enabled = true;
}

void CompilationCache::Disable() {
  enabled = false;
  Clear();
}

} }  // namespace v8::internal
<|endoftext|>


<commit_before>// Taken from llvm/Support/Casting.h

/*
==============================================================================
LLVM Release License
==============================================================================
University of Illinois/NCSA
Open Source License

Copyright (c) 2003-2012 University of Illinois at Urbana-Champaign.
All rights reserved.

Developed by:

    LLVM Team

    University of Illinois at Urbana-Champaign

    http://llvm.org

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal with
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:

    * Redistributions of source code must retain the above copyright notice,
      this list of conditions and the following disclaimers.

    * Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimers in the
      documentation and/or other materials provided with the distribution.

    * Neither the names of the LLVM Team, University of Illinois at
      Urbana-Champaign, nor the names of its contributors may be used to
      endorse or promote products derived from this Software without specific
      prior written permission.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
SOFTWARE.
*/

//===----------------------------------------------------------------------===//
//
// This file defines the isa<X>(), cast<X>(), dyn_cast<X>(), cast_or_null<X>(),
// and dyn_cast_or_null<X>() templates.
//
//===----------------------------------------------------------------------===//

#pragma once

#include <cassert>
#include <memory>

namespace JoeLang
{

//===----------------------------------------------------------------------===//
//                          isa<x> Support Templates
//===----------------------------------------------------------------------===//

// Define a template that can be specialized by smart pointers to reflect the
// fact that they are automatically dereferenced, and are not involved with the
// template selection process...  the default implementation is a noop.
//
template<typename From> struct simplify_type {
  typedef       From SimpleType;        // The real type this represents...

  // An accessor to get the real value...
  static SimpleType &getSimplifiedValue(From &Val) { return Val; }
};

template<typename From> struct simplify_type<const From> {
  typedef const From SimpleType;
  static SimpleType &getSimplifiedValue(const From &Val) {
    return simplify_type<From>::getSimplifiedValue(static_cast<From&>(Val));
  }
};

// Specialization for std::unique_ptr
template<typename T>
struct simplify_type<const std::unique_ptr<T> > {
    typedef const T* SimpleType;
    static SimpleType getSimplifiedValue( const std::unique_ptr<T> &Val) {
        return Val.get();
    }
};

template<typename T>
struct simplify_type<std::unique_ptr<T> >
        :public simplify_type<const std::unique_ptr<T> >
{
};

// The core of the implementation of isa<X> is here; To and From should be
// the names of classes.  This template can be specialized to customize the
// implementation of isa<> without rewriting it from scratch.
template <typename To, typename From>
struct isa_impl {
  static inline bool doit(const From &Val) {
    return To::classof(&Val);
  }
};

template <typename To, typename From> struct isa_impl_cl {
  static inline bool doit(const From &Val) {
    return isa_impl<To, From>::doit(Val);
  }
};

template <typename To, typename From> struct isa_impl_cl<To, const From> {
  static inline bool doit(const From &Val) {
    return isa_impl<To, From>::doit(Val);
  }
};

template <typename To, typename From> struct isa_impl_cl<To, From*> {
  static inline bool doit(const From *Val) {
    return isa_impl<To, From>::doit(*Val);
  }
};

template <typename To, typename From> struct isa_impl_cl<To, const From*> {
  static inline bool doit(const From *Val) {
    return isa_impl<To, From>::doit(*Val);
  }
};

template <typename To, typename From> struct isa_impl_cl<To, const From*const> {
  static inline bool doit(const From *Val) {
    return isa_impl<To, From>::doit(*Val);
  }
};

template<typename To, typename From, typename SimpleFrom>
struct isa_impl_wrap {
  // When From != SimplifiedType, we can simplify the type some more by using
  // the simplify_type template.
  static bool doit(const From &Val) {
    return isa_impl_wrap<To, SimpleFrom,
      typename simplify_type<SimpleFrom>::SimpleType>::doit(
                          simplify_type<From>::getSimplifiedValue(Val));
  }
};

template<typename To, typename FromTy>
struct isa_impl_wrap<To, FromTy, FromTy> {
  // When From == SimpleType, we are as simple as we are going to get.
  static bool doit(const FromTy &Val) {
    return isa_impl_cl<To,FromTy>::doit(Val);
  }
};

// isa<X> - Return true if the parameter to the template is an instance of the
// template type argument.  Used like this:
//
//  if (isa<Type>(myVal)) { ... }
//
template <class X, class Y>
inline bool isa(const Y &Val) {
  return isa_impl_wrap<X, Y, typename simplify_type<Y>::SimpleType>::doit(Val);
}

//===----------------------------------------------------------------------===//
//                          cast<x> Support Templates
//===----------------------------------------------------------------------===//

template<class To, class From> struct cast_retty;

// Calculate what type the 'cast' function should return, based on a requested
// type of To and a source type of From.
template<class To, class From> struct cast_retty_impl {
  typedef To& ret_type;         // Normal case, return Ty&
};
template<class To, class From> struct cast_retty_impl<To, const From> {
  typedef const To &ret_type;   // Normal case, return Ty&
};

template<class To, class From> struct cast_retty_impl<To, From*> {
  typedef To* ret_type;         // Pointer arg case, return Ty*
};

template<class To, class From> struct cast_retty_impl<To, const From*> {
  typedef const To* ret_type;   // Constant pointer arg case, return const Ty*
};

template<class To, class From> struct cast_retty_impl<To, const From*const> {
  typedef const To* ret_type;   // Constant pointer arg case, return const Ty*
};

template<class To, class From, class SimpleFrom>
struct cast_retty_wrap {
  // When the simplified type and the from type are not the same, use the type
  // simplifier to reduce the type, then reuse cast_retty_impl to get the
  // resultant type.
  typedef typename cast_retty<To, SimpleFrom>::ret_type ret_type;
};

template<class To, class FromTy>
struct cast_retty_wrap<To, FromTy, FromTy> {
  // When the simplified type is equal to the from type, use it directly.
  typedef typename cast_retty_impl<To,FromTy>::ret_type ret_type;
};

template<class To, class From>
struct cast_retty {
  typedef typename cast_retty_wrap<To, From,
                   typename simplify_type<From>::SimpleType>::ret_type ret_type;
};

// Ensure the non-simple values are converted using the simplify_type template
// that may be specialized by smart pointers...
//
template<class To, class From, class SimpleFrom> struct cast_convert_val {
  // This is not a simple type, use the template to simplify it...
  static typename cast_retty<To, From>::ret_type doit(const From &Val) {
    return cast_convert_val<To, SimpleFrom,
      typename simplify_type<SimpleFrom>::SimpleType>::doit(
                          simplify_type<From>::getSimplifiedValue(Val));
  }
};

template<class To, class FromTy> struct cast_convert_val<To,FromTy,FromTy> {
  // This _is_ a simple type, just cast it.
  static typename cast_retty<To, FromTy>::ret_type doit(const FromTy &Val) {
    typename cast_retty<To, FromTy>::ret_type Res2
     = (typename cast_retty<To, FromTy>::ret_type)const_cast<FromTy&>(Val);
    return Res2;
  }
};

// cast<X> - Return the argument parameter cast to the specified type.  This
// casting operator asserts that the type is correct, so it does not return null
// on failure.  It does not allow a null argument (use cast_or_null for that).
// It is typically used like this:
//
//  cast<Instruction>(myVal)->getParent()
//
template <class X, class Y>
inline typename cast_retty<X, Y>::ret_type cast(const Y &Val) {
  assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!");
  return cast_convert_val<X, Y,
                          typename simplify_type<Y>::SimpleType>::doit(Val);
}

// cast_or_null<X> - Functionally identical to cast, except that a null value is
// accepted.
//
template <class X, class Y>
inline typename cast_retty<X, Y*>::ret_type cast_or_null(Y *Val) {
  if (Val == 0) return 0;
  assert(isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!");
  return cast<X>(Val);
}

// dyn_cast<X> - Return the argument parameter cast to the specified type.  This
// casting operator returns null if the argument is of the wrong type, so it can
// be used to test for a type as well as cast if successful.  This should be
// used in the context of an if statement like this:
//
//  if (const Instruction *I = dyn_cast<Instruction>(myVal)) { ... }
//

template <class X, class Y>
inline typename cast_retty<X, Y>::ret_type dyn_cast(const Y &Val) {
  return isa<X>(Val) ? cast<X, Y>(Val) : 0;
}

// dyn_cast_or_null<X> - Functionally identical to dyn_cast, except that a null
// value is accepted.
//
template <class X, class Y>
inline typename cast_retty<X, Y*>::ret_type dyn_cast_or_null(Y *Val) {
  return (Val && isa<X>(Val)) ? cast<X>(Val) : 0;
}

} // namespace JoeLang
<commit_msg>[+] Added specialization for shared_ptr<commit_after>// Taken from llvm/Support/Casting.h

/*
==============================================================================
LLVM Release License
==============================================================================
University of Illinois/NCSA
Open Source License

Copyright (c) 2003-2012 University of Illinois at Urbana-Champaign.
All rights reserved.

Developed by:

    LLVM Team

    University of Illinois at Urbana-Champaign

    http://llvm.org

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal with
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:

    * Redistributions of source code must retain the above copyright notice,
      this list of conditions and the following disclaimers.

    * Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimers in the
      documentation and/or other materials provided with the distribution.

    * Neither the names of the LLVM Team, University of Illinois at
      Urbana-Champaign, nor the names of its contributors may be used to
      endorse or promote products derived from this Software without specific
      prior written permission.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
SOFTWARE.
*/

//===----------------------------------------------------------------------===//
//
// This file defines the isa<X>(), cast<X>(), dyn_cast<X>(), cast_or_null<X>(),
// and dyn_cast_or_null<X>() templates.
//
//===----------------------------------------------------------------------===//

#pragma once

#include <cassert>
#include <memory>

namespace JoeLang
{

//===----------------------------------------------------------------------===//
//                          isa<x> Support Templates
//===----------------------------------------------------------------------===//

// Define a template that can be specialized by smart pointers to reflect the
// fact that they are automatically dereferenced, and are not involved with the
// template selection process...  the default implementation is a noop.
//
template<typename From> struct simplify_type {
  typedef       From SimpleType;        // The real type this represents...

  // An accessor to get the real value...
  static SimpleType &getSimplifiedValue(From &Val) { return Val; }
};

template<typename From> struct simplify_type<const From> {
  typedef const From SimpleType;
  static SimpleType &getSimplifiedValue(const From &Val) {
    return simplify_type<From>::getSimplifiedValue(static_cast<From&>(Val));
  }
};

// Specialization for std::unique_ptr
template<typename T>
struct simplify_type<const std::unique_ptr<T> > {
    typedef const T* SimpleType;
    static SimpleType getSimplifiedValue( const std::unique_ptr<T> &Val) {
        return Val.get();
    }
};

template<typename T>
struct simplify_type<std::unique_ptr<T> >
        :public simplify_type<const std::unique_ptr<T> >
{
};

// Specialization for std::shared_ptr
template<typename T>
struct simplify_type<const std::shared_ptr<T> > {
    typedef const T* SimpleType;
    static SimpleType getSimplifiedValue( const std::shared_ptr<T> &Val) {
        return Val.get();
    }
};

template<typename T>
struct simplify_type<std::shared_ptr<T> >
        :public simplify_type<const std::shared_ptr<T> >
{
};

// The core of the implementation of isa<X> is here; To and From should be
// the names of classes.  This template can be specialized to customize the
// implementation of isa<> without rewriting it from scratch.
template <typename To, typename From>
struct isa_impl {
  static inline bool doit(const From &Val) {
    return To::classof(&Val);
  }
};

template <typename To, typename From> struct isa_impl_cl {
  static inline bool doit(const From &Val) {
    return isa_impl<To, From>::doit(Val);
  }
};

template <typename To, typename From> struct isa_impl_cl<To, const From> {
  static inline bool doit(const From &Val) {
    return isa_impl<To, From>::doit(Val);
  }
};

template <typename To, typename From> struct isa_impl_cl<To, From*> {
  static inline bool doit(const From *Val) {
    return isa_impl<To, From>::doit(*Val);
  }
};

template <typename To, typename From> struct isa_impl_cl<To, const From*> {
  static inline bool doit(const From *Val) {
    return isa_impl<To, From>::doit(*Val);
  }
};

template <typename To, typename From> struct isa_impl_cl<To, const From*const> {
  static inline bool doit(const From *Val) {
    return isa_impl<To, From>::doit(*Val);
  }
};

template<typename To, typename From, typename SimpleFrom>
struct isa_impl_wrap {
  // When From != SimplifiedType, we can simplify the type some more by using
  // the simplify_type template.
  static bool doit(const From &Val) {
    return isa_impl_wrap<To, SimpleFrom,
      typename simplify_type<SimpleFrom>::SimpleType>::doit(
                          simplify_type<From>::getSimplifiedValue(Val));
  }
};

template<typename To, typename FromTy>
struct isa_impl_wrap<To, FromTy, FromTy> {
  // When From == SimpleType, we are as simple as we are going to get.
  static bool doit(const FromTy &Val) {
    return isa_impl_cl<To,FromTy>::doit(Val);
  }
};

// isa<X> - Return true if the parameter to the template is an instance of the
// template type argument.  Used like this:
//
//  if (isa<Type>(myVal)) { ... }
//
template <class X, class Y>
inline bool isa(const Y &Val) {
  return isa_impl_wrap<X, Y, typename simplify_type<Y>::SimpleType>::doit(Val);
}

//===----------------------------------------------------------------------===//
//                          cast<x> Support Templates
//===----------------------------------------------------------------------===//

template<class To, class From> struct cast_retty;

// Calculate what type the 'cast' function should return, based on a requested
// type of To and a source type of From.
template<class To, class From> struct cast_retty_impl {
  typedef To& ret_type;         // Normal case, return Ty&
};
template<class To, class From> struct cast_retty_impl<To, const From> {
  typedef const To &ret_type;   // Normal case, return Ty&
};

template<class To, class From> struct cast_retty_impl<To, From*> {
  typedef To* ret_type;         // Pointer arg case, return Ty*
};

template<class To, class From> struct cast_retty_impl<To, const From*> {
  typedef const To* ret_type;   // Constant pointer arg case, return const Ty*
};

template<class To, class From> struct cast_retty_impl<To, const From*const> {
  typedef const To* ret_type;   // Constant pointer arg case, return const Ty*
};

template<class To, class From, class SimpleFrom>
struct cast_retty_wrap {
  // When the simplified type and the from type are not the same, use the type
  // simplifier to reduce the type, then reuse cast_retty_impl to get the
  // resultant type.
  typedef typename cast_retty<To, SimpleFrom>::ret_type ret_type;
};

template<class To, class FromTy>
struct cast_retty_wrap<To, FromTy, FromTy> {
  // When the simplified type is equal to the from type, use it directly.
  typedef typename cast_retty_impl<To,FromTy>::ret_type ret_type;
};

template<class To, class From>
struct cast_retty {
  typedef typename cast_retty_wrap<To, From,
                   typename simplify_type<From>::SimpleType>::ret_type ret_type;
};

// Ensure the non-simple values are converted using the simplify_type template
// that may be specialized by smart pointers...
//
template<class To, class From, class SimpleFrom> struct cast_convert_val {
  // This is not a simple type, use the template to simplify it...
  static typename cast_retty<To, From>::ret_type doit(const From &Val) {
    return cast_convert_val<To, SimpleFrom,
      typename simplify_type<SimpleFrom>::SimpleType>::doit(
                          simplify_type<From>::getSimplifiedValue(Val));
  }
};

template<class To, class FromTy> struct cast_convert_val<To,FromTy,FromTy> {
  // This _is_ a simple type, just cast it.
  static typename cast_retty<To, FromTy>::ret_type doit(const FromTy &Val) {
    typename cast_retty<To, FromTy>::ret_type Res2
     = (typename cast_retty<To, FromTy>::ret_type)const_cast<FromTy&>(Val);
    return Res2;
  }
};

// cast<X> - Return the argument parameter cast to the specified type.  This
// casting operator asserts that the type is correct, so it does not return null
// on failure.  It does not allow a null argument (use cast_or_null for that).
// It is typically used like this:
//
//  cast<Instruction>(myVal)->getParent()
//
template <class X, class Y>
inline typename cast_retty<X, Y>::ret_type cast(const Y &Val) {
  assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!");
  return cast_convert_val<X, Y,
                          typename simplify_type<Y>::SimpleType>::doit(Val);
}

// cast_or_null<X> - Functionally identical to cast, except that a null value is
// accepted.
//
template <class X, class Y>
inline typename cast_retty<X, Y*>::ret_type cast_or_null(Y *Val) {
  if (Val == 0) return 0;
  assert(isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!");
  return cast<X>(Val);
}

// dyn_cast<X> - Return the argument parameter cast to the specified type.  This
// casting operator returns null if the argument is of the wrong type, so it can
// be used to test for a type as well as cast if successful.  This should be
// used in the context of an if statement like this:
//
//  if (const Instruction *I = dyn_cast<Instruction>(myVal)) { ... }
//

template <class X, class Y>
inline typename cast_retty<X, Y>::ret_type dyn_cast(const Y &Val) {
  return isa<X>(Val) ? cast<X, Y>(Val) : 0;
}

// dyn_cast_or_null<X> - Functionally identical to dyn_cast, except that a null
// value is accepted.
//
template <class X, class Y>
inline typename cast_retty<X, Y*>::ret_type dyn_cast_or_null(Y *Val) {
  return (Val && isa<X>(Val)) ? cast<X>(Val) : 0;
}

} // namespace JoeLang
<|endoftext|>


<commit_before>//
// (c) Copyright 2017 DESY, ESS
//
// This file is part of h5cpp
//
// 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 ofMERCHANTABILITY
// 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 Street, Fifth Floor
// Boston, MA  02110-1301 USA
//
// ===========================================================================
//
// Created on: Feb 12, 2016
//     Author: Eugen Wintersberger <eugen.wintersberger@desy.de>
//
#pragma once

#ifdef _MSC_VER
	#ifdef DLL_BUILD
		#define DLL_EXPORT __declspec(dllexport)
	#else
		#define DLL_EXPORT __declspec(dllimport)
	#endif
#else
	#define DLL_EXPORT
#endif

#ifdef _MSC_VER
#include <BaseTsd.h>

using ssize_t = SSIZE_T;

#endif

<commit_msg>fixed ssize_t redefined [win32]<commit_after>//
// (c) Copyright 2017 DESY, ESS
//
// This file is part of h5cpp
//
// 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 ofMERCHANTABILITY
// 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 Street, Fifth Floor
// Boston, MA  02110-1301 USA
//
// ===========================================================================
//
// Created on: Feb 12, 2016
//     Author: Eugen Wintersberger <eugen.wintersberger@desy.de>
//
#pragma once

#ifdef _MSC_VER
	#ifdef DLL_BUILD
		#define DLL_EXPORT __declspec(dllexport)
	#else
		#define DLL_EXPORT __declspec(dllimport)
	#endif
#else
	#define DLL_EXPORT
#endif

#ifdef _MSC_VER
#if defined _M_IX86
    using ssize_t = int;
#elif defined _M_X64
    #include <BaseTsd.h>
    using ssize_t = SSIZE_T;
#endif
#endif

<|endoftext|>


<commit_before>#include <ros/ros.h>
#include <ros/subscriber.h>
#include <ros/publisher.h>
#include <sensor_msgs/PointCloud2.h>
#include <nav_msgs/Path.h>
#include <geometry_msgs/PoseStamped.h>
#include "GraphSearch.hpp"
#include "igvcsearchproblem.h"
#include <geometry_msgs/PoseStamped.h>
#include <tf/transform_datatypes.h>
#include <mutex>
#include <pcl_conversions/pcl_conversions.h>
#include <algorithm>
#include <igvc_msgs/action_path.h>

using namespace std;

ros::Publisher disp_path_pub;

ros::Publisher act_path_pub;

IGVCSearchProblem search_problem;

mutex planning_mutex;

void map_callback(const sensor_msgs::PointCloud2ConstPtr &msg)
{
    lock_guard<mutex> lock(planning_mutex);
    pcl::fromROSMsg(*msg, *search_problem.Map);
}

void position_callback(const geometry_msgs::PoseStampedConstPtr& msg)
{
    lock_guard<mutex> lock(planning_mutex);
    search_problem.Start.x = msg->pose.position.x;
    search_problem.Start.y = msg->pose.position.y;
    tf::Quaternion q;
    tf::quaternionMsgToTF(msg->pose.orientation, q);
    search_problem.Start.theta = tf::getYaw(q);
}

void waypoint_callback(const geometry_msgs::PointStampedConstPtr& msg)
{
    lock_guard<mutex> lock(planning_mutex);
    search_problem.Goal.x = msg->point.x;
    search_problem.Goal.y = msg->point.y;
}

int main(int argc, char** argv)
{
    ros::init(argc, argv, "pathplanner");

    ros::NodeHandle nh;

    ros::Subscriber map_sub = nh.subscribe("/map", 1, map_callback);

    ros::Subscriber pose_sub = nh.subscribe("/robot_pose_ekf/odom_combined", 1, position_callback);

    ros::Subscriber waypoint_sub = nh.subscribe("/waypoint", 1, waypoint_callback);

    disp_path_pub = nh.advertise<nav_msgs::Path>("/path_display", 1);

    act_path_pub = nh.advertise<igvc_msgs::action_path>("/path", 1);

    double baseline = 0.7275;

    search_problem.Map = pcl::PointCloud<pcl::PointXYZ>::Ptr(new pcl::PointCloud<pcl::PointXYZ>());
    search_problem.GoalThreshold = 1.0;
    search_problem.Threshold = 0.36375;
    search_problem.Speed = 0.25;
    search_problem.Baseline = baseline;
    search_problem.DeltaT = 0.25;

    ros::Rate rate(3);
    while(ros::ok())
    {
        ros::spinOnce();

        /* Do not attempt to plan a path if the path length would be greater than 100ft (~30m).
         * This should only happen when we have received either a waypoint or position estimate, but not both.
         * Long paths take forever to compute, and will freeze up this node.
         */
        if(search_problem.Start.distTo(search_problem.Goal) > 30)
            continue;

        planning_mutex.lock();
        // TODO only replan if needed.
        auto path = GraphSearch::AStar(search_problem);

        if(disp_path_pub.getNumSubscribers() > 0)
        {
            nav_msgs::Path disp_path_msg;
            disp_path_msg.header.stamp = ros::Time::now();
            disp_path_msg.header.frame_id = "map";
            for(auto loc : *(path.getStates()))
            {
                geometry_msgs::PoseStamped pose;
                pose.header.stamp = disp_path_msg.header.stamp;
                pose.header.frame_id = disp_path_msg.header.frame_id;
                pose.pose.position.x = loc.x;
                pose.pose.position.y = loc.y;
                disp_path_msg.poses.push_back(pose);
            }
            disp_path_pub.publish(disp_path_msg);

            igvc_msgs::action_path act_path_msg;
            act_path_msg.header.stamp = ros::Time::now();
            act_path_msg.header.frame_id = "map";
            for(auto action : *(path.getActions()))
            {
                igvc_msgs::velocity_pair vels;
                vels.header.stamp = act_path_msg.header.stamp;
                vels.header.frame_id = act_path_msg.header.frame_id;
                double radius = action.V / action.W;
                vels.left_velocity = (radius - baseline/2.) * action.W;
                vels.right_velocity = (radius + baseline/2.) * action.W;
                vels.duration = action.DeltaT;
                act_path_msg.actions.push_back(vels);
            }
            act_path_pub.publish(act_path_msg);
        }

        planning_mutex.unlock();

        rate.sleep();
    }

    return 0;
}
<commit_msg>Refactors pathplanner to use pcl::PointCloud<T> message types to match mapper published topics.<commit_after>#include <ros/ros.h>
#include <ros/subscriber.h>
#include <ros/publisher.h>
#include <nav_msgs/Path.h>
#include <geometry_msgs/PoseStamped.h>
#include "GraphSearch.hpp"
#include "igvcsearchproblem.h"
#include <geometry_msgs/PoseStamped.h>
#include <tf/transform_datatypes.h>
#include <mutex>
#include <algorithm>
#include <igvc_msgs/action_path.h>
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl_ros/point_cloud.h>

using namespace std;

ros::Publisher disp_path_pub;

ros::Publisher act_path_pub;

IGVCSearchProblem search_problem;

mutex planning_mutex;

void map_callback(const pcl::PointCloud<pcl::PointXYZ>::ConstPtr &msg)
{
    lock_guard<mutex> lock(planning_mutex);
    *search_problem.Map = *msg;
}

void position_callback(const geometry_msgs::PoseStampedConstPtr& msg)
{
    lock_guard<mutex> lock(planning_mutex);
    search_problem.Start.x = msg->pose.position.x;
    search_problem.Start.y = msg->pose.position.y;
    tf::Quaternion q;
    tf::quaternionMsgToTF(msg->pose.orientation, q);
    search_problem.Start.theta = tf::getYaw(q);
}

void waypoint_callback(const geometry_msgs::PointStampedConstPtr& msg)
{
    lock_guard<mutex> lock(planning_mutex);
    search_problem.Goal.x = msg->point.x;
    search_problem.Goal.y = msg->point.y;
}

int main(int argc, char** argv)
{
    ros::init(argc, argv, "pathplanner");

    ros::NodeHandle nh;

    ros::Subscriber map_sub = nh.subscribe("/map", 1, map_callback);

    ros::Subscriber pose_sub = nh.subscribe("/robot_pose_ekf/odom_combined", 1, position_callback);

    ros::Subscriber waypoint_sub = nh.subscribe("/waypoint", 1, waypoint_callback);

    disp_path_pub = nh.advertise<nav_msgs::Path>("/path_display", 1);

    act_path_pub = nh.advertise<igvc_msgs::action_path>("/path", 1);

    double baseline = 0.7275;

    search_problem.Map = pcl::PointCloud<pcl::PointXYZ>().makeShared();
    search_problem.GoalThreshold = 1.0;
    search_problem.Threshold = 0.36375;
    search_problem.Speed = 0.25;
    search_problem.Baseline = baseline;
    search_problem.DeltaT = 0.25;

    ros::Rate rate(3);
    while(ros::ok())
    {
        ros::spinOnce();

        /* Do not attempt to plan a path if the path length would be greater than 100ft (~30m).
         * This should only happen when we have received either a waypoint or position estimate, but not both.
         * Long paths take forever to compute, and will freeze up this node.
         */
        if(search_problem.Start.distTo(search_problem.Goal) > 30)
            continue;

        planning_mutex.lock();
        // TODO only replan if needed.
        auto path = GraphSearch::AStar(search_problem);

        if(disp_path_pub.getNumSubscribers() > 0)
        {
            nav_msgs::Path disp_path_msg;
            disp_path_msg.header.stamp = ros::Time::now();
            disp_path_msg.header.frame_id = "map";
            for(auto loc : *(path.getStates()))
            {
                geometry_msgs::PoseStamped pose;
                pose.header.stamp = disp_path_msg.header.stamp;
                pose.header.frame_id = disp_path_msg.header.frame_id;
                pose.pose.position.x = loc.x;
                pose.pose.position.y = loc.y;
                disp_path_msg.poses.push_back(pose);
            }
            disp_path_pub.publish(disp_path_msg);

            igvc_msgs::action_path act_path_msg;
            act_path_msg.header.stamp = ros::Time::now();
            act_path_msg.header.frame_id = "map";
            for(auto action : *(path.getActions()))
            {
                igvc_msgs::velocity_pair vels;
                vels.header.stamp = act_path_msg.header.stamp;
                vels.header.frame_id = act_path_msg.header.frame_id;
                double radius = action.V / action.W;
                vels.left_velocity = (radius - baseline/2.) * action.W;
                vels.right_velocity = (radius + baseline/2.) * action.W;
                vels.duration = action.DeltaT;
                act_path_msg.actions.push_back(vels);
            }
            act_path_pub.publish(act_path_msg);
        }

        planning_mutex.unlock();

        rate.sleep();
    }

    return 0;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: tabsh.hxx,v $
 *
 *  $Revision: 1.1.1.1 $
 *
 *  last change: $Author: hr $ $Date: 2000-09-18 17:14:42 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#ifndef _SWTABSH_HXX
#define _SWTABSH_HXX

#include "basesh.hxx"

class SwTableShell: public SwBaseShell
{
public:
    SFX_DECL_INTERFACE(SW_TABSHELL);
    TYPEINFO();

    void    Execute(SfxRequest &);
    void    GetState(SfxItemSet &);
    void    GetFrmBorderState(SfxItemSet &rSet);
    void    GetLineStyleState(SfxItemSet &rSet);
    void    ExecTableStyle(SfxRequest& rReq);

    void    ExecNumberFormat(SfxRequest& rReq);

            SwTableShell(SwView &rView);
};

#endif
<commit_msg>INTEGRATION: CWS tune03 (1.1.1.1.788); FILE MERGED 2004/07/19 19:11:31 mhu 1.1.1.1.788.1: #i29979# Added SW_DLLPUBLIC/PRIVATE (see swdllapi.h) to exported symbols/classes.<commit_after>/*************************************************************************
 *
 *  $RCSfile: tabsh.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: rt $ $Date: 2004-08-23 09:02:44 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#ifndef _SWTABSH_HXX
#define _SWTABSH_HXX

#ifndef _SWBASESH_HXX
#include "basesh.hxx"
#endif

#ifndef INCLUDED_SWDLLAPI_H
#include "swdllapi.h"
#endif

class SfxItemSet;
class SwWrtShell;

SW_DLLPUBLIC void ItemSetToTableParam( const SfxItemSet& rSet, SwWrtShell &rSh );

extern const USHORT __FAR_DATA aUITableAttrRange[];
SW_DLLPUBLIC const USHORT* SwuiGetUITableAttrRange();

class SwTableShell: public SwBaseShell
{
public:
    SFX_DECL_INTERFACE(SW_TABSHELL);
    TYPEINFO();

    void    Execute(SfxRequest &);
    void    GetState(SfxItemSet &);
    void    GetFrmBorderState(SfxItemSet &rSet);
    void    GetLineStyleState(SfxItemSet &rSet);
    void    ExecTableStyle(SfxRequest& rReq);

    void    ExecNumberFormat(SfxRequest& rReq);

            SwTableShell(SwView &rView);
};

#endif
<|endoftext|>


<commit_before>#include <iostream>
#include <chrono>
#include <random>
#include <algorithm>
#include <iterator>
#include <vector>

template <typename T>
void print(std::vector<T> v)
{
    for (auto && e : v) {
        std::cout << e << ",";
    }
    std::cout << std::endl;
}

static inline double wtime(void)
{
    using t = std::chrono::high_resolution_clock;
    auto c = t::now().time_since_epoch().count();
    auto n = t::period::num;
    auto d = t::period::den;
    double r = static_cast<double>(c)/static_cast<double>(d)*static_cast<double>(n);
    return r;
}

int main(int argc, char* argv[])
{
    size_t n = (argc > 1) ? std::atol(argv[1]) : 100;
    std::cout << "bogosort of " << n << " elements" << std::endl;

    std::vector<size_t> v(n,0);
    std::iota(v.begin(), v.end(),0);
    {
        std::random_device rd;
        std::mt19937 g(rd());
        std::shuffle(v.begin(), v.end(), g);
    }
    std::cout << "Before:\n";
    print(v);

    {
        std::random_device rd;
        std::mt19937 g(rd());

        // warmup
        std::shuffle(v.begin(), v.end(), g);

        size_t i{0};
        double t0 = wtime();
        while ( !std::is_sorted(v.begin(), v.end()) ) {
            std::cout << "Iteration " << i << "\n";
            std::shuffle(v.begin(), v.end(), g);
            i++;
        }
        double t1 = wtime();
        std::cout << "Time: " << t1-t0 << std::endl;
    }

    return 0;
}
<commit_msg>10 is enough<commit_after>#include <iostream>
#include <chrono>
#include <random>
#include <algorithm>
#include <iterator>
#include <vector>

template <typename T>
void print(std::vector<T> v)
{
    for (auto && e : v) {
        std::cout << e << ",";
    }
    std::cout << std::endl;
}

static inline double wtime(void)
{
    using t = std::chrono::high_resolution_clock;
    auto c = t::now().time_since_epoch().count();
    auto n = t::period::num;
    auto d = t::period::den;
    double r = static_cast<double>(c)/static_cast<double>(d)*static_cast<double>(n);
    return r;
}

int main(int argc, char* argv[])
{
    size_t n = (argc > 1) ? std::atol(argv[1]) : 10;
    std::cout << "bogosort of " << n << " elements" << std::endl;

    std::vector<size_t> v(n,0);
    std::iota(v.begin(), v.end(),0);
    {
        std::random_device rd;
        std::mt19937 g(rd());
        std::shuffle(v.begin(), v.end(), g);
    }
    std::cout << "Before:\n";
    print(v);

    {
        std::random_device rd;
        std::mt19937 g(rd());

        // warmup
        std::shuffle(v.begin(), v.end(), g);

        size_t i{0};
        double t0 = wtime();
        while ( !std::is_sorted(v.begin(), v.end()) ) {
            std::cout << "Iteration " << i << "\n";
            std::shuffle(v.begin(), v.end(), g);
            i++;
        }
        double t1 = wtime();
        std::cout << "Time: " << t1-t0 << std::endl;
    }

    return 0;
}
<|endoftext|>


<commit_before>#include "HelloWorldScene.h"
#include "SimpleAudioEngine.h"
#include "Enemy.h"

using namespace cocos2d;
using namespace CocosDenshion;

#define HERO1_RECT       CCRectMake(0, 99, 102, 126)
#define HERO2_RECT       CCRectMake(165, 360, 102, 126)
#define ENEMY1_RECT     CCRectMake(534, 612, 57, 43)
#define BULLET_RECT     CCRectMake(1004, 987, 9, 21)

CCScene* HelloWorld::scene()
{
    // 'scene' is an autorelease object
    CCScene *scene = CCScene::create();

    // 'layer' is an autorelease object
    HelloWorld *layer = HelloWorld::create();

    // add layer as a child to scene
    scene->addChild(layer);

    // return the scene
    return scene;
}

// on "init" you need to initialize your instance
bool HelloWorld::init()
{
    //////////////////////////////
    // 1. super init first
    if ( !CCLayerColor::initWithColor( ccc4(255,255,255,255) ) )
    {
        return false;
    }

    // enable touch
    this->setTouchEnabled(true); //this->setIsTouchEnabled(true);

    CCSize winSize = CCDirector::sharedDirector()->getWinSize();
    this->player = CCSprite::create("shoot.png", HERO1_RECT );
    this->player->setPosition( ccp(winSize.width/2, this->player->getContentSize().height/2) );
    this->addChild(this->player);

    this->playerAnimation = CCAnimation::create();
    CCSpriteFrame *sframe = CCSpriteFrame::create("shoot.png", HERO2_RECT);
    this->playerAnimation->addSpriteFrame(sframe);
    CCSpriteFrame *sframe2 = CCSpriteFrame::create("shoot.png", HERO1_RECT);
    this->playerAnimation->addSpriteFrame(sframe2);
    this->playerAnimation->setDelayPerUnit(0.1);
    CCAnimate *animate = CCAnimate::create(this->playerAnimation);
    player->runAction(CCRepeatForever::create(animate));

    this->schedule( schedule_selector(HelloWorld::addEnemies), 1.0 );
    this->schedule( schedule_selector(HelloWorld::fireBullets), 1.0/7.0 );
    this->schedule( schedule_selector(HelloWorld::update) );

    _enemies = new CCArray;
    _bullets = new CCArray;

    return true;
}

HelloWorld::HelloWorld():_enemies(NULL),_bullets(NULL)
{
}

HelloWorld::~HelloWorld()
{
    if (_enemies)
    {
        _enemies->release();
        _enemies = NULL;
    }

    if (_bullets)
    {
        _bullets->release();
        _bullets = NULL;
    }

    // cpp don't need to call super dealloc
    // virtual destructor will do this
}

//
// enemy
//

void HelloWorld::addEnemies(float dt)
{
    this->addEnemy();
}

void HelloWorld::addEnemy()
{
//    CCSprite *enemy = CCSprite::create("shoot.png", ENEMY1_RECT);
    Enemy *enemy = new Enemy(1);

    // Determine where to spawn the target along the X axis
    CCSize winSize = CCDirector::sharedDirector()->getWinSize();
    int minX = enemy->getContentSize().width/2;
    int maxX = winSize.width - enemy->getContentSize().width/2;
    int rangeX = maxX - minX;
    // srand( TimGetTicks() );
    int actualX = ( rand() % rangeX ) + minX;

    // Create the target slightly off-screen along the top edge,
    // and along a random position along the X axis as calculated
    enemy->setPosition( ccp(actualX, winSize.height + enemy->getContentSize().height/2) );
    this->addChild(enemy);

    // Determine speed of the target
    int minDuration = (int)3.0;
    int maxDuration = (int)6.0;
    int rangeDuration = maxDuration - minDuration;
    // srand( TimGetTicks() );
    int actualDuration = ( rand() % rangeDuration ) + minDuration;

    // Create the actions
    CCFiniteTimeAction* actionMove = CCMoveTo::create((float)actualDuration,
                                                      ccp( actualX, 0 - enemy->getContentSize().height/2) );
    CCFiniteTimeAction* actionMoveDone = CCCallFuncN::create(this,
                                                             callfuncN_selector(HelloWorld::removeEnemy));
    enemy->runAction( CCSequence::create(actionMove, actionMoveDone, NULL) );

    enemy->setTag(1);
    _enemies->addObject(enemy);
}

void HelloWorld::removeEnemy(CCNode *sender)
{
    CCSprite *sprite = dynamic_cast<CCSprite*>(sender);
    //    enemy->getSprite()->stopAllActions();
    //    this->removeChild(enemy->getSprite(), true);
    sprite->removeFromParentAndCleanup(true);
//    _enemies->removeObject(enemy);
#warning this must remove from array
}

//
// bullets
//

void HelloWorld::fireBullets(float dt)
{
    this->fireBullet();
}

void HelloWorld::fireBullet()
{
    CCSprite *bullet = CCSprite::create("shoot.png", BULLET_RECT);

    CCSize winSize = CCDirector::sharedDirector()->getWinSize();

    CCPoint playerLocation = player->getPosition();
    bullet->setPosition(CCPoint(playerLocation.x, playerLocation.y + player->getContentSize().height/2));
    this->addChild(bullet);

    // Create the actions
    CCFiniteTimeAction* actionMove = CCMoveTo::create(1.0f,
                                                      ccp( bullet->getPosition().x, bullet->getPosition().y + winSize.height*3/4) );
    CCFiniteTimeAction* actionMoveDone = CCCallFuncN::create(this,
                                                             callfuncN_selector(HelloWorld::bulletMoveFinished));
    bullet->runAction( CCSequence::create(actionMove, actionMoveDone, NULL) );

    bullet->setTag(2);
    _bullets->addObject(bullet);
}

void HelloWorld::bulletMoveFinished(CCNode* sender)
{
    CCSprite *sprite = (CCSprite *)sender;
    this->removeChild(sprite, true);
    _bullets->removeObject(sprite);
}

//
// hero
//

void HelloWorld::ccTouchesBegan(CCSet *touches, CCEvent *pEvent)
{
    CCTouch* touch = (CCTouch*)( touches->anyObject() );
    CCPoint location = touch->getLocationInView();
    location = CCDirector::sharedDirector()->convertToGL(location);
    CCPoint playerLocation = player->getPosition();

    this->touchOffset = CCPoint(playerLocation.x - location.x,
                                playerLocation.y - location.y);
}

void HelloWorld::ccTouchesMoved(CCSet *touches, CCEvent* event)
{
    CCTouch* touch = (CCTouch*)( touches->anyObject() );
    CCPoint location = touch->getLocationInView();
    location = CCDirector::sharedDirector()->convertToGL(location);

    CCSize winSize = CCDirector::sharedDirector()->getWinSize();
    CCSize playerSize = player->getContentSize();

    float newX = location.x + this->touchOffset.x;
    newX = newX < playerSize.width/2 ? playerSize.width/2 : newX;
    newX = newX > winSize.width - playerSize.width/2 ? winSize.width - playerSize.width/2 : newX;

    float newY = location.y + this->touchOffset.y;
    newY = newY < playerSize.height/2 ? playerSize.height/2 : newY;
    newY = newY > winSize.height - playerSize.height/2 ? winSize.height - playerSize.height/2 : newY;

    this->player->setPosition(CCPoint(newX, newY));
}

void HelloWorld::update(float dt)
{
    CCArray *bulletsToDelete = new CCArray;
    CCArray* enemiesToDelete =new CCArray;
    CCObject* it = NULL;
    CCObject* jt = NULL;

    CCARRAY_FOREACH(_bullets, it)
    {
        CCSprite *bullet = dynamic_cast<CCSprite*>(it);
        CCRect bulletRect = CCRectMake(bullet->getPosition().x - (bullet->getContentSize().width/2),
                                       bullet->getPosition().y - (bullet->getContentSize().height/2),
                                       bullet->getContentSize().width,
                                       bullet->getContentSize().height);

        CCARRAY_FOREACH(_enemies, jt)
        {
            Enemy *enemy = dynamic_cast<Enemy*>(jt);

            if (!enemy) {
                continue;
            }
            if (enemy->getCurrentStatus() == ENEMY_STATUS_DESTROYING) {
                continue;
            }

            CCRect enemyRect = CCRectMake(enemy->getPosition().x - (enemy->getContentSize().width/2),
                                          enemy->getPosition().y - (enemy->getContentSize().height/2),
                                          enemy->getContentSize().width,
                                          enemy->getContentSize().height);

            if (bulletRect.intersectsRect(enemyRect))
            {
                bulletsToDelete->addObject(bullet);
                if (enemy->minusHP() <= 0) {
                    enemiesToDelete->addObject(enemy);
                }
            }
        }
    }

    CCARRAY_FOREACH(enemiesToDelete, jt)
    {
        Enemy *enemy = dynamic_cast<Enemy*>(jt);
        enemy->stopAllActions();

        CCAnimate *animAction = enemy->destroyAnimation();
        CCCallFuncN *callFunc = CCCallFuncN::create(this, callfuncN_selector(HelloWorld::removeEnemy));
        enemy->runAction(CCSequence::create(animAction, callFunc, NULL));
    }

    CCARRAY_FOREACH(bulletsToDelete, it)
    {
        CCSprite* bullet = dynamic_cast<CCSprite*>(it);
        _bullets->removeObject(bullet);
        this->removeChild(bullet, true);
    }

    bulletsToDelete->release();
    enemiesToDelete->release();
}

<commit_msg>remove it enemy from array<commit_after>#include "HelloWorldScene.h"
#include "SimpleAudioEngine.h"
#include "Enemy.h"

using namespace cocos2d;
using namespace CocosDenshion;

#define HERO1_RECT       CCRectMake(0, 99, 102, 126)
#define HERO2_RECT       CCRectMake(165, 360, 102, 126)
#define ENEMY1_RECT     CCRectMake(534, 612, 57, 43)
#define BULLET_RECT     CCRectMake(1004, 987, 9, 21)

CCScene* HelloWorld::scene()
{
    // 'scene' is an autorelease object
    CCScene *scene = CCScene::create();

    // 'layer' is an autorelease object
    HelloWorld *layer = HelloWorld::create();

    // add layer as a child to scene
    scene->addChild(layer);

    // return the scene
    return scene;
}

// on "init" you need to initialize your instance
bool HelloWorld::init()
{
    //////////////////////////////
    // 1. super init first
    if ( !CCLayerColor::initWithColor( ccc4(255,255,255,255) ) )
    {
        return false;
    }

    // enable touch
    this->setTouchEnabled(true); //this->setIsTouchEnabled(true);

    CCSize winSize = CCDirector::sharedDirector()->getWinSize();
    this->player = CCSprite::create("shoot.png", HERO1_RECT );
    this->player->setPosition( ccp(winSize.width/2, this->player->getContentSize().height/2) );
    this->addChild(this->player);

    this->playerAnimation = CCAnimation::create();
    CCSpriteFrame *sframe = CCSpriteFrame::create("shoot.png", HERO2_RECT);
    this->playerAnimation->addSpriteFrame(sframe);
    CCSpriteFrame *sframe2 = CCSpriteFrame::create("shoot.png", HERO1_RECT);
    this->playerAnimation->addSpriteFrame(sframe2);
    this->playerAnimation->setDelayPerUnit(0.1);
    CCAnimate *animate = CCAnimate::create(this->playerAnimation);
    player->runAction(CCRepeatForever::create(animate));

    this->schedule( schedule_selector(HelloWorld::addEnemies), 1.0 );
    this->schedule( schedule_selector(HelloWorld::fireBullets), 1.0/7.0 );
    this->schedule( schedule_selector(HelloWorld::update) );

    _enemies = new CCArray;
    _bullets = new CCArray;

    return true;
}

HelloWorld::HelloWorld():_enemies(NULL),_bullets(NULL)
{
}

HelloWorld::~HelloWorld()
{
    if (_enemies)
    {
        _enemies->release();
        _enemies = NULL;
    }

    if (_bullets)
    {
        _bullets->release();
        _bullets = NULL;
    }

    // cpp don't need to call super dealloc
    // virtual destructor will do this
}

//
// enemy
//

void HelloWorld::addEnemies(float dt)
{
    this->addEnemy();
}

void HelloWorld::addEnemy()
{
//    CCSprite *enemy = CCSprite::create("shoot.png", ENEMY1_RECT);
    Enemy *enemy = new Enemy(1);

    // Determine where to spawn the target along the X axis
    CCSize winSize = CCDirector::sharedDirector()->getWinSize();
    int minX = enemy->getContentSize().width/2;
    int maxX = winSize.width - enemy->getContentSize().width/2;
    int rangeX = maxX - minX;
    // srand( TimGetTicks() );
    int actualX = ( rand() % rangeX ) + minX;

    // Create the target slightly off-screen along the top edge,
    // and along a random position along the X axis as calculated
    enemy->setPosition( ccp(actualX, winSize.height + enemy->getContentSize().height/2) );
    this->addChild(enemy);

    // Determine speed of the target
    int minDuration = (int)3.0;
    int maxDuration = (int)6.0;
    int rangeDuration = maxDuration - minDuration;
    // srand( TimGetTicks() );
    int actualDuration = ( rand() % rangeDuration ) + minDuration;

    // Create the actions
    CCFiniteTimeAction* actionMove = CCMoveTo::create((float)actualDuration,
                                                      ccp( actualX, 0 - enemy->getContentSize().height/2) );
    CCFiniteTimeAction* actionMoveDone = CCCallFuncN::create(this,
                                                             callfuncN_selector(HelloWorld::removeEnemy));
    enemy->runAction( CCSequence::create(actionMove, actionMoveDone, NULL) );

    enemy->setTag(1);
    _enemies->addObject(enemy);
}

void HelloWorld::removeEnemy(CCNode *sender)
{
    CCSprite *sprite = dynamic_cast<CCSprite*>(sender);
    //    enemy->getSprite()->stopAllActions();
    //    this->removeChild(enemy->getSprite(), true);
    sprite->removeFromParentAndCleanup(true);
    _enemies->removeObject(sprite);
}

//
// bullets
//

void HelloWorld::fireBullets(float dt)
{
    this->fireBullet();
}

void HelloWorld::fireBullet()
{
    CCSprite *bullet = CCSprite::create("shoot.png", BULLET_RECT);

    CCSize winSize = CCDirector::sharedDirector()->getWinSize();

    CCPoint playerLocation = player->getPosition();
    bullet->setPosition(CCPoint(playerLocation.x, playerLocation.y + player->getContentSize().height/2));
    this->addChild(bullet);

    // Create the actions
    CCFiniteTimeAction* actionMove = CCMoveTo::create(1.0f,
                                                      ccp( bullet->getPosition().x, bullet->getPosition().y + winSize.height*3/4) );
    CCFiniteTimeAction* actionMoveDone = CCCallFuncN::create(this,
                                                             callfuncN_selector(HelloWorld::bulletMoveFinished));
    bullet->runAction( CCSequence::create(actionMove, actionMoveDone, NULL) );

    bullet->setTag(2);
    _bullets->addObject(bullet);
}

void HelloWorld::bulletMoveFinished(CCNode* sender)
{
    CCSprite *sprite = (CCSprite *)sender;
    this->removeChild(sprite, true);
    _bullets->removeObject(sprite);
}

//
// hero
//

void HelloWorld::ccTouchesBegan(CCSet *touches, CCEvent *pEvent)
{
    CCTouch* touch = (CCTouch*)( touches->anyObject() );
    CCPoint location = touch->getLocationInView();
    location = CCDirector::sharedDirector()->convertToGL(location);
    CCPoint playerLocation = player->getPosition();

    this->touchOffset = CCPoint(playerLocation.x - location.x,
                                playerLocation.y - location.y);
}

void HelloWorld::ccTouchesMoved(CCSet *touches, CCEvent* event)
{
    CCTouch* touch = (CCTouch*)( touches->anyObject() );
    CCPoint location = touch->getLocationInView();
    location = CCDirector::sharedDirector()->convertToGL(location);

    CCSize winSize = CCDirector::sharedDirector()->getWinSize();
    CCSize playerSize = player->getContentSize();

    float newX = location.x + this->touchOffset.x;
    newX = newX < playerSize.width/2 ? playerSize.width/2 : newX;
    newX = newX > winSize.width - playerSize.width/2 ? winSize.width - playerSize.width/2 : newX;

    float newY = location.y + this->touchOffset.y;
    newY = newY < playerSize.height/2 ? playerSize.height/2 : newY;
    newY = newY > winSize.height - playerSize.height/2 ? winSize.height - playerSize.height/2 : newY;

    this->player->setPosition(CCPoint(newX, newY));
}

void HelloWorld::update(float dt)
{
    CCArray *bulletsToDelete = new CCArray;
    CCArray* enemiesToDelete =new CCArray;
    CCObject* it = NULL;
    CCObject* jt = NULL;

    CCARRAY_FOREACH(_bullets, it)
    {
        CCSprite *bullet = dynamic_cast<CCSprite*>(it);
        CCRect bulletRect = CCRectMake(bullet->getPosition().x - (bullet->getContentSize().width/2),
                                       bullet->getPosition().y - (bullet->getContentSize().height/2),
                                       bullet->getContentSize().width,
                                       bullet->getContentSize().height);

        CCARRAY_FOREACH(_enemies, jt)
        {
            Enemy *enemy = dynamic_cast<Enemy*>(jt);

            if (!enemy) {
                continue;
            }
            if (enemy->getCurrentStatus() == ENEMY_STATUS_DESTROYING) {
                continue;
            }

            CCRect enemyRect = CCRectMake(enemy->getPosition().x - (enemy->getContentSize().width/2),
                                          enemy->getPosition().y - (enemy->getContentSize().height/2),
                                          enemy->getContentSize().width,
                                          enemy->getContentSize().height);

            if (bulletRect.intersectsRect(enemyRect))
            {
                bulletsToDelete->addObject(bullet);
                if (enemy->minusHP() <= 0) {
                    enemiesToDelete->addObject(enemy);
                }
            }
        }
    }

    CCARRAY_FOREACH(enemiesToDelete, jt)
    {
        Enemy *enemy = dynamic_cast<Enemy*>(jt);
        enemy->stopAllActions();

        CCAnimate *animAction = enemy->destroyAnimation();
        CCCallFuncN *callFunc = CCCallFuncN::create(this, callfuncN_selector(HelloWorld::removeEnemy));
        enemy->runAction(CCSequence::create(animAction, callFunc, NULL));
    }

    CCARRAY_FOREACH(bulletsToDelete, it)
    {
        CCSprite* bullet = dynamic_cast<CCSprite*>(it);
        _bullets->removeObject(bullet);
        this->removeChild(bullet, true);
    }

    bulletsToDelete->release();
    enemiesToDelete->release();
}

<|endoftext|>


<commit_before>#include <iostream>
#include <algorithm>
#include <functional>
#include <array>
#include <vector>
#include <set>
#include <functional>
#include <boost/range/algorithm.hpp>

template <typename T>
struct Inserter
{
    using Type = T;
    using OutputIterator = typename T::iterator;
    OutputIterator operator()(Type& cont) { return cont.begin(); }
    size_t dist(const Type& cont, OutputIterator it)
    {
        return std::distance(cont.begin(), it);
    }
};

template <typename T, typename... Rest>
struct Inserter<std::vector<T, Rest...>>
{
    using Type = std::vector<T, Rest...>;
    using OutputIterator = std::back_insert_iterator<Type>;
    OutputIterator operator()(Type& cont) { return std::back_inserter(cont); }
    size_t dist(const Type& cont, OutputIterator)
    {
        return cont.size();
    }
};

template <typename T>
typename Inserter<T>::OutputIterator append(T& cont)
{
    Inserter<T> inserter;
    return inserter(cont);
}

template <typename T>
size_t dist(const T& cont, typename Inserter<T>::OutputIterator it)
{
    Inserter<T> inserter;
    return inserter.dist(cont, it);
}

template <typename RetCont, typename AIterator, typename BIterator, typename SetOp>
int setOpIndices(RetCont& result,
                 AIterator contAbegin, AIterator contAend,
                 BIterator contBbegin, BIterator contBend,
                 SetOp setOp)
{
  RetCont contAcopy, contBcopy;
  std::copy(contAbegin, contAend, append(contAcopy));
  std::copy(contBbegin, contBend, append(contBcopy));
  boost::sort(contAcopy);
  boost::sort(contBcopy);
  auto initialPosition = append(result);
  auto pos = setOp(contAcopy, contBcopy, append(result));
  return dist(result, pos);
}

template <typename RetCont, typename AIterator, typename BIterator,
          typename OutputIterator = typename RetCont::iterator>
int diffIndices(RetCont& result,
                AIterator contAbegin, AIterator contAend,
                BIterator contBbegin, BIterator contBend)
{
  return setOpIndices(result, contAbegin, contAend, contBbegin, contBend,
    boost::set_difference<RetCont, RetCont, OutputIterator>);
}

template <typename RetCont, typename AIterator, typename BIterator,
          typename OutputIterator = typename RetCont::iterator>
int intersectIndices(RetCont& result,
                     AIterator contAbegin, AIterator contAend,
                     BIterator contBbegin, BIterator contBend)
{
  return setOpIndices(result, contAbegin, contAend, contBbegin, contBend,
    boost::set_intersection<RetCont, RetCont, OutputIterator>);
}

// range-based syntax sugar BEWARE uses std::back_inserter
template <typename RetCont, typename ARange, typename BRange>
int diffIndicesRange(RetCont& result, const ARange& acont, const BRange& bcont)
{
  return diffIndices<RetCont, typename ARange::const_iterator, typename BRange::const_iterator,
                     std::back_insert_iterator<RetCont>>
    (result, begin(acont), end(acont), begin(bcont), end(bcont));
}

template <typename RetCont, typename ARange, typename BRange>
int intersectIndicesRange(RetCont& result, const ARange& acont, const BRange& bcont)
{
  return intersectIndices<RetCont, typename ARange::const_iterator, typename BRange::const_iterator,
                          std::back_insert_iterator<RetCont>>
    (result, begin(acont), end(acont), begin(bcont), end(bcont));
}

int main()
{
    std::array<double, 3> arr{1,2,3}, crr{17,18,19};
    std::vector<double> brr{7,8,9};
    std::copy(std::begin(brr), std::end(brr), append(arr));
    std::cout << "arr[0] : " << arr[0] << " arr[1] : " << arr[1] << " arr[2] : " << arr[2] << " arr.size() : " << arr.size() << std::endl;
    std::copy(std::begin(crr), std::end(crr), append(brr));
    std::cout << "brr[3] : " << brr[3] << " brr[1] : " << brr[1] << " brr[2] : " << brr[2] << " brr.size() : " << brr.size() << std::endl;
    std::vector<int> xxx{7,18}, ddd;
    size_t size = diffIndicesRange(ddd, brr, xxx);
    std::cout << "size : " << size << std::endl;
    std::cout << "ddd : {";
    for (auto e : ddd) {
        std::cout << e << ", ";
    }
    std::cout << "}\n";
}

<commit_msg>added MIT License to specialization sample<commit_after>// The MIT License (MIT)
//
// Copyright (c) 2019 Alexander Samoilov
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE

#include <iostream>
#include <algorithm>
#include <functional>
#include <array>
#include <vector>
#include <set>
#include <functional>
#include <boost/range/algorithm.hpp>

template <typename T>
struct Inserter
{
    using Type = T;
    using OutputIterator = typename T::iterator;
    OutputIterator operator()(Type& cont) { return cont.begin(); }
    size_t dist(const Type& cont, OutputIterator it)
    {
        return std::distance(cont.begin(), it);
    }
};

template <typename T, typename... Rest>
struct Inserter<std::vector<T, Rest...>>
{
    using Type = std::vector<T, Rest...>;
    using OutputIterator = std::back_insert_iterator<Type>;
    OutputIterator operator()(Type& cont) { return std::back_inserter(cont); }
    size_t dist(const Type& cont, OutputIterator)
    {
        return cont.size();
    }
};

template <typename T>
typename Inserter<T>::OutputIterator append(T& cont)
{
    Inserter<T> inserter;
    return inserter(cont);
}

template <typename T>
size_t dist(const T& cont, typename Inserter<T>::OutputIterator it)
{
    Inserter<T> inserter;
    return inserter.dist(cont, it);
}

template <typename RetCont, typename AIterator, typename BIterator, typename SetOp>
int setOpIndices(RetCont& result,
                 AIterator contAbegin, AIterator contAend,
                 BIterator contBbegin, BIterator contBend,
                 SetOp setOp)
{
  RetCont contAcopy, contBcopy;
  std::copy(contAbegin, contAend, append(contAcopy));
  std::copy(contBbegin, contBend, append(contBcopy));
  boost::sort(contAcopy);
  boost::sort(contBcopy);
  auto initialPosition = append(result);
  auto pos = setOp(contAcopy, contBcopy, append(result));
  return dist(result, pos);
}

template <typename RetCont, typename AIterator, typename BIterator,
          typename OutputIterator = typename RetCont::iterator>
int diffIndices(RetCont& result,
                AIterator contAbegin, AIterator contAend,
                BIterator contBbegin, BIterator contBend)
{
  return setOpIndices(result, contAbegin, contAend, contBbegin, contBend,
    boost::set_difference<RetCont, RetCont, OutputIterator>);
}

template <typename RetCont, typename AIterator, typename BIterator,
          typename OutputIterator = typename RetCont::iterator>
int intersectIndices(RetCont& result,
                     AIterator contAbegin, AIterator contAend,
                     BIterator contBbegin, BIterator contBend)
{
  return setOpIndices(result, contAbegin, contAend, contBbegin, contBend,
    boost::set_intersection<RetCont, RetCont, OutputIterator>);
}

// range-based syntax sugar BEWARE uses std::back_inserter
template <typename RetCont, typename ARange, typename BRange>
int diffIndicesRange(RetCont& result, const ARange& acont, const BRange& bcont)
{
  return diffIndices<RetCont, typename ARange::const_iterator, typename BRange::const_iterator,
                     std::back_insert_iterator<RetCont>>
    (result, begin(acont), end(acont), begin(bcont), end(bcont));
}

template <typename RetCont, typename ARange, typename BRange>
int intersectIndicesRange(RetCont& result, const ARange& acont, const BRange& bcont)
{
  return intersectIndices<RetCont, typename ARange::const_iterator, typename BRange::const_iterator,
                          std::back_insert_iterator<RetCont>>
    (result, begin(acont), end(acont), begin(bcont), end(bcont));
}

int main()
{
    std::array<double, 3> arr{1,2,3}, crr{17,18,19};
    std::vector<double> brr{7,8,9};
    std::copy(std::begin(brr), std::end(brr), append(arr));
    std::cout << "arr[0] : " << arr[0] << " arr[1] : " << arr[1] << " arr[2] : " << arr[2] << " arr.size() : " << arr.size() << std::endl;
    std::copy(std::begin(crr), std::end(crr), append(brr));
    std::cout << "brr[3] : " << brr[3] << " brr[1] : " << brr[1] << " brr[2] : " << brr[2] << " brr.size() : " << brr.size() << std::endl;
    std::vector<int> xxx{7,18}, ddd;
    size_t size = diffIndicesRange(ddd, brr, xxx);
    std::cout << "size : " << size << std::endl;
    std::cout << "ddd : {";
    for (auto e : ddd) {
        std::cout << e << ", ";
    }
    std::cout << "}\n";
}

<|endoftext|>


<commit_before>#include <ros/ros.h>
#include <nav_msgs/OccupancyGrid.h>
#include <image_transport/image_transport.h>
#include <cv_bridge/cv_bridge.h>
#include <sensor_msgs/image_encodings.h>
#include <opencv2/core/core.hpp>
//using namespace cv;
void occupancyGridCb(const nav_msgs::OccupancyGrid::Ptr msg);
cv::Vec3b getColorFromMapValue(int8_t val);
image_transport::Publisher image_pub;
image_transport::Publisher color_image_pub;
int main(int argc, char** argv)
{
    ros::init(argc, argv, "occupancy_image_publisher");
    ros::NodeHandle n;
    ros::Subscriber sub = n.subscribe<nav_msgs::OccupancyGrid::Ptr>("/costmap/costmap/costmap", 1, &occupancyGridCb);
    image_transport::ImageTransport it(n);
    image_pub = it.advertise("occupancy_image", 1);
    color_image_pub = it.advertise("occupancy_image_color", 1);
    ros::spin();
    return 0;
}

void occupancyGridCb(const nav_msgs::OccupancyGrid::Ptr msg)
{
    // Greyscale image
    cv::Mat im(msg->info.height, msg->info.width, CV_8SC1);
    unsigned im_length = msg->info.height*msg->info.width;
    for (int i = 0; i < msg->info.height; ++i) {
        for (int j = 0; j < msg->info.width; ++j) {
            im.data[i* msg->info.width + j] = msg->data[(msg->info.height-(i+1))*msg->info.width + j];
        }
    }
    sensor_msgs::ImagePtr im_msg = cv_bridge::CvImage(std_msgs::Header(), "mono8", im).toImageMsg();
    image_pub.publish(im_msg);

    // Color image
    cv::Mat imgColor(msg->info.height,msg->info.width, CV_8UC3);
    for(int y=0; y < msg->info.height;y++){
        cv::Vec3b* imgRow = imgColor.ptr<cv::Vec3b>(y);
        for(int x = 0; x < msg->info.width;x++){
            imgRow[x] = getColorFromMapValue(msg->data[(msg->info.height-(y+1))*msg->info.width + x]);
        }
    }
    sensor_msgs::ImagePtr imColor_msg = cv_bridge::CvImage(std_msgs::Header(), "bgr8", imgColor).toImageMsg();
    color_image_pub.publish(imColor_msg);

}

cv::Vec3b getColorFromMapValue(int8_t val)
{
    cv::Vec3b res;

    if(val < 0)
    {
        res[0] = 128;
        res[1] = 128;
        res[2] = 128;
    }
    else if( val >= 0 && val <=100)
    {
        if(val <= 50){
            res[2] = 250 - (50 -val) * 3;
            res[1] = 250;
            res[0] = 0;
        }
        else
        {
            res[2] = 250;
            res[1] = 250 - val * 2.5;
            res[0] = 0;
           // ROS_INFO("val: %i   - green: %i",val,res[1]);
        }
    }
    else
    {
        res[0] = 0;
        res[1] = 0;
        res[2] = 0;
    }
    return res;
}
<commit_msg>color corrected<commit_after>#include <ros/ros.h>
#include <nav_msgs/OccupancyGrid.h>
#include <image_transport/image_transport.h>
#include <cv_bridge/cv_bridge.h>
#include <sensor_msgs/image_encodings.h>
#include <opencv2/core/core.hpp>
//using namespace cv;
void occupancyGridCb(const nav_msgs::OccupancyGrid::Ptr msg);
cv::Vec3b getColorFromMapValue(int8_t val);
image_transport::Publisher image_pub;
image_transport::Publisher color_image_pub;
int main(int argc, char** argv)
{
    ros::init(argc, argv, "occupancy_image_publisher");
    ros::NodeHandle n;
    ros::Subscriber sub = n.subscribe<nav_msgs::OccupancyGrid::Ptr>("/costmap/costmap/costmap", 1, &occupancyGridCb);
    image_transport::ImageTransport it(n);
    image_pub = it.advertise("occupancy_image", 1);
    color_image_pub = it.advertise("occupancy_image_color", 1);
    ros::spin();
    return 0;
}

void occupancyGridCb(const nav_msgs::OccupancyGrid::Ptr msg)
{
    // Greyscale image
    cv::Mat im(msg->info.height, msg->info.width, CV_8SC1);
    unsigned im_length = msg->info.height*msg->info.width;
    for (int i = 0; i < msg->info.height; ++i) {
        for (int j = 0; j < msg->info.width; ++j) {
            im.data[i* msg->info.width + j] = msg->data[(msg->info.height-(i+1))*msg->info.width + j];
        }
    }
    sensor_msgs::ImagePtr im_msg = cv_bridge::CvImage(std_msgs::Header(), "mono8", im).toImageMsg();
    image_pub.publish(im_msg);

    // Color image
    cv::Mat imgColor(msg->info.height,msg->info.width, CV_8UC3);
    for(int y=0; y < msg->info.height;y++){
        cv::Vec3b* imgRow = imgColor.ptr<cv::Vec3b>(y);
        for(int x = 0; x < msg->info.width;x++){
            imgRow[x] = getColorFromMapValue(msg->data[(msg->info.height-(y+1))*msg->info.width + x]);
        }
    }
    sensor_msgs::ImagePtr imColor_msg = cv_bridge::CvImage(std_msgs::Header(), "bgr8", imgColor).toImageMsg();
    color_image_pub.publish(imColor_msg);

}

cv::Vec3b getColorFromMapValue(int8_t val)
{
    cv::Vec3b res;

    u_char min = 0, max = 100, halfmax = 50;
    if(val < 0)
    {
        res[0] = 128;
        res[1] = 128;
        res[2] = 128;
    }
    else if(min <= val && val < halfmax)
    {
        res[2] = 0;
        res[1] = (u_char)( 255./(halfmax - min) * (val - min));
        res[0] = u_char( 255. + -255./(halfmax - min)  * (val - min));
    }
    else
    {
        res[2] = (u_char)( 255./(max - halfmax) * (val - max));
        res[1] = (u_char)( 255. + -255./(max - halfmax)  * (val - max));
        res[0] = 0;
    }

    return res;
}
<|endoftext|>