<commit_before>////////////////////////////////////////////////////////////////////////////
//
// Copyright 2015 Realm Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
////////////////////////////////////////////////////////////////////////////

#include "shared_realm.hpp"

#include <realm/commit_log.hpp>
#include <realm/group_shared.hpp>
#include <realm/lang_bind_helper.hpp>

#include <memory>
#include <mutex>

using namespace realm;

RealmCache Realm::s_global_cache;

Realm::Config::Config(const Config& c) : path(c.path), read_only(c.read_only), in_memory(c.in_memory), schema_version(c.schema_version), migration_function(c.migration_function)
{
    if (c.schema) {
        schema = std::make_unique<Schema>(*c.schema);
    }
    if (c.encryption_key) {
        encryption_key = std::make_unique<char[]>(64);
        memcpy(encryption_key.get(), c.encryption_key.get(), 64);
    }
}

Realm::Realm(Config &config) : m_config(config)
{
    try {
        if (config.read_only) {
            m_read_only_group = std::make_unique<Group>(config.path, config.encryption_key.get(), Group::mode_ReadOnly);
            m_group = m_read_only_group.get();
        }
        else {
            m_history = realm::make_client_history(config.path, config.encryption_key.get());
            SharedGroup::DurabilityLevel durability = config.in_memory ? SharedGroup::durability_MemOnly :
                                                                         SharedGroup::durability_Full;
            m_shared_group = std::make_unique<SharedGroup>(*m_history, durability, config.encryption_key.get());
        }
    }
    catch (util::File::PermissionDenied const& ex) {
        throw RealmFileException(RealmFileException::Kind::PermissionDenied, "Unable to open a realm at path '" + config.path +
                             "'. Please use a path where your app has " + (config.read_only ? "read" : "read-write") + " permissions.");
    }
    catch (util::File::Exists const& ex) {
        throw RealmFileException(RealmFileException::Kind::Exists, "Unable to open a realm at path '" + config.path + "'");
    }
    catch (util::File::AccessError const& ex) {
        throw RealmFileException(RealmFileException::Kind::AccessError, "Unable to open a realm at path '" + config.path + "'");
    }
    catch (IncompatibleLockFile const&) {
        throw RealmFileException(RealmFileException::Kind::IncompatibleLockFile, "Realm file is currently open in another process "
        "which cannot share access with this process. All processes sharing a single file must be the same architecture.");
    }
}

Group *Realm::read_group()
{
    if (!m_group) {
        m_group = &const_cast<Group&>(m_shared_group->begin_read());
    }
    return m_group;
}

SharedRealm Realm::get_shared_realm(Config &config)
{
    SharedRealm realm = s_global_cache.get_realm(config.path);
    if (realm) {
        if (realm->config().read_only != config.read_only) {
            throw MismatchedConfigException("Realm at path already opened with different read permissions.");
        }
        if (realm->config().in_memory != config.in_memory) {
            throw MismatchedConfigException("Realm at path already opened with different inMemory settings.");
        }
        if (realm->config().encryption_key != config.encryption_key) {
            throw MismatchedConfigException("Realm at path already opened with a different encryption key.");
        }
        if (realm->config().schema_version != config.schema_version && config.schema_version != ObjectStore::NotVersioned) {
            throw MismatchedConfigException("Realm at path already opened with different schema version.");
        }
        // FIXME - enable schma comparison
        /*if (realm->config().schema != config.schema) {
            throw MismatchedConfigException("Realm at path already opened with different schema");
        }*/

        realm->m_config.migration_function = config.migration_function;

        return realm;
    }

    realm = SharedRealm(new Realm(config));

    // we want to ensure we are only initializing a single realm at a time
    static std::mutex s_init_mutex;
    std::lock_guard<std::mutex> lock(s_init_mutex);

    uint64_t old_version = ObjectStore::get_schema_version(realm->read_group());
    if (auto existing = s_global_cache.get_any_realm(realm->config().path)) {
        // if there is an existing realm at the current path steal its schema/column mapping
        // FIXME - need to validate that schemas match
        realm->m_config.schema = std::make_unique<Schema>(*existing->m_config.schema);
    }
    else if (!realm->m_config.schema) {
        // get schema from group and skip validation
        realm->m_config.schema_version = old_version;
        realm->m_config.schema = std::make_unique<Schema>(ObjectStore::schema_from_group(realm->read_group()));
    }
    else if (realm->m_config.read_only) {
        if (old_version == ObjectStore::NotVersioned) {
            throw UnitializedRealmException("Can't open an un-initizliazed Realm without a Schema");
        }
        ObjectStore::verify_schema(realm->read_group(), *realm->m_config.schema, true);
    }
    else {
        // its a non-cached realm so update/migrate if needed
        realm->update_schema(*realm->m_config.schema, realm->m_config.schema_version);
    }

    s_global_cache.cache_realm(realm, realm->m_thread_id);
    return realm;
}

bool Realm::update_schema(Schema &schema, uint64_t version)
{
    bool changed = false;
    Config old_config(m_config);

    // set new version/schema
    if (m_config.schema.get() != &schema) {
        m_config.schema = std::make_unique<Schema>(schema);
    }
    m_config.schema_version = version;

    try {
        if (!m_config.read_only && ObjectStore::realm_requires_update(read_group(), version, schema)) {
            // keep old copy to pass to migration function
            old_config.read_only = true;
            SharedRealm old_realm = SharedRealm(new Realm(old_config)), updated_realm = shared_from_this();

            // update and migrate
            begin_transaction();
            changed = ObjectStore::update_realm_with_schema(read_group(), version, *m_config.schema, [=](__unused Group *group, __unused Schema &target_schema) {
                m_config.migration_function(old_realm, updated_realm);
            });
            commit_transaction();
        }
        else {
            ObjectStore::verify_schema(read_group(), *m_config.schema, m_config.read_only);
        }
    }
    catch (...) {
        if (is_in_transaction()) {
            cancel_transaction();
        }
        m_config.schema_version = old_config.schema_version;
        m_config.schema = std::move(old_config.schema);
        throw;
    }
    return changed;
}

static void check_read_write(Realm *realm)
{
    if (realm->config().read_only) {
        throw InvalidTransactionException("Can't perform transactions on read-only Realms.");
    }
}

void Realm::verify_thread()
{
    if (m_thread_id != std::this_thread::get_id()) {
        throw IncorrectThreadException("Realm accessed from incorrect thread.");
    }
}

void Realm::begin_transaction()
{
    check_read_write(this);
    verify_thread();

    if (m_in_transaction) {
        throw InvalidTransactionException("The Realm is already in a write transaction");
    }

    // if the upgrade to write will move the transaction forward, announce the change after promoting
    bool announce = m_shared_group->has_changed();

    // make sure we have a read transaction
    read_group();

    LangBindHelper::promote_to_write(*m_shared_group, *m_history);
    m_in_transaction = true;

    if (announce) {
        send_local_notifications(DidChangeNotification);
    }
}

void Realm::commit_transaction()
{
    check_read_write(this);
    verify_thread();

    if (!m_in_transaction) {
        throw InvalidTransactionException("Can't commit a non-existing write transaction");
    }

    LangBindHelper::commit_and_continue_as_read(*m_shared_group);
    m_in_transaction = false;

    send_external_notifications();
    send_local_notifications(DidChangeNotification);
}

void Realm::cancel_transaction()
{
    check_read_write(this);
    verify_thread();

    if (!m_in_transaction) {
        throw InvalidTransactionException("Can't cancel a non-existing write transaction");
    }

    LangBindHelper::rollback_and_continue_as_read(*m_shared_group, *m_history);
    m_in_transaction = false;
}

void Realm::invalidate()
{
    verify_thread();
    check_read_write(this);

    if (m_in_transaction) {
        cancel_transaction();
    }
    if (!m_group) {
        return;
    }

    m_shared_group->end_read();
    m_group = nullptr;
}

bool Realm::compact()
{
    verify_thread();

    bool success = false;
    if (m_in_transaction) {
        throw InvalidTransactionException("Can't compact a Realm within a write transaction");
    }

    for (auto &object_schema : *m_config.schema) {
        ObjectStore::table_for_object_type(read_group(), object_schema.first)->optimize();
    }

    m_shared_group->end_read();
    success = m_shared_group->compact();
    m_shared_group->begin_read();

    return success;
}

void Realm::notify()
{
    verify_thread();

    if (m_shared_group->has_changed()) { // Throws
        if (m_auto_refresh) {
            if (m_group) {
                LangBindHelper::advance_read(*m_shared_group, *m_history);
            }
            send_local_notifications(DidChangeNotification);
        }
        else {
            send_local_notifications(RefreshRequiredNotification);
        }
    }
}

void Realm::send_local_notifications(const std::string &type)
{
    verify_thread();
    for (NotificationFunction notification : m_notifications) {
        (*notification)(type);
    }
}

bool Realm::refresh()
{
    verify_thread();
    check_read_write(this);

    // can't be any new changes if we're in a write transaction
    if (m_in_transaction) {
        return false;
    }

    // advance transaction if database has changed
    if (!m_shared_group->has_changed()) { // Throws
        return false;
    }

    if (m_group) {
        LangBindHelper::advance_read(*m_shared_group, *m_history);
    }
    else {
        // Create the read transaction
        read_group();
    }

    send_local_notifications(DidChangeNotification);
    return true;
}

SharedRealm RealmCache::get_realm(const std::string &path, std::thread::id thread_id)
{
    std::lock_guard<std::mutex> lock(m_mutex);

    auto path_iter = m_cache.find(path);
    if (path_iter == m_cache.end()) {
        return SharedRealm();
    }

    auto thread_iter = path_iter->second.find(thread_id);
    if (thread_iter == path_iter->second.end()) {
        return SharedRealm();
    }

    return thread_iter->second.lock();
}

SharedRealm RealmCache::get_any_realm(const std::string &path)
{
    std::lock_guard<std::mutex> lock(m_mutex);

    auto path_iter = m_cache.find(path);
    if (path_iter == m_cache.end()) {
        return SharedRealm();
    }

    auto thread_iter = path_iter->second.begin();
    while (thread_iter != path_iter->second.end()) {
        if (auto realm = thread_iter->second.lock()) {
            return realm;
        }
        path_iter->second.erase(thread_iter++);
    }

    return SharedRealm();
}

void RealmCache::remove(const std::string &path, std::thread::id thread_id)
{
    std::lock_guard<std::mutex> lock(m_mutex);

    auto path_iter = m_cache.find(path);
    if (path_iter == m_cache.end()) {
        return;
    }

    auto thread_iter = path_iter->second.find(thread_id);
    if (thread_iter != path_iter->second.end()) {
        path_iter->second.erase(thread_iter);
    }

    if (path_iter->second.size() == 0) {
        m_cache.erase(path_iter);
    }
}

void RealmCache::cache_realm(SharedRealm &realm, std::thread::id thread_id)
{
    std::lock_guard<std::mutex> lock(m_mutex);

    auto path_iter = m_cache.find(realm->config().path);
    if (path_iter == m_cache.end()) {
        m_cache.emplace(realm->config().path, std::map<std::thread::id, WeakRealm>{{thread_id, realm}});
    }
    else {
        path_iter->second.emplace(thread_id, realm);
    }
}

void RealmCache::clear()
{
    std::lock_guard<std::mutex> lock(m_mutex);

    m_cache.clear();
}

<commit_msg>Eliminate some copies<commit_after>////////////////////////////////////////////////////////////////////////////
//
// Copyright 2015 Realm Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
////////////////////////////////////////////////////////////////////////////

#include "shared_realm.hpp"

#include <realm/commit_log.hpp>
#include <realm/group_shared.hpp>
#include <realm/lang_bind_helper.hpp>

#include <memory>
#include <mutex>

using namespace realm;

RealmCache Realm::s_global_cache;

Realm::Config::Config(const Config& c) : path(c.path), read_only(c.read_only), in_memory(c.in_memory), schema_version(c.schema_version), migration_function(c.migration_function)
{
    if (c.schema) {
        schema = std::make_unique<Schema>(*c.schema);
    }
    if (c.encryption_key) {
        encryption_key = std::make_unique<char[]>(64);
        memcpy(encryption_key.get(), c.encryption_key.get(), 64);
    }
}

Realm::Realm(Config &config) : m_config(config)
{
    try {
        if (config.read_only) {
            m_read_only_group = std::make_unique<Group>(config.path, config.encryption_key.get(), Group::mode_ReadOnly);
            m_group = m_read_only_group.get();
        }
        else {
            m_history = realm::make_client_history(config.path, config.encryption_key.get());
            SharedGroup::DurabilityLevel durability = config.in_memory ? SharedGroup::durability_MemOnly :
                                                                         SharedGroup::durability_Full;
            m_shared_group = std::make_unique<SharedGroup>(*m_history, durability, config.encryption_key.get());
        }
    }
    catch (util::File::PermissionDenied const& ex) {
        throw RealmFileException(RealmFileException::Kind::PermissionDenied, "Unable to open a realm at path '" + config.path +
                             "'. Please use a path where your app has " + (config.read_only ? "read" : "read-write") + " permissions.");
    }
    catch (util::File::Exists const& ex) {
        throw RealmFileException(RealmFileException::Kind::Exists, "Unable to open a realm at path '" + config.path + "'");
    }
    catch (util::File::AccessError const& ex) {
        throw RealmFileException(RealmFileException::Kind::AccessError, "Unable to open a realm at path '" + config.path + "'");
    }
    catch (IncompatibleLockFile const&) {
        throw RealmFileException(RealmFileException::Kind::IncompatibleLockFile, "Realm file is currently open in another process "
        "which cannot share access with this process. All processes sharing a single file must be the same architecture.");
    }
}

Group *Realm::read_group()
{
    if (!m_group) {
        m_group = &const_cast<Group&>(m_shared_group->begin_read());
    }
    return m_group;
}

SharedRealm Realm::get_shared_realm(Config &config)
{
    SharedRealm realm = s_global_cache.get_realm(config.path);
    if (realm) {
        if (realm->config().read_only != config.read_only) {
            throw MismatchedConfigException("Realm at path already opened with different read permissions.");
        }
        if (realm->config().in_memory != config.in_memory) {
            throw MismatchedConfigException("Realm at path already opened with different inMemory settings.");
        }
        if (realm->config().encryption_key != config.encryption_key) {
            throw MismatchedConfigException("Realm at path already opened with a different encryption key.");
        }
        if (realm->config().schema_version != config.schema_version && config.schema_version != ObjectStore::NotVersioned) {
            throw MismatchedConfigException("Realm at path already opened with different schema version.");
        }
        // FIXME - enable schma comparison
        /*if (realm->config().schema != config.schema) {
            throw MismatchedConfigException("Realm at path already opened with different schema");
        }*/

        realm->m_config.migration_function = config.migration_function;

        return realm;
    }

    realm = SharedRealm(new Realm(config));

    // we want to ensure we are only initializing a single realm at a time
    static std::mutex s_init_mutex;
    std::lock_guard<std::mutex> lock(s_init_mutex);

    uint64_t old_version = ObjectStore::get_schema_version(realm->read_group());
    if (auto existing = s_global_cache.get_any_realm(realm->config().path)) {
        // if there is an existing realm at the current path steal its schema/column mapping
        // FIXME - need to validate that schemas match
        realm->m_config.schema = std::make_unique<Schema>(*existing->m_config.schema);
    }
    else if (!realm->m_config.schema) {
        // get schema from group and skip validation
        realm->m_config.schema_version = old_version;
        realm->m_config.schema = std::make_unique<Schema>(ObjectStore::schema_from_group(realm->read_group()));
    }
    else if (realm->m_config.read_only) {
        if (old_version == ObjectStore::NotVersioned) {
            throw UnitializedRealmException("Can't open an un-initizliazed Realm without a Schema");
        }
        ObjectStore::verify_schema(realm->read_group(), *realm->m_config.schema, true);
    }
    else {
        // its a non-cached realm so update/migrate if needed
        realm->update_schema(*realm->m_config.schema, realm->m_config.schema_version);
    }

    s_global_cache.cache_realm(realm, realm->m_thread_id);
    return realm;
}

bool Realm::update_schema(Schema &schema, uint64_t version)
{
    bool changed = false;
    Config old_config(m_config);

    // set new version/schema
    if (m_config.schema.get() != &schema) {
        m_config.schema = std::make_unique<Schema>(schema);
    }
    m_config.schema_version = version;

    try {
        if (!m_config.read_only && ObjectStore::realm_requires_update(read_group(), version, schema)) {
            // keep old copy to pass to migration function
            old_config.read_only = true;
            SharedRealm old_realm = SharedRealm(new Realm(old_config)), updated_realm = shared_from_this();

            // update and migrate
            begin_transaction();
            changed = ObjectStore::update_realm_with_schema(read_group(), version, *m_config.schema, [=](__unused Group *group, __unused Schema &target_schema) {
                m_config.migration_function(old_realm, updated_realm);
            });
            commit_transaction();
        }
        else {
            ObjectStore::verify_schema(read_group(), *m_config.schema, m_config.read_only);
        }
    }
    catch (...) {
        if (is_in_transaction()) {
            cancel_transaction();
        }
        m_config.schema_version = old_config.schema_version;
        m_config.schema = std::move(old_config.schema);
        throw;
    }
    return changed;
}

static void check_read_write(Realm *realm)
{
    if (realm->config().read_only) {
        throw InvalidTransactionException("Can't perform transactions on read-only Realms.");
    }
}

void Realm::verify_thread()
{
    if (m_thread_id != std::this_thread::get_id()) {
        throw IncorrectThreadException("Realm accessed from incorrect thread.");
    }
}

void Realm::begin_transaction()
{
    check_read_write(this);
    verify_thread();

    if (m_in_transaction) {
        throw InvalidTransactionException("The Realm is already in a write transaction");
    }

    // if the upgrade to write will move the transaction forward, announce the change after promoting
    bool announce = m_shared_group->has_changed();

    // make sure we have a read transaction
    read_group();

    LangBindHelper::promote_to_write(*m_shared_group, *m_history);
    m_in_transaction = true;

    if (announce) {
        send_local_notifications(DidChangeNotification);
    }
}

void Realm::commit_transaction()
{
    check_read_write(this);
    verify_thread();

    if (!m_in_transaction) {
        throw InvalidTransactionException("Can't commit a non-existing write transaction");
    }

    LangBindHelper::commit_and_continue_as_read(*m_shared_group);
    m_in_transaction = false;

    send_external_notifications();
    send_local_notifications(DidChangeNotification);
}

void Realm::cancel_transaction()
{
    check_read_write(this);
    verify_thread();

    if (!m_in_transaction) {
        throw InvalidTransactionException("Can't cancel a non-existing write transaction");
    }

    LangBindHelper::rollback_and_continue_as_read(*m_shared_group, *m_history);
    m_in_transaction = false;
}

void Realm::invalidate()
{
    verify_thread();
    check_read_write(this);

    if (m_in_transaction) {
        cancel_transaction();
    }
    if (!m_group) {
        return;
    }

    m_shared_group->end_read();
    m_group = nullptr;
}

bool Realm::compact()
{
    verify_thread();

    bool success = false;
    if (m_in_transaction) {
        throw InvalidTransactionException("Can't compact a Realm within a write transaction");
    }

    for (auto &object_schema : *m_config.schema) {
        ObjectStore::table_for_object_type(read_group(), object_schema.first)->optimize();
    }

    m_shared_group->end_read();
    success = m_shared_group->compact();
    m_shared_group->begin_read();

    return success;
}

void Realm::notify()
{
    verify_thread();

    if (m_shared_group->has_changed()) { // Throws
        if (m_auto_refresh) {
            if (m_group) {
                LangBindHelper::advance_read(*m_shared_group, *m_history);
            }
            send_local_notifications(DidChangeNotification);
        }
        else {
            send_local_notifications(RefreshRequiredNotification);
        }
    }
}

void Realm::send_local_notifications(const std::string &type)
{
    verify_thread();
    for (NotificationFunction const& notification : m_notifications) {
        (*notification)(type);
    }
}

bool Realm::refresh()
{
    verify_thread();
    check_read_write(this);

    // can't be any new changes if we're in a write transaction
    if (m_in_transaction) {
        return false;
    }

    // advance transaction if database has changed
    if (!m_shared_group->has_changed()) { // Throws
        return false;
    }

    if (m_group) {
        LangBindHelper::advance_read(*m_shared_group, *m_history);
    }
    else {
        // Create the read transaction
        read_group();
    }

    send_local_notifications(DidChangeNotification);
    return true;
}

SharedRealm RealmCache::get_realm(const std::string &path, std::thread::id thread_id)
{
    std::lock_guard<std::mutex> lock(m_mutex);

    auto path_iter = m_cache.find(path);
    if (path_iter == m_cache.end()) {
        return SharedRealm();
    }

    auto thread_iter = path_iter->second.find(thread_id);
    if (thread_iter == path_iter->second.end()) {
        return SharedRealm();
    }

    return thread_iter->second.lock();
}

SharedRealm RealmCache::get_any_realm(const std::string &path)
{
    std::lock_guard<std::mutex> lock(m_mutex);

    auto path_iter = m_cache.find(path);
    if (path_iter == m_cache.end()) {
        return SharedRealm();
    }

    auto thread_iter = path_iter->second.begin();
    while (thread_iter != path_iter->second.end()) {
        if (auto realm = thread_iter->second.lock()) {
            return realm;
        }
        path_iter->second.erase(thread_iter++);
    }

    return SharedRealm();
}

void RealmCache::remove(const std::string &path, std::thread::id thread_id)
{
    std::lock_guard<std::mutex> lock(m_mutex);

    auto path_iter = m_cache.find(path);
    if (path_iter == m_cache.end()) {
        return;
    }

    auto thread_iter = path_iter->second.find(thread_id);
    if (thread_iter != path_iter->second.end()) {
        path_iter->second.erase(thread_iter);
    }

    if (path_iter->second.size() == 0) {
        m_cache.erase(path_iter);
    }
}

void RealmCache::cache_realm(SharedRealm &realm, std::thread::id thread_id)
{
    std::lock_guard<std::mutex> lock(m_mutex);

    auto path_iter = m_cache.find(realm->config().path);
    if (path_iter == m_cache.end()) {
        m_cache.emplace(realm->config().path, std::map<std::thread::id, WeakRealm>{{thread_id, realm}});
    }
    else {
        path_iter->second.emplace(thread_id, realm);
    }
}

void RealmCache::clear()
{
    std::lock_guard<std::mutex> lock(m_mutex);

    m_cache.clear();
}

<|endoftext|>


<commit_before>#include "itkCudaFDKBackProjectionImageFilter.h"
#include "itkCudaUtilities.hcu"

#include <itkImageRegionConstIterator.h>
#include <itkImageRegionIteratorWithIndex.h>
#include <itkLinearInterpolateImageFunction.h>

namespace itk
{

void
CudaFDKBackProjectionImageFilter
::GenerateData()
{
  this->AllocateOutputs();
  std::vector<double> angWeights = dynamic_cast<GeometryType *>(this->GetGeometry().GetPointer())->GetAngularGaps();

  OutputImageRegionType region = this->GetOutput()->GetRequestedRegion();

  const unsigned int Dimension = ImageType::ImageDimension;
  const unsigned int nProj = this->GetInput(1)->GetLargestPossibleRegion().GetSize(Dimension-1);

  // Ramp factor is the correction for ramp filter which did not account for the divergence of the beam
  const GeometryPointer geometry = dynamic_cast<GeometryType *>(this->GetGeometry().GetPointer());
  double rampFactor = geometry->GetSourceToDetectorDistance() / geometry->GetSourceToIsocenterDistance();
  rampFactor *= 0.5; // Factor 1/2 in eq 176, page 106, Kak & Slaney

  // Rotation center (assumed to be at 0 yet)
  ImageType::PointType rotCenterPoint;
  rotCenterPoint.Fill(0.0);
  ContinuousIndex<double, Dimension> rotCenterIndex;
  this->GetInput(0)->TransformPhysicalPointToContinuousIndex(rotCenterPoint, rotCenterIndex);

  // Load dimensions arguments
  int3 vol_dim;
  vol_dim.x = this->GetOutput()->GetLargestPossibleRegion().GetSize()[0];
  vol_dim.y = this->GetOutput()->GetLargestPossibleRegion().GetSize()[1];
  vol_dim.z = this->GetOutput()->GetLargestPossibleRegion().GetSize()[2];

  int2 img_dim;
  img_dim.x = this->GetInput(1)->GetLargestPossibleRegion().GetSize()[0];
  img_dim.y = this->GetInput(1)->GetLargestPossibleRegion().GetSize()[1];

  // Cuda init
  std::vector<int> devices = GetListOfCudaDevices();
  if(devices.size()>1)
    {
    cudaThreadExit();
    cudaSetDevice(devices[0]);
    }

  float *dev_vol;
  cudaArray *dev_img;
  float *dev_matrix;
  CUDA_reconstruct_conebeam_init (img_dim, vol_dim, dev_vol, dev_img, dev_matrix);

  // Go over each projection
  for(unsigned int iProj=0; iProj<nProj; iProj++)
    {
    // Extract the current slice
    ProjectionImagePointer projection = this->GetProjection(iProj, angWeights[iProj] * rampFactor);

    // Index to index matrix normalized to have a correct backprojection weight (1 at the isocenter)
    ProjectionMatrixType matrix = GetIndexToIndexProjectionMatrix(iProj, projection);

    // We correct the matrix for non zero indexes
    itk::Matrix<double, 4, 4> matrixIdxVol;
    matrixIdxVol.SetIdentity();
    for(unsigned int i=0; i<3; i++)
      matrixIdxVol[i][3] = this->GetOutput()->GetLargestPossibleRegion().GetIndex()[i];
    itk::Matrix<double, 3, 3> matrixIdxProj;
    matrixIdxProj.SetIdentity();
    for(unsigned int i=0; i<2; i++)
      matrixIdxProj[i][2] = -1*(projection->GetLargestPossibleRegion().GetIndex()[i])+0.5; //SR: 0.5 for 2D texture?

    matrix = matrixIdxProj.GetVnlMatrix() * matrix.GetVnlMatrix() * matrixIdxVol.GetVnlMatrix();

    double perspFactor = matrix[Dimension-1][Dimension];
    for(unsigned int j=0; j<Dimension; j++)
      perspFactor += matrix[Dimension-1][j] * rotCenterIndex[j];
    matrix /= perspFactor;

    float fMatrix[12];
    for (int j = 0; j < 12; j++)
      fMatrix[j] = matrix[j/4][j%4];

    CUDA_reconstruct_conebeam(img_dim, vol_dim, projection->GetBufferPointer(), fMatrix, dev_vol, dev_img, dev_matrix);
    }

  CUDA_reconstruct_conebeam_cleanup (vol_dim, this->GetOutput()->GetBufferPointer(), dev_vol, dev_img, dev_matrix);
}

} // end namespace itk
<commit_msg>Allocate only what is requested on gpu<commit_after>#include "itkCudaFDKBackProjectionImageFilter.h"
#include "itkCudaUtilities.hcu"

#include <itkImageRegionConstIterator.h>
#include <itkImageRegionIteratorWithIndex.h>
#include <itkLinearInterpolateImageFunction.h>

namespace itk
{

void
CudaFDKBackProjectionImageFilter
::GenerateData()
{
  this->AllocateOutputs();
  std::vector<double> angWeights = dynamic_cast<GeometryType *>(this->GetGeometry().GetPointer())->GetAngularGaps();

  OutputImageRegionType region = this->GetOutput()->GetRequestedRegion();

  const unsigned int Dimension = ImageType::ImageDimension;
  const unsigned int nProj = this->GetInput(1)->GetLargestPossibleRegion().GetSize(Dimension-1);

  // Ramp factor is the correction for ramp filter which did not account for the divergence of the beam
  const GeometryPointer geometry = dynamic_cast<GeometryType *>(this->GetGeometry().GetPointer());
  double rampFactor = geometry->GetSourceToDetectorDistance() / geometry->GetSourceToIsocenterDistance();
  rampFactor *= 0.5; // Factor 1/2 in eq 176, page 106, Kak & Slaney

  // Rotation center (assumed to be at 0 yet)
  ImageType::PointType rotCenterPoint;
  rotCenterPoint.Fill(0.0);
  ContinuousIndex<double, Dimension> rotCenterIndex;
  this->GetInput(0)->TransformPhysicalPointToContinuousIndex(rotCenterPoint, rotCenterIndex);

  // Load dimensions arguments
  int3 vol_dim;
  vol_dim.x = this->GetOutput()->GetBufferedRegion().GetSize()[0];
  vol_dim.y = this->GetOutput()->GetBufferedRegion().GetSize()[1];
  vol_dim.z = region.GetSize()[2];

  int2 img_dim;
  img_dim.x = this->GetInput(1)->GetBufferedRegion().GetSize()[0];
  img_dim.y = this->GetInput(1)->GetBufferedRegion().GetSize()[1];

  // Cuda init
  std::vector<int> devices = GetListOfCudaDevices();
  if(devices.size()>1)
    {
    cudaThreadExit();
    cudaSetDevice(devices[0]);
    }

  float *dev_vol;
  cudaArray *dev_img;
  float *dev_matrix;
  CUDA_reconstruct_conebeam_init (img_dim, vol_dim, dev_vol, dev_img, dev_matrix);

  // Go over each projection
  for(unsigned int iProj=0; iProj<nProj; iProj++)
    {
    // Extract the current slice
    ProjectionImagePointer projection = this->GetProjection(iProj, angWeights[iProj] * rampFactor);

    // Index to index matrix normalized to have a correct backprojection weight (1 at the isocenter)
    ProjectionMatrixType matrix = GetIndexToIndexProjectionMatrix(iProj, projection);

    // We correct the matrix for non zero indexes
    itk::Matrix<double, 4, 4> matrixIdxVol;
    matrixIdxVol.SetIdentity();
    for(unsigned int i=0; i<2; i++)
      matrixIdxVol[i][3] = this->GetOutput()->GetBufferedRegion().GetIndex()[i];
    matrixIdxVol[2][3] = region.GetIndex()[2];

    itk::Matrix<double, 3, 3> matrixIdxProj;
    matrixIdxProj.SetIdentity();
    for(unsigned int i=0; i<2; i++)
      matrixIdxProj[i][2] = -1*(projection->GetBufferedRegion().GetIndex()[i])+0.5; //SR: 0.5 for 2D texture?

    matrix = matrixIdxProj.GetVnlMatrix() * matrix.GetVnlMatrix() * matrixIdxVol.GetVnlMatrix();

    double perspFactor = matrix[Dimension-1][Dimension];
    for(unsigned int j=0; j<Dimension; j++)
      perspFactor += matrix[Dimension-1][j] * rotCenterIndex[j];
    matrix /= perspFactor;

    float fMatrix[12];
    for (int j = 0; j < 12; j++)
      fMatrix[j] = matrix[j/4][j%4];

    CUDA_reconstruct_conebeam(img_dim, vol_dim, projection->GetBufferPointer(), fMatrix, dev_vol, dev_img, dev_matrix);
    }

  CUDA_reconstruct_conebeam_cleanup (vol_dim, this->GetOutput()->GetBufferPointer(), dev_vol, dev_img, dev_matrix);
}

} // end namespace itk
<|endoftext|>


<commit_before>// Copyright 2014 Vladimir Alyamkin. All Rights Reserved.

#include "VaOcean.h"
#include "VaOceanPrivate.h"

#define LOCTEXT_NAMESPACE "FVaOceanModule"

void FVaOceanModule::StartupModule()
{
	// This code will execute after your module is loaded into memory; the exact timing is specified in the .uplugin file per-module
}

void FVaOceanModule::ShutdownModule()
{
	// This function may be called during shutdown to clean up your module.  For modules that support dynamic reloading,
	// we call this function before unloading the module.
}

#undef LOCTEXT_NAMESPACE

IMPLEMENT_MODULE(FVaOceanModule, VaOcean)

DEFINE_LOG_CATEGORY(LogVaOcean);
<commit_msg>Copyright update<commit_after>// Copyright 2014-2018 Vladimir Alyamkin. All Rights Reserved.

#include "VaOcean.h"
#include "VaOceanPrivate.h"

#define LOCTEXT_NAMESPACE "FVaOceanModule"

void FVaOceanModule::StartupModule()
{
	// This code will execute after your module is loaded into memory; the exact timing is specified in the .uplugin file per-module
}

void FVaOceanModule::ShutdownModule()
{
	// This function may be called during shutdown to clean up your module.  For modules that support dynamic reloading,
	// we call this function before unloading the module.
}

#undef LOCTEXT_NAMESPACE

IMPLEMENT_MODULE(FVaOceanModule, VaOcean)

DEFINE_LOG_CATEGORY(LogVaOcean);
<|endoftext|>


<commit_before>#include <cxxtest/TestDrive.h>

#include <openma/io/handlerwriter.h>
#include <openma/io/file.h>

#include "c3dhandlerTest_def.h"
#include "test_file_path.h"

CXXTEST_SUITE(C3DWriterTest)
{
  CXXTEST_TEST(capability)
  {
    ma::io::HandlerWriter writer(nullptr,"org.c3d");
    TS_ASSERT_EQUALS(writer.canWrite(), false);
    ma::io::File file;
    file.open(OPENMA_TDD_PATH_OUT("c3d/sample01_Eb015pi.c3d"), ma::io::Mode::Out);
    writer.setDevice(&file);
    TS_ASSERT_EQUALS(writer.canWrite(), true);
    TS_ASSERT_EQUALS(writer.format(), "org.c3d");
    TS_ASSERT_EQUALS(writer.errorCode(), ma::io::Error::None);
  };

  CXXTEST_TEST(supportedTrialFormats)
  {
    ma::io::HandlerWriter writer;
    auto formats = writer.availableFormats();
    TS_ASSERT_EQUALS(std::find(formats.cbegin(), formats.cend(), "org.c3d") != formats.cend(), true);
  };

  CXXTEST_TEST(detectNoDevice)
  {
    ma::io::HandlerWriter writer;
    TS_ASSERT_EQUALS(writer.canWrite(), false);
    TS_ASSERT_EQUALS(writer.errorCode(), ma::io::Error::Device);
  };

  CXXTEST_TEST(detectDeviceNotOpen)
  {
    ma::io::File file;
    ma::io::HandlerWriter writer(&file);
    TS_ASSERT_EQUALS(writer.canWrite(), false);
    TS_ASSERT_EQUALS(writer.errorCode(), ma::io::Error::Device);
  };

  CXXTEST_TEST(detectFail)
  {
    ma::io::File file;
    file.open(OPENMA_TDD_PATH_OUT("fail.xyz"), ma::io::Mode::Out);
    ma::io::HandlerWriter writer(&file);
    TS_ASSERT_EQUALS(writer.canWrite(), false);
    TS_ASSERT_EQUALS(writer.errorCode(), ma::io::Error::UnsupportedFormat);
  };

  CXXTEST_TEST(detectOk)
  {
    ma::io::File file;
    file.open(OPENMA_TDD_PATH_OUT("c3d/sample01_Eb015pi.c3d"), ma::io::Mode::Out);
    ma::io::HandlerWriter writer(&file);
    TS_ASSERT_EQUALS(writer.canWrite(), true);
    TS_ASSERT_EQUALS(writer.errorCode(), ma::io::Error::None);
  };

  CXXTEST_TEST(queryOkOne)
  {
    ma::io::File file;
    file.open(OPENMA_TDD_PATH_OUT("c3d/sample01_Eb015pi.c3d"), ma::io::Mode::Out);
    ma::io::HandlerWriter writer(&file, "org.c3d");
    TS_ASSERT_EQUALS(writer.canWrite(), true);
    TS_ASSERT_EQUALS(writer.errorCode(), ma::io::Error::None);
  };

  CXXTEST_TEST(queryOkTwo)
  {
    ma::io::File file;
    file.open(OPENMA_TDD_PATH_OUT("c3d/sample01_Eb015pi.c3d"), ma::io::Mode::Out);
    ma::io::HandlerWriter writer(nullptr, "org.c3d");
    writer.setDevice(&file);
    TS_ASSERT_EQUALS(writer.canWrite(), true);
    TS_ASSERT_EQUALS(writer.errorCode(), ma::io::Error::None);
  };

  CXXTEST_TEST(queryOkThree)
  {
    ma::io::File file;
    file.open(OPENMA_TDD_PATH_OUT("c3d/sample01_Eb015pi.c3d"), ma::io::Mode::Out);
    ma::io::HandlerWriter writer;
    writer.setDevice(&file);
    writer.setFormat("org.c3d");
    TS_ASSERT_EQUALS(writer.canWrite(), true);
    TS_ASSERT_EQUALS(writer.errorCode(), ma::io::Error::None);
  };

  CXXTEST_TEST(sample01Rewrited)
  {
    c3dhandlertest_rewrite_sample01("PI", "sample01_Eb015pi.c3d", OPENMA_TDD_PATH_OUT("c3d/sample01_Eb015pi.c3d"), OPENMA_TDD_PATH_IN("c3d/standard/sample01/Eb015pi.c3d"));
  }

  CXXTEST_TEST(sample09Rewrited)
  {
    ma::Node rootIn("rootIn"), rootOut("rootOut");
    if (!c3dhandlertest_read("", OPENMA_TDD_PATH_IN("c3d/standard/sample09/PlugInC3D.c3d"), &rootIn)) return;
    ma::TimeSequence* ts = rootIn.findChild<ma::TimeSequence*>("LHipForce");
    TS_ASSERT_EQUALS(ts->type(), ma::TimeSequence::Force);
    TS_ASSERT_EQUALS(ts->unit(), "N");
    if (!c3dhandlertest_write("", OPENMA_TDD_PATH_OUT("c3d/sample09_PlugInC3D.c3d"), &rootIn)) return;
    if (!c3dhandlertest_read("", OPENMA_TDD_PATH_OUT("c3d/sample09_PlugInC3D.c3d"), &rootOut)) return;
    ma::TimeSequence* ts2 = rootOut.findChild<ma::TimeSequence*>("LHipForce");
    TS_ASSERT_EQUALS(ts2->type(), ma::TimeSequence::Force);
    TS_ASSERT_EQUALS(ts2->unit(), "N");
    // Compare time sequences together
    TS_ASSERT_EQUALS(ts2->elements(), ts->elements());
    TS_ASSERT_EQUALS(ts2->elements(), 281 * 4);
    for (unsigned i = 0 ; i < ts->elements() ; ++i)
    {
      TS_ASSERT_DELTA(ts2->data()[i], ts->data()[i], 1e-5);
    }
  }
};

CXXTEST_SUITE_REGISTRATION(C3DWriterTest)
CXXTEST_TEST_REGISTRATION(C3DWriterTest, capability)
CXXTEST_TEST_REGISTRATION(C3DWriterTest, supportedTrialFormats)
CXXTEST_TEST_REGISTRATION(C3DWriterTest, detectNoDevice)
CXXTEST_TEST_REGISTRATION(C3DWriterTest, detectDeviceNotOpen)
CXXTEST_TEST_REGISTRATION(C3DWriterTest, detectFail)
CXXTEST_TEST_REGISTRATION(C3DWriterTest, detectOk)
CXXTEST_TEST_REGISTRATION(C3DWriterTest, queryOkOne)
CXXTEST_TEST_REGISTRATION(C3DWriterTest, queryOkTwo)
CXXTEST_TEST_REGISTRATION(C3DWriterTest, queryOkThree)
CXXTEST_TEST_REGISTRATION(C3DWriterTest, sample01Rewrited)
CXXTEST_TEST_REGISTRATION(C3DWriterTest, sample09Rewrited)<commit_msg>comparison of integers of different signs: 'unsigned long' and 'int'.<commit_after>#include <cxxtest/TestDrive.h>

#include <openma/io/handlerwriter.h>
#include <openma/io/file.h>

#include "c3dhandlerTest_def.h"
#include "test_file_path.h"

CXXTEST_SUITE(C3DWriterTest)
{
  CXXTEST_TEST(capability)
  {
    ma::io::HandlerWriter writer(nullptr,"org.c3d");
    TS_ASSERT_EQUALS(writer.canWrite(), false);
    ma::io::File file;
    file.open(OPENMA_TDD_PATH_OUT("c3d/sample01_Eb015pi.c3d"), ma::io::Mode::Out);
    writer.setDevice(&file);
    TS_ASSERT_EQUALS(writer.canWrite(), true);
    TS_ASSERT_EQUALS(writer.format(), "org.c3d");
    TS_ASSERT_EQUALS(writer.errorCode(), ma::io::Error::None);
  };

  CXXTEST_TEST(supportedTrialFormats)
  {
    ma::io::HandlerWriter writer;
    auto formats = writer.availableFormats();
    TS_ASSERT_EQUALS(std::find(formats.cbegin(), formats.cend(), "org.c3d") != formats.cend(), true);
  };

  CXXTEST_TEST(detectNoDevice)
  {
    ma::io::HandlerWriter writer;
    TS_ASSERT_EQUALS(writer.canWrite(), false);
    TS_ASSERT_EQUALS(writer.errorCode(), ma::io::Error::Device);
  };

  CXXTEST_TEST(detectDeviceNotOpen)
  {
    ma::io::File file;
    ma::io::HandlerWriter writer(&file);
    TS_ASSERT_EQUALS(writer.canWrite(), false);
    TS_ASSERT_EQUALS(writer.errorCode(), ma::io::Error::Device);
  };

  CXXTEST_TEST(detectFail)
  {
    ma::io::File file;
    file.open(OPENMA_TDD_PATH_OUT("fail.xyz"), ma::io::Mode::Out);
    ma::io::HandlerWriter writer(&file);
    TS_ASSERT_EQUALS(writer.canWrite(), false);
    TS_ASSERT_EQUALS(writer.errorCode(), ma::io::Error::UnsupportedFormat);
  };

  CXXTEST_TEST(detectOk)
  {
    ma::io::File file;
    file.open(OPENMA_TDD_PATH_OUT("c3d/sample01_Eb015pi.c3d"), ma::io::Mode::Out);
    ma::io::HandlerWriter writer(&file);
    TS_ASSERT_EQUALS(writer.canWrite(), true);
    TS_ASSERT_EQUALS(writer.errorCode(), ma::io::Error::None);
  };

  CXXTEST_TEST(queryOkOne)
  {
    ma::io::File file;
    file.open(OPENMA_TDD_PATH_OUT("c3d/sample01_Eb015pi.c3d"), ma::io::Mode::Out);
    ma::io::HandlerWriter writer(&file, "org.c3d");
    TS_ASSERT_EQUALS(writer.canWrite(), true);
    TS_ASSERT_EQUALS(writer.errorCode(), ma::io::Error::None);
  };

  CXXTEST_TEST(queryOkTwo)
  {
    ma::io::File file;
    file.open(OPENMA_TDD_PATH_OUT("c3d/sample01_Eb015pi.c3d"), ma::io::Mode::Out);
    ma::io::HandlerWriter writer(nullptr, "org.c3d");
    writer.setDevice(&file);
    TS_ASSERT_EQUALS(writer.canWrite(), true);
    TS_ASSERT_EQUALS(writer.errorCode(), ma::io::Error::None);
  };

  CXXTEST_TEST(queryOkThree)
  {
    ma::io::File file;
    file.open(OPENMA_TDD_PATH_OUT("c3d/sample01_Eb015pi.c3d"), ma::io::Mode::Out);
    ma::io::HandlerWriter writer;
    writer.setDevice(&file);
    writer.setFormat("org.c3d");
    TS_ASSERT_EQUALS(writer.canWrite(), true);
    TS_ASSERT_EQUALS(writer.errorCode(), ma::io::Error::None);
  };

  CXXTEST_TEST(sample01Rewrited)
  {
    c3dhandlertest_rewrite_sample01("PI", "sample01_Eb015pi.c3d", OPENMA_TDD_PATH_OUT("c3d/sample01_Eb015pi.c3d"), OPENMA_TDD_PATH_IN("c3d/standard/sample01/Eb015pi.c3d"));
  }

  CXXTEST_TEST(sample09Rewrited)
  {
    ma::Node rootIn("rootIn"), rootOut("rootOut");
    if (!c3dhandlertest_read("", OPENMA_TDD_PATH_IN("c3d/standard/sample09/PlugInC3D.c3d"), &rootIn)) return;
    ma::TimeSequence* ts = rootIn.findChild<ma::TimeSequence*>("LHipForce");
    TS_ASSERT_EQUALS(ts->type(), ma::TimeSequence::Force);
    TS_ASSERT_EQUALS(ts->unit(), "N");
    if (!c3dhandlertest_write("", OPENMA_TDD_PATH_OUT("c3d/sample09_PlugInC3D.c3d"), &rootIn)) return;
    if (!c3dhandlertest_read("", OPENMA_TDD_PATH_OUT("c3d/sample09_PlugInC3D.c3d"), &rootOut)) return;
    ma::TimeSequence* ts2 = rootOut.findChild<ma::TimeSequence*>("LHipForce");
    TS_ASSERT_EQUALS(ts2->type(), ma::TimeSequence::Force);
    TS_ASSERT_EQUALS(ts2->unit(), "N");
    // Compare time sequences together
    TS_ASSERT_EQUALS(ts2->elements(), ts->elements());
    TS_ASSERT_EQUALS(ts2->elements(), size_t(281 * 4));
    for (unsigned i = 0 ; i < ts->elements() ; ++i)
    {
      TS_ASSERT_DELTA(ts2->data()[i], ts->data()[i], 1e-5);
    }
  }
};

CXXTEST_SUITE_REGISTRATION(C3DWriterTest)
CXXTEST_TEST_REGISTRATION(C3DWriterTest, capability)
CXXTEST_TEST_REGISTRATION(C3DWriterTest, supportedTrialFormats)
CXXTEST_TEST_REGISTRATION(C3DWriterTest, detectNoDevice)
CXXTEST_TEST_REGISTRATION(C3DWriterTest, detectDeviceNotOpen)
CXXTEST_TEST_REGISTRATION(C3DWriterTest, detectFail)
CXXTEST_TEST_REGISTRATION(C3DWriterTest, detectOk)
CXXTEST_TEST_REGISTRATION(C3DWriterTest, queryOkOne)
CXXTEST_TEST_REGISTRATION(C3DWriterTest, queryOkTwo)
CXXTEST_TEST_REGISTRATION(C3DWriterTest, queryOkThree)
CXXTEST_TEST_REGISTRATION(C3DWriterTest, sample01Rewrited)
CXXTEST_TEST_REGISTRATION(C3DWriterTest, sample09Rewrited)<|endoftext|>


<commit_before>// /*****************************************************************************************
//  *                                                                                *
//  * OpenSpace                                                                             *
//  *                                                                                *
//  * Copyright (c) 2014-2016                                                               *
//  *                                                                                *
//  * 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.                                         *
//  ****************************************************************************************/
#include <modules/iswa/rendering/textureplane.h>
#include <openspace/engine/openspaceengine.h>
#include <openspace/rendering/renderengine.h>
#include <ghoul/filesystem/filesystem>
#include <ghoul/io/texture/texturereader.h>
#include <ghoul/opengl/programobject.h>
#include <ghoul/opengl/texture.h>
#include <ghoul/opengl/textureunit.h>
#include <modules/kameleon/include/kameleonwrapper.h>
#include <openspace/scene/scene.h>
#include <openspace/scene/scenegraphnode.h>
#include <openspace/util/time.h>
#include <openspace/util/spicemanager.h>

namespace {
	const std::string _loggerCat = "TexutePlane";
}

namespace openspace {

TexturePlane::TexturePlane()
	:CygnetPlane()
	,_futureTexture(nullptr)
{
	_id = id();
	setName("TexturePlane" + std::to_string(_id));
	registerProperties();

	_fileExtension = ISWAManager::ref().fileExtension(_cygnetId.value());
	_path = "${OPENSPACE_DATA}/"+ name()+_fileExtension;

	_cygnetId.onChange([this](){
		_fileExtension = ISWAManager::ref().fileExtension(_cygnetId.value());
		_path = "${OPENSPACE_DATA}/"+ name()+_fileExtension;
		updateTexture(); });
}

TexturePlane::~TexturePlane(){

}

bool TexturePlane::initialize(){
	_modelScale = glm::vec4(3, 3, 3, 10);
	_pscOffset  = glm::vec4(0, 0, 0, 1);

	CygnetPlane::initialize();

	std::thread t = std::thread(std::bind(&TexturePlane::updateTexture, this));
	t.detach();

    loadTexture();

    return isReady();
}

bool TexturePlane::deinitialize(){
	CygnetPlane::deinitialize();

	glDeleteVertexArrays(1, &_quad);
	_quad = 0;

	glDeleteBuffers(1, &_vertexPositionBuffer);
	_vertexPositionBuffer = 0;

    RenderEngine& renderEngine = OsEng.renderEngine();
    if (_shader) {
        renderEngine.removeRenderProgram(_shader);
        _shader = nullptr;
    }

    std::remove(absPath(_path).c_str());

	return true;
}

void TexturePlane::render(){
	psc position = _parent->worldPosition();

	glm::mat4 transform = glm::mat4(1.0);
	transform = glm::inverse(OsEng.renderEngine().camera()->viewRotationMatrix());

	float textureRatio = (float (_texture->height()/float(_texture->width())));
	transform = glm::scale(transform, glm::vec3(1, textureRatio, 1));

	glm::mat4 rotx = glm::rotate(transform, static_cast<float>(M_PI_2), glm::vec3(1, 0, 0));
	glm::mat4 roty = glm::rotate(transform, static_cast<float>(M_PI_2), glm::vec3(0, 1, 0));
	// glm::mat4 rot = glm::mat4(1.0);
/*	for (int i = 0; i < 3; i++){
		for (int j = 0; j < 3; j++){
			transform[i][j] = static_cast<float>(_stateMatrix[i][j]);
		}
	}*/

	//transform = transform * roty * rotx;
	//position += transform*glm::vec4(-_pscOffset.x, _pscOffset.z, _pscOffset.y, _pscOffset.w);

	// transform = glm::rotate(transform, _roatation.value()[0], glm::vec3(1,0,0));
	// transform = glm::rotate(transform, _roatation.value()[1], glm::vec3(0,1,0));
	// transform = glm::rotate(transform, _roatation.value()[2], glm::vec3(0,0,1));

	// Activate shader
	_shader->activate();
	glEnable(GL_ALPHA_TEST);
	glDisable(GL_CULL_FACE);
	_shader->setUniform("ViewProjection", OsEng.renderEngine().camera()->viewProjectionMatrix());
	_shader->setUniform("ModelTransform", transform);
	setPscUniforms(_shader.get(), OsEng.renderEngine().camera(), position);

	ghoul::opengl::TextureUnit unit;
	unit.activate();
	_texture->bind();
	_shader->setUniform("texture1", unit);

	glBindVertexArray(_quad);
	glDrawArrays(GL_TRIANGLES, 0, 6);
	glEnable(GL_CULL_FACE);

	_shader->deactivate();

}

void TexturePlane::update(){
	CygnetPlane::update();

	if(_futureTexture && _futureTexture->isFinished){
		_path = absPath("${OPENSPACE_DATA}/"+_futureTexture->filePath);
		loadTexture();

		delete _futureTexture;
		_futureTexture = nullptr;
	}
}

void TexturePlane::setParent(){
	_parent = OsEng.renderEngine().scene()->sceneGraphNode("Sun");
}

void TexturePlane::updateTexture(){
	DownloadManager::FileFuture* future = ISWAManager::ref().downloadImage(_cygnetId.value(), absPath(_path));
	if(future){
		_futureTexture = future;
	}
}

void TexturePlane::loadTexture() {

		std::unique_ptr<ghoul::opengl::Texture> texture = ghoul::io::TextureReader::ref().loadTexture(absPath(_path));

		if (texture) {
			LDEBUG("Loaded texture from '" << absPath(_path) << "'");

			texture->uploadTexture();
			// Textures of planets looks much smoother with AnisotropicMipMap rather than linear
			texture->setFilter(ghoul::opengl::Texture::FilterMode::Linear);

            _texture = std::move(texture);
		}

}

int TexturePlane::id(){
		static int id = 0;
		return id++;
}

}// namespace openspace<commit_msg>remove thread and called update texture in textureplane constructor<commit_after>// /*****************************************************************************************
//  *                                                                                *
//  * OpenSpace                                                                             *
//  *                                                                                *
//  * Copyright (c) 2014-2016                                                               *
//  *                                                                                *
//  * 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.                                         *
//  ****************************************************************************************/
#include <modules/iswa/rendering/textureplane.h>
#include <openspace/engine/openspaceengine.h>
#include <openspace/rendering/renderengine.h>
#include <ghoul/filesystem/filesystem>
#include <ghoul/io/texture/texturereader.h>
#include <ghoul/opengl/programobject.h>
#include <ghoul/opengl/texture.h>
#include <ghoul/opengl/textureunit.h>
#include <modules/kameleon/include/kameleonwrapper.h>
#include <openspace/scene/scene.h>
#include <openspace/scene/scenegraphnode.h>
#include <openspace/util/time.h>
#include <openspace/util/spicemanager.h>

namespace {
	const std::string _loggerCat = "TexutePlane";
}

namespace openspace {

TexturePlane::TexturePlane()
	:CygnetPlane()
	,_futureTexture(nullptr)
{
	_id = id();
	setName("TexturePlane" + std::to_string(_id));
	registerProperties();

	_fileExtension = ISWAManager::ref().fileExtension(_cygnetId.value());
	_path = "${OPENSPACE_DATA}/"+ name()+_fileExtension;

	updateTexture();

	_cygnetId.onChange([this](){
		_fileExtension = ISWAManager::ref().fileExtension(_cygnetId.value());
		_path = "${OPENSPACE_DATA}/"+ name()+_fileExtension;
		updateTexture(); });
}

TexturePlane::~TexturePlane(){

}

bool TexturePlane::initialize(){
	_modelScale = glm::vec4(3, 3, 3, 10);
	_pscOffset  = glm::vec4(0, 0, 0, 1);

	CygnetPlane::initialize();

    loadTexture();

    return isReady();
}

bool TexturePlane::deinitialize(){
	CygnetPlane::deinitialize();

	glDeleteVertexArrays(1, &_quad);
	_quad = 0;

	glDeleteBuffers(1, &_vertexPositionBuffer);
	_vertexPositionBuffer = 0;

    RenderEngine& renderEngine = OsEng.renderEngine();
    if (_shader) {
        renderEngine.removeRenderProgram(_shader);
        _shader = nullptr;
    }

    std::remove(absPath(_path).c_str());

	return true;
}

void TexturePlane::render(){
	psc position = _parent->worldPosition();

	glm::mat4 transform = glm::mat4(1.0);
	transform = glm::inverse(OsEng.renderEngine().camera()->viewRotationMatrix());

	float textureRatio = (float (_texture->height()/float(_texture->width())));
	transform = glm::scale(transform, glm::vec3(1, textureRatio, 1));

	glm::mat4 rotx = glm::rotate(transform, static_cast<float>(M_PI_2), glm::vec3(1, 0, 0));
	glm::mat4 roty = glm::rotate(transform, static_cast<float>(M_PI_2), glm::vec3(0, 1, 0));
	// glm::mat4 rot = glm::mat4(1.0);
/*	for (int i = 0; i < 3; i++){
		for (int j = 0; j < 3; j++){
			transform[i][j] = static_cast<float>(_stateMatrix[i][j]);
		}
	}*/

	//transform = transform * roty * rotx;
	//position += transform*glm::vec4(-_pscOffset.x, _pscOffset.z, _pscOffset.y, _pscOffset.w);

	// transform = glm::rotate(transform, _roatation.value()[0], glm::vec3(1,0,0));
	// transform = glm::rotate(transform, _roatation.value()[1], glm::vec3(0,1,0));
	// transform = glm::rotate(transform, _roatation.value()[2], glm::vec3(0,0,1));

	// Activate shader
	_shader->activate();
	glEnable(GL_ALPHA_TEST);
	glDisable(GL_CULL_FACE);
	_shader->setUniform("ViewProjection", OsEng.renderEngine().camera()->viewProjectionMatrix());
	_shader->setUniform("ModelTransform", transform);
	setPscUniforms(_shader.get(), OsEng.renderEngine().camera(), position);

	ghoul::opengl::TextureUnit unit;
	unit.activate();
	_texture->bind();
	_shader->setUniform("texture1", unit);

	glBindVertexArray(_quad);
	glDrawArrays(GL_TRIANGLES, 0, 6);
	glEnable(GL_CULL_FACE);

	_shader->deactivate();

}

void TexturePlane::update(){
	CygnetPlane::update();

	if(_futureTexture && _futureTexture->isFinished){
		_path = absPath("${OPENSPACE_DATA}/"+_futureTexture->filePath);
		loadTexture();

		delete _futureTexture;
		_futureTexture = nullptr;
	}
}

void TexturePlane::setParent(){
	_parent = OsEng.renderEngine().scene()->sceneGraphNode("Sun");
}

void TexturePlane::updateTexture(){
	DownloadManager::FileFuture* future = ISWAManager::ref().downloadImage(_cygnetId.value(), absPath(_path));
	if(future){
		_futureTexture = future;
	}
}

void TexturePlane::loadTexture() {

		std::unique_ptr<ghoul::opengl::Texture> texture = ghoul::io::TextureReader::ref().loadTexture(absPath(_path));

		if (texture) {
			LDEBUG("Loaded texture from '" << absPath(_path) << "'");

			texture->uploadTexture();
			// Textures of planets looks much smoother with AnisotropicMipMap rather than linear
			texture->setFilter(ghoul::opengl::Texture::FilterMode::Linear);

            _texture = std::move(texture);
		}

}

int TexturePlane::id(){
		static int id = 0;
		return id++;
}

}// namespace openspace<|endoftext|>


<commit_before>// Copyright 2015 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 "mojo/edk/system/ipc_support.h"

#include "base/bind.h"
#include "base/command_line.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/synchronization/waitable_event.h"
#include "base/test/test_io_thread.h"
#include "base/test/test_timeouts.h"
#include "mojo/edk/embedder/master_process_delegate.h"
#include "mojo/edk/embedder/platform_channel_pair.h"
#include "mojo/edk/embedder/simple_platform_support.h"
#include "mojo/edk/embedder/slave_process_delegate.h"
#include "mojo/edk/system/connection_identifier.h"
#include "mojo/edk/system/process_identifier.h"
#include "mojo/edk/test/multiprocess_test_helper.h"
#include "mojo/edk/test/test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace mojo {
namespace system {
namespace {

const char kConnectionIdFlag[] = "test-connection-id";

class TestMasterProcessDelegate : public embedder::MasterProcessDelegate {
 public:
  TestMasterProcessDelegate()
      : on_slave_disconnect_event_(true, false) {}  // Manual reset.
  ~TestMasterProcessDelegate() override {}

  bool TryWaitForOnSlaveDisconnect() {
    return on_slave_disconnect_event_.TimedWait(TestTimeouts::action_timeout());
  }

 private:
  // |embedder::MasterProcessDelegate| methods:
  void OnShutdownComplete() override { NOTREACHED(); }

  void OnSlaveDisconnect(embedder::SlaveInfo /*slave_info*/) override {
    on_slave_disconnect_event_.Signal();
  }

  base::WaitableEvent on_slave_disconnect_event_;

  DISALLOW_COPY_AND_ASSIGN(TestMasterProcessDelegate);
};

class TestSlaveProcessDelegate : public embedder::SlaveProcessDelegate {
 public:
  TestSlaveProcessDelegate() {}
  ~TestSlaveProcessDelegate() override {}

 private:
  // |embedder::SlaveProcessDelegate| methods:
  void OnShutdownComplete() override { NOTREACHED(); }

  void OnMasterDisconnect() override { NOTREACHED(); }

  DISALLOW_COPY_AND_ASSIGN(TestSlaveProcessDelegate);
};

}  // namespace

// Note: This test isn't in an anonymous namespace, since it needs to be
// friended by |IPCSupport|.
TEST(IPCSupportTest, MasterSlaveInternal) {
  embedder::SimplePlatformSupport platform_support;
  base::TestIOThread test_io_thread(base::TestIOThread::kAutoStart);
  TestMasterProcessDelegate master_process_delegate;
  // Note: Run master process delegate methods on the I/O thread.
  IPCSupport master_ipc_support(
      &platform_support, embedder::ProcessType::MASTER,
      test_io_thread.task_runner(), &master_process_delegate,
      test_io_thread.task_runner(), embedder::ScopedPlatformHandle());

  ConnectionIdentifier connection_id =
      master_ipc_support.GenerateConnectionIdentifier();

  embedder::PlatformChannelPair channel_pair;
  ProcessIdentifier slave_id = kInvalidProcessIdentifier;
  embedder::ScopedPlatformHandle master_second_platform_handle =
      master_ipc_support.ConnectToSlaveInternal(
          connection_id, nullptr, channel_pair.PassServerHandle(), &slave_id);
  ASSERT_TRUE(master_second_platform_handle.is_valid());
  EXPECT_NE(slave_id, kInvalidProcessIdentifier);
  EXPECT_NE(slave_id, kMasterProcessIdentifier);

  TestSlaveProcessDelegate slave_process_delegate;
  // Note: Run process delegate methods on the I/O thread.
  IPCSupport slave_ipc_support(
      &platform_support, embedder::ProcessType::SLAVE,
      test_io_thread.task_runner(), &slave_process_delegate,
      test_io_thread.task_runner(), channel_pair.PassClientHandle());

  embedder::ScopedPlatformHandle slave_second_platform_handle =
      slave_ipc_support.ConnectToMasterInternal(connection_id);
  ASSERT_TRUE(slave_second_platform_handle.is_valid());

  // Write an 'x' through the master's end.
  size_t n = 0;
  EXPECT_TRUE(mojo::test::BlockingWrite(master_second_platform_handle.get(),
                                        "x", 1, &n));
  EXPECT_EQ(1u, n);

  // Read it from the slave's end.
  char c = '\0';
  n = 0;
  EXPECT_TRUE(
      mojo::test::BlockingRead(slave_second_platform_handle.get(), &c, 1, &n));
  EXPECT_EQ(1u, n);
  EXPECT_EQ('x', c);

  test_io_thread.PostTaskAndWait(
      FROM_HERE, base::Bind(&IPCSupport::ShutdownOnIOThread,
                            base::Unretained(&slave_ipc_support)));

  EXPECT_TRUE(master_process_delegate.TryWaitForOnSlaveDisconnect());

  test_io_thread.PostTaskAndWait(
      FROM_HERE, base::Bind(&IPCSupport::ShutdownOnIOThread,
                            base::Unretained(&master_ipc_support)));
}

// This is a true multiprocess version of IPCSupportTest.MasterSlaveInternal.
// Note: This test isn't in an anonymous namespace, since it needs to be
// friended by |IPCSupport|.
#if defined(OS_ANDROID)
// Android multi-process tests are not executing the new process. This is flaky.
// TODO(vtl): I'm guessing this is true of this test too?
#define MAYBE_MultiprocessMasterSlaveInternal \
  DISABLED_MultiprocessMasterSlaveInternal
#else
#define MAYBE_MultiprocessMasterSlaveInternal MultiprocessMasterSlaveInternal
#endif  // defined(OS_ANDROID)
TEST(IPCSupportTest, MAYBE_MultiprocessMasterSlaveInternal) {
  embedder::SimplePlatformSupport platform_support;
  base::TestIOThread test_io_thread(base::TestIOThread::kAutoStart);
  TestMasterProcessDelegate master_process_delegate;
  // Note: Run process delegate methods on the I/O thread.
  IPCSupport ipc_support(&platform_support, embedder::ProcessType::MASTER,
                         test_io_thread.task_runner(), &master_process_delegate,
                         test_io_thread.task_runner(),
                         embedder::ScopedPlatformHandle());

  ConnectionIdentifier connection_id =
      ipc_support.GenerateConnectionIdentifier();
  mojo::test::MultiprocessTestHelper multiprocess_test_helper;
  ProcessIdentifier slave_id = kInvalidProcessIdentifier;
  embedder::ScopedPlatformHandle second_platform_handle =
      ipc_support.ConnectToSlaveInternal(
          connection_id, nullptr,
          multiprocess_test_helper.server_platform_handle.Pass(), &slave_id);
  ASSERT_TRUE(second_platform_handle.is_valid());
  EXPECT_NE(slave_id, kInvalidProcessIdentifier);
  EXPECT_NE(slave_id, kMasterProcessIdentifier);

  multiprocess_test_helper.StartChildWithExtraSwitch(
      "MultiprocessMasterSlaveInternal", kConnectionIdFlag,
      connection_id.ToString());

  // We write a '?'. The slave should write a '!' in response.
  size_t n = 0;
  EXPECT_TRUE(
      mojo::test::BlockingWrite(second_platform_handle.get(), "?", 1, &n));
  EXPECT_EQ(1u, n);

  char c = '\0';
  n = 0;
  EXPECT_TRUE(
      mojo::test::BlockingRead(second_platform_handle.get(), &c, 1, &n));
  EXPECT_EQ(1u, n);
  EXPECT_EQ('!', c);

  EXPECT_TRUE(master_process_delegate.TryWaitForOnSlaveDisconnect());
  EXPECT_TRUE(multiprocess_test_helper.WaitForChildTestShutdown());

  test_io_thread.PostTaskAndWait(FROM_HERE,
                                 base::Bind(&IPCSupport::ShutdownOnIOThread,
                                            base::Unretained(&ipc_support)));
}

MOJO_MULTIPROCESS_TEST_CHILD_TEST(MultiprocessMasterSlaveInternal) {
  embedder::ScopedPlatformHandle client_platform_handle =
      mojo::test::MultiprocessTestHelper::client_platform_handle.Pass();
  ASSERT_TRUE(client_platform_handle.is_valid());

  embedder::SimplePlatformSupport platform_support;
  base::TestIOThread test_io_thread(base::TestIOThread::kAutoStart);
  TestSlaveProcessDelegate slave_process_delegate;
  // Note: Run process delegate methods on the I/O thread.
  IPCSupport ipc_support(&platform_support, embedder::ProcessType::SLAVE,
                         test_io_thread.task_runner(), &slave_process_delegate,
                         test_io_thread.task_runner(),
                         client_platform_handle.Pass());

  const base::CommandLine& command_line =
      *base::CommandLine::ForCurrentProcess();
  ASSERT_TRUE(command_line.HasSwitch(kConnectionIdFlag));
  bool ok = false;
  ConnectionIdentifier connection_id = ConnectionIdentifier::FromString(
      command_line.GetSwitchValueASCII(kConnectionIdFlag), &ok);
  ASSERT_TRUE(ok);

  embedder::ScopedPlatformHandle second_platform_handle =
      ipc_support.ConnectToMasterInternal(connection_id);
  ASSERT_TRUE(second_platform_handle.is_valid());

  // The master should write a '?'. We'll write a '!' in response.
  char c = '\0';
  size_t n = 0;
  EXPECT_TRUE(
      mojo::test::BlockingRead(second_platform_handle.get(), &c, 1, &n));
  EXPECT_EQ(1u, n);
  EXPECT_EQ('?', c);

  n = 0;
  EXPECT_TRUE(
      mojo::test::BlockingWrite(second_platform_handle.get(), "!", 1, &n));
  EXPECT_EQ(1u, n);

  test_io_thread.PostTaskAndWait(FROM_HERE,
                                 base::Bind(&IPCSupport::ShutdownOnIOThread,
                                            base::Unretained(&ipc_support)));
}

// TODO(vtl): Also test the case of the master "dying" before the slave. (The
// slave should get OnMasterDisconnect(), which we currently don't test.)

}  // namespace system
}  // namespace mojo
<commit_msg>Add a test for IPCSupport::ConnectTo{Slave,Master}().<commit_after>// Copyright 2015 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 "mojo/edk/system/ipc_support.h"

#include "base/bind.h"
#include "base/command_line.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/synchronization/waitable_event.h"
#include "base/test/test_io_thread.h"
#include "base/test/test_timeouts.h"
#include "mojo/edk/embedder/master_process_delegate.h"
#include "mojo/edk/embedder/platform_channel_pair.h"
#include "mojo/edk/embedder/simple_platform_support.h"
#include "mojo/edk/embedder/slave_process_delegate.h"
#include "mojo/edk/system/channel_manager.h"
#include "mojo/edk/system/connection_identifier.h"
#include "mojo/edk/system/message_pipe_dispatcher.h"
#include "mojo/edk/system/process_identifier.h"
#include "mojo/edk/system/test_utils.h"
#include "mojo/edk/system/waiter.h"
#include "mojo/edk/test/multiprocess_test_helper.h"
#include "mojo/edk/test/test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace mojo {
namespace system {
namespace {

const char kConnectionIdFlag[] = "test-connection-id";

class TestMasterProcessDelegate : public embedder::MasterProcessDelegate {
 public:
  TestMasterProcessDelegate()
      : on_slave_disconnect_event_(true, false) {}  // Manual reset.
  ~TestMasterProcessDelegate() override {}

  bool TryWaitForOnSlaveDisconnect() {
    return on_slave_disconnect_event_.TimedWait(TestTimeouts::action_timeout());
  }

 private:
  // |embedder::MasterProcessDelegate| methods:
  void OnShutdownComplete() override { NOTREACHED(); }

  void OnSlaveDisconnect(embedder::SlaveInfo /*slave_info*/) override {
    on_slave_disconnect_event_.Signal();
  }

  base::WaitableEvent on_slave_disconnect_event_;

  DISALLOW_COPY_AND_ASSIGN(TestMasterProcessDelegate);
};

class TestSlaveProcessDelegate : public embedder::SlaveProcessDelegate {
 public:
  TestSlaveProcessDelegate() {}
  ~TestSlaveProcessDelegate() override {}

 private:
  // |embedder::SlaveProcessDelegate| methods:
  void OnShutdownComplete() override { NOTREACHED(); }

  void OnMasterDisconnect() override { NOTREACHED(); }

  DISALLOW_COPY_AND_ASSIGN(TestSlaveProcessDelegate);
};

TEST(IPCSupportTest, MasterSlave) {
  embedder::SimplePlatformSupport platform_support;
  base::TestIOThread test_io_thread(base::TestIOThread::kAutoStart);
  TestMasterProcessDelegate master_process_delegate;
  // Note: Run master process delegate methods on the I/O thread.
  IPCSupport master_ipc_support(
      &platform_support, embedder::ProcessType::MASTER,
      test_io_thread.task_runner(), &master_process_delegate,
      test_io_thread.task_runner(), embedder::ScopedPlatformHandle());

  ConnectionIdentifier connection_id =
      master_ipc_support.GenerateConnectionIdentifier();

  embedder::PlatformChannelPair channel_pair;
  // Note: |ChannelId|s and |ProcessIdentifier|s are interchangeable.
  ProcessIdentifier slave_id = kInvalidProcessIdentifier;
  base::WaitableEvent event1(true, false);
  scoped_refptr<MessagePipeDispatcher> master_mp =
      master_ipc_support.ConnectToSlave(
          connection_id, nullptr, channel_pair.PassServerHandle(),
          base::Bind(&base::WaitableEvent::Signal, base::Unretained(&event1)),
          nullptr, &slave_id);
  ASSERT_TRUE(master_mp);
  EXPECT_NE(slave_id, kInvalidProcessIdentifier);
  EXPECT_NE(slave_id, kMasterProcessIdentifier);
  // Note: We don't have to wait on |event1| now, but we'll have to do so before
  // tearing down the channel.

  TestSlaveProcessDelegate slave_process_delegate;
  // Note: Run process delegate methods on the I/O thread.
  IPCSupport slave_ipc_support(
      &platform_support, embedder::ProcessType::SLAVE,
      test_io_thread.task_runner(), &slave_process_delegate,
      test_io_thread.task_runner(), channel_pair.PassClientHandle());

  ProcessIdentifier master_id = kInvalidProcessIdentifier;
  base::WaitableEvent event2(true, false);
  scoped_refptr<MessagePipeDispatcher> slave_mp =
      slave_ipc_support.ConnectToMaster(
          connection_id,
          base::Bind(&base::WaitableEvent::Signal, base::Unretained(&event2)),
          nullptr, &master_id);
  ASSERT_TRUE(slave_mp);
  EXPECT_EQ(kMasterProcessIdentifier, master_id);

  // Set up waiting on the slave end first (to avoid racing).
  Waiter waiter;
  waiter.Init();
  ASSERT_EQ(
      MOJO_RESULT_OK,
      slave_mp->AddAwakable(&waiter, MOJO_HANDLE_SIGNAL_READABLE, 0, nullptr));

  // Write a message with just 'x' through the master's end.
  EXPECT_EQ(MOJO_RESULT_OK,
            master_mp->WriteMessage(UserPointer<const void>("x"), 1, nullptr,
                                    MOJO_WRITE_MESSAGE_FLAG_NONE));

  // Wait for it to arrive.
  EXPECT_EQ(MOJO_RESULT_OK, waiter.Wait(test::ActionDeadline(), nullptr));
  slave_mp->RemoveAwakable(&waiter, nullptr);

  // Read the message from the slave's end.
  char buffer[10] = {};
  uint32_t buffer_size = static_cast<uint32_t>(sizeof(buffer));
  EXPECT_EQ(MOJO_RESULT_OK,
            slave_mp->ReadMessage(UserPointer<void>(buffer),
                                  MakeUserPointer(&buffer_size), 0, nullptr,
                                  MOJO_READ_MESSAGE_FLAG_NONE));
  EXPECT_EQ(1u, buffer_size);
  EXPECT_EQ('x', buffer[0]);

  // Don't need the message pipe anymore.
  master_mp->Close();
  slave_mp->Close();

  // A message was sent through the message pipe, |Channel|s must have been
  // established on both sides. The events have thus almost certainly been
  // signalled, but we'll wait just to be sure.
  EXPECT_TRUE(event1.TimedWait(TestTimeouts::action_timeout()));
  EXPECT_TRUE(event2.TimedWait(TestTimeouts::action_timeout()));

  test_io_thread.PostTaskAndWait(
      FROM_HERE,
      base::Bind(&ChannelManager::ShutdownChannelOnIOThread,
                 base::Unretained(slave_ipc_support.channel_manager()),
                 master_id));
  test_io_thread.PostTaskAndWait(
      FROM_HERE, base::Bind(&IPCSupport::ShutdownOnIOThread,
                            base::Unretained(&slave_ipc_support)));

  EXPECT_TRUE(master_process_delegate.TryWaitForOnSlaveDisconnect());

  test_io_thread.PostTaskAndWait(
      FROM_HERE,
      base::Bind(&ChannelManager::ShutdownChannelOnIOThread,
                 base::Unretained(master_ipc_support.channel_manager()),
                 slave_id));
  test_io_thread.PostTaskAndWait(
      FROM_HERE, base::Bind(&IPCSupport::ShutdownOnIOThread,
                            base::Unretained(&master_ipc_support)));
}

}  // namespace

// Note: This test isn't in an anonymous namespace, since it needs to be
// friended by |IPCSupport|.
TEST(IPCSupportTest, MasterSlaveInternal) {
  embedder::SimplePlatformSupport platform_support;
  base::TestIOThread test_io_thread(base::TestIOThread::kAutoStart);
  TestMasterProcessDelegate master_process_delegate;
  // Note: Run master process delegate methods on the I/O thread.
  IPCSupport master_ipc_support(
      &platform_support, embedder::ProcessType::MASTER,
      test_io_thread.task_runner(), &master_process_delegate,
      test_io_thread.task_runner(), embedder::ScopedPlatformHandle());

  ConnectionIdentifier connection_id =
      master_ipc_support.GenerateConnectionIdentifier();

  embedder::PlatformChannelPair channel_pair;
  ProcessIdentifier slave_id = kInvalidProcessIdentifier;
  embedder::ScopedPlatformHandle master_second_platform_handle =
      master_ipc_support.ConnectToSlaveInternal(
          connection_id, nullptr, channel_pair.PassServerHandle(), &slave_id);
  ASSERT_TRUE(master_second_platform_handle.is_valid());
  EXPECT_NE(slave_id, kInvalidProcessIdentifier);
  EXPECT_NE(slave_id, kMasterProcessIdentifier);

  TestSlaveProcessDelegate slave_process_delegate;
  // Note: Run process delegate methods on the I/O thread.
  IPCSupport slave_ipc_support(
      &platform_support, embedder::ProcessType::SLAVE,
      test_io_thread.task_runner(), &slave_process_delegate,
      test_io_thread.task_runner(), channel_pair.PassClientHandle());

  embedder::ScopedPlatformHandle slave_second_platform_handle =
      slave_ipc_support.ConnectToMasterInternal(connection_id);
  ASSERT_TRUE(slave_second_platform_handle.is_valid());

  // Write an 'x' through the master's end.
  size_t n = 0;
  EXPECT_TRUE(mojo::test::BlockingWrite(master_second_platform_handle.get(),
                                        "x", 1, &n));
  EXPECT_EQ(1u, n);

  // Read it from the slave's end.
  char c = '\0';
  n = 0;
  EXPECT_TRUE(
      mojo::test::BlockingRead(slave_second_platform_handle.get(), &c, 1, &n));
  EXPECT_EQ(1u, n);
  EXPECT_EQ('x', c);

  test_io_thread.PostTaskAndWait(
      FROM_HERE, base::Bind(&IPCSupport::ShutdownOnIOThread,
                            base::Unretained(&slave_ipc_support)));

  EXPECT_TRUE(master_process_delegate.TryWaitForOnSlaveDisconnect());

  test_io_thread.PostTaskAndWait(
      FROM_HERE, base::Bind(&IPCSupport::ShutdownOnIOThread,
                            base::Unretained(&master_ipc_support)));
}

// This is a true multiprocess version of IPCSupportTest.MasterSlaveInternal.
// Note: This test isn't in an anonymous namespace, since it needs to be
// friended by |IPCSupport|.
#if defined(OS_ANDROID)
// Android multi-process tests are not executing the new process. This is flaky.
// TODO(vtl): I'm guessing this is true of this test too?
#define MAYBE_MultiprocessMasterSlaveInternal \
  DISABLED_MultiprocessMasterSlaveInternal
#else
#define MAYBE_MultiprocessMasterSlaveInternal MultiprocessMasterSlaveInternal
#endif  // defined(OS_ANDROID)
TEST(IPCSupportTest, MAYBE_MultiprocessMasterSlaveInternal) {
  embedder::SimplePlatformSupport platform_support;
  base::TestIOThread test_io_thread(base::TestIOThread::kAutoStart);
  TestMasterProcessDelegate master_process_delegate;
  // Note: Run process delegate methods on the I/O thread.
  IPCSupport ipc_support(&platform_support, embedder::ProcessType::MASTER,
                         test_io_thread.task_runner(), &master_process_delegate,
                         test_io_thread.task_runner(),
                         embedder::ScopedPlatformHandle());

  ConnectionIdentifier connection_id =
      ipc_support.GenerateConnectionIdentifier();
  mojo::test::MultiprocessTestHelper multiprocess_test_helper;
  ProcessIdentifier slave_id = kInvalidProcessIdentifier;
  embedder::ScopedPlatformHandle second_platform_handle =
      ipc_support.ConnectToSlaveInternal(
          connection_id, nullptr,
          multiprocess_test_helper.server_platform_handle.Pass(), &slave_id);
  ASSERT_TRUE(second_platform_handle.is_valid());
  EXPECT_NE(slave_id, kInvalidProcessIdentifier);
  EXPECT_NE(slave_id, kMasterProcessIdentifier);

  multiprocess_test_helper.StartChildWithExtraSwitch(
      "MultiprocessMasterSlaveInternal", kConnectionIdFlag,
      connection_id.ToString());

  // We write a '?'. The slave should write a '!' in response.
  size_t n = 0;
  EXPECT_TRUE(
      mojo::test::BlockingWrite(second_platform_handle.get(), "?", 1, &n));
  EXPECT_EQ(1u, n);

  char c = '\0';
  n = 0;
  EXPECT_TRUE(
      mojo::test::BlockingRead(second_platform_handle.get(), &c, 1, &n));
  EXPECT_EQ(1u, n);
  EXPECT_EQ('!', c);

  EXPECT_TRUE(master_process_delegate.TryWaitForOnSlaveDisconnect());
  EXPECT_TRUE(multiprocess_test_helper.WaitForChildTestShutdown());

  test_io_thread.PostTaskAndWait(FROM_HERE,
                                 base::Bind(&IPCSupport::ShutdownOnIOThread,
                                            base::Unretained(&ipc_support)));
}

MOJO_MULTIPROCESS_TEST_CHILD_TEST(MultiprocessMasterSlaveInternal) {
  embedder::ScopedPlatformHandle client_platform_handle =
      mojo::test::MultiprocessTestHelper::client_platform_handle.Pass();
  ASSERT_TRUE(client_platform_handle.is_valid());

  embedder::SimplePlatformSupport platform_support;
  base::TestIOThread test_io_thread(base::TestIOThread::kAutoStart);
  TestSlaveProcessDelegate slave_process_delegate;
  // Note: Run process delegate methods on the I/O thread.
  IPCSupport ipc_support(&platform_support, embedder::ProcessType::SLAVE,
                         test_io_thread.task_runner(), &slave_process_delegate,
                         test_io_thread.task_runner(),
                         client_platform_handle.Pass());

  const base::CommandLine& command_line =
      *base::CommandLine::ForCurrentProcess();
  ASSERT_TRUE(command_line.HasSwitch(kConnectionIdFlag));
  bool ok = false;
  ConnectionIdentifier connection_id = ConnectionIdentifier::FromString(
      command_line.GetSwitchValueASCII(kConnectionIdFlag), &ok);
  ASSERT_TRUE(ok);

  embedder::ScopedPlatformHandle second_platform_handle =
      ipc_support.ConnectToMasterInternal(connection_id);
  ASSERT_TRUE(second_platform_handle.is_valid());

  // The master should write a '?'. We'll write a '!' in response.
  char c = '\0';
  size_t n = 0;
  EXPECT_TRUE(
      mojo::test::BlockingRead(second_platform_handle.get(), &c, 1, &n));
  EXPECT_EQ(1u, n);
  EXPECT_EQ('?', c);

  n = 0;
  EXPECT_TRUE(
      mojo::test::BlockingWrite(second_platform_handle.get(), "!", 1, &n));
  EXPECT_EQ(1u, n);

  test_io_thread.PostTaskAndWait(FROM_HERE,
                                 base::Bind(&IPCSupport::ShutdownOnIOThread,
                                            base::Unretained(&ipc_support)));
}

// TODO(vtl): Also test the case of the master "dying" before the slave. (The
// slave should get OnMasterDisconnect(), which we currently don't test.)

}  // namespace system
}  // namespace mojo
<|endoftext|>


<commit_before>#include <vector>
#include <GL/glew.h>
#include <GL/gl.h>

#define GLM_FORCE_RADIANS
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <SDL2/SDL.h>
#include <SDL2/SDL_opengl.h>
#include <SDL2/SDL_image.h>
#include <stdlib.h>
#include <stdio.h>

#include "../utils/base_eng/base_eng.hpp"
#include "../shader_compiler/shader_compiler.hpp"
#include "../utils/utils.hpp"
#include "../InputProcessor/gen_input_processor.hpp"
#include "boaler.hpp"

enum { WIN_W = 800, WIN_H = 600, FPS = 100 };

enum game_states { TEST_STATE1, TEST_STATE2, TEST_STATE3 };

int main()
{
    SDL_Event event;
    BaseEng engine(WIN_W, WIN_H, "Hooke Cloth", FPS);
    bool carry_on = true;

    GLuint shader_program = compile_shader(
        "resources/basic_shading.vertexshader",
        "resources/basic_shading.fragmentshader");
    BoalerShaderUnit shader_unit(shader_program);

    GLuint texture_id = load_texture("resources/test_texture.png");

    glm::mat4 V = glm::lookAt(
        glm::vec3(0.0, 0.0, 4.0),
        glm::vec3(0.0, 0.0, -1.0),
        glm::vec3(0.0, 1.0, 0.0));

    glm::mat4 P = glm::perspective(44.9f, 4.0f / 3.0f, 0.1f, 100.0f);
    BoalerViewUnit view_unit(V, P);

    BoalerModel model("triangle.bin");
    BoalerModelUnit model_unit(glm::mat4(), 0, texture_id, model);

    BoalerVSLink vs_link(view_unit, shader_unit);
    BoalerVSLModelUnitLink vslm_link(vs_link, model_unit);

    BoalerEng beng;
    beng.reg_view_unit(&view_unit);
    beng.reg_shader_unit(&shader_unit);
    beng.reg_model(&model);
    beng.reg_model_unit(&model_unit);

    GenInputProcessor<game_states> input_processor;
    input_processor.add_key_binding(SDLK_DOWN, TEST_STATE1);

    while(carry_on) {
        beng.render();
        SDL_GL_SwapWindow(engine.window);

        if (input_processor.is_state_active(TEST_STATE1)) {
            fprintf(stderr, "state 1 active");
        }

        while (SDL_PollEvent(&event)) {
            if (event.type == SDL_QUIT) {
                carry_on = false;
            }
            input_processor.process_input(&event);
        }
    }
}
<commit_msg>finished gen_input_processor<commit_after>#include <vector>
#include <GL/glew.h>
#include <GL/gl.h>

#define GLM_FORCE_RADIANS
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <SDL2/SDL.h>
#include <SDL2/SDL_opengl.h>
#include <SDL2/SDL_image.h>
#include <stdlib.h>
#include <stdio.h>

#include "../utils/base_eng/base_eng.hpp"
#include "../shader_compiler/shader_compiler.hpp"
#include "../utils/utils.hpp"
#include "../InputProcessor/gen_input_processor.hpp"
#include "boaler.hpp"

enum { WIN_W = 800, WIN_H = 600, FPS = 100 };

enum game_states { TEST_STATE1, TEST_STATE2, TEST_STATE3 };

int main()
{
    SDL_Event event;
    BaseEng engine(WIN_W, WIN_H, "Hooke Cloth", FPS);
    bool carry_on = true;

    GLuint shader_program = compile_shader(
        "resources/basic_shading.vertexshader",
        "resources/basic_shading.fragmentshader");
    BoalerShaderUnit shader_unit(shader_program);

    GLuint texture_id = load_texture("resources/test_texture.png");

    glm::mat4 V = glm::lookAt(
        glm::vec3(0.0, 0.0, 4.0),
        glm::vec3(0.0, 0.0, -1.0),
        glm::vec3(0.0, 1.0, 0.0));

    glm::mat4 P = glm::perspective(44.9f, 4.0f / 3.0f, 0.1f, 100.0f);
    BoalerViewUnit view_unit(V, P);

    BoalerModel model("triangle.bin");
    BoalerModelUnit model_unit(glm::mat4(), 0, texture_id, model);

    BoalerVSLink vs_link(view_unit, shader_unit);
    BoalerVSLModelUnitLink vslm_link(vs_link, model_unit);

    BoalerEng beng;
    beng.reg_view_unit(&view_unit);
    beng.reg_shader_unit(&shader_unit);
    beng.reg_model(&model);
    beng.reg_model_unit(&model_unit);

    GenInputProcessor<game_states> input_processor;
    input_processor.add_key_binding(SDLK_DOWN, TEST_STATE1);

    while(carry_on) {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        beng.render();
        SDL_GL_SwapWindow(engine.window);

        if (input_processor.is_state_active(TEST_STATE1)) {
            fprintf(stderr, "state 1 active");
        }

        while (SDL_PollEvent(&event)) {
            if (event.type == SDL_QUIT) {
                carry_on = false;
            }
            input_processor.process_input(&event);
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>WaE: null argument where non-null required (argument 2)<commit_after><|endoftext|>


<commit_before>/*
* Copyright 2010-2011 Research In Motion Limited.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include "stdafx.h"
#include "QtStageWebView.h"
#include "ScrollHandler.h"
#include <QMenu>
#include <QAction>
#include <QMessageBox>
#include "RemoteDebugger.h"
#include "PortScanner.h"

using namespace BlackBerry::Starbuck;

QtStageWebView::QtStageWebView(QWidget *p) : waitForJsLoad(false)
{
    //Turn off context menu's (i.e. menu when right clicking, you will need to uncommment this if you want to use web inspector,
    //there is currently a conflict between the context menus when using two QWebView's
    //this->setContextMenuPolicy(Qt::NoContextMenu);

	// Connect signals for events
	connect(this, SIGNAL(urlChanged(const QUrl&)), this, SLOT(notifyUrlChanged(const QUrl&)));

	if (page() && page()->mainFrame())
    {
        connect(page()->mainFrame(), SIGNAL(javaScriptWindowObjectCleared()), this, SLOT(notifyJavaScriptWindowObjectCleared()));
    }

	//Initialize headers to 0
	_headersSize = 0;

	//enable web inspector
	this->settings()->setAttribute(QWebSettings::DeveloperExtrasEnabled, true);

    m_pScrollHandler = new ScrollHandler(this);
    m_inspector = new QWebInspector();
    m_inspectorProcess = new QProcess();

    //init the remote inspector and set the port
    m_remoteInspectorPort = PortScanner::findUsablePort(9292);
    page()->setProperty("_q_webInspectorServerPort", m_remoteInspectorPort);

    //install scroll handler
    this->installEventFilter(m_pScrollHandler);
}

QtStageWebView::~QtStageWebView(void)
{
    if (m_pScrollHandler != 0)
        delete m_pScrollHandler;

    if (m_inspector != 0)
        delete m_inspector;

    if (m_inspectorProcess != 0)
        delete m_inspectorProcess;
}

void QtStageWebView::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
{
    QMenu menu;
    QAction *inspectAction = menu.addAction("Inspect");
    QAction *selectedAction = menu.exec(event->screenPos());
    if (inspectAction == selectedAction) {
        m_inspector->setPage(page());
        QString quotation = "\"";
        QString cmd = QString(quotation + QApplication::applicationFilePath() + quotation + QString(" -inspect 9292"));
        m_inspectorProcess->start(cmd);
    }
}

void QtStageWebView::loadURL(QString url)
{
	QNetworkRequest request(url);

	//Add custom headers
	for (unsigned int i = 0; i + 1 < _headersSize; i += 2)
		request.setRawHeader(_headers[i], _headers[i + 1]);

	load(request);
}

void QtStageWebView::reload()
{
	QGraphicsWebView::reload();
}

void QtStageWebView::notifyUrlChanged(const QUrl& url)
{
	emit urlChanged(url.toString());
    m_inspector->setPage(page());
}

void QtStageWebView::notifyJavaScriptWindowObjectCleared()
{
//  registerEventbus();
  QEventLoop loop;
  QObject::connect(this, SIGNAL(jsLoaded()), &loop, SLOT(quit()));
    emit javaScriptWindowObjectCleared();

  if (waitForJsLoad)
      loop.exec();
}

#if 0
void QtStageWebView::registerEventbus()
{
    QWebFrame* frame = page()->mainFrame();
    frame->addToJavaScriptWindowObject(QString("eventbus2"), new BlackBerryBus(this, frame));
    frame->evaluateJavaScript(BlackBerry::Starbuck::eventbusSource);

    // check for iframes, if found add to window object
    for(int i = 0; i < frame->childFrames().length(); i++)
    {
        frame->childFrames()[i]->addToJavaScriptWindowObject(QString("eventbus2"), new BlackBerryBus(this, frame->childFrames()[i]));
        frame->childFrames()[i]->evaluateJavaScript(BlackBerry::Starbuck::eventbusSource);
  }
}
#endif

void QtStageWebView::continueLoad()
{
    emit jsLoaded();
    waitForJsLoad = false;
}

bool QtStageWebView::enableCrossSiteXHR()
{
	return this->settings()->testAttribute(QWebSettings::LocalContentCanAccessRemoteUrls);
}

void QtStageWebView::enableCrossSiteXHR(bool xhr)
{
    return this->settings()->setAttribute(QWebSettings::LocalContentCanAccessRemoteUrls, xhr);
}

QVariant QtStageWebView::executeJavaScript(QString script)
{
	return page()->mainFrame()->evaluateJavaScript(script);
}

QString QtStageWebView::location()
{
	return url().toString();
}

bool QtStageWebView::isHistoryBackEnabled()
{
	return history() ? history()->canGoBack() : false;
}

bool QtStageWebView::isHistoryForwardEnabled()
{
	return history() ? history()->canGoForward() : false;
}

void QtStageWebView::historyBack()
{
	back();
}

void QtStageWebView::historyForward()
{
	forward();
}

int QtStageWebView::historyLength()
{
	return history() ? history()->count() : 0;
}

int QtStageWebView::historyPosition()
{
	return history() ? history()->currentItemIndex() : -1;
}

void QtStageWebView::historyPosition(int position)
{
	if (history() && position >= 0 && position < history()->count())
	{
		history()->goToItem(history()->itemAt(position));
	}
}

char** QtStageWebView::customHTTPHeaders()
{
	return _headers;
}

void QtStageWebView::customHTTPHeaders(char *headers[], unsigned int headersSize)
{
	_headers = new char*[headersSize];

	for (unsigned int i = 0; i < headersSize; i++)
    {
        _headers[i] = new char[strlen(headers[i]) + 1];
		strcpy(_headers[i], headers[i]);
	}

	_headersSize = headersSize;
}

void QtStageWebView::customHTTPHeaders(QString key, QString value)
{
	QByteArray mKey = key.toAscii();
	QByteArray mValue = value.toAscii();

	char *headersArray[2];
	headersArray[0] = mKey.data();
	headersArray[1] = mValue.data();

	customHTTPHeaders( headersArray, 2);
}

void QtStageWebView::visible(bool enable)
{
	if (this->isVisible() == enable)
		return;

	(enable) ? this->show():this->hide();
}

void QtStageWebView::setZoom(float zoom) {
  this->setZoomFactor(zoom);
}

float QtStageWebView::zoom() {
  return this->zoomFactor();
}
<commit_msg>Changed Windows version to use local web inspector.<commit_after>/*
* Copyright 2010-2011 Research In Motion Limited.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include "stdafx.h"
#include "QtStageWebView.h"
#include "ScrollHandler.h"
#include <QMenu>
#include <QAction>
#include <QMessageBox>
#include "RemoteDebugger.h"
#include "PortScanner.h"

using namespace BlackBerry::Starbuck;

QtStageWebView::QtStageWebView(QWidget *p) : waitForJsLoad(false),_headersSize(0), m_inspector(0), m_inspectorProcess(0)
{
	// Connect signals for events
	connect(this, SIGNAL(urlChanged(const QUrl&)), this, SLOT(notifyUrlChanged(const QUrl&)));

	if (page() && page()->mainFrame())
    {
        connect(page()->mainFrame(), SIGNAL(javaScriptWindowObjectCleared()), this, SLOT(notifyJavaScriptWindowObjectCleared()));
    }

	//enable web inspector
	this->settings()->setAttribute(QWebSettings::DeveloperExtrasEnabled, true);

    m_pScrollHandler = new ScrollHandler(this);

#ifndef Q_WS_WIN
    m_inspector = new QWebInspector();
    m_inspectorProcess = new QProcess();

    //init the remote inspector and set the port
    m_remoteInspectorPort = PortScanner::findUsablePort(9292);
    page()->setProperty("_q_webInspectorServerPort", m_remoteInspectorPort);
#endif
    //install scroll handler
    this->installEventFilter(m_pScrollHandler);
}

QtStageWebView::~QtStageWebView(void)
{
    if (m_pScrollHandler != 0)
        delete m_pScrollHandler;

    if (m_inspector != 0)
        delete m_inspector;

    if (m_inspectorProcess != 0)
        delete m_inspectorProcess;
}

void QtStageWebView::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
{
  QMenu menu;
  QAction *inspectAction = menu.addAction("Inspect");
  QAction *selectedAction = menu.exec(event->screenPos());
  if (inspectAction == selectedAction) {
    #ifdef Q_WS_WIN
      this->page()->triggerAction(QWebPage::InspectElement);
    #else
      m_inspector->setPage(page());
      QString quotation = "\"";
      QString cmd = QString(quotation + QApplication::applicationFilePath() + quotation + QString(" -inspect 9292"));
      m_inspectorProcess->start(cmd);
    #endif
  }

}

void QtStageWebView::loadURL(QString url)
{
	QNetworkRequest request(url);

	//Add custom headers
	for (unsigned int i = 0; i + 1 < _headersSize; i += 2)
		request.setRawHeader(_headers[i], _headers[i + 1]);

	load(request);
}

void QtStageWebView::reload()
{
	QGraphicsWebView::reload();
}

void QtStageWebView::notifyUrlChanged(const QUrl& url)
{
	emit urlChanged(url.toString());
  if(m_inspector)
    m_inspector->setPage(page());
}

void QtStageWebView::notifyJavaScriptWindowObjectCleared()
{
//  registerEventbus();
  QEventLoop loop;
  QObject::connect(this, SIGNAL(jsLoaded()), &loop, SLOT(quit()));
    emit javaScriptWindowObjectCleared();

  if (waitForJsLoad)
      loop.exec();
}

#if 0
void QtStageWebView::registerEventbus()
{
    QWebFrame* frame = page()->mainFrame();
    frame->addToJavaScriptWindowObject(QString("eventbus2"), new BlackBerryBus(this, frame));
    frame->evaluateJavaScript(BlackBerry::Starbuck::eventbusSource);

    // check for iframes, if found add to window object
    for(int i = 0; i < frame->childFrames().length(); i++)
    {
        frame->childFrames()[i]->addToJavaScriptWindowObject(QString("eventbus2"), new BlackBerryBus(this, frame->childFrames()[i]));
        frame->childFrames()[i]->evaluateJavaScript(BlackBerry::Starbuck::eventbusSource);
  }
}
#endif

void QtStageWebView::continueLoad()
{
    emit jsLoaded();
    waitForJsLoad = false;
}

bool QtStageWebView::enableCrossSiteXHR()
{
	return this->settings()->testAttribute(QWebSettings::LocalContentCanAccessRemoteUrls);
}

void QtStageWebView::enableCrossSiteXHR(bool xhr)
{
    return this->settings()->setAttribute(QWebSettings::LocalContentCanAccessRemoteUrls, xhr);
}

QVariant QtStageWebView::executeJavaScript(QString script)
{
	return page()->mainFrame()->evaluateJavaScript(script);
}

QString QtStageWebView::location()
{
	return url().toString();
}

bool QtStageWebView::isHistoryBackEnabled()
{
	return history() ? history()->canGoBack() : false;
}

bool QtStageWebView::isHistoryForwardEnabled()
{
	return history() ? history()->canGoForward() : false;
}

void QtStageWebView::historyBack()
{
	back();
}

void QtStageWebView::historyForward()
{
	forward();
}

int QtStageWebView::historyLength()
{
	return history() ? history()->count() : 0;
}

int QtStageWebView::historyPosition()
{
	return history() ? history()->currentItemIndex() : -1;
}

void QtStageWebView::historyPosition(int position)
{
	if (history() && position >= 0 && position < history()->count())
	{
		history()->goToItem(history()->itemAt(position));
	}
}

char** QtStageWebView::customHTTPHeaders()
{
	return _headers;
}

void QtStageWebView::customHTTPHeaders(char *headers[], unsigned int headersSize)
{
	_headers = new char*[headersSize];

	for (unsigned int i = 0; i < headersSize; i++)
    {
        _headers[i] = new char[strlen(headers[i]) + 1];
		strcpy(_headers[i], headers[i]);
	}

	_headersSize = headersSize;
}

void QtStageWebView::customHTTPHeaders(QString key, QString value)
{
	QByteArray mKey = key.toAscii();
	QByteArray mValue = value.toAscii();

	char *headersArray[2];
	headersArray[0] = mKey.data();
	headersArray[1] = mValue.data();

	customHTTPHeaders( headersArray, 2);
}

void QtStageWebView::visible(bool enable)
{
	if (this->isVisible() == enable)
		return;

	(enable) ? this->show():this->hide();
}

void QtStageWebView::setZoom(float zoom) {
  this->setZoomFactor(zoom);
}

float QtStageWebView::zoom() {
  return this->zoomFactor();
}
<|endoftext|>