<commit_before>/**
 * A class which is responsible for listing all controllers and their properties
 * in IAS.
 *
 * @date                    Jul 20, 2014
 * @author                    Joeri HERMANS
 * @version                    0.1
 *
 * Copyright 2013 Joeri HERMANS
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// BEGIN Includes. ///////////////////////////////////////////////////

// System dependencies.
#include <cassert>

// Application dependencies.
#include <ias/application/constants.h>
#include <ias/user/command/command_list_controllers.h>

// END Includes. /////////////////////////////////////////////////////

// BEGIN Constants. //////////////////////////////////////////////////

const char CommandListControllers::kIdentifier[] = "lsc";

// END Constants. ////////////////////////////////////////////////////

void CommandListControllers::setControllerContainer(
    Container<Controller *> * c ) {
    // Checking the precondition.
    assert( c != nullptr );

    mControllers = c;
}

CommandListControllers::CommandListControllers( Container<Controller *> * c ) :
    Command(kIdentifier) {
    setControllerContainer(c);
}

CommandListControllers::~CommandListControllers( void ) {
    // Nothing to do here.
}

std::string CommandListControllers::execute( User * user,
                                             const std::string & params ) {
    std::string output;
    std::vector<Controller *> controllers;
    Controller * c;
    std::size_t n;

    // Checking the precondition.
    assert( user != nullptr );

    controllers = mControllers->getAll();
    n = controllers.size();
    output = "{\"controllers\": [\n";
    for( std::size_t i = 0 ; i < n ; ++i ) {
        c = controllers.at(i);
        output += "  {\n";
        output += "    \"identifier\":\"" + c->getIdentifier() + "\",\n";
        output += "    \"state\":" + std::to_string(c->isConnected()) + "\n";
        output += "  }";
        if( n > 1 && i < (n - 1) )
              output += ",";
        output += "\n";
    }
    output += "]}";

    return ( output );
}
<commit_msg>Add additional information to controller list command.<commit_after>/**
 * A class which is responsible for listing all controllers and their properties
 * in IAS.
 *
 * @date                    Jul 20, 2014
 * @author                    Joeri HERMANS
 * @version                    0.1
 *
 * Copyright 2013 Joeri HERMANS
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// BEGIN Includes. ///////////////////////////////////////////////////

// System dependencies.
#include <cassert>

// Application dependencies.
#include <ias/application/constants.h>
#include <ias/user/command/command_list_controllers.h>

// END Includes. /////////////////////////////////////////////////////

// BEGIN Constants. //////////////////////////////////////////////////

const char CommandListControllers::kIdentifier[] = "lsc";

// END Constants. ////////////////////////////////////////////////////

void CommandListControllers::setControllerContainer(
    Container<Controller *> * c ) {
    // Checking the precondition.
    assert( c != nullptr );

    mControllers = c;
}

CommandListControllers::CommandListControllers( Container<Controller *> * c ) :
    Command(kIdentifier) {
    setControllerContainer(c);
}

CommandListControllers::~CommandListControllers( void ) {
    // Nothing to do here.
}

std::string CommandListControllers::execute( User * user,
                                             const std::string & params ) {
    std::string output;
    std::vector<Controller *> controllers;
    Controller * c;
    std::size_t n;

    // Checking the precondition.
    assert( user != nullptr );

    controllers = mControllers->getAll();
    n = controllers.size();
    output = "{\"controllers\": [\n";
    for( std::size_t i = 0 ; i < n ; ++i ) {
        c = controllers.at(i);
        output += "  {\n";
        output += "    \"identifier\":\"" + c->getIdentifier() + "\",\n";
        output += "    \"name\": \"" + c->getName() + "\"";
		output += "    \"description\": \"" + c->getDescription() + "\"";
		output += "    \"state\":" + std::to_string(c->isConnected()) + "\n";
        output += "  }";
        if( n > 1 && i < (n - 1) )
              output += ",";
        output += "\n";
    }
    output += "]}";

    return ( output );
}
<|endoftext|>


<commit_before>/*
Copyright (c) 2016 Miroslaw Opoka <mirek@opoki.com>

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
SOFTWARE.
*/

#ifndef __UI_SERIAL_HPP__
#define __UI_SERIAL_HPP__

#include "UI_IF.hpp"
#include "State_IF.hpp"

namespace MO
{
    /// UI using plain text messages on serial console.
    class UI: public UI_IF
    {
        public:
            UI();

            virtual void Show_Ready(const State_IF &);
            virtual void Show_Running(const State_IF &);
            virtual void Show_Paused(const State_IF &);
            virtual void Show_Finished(const State_IF &);

            virtual void Set_Beeper(uint8_t);
            virtual bool Showing() const;

            virtual void Setup();
        private:
            void write(const char *a_format, ...);

            enum
            {
                B_SIZE = 64
            };

            uint8_t the_timer;
            char    the_buf[B_SIZE];
            char    the_last_buf[B_SIZE];
    };
}

#endif
<commit_msg>updated ifdef<commit_after>/*
Copyright (c) 2016 Miroslaw Opoka <mirek@opoki.com>

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
SOFTWARE.
*/

#ifndef __UI_HPP__
#define __UI_HPP__

#include "UI_IF.hpp"
#include "State_IF.hpp"

namespace MO
{
    /// UI using plain text messages on serial console.
    class UI: public UI_IF
    {
        public:
            UI();

            virtual void Show_Ready(const State_IF &);
            virtual void Show_Running(const State_IF &);
            virtual void Show_Paused(const State_IF &);
            virtual void Show_Finished(const State_IF &);

            virtual void Set_Beeper(uint8_t);
            virtual bool Showing() const;

            virtual void Setup();
        private:
            void write(const char *a_format, ...);

            enum
            {
                B_SIZE = 64
            };

            uint8_t the_timer;
            char    the_buf[B_SIZE];
            char    the_last_buf[B_SIZE];
    };
}

#endif
<|endoftext|>


<commit_before>
#pragma once

#include "physics/discrete_trajectory.hpp"

#include <algorithm>
#include <list>
#include <map>
#include <vector>

#include "geometry/named_quantities.hpp"
#include "glog/logging.h"

namespace principia {

using base::make_not_null_unique;
using geometry::Instant;

namespace physics {
namespace internal {

template<typename Frame>
Instant const& ForkableTraits<DiscreteTrajectory<Frame>>::time(
    TimelineConstIterator const it) {
  return it->first;
}

template<typename Frame>
Instant const& DiscreteTrajectoryIterator<Frame>::time() const {
  return this->current()->first;
}

template<typename Frame>
DegreesOfFreedom<Frame> const&
DiscreteTrajectoryIterator<Frame>::degrees_of_freedom() const {
  return this->current()->second;
}

template<typename Frame>
not_null<DiscreteTrajectoryIterator<Frame>*>
DiscreteTrajectoryIterator<Frame>::that() {
  return this;
}

template<typename Frame>
not_null<DiscreteTrajectoryIterator<Frame> const*>
DiscreteTrajectoryIterator<Frame>::that() const {
  return this;
}

}  // namespace internal

template<typename Frame>
DiscreteTrajectory<Frame>::~DiscreteTrajectory() {
  if (on_destroy_) {
    on_destroy_(this);
  }
}

template<typename Frame>
void DiscreteTrajectory<Frame>::set_on_destroy(
    OnDestroyCallback on_destroy) {
  on_destroy_ = on_destroy;
}

template<typename Frame>
typename DiscreteTrajectory<Frame>::OnDestroyCallback
DiscreteTrajectory<Frame>::get_on_destroy() const {
  return on_destroy_;
}

template<typename Frame>
typename DiscreteTrajectory<Frame>::Iterator
DiscreteTrajectory<Frame>::last() const {
  return --this->End();
}

template<typename Frame>
not_null<DiscreteTrajectory<Frame>*>
DiscreteTrajectory<Frame>::NewForkWithCopy(Instant const& time) {
  // May be at |timeline_end()| if |time| is the fork time of this object.
  auto timeline_it = timeline_.find(time);
  CHECK(timeline_it != timeline_end() ||
        (!this->is_root() && time == this->Fork().time()))
      << "NewForkWithCopy at nonexistent time " << time;

  auto const fork = this->NewFork(timeline_it);

  // Copy the tail of the trajectory in the child object.
  if (timeline_it != timeline_.end()) {
    fork->timeline_.insert(++timeline_it, timeline_.end());
  }
  return fork;
}

template<typename Frame>
not_null<DiscreteTrajectory<Frame>*>
DiscreteTrajectory<Frame>::NewForkWithoutCopy(Instant const& time) {
  // May be at |timeline_end()| if |time| is the fork time of this object.
  auto timeline_it = timeline_.find(time);
  CHECK(timeline_it != timeline_end() ||
        (!this->is_root() && time == this->Fork().time()))
      << "NewForkWithoutCopy at nonexistent time " << time;

  return this->NewFork(timeline_it);
}

template<typename Frame>
not_null<DiscreteTrajectory<Frame>*>
DiscreteTrajectory<Frame>::NewForkAtLast() {
  auto end = timeline_.end();
  if (timeline_.empty()) {
    return this->NewFork(end);
  } else {
    return this->NewFork(--end);
  }
}

template<typename Frame>
void DiscreteTrajectory<Frame>::AttachFork(
    not_null<std::unique_ptr<DiscreteTrajectory<Frame>>> fork) {
  CHECK(fork->is_root());
  CHECK(!fork->timeline_.empty());
  auto it = fork->timeline_.begin();
  Append(it->first, it->second);
  fork->timeline_.erase(it);
}

template<typename Frame>
not_null<std::unique_ptr<DiscreteTrajectory<Frame>>>
DiscreteTrajectory<Frame>::DetachFork() {
  CHECK(!this->is_root());

  // Insert a new point in the timeline for the fork time.  It should go at the
  // beginning of the timeline.
  auto const fork_it = this->Fork();
  auto const begin_it = timeline_.emplace_hint(
      timeline_.begin(), fork_it.time(), fork_it.degrees_of_freedom());
  CHECK(begin_it == timeline_.begin());

  // Detach this trajectory and tell the caller that it owns the pieces.
  return this->DetachForkWithCopiedBegin();
}

template<typename Frame>
void DiscreteTrajectory<Frame>::Append(
    Instant const& time,
    DegreesOfFreedom<Frame> const& degrees_of_freedom) {
  CHECK(this->is_root() || time > this->Fork().time())
       << "Append at " << time << " which is before fork time "
       << this->Fork().time();

  if (!timeline_.empty() && timeline_.cbegin()->first == time) {
    LOG(WARNING) << "Append at existing time " << time
                 << ", time range = [" << this->Begin().time() << ", "
                 << last().time() << "]";
    return;
  }
  auto it = timeline_.emplace_hint(timeline_.end(),
                                   time,
                                   degrees_of_freedom);
  // Decrementing |end()| is much faster than incrementing |it|.  Don't ask.
  CHECK(--timeline_.end() == it) << "Append out of order at " << time;
}

template<typename Frame>
void DiscreteTrajectory<Frame>::ForgetAfter(Instant const& time) {
  this->DeleteAllForksAfter(time);

  // Get an iterator denoting the first entry with time > |time|.  Remove that
  // entry and all the entries that follow it.  This preserves any entry with
  // time == |time|.
  auto const it = timeline_.upper_bound(time);
  timeline_.erase(it, timeline_.end());
}

template<typename Frame>
void DiscreteTrajectory<Frame>::ForgetBefore(Instant const& time) {
  this->CheckNoForksBefore(time);

  // Get an iterator denoting the first entry with time >= |time|.  Remove all
  // the entries that precede it.  This preserves any entry with time == |time|.
  auto it = timeline_.lower_bound(time);
  timeline_.erase(timeline_.begin(), it);
}

template<typename Frame>
void DiscreteTrajectory<Frame>::WriteToMessage(
    not_null<serialization::DiscreteTrajectory*> const message,
    std::vector<DiscreteTrajectory<Frame>*> const& forks)
    const {
  LOG(INFO) << __FUNCTION__;
  CHECK(this->is_root());

  std::vector<DiscreteTrajectory<Frame>*> mutable_forks = forks;
  WriteSubTreeToMessage(message, mutable_forks);
  CHECK(std::all_of(mutable_forks.begin(),
                    mutable_forks.end(),
                    [](DiscreteTrajectory<Frame>* const fork) {
                      return fork == nullptr;
                    }));

  LOG(INFO) << NAMED(this);
  LOG(INFO) << NAMED(message->SpaceUsed());
  LOG(INFO) << NAMED(message->ByteSize());
}

template<typename Frame>
not_null<std::unique_ptr<DiscreteTrajectory<Frame>>>
DiscreteTrajectory<Frame>::ReadFromMessage(
    serialization::DiscreteTrajectory const& message,
    std::vector<DiscreteTrajectory<Frame>**> const& forks) {
  auto trajectory = make_not_null_unique<DiscreteTrajectory>();
  CHECK(std::all_of(forks.begin(),
                    forks.end(),
                    [](DiscreteTrajectory<Frame>** const fork) {
                      return fork != nullptr && *fork == nullptr;
                    }));
  trajectory->FillSubTreeFromMessage(message, forks);
  return trajectory;
}

template<typename Frame>
not_null<DiscreteTrajectory<Frame>*> DiscreteTrajectory<Frame>::that() {
  return this;
}

template<typename Frame>
not_null<DiscreteTrajectory<Frame> const*>
DiscreteTrajectory<Frame>::that() const {
  return this;
}

template<typename Frame>
typename DiscreteTrajectory<Frame>::TimelineConstIterator
DiscreteTrajectory<Frame>::timeline_begin() const {
  return timeline_.begin();
}

template<typename Frame>
typename DiscreteTrajectory<Frame>::TimelineConstIterator
DiscreteTrajectory<Frame>::timeline_end() const {
  return timeline_.end();
}

template<typename Frame>
typename DiscreteTrajectory<Frame>::TimelineConstIterator
DiscreteTrajectory<Frame>::timeline_find(Instant const& time) const {
  return timeline_.find(time);
}

template<typename Frame>
typename DiscreteTrajectory<Frame>::TimelineConstIterator
DiscreteTrajectory<Frame>::timeline_lower_bound(Instant const& time) const {
  return timeline_.lower_bound(time);
}

template<typename Frame>
bool DiscreteTrajectory<Frame>::timeline_empty() const {
  return timeline_.empty();
}

template<typename Frame>
void DiscreteTrajectory<Frame>::WriteSubTreeToMessage(
    not_null<serialization::DiscreteTrajectory*> const message,
    std::vector<DiscreteTrajectory<Frame>*>& forks) const {
  Forkable<DiscreteTrajectory, Iterator>::WriteSubTreeToMessage(message, forks);
  for (auto const& pair : timeline_) {
    Instant const& instant = pair.first;
    DegreesOfFreedom<Frame> const& degrees_of_freedom = pair.second;
    auto const instantaneous_degrees_of_freedom = message->add_timeline();
    instant.WriteToMessage(instantaneous_degrees_of_freedom->mutable_instant());
    degrees_of_freedom.WriteToMessage(
        instantaneous_degrees_of_freedom->mutable_degrees_of_freedom());
  }
}

template<typename Frame>
void DiscreteTrajectory<Frame>::FillSubTreeFromMessage(
    serialization::DiscreteTrajectory const& message,
    std::vector<DiscreteTrajectory<Frame>**> const& forks) {
  for (auto timeline_it = message.timeline().begin();
       timeline_it != message.timeline().end();
       ++timeline_it) {
    Append(Instant::ReadFromMessage(timeline_it->instant()),
           DegreesOfFreedom<Frame>::ReadFromMessage(
               timeline_it->degrees_of_freedom()));
  }
  Forkable<DiscreteTrajectory, Iterator>::FillSubTreeFromMessage(message,
                                                                 forks);
}

}  // namespace physics
}  // namespace principia
<commit_msg>Two phases.<commit_after>
#pragma once

#include "physics/discrete_trajectory.hpp"

#include <algorithm>
#include <list>
#include <map>
#include <vector>

#include "geometry/named_quantities.hpp"
#include "glog/logging.h"

namespace principia {

using base::make_not_null_unique;
using geometry::Instant;

namespace physics {
namespace internal {

template<typename Frame>
Instant const& ForkableTraits<DiscreteTrajectory<Frame>>::time(
    TimelineConstIterator const it) {
  return it->first;
}

template<typename Frame>
Instant const& DiscreteTrajectoryIterator<Frame>::time() const {
  return this->current()->first;
}

template<typename Frame>
DegreesOfFreedom<Frame> const&
DiscreteTrajectoryIterator<Frame>::degrees_of_freedom() const {
  return this->current()->second;
}

template<typename Frame>
not_null<DiscreteTrajectoryIterator<Frame>*>
DiscreteTrajectoryIterator<Frame>::that() {
  return this;
}

template<typename Frame>
not_null<DiscreteTrajectoryIterator<Frame> const*>
DiscreteTrajectoryIterator<Frame>::that() const {
  return this;
}

}  // namespace internal

template<typename Frame>
DiscreteTrajectory<Frame>::~DiscreteTrajectory() {
  if (on_destroy_) {
    on_destroy_(this);
  }
}

template<typename Frame>
void DiscreteTrajectory<Frame>::set_on_destroy(
    OnDestroyCallback on_destroy) {
  on_destroy_ = on_destroy;
}

template<typename Frame>
typename DiscreteTrajectory<Frame>::OnDestroyCallback
DiscreteTrajectory<Frame>::get_on_destroy() const {
  return on_destroy_;
}

template<typename Frame>
typename DiscreteTrajectory<Frame>::Iterator
DiscreteTrajectory<Frame>::last() const {
  return --this->End();
}

template<typename Frame>
not_null<DiscreteTrajectory<Frame>*>
DiscreteTrajectory<Frame>::NewForkWithCopy(Instant const& time) {
  // May be at |timeline_end()| if |time| is the fork time of this object.
  auto timeline_it = timeline_.find(time);
  CHECK(timeline_it != timeline_end() ||
        (!this->is_root() && time == this->Fork().time()))
      << "NewForkWithCopy at nonexistent time " << time;

  auto const fork = this->NewFork(timeline_it);

  // Copy the tail of the trajectory in the child object.
  if (timeline_it != timeline_.end()) {
    fork->timeline_.insert(++timeline_it, timeline_.end());
  }
  return fork;
}

template<typename Frame>
not_null<DiscreteTrajectory<Frame>*>
DiscreteTrajectory<Frame>::NewForkWithoutCopy(Instant const& time) {
  // May be at |timeline_end()| if |time| is the fork time of this object.
  auto timeline_it = timeline_.find(time);
  CHECK(timeline_it != timeline_end() ||
        (!this->is_root() && time == this->Fork().time()))
      << "NewForkWithoutCopy at nonexistent time " << time;

  return this->NewFork(timeline_it);
}

template<typename Frame>
not_null<DiscreteTrajectory<Frame>*>
DiscreteTrajectory<Frame>::NewForkAtLast() {
  auto end = timeline_.end();
  if (timeline_.empty()) {
    return this->NewFork(end);
  } else {
    return this->NewFork(--end);
  }
}

template<typename Frame>
void DiscreteTrajectory<Frame>::AttachFork(
    not_null<std::unique_ptr<DiscreteTrajectory<Frame>>> fork) {
  CHECK(fork->is_root());
  CHECK(!fork->timeline_.empty());

  // Append to this trajectory a copy of the first point of |fork|.
  auto& fork_timeline = fork->timeline_;
  auto fork_begin = fork_timeline.begin();
  Append(fork_begin->first, fork_begin->second);

  // Attach |fork| to this trajectory.
  AttachForkToCopiedBegin(fork);

  // Remove the first point of |fork| now that it properly attached to its
  // parent.
  fork_timeline.erase(fork_begin);
}

template<typename Frame>
not_null<std::unique_ptr<DiscreteTrajectory<Frame>>>
DiscreteTrajectory<Frame>::DetachFork() {
  CHECK(!this->is_root());

  // Insert a new point in the timeline for the fork time.  It should go at the
  // beginning of the timeline.
  auto const fork_it = this->Fork();
  auto const begin_it = timeline_.emplace_hint(
      timeline_.begin(), fork_it.time(), fork_it.degrees_of_freedom());
  CHECK(begin_it == timeline_.begin());

  // Detach this trajectory and tell the caller that it owns the pieces.
  return this->DetachForkWithCopiedBegin();
}

template<typename Frame>
void DiscreteTrajectory<Frame>::Append(
    Instant const& time,
    DegreesOfFreedom<Frame> const& degrees_of_freedom) {
  CHECK(this->is_root() || time > this->Fork().time())
       << "Append at " << time << " which is before fork time "
       << this->Fork().time();

  if (!timeline_.empty() && timeline_.cbegin()->first == time) {
    LOG(WARNING) << "Append at existing time " << time
                 << ", time range = [" << this->Begin().time() << ", "
                 << last().time() << "]";
    return;
  }
  auto it = timeline_.emplace_hint(timeline_.end(),
                                   time,
                                   degrees_of_freedom);
  // Decrementing |end()| is much faster than incrementing |it|.  Don't ask.
  CHECK(--timeline_.end() == it) << "Append out of order at " << time;
}

template<typename Frame>
void DiscreteTrajectory<Frame>::ForgetAfter(Instant const& time) {
  this->DeleteAllForksAfter(time);

  // Get an iterator denoting the first entry with time > |time|.  Remove that
  // entry and all the entries that follow it.  This preserves any entry with
  // time == |time|.
  auto const it = timeline_.upper_bound(time);
  timeline_.erase(it, timeline_.end());
}

template<typename Frame>
void DiscreteTrajectory<Frame>::ForgetBefore(Instant const& time) {
  this->CheckNoForksBefore(time);

  // Get an iterator denoting the first entry with time >= |time|.  Remove all
  // the entries that precede it.  This preserves any entry with time == |time|.
  auto it = timeline_.lower_bound(time);
  timeline_.erase(timeline_.begin(), it);
}

template<typename Frame>
void DiscreteTrajectory<Frame>::WriteToMessage(
    not_null<serialization::DiscreteTrajectory*> const message,
    std::vector<DiscreteTrajectory<Frame>*> const& forks)
    const {
  LOG(INFO) << __FUNCTION__;
  CHECK(this->is_root());

  std::vector<DiscreteTrajectory<Frame>*> mutable_forks = forks;
  WriteSubTreeToMessage(message, mutable_forks);
  CHECK(std::all_of(mutable_forks.begin(),
                    mutable_forks.end(),
                    [](DiscreteTrajectory<Frame>* const fork) {
                      return fork == nullptr;
                    }));

  LOG(INFO) << NAMED(this);
  LOG(INFO) << NAMED(message->SpaceUsed());
  LOG(INFO) << NAMED(message->ByteSize());
}

template<typename Frame>
not_null<std::unique_ptr<DiscreteTrajectory<Frame>>>
DiscreteTrajectory<Frame>::ReadFromMessage(
    serialization::DiscreteTrajectory const& message,
    std::vector<DiscreteTrajectory<Frame>**> const& forks) {
  auto trajectory = make_not_null_unique<DiscreteTrajectory>();
  CHECK(std::all_of(forks.begin(),
                    forks.end(),
                    [](DiscreteTrajectory<Frame>** const fork) {
                      return fork != nullptr && *fork == nullptr;
                    }));
  trajectory->FillSubTreeFromMessage(message, forks);
  return trajectory;
}

template<typename Frame>
not_null<DiscreteTrajectory<Frame>*> DiscreteTrajectory<Frame>::that() {
  return this;
}

template<typename Frame>
not_null<DiscreteTrajectory<Frame> const*>
DiscreteTrajectory<Frame>::that() const {
  return this;
}

template<typename Frame>
typename DiscreteTrajectory<Frame>::TimelineConstIterator
DiscreteTrajectory<Frame>::timeline_begin() const {
  return timeline_.begin();
}

template<typename Frame>
typename DiscreteTrajectory<Frame>::TimelineConstIterator
DiscreteTrajectory<Frame>::timeline_end() const {
  return timeline_.end();
}

template<typename Frame>
typename DiscreteTrajectory<Frame>::TimelineConstIterator
DiscreteTrajectory<Frame>::timeline_find(Instant const& time) const {
  return timeline_.find(time);
}

template<typename Frame>
typename DiscreteTrajectory<Frame>::TimelineConstIterator
DiscreteTrajectory<Frame>::timeline_lower_bound(Instant const& time) const {
  return timeline_.lower_bound(time);
}

template<typename Frame>
bool DiscreteTrajectory<Frame>::timeline_empty() const {
  return timeline_.empty();
}

template<typename Frame>
void DiscreteTrajectory<Frame>::WriteSubTreeToMessage(
    not_null<serialization::DiscreteTrajectory*> const message,
    std::vector<DiscreteTrajectory<Frame>*>& forks) const {
  Forkable<DiscreteTrajectory, Iterator>::WriteSubTreeToMessage(message, forks);
  for (auto const& pair : timeline_) {
    Instant const& instant = pair.first;
    DegreesOfFreedom<Frame> const& degrees_of_freedom = pair.second;
    auto const instantaneous_degrees_of_freedom = message->add_timeline();
    instant.WriteToMessage(instantaneous_degrees_of_freedom->mutable_instant());
    degrees_of_freedom.WriteToMessage(
        instantaneous_degrees_of_freedom->mutable_degrees_of_freedom());
  }
}

template<typename Frame>
void DiscreteTrajectory<Frame>::FillSubTreeFromMessage(
    serialization::DiscreteTrajectory const& message,
    std::vector<DiscreteTrajectory<Frame>**> const& forks) {
  for (auto timeline_it = message.timeline().begin();
       timeline_it != message.timeline().end();
       ++timeline_it) {
    Append(Instant::ReadFromMessage(timeline_it->instant()),
           DegreesOfFreedom<Frame>::ReadFromMessage(
               timeline_it->degrees_of_freedom()));
  }
  Forkable<DiscreteTrajectory, Iterator>::FillSubTreeFromMessage(message,
                                                                 forks);
}

}  // namespace physics
}  // namespace principia
<|endoftext|>


<commit_before>//
// RemotePhotoTool - remote camera control software
// Copyright (C) 2008-2014 Michael Fink
//
/// \file PsrecCommon.cpp PS-ReC common header
//
#pragma once

// includes
#include "stdafx.h"
#include "PsrecCommon.hpp"
#include "PsrecSourceInfoImpl.hpp"

using PSREC::Ref;
using PSREC::CheckError;

void PSREC::CheckError(const CString& cszFunction, prResponse err, LPCSTR pszFile, UINT uiLine)
{
   if (err == prOK)
      return;

   prResponse componentId = err & prERROR_COMPONENTID_MASK;
   prResponse errorId = err & prERROR_ERRORID_MASK;

   CString cszMessage;
   cszMessage.Format(_T("Error in function \"%s\": %s, %s (%08x)"),
      cszFunction.GetString(),
      componentId == prERROR_PTP_COMPONENTID ? _T("PTP") :
      componentId == prERROR_PRSDK_COMPONENTID ? _T("PRSDK") :
      componentId == prERROR_WIA_STI_COMPONENTID ? _T("WIA/STI") :
      componentId == prERROR_WINDOWS_COMPONENTID ? _T("Windows") :
      componentId == prERROR_COMIF_COMPONENTID ? _T("COM") : _T("???"),
      ErrorTextFromErrorId(errorId, true),
      err);

   throw CameraException(cszFunction, cszMessage, err, pszFile, uiLine);
}

Ref::Ref()
{
   // may return prNOT_SUPPORTED when OS is not supported
   // may return prMEM_ALLOC_FAILED when insufficient memory
   // may return prINTERNAL_ERROR on internal error
   // may also return Win32 error value
   prResponse err = PR_StartSDK();

   LOG_TRACE(_T("PR_StartSDK() returned %08x\n"), err);
   CheckError(_T("PR_StartSDK"), err, __FILE__, __LINE__);
}

Ref::~Ref() throw()
{
   // may return prINVALID_FN_CALL
   // may also return Win32 error value
   prResponse err = PR_FinishSDK();

   // can only trace here
   LOG_TRACE(_T("PR_FinishSDK() returned %08x\n"), err);
}

void Ref::AddVersionText(CString& cszVersionText) const
{
   cszVersionText += _T("PS-ReC (Powershot Remote Capture SDK)\n");

   // get size of buffer
   prUInt32 uiSize = 0;
   prResponse err = PR_GetDllsVersion(&uiSize, nullptr);
   if ((err & prERROR_ERRORID_MASK) != prINSUFFICIENT_BUFFER)
   {
      LOG_TRACE(_T("PR_GetDllsVersion(0, nullptr) returned %08x, buffer size %u\n"), err, uiSize);
      CheckError(_T("PR_GetDllsVersion"), err, __FILE__, __LINE__);
      return;
   }

   if (uiSize == 0)
      return;

   std::vector<BYTE> vecBuffer(uiSize);
   prDllsVerInfo* pVerInfo = reinterpret_cast<prDllsVerInfo*>(&vecBuffer[0]);

   // may return prINVALID_PARAMETER, prMEM_ALLOC_FAILED, prINSUFFICIENT_BUFFER or @ERR
   err = PR_GetDllsVersion(&uiSize, pVerInfo);
   LOG_TRACE(_T("PR_GetDllsVersion(size = %u, buffer) returned %08x\n"), uiSize, err);
   CheckError(_T("PR_GetDllsVersion"), err, __FILE__, __LINE__);

   prDllsVerInfo& allVersionInfos = *pVerInfo;
   for (prUInt32 ui=0; ui<allVersionInfos.Entry; ui++)
   {
      prVerInfo& versionInfo = allVersionInfos.VerInfo[ui];

      LOG_TRACE(_T("%u: ModuleName=%ls, Version=%ls\n"),
         ui,
         versionInfo.ModuleName,
         versionInfo.Version
      );

      CString cszModuleName(reinterpret_cast<LPCWSTR>(versionInfo.ModuleName));
      int iPos = cszModuleName.ReverseFind(_T('\\'));
      if (iPos != -1)
         cszModuleName = cszModuleName.Mid(iPos+1);

      CString cszTemp;
      cszTemp.Format(_T("   %s: %ls\n"),
         cszModuleName.GetString(),
         versionInfo.Version);

      // version numbers are separated with comma; use points instead
      cszTemp.Replace(_T(", "), _T("."));

      cszVersionText += cszTemp;
   }

   cszVersionText += _T("\n");
}

void Ref::EnumerateDevices(std::vector<std::shared_ptr<SourceInfo>>& vecSourceDevices) const
{
   // get size of buffer
   prUInt32 uiSize = 0;
   prResponse err = PR_GetDeviceList(&uiSize, nullptr);
   if ((err & prERROR_ERRORID_MASK) != prINSUFFICIENT_BUFFER)
   {
      LOG_TRACE(_T("PR_GetDeviceList(0, nullptr) returned %08x, buffer size %u\n"), err, uiSize);
      CheckError(_T("PR_GetDeviceList"), err, __FILE__, __LINE__);
      return;
   }

   if (uiSize == 0)
      return;

   std::vector<BYTE> vecBuffer(uiSize);
   prDeviceList* pDeviceList = reinterpret_cast<prDeviceList*>(&vecBuffer[0]);

   // may return prINVALID_FN_CALL, prINVALID_PARAMETER, prMEM_ALLOC_FAILED, prINSUFFICIENT_BUFFER, prINTERNAL_ERROR or @ERR
   err = PR_GetDeviceList(&uiSize, pDeviceList);
   if (uiSize != 4 && err != prOK) // only log non-empty lists
      LOG_TRACE(_T("PR_GetDeviceList(size = %u, buffer) returned %08x\n"), uiSize, err);
   CheckError(_T("PR_GetDeviceList"), err, __FILE__, __LINE__);

   prDeviceList& deviceList = *pDeviceList;
   for (prUInt32 ui=0; ui<deviceList.NumList; ui++)
   {
      prDeviceInfoTable& deviceInfo = deviceList.DeviceInfo[ui];

      LOG_TRACE(_T("device %u, ModelName=%ls, InternalName=%ls, Generation=%u, ModelID=%08x, PortType=%s\n"),
         ui,
         deviceInfo.ModelName,
         deviceInfo.DeviceInternalName,
         prSUB_GENERATION_CAMERA(deviceInfo.Generation),
         deviceInfo.ModelID,
         deviceInfo.PortType == 0x01 ? _T("WIA") : deviceInfo.PortType == 0x02 ? _T("STI") : _T("???")
      );

      std::shared_ptr<SourceInfo> spSourceInfo(
         new SourceInfoImpl(const_cast<Ref*>(this)->shared_from_this(), deviceInfo));

      vecSourceDevices.push_back(spSourceInfo);
   }
}
<commit_msg>removed #pragma once not needed in .cpp file<commit_after>//
// RemotePhotoTool - remote camera control software
// Copyright (C) 2008-2014 Michael Fink
//
/// \file PsrecCommon.cpp PS-ReC common header
//

// includes
#include "stdafx.h"
#include "PsrecCommon.hpp"
#include "PsrecSourceInfoImpl.hpp"

using PSREC::Ref;
using PSREC::CheckError;

void PSREC::CheckError(const CString& cszFunction, prResponse err, LPCSTR pszFile, UINT uiLine)
{
   if (err == prOK)
      return;

   prResponse componentId = err & prERROR_COMPONENTID_MASK;
   prResponse errorId = err & prERROR_ERRORID_MASK;

   CString cszMessage;
   cszMessage.Format(_T("Error in function \"%s\": %s, %s (%08x)"),
      cszFunction.GetString(),
      componentId == prERROR_PTP_COMPONENTID ? _T("PTP") :
      componentId == prERROR_PRSDK_COMPONENTID ? _T("PRSDK") :
      componentId == prERROR_WIA_STI_COMPONENTID ? _T("WIA/STI") :
      componentId == prERROR_WINDOWS_COMPONENTID ? _T("Windows") :
      componentId == prERROR_COMIF_COMPONENTID ? _T("COM") : _T("???"),
      ErrorTextFromErrorId(errorId, true),
      err);

   throw CameraException(cszFunction, cszMessage, err, pszFile, uiLine);
}

Ref::Ref()
{
   // may return prNOT_SUPPORTED when OS is not supported
   // may return prMEM_ALLOC_FAILED when insufficient memory
   // may return prINTERNAL_ERROR on internal error
   // may also return Win32 error value
   prResponse err = PR_StartSDK();

   LOG_TRACE(_T("PR_StartSDK() returned %08x\n"), err);
   CheckError(_T("PR_StartSDK"), err, __FILE__, __LINE__);
}

Ref::~Ref() throw()
{
   // may return prINVALID_FN_CALL
   // may also return Win32 error value
   prResponse err = PR_FinishSDK();

   // can only trace here
   LOG_TRACE(_T("PR_FinishSDK() returned %08x\n"), err);
}

void Ref::AddVersionText(CString& cszVersionText) const
{
   cszVersionText += _T("PS-ReC (Powershot Remote Capture SDK)\n");

   // get size of buffer
   prUInt32 uiSize = 0;
   prResponse err = PR_GetDllsVersion(&uiSize, nullptr);
   if ((err & prERROR_ERRORID_MASK) != prINSUFFICIENT_BUFFER)
   {
      LOG_TRACE(_T("PR_GetDllsVersion(0, nullptr) returned %08x, buffer size %u\n"), err, uiSize);
      CheckError(_T("PR_GetDllsVersion"), err, __FILE__, __LINE__);
      return;
   }

   if (uiSize == 0)
      return;

   std::vector<BYTE> vecBuffer(uiSize);
   prDllsVerInfo* pVerInfo = reinterpret_cast<prDllsVerInfo*>(&vecBuffer[0]);

   // may return prINVALID_PARAMETER, prMEM_ALLOC_FAILED, prINSUFFICIENT_BUFFER or @ERR
   err = PR_GetDllsVersion(&uiSize, pVerInfo);
   LOG_TRACE(_T("PR_GetDllsVersion(size = %u, buffer) returned %08x\n"), uiSize, err);
   CheckError(_T("PR_GetDllsVersion"), err, __FILE__, __LINE__);

   prDllsVerInfo& allVersionInfos = *pVerInfo;
   for (prUInt32 ui=0; ui<allVersionInfos.Entry; ui++)
   {
      prVerInfo& versionInfo = allVersionInfos.VerInfo[ui];

      LOG_TRACE(_T("%u: ModuleName=%ls, Version=%ls\n"),
         ui,
         versionInfo.ModuleName,
         versionInfo.Version
      );

      CString cszModuleName(reinterpret_cast<LPCWSTR>(versionInfo.ModuleName));
      int iPos = cszModuleName.ReverseFind(_T('\\'));
      if (iPos != -1)
         cszModuleName = cszModuleName.Mid(iPos+1);

      CString cszTemp;
      cszTemp.Format(_T("   %s: %ls\n"),
         cszModuleName.GetString(),
         versionInfo.Version);

      // version numbers are separated with comma; use points instead
      cszTemp.Replace(_T(", "), _T("."));

      cszVersionText += cszTemp;
   }

   cszVersionText += _T("\n");
}

void Ref::EnumerateDevices(std::vector<std::shared_ptr<SourceInfo>>& vecSourceDevices) const
{
   // get size of buffer
   prUInt32 uiSize = 0;
   prResponse err = PR_GetDeviceList(&uiSize, nullptr);
   if ((err & prERROR_ERRORID_MASK) != prINSUFFICIENT_BUFFER)
   {
      LOG_TRACE(_T("PR_GetDeviceList(0, nullptr) returned %08x, buffer size %u\n"), err, uiSize);
      CheckError(_T("PR_GetDeviceList"), err, __FILE__, __LINE__);
      return;
   }

   if (uiSize == 0)
      return;

   std::vector<BYTE> vecBuffer(uiSize);
   prDeviceList* pDeviceList = reinterpret_cast<prDeviceList*>(&vecBuffer[0]);

   // may return prINVALID_FN_CALL, prINVALID_PARAMETER, prMEM_ALLOC_FAILED, prINSUFFICIENT_BUFFER, prINTERNAL_ERROR or @ERR
   err = PR_GetDeviceList(&uiSize, pDeviceList);
   if (uiSize != 4 && err != prOK) // only log non-empty lists
      LOG_TRACE(_T("PR_GetDeviceList(size = %u, buffer) returned %08x\n"), uiSize, err);
   CheckError(_T("PR_GetDeviceList"), err, __FILE__, __LINE__);

   prDeviceList& deviceList = *pDeviceList;
   for (prUInt32 ui=0; ui<deviceList.NumList; ui++)
   {
      prDeviceInfoTable& deviceInfo = deviceList.DeviceInfo[ui];

      LOG_TRACE(_T("device %u, ModelName=%ls, InternalName=%ls, Generation=%u, ModelID=%08x, PortType=%s\n"),
         ui,
         deviceInfo.ModelName,
         deviceInfo.DeviceInternalName,
         prSUB_GENERATION_CAMERA(deviceInfo.Generation),
         deviceInfo.ModelID,
         deviceInfo.PortType == 0x01 ? _T("WIA") : deviceInfo.PortType == 0x02 ? _T("STI") : _T("???")
      );

      std::shared_ptr<SourceInfo> spSourceInfo(
         new SourceInfoImpl(const_cast<Ref*>(this)->shared_from_this(), deviceInfo));

      vecSourceDevices.push_back(spSourceInfo);
   }
}
<|endoftext|>


<commit_before>#include "Zenderer/CoreGraphics/VertexArray.hpp"

using namespace zen::gfxcore;

CVertexArray::CVertexArray(const GLenum type) :
    CGLSubsystem("Vertex Array"),
    m_icount(0), m_vcount(0),
    m_vao(0), m_vbo(0), m_ibo(0),
    m_type(type)
{
    m_vaoIndices.clear();
    m_vaoVertices.clear();
}

CVertexArray::~CVertexArray()
{
    this->Destroy();
}

bool CVertexArray::Init()
{
    if(m_init) this->Destroy();

    // Bad GL version.
    if(!glGenVertexArrays) return false;

    GL(glGenVertexArrays(1, &m_vao));
    GL(glGenBuffers(1, &m_vbo));
    GL(glGenBuffers(1, &m_ibo));

    ZEN_ASSERT(m_vao != 0);
    ZEN_ASSERT(m_vbo != 0);
    ZEN_ASSERT(m_ibo != 0);

    return (m_init = true);
}

bool CVertexArray::Destroy()
{
    if(!m_init) return true;

    ZEN_ASSERT(m_vao != 0);
    ZEN_ASSERT(m_vbo != 0);
    ZEN_ASSERT(m_ibo != 0);

    glDeleteVertexArrays(1, &m_vao);
    glDeleteBuffers(1, &m_vbo);
    glDeleteBuffers(1, &m_ibo);

    return true;
}

bool CVertexArray::Bind()
{
    if(!m_init) return false;

    GL(glBindVertexArray(m_vao));
    GL(glEnableVertexAttribArray(0));       // Enable shader attribute 0
    GL(glEnableVertexAttribArray(1));
    GL(glEnableVertexAttribArray(2));
    return true;
}

bool CVertexArray::Unbind()
{
    if(!this->Init()) return false;

    GL(glBindVertexArray(0));

    return true;
}

index_t CVertexArray::AddData(const DrawBatch& D)
{
    ZEN_ASSERTM(D.vcount > 0, "no buffer vertices given");
    ZEN_ASSERTM(D.icount > 0, "no buffer indices given");

    m_vaoVertices.resize(m_vaoVertices.size() + D.vcount);
    for(size_t v = 0; v < D.vcount; ++v)
        m_vaoVertices.push_back(D.Vertices[v]);

    size_t offset = m_vaoIndices.size();

    m_vaoIndices.resize(m_vaoIndices.size() + D.icount);
    for(size_t i = 0; i < D.icount; ++i)
        m_vaoIndices.push_back(D.Indices[i]);

    return offset + m_icount;
}

bool CVertexArray::Offload()
{
    if(!this->Bind())       return false;
    if(this->Offloaded())   return false;

    // Check if there's existing data on the buffers.
    GLint bsize = 0;
    glGetBufferParameteriv(GL_ARRAY_BUFFER, GL_BUFFER_SIZE, &bsize);

    // There is!
    if(bsize > 0)
    {
        // Copy existing buffer data from GPU to local buffer.
        const vertex_t* const data = this->GetVerticesFromGPU();
        vertex_t* tmp  = new vertex_t[bsize / sizeof(vertex_t)];
        memcpy(tmp, data, bsize);
        glUnmapBuffer(GL_ARRAY_BUFFER);

        // Allocate enough GPU space for all vertex data, new and old.
        // Pass the old data directly to it.
        glBufferData(GL_ARRAY_BUFFER,
                     bsize + (sizeof(vertex_t) * m_vaoVertices.size()),
                     tmp, m_type);

        // Pass the latest vertex data at the end of the existing data.
        glBufferSubData(GL_ARRAY_BUFFER, bsize,
                        sizeof(vertex_t) * m_vaoVertices.size(),
                        &m_vaoVertices[0]);
    }
    // No existing buffer or vertices.
    else
    {
        // Allocate enough space for all vertices on GPU.
        glBufferData(GL_ARRAY_BUFFER,
                     sizeof(vertex_t) * m_vaoVertices.size(),
                     &m_vaoVertices[0], m_type);
    }

    // Repeat process for index buffer.
    bsize = 0;
    glGetBufferParameteriv(GL_ELEMENT_ARRAY_BUFFER, GL_BUFFER_SIZE, &bsize);

    if(bsize > 0)
    {
        // Copy from GPU to local buffer.
        const index_t* const data = this->GetIndicesFromGPU();
        index_t* tmp  = new index_t[bsize / sizeof(index_t)];
        memcpy(tmp, data, bsize);
        glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);

        // Allocate enough GPU space for all vertex data, new and old.
        // Pass the old data directly to it.
        glBufferData(GL_ELEMENT_ARRAY_BUFFER,                         // IBO
                     bsize + (sizeof(index_t) * m_vaoIndices.size()), // Size
                     tmp,       // Initial data
                     m_type);   // Access type

        // Pass the latest vertex data at the end of the existing data.
        glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, bsize,
                        sizeof(index_t) * m_vaoIndices.size(),
                        &m_vaoIndices[0]);
    }
    else
    {
        // No existing data, so we just write new stuff to the buffer.
        glBufferData(GL_ELEMENT_ARRAY_BUFFER,
                     sizeof(index_t) * m_vaoIndices.size(),
                     &m_vaoIndices[0], m_type);
    }

    // Vertices are arranged in memory like so:
    //
    // [ x, y, z, t, s, r, r, g, b, a ]
    //
    // (see the definition of vertex_t in Zenderer/CoreGraphics/OpenGL.hpp)
    //
    // Specify vertex position arrangement.
    // According to the diagram shown above, the vertex position
    // would start at index 0.
    glVertexAttribPointer(0,                /* Attribute index  */
                          3,                /* Number of values */
                          GL_FLOAT,         /* Type of value    */
                          GL_FALSE,         /* Normalized?      */
                          sizeof(vertex_t), /* Size of field    */
        VBO_OFFSET(0, vertex_t, position)); /* Size of offset   */

    // Specify texture coordinate position arrangement.
    // According to the diagram, texture coordinates
    // start at index 3.
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(vertex_t),
                          VBO_OFFSET(0, vertex_t, tc));

    // Specify the color arrangement, starting at index 4.
    glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, sizeof(vertex_t),
                          VBO_OFFSET(0, vertex_t, color));

    // We're done, clean up buffers.
    m_vcount += m_vaoVertices.size();
    m_icount += m_vaoIndices.size();

    m_vaoVertices.clear();
    m_vaoIndices.clear();

    return this->Unbind();
}

const vertex_t* const CVertexArray::GetVerticesFromGPU() const
{
    return (vertex_t*)glMapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY);
}

const index_t* const CVertexArray::GetIndicesFromGPU() const
{
    return (index_t*)glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_READ_ONLY);
}

size_t CVertexArray::GetVertexCount() const
{
    return m_vcount;
}

size_t CVertexArray::GetIndexCount() const
{
    return m_icount;
}

bool CVertexArray::Offloaded() const
{
    return (m_vaoIndices.size() == 0 && m_vaoVertices.size() == 0);
}
<commit_msg>Better error support; bind buffers too<commit_after>#include "Zenderer/CoreGraphics/VertexArray.hpp"

using namespace zen::gfxcore;

CVertexArray::CVertexArray(const GLenum type) :
    CGLSubsystem("Vertex Array"),
    m_icount(0), m_vcount(0),
    m_vao(0), m_vbo(0), m_ibo(0),
    m_type(type)
{
    m_vaoIndices.clear();
    m_vaoVertices.clear();
}

CVertexArray::~CVertexArray()
{
    this->Destroy();
}

bool CVertexArray::Init()
{
    if(m_init) this->Destroy();

    // Bad GL version.
    if(!glGenVertexArrays) return false;

    GL(glGenVertexArrays(1, &m_vao));
    GL(glGenBuffers(1, &m_vbo));
    GL(glGenBuffers(1, &m_ibo));

    ZEN_ASSERT(m_vao != 0);
    ZEN_ASSERT(m_vbo != 0);
    ZEN_ASSERT(m_ibo != 0);

    return (m_init = true);
}

bool CVertexArray::Destroy()
{
    if(!m_init) return true;

    ZEN_ASSERT(m_vao != 0);
    ZEN_ASSERT(m_vbo != 0);
    ZEN_ASSERT(m_ibo != 0);

    glDeleteVertexArrays(1, &m_vao);
    glDeleteBuffers(1, &m_vbo);
    glDeleteBuffers(1, &m_ibo);

    return true;
}

bool CVertexArray::Bind()
{
    if(!m_init) return false;

    GL(glBindVertexArray(m_vao));
    GL(glEnableVertexAttribArray(0));       // Enable shader attribute 0
    GL(glEnableVertexAttribArray(1));
    GL(glEnableVertexAttribArray(2));

    GL(glBindBuffer(GL_ARRAY_BUFFER, m_vbo));
    GL(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ibo));

    return true;
}

bool CVertexArray::Unbind()
{
    if(!m_init) return false;

    GL(glBindBuffer(GL_ARRAY_BUFFER, 0));
    GL(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
    GL(glBindVertexArray(0));

    return true;
}

index_t CVertexArray::AddData(const DrawBatch& D)
{
    ZEN_ASSERTM(D.vcount > 0, "no buffer vertices given");
    ZEN_ASSERTM(D.icount > 0, "no buffer indices given");

    m_vaoVertices.resize(m_vaoVertices.size() + D.vcount);
    for(size_t v = 0; v < D.vcount; ++v)
        m_vaoVertices.push_back(D.Vertices[v]);

    size_t offset = m_vaoIndices.size();

    m_vaoIndices.resize(m_vaoIndices.size() + D.icount);
    for(size_t i = 0; i < D.icount; ++i)
        m_vaoIndices.push_back(D.Indices[i]);

    return offset + m_icount;
}

bool CVertexArray::Offload()
{
    if(!this->Bind())       return false;
    if(this->Offloaded())   return false;

    // Check if there's existing data on the buffers.
    GLint bsize = 0;
    GL(glGetBufferParameteriv(GL_ARRAY_BUFFER, GL_BUFFER_SIZE, &bsize));

    // There is!
    if(bsize > 0)
    {
        // Copy existing buffer data from GPU to local buffer.
        const vertex_t* const data = this->GetVerticesFromGPU();
        vertex_t* tmp  = new vertex_t[bsize / sizeof(vertex_t)];
        memcpy(tmp, data, bsize);
        GL(glUnmapBuffer(GL_ARRAY_BUFFER));

        // Allocate enough GPU space for all vertex data, new and old.
        // Pass the old data directly to it.
        GL(glBufferData(GL_ARRAY_BUFFER,
                        bsize + (sizeof(vertex_t) * m_vaoVertices.size()),
                        tmp, m_type));

        // Pass the latest vertex data at the end of the existing data.
        GL(glBufferSubData(GL_ARRAY_BUFFER, bsize,
                           sizeof(vertex_t) * m_vaoVertices.size(),
                           &m_vaoVertices[0]));
    }
    // No existing buffer or vertices.
    else
    {
        // Allocate enough space for all vertices on GPU.
        GL(glBufferData(GL_ARRAY_BUFFER,
                        sizeof(vertex_t) * m_vaoVertices.size(),
                        &m_vaoVertices[0], m_type));
    }

    // Repeat process for index buffer.
    bsize = 0;
    GL(glGetBufferParameteriv(GL_ELEMENT_ARRAY_BUFFER, GL_BUFFER_SIZE, &bsize));

    if(bsize > 0)
    {
        // Copy from GPU to local buffer.
        const index_t* const data = this->GetIndicesFromGPU();
        index_t* tmp  = new index_t[bsize / sizeof(index_t)];
        memcpy(tmp, data, bsize);
        GL(glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER));

        // Allocate enough GPU space for all vertex data, new and old.
        // Pass the old data directly to it.
        GL(glBufferData(GL_ELEMENT_ARRAY_BUFFER,                        // IBO
                        bsize + (sizeof(index_t) * m_vaoIndices.size()),// Size
                        tmp,       // Initial data
                        m_type));  // Access type

        // Pass the latest vertex data at the end of the existing data.
        GL(glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, bsize,
                           sizeof(index_t) * m_vaoIndices.size(),
                           &m_vaoIndices[0]));
    }
    else
    {
        // No existing data, so we just write new stuff to the buffer.
        GL(glBufferData(GL_ELEMENT_ARRAY_BUFFER,
                        sizeof(index_t) * m_vaoIndices.size(),
                        &m_vaoIndices[0], m_type));
    }

    // Vertices are arranged in memory like so:
    //
    // [ x, y, z, t, s, r, r, g, b, a ]
    //
    // (see the definition of vertex_t in Zenderer/CoreGraphics/OpenGL.hpp)
    //
    // Specify vertex position arrangement.
    // According to the diagram shown above, the vertex position
    // would start at index 0.
    GL(glVertexAttribPointer(0,             /* Attribute index  */
                          3,                /* Number of values */
                          GL_FLOAT,         /* Type of value    */
                          GL_FALSE,         /* Normalized?      */
                          sizeof(vertex_t), /* Size of field    */
        VBO_OFFSET(0, vertex_t, position)));/* Size of offset   */

    // Specify texture coordinate position arrangement.
    // According to the diagram, texture coordinates
    // start at index 3.
    GL(glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(vertex_t),
                             VBO_OFFSET(0, vertex_t, tc)));

    // Specify the color arrangement, starting at index 4.
    GL(glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, sizeof(vertex_t),
                             VBO_OFFSET(0, vertex_t, color)));

    // We're done, clean up buffers.
    m_vcount += m_vaoVertices.size();
    m_icount += m_vaoIndices.size();

    m_vaoVertices.clear();
    m_vaoIndices.clear();

    return this->Unbind();
}

const vertex_t* const CVertexArray::GetVerticesFromGPU() const
{
    return (vertex_t*)GL(glMapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY));
}

const index_t* const CVertexArray::GetIndicesFromGPU() const
{
    return (index_t*)GL(glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_READ_ONLY));
}

size_t CVertexArray::GetVertexCount() const
{
    return m_vcount;
}

size_t CVertexArray::GetIndexCount() const
{
    return m_icount;
}

bool CVertexArray::Offloaded() const
{
    return (m_vaoIndices.size() == 0 && m_vaoVertices.size() == 0);
}
<|endoftext|>


<commit_before>
/*
 *  $Author$
 *  $Date$
 *  $Revision$
 *

 */
#ifdef SRCDIRTREE
#include "ct_defs.h"
#include "ctml.h"
#include "GasKinetics.h"
#include "importCTML.h"
#include "ThermoPhase.h"
#include "InterfaceKinetics.h"
#else
#include "Cantera.h"
#include "kernel/ct_defs.h"
#include "kernel/ctml.h"
#include "kernel/GasKinetics.h"
#include "kernel/importCTML.h"
#include "kernel/ThermoPhase.h"
#include "kernel/InterfaceKinetics.h"
#endif

using namespace Cantera;

#
int main(int argc, char **argv) {
  try {
    int i;
    string infile = "noxNeg.cti";
    double x[20];
    double cdot[20], ddot[20];

    XML_Node *xc = new XML_Node();
    string path = findInputFile(infile);
    ctml::get_CTML_Tree(xc, path);

    XML_Node * const xg = xc->findNameID("phase", "air");
    ThermoPhase *gasTP = newPhase(*xg);
    int nsp = gasTP->nSpecies();
    cout << "Number of species = " << nsp << endl;

    vector<ThermoPhase *> phaseList;
    phaseList.push_back(gasTP);
    GasKinetics *iKin_ptr = new GasKinetics();
    importKinetics(*xg, phaseList, iKin_ptr);
    int nr = iKin_ptr->nReactions();
    cout << "Number of reactions = " << nr << endl;

    int iH2 = gasTP->speciesIndex("H2");
    int iH = gasTP->speciesIndex("H");
    int iO2 = gasTP->speciesIndex("O2");
    int iOH = gasTP->speciesIndex("OH");
    int iH2O = gasTP->speciesIndex("H2O");
    int iNH = gasTP->speciesIndex("NH");
    int iNO = gasTP->speciesIndex("NO");
    int iN2O = gasTP->speciesIndex("N2O");

    for (i = 0; i < nsp; i++) {
      x[i] = 0.0;
    }
    x[iH2O] = 1.0 /2.0;
    x[iOH]  = 0.1 /2.0;
    x[iH]   = 0.2 /2.0;
    x[iO2]  = 0.3 /2.0;
    x[iH2]  = 0.25 /2.0;
    x[iNH]  = 0.05/2.0;
    x[iNO]  = 0.05/2.0;
    x[iN2O]  = 0.05/2.0;

    double p = OneAtm;

    gasTP->setState_TPX(2000., p, x);

    double src[20];
    for (i = 0; i < 20; i++) src[i] = 0.0;
    iKin_ptr->getNetProductionRates(src);

    for (i = 0; i < nsp; i++) {
      string sSt = gasTP->speciesName(i);
      printf("rop [ %d:%s ] = %g \n", i, sSt.c_str(), src[i]);
    }

    int nReactions = iKin_ptr->nReactions();
    cout << "number of reactions = " << nReactions << endl;

    double fwd_rop[20];
    double rev_rop[20];
    iKin_ptr->getFwdRatesOfProgress(fwd_rop);
    iKin_ptr->getRevRatesOfProgress(rev_rop);
    for (i = 0; i < nReactions; i++) {
      printf("fwd_rop[%3d] = %13g    rev_rop[%3d] = %13g\n", i, fwd_rop[i],
	     i, rev_rop[i]);
    }

    iKin_ptr->getCreationRates(cdot);
    iKin_ptr->getDestructionRates(ddot);

    return 0;
  }
  catch (CanteraError) {
    showErrors(cerr);
    cerr << "program terminating." << endl;
    return -1;
  }
}
<commit_msg>Added the namespace std;<commit_after>
/*
 *  $Author$
 *  $Date$
 *  $Revision$
 *

 */
#ifdef SRCDIRTREE
#include "ct_defs.h"
#include "ctml.h"
#include "GasKinetics.h"
#include "importCTML.h"
#include "ThermoPhase.h"
#include "InterfaceKinetics.h"
#else
#include "Cantera.h"
#include "kernel/ct_defs.h"
#include "kernel/ctml.h"
#include "kernel/GasKinetics.h"
#include "kernel/importCTML.h"
#include "kernel/ThermoPhase.h"
#include "kernel/InterfaceKinetics.h"
#endif

using namespace Cantera;
using namespace std;

#
int main(int argc, char **argv) {
  try {
    int i;
    string infile = "noxNeg.cti";
    double x[20];
    double cdot[20], ddot[20];

    XML_Node *xc = new XML_Node();
    string path = findInputFile(infile);
    ctml::get_CTML_Tree(xc, path);

    XML_Node * const xg = xc->findNameID("phase", "air");
    ThermoPhase *gasTP = newPhase(*xg);
    int nsp = gasTP->nSpecies();
    cout << "Number of species = " << nsp << endl;

    vector<ThermoPhase *> phaseList;
    phaseList.push_back(gasTP);
    GasKinetics *iKin_ptr = new GasKinetics();
    importKinetics(*xg, phaseList, iKin_ptr);
    int nr = iKin_ptr->nReactions();
    cout << "Number of reactions = " << nr << endl;

    int iH2 = gasTP->speciesIndex("H2");
    int iH = gasTP->speciesIndex("H");
    int iO2 = gasTP->speciesIndex("O2");
    int iOH = gasTP->speciesIndex("OH");
    int iH2O = gasTP->speciesIndex("H2O");
    int iNH = gasTP->speciesIndex("NH");
    int iNO = gasTP->speciesIndex("NO");
    int iN2O = gasTP->speciesIndex("N2O");

    for (i = 0; i < nsp; i++) {
      x[i] = 0.0;
    }
    x[iH2O] = 1.0 /2.0;
    x[iOH]  = 0.1 /2.0;
    x[iH]   = 0.2 /2.0;
    x[iO2]  = 0.3 /2.0;
    x[iH2]  = 0.25 /2.0;
    x[iNH]  = 0.05/2.0;
    x[iNO]  = 0.05/2.0;
    x[iN2O]  = 0.05/2.0;

    double p = OneAtm;

    gasTP->setState_TPX(2000., p, x);

    double src[20];
    for (i = 0; i < 20; i++) src[i] = 0.0;
    iKin_ptr->getNetProductionRates(src);

    for (i = 0; i < nsp; i++) {
      string sSt = gasTP->speciesName(i);
      printf("rop [ %d:%s ] = %g \n", i, sSt.c_str(), src[i]);
    }

    int nReactions = iKin_ptr->nReactions();
    cout << "number of reactions = " << nReactions << endl;

    double fwd_rop[20];
    double rev_rop[20];
    iKin_ptr->getFwdRatesOfProgress(fwd_rop);
    iKin_ptr->getRevRatesOfProgress(rev_rop);
    for (i = 0; i < nReactions; i++) {
      printf("fwd_rop[%3d] = %13g    rev_rop[%3d] = %13g\n", i, fwd_rop[i],
	     i, rev_rop[i]);
    }

    iKin_ptr->getCreationRates(cdot);
    iKin_ptr->getDestructionRates(ddot);

    return 0;
  }
  catch (CanteraError) {
    showErrors(cerr);
    cerr << "program terminating." << endl;
    return -1;
  }
}
<|endoftext|>


<commit_before><commit_msg>remove auto generated file: src/nark/my_auto_config.hpp<commit_after><|endoftext|>


<commit_before><commit_msg>Fixed problems with game ending in local play (#2530837)<commit_after><|endoftext|>


<commit_before>#ifndef __STAN__IO__VAR_CONTEXT_HPP__
#define __STAN__IO__VAR_CONTEXT_HPP__

#include <cstddef>
#include <sstream>
#include <string>
#include <vector>

namespace stan {

  namespace io {

    /**
     * A var_reader reads array variables of integer and
     * floating point type by name and dimension.
     *
     *
An array's dimensionality is described by a sequence of
     * (unsigned) integers.  For instance, (7, 2, 3) picks
     * out a 7 by 2 by 3 array.  The empty dimensionality sequence
     * () is used for scalars.
     *
     *
Multidimensional arrays are stored in column-major order,
     * meaning the first index changes the most quickly.
     *
     *
If a variable has integer variables, it should return
     * those integer values cast to floating point values when
     * accessed through the floating-point methods.
     */
    class var_context {
    public:

      /**
       * Return true if the specified variable name is
       * defined.  This method should return true even
       * if the values are all integers.
       *
       * @param name Name of variable.
       * @return true if the variable exists with real
       * values.
       */
      virtual bool contains_r(const std::string& name) const = 0;

      /**
       * Return the floating point values for the variable of the
       * specified variable name in last-index-major order.  This
       * method should cast integers to floating point values if the
       * values of the named variable are all integers.
       *
       *
If there is no variable of the specified name, the empty
       * vector is returned.
       *
       * @param name Name of variable.
       * @return Sequence of values for the named variable.
       */
      virtual std::vector<double> vals_r(const std::string& name) const = 0;

      /**
       * Return the dimensions for the specified floating point variable.
       * If the variable doesn't exist or if it is a scalar, the
       * return result should be the empty vector.
       *
       * @param name Name of variable.
       * @return Sequence of dimensions for the variable.
       */
      virtual std::vector<size_t> dims_r(const std::string& name) const = 0;

      /**
       * Return true if the specified variable name has
       * integer values.
       *
       * @param name Name of variable.
       * @return true if an integer variable of the specified
       * name is defined.
       */
      virtual bool contains_i(const std::string& name) const = 0;

      /**
       * Return the integer values for the variable of the specified
       * name in last-index-major order or the empty sequence if the
       * variable is not defined.
       *
       * @param name Name of variable.
       * @return Sequence of integer values.
       */
      virtual std::vector<int> vals_i(const std::string& name) const = 0;

      /**
       * Return the dimensions of the specified floating point variable.
       * If the variable doesn't exist (or if it is a scalar), the
       * return result should be the empty vector.
       *
       * @param name Name of variable.
       * @return Sequence of dimensions for the variable.
       */
      virtual std::vector<size_t> dims_i(const std::string& name) const = 0;

      /**
       * Return a list of the names of the floating point variables in
       * the context.
       *
       * @param names Vector to store the list of names in.
       */
      virtual void names_r(std::vector<std::string>& names) const = 0;

      /**
       * Return a list of the names of the integer variables in
       * the context.
       *
       * @param names Vector to store the list of names in.
       */
      virtual void names_i(std::vector<std::string>& names) const = 0;

      void add_vec(std::stringstream& msg,
                   std::vector<size_t> dims) {
        msg << '(';
        for (size_t i = 0; i < dims.size(); ++i) {
          if (i > 0) msg << ',';
          msg << dims[i];
        }
        msg << ')';
      }

      void validate_dims(const std::string& name,
                         const std::vector<size_t>& dims_declared) {
        std::vector<size_t> dims = dims_r(name);
        if (dims.size() != dims_declared.size()) {
          std::stringstream msg;
          msg << "mismatch in number dimensions declared and found in context";
          msg << "; dims declared=";
          add_vec(msg,dims_declared);
          msg << "; dims found=";
          add_vec(msg,dims);
          throw std::runtime_error(msg.str());
        }
        for (size_t i = 0; i < dims.size(); ++i) {
          if (dims_declared[i] != dims[i]) {
            std::stringstream msg;
            msg << "mismatch in dimension declared and found in context";
            msg << "; position=";
            msg << i;
            msg << "; dims declared=";
            add_vec(msg,dims_declared);
            msg << "; dims found=";
            add_vec(msg,dims);
            throw std::runtime_error(msg.str());
          }
        }
      }

      static std::vector<size_t> to_vec() {
        return std::vector<size_t>();
      }
      static std::vector<size_t> to_vec(size_t n1) {
        std::vector<size_t> v(1);
        v[0] = n1;
        return v;
      }
      static std::vector<size_t> to_vec(size_t n1, size_t n2) {
        std::vector<size_t> v(2);
        v[0] = n1;
        v[1] = n2;
        return v;
      }
      static std::vector<size_t> to_vec(size_t n1, size_t n2,
                                        size_t n3) {
        std::vector<size_t> v(3);
        v[0] = n1;
        v[1] = n2;
        v[2] = n3;
        return v;
      }
      static std::vector<size_t> to_vec(size_t n1, size_t n2,
                                        size_t n3, size_t n4) {
        std::vector<size_t> v(4);
        v[0] = n1;
        v[1] = n2;
        v[2] = n3;
        v[3] = n4;
        return v;
      }
      static std::vector<size_t> to_vec(size_t n1, size_t n2,
                                        size_t n3, size_t n4,
                                        size_t n5) {
        std::vector<size_t> v(5);
        v[0] = n1;
        v[1] = n2;
        v[2] = n3;
        v[3] = n4;
        v[4] = n5;
        return v;
      }
      static std::vector<size_t> to_vec(size_t n1, size_t n2,
                                        size_t n3, size_t n4,
                                        size_t n5, size_t n6) {
        std::vector<size_t> v(6);
        v[0] = n1;
        v[1] = n2;
        v[2] = n3;
        v[3] = n4;
        v[4] = n5;
        v[5] = n6;
        return v;
      }
      static std::vector<size_t> to_vec(size_t n1, size_t n2,
                                        size_t n3, size_t n4,
                                        size_t n5, size_t n6,
                                        size_t n7) {
        std::vector<size_t> v(7);
        v[0] = n1;
        v[1] = n2;
        v[2] = n3;
        v[3] = n4;
        v[4] = n5;
        v[5] = n6;
        v[6] = n7;
        return v;
      }
      static std::vector<size_t> to_vec(size_t n1, size_t n2,
                                        size_t n3, size_t n4,
                                        size_t n5, size_t n6,
                                        size_t n7, size_t n8) {
        std::vector<size_t> v(8);
        v[0] = n1;
        v[1] = n2;
        v[2] = n3;
        v[3] = n4;
        v[4] = n5;
        v[5] = n6;
        v[6] = n7;
        v[7] = n8;
        return v;
      }
    };

  }

}

#endif
<commit_msg>added requisite include for var_context exceptions<commit_after>#ifndef __STAN__IO__VAR_CONTEXT_HPP__
#define __STAN__IO__VAR_CONTEXT_HPP__

#include <cstddef>
#include <sstream>
#include <stdexcept>
#include <string>
#include <vector>

namespace stan {

  namespace io {

    /**
     * A var_reader reads array variables of integer and
     * floating point type by name and dimension.
     *
     *
An array's dimensionality is described by a sequence of
     * (unsigned) integers.  For instance, (7, 2, 3) picks
     * out a 7 by 2 by 3 array.  The empty dimensionality sequence
     * () is used for scalars.
     *
     *
Multidimensional arrays are stored in column-major order,
     * meaning the first index changes the most quickly.
     *
     *
If a variable has integer variables, it should return
     * those integer values cast to floating point values when
     * accessed through the floating-point methods.
     */
    class var_context {
    public:

      /**
       * Return true if the specified variable name is
       * defined.  This method should return true even
       * if the values are all integers.
       *
       * @param name Name of variable.
       * @return true if the variable exists with real
       * values.
       */
      virtual bool contains_r(const std::string& name) const = 0;

      /**
       * Return the floating point values for the variable of the
       * specified variable name in last-index-major order.  This
       * method should cast integers to floating point values if the
       * values of the named variable are all integers.
       *
       *
If there is no variable of the specified name, the empty
       * vector is returned.
       *
       * @param name Name of variable.
       * @return Sequence of values for the named variable.
       */
      virtual std::vector<double> vals_r(const std::string& name) const = 0;

      /**
       * Return the dimensions for the specified floating point variable.
       * If the variable doesn't exist or if it is a scalar, the
       * return result should be the empty vector.
       *
       * @param name Name of variable.
       * @return Sequence of dimensions for the variable.
       */
      virtual std::vector<size_t> dims_r(const std::string& name) const = 0;

      /**
       * Return true if the specified variable name has
       * integer values.
       *
       * @param name Name of variable.
       * @return true if an integer variable of the specified
       * name is defined.
       */
      virtual bool contains_i(const std::string& name) const = 0;

      /**
       * Return the integer values for the variable of the specified
       * name in last-index-major order or the empty sequence if the
       * variable is not defined.
       *
       * @param name Name of variable.
       * @return Sequence of integer values.
       */
      virtual std::vector<int> vals_i(const std::string& name) const = 0;

      /**
       * Return the dimensions of the specified floating point variable.
       * If the variable doesn't exist (or if it is a scalar), the
       * return result should be the empty vector.
       *
       * @param name Name of variable.
       * @return Sequence of dimensions for the variable.
       */
      virtual std::vector<size_t> dims_i(const std::string& name) const = 0;

      /**
       * Return a list of the names of the floating point variables in
       * the context.
       *
       * @param names Vector to store the list of names in.
       */
      virtual void names_r(std::vector<std::string>& names) const = 0;

      /**
       * Return a list of the names of the integer variables in
       * the context.
       *
       * @param names Vector to store the list of names in.
       */
      virtual void names_i(std::vector<std::string>& names) const = 0;

      void add_vec(std::stringstream& msg,
                   std::vector<size_t> dims) {
        msg << '(';
        for (size_t i = 0; i < dims.size(); ++i) {
          if (i > 0) msg << ',';
          msg << dims[i];
        }
        msg << ')';
      }

      void validate_dims(const std::string& name,
                         const std::vector<size_t>& dims_declared) {
        std::vector<size_t> dims = dims_r(name);
        if (dims.size() != dims_declared.size()) {
          std::stringstream msg;
          msg << "mismatch in number dimensions declared and found in context";
          msg << "; dims declared=";
          add_vec(msg,dims_declared);
          msg << "; dims found=";
          add_vec(msg,dims);
          throw std::runtime_error(msg.str());
        }
        for (size_t i = 0; i < dims.size(); ++i) {
          if (dims_declared[i] != dims[i]) {
            std::stringstream msg;
            msg << "mismatch in dimension declared and found in context";
            msg << "; position=";
            msg << i;
            msg << "; dims declared=";
            add_vec(msg,dims_declared);
            msg << "; dims found=";
            add_vec(msg,dims);
            throw std::runtime_error(msg.str());
          }
        }
      }

      static std::vector<size_t> to_vec() {
        return std::vector<size_t>();
      }
      static std::vector<size_t> to_vec(size_t n1) {
        std::vector<size_t> v(1);
        v[0] = n1;
        return v;
      }
      static std::vector<size_t> to_vec(size_t n1, size_t n2) {
        std::vector<size_t> v(2);
        v[0] = n1;
        v[1] = n2;
        return v;
      }
      static std::vector<size_t> to_vec(size_t n1, size_t n2,
                                        size_t n3) {
        std::vector<size_t> v(3);
        v[0] = n1;
        v[1] = n2;
        v[2] = n3;
        return v;
      }
      static std::vector<size_t> to_vec(size_t n1, size_t n2,
                                        size_t n3, size_t n4) {
        std::vector<size_t> v(4);
        v[0] = n1;
        v[1] = n2;
        v[2] = n3;
        v[3] = n4;
        return v;
      }
      static std::vector<size_t> to_vec(size_t n1, size_t n2,
                                        size_t n3, size_t n4,
                                        size_t n5) {
        std::vector<size_t> v(5);
        v[0] = n1;
        v[1] = n2;
        v[2] = n3;
        v[3] = n4;
        v[4] = n5;
        return v;
      }
      static std::vector<size_t> to_vec(size_t n1, size_t n2,
                                        size_t n3, size_t n4,
                                        size_t n5, size_t n6) {
        std::vector<size_t> v(6);
        v[0] = n1;
        v[1] = n2;
        v[2] = n3;
        v[3] = n4;
        v[4] = n5;
        v[5] = n6;
        return v;
      }
      static std::vector<size_t> to_vec(size_t n1, size_t n2,
                                        size_t n3, size_t n4,
                                        size_t n5, size_t n6,
                                        size_t n7) {
        std::vector<size_t> v(7);
        v[0] = n1;
        v[1] = n2;
        v[2] = n3;
        v[3] = n4;
        v[4] = n5;
        v[5] = n6;
        v[6] = n7;
        return v;
      }
      static std::vector<size_t> to_vec(size_t n1, size_t n2,
                                        size_t n3, size_t n4,
                                        size_t n5, size_t n6,
                                        size_t n7, size_t n8) {
        std::vector<size_t> v(8);
        v[0] = n1;
        v[1] = n2;
        v[2] = n3;
        v[3] = n4;
        v[4] = n5;
        v[5] = n6;
        v[6] = n7;
        v[7] = n8;
        return v;
      }
    };

  }

}

#endif
<|endoftext|>


<commit_before>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ash/drag_drop/drag_drop_tracker.h"

#include "ash/shell.h"
#include "ash/shell_window_ids.h"
#include "ash/wm/coordinate_conversion.h"
#include "ui/aura/client/window_tree_client.h"
#include "ui/aura/window.h"
#include "ui/aura/window_event_dispatcher.h"
#include "ui/events/event.h"
#include "ui/gfx/screen.h"
#include "ui/wm/core/coordinate_conversion.h"
#include "ui/wm/public/activation_delegate.h"

namespace ash {
namespace {

// An activation delegate which disables activating the drag and drop window.
class CaptureWindowActivationDelegate
    : public aura::client::ActivationDelegate {
 public:
  CaptureWindowActivationDelegate() {}
  virtual ~CaptureWindowActivationDelegate() {}

  // aura::client::ActivationDelegate overrides:
  virtual bool ShouldActivate() const OVERRIDE {
    return false;
  }

 private:

  DISALLOW_COPY_AND_ASSIGN(CaptureWindowActivationDelegate);
};

// Creates a window for capturing drag events.
aura::Window* CreateCaptureWindow(aura::Window* context_root,
                                  aura::WindowDelegate* delegate) {
  static CaptureWindowActivationDelegate* activation_delegate_instance = NULL;
  if (!activation_delegate_instance)
    activation_delegate_instance = new CaptureWindowActivationDelegate;
  aura::Window* window = new aura::Window(delegate);
  window->SetType(ui::wm::WINDOW_TYPE_NORMAL);
  window->Init(aura::WINDOW_LAYER_NOT_DRAWN);
  aura::client::ParentWindowWithContext(window, context_root, gfx::Rect());
  aura::client::SetActivationDelegate(window, activation_delegate_instance);
  window->Show();
  DCHECK(window->bounds().size().IsEmpty());
  return window;
}

}  // namespace

DragDropTracker::DragDropTracker(aura::Window* context_root,
                                 aura::WindowDelegate* delegate)
    : capture_window_(CreateCaptureWindow(context_root, delegate)) {
}

DragDropTracker::~DragDropTracker()  {
  capture_window_->ReleaseCapture();
}

void DragDropTracker::TakeCapture() {
  capture_window_->SetCapture();
}

aura::Window* DragDropTracker::GetTarget(const ui::LocatedEvent& event) {
  DCHECK(capture_window_.get());
  gfx::Point location_in_screen = event.location();
  ::wm::ConvertPointToScreen(capture_window_.get(), &location_in_screen);
  aura::Window* root_window_at_point =
      wm::GetRootWindowAt(location_in_screen);
  gfx::Point location_in_root = location_in_screen;
  ::wm::ConvertPointFromScreen(root_window_at_point, &location_in_root);
  return root_window_at_point->GetEventHandlerForPoint(location_in_root);
}

ui::LocatedEvent* DragDropTracker::ConvertEvent(
    aura::Window* target,
    const ui::LocatedEvent& event) {
  DCHECK(capture_window_.get());
  gfx::Point target_location = event.location();
  aura::Window::ConvertPointToTarget(capture_window_.get(), target,
                                     &target_location);
  gfx::Point location_in_screen = event.location();
  ::wm::ConvertPointToScreen(capture_window_.get(), &location_in_screen);
  gfx::Point target_root_location = event.root_location();
  aura::Window::ConvertPointToTarget(
      capture_window_->GetRootWindow(),
      ash::wm::GetRootWindowAt(location_in_screen),
      &target_root_location);
  return new ui::MouseEvent(event.type(),
                            target_location,
                            target_root_location,
                            event.flags(),
                            static_cast<const ui::MouseEvent&>(event).
                                changed_button_flags());
}

}  // namespace ash
<commit_msg>Change type of drag-drop window to popup<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ash/drag_drop/drag_drop_tracker.h"

#include "ash/shell.h"
#include "ash/shell_window_ids.h"
#include "ash/wm/coordinate_conversion.h"
#include "ui/aura/client/window_tree_client.h"
#include "ui/aura/window.h"
#include "ui/aura/window_event_dispatcher.h"
#include "ui/events/event.h"
#include "ui/gfx/screen.h"
#include "ui/wm/core/coordinate_conversion.h"
#include "ui/wm/public/activation_delegate.h"

namespace ash {
namespace {

// An activation delegate which disables activating the drag and drop window.
class CaptureWindowActivationDelegate
    : public aura::client::ActivationDelegate {
 public:
  CaptureWindowActivationDelegate() {}
  virtual ~CaptureWindowActivationDelegate() {}

  // aura::client::ActivationDelegate overrides:
  virtual bool ShouldActivate() const OVERRIDE {
    return false;
  }

 private:

  DISALLOW_COPY_AND_ASSIGN(CaptureWindowActivationDelegate);
};

// Creates a window for capturing drag events.
aura::Window* CreateCaptureWindow(aura::Window* context_root,
                                  aura::WindowDelegate* delegate) {
  static CaptureWindowActivationDelegate* activation_delegate_instance = NULL;
  if (!activation_delegate_instance)
    activation_delegate_instance = new CaptureWindowActivationDelegate;
  aura::Window* window = new aura::Window(delegate);
  // Set type of window as popup to prevent different window manager codes
  // trying to manage this window.
  window->SetType(ui::wm::WINDOW_TYPE_POPUP);
  window->Init(aura::WINDOW_LAYER_NOT_DRAWN);
  aura::client::ParentWindowWithContext(window, context_root, gfx::Rect());
  aura::client::SetActivationDelegate(window, activation_delegate_instance);
  window->Show();
  DCHECK(window->bounds().size().IsEmpty());
  return window;
}

}  // namespace

DragDropTracker::DragDropTracker(aura::Window* context_root,
                                 aura::WindowDelegate* delegate)
    : capture_window_(CreateCaptureWindow(context_root, delegate)) {
}

DragDropTracker::~DragDropTracker()  {
  capture_window_->ReleaseCapture();
}

void DragDropTracker::TakeCapture() {
  capture_window_->SetCapture();
}

aura::Window* DragDropTracker::GetTarget(const ui::LocatedEvent& event) {
  DCHECK(capture_window_.get());
  gfx::Point location_in_screen = event.location();
  ::wm::ConvertPointToScreen(capture_window_.get(), &location_in_screen);
  aura::Window* root_window_at_point =
      wm::GetRootWindowAt(location_in_screen);
  gfx::Point location_in_root = location_in_screen;
  ::wm::ConvertPointFromScreen(root_window_at_point, &location_in_root);
  return root_window_at_point->GetEventHandlerForPoint(location_in_root);
}

ui::LocatedEvent* DragDropTracker::ConvertEvent(
    aura::Window* target,
    const ui::LocatedEvent& event) {
  DCHECK(capture_window_.get());
  gfx::Point target_location = event.location();
  aura::Window::ConvertPointToTarget(capture_window_.get(), target,
                                     &target_location);
  gfx::Point location_in_screen = event.location();
  ::wm::ConvertPointToScreen(capture_window_.get(), &location_in_screen);
  gfx::Point target_root_location = event.root_location();
  aura::Window::ConvertPointToTarget(
      capture_window_->GetRootWindow(),
      ash::wm::GetRootWindowAt(location_in_screen),
      &target_root_location);
  return new ui::MouseEvent(event.type(),
                            target_location,
                            target_root_location,
                            event.flags(),
                            static_cast<const ui::MouseEvent&>(event).
                                changed_button_flags());
}

}  // namespace ash
<|endoftext|>


<commit_before>#include <algorithm>

#include "Vajra/Common/Messages/Message.h"
#include "Vajra/Engine/Core/Engine.h"
#include "Vajra/Engine/Input/Input.h"
#include "Vajra/Engine/MessageHub/MessageHub.h"
#include "Vajra/Engine/SceneGraph/SceneGraphUi.h"
#include "Vajra/Engine/SceneGraph/SceneGraph3D.h"
#include "Vajra/Utilities/Utilities.h"

#if PLATFORM_DESKTOP
#include "Vajra/Engine/Timer/Timer.h"
// Global callback function for desktop input
void cursorPosCallback(int x, int y) {
	ENGINE->GetInput()->cursorPosUpdate(x, y);
}
#endif

Input::Input() {
}

Input::~Input() {
	this->destroy();
}

void Input::init() {
	this->nextFingerId = 0;
#if PLATFORM_DESKTOP
	glfwSetMousePosCallback(cursorPosCallback);
#endif
}

void Input::destroy() {
	this->currentTouchTarget = nullptr;
}

bool touchOver(const Touch &touch) {
	return (touch.phase == TouchPhase::Ended
			|| touch.phase == TouchPhase::Cancelled);
}

void Input::updateInput() {
#if PLATFORM_DESKTOP
	this->updateDesktopInput();
#endif
	// Populate frame touches with all input that has been asynchronously collected
	this->frameTouches = this->asyncTouches;

	// Send touches to the interested target
	for (unsigned int i = 0; i < this->frameTouches.size(); ++i) {
		if (this->currentTouchTarget != nullptr) {
			this->currentTouchTarget->OnTouchUpdate(i);
		}
	}

	// Remove all touches that have ended or been cancelled
	this->asyncTouches.erase(
			std::remove_if(this->asyncTouches.begin(), this->asyncTouches.end(),
					touchOver), this->asyncTouches.end());

	for (std::vector<Touch>::iterator it = this->asyncTouches.begin();
			it != this->asyncTouches.end(); ++it) {
		it->phase = TouchPhase::Stationary;
	}
	//logTouches();

	this->framePinch = this->asyncPinch;

	// Set the async pinch as inactive so UpdatePinch will know to update it
	this->asyncPinch.gestureState = GestureState::GestureState_Inactive;

	// If the gesture state is greater then end it has either ended, been cancelled or another gesture has been detected
	if (this->asyncPinch.gestureState >= GestureState::GestureState_End) {
		this->asyncPinch.gestureState = GestureState::GestureState_Inactive;
	}
	if (this->framePinch.gestureState != GestureState::GestureState_Inactive) {
		// Raise the pinch gesture event
		MessageChunkpinchGestureMessage = ENGINE->GetMessageHub()->GetOneFreeMessage();
		pinchGestureMessage->SetMessageType(MESSAGE_TYPE_PINCH_GESTURE);
		ENGINE->GetMessageHub()->SendMulticastMessage(pinchGestureMessage, this->GetId());
	}

	this->frameLongPress = this->asyncLongPress;
	this->asyncLongPress.gestureState = GestureState::GestureState_Inactive;

	if (this->asyncLongPress.gestureState >= GestureState::GestureState_End) {
		this->asyncLongPress.gestureState = GestureState::GestureState_Inactive;
	}
	if (this->frameLongPress.gestureState
			!= GestureState::GestureState_Inactive) {
		// Raise the pinch gesture event
		MessageChunklongPressGestureMessage = ENGINE->GetMessageHub()->GetOneFreeMessage();
		longPressGestureMessage->SetMessageType(MESSAGE_TYPE_LONG_PRESS_GESTURE);
		ENGINE->GetMessageHub()->SendMulticastMessage(longPressGestureMessage, this->GetId());
	}
}

Touch Input::GetTouch(int index) {
	ASSERT((unsigned int)index < this->frameTouches.size(), "Index (%d) is lesser than current number of touches (%u)", index, this->frameTouches.size());
	return this->frameTouches[index];
}

void Input::AddTouch(int uId, float startX, float startY, TouchPhase phase) {
	Touch t;
	t.uId = uId;
	t.pos.x = startX;
	t.pos.y = startY;
	t.prevPos = t.pos;
	t.phase = phase;
	t.fingerId = this->nextFingerId;
	// increase the unique finger id
	this->nextFingerId = (this->nextFingerId + 1) % MAX_TOUCHES;

	// add the touch
	this->asyncTouches.push_back(t);

	// Find correct touch target for touch using vector index
	this->testTouchTargets(t);

}

void Input::UpdateTouch(int uId, float curX, float curY, TouchPhase phase) {
	for (std::vector<Touch>::iterator it = this->asyncTouches.begin();
			it != this->asyncTouches.end(); ++it) {
		if (it->uId == uId) {
			it->prevPos = it->pos;
			it->pos.x = curX;
			it->pos.y = curY;
			it->phase = phase;
			break;
		}
	}
}

void Input::UpdatePinch(float scale, float velocity,
		GestureState gestureState) {
	this->asyncPinch.scale = scale;
	this->asyncPinch.velocity = velocity;

	if (this->asyncPinch.gestureState != GestureState::GestureState_Start)
		this->asyncPinch.gestureState = gestureState;
}

void Input::UpdateLongPress(float x, float y, GestureState gestureState) {
	this->asyncLongPress.pos.x = x;
	this->asyncLongPress.pos.y = y;

	if (this->asyncLongPress.gestureState != GestureState::GestureState_Start) {
		this->asyncLongPress.gestureState = gestureState;
	}
}

void Input::AddGameTouchTarget(IGameTouchTarget* newTarget) {
	this->gameTouchTargets.push_back(newTarget);
}

void Input::logTouches() {
	if (this->GetTouchCount() > 0) {
		FRAMEWORK->GetLogger()->dbglog("TOUCH LOG \n");
		for(std::vector<Touch>::iterator it = this->frameTouches.begin(); it != this->frameTouches.end(); ++it) {
			FRAMEWORK->GetLogger()->dbglog("Touch id: %i pos: (%f, %f) %i \n", it->fingerId, it->pos.x, it->pos.y, (int)it->phase);
		}
	}
}

void Input::testTouchTargets(Touch touch) {
	// Test UIScene first
	if (ENGINE->GetSceneGraphUi()->TestTouchStart(touch)) {
		this->currentTouchTarget = ENGINE->GetSceneGraphUi();
		return;
	}

	// Test all game targets
	for(ITouchTarget* iTarget : this->gameTouchTargets) {
		if(iTarget->TestTouchStart(touch)) {
			this->currentTouchTarget = iTarget;
			return;
		}
	}

	// Test 3DScene last
	if(ENGINE->GetSceneGraph3D()->TestTouchStart(touch)) {
		this->currentTouchTarget = ENGINE->GetSceneGraph3D();
		return;
	}
}

#if PLATFORM_DESKTOP
#define GLFW_KEY_I 73
#define GLFW_KEY_O 79

float downTime = 0;
const float longPress = 1.0f;
float startX, startY;
void Input::updateDesktopInput() {
	// Grab the left click state and make it act like a single touch
	int button = glfwGetMouseButton(GLFW_MOUSE_BUTTON_LEFT);

	if (this->frameLongPress.gestureState != GestureState::GestureState_Inactive
			&& this->frameLongPress.gestureState
					!= GestureState::GestureState_End) {
		if (button == GLFW_RELEASE) {
			this->UpdateLongPress(this->mouseX, this->mouseY,
					GestureState::GestureState_End);
		} else {
			this->UpdateLongPress(this->mouseX, this->mouseY,
					GestureState::GestureState_Changed);
		}
	} else {
		if (this->frameTouches.size() == 0) {
			if (button == GLFW_PRESS) {
				this->touchDown = true;
				downTime = 0;
				ENGINE->GetInput()->AddTouch(0, this->mouseX, this->mouseY);
				startX = this->mouseX;
				startY = this->mouseY;
			}
		} else {
			if (button == GLFW_RELEASE) {
				if (this->touchDown) {
					ENGINE->GetInput()->UpdateTouch(0, this->mouseX, this->mouseY, TouchPhase::Ended);
					this->touchDown = false;
				}
			}
			else {
				if(this->touchDown) {
					downTime += (float)ENGINE->GetTimer()->GetDeltaFrameTime();
					if(downTime >= longPress) {
						if((startX == this->mouseX) && (startY == this->mouseY)) {
							ENGINE->GetInput()->UpdateTouch(0, this->mouseX, this->mouseY, TouchPhase::Cancelled);
							this->UpdateLongPress(this->mouseX, this->mouseY, GestureState::GestureState_Start);
							this->touchDown = false;
						}
					}
				}
			}
		}
	}
	//pinch
	int pinchIn = glfwGetKey(GLFW_KEY_I);
	int pinchOut = glfwGetKey(GLFW_KEY_O);

	if (pinchIn == GLFW_PRESS) {
		this->UpdatePinch(10.0f, 10.0f, GestureState::GestureState_Start);
	}
	if (pinchOut == GLFW_PRESS) {
		this->UpdatePinch(10.0f, -10.0f, GestureState::GestureState_Start);
	}
}

void Input::cursorPosUpdate(int x, int y) {
	this->mouseX = x;
	this->mouseY = y;
	if (this->frameTouches.size() == 0) {
		return;
	}
	this->UpdateTouch(0, x, y, TouchPhase::Moved);

}
#endif
<commit_msg>Spaces got removed between some lines of code<commit_after>#include <algorithm>

#include "Vajra/Common/Messages/Message.h"
#include "Vajra/Engine/Core/Engine.h"
#include "Vajra/Engine/Input/Input.h"
#include "Vajra/Engine/MessageHub/MessageHub.h"
#include "Vajra/Engine/SceneGraph/SceneGraphUi.h"
#include "Vajra/Engine/SceneGraph/SceneGraph3D.h"
#include "Vajra/Utilities/Utilities.h"

#if PLATFORM_DESKTOP
#include "Vajra/Engine/Timer/Timer.h"
// Global callback function for desktop input
void cursorPosCallback(int x, int y) {
	ENGINE->GetInput()->cursorPosUpdate(x, y);
}
#endif

Input::Input() {
}

Input::~Input() {
	this->destroy();
}

void Input::init() {
	this->nextFingerId = 0;
#if PLATFORM_DESKTOP
	glfwSetMousePosCallback(cursorPosCallback);
#endif
}

void Input::destroy() {
	this->currentTouchTarget = nullptr;
}

bool touchOver(const Touch &touch) {
	return (touch.phase == TouchPhase::Ended
			|| touch.phase == TouchPhase::Cancelled);
}

void Input::updateInput() {
#if PLATFORM_DESKTOP
	this->updateDesktopInput();
#endif
	// Populate frame touches with all input that has been asynchronously collected
	this->frameTouches = this->asyncTouches;

	// Send touches to the interested target
	for (unsigned int i = 0; i < this->frameTouches.size(); ++i) {
		if (this->currentTouchTarget != nullptr) {
			this->currentTouchTarget->OnTouchUpdate(i);
		}
	}

	// Remove all touches that have ended or been cancelled
	this->asyncTouches.erase(
			std::remove_if(this->asyncTouches.begin(), this->asyncTouches.end(),
					touchOver), this->asyncTouches.end());

	for (std::vector<Touch>::iterator it = this->asyncTouches.begin();
			it != this->asyncTouches.end(); ++it) {
		it->phase = TouchPhase::Stationary;
	}
	//logTouches();

	this->framePinch = this->asyncPinch;

	// Set the async pinch as inactive so UpdatePinch will know to update it
	this->asyncPinch.gestureState = GestureState::GestureState_Inactive;

	// If the gesture state is greater then end it has either ended, been cancelled or another gesture has been detected
	if (this->asyncPinch.gestureState >= GestureState::GestureState_End) {
		this->asyncPinch.gestureState = GestureState::GestureState_Inactive;
	}
	if (this->framePinch.gestureState != GestureState::GestureState_Inactive) {
		// Raise the pinch gesture event
		MessageChunk pinchGestureMessage = ENGINE->GetMessageHub()->GetOneFreeMessage();
		pinchGestureMessage->SetMessageType(MESSAGE_TYPE_PINCH_GESTURE);
		ENGINE->GetMessageHub()->SendMulticastMessage(pinchGestureMessage, this->GetId());
	}

	this->frameLongPress = this->asyncLongPress;
	this->asyncLongPress.gestureState = GestureState::GestureState_Inactive;

	if (this->asyncLongPress.gestureState >= GestureState::GestureState_End) {
		this->asyncLongPress.gestureState = GestureState::GestureState_Inactive;
	}
	if (this->frameLongPress.gestureState
			!= GestureState::GestureState_Inactive) {
		// Raise the pinch gesture event
		MessageChunk longPressGestureMessage = ENGINE->GetMessageHub()->GetOneFreeMessage();
		longPressGestureMessage->SetMessageType(MESSAGE_TYPE_LONG_PRESS_GESTURE);
		ENGINE->GetMessageHub()->SendMulticastMessage(longPressGestureMessage, this->GetId());
	}
}

Touch Input::GetTouch(int index) {
	ASSERT((unsigned int)index < this->frameTouches.size(), "Index (%d) is lesser than current number of touches (%u)", index, this->frameTouches.size());
	return this->frameTouches[index];
}

void Input::AddTouch(int uId, float startX, float startY, TouchPhase phase) {
	Touch t;
	t.uId = uId;
	t.pos.x = startX;
	t.pos.y = startY;
	t.prevPos = t.pos;
	t.phase = phase;
	t.fingerId = this->nextFingerId;
	// increase the unique finger id
	this->nextFingerId = (this->nextFingerId + 1) % MAX_TOUCHES;

	// add the touch
	this->asyncTouches.push_back(t);

	// Find correct touch target for touch using vector index
	this->testTouchTargets(t);

}

void Input::UpdateTouch(int uId, float curX, float curY, TouchPhase phase) {
	for (std::vector<Touch>::iterator it = this->asyncTouches.begin();
			it != this->asyncTouches.end(); ++it) {
		if (it->uId == uId) {
			it->prevPos = it->pos;
			it->pos.x = curX;
			it->pos.y = curY;
			it->phase = phase;
			break;
		}
	}
}

void Input::UpdatePinch(float scale, float velocity,
		GestureState gestureState) {
	this->asyncPinch.scale = scale;
	this->asyncPinch.velocity = velocity;

	if (this->asyncPinch.gestureState != GestureState::GestureState_Start)
		this->asyncPinch.gestureState = gestureState;
}

void Input::UpdateLongPress(float x, float y, GestureState gestureState) {
	this->asyncLongPress.pos.x = x;
	this->asyncLongPress.pos.y = y;

	if (this->asyncLongPress.gestureState != GestureState::GestureState_Start) {
		this->asyncLongPress.gestureState = gestureState;
	}
}

void Input::AddGameTouchTarget(IGameTouchTarget* newTarget) {
	this->gameTouchTargets.push_back(newTarget);
}

void Input::logTouches() {
	if (this->GetTouchCount() > 0) {
		FRAMEWORK->GetLogger()->dbglog("TOUCH LOG \n");
		for(std::vector<Touch>::iterator it = this->frameTouches.begin(); it != this->frameTouches.end(); ++it) {
			FRAMEWORK->GetLogger()->dbglog("Touch id: %i pos: (%f, %f) %i \n", it->fingerId, it->pos.x, it->pos.y, (int)it->phase);
		}
	}
}

void Input::testTouchTargets(Touch touch) {
	// Test UIScene first
	if (ENGINE->GetSceneGraphUi()->TestTouchStart(touch)) {
		this->currentTouchTarget = ENGINE->GetSceneGraphUi();
		return;
	}

	// Test all game targets
	for(ITouchTarget* iTarget : this->gameTouchTargets) {
		if(iTarget->TestTouchStart(touch)) {
			this->currentTouchTarget = iTarget;
			return;
		}
	}

	// Test 3DScene last
	if(ENGINE->GetSceneGraph3D()->TestTouchStart(touch)) {
		this->currentTouchTarget = ENGINE->GetSceneGraph3D();
		return;
	}
}

#if PLATFORM_DESKTOP
#define GLFW_KEY_I 73
#define GLFW_KEY_O 79

float downTime = 0;
const float longPress = 1.0f;
float startX, startY;
void Input::updateDesktopInput() {
	// Grab the left click state and make it act like a single touch
	int button = glfwGetMouseButton(GLFW_MOUSE_BUTTON_LEFT);

	if (this->frameLongPress.gestureState != GestureState::GestureState_Inactive
			&& this->frameLongPress.gestureState
					!= GestureState::GestureState_End) {
		if (button == GLFW_RELEASE) {
			this->UpdateLongPress(this->mouseX, this->mouseY,
					GestureState::GestureState_End);
		} else {
			this->UpdateLongPress(this->mouseX, this->mouseY,
					GestureState::GestureState_Changed);
		}
	} else {
		if (this->frameTouches.size() == 0) {
			if (button == GLFW_PRESS) {
				this->touchDown = true;
				downTime = 0;
				ENGINE->GetInput()->AddTouch(0, this->mouseX, this->mouseY);
				startX = this->mouseX;
				startY = this->mouseY;
			}
		} else {
			if (button == GLFW_RELEASE) {
				if (this->touchDown) {
					ENGINE->GetInput()->UpdateTouch(0, this->mouseX, this->mouseY, TouchPhase::Ended);
					this->touchDown = false;
				}
			}
			else {
				if(this->touchDown) {
					downTime += (float)ENGINE->GetTimer()->GetDeltaFrameTime();
					if(downTime >= longPress) {
						if((startX == this->mouseX) && (startY == this->mouseY)) {
							ENGINE->GetInput()->UpdateTouch(0, this->mouseX, this->mouseY, TouchPhase::Cancelled);
							this->UpdateLongPress(this->mouseX, this->mouseY, GestureState::GestureState_Start);
							this->touchDown = false;
						}
					}
				}
			}
		}
	}
	//pinch
	int pinchIn = glfwGetKey(GLFW_KEY_I);
	int pinchOut = glfwGetKey(GLFW_KEY_O);

	if (pinchIn == GLFW_PRESS) {
		this->UpdatePinch(10.0f, 10.0f, GestureState::GestureState_Start);
	}
	if (pinchOut == GLFW_PRESS) {
		this->UpdatePinch(10.0f, -10.0f, GestureState::GestureState_Start);
	}
}

void Input::cursorPosUpdate(int x, int y) {
	this->mouseX = x;
	this->mouseY = y;
	if (this->frameTouches.size() == 0) {
		return;
	}
	this->UpdateTouch(0, x, y, TouchPhase::Moved);

}
#endif
<|endoftext|>