<commit_before>
/// *********************************************************************************
/// *********************************************************************************
///                     EMSCRIPTEN (for javascript)
/// *********************************************************************************
/// *********************************************************************************

#ifdef EMSCRIPTEN

#include "CoolProp.h"
#include "AbstractState.h"
#include "Configuration.h"
#include "HumidAirProp.h"
#include "DataStructures.h"
#include "Backends/Helmholtz/MixtureParameters.h"

#include <emscripten/bind.h>
using namespace emscripten;

// Binding code
EMSCRIPTEN_BINDINGS(coolprop_bindings) {
    function("Props1SI", &CoolProp::Props1SI);
    function("PropsSI", &CoolProp::PropsSI);
    function("get_global_param_string", &CoolProp::get_global_param_string);
}

// Binding code
EMSCRIPTEN_BINDINGS(humid_air_bindings) {
    function("HAPropsSI", &HumidAir::HAPropsSI);
}

CoolProp::AbstractState * factory(const std::string &backend, const std::string &fluid_names)
{
    return CoolProp::AbstractState::factory(backend, strsplit(fluid_names, '&'));
}

// Binding code
EMSCRIPTEN_BINDINGS(abstract_state_bindings) {

    register_vector<double>("VectorDouble");
    register_vector<std::string>("VectorString");

    value_object<CoolProp::PhaseEnvelopeData>("CoolProp::PhaseEnvelopeData")
        // Use X macros to auto-generate the variables;
        // each will look something like: .field("T", &CoolProp::PhaseEnvelopeData::T);
        #define X(name) .field(#name, &CoolProp::PhaseEnvelopeData::name)
            PHASE_ENVELOPE_VECTORS
        #undef X
        ;

    function("factory", &factory, allow_raw_pointers());

    class_<CoolProp::AbstractState>("AbstractState")
        .function("gas_constant", &CoolProp::AbstractState::gas_constant)
        .function("update", &CoolProp::AbstractState::update)
        .function("set_mole_fractions", &CoolProp::AbstractState::set_mole_fractions_double)
        .function("build_phase_envelope", &CoolProp::AbstractState::build_phase_envelope)
        .function("get_phase_envelope_data", &CoolProp::AbstractState::get_phase_envelope_data);

}

#endif<commit_msg>Added a few things to the emscripten interface<commit_after>
/// *********************************************************************************
/// *********************************************************************************
///                     EMSCRIPTEN (for javascript)
/// *********************************************************************************
/// *********************************************************************************

#ifdef EMSCRIPTEN

#include "CoolProp.h"
#include "AbstractState.h"
#include "Configuration.h"
#include "HumidAirProp.h"
#include "DataStructures.h"
#include "Backends/Helmholtz/MixtureParameters.h"

#include <emscripten/bind.h>
using namespace emscripten;

// Binding code
EMSCRIPTEN_BINDINGS(coolprop_bindings) {
    function("Props1SI", &CoolProp::Props1SI);
    function("PropsSI", &CoolProp::PropsSI);
    function("get_global_param_string", &CoolProp::get_global_param_string);

    enum_<CoolProp::input_pairs>("input_pairs")
        .value("PT_INPUTS", CoolProp::PT_INPUTS)
        ;
}
// Binding code
EMSCRIPTEN_BINDINGS(humid_air_bindings) {
    function("HAPropsSI", &HumidAir::HAPropsSI);
}

CoolProp::AbstractState * factory(const std::string &backend, const std::string &fluid_names)
{
    return CoolProp::AbstractState::factory(backend, strsplit(fluid_names, '&'));
}

// Binding code
EMSCRIPTEN_BINDINGS(abstract_state_bindings) {

    register_vector<double>("VectorDouble");
    register_vector<std::string>("VectorString");

    value_object<CoolProp::PhaseEnvelopeData>("CoolProp::PhaseEnvelopeData")
        // Use X macros to auto-generate the variables;
        // each will look something like: .field("T", &CoolProp::PhaseEnvelopeData::T);
        #define X(name) .field(#name, &CoolProp::PhaseEnvelopeData::name)
            PHASE_ENVELOPE_VECTORS
        #undef X
        ;

    function("factory", &factory, allow_raw_pointers());

    class_<CoolProp::AbstractState>("AbstractState")
        .function("gas_constant", &CoolProp::AbstractState::gas_constant)
        .function("update", &CoolProp::AbstractState::update)
        .function("p", &CoolProp::AbstractState::p)
        .function("rhomass", &CoolProp::AbstractState::rhomass)
        .function("viscosity", &CoolProp::AbstractState::viscosity)
        .function("set_mole_fractions", &CoolProp::AbstractState::set_mole_fractions_double)
        .function("build_phase_envelope", &CoolProp::AbstractState::build_phase_envelope)
        .function("get_phase_envelope_data", &CoolProp::AbstractState::get_phase_envelope_data);

}

#endif<|endoftext|>


<commit_before>
/// *********************************************************************************
/// *********************************************************************************
///                     EMSCRIPTEN (for javascript)
/// *********************************************************************************
/// *********************************************************************************

#ifdef EMSCRIPTEN

#include "CoolProp.h"
#include "AbstractState.h"
#include "Configuration.h"
#include "HumidAirProp.h"
#include "DataStructures.h"
#include "Backends/Helmholtz/MixtureParameters.h"

#include <emscripten/bind.h>
using namespace emscripten;

/// *********************************************************************************
/// *********************************************************************************
///                     EMSCRIPTEN (for javascript)
/// *********************************************************************************
/// *********************************************************************************

#ifdef EMSCRIPTEN

#include <emscripten/bind.h>
using namespace emscripten;

// Binding code
EMSCRIPTEN_BINDINGS(coolprop_bindings) {
    function("F2K", &F2K);
    function("Props1SI", &CoolProp::Props1SI);
    function("PropsSI", &CoolProp::PropsSI);
    function("get_global_param_string", &CoolProp::get_global_param_string);

    enum_<CoolProp::input_pairs>("input_pairs")
        .value("PT_INPUTS", CoolProp::PT_INPUTS)
        ;
}
// Binding code
EMSCRIPTEN_BINDINGS(humid_air_bindings) {
    function("HAPropsSI", &HumidAir::HAPropsSI);
}

CoolProp::AbstractState * factory(const std::string &backend, const std::string &fluid_names)
{
    return CoolProp::AbstractState::factory(backend, strsplit(fluid_names, '&'));
}

// Binding code
EMSCRIPTEN_BINDINGS(abstract_state_bindings) {

    register_vector<double>("VectorDouble");
    register_vector<std::string>("VectorString");

    value_object<CoolProp::PhaseEnvelopeData>("CoolProp::PhaseEnvelopeData")
        // Use X macros to auto-generate the variables;
        // each will look something like: .field("T", &CoolProp::PhaseEnvelopeData::T);
        #define X(name) .field(#name, &CoolProp::PhaseEnvelopeData::name)
            PHASE_ENVELOPE_VECTORS
        #undef X
        ;

    function("factory", &factory, allow_raw_pointers());

    class_<CoolProp::AbstractState>("AbstractState")
        .function("gas_constant", &CoolProp::AbstractState::gas_constant)
        .function("update", &CoolProp::AbstractState::update)
        .function("p", &CoolProp::AbstractState::p)
        .function("rhomass", &CoolProp::AbstractState::rhomass)
        .function("viscosity", &CoolProp::AbstractState::viscosity)
        .function("set_mole_fractions", &CoolProp::AbstractState::set_mole_fractions_double)
        .function("build_phase_envelope", &CoolProp::AbstractState::build_phase_envelope)
        .function("get_phase_envelope_data", &CoolProp::AbstractState::get_phase_envelope_data);

}

#endif<commit_msg>Another attempt at emscripten relocation; see #1449<commit_after>
/// *********************************************************************************
/// *********************************************************************************
///                     EMSCRIPTEN (for javascript)
/// *********************************************************************************
/// *********************************************************************************

#ifdef EMSCRIPTEN

#include "CoolProp.h"
#include "AbstractState.h"
#include "Configuration.h"
#include "HumidAirProp.h"
#include "DataStructures.h"
#include "Backends/Helmholtz/MixtureParameters.h"
#include "CoolPropLib.h"

/// *********************************************************************************
/// *********************************************************************************
///                     EMSCRIPTEN (for javascript)
/// *********************************************************************************
/// *********************************************************************************

#include <emscripten/bind.h>
using namespace emscripten;

// Binding code
EMSCRIPTEN_BINDINGS(coolprop_bindings) {
    function("F2K", &CoolProp::F2K);
    function("Props1SI", &CoolProp::Props1SI);
    function("PropsSI", &CoolProp::PropsSI);
    function("get_global_param_string", &CoolProp::get_global_param_string);

    enum_<CoolProp::input_pairs>("input_pairs")
        .value("PT_INPUTS", CoolProp::PT_INPUTS)
        ;
}
// Binding code
EMSCRIPTEN_BINDINGS(humid_air_bindings) {
    function("HAPropsSI", &HumidAir::HAPropsSI);
}

CoolProp::AbstractState * factory(const std::string &backend, const std::string &fluid_names)
{
    return CoolProp::AbstractState::factory(backend, strsplit(fluid_names, '&'));
}

// Binding code
EMSCRIPTEN_BINDINGS(abstract_state_bindings) {

    register_vector<double>("VectorDouble");
    register_vector<std::string>("VectorString");

    value_object<CoolProp::PhaseEnvelopeData>("CoolProp::PhaseEnvelopeData")
        // Use X macros to auto-generate the variables;
        // each will look something like: .field("T", &CoolProp::PhaseEnvelopeData::T);
        #define X(name) .field(#name, &CoolProp::PhaseEnvelopeData::name)
            PHASE_ENVELOPE_VECTORS
        #undef X
        ;

    function("factory", &factory, allow_raw_pointers());

    class_<CoolProp::AbstractState>("AbstractState")
        .function("gas_constant", &CoolProp::AbstractState::gas_constant)
        .function("update", &CoolProp::AbstractState::update)
        .function("p", &CoolProp::AbstractState::p)
        .function("rhomass", &CoolProp::AbstractState::rhomass)
        .function("viscosity", &CoolProp::AbstractState::viscosity)
        .function("set_mole_fractions", &CoolProp::AbstractState::set_mole_fractions_double)
        .function("build_phase_envelope", &CoolProp::AbstractState::build_phase_envelope)
        .function("get_phase_envelope_data", &CoolProp::AbstractState::get_phase_envelope_data);

}

#endif<|endoftext|>


<commit_before>/*
===========================================================================

daemon gpl source code
copyright (c) 2013 unvanquished developers

this file is part of the daemon gpl source code (daemon source code).

daemon source code is free software: you can redistribute it and/or modify
it under the terms of the gnu general public license as published by
the free software foundation, either version 3 of the license, or
(at your option) any later version.

daemon source code is distributed in the hope that it will be useful,
but without any warranty; without even the implied warranty of
merchantability or fitness for a particular purpose.  see the
gnu general public license for more details.

you should have received a copy of the gnu general public license
along with daemon source code.  if not, see <http://www.gnu.org/licenses/>.

===========================================================================
*/

#include "AudioPrivate.h"

namespace Audio {

    // Structures to keep the state of entities we were given
    struct entityData_t {
        vec3_t position;
        vec3_t velocity;
        float occlusion;
    };
    static entityData_t entities[MAX_GENTITIES];
    static int listenerEntity = -1;

    // Keep Entitymitters in an array because there is at most one per entity.
    static std::shared_ptr<Emitter> entityEmitters[MAX_GENTITIES];

    // Position Emitters can be reused so we keep the list of all of them
    // this is not very efficient but we cannot have more position emitters
    // than sounds, that is about 128
    static std::vector<std::shared_ptr<PositionEmitter>> posEmitters;

    // There is a single LocalEmitter
    static std::shared_ptr<Emitter> localEmitter;

    static const vec3_t origin = {0.0f, 0.0f, 0.0f};

    static Cvar::Modified<Cvar::Cvar<bool>> useReverb("sound.reverb", "should reverb effects be used", Cvar::ARCHIVE, true);
    //TODO use optional once we have it
    static bool removeReverb = false;
    static bool addReverb = false;

    static AL::EffectSlot* globalEffect = nullptr;

    static bool initialized = false;

    void InitEmitters() {
        if (initialized) {
            return;
        }

        // This is a temporrary effect to test reverb
        AL::Effect effectParams;
        effectParams.ApplyReverbPreset(AL::GetHangarEffectPreset());

        globalEffect = new AL::EffectSlot();
        globalEffect->SetEffect(effectParams);

        AL::SetSpeedOfSound(SPEED_OF_SOUND);
        AL::SetDopplerExaggerationFactor(1); //keep it small else we get a deadlock in OpenAL's mixer

        localEmitter = std::make_shared<LocalEmitter>();

        initialized = true;
    }

    void ShutdownEmitters() {
        if (not initialized) {
            return;
        }

        localEmitter = nullptr;

        for (int i = 0; i < MAX_GENTITIES; i++) {
            if (entityEmitters[i]) {
                entityEmitters[i] = nullptr;
            }
        }

        posEmitters.clear();

        delete globalEffect;
        globalEffect = nullptr;

        initialized = false;
    }

    void UpdateEmitters() {
        localEmitter->Update();

        // Both PositionEmitters and EntityEmitters are ref-counted.
        // If we hold the only reference to them then no sound is still using
        // the Emitter that can be destroyed.
        for (int i = 0; i < MAX_GENTITIES; i++) {
            auto emitter = entityEmitters[i];

            if (not emitter) {
                continue;
            }

            emitter->Update();

            // No sound is using this emitter, destroy it
            if (emitter.unique()) {
                entityEmitters[i] = nullptr;
            }
        }

        for (auto it = posEmitters.begin(); it != posEmitters.end();){
            (*it)->Update();

            // No sound is using this emitter, destroy it
            if ((*it).unique()) {
                it = posEmitters.erase(it);
            } else {
                it ++;
            }
        }

        addReverb = removeReverb = false;
        bool use;
        if (useReverb.GetModifiedValue(use)) {
            if (use) {
                addReverb = true;
            } else {
                removeReverb = true;
            }
        }
    }

    void UpdateListenerEntity(int entityNum, vec3_t orientation[3]) {
        listenerEntity = entityNum;

        AL::SetListenerPosition(entities[listenerEntity].position);
        AL::SetListenerVelocity(entities[listenerEntity].velocity);
        AL::SetListenerOrientation(orientation);
    }

    std::shared_ptr<Emitter> GetEmitterForEntity(int entityNum) {
        if (not entityEmitters[entityNum]) {
            entityEmitters[entityNum] = std::make_shared<EntityEmitter>(entityNum);
        }

        return entityEmitters[entityNum];
    }

    std::shared_ptr<Emitter> GetEmitterForPosition(const vec3_t position) {
        for (auto emitter : posEmitters) {
            if (Distance(emitter->GetPosition(), position) <= 1.0f) {
                return emitter;
            }
        }
        auto emitter = std::make_shared<PositionEmitter>(position);
        posEmitters.push_back(emitter);
        return emitter;
    }

    std::shared_ptr<Emitter> GetLocalEmitter() {
        return localEmitter;
    }

    void UpdateRegisteredEntityPosition(int entityNum, const vec3_t position) {
        VectorCopy(position, entities[entityNum].position);
    }

    void UpdateRegisteredEntityVelocity(int entityNum, const vec3_t velocity) {
        VectorCopy(velocity, entities[entityNum].velocity);
    }

    void UpdateRegisteredEntityOcclusion(int entityNum, float ratio) {
        entities[entityNum].occlusion = ratio;
    }

    // Utility functions for emitters

    // TODO avoid more unnecessary al calls

    void MakeLocal(AL::Source& source) {
        source.SetRelative(true);
        source.SetPosition(origin);
        source.SetVelocity(origin);

        source.DisableEffect(POSITIONAL_EFFECT_SLOT);
    }

    void Make3D(AL::Source& source, const vec3_t position, const vec3_t velocity, bool forceReverb = false) {
        source.SetRelative(false);
        source.SetPosition(position);
        source.SetVelocity(velocity);

        if ((forceReverb and useReverb.Get()) or addReverb) {
            source.EnableEffect(POSITIONAL_EFFECT_SLOT, *globalEffect);
        } else if ((forceReverb and not useReverb.Get()) or removeReverb) {
            source.DisableEffect(POSITIONAL_EFFECT_SLOT);
        }
    }

    // Implementation for Emitter

    Emitter::Emitter() {
    }

    Emitter::~Emitter() {
    }

    void Emitter::SetupSound(Sound& sound) {
        sound.GetSource().SetReferenceDistance(60.0f);
        InternalSetupSound(sound);
        UpdateSound(sound);
    }

    // Implementation of EntityEmitter

    EntityEmitter::EntityEmitter(int entityNum): entityNum(entityNum) {
    }

    EntityEmitter::~EntityEmitter(){
    }

    void EntityEmitter::Update() {
        // TODO
    }

    void EntityEmitter::UpdateSound(Sound& sound) {
        AL::Source& source = sound.GetSource();

        if (entityNum == listenerEntity) {
            MakeLocal(source);
        } else {
            Make3D(source, entities[entityNum].position, entities[entityNum].velocity);
        }
    }

    void EntityEmitter::InternalSetupSound(Sound& sound) {
        AL::Source& source = sound.GetSource();

        Make3D(source, entities[entityNum].position, entities[entityNum].velocity, true);
    }

    // Implementation of PositionEmitter

    PositionEmitter::PositionEmitter(const vec3_t position){
        VectorCopy(position, this->position);
    }

    PositionEmitter::~PositionEmitter() {
    }

    void PositionEmitter::Update() {
        //TODO
    }

    void PositionEmitter::UpdateSound(Sound& sound) {
        AL::Source& source = sound.GetSource();

        Make3D(source, position, origin);
    }

    void PositionEmitter::InternalSetupSound(Sound& sound) {
        AL::Source& source = sound.GetSource();

        Make3D(source, position, origin, true);
    }

    const vec3_t& PositionEmitter::GetPosition() const {
        return position;
    }

    // Implementation of LocalEmitter

    LocalEmitter::LocalEmitter() {
    }

    LocalEmitter::~LocalEmitter() {
    }

    void LocalEmitter::Update() {
    }

    void LocalEmitter::UpdateSound(Sound&) {
    }

    void LocalEmitter::InternalSetupSound(Sound& sound) {
        AL::Source& source = sound.GetSource();

        MakeLocal(source);
    }

}
<commit_msg>Audio: add sound.doppler to enable/disable doppler at runtime<commit_after>/*
===========================================================================

daemon gpl source code
copyright (c) 2013 unvanquished developers

this file is part of the daemon gpl source code (daemon source code).

daemon source code is free software: you can redistribute it and/or modify
it under the terms of the gnu general public license as published by
the free software foundation, either version 3 of the license, or
(at your option) any later version.

daemon source code is distributed in the hope that it will be useful,
but without any warranty; without even the implied warranty of
merchantability or fitness for a particular purpose.  see the
gnu general public license for more details.

you should have received a copy of the gnu general public license
along with daemon source code.  if not, see <http://www.gnu.org/licenses/>.

===========================================================================
*/

#include "AudioPrivate.h"

namespace Audio {

    // Structures to keep the state of entities we were given
    struct entityData_t {
        vec3_t position;
        vec3_t velocity;
        float occlusion;
    };
    static entityData_t entities[MAX_GENTITIES];
    static int listenerEntity = -1;

    // Keep Entitymitters in an array because there is at most one per entity.
    static std::shared_ptr<Emitter> entityEmitters[MAX_GENTITIES];

    // Position Emitters can be reused so we keep the list of all of them
    // this is not very efficient but we cannot have more position emitters
    // than sounds, that is about 128
    static std::vector<std::shared_ptr<PositionEmitter>> posEmitters;

    // There is a single LocalEmitter
    static std::shared_ptr<Emitter> localEmitter;

    static const vec3_t origin = {0.0f, 0.0f, 0.0f};

    static Cvar::Cvar<bool> useDoppler("sound.doppler", "should the doppler effect be used", Cvar::ARCHIVE, true);
    static Cvar::Modified<Cvar::Cvar<bool>> useReverb("sound.reverb", "should reverb effects be used", Cvar::ARCHIVE, true);
    //TODO use optional once we have it
    static bool removeReverb = false;
    static bool addReverb = false;

    static AL::EffectSlot* globalEffect = nullptr;

    static bool initialized = false;

    void UseDoppler(bool use) {
        float factor = use ? 1.0f : 0.0f;
        AL::SetDopplerExaggerationFactor(factor);
    }

    void InitEmitters() {
        if (initialized) {
            return;
        }

        // This is a temporrary effect to test reverb
        AL::Effect effectParams;
        effectParams.ApplyReverbPreset(AL::GetHangarEffectPreset());

        globalEffect = new AL::EffectSlot();
        globalEffect->SetEffect(effectParams);

        AL::SetSpeedOfSound(SPEED_OF_SOUND);
        UseDoppler(useDoppler.Get());

        localEmitter = std::make_shared<LocalEmitter>();

        initialized = true;
    }

    void ShutdownEmitters() {
        if (not initialized) {
            return;
        }

        localEmitter = nullptr;

        for (int i = 0; i < MAX_GENTITIES; i++) {
            if (entityEmitters[i]) {
                entityEmitters[i] = nullptr;
            }
        }

        posEmitters.clear();

        delete globalEffect;
        globalEffect = nullptr;

        initialized = false;
    }

    void UpdateEmitters() {
        localEmitter->Update();

        // Both PositionEmitters and EntityEmitters are ref-counted.
        // If we hold the only reference to them then no sound is still using
        // the Emitter that can be destroyed.
        for (int i = 0; i < MAX_GENTITIES; i++) {
            auto emitter = entityEmitters[i];

            if (not emitter) {
                continue;
            }

            emitter->Update();

            // No sound is using this emitter, destroy it
            if (emitter.unique()) {
                entityEmitters[i] = nullptr;
            }
        }

        for (auto it = posEmitters.begin(); it != posEmitters.end();){
            (*it)->Update();

            // No sound is using this emitter, destroy it
            if ((*it).unique()) {
                it = posEmitters.erase(it);
            } else {
                it ++;
            }
        }

        addReverb = removeReverb = false;
        bool use;
        if (useReverb.GetModifiedValue(use)) {
            if (use) {
                addReverb = true;
            } else {
                removeReverb = true;
            }
        }

        UseDoppler(useDoppler.Get());
    }

    void UpdateListenerEntity(int entityNum, vec3_t orientation[3]) {
        listenerEntity = entityNum;

        AL::SetListenerPosition(entities[listenerEntity].position);
        AL::SetListenerVelocity(entities[listenerEntity].velocity);
        AL::SetListenerOrientation(orientation);
    }

    std::shared_ptr<Emitter> GetEmitterForEntity(int entityNum) {
        if (not entityEmitters[entityNum]) {
            entityEmitters[entityNum] = std::make_shared<EntityEmitter>(entityNum);
        }

        return entityEmitters[entityNum];
    }

    std::shared_ptr<Emitter> GetEmitterForPosition(const vec3_t position) {
        for (auto emitter : posEmitters) {
            if (Distance(emitter->GetPosition(), position) <= 1.0f) {
                return emitter;
            }
        }
        auto emitter = std::make_shared<PositionEmitter>(position);
        posEmitters.push_back(emitter);
        return emitter;
    }

    std::shared_ptr<Emitter> GetLocalEmitter() {
        return localEmitter;
    }

    void UpdateRegisteredEntityPosition(int entityNum, const vec3_t position) {
        VectorCopy(position, entities[entityNum].position);
    }

    void UpdateRegisteredEntityVelocity(int entityNum, const vec3_t velocity) {
        VectorCopy(velocity, entities[entityNum].velocity);
    }

    void UpdateRegisteredEntityOcclusion(int entityNum, float ratio) {
        entities[entityNum].occlusion = ratio;
    }

    // Utility functions for emitters

    // TODO avoid more unnecessary al calls

    void MakeLocal(AL::Source& source) {
        source.SetRelative(true);
        source.SetPosition(origin);
        source.SetVelocity(origin);

        source.DisableEffect(POSITIONAL_EFFECT_SLOT);
    }

    void Make3D(AL::Source& source, const vec3_t position, const vec3_t velocity, bool forceReverb = false) {
        source.SetRelative(false);
        source.SetPosition(position);
        source.SetVelocity(velocity);

        if ((forceReverb and useReverb.Get()) or addReverb) {
            source.EnableEffect(POSITIONAL_EFFECT_SLOT, *globalEffect);
        } else if ((forceReverb and not useReverb.Get()) or removeReverb) {
            source.DisableEffect(POSITIONAL_EFFECT_SLOT);
        }
    }

    // Implementation for Emitter

    Emitter::Emitter() {
    }

    Emitter::~Emitter() {
    }

    void Emitter::SetupSound(Sound& sound) {
        sound.GetSource().SetReferenceDistance(60.0f);
        InternalSetupSound(sound);
        UpdateSound(sound);
    }

    // Implementation of EntityEmitter

    EntityEmitter::EntityEmitter(int entityNum): entityNum(entityNum) {
    }

    EntityEmitter::~EntityEmitter(){
    }

    void EntityEmitter::Update() {
        // TODO
    }

    void EntityEmitter::UpdateSound(Sound& sound) {
        AL::Source& source = sound.GetSource();

        if (entityNum == listenerEntity) {
            MakeLocal(source);
        } else {
            Make3D(source, entities[entityNum].position, entities[entityNum].velocity);
        }
    }

    void EntityEmitter::InternalSetupSound(Sound& sound) {
        AL::Source& source = sound.GetSource();

        Make3D(source, entities[entityNum].position, entities[entityNum].velocity, true);
    }

    // Implementation of PositionEmitter

    PositionEmitter::PositionEmitter(const vec3_t position){
        VectorCopy(position, this->position);
    }

    PositionEmitter::~PositionEmitter() {
    }

    void PositionEmitter::Update() {
        //TODO
    }

    void PositionEmitter::UpdateSound(Sound& sound) {
        AL::Source& source = sound.GetSource();

        Make3D(source, position, origin);
    }

    void PositionEmitter::InternalSetupSound(Sound& sound) {
        AL::Source& source = sound.GetSource();

        Make3D(source, position, origin, true);
    }

    const vec3_t& PositionEmitter::GetPosition() const {
        return position;
    }

    // Implementation of LocalEmitter

    LocalEmitter::LocalEmitter() {
    }

    LocalEmitter::~LocalEmitter() {
    }

    void LocalEmitter::Update() {
    }

    void LocalEmitter::UpdateSound(Sound&) {
    }

    void LocalEmitter::InternalSetupSound(Sound& sound) {
        AL::Source& source = sound.GetSource();

        MakeLocal(source);
    }

}
<|endoftext|>


<commit_before>#include "FAST/Testing.hpp"
#include "AirwaySegmentation.hpp"
#include "FAST/Importers/ImageFileImporter.hpp"
#include "FAST/Algorithms/SurfaceExtraction/SurfaceExtraction.hpp"
#include "FAST/Algorithms/CenterlineExtraction/CenterlineExtraction.hpp"
#include "FAST/Visualization/MeshRenderer/MeshRenderer.hpp"
#include "FAST/Visualization/LineRenderer/LineRenderer.hpp"
#include "FAST/Visualization/SimpleWindow.hpp"

using namespace fast;

TEST_CASE("Airway segmentation", "[fast][AirwaySegmentation]") {
	Reporter::setGlobalReportMethod(Reporter::COUT);
	for(int i = 1; i < 26; ++i) {
        ImageFileImporter::pointer importer = ImageFileImporter::New();
        //importer->setFilename(std::string(FAST_TEST_DATA_DIR) + "CT-Thorax.mhd");
        std::string nr = boost::lexical_cast<std::string>(i);
        if(nr.size() == 1) {
        	nr = "0" + nr;
        }
        importer->setFilename("/home/smistad/Data/lunge_datasett/pasient" + nr + ".mhd");

        AirwaySegmentation::pointer segmentation = AirwaySegmentation::New();
        segmentation->setInputConnection(importer->getOutputPort());

        CenterlineExtraction::pointer centerline = CenterlineExtraction::New();
        centerline->setInputConnection(segmentation->getOutputPort());
        centerline->update();

        SurfaceExtraction::pointer extraction = SurfaceExtraction::New();
        extraction->setInputConnection(segmentation->getOutputPort());

        MeshRenderer::pointer renderer = MeshRenderer::New();
        renderer->addInputConnection(extraction->getOutputPort());

        LineRenderer::pointer lineRenderer = LineRenderer::New();
        lineRenderer->addInputConnection(centerline->getOutputPort());
        lineRenderer->setDefaultDrawOnTop(true);

        SimpleWindow::pointer window = SimpleWindow::New();
        window->addRenderer(renderer);
        window->addRenderer(lineRenderer);
        window->start();
	}

}
<commit_msg>added airway test<commit_after>#include "FAST/Testing.hpp"
#include "AirwaySegmentation.hpp"
#include "FAST/Importers/ImageFileImporter.hpp"
#include "FAST/Algorithms/SurfaceExtraction/SurfaceExtraction.hpp"
#include "FAST/Algorithms/CenterlineExtraction/CenterlineExtraction.hpp"
#include "FAST/Visualization/MeshRenderer/MeshRenderer.hpp"
#include "FAST/Visualization/LineRenderer/LineRenderer.hpp"
#include "FAST/Visualization/SimpleWindow.hpp"

using namespace fast;

TEST_CASE("Airway segmentation ALL", "[fast][AirwaySegmentation]") {
	Reporter::setGlobalReportMethod(Reporter::COUT);
	for(int i = 1; i < 26; ++i) {
        ImageFileImporter::pointer importer = ImageFileImporter::New();
        //importer->setFilename(std::string(FAST_TEST_DATA_DIR) + "CT-Thorax.mhd");
        std::string nr = boost::lexical_cast<std::string>(i);
        if(nr.size() == 1) {
        	nr = "0" + nr;
        }
        importer->setFilename("/home/smistad/Data/lunge_datasett/pasient" + nr + ".mhd");

        AirwaySegmentation::pointer segmentation = AirwaySegmentation::New();
        segmentation->setInputConnection(importer->getOutputPort());

        CenterlineExtraction::pointer centerline = CenterlineExtraction::New();
        centerline->setInputConnection(segmentation->getOutputPort());
        centerline->update();

        SurfaceExtraction::pointer extraction = SurfaceExtraction::New();
        extraction->setInputConnection(segmentation->getOutputPort());

        MeshRenderer::pointer renderer = MeshRenderer::New();
        renderer->addInputConnection(extraction->getOutputPort());

        LineRenderer::pointer lineRenderer = LineRenderer::New();
        lineRenderer->addInputConnection(centerline->getOutputPort());
        lineRenderer->setDefaultDrawOnTop(true);

        SimpleWindow::pointer window = SimpleWindow::New();
        window->addRenderer(renderer);
        window->addRenderer(lineRenderer);
        window->start();
	}
}

TEST_CASE("Airway segmentation", "[fast][AirwaySegmentation]") {
	Reporter::setGlobalReportMethod(Reporter::COUT);
	ImageFileImporter::pointer importer = ImageFileImporter::New();
	importer->setFilename(std::string(FAST_TEST_DATA_DIR) + "CT-Thorax.mhd");

	AirwaySegmentation::pointer segmentation = AirwaySegmentation::New();
	segmentation->setInputConnection(importer->getOutputPort());

	CenterlineExtraction::pointer centerline = CenterlineExtraction::New();
	centerline->setInputConnection(segmentation->getOutputPort());
	centerline->update();

	SurfaceExtraction::pointer extraction = SurfaceExtraction::New();
	extraction->setInputConnection(segmentation->getOutputPort());

	MeshRenderer::pointer renderer = MeshRenderer::New();
	renderer->addInputConnection(extraction->getOutputPort());

	LineRenderer::pointer lineRenderer = LineRenderer::New();
	lineRenderer->addInputConnection(centerline->getOutputPort());
	lineRenderer->setDefaultDrawOnTop(true);

	SimpleWindow::pointer window = SimpleWindow::New();
	window->addRenderer(renderer);
	window->addRenderer(lineRenderer);
	window->start();
}
<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.  For licensing terms and
** conditions see http://qt.digia.com/licensing.  For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights.  These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/

#include "subcomponentmanager.h"
#include "model.h"
#include "metainfo.h"

#include <utils/hostosinfo.h>

#include <QDir>
#include <QMetaType>
#include <QUrl>

enum { debug = false };

QT_BEGIN_NAMESPACE

// Allow usage of QFileInfo in qSort

static bool operator<(const QFileInfo &file1, const QFileInfo &file2)
{
    return file1.filePath() < file2.filePath();
}

QT_END_NAMESPACE

static inline QStringList importPaths() {
    QStringList paths;

    // env import paths
    QByteArray envImportPath = qgetenv("QML_IMPORT_PATH");
    if (!envImportPath.isEmpty()) {
        paths = QString::fromLatin1(envImportPath)
                .split(Utils::HostOsInfo::pathListSeparator(), QString::SkipEmptyParts);
    }

    return paths;
}

namespace QmlDesigner {
static const QString s_qmlFilePattern = QString(QLatin1String("*.qml"));

SubComponentManager::SubComponentManager(Model *model, QObject *parent)
    : QObject(parent),
      m_model(model)
{
    connect(&m_watcher, SIGNAL(directoryChanged(QString)), this, SLOT(parseDirectory(QString)));
}

void SubComponentManager::addImport(int pos, const Import &import)
{
    if (debug)
        qDebug() << Q_FUNC_INFO << pos << import.file().toLatin1();

    if (import.isFileImport()) {
        QFileInfo dirInfo = QFileInfo(m_filePath.resolved(import.file()).toLocalFile());
        if (dirInfo.exists() && dirInfo.isDir()) {
            const QString canonicalDirPath = dirInfo.canonicalFilePath();
            m_watcher.addPath(canonicalDirPath);
            //m_dirToQualifier.insertMulti(canonicalDirPath, import.qualifier()); ### todo: proper support for import as
        }
    } else {
        QString url = import.url();

        url.replace(QLatin1Char('.'), QLatin1Char('/'));

        foreach (const QString &path, importPaths()) {
            url  = path + QLatin1Char('/') + url;
            QFileInfo dirInfo = QFileInfo(url);
            if (dirInfo.exists() && dirInfo.isDir()) {
                const QString canonicalDirPath = dirInfo.canonicalFilePath();
                m_watcher.addPath(canonicalDirPath);
                //m_dirToQualifier.insertMulti(canonicalDirPath, import.qualifier()); ### todo: proper support for import as
            }
        }
        // TODO: QDeclarativeDomImport::Library
    }

    m_imports.insert(pos, import);
}

void SubComponentManager::removeImport(int pos)
{
    const Import import = m_imports.takeAt(pos);

    if (import.isFileImport()) {
        const QFileInfo dirInfo = QFileInfo(m_filePath.resolved(import.file()).toLocalFile());
        const QString canonicalDirPath = dirInfo.canonicalFilePath();

        //m_dirToQualifier.remove(canonicalDirPath, import.qualifier()); ### todo: proper support for import as

        if (!m_dirToQualifier.contains(canonicalDirPath))
            m_watcher.removePath(canonicalDirPath);

//        foreach (const QFileInfo &monitoredFile, watchedFiles(canonicalDirPath)) { ### todo: proper support for import as
//            if (!m_dirToQualifier.contains(canonicalDirPath))
//                unregisterQmlFile(monitoredFile, import.qualifier());
//        }
    } else {
            // TODO: QDeclarativeDomImport::Library
    }
}

void SubComponentManager::parseDirectories()
{
    if (!m_filePath.isEmpty()) {
        const QString file = m_filePath.toLocalFile();
        QFileInfo dirInfo = QFileInfo(QFileInfo(file).path());
        if (dirInfo.exists() && dirInfo.isDir())
            parseDirectory(dirInfo.canonicalFilePath());

        foreach (const QString subDir, QDir(QFileInfo(file).path()).entryList(QDir::Dirs | QDir::NoDot | QDir::NoDotDot)) {
            parseDirectory(dirInfo.canonicalFilePath() + "/" + subDir, true, subDir);
        }
    }

    foreach (const Import &import, m_imports) {
        if (import.isFileImport()) {
            QFileInfo dirInfo = QFileInfo(m_filePath.resolved(import.file()).toLocalFile());
            if (dirInfo.exists() && dirInfo.isDir()) {
                parseDirectory(dirInfo.canonicalFilePath());
            }
        } else {
            QString url = import.url();
            foreach (const QString &path, importPaths()) {
                url.replace(QLatin1Char('.'), QLatin1Char('/'));
                url  = path + QLatin1Char('/') + url;
                QFileInfo dirInfo = QFileInfo(url);
                if (dirInfo.exists() && dirInfo.isDir()) {
                    //### todo full qualified names QString nameSpace = import.uri();
                    parseDirectory(dirInfo.canonicalFilePath(), false);
                }
            }
        }
    }
}

void SubComponentManager::parseDirectory(const QString &canonicalDirPath, bool addToLibrary, const QString& qualification)
{
    if (debug)
        qDebug() << Q_FUNC_INFO << canonicalDirPath;

    QDir dir(canonicalDirPath);

    dir.setNameFilters(QStringList(s_qmlFilePattern));
    dir.setFilter(QDir::Files | QDir::Readable | QDir::CaseSensitive);

    QList<QFileInfo> monitoredList = watchedFiles(canonicalDirPath);
    QList<QFileInfo> newList;
    foreach (const QFileInfo &qmlFile, dir.entryInfoList()) {
        if (QFileInfo(m_filePath.toLocalFile()) == qmlFile) {
            // do not parse main file
            continue;
        }
        if (!qmlFile.fileName().at(0).isUpper()) {
            // QML sub components must be upper case
            continue;
        }
        newList << qmlFile;
    }

    qSort(monitoredList);
    qSort(newList);

    if (debug)
        qDebug() << "monitored list " << monitoredList.size() << "new list " << newList.size();
    QList<QFileInfo>::const_iterator oldIter = monitoredList.constBegin();
    QList<QFileInfo>::const_iterator newIter = newList.constBegin();

    while (oldIter != monitoredList.constEnd() && newIter != newList.constEnd()) {
        const QFileInfo oldFileInfo = *oldIter;
        const QFileInfo newFileInfo = *newIter;
        if (oldFileInfo == newFileInfo) {
            ++oldIter;
            ++newIter;
            continue;
        }
        if (oldFileInfo < newFileInfo) {
            foreach (const QString &qualifier, m_dirToQualifier.value(canonicalDirPath))
                unregisterQmlFile(oldFileInfo, qualifier);
            m_watcher.removePath(oldFileInfo.filePath());
            ++oldIter;
            continue;
        }
        // oldFileInfo > newFileInfo
        parseFile(newFileInfo.filePath(), addToLibrary, qualification);
        ++newIter;
    }

    while (oldIter != monitoredList.constEnd()) {
        foreach (const QString &qualifier, m_dirToQualifier.value(canonicalDirPath))
            unregisterQmlFile(*oldIter, qualifier);
        ++oldIter;
    }

    while (newIter != newList.constEnd()) {
        parseFile(newIter->filePath(), addToLibrary, qualification);
        if (debug)
            qDebug() << "m_watcher.addPath(" << newIter->filePath() << ')';
        ++newIter;
    }
}

void SubComponentManager::parseFile(const QString &canonicalFilePath, bool addToLibrary, const QString&  qualification)
{
    if (debug)
        qDebug() << Q_FUNC_INFO << canonicalFilePath;

    QFile file(canonicalFilePath);
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        return;
    }

    QString dir = QFileInfo(canonicalFilePath).path();
    foreach (const QString &qualifier, m_dirToQualifier.values(dir)) {
        registerQmlFile(canonicalFilePath, qualifier, addToLibrary);
    }
    registerQmlFile(canonicalFilePath, qualification, addToLibrary);
}

void SubComponentManager::parseFile(const QString &canonicalFilePath)
{
    parseFile(canonicalFilePath, true, QString());
}

// dirInfo must already contain a canonical path
QList<QFileInfo> SubComponentManager::watchedFiles(const QString &canonicalDirPath)
{
    QList<QFileInfo> files;

    foreach (const QString &monitoredFile, m_watcher.files()) {
        QFileInfo fileInfo(monitoredFile);
        if (fileInfo.dir().absolutePath() == canonicalDirPath) {
            files.append(fileInfo);
        }
    }
    return files;
}

void SubComponentManager::unregisterQmlFile(const QFileInfo &fileInfo, const QString &qualifier)
{
    QString componentName = fileInfo.baseName();
    if (!qualifier.isEmpty())
        componentName = qualifier + '.' + componentName;
}

static inline bool isDepricatedQtType(const QString &typeName)
{
    if (typeName.length() < 8)
        return false;

    return typeName.contains("Qt.");
}

void SubComponentManager::registerQmlFile(const QFileInfo &fileInfo, const QString &qualifier,
                                                 bool addToLibrary)
{
    if (!model())
        return;

    QString componentName = fileInfo.baseName();

    if (debug)
        qDebug() << "SubComponentManager" << __FUNCTION__ << componentName;

    if (addToLibrary) {
        // Add file components to the library
        ItemLibraryEntry itemLibraryEntry;
        itemLibraryEntry.setType(componentName, -1, -1);
        itemLibraryEntry.setName(componentName);
        itemLibraryEntry.setCategory("QML Components");
        if (!qualifier.isEmpty()) {
            itemLibraryEntry.setForceImport(true);
            itemLibraryEntry.setRequiredImport(qualifier);
        }

        if (model()->metaInfo(componentName).isValid() && model()->metaInfo(componentName).isSubclassOf("QtQuick.Item", -1, -1) &&
            !model()->metaInfo().itemLibraryInfo()->containsEntry(itemLibraryEntry)) {

            model()->metaInfo().itemLibraryInfo()->addEntry(itemLibraryEntry);
        }
    }
}

Model *SubComponentManager::model() const
{
    return m_model.data();
}

/*!
  \class SubComponentManager

  Detects & monitors (potential) component files in a list of directories, and registers
  these in the metatype system.
*/

QStringList SubComponentManager::directories() const
{
    return m_watcher.directories();
}

QStringList SubComponentManager::qmlFiles() const
{
    return m_watcher.files();
}

void SubComponentManager::update(const QUrl &filePath, const QList<Import> &imports)
{
    if (debug)
        qDebug() << Q_FUNC_INFO << filePath << imports.size();

    QFileInfo oldDir, newDir;

    if (!m_filePath.isEmpty()) {
        const QString file = m_filePath.toLocalFile();
        oldDir = QFileInfo(QFileInfo(file).path());
    }
    if (!filePath.isEmpty()) {
        const QString file = filePath.toLocalFile();
        newDir = QFileInfo(QFileInfo(file).path());
    }

    m_filePath = filePath;

    //
    // (implicit) import of local directory
    //
    if (oldDir != newDir) {
        if (!oldDir.filePath().isEmpty()) {
            m_dirToQualifier.remove(oldDir.canonicalFilePath(), QString());
            if (!m_dirToQualifier.contains(oldDir.canonicalFilePath()))
                m_watcher.removePath(oldDir.filePath());
        }

        if (!newDir.filePath().isEmpty()) {
            m_dirToQualifier.insertMulti(newDir.canonicalFilePath(), QString());
        }
    }

    //
    // Imports
    //

    // skip first list items until the lists differ
    int i = 0;
    while (i < qMin(imports.size(), m_imports.size())) {
        if (!(imports.at(i) == m_imports.at(i)))
            break;
        ++i;
    }

    for (int ii = m_imports.size() - 1; ii >= i; --ii)
        removeImport(ii);

    for (int ii = i; ii < imports.size(); ++ii) {
        addImport(ii, imports.at(ii));
    }

    parseDirectories();
}

} // namespace QmlDesigner

<commit_msg>QmlDesigner.SubComponentManager: support for .metainfo files<commit_after>/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.  For licensing terms and
** conditions see http://qt.digia.com/licensing.  For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights.  These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/

#include <qmldesignerconstants.h>

#include "subcomponentmanager.h"
#include "model.h"
#include "metainfo.h"
#include "metainforeader.h"

#include <utils/hostosinfo.h>

#include <QDir>
#include <QMetaType>
#include <QMessageBox>
#include <QUrl>

enum { debug = false };

QT_BEGIN_NAMESPACE

// Allow usage of QFileInfo in qSort

static bool operator<(const QFileInfo &file1, const QFileInfo &file2)
{
    return file1.filePath() < file2.filePath();
}

QT_END_NAMESPACE

static inline QStringList importPaths() {
    QStringList paths;

    // env import paths
    QByteArray envImportPath = qgetenv("QML_IMPORT_PATH");
    if (!envImportPath.isEmpty()) {
        paths = QString::fromLatin1(envImportPath)
                .split(Utils::HostOsInfo::pathListSeparator(), QString::SkipEmptyParts);
    }

    return paths;
}

namespace QmlDesigner {
static const QString s_qmlFilePattern = QString(QLatin1String("*.qml"));

SubComponentManager::SubComponentManager(Model *model, QObject *parent)
    : QObject(parent),
      m_model(model)
{
    connect(&m_watcher, SIGNAL(directoryChanged(QString)), this, SLOT(parseDirectory(QString)));
}

void SubComponentManager::addImport(int pos, const Import &import)
{
    if (debug)
        qDebug() << Q_FUNC_INFO << pos << import.file().toLatin1();

    if (import.isFileImport()) {
        QFileInfo dirInfo = QFileInfo(m_filePath.resolved(import.file()).toLocalFile());
        if (dirInfo.exists() && dirInfo.isDir()) {
            const QString canonicalDirPath = dirInfo.canonicalFilePath();
            m_watcher.addPath(canonicalDirPath);
            //m_dirToQualifier.insertMulti(canonicalDirPath, import.qualifier()); ### todo: proper support for import as
        }
    } else {
        QString url = import.url();

        url.replace(QLatin1Char('.'), QLatin1Char('/'));

        foreach (const QString &path, importPaths()) {
            url  = path + QLatin1Char('/') + url;
            QFileInfo dirInfo = QFileInfo(url);
            if (dirInfo.exists() && dirInfo.isDir()) {
                const QString canonicalDirPath = dirInfo.canonicalFilePath();
                m_watcher.addPath(canonicalDirPath);
                //m_dirToQualifier.insertMulti(canonicalDirPath, import.qualifier()); ### todo: proper support for import as
            }
        }
        // TODO: QDeclarativeDomImport::Library
    }

    m_imports.insert(pos, import);
}

void SubComponentManager::removeImport(int pos)
{
    const Import import = m_imports.takeAt(pos);

    if (import.isFileImport()) {
        const QFileInfo dirInfo = QFileInfo(m_filePath.resolved(import.file()).toLocalFile());
        const QString canonicalDirPath = dirInfo.canonicalFilePath();

        //m_dirToQualifier.remove(canonicalDirPath, import.qualifier()); ### todo: proper support for import as

        if (!m_dirToQualifier.contains(canonicalDirPath))
            m_watcher.removePath(canonicalDirPath);

//        foreach (const QFileInfo &monitoredFile, watchedFiles(canonicalDirPath)) { ### todo: proper support for import as
//            if (!m_dirToQualifier.contains(canonicalDirPath))
//                unregisterQmlFile(monitoredFile, import.qualifier());
//        }
    } else {
            // TODO: QDeclarativeDomImport::Library
    }
}

void SubComponentManager::parseDirectories()
{
    if (!m_filePath.isEmpty()) {
        const QString file = m_filePath.toLocalFile();
        QFileInfo dirInfo = QFileInfo(QFileInfo(file).path());
        if (dirInfo.exists() && dirInfo.isDir())
            parseDirectory(dirInfo.canonicalFilePath());

        foreach (const QString subDir, QDir(QFileInfo(file).path()).entryList(QDir::Dirs | QDir::NoDot | QDir::NoDotDot)) {
            parseDirectory(dirInfo.canonicalFilePath() + "/" + subDir, true, subDir);
        }
    }

    foreach (const Import &import, m_imports) {
        if (import.isFileImport()) {
            QFileInfo dirInfo = QFileInfo(m_filePath.resolved(import.file()).toLocalFile());
            if (dirInfo.exists() && dirInfo.isDir()) {
                parseDirectory(dirInfo.canonicalFilePath());
            }
        } else {
            QString url = import.url();
            foreach (const QString &path, importPaths()) {
                url.replace(QLatin1Char('.'), QLatin1Char('/'));
                url  = path + QLatin1Char('/') + url;
                QFileInfo dirInfo = QFileInfo(url);
                if (dirInfo.exists() && dirInfo.isDir()) {
                    //### todo full qualified names QString nameSpace = import.uri();
                    parseDirectory(dirInfo.canonicalFilePath(), false);
                }
            }
        }
    }
}

void SubComponentManager::parseDirectory(const QString &canonicalDirPath, bool addToLibrary, const QString& qualification)
{

    QDir designerDir(canonicalDirPath + Constants::QML_DESIGNER_SUBFOLDER);
    if (designerDir.exists()) {
        QStringList filter;
        filter << "*.metainfo";
        designerDir.setNameFilters(filter);

        QStringList metaFiles = designerDir.entryList(QDir::Files);
        foreach (const QFileInfo &metaInfoFile, designerDir.entryInfoList(QDir::Files)) {
            if (model() && model()->metaInfo().itemLibraryInfo()) {
                Internal::MetaInfoReader reader(model()->metaInfo());
                try {
                    reader.readMetaInfoFile(metaInfoFile.absoluteFilePath(), true);
                } catch (InvalidMetaInfoException &e) {
                    qWarning() << e.description();
                    const QString errorMessage = metaInfoFile.absoluteFilePath() + QLatin1Char('\n') + QLatin1Char('\n') + reader.errors().join(QLatin1String("\n"));
                    QMessageBox::critical(0,
                                          QCoreApplication::translate("SubComponentManager::parseDirectory", "Invalid meta info"),
                                          errorMessage);
                }
            }
        }
        if (!metaFiles.isEmpty()) {
            return;
        }
    }

    if (debug)
        qDebug() << Q_FUNC_INFO << canonicalDirPath;

    QDir dir(canonicalDirPath);

    dir.setNameFilters(QStringList(s_qmlFilePattern));
    dir.setFilter(QDir::Files | QDir::Readable | QDir::CaseSensitive);

    QList<QFileInfo> monitoredList = watchedFiles(canonicalDirPath);
    QList<QFileInfo> newList;
    foreach (const QFileInfo &qmlFile, dir.entryInfoList()) {
        if (QFileInfo(m_filePath.toLocalFile()) == qmlFile) {
            // do not parse main file
            continue;
        }
        if (!qmlFile.fileName().at(0).isUpper()) {
            // QML sub components must be upper case
            continue;
        }
        newList << qmlFile;
    }

    qSort(monitoredList);
    qSort(newList);

    if (debug)
        qDebug() << "monitored list " << monitoredList.size() << "new list " << newList.size();
    QList<QFileInfo>::const_iterator oldIter = monitoredList.constBegin();
    QList<QFileInfo>::const_iterator newIter = newList.constBegin();

    while (oldIter != monitoredList.constEnd() && newIter != newList.constEnd()) {
        const QFileInfo oldFileInfo = *oldIter;
        const QFileInfo newFileInfo = *newIter;
        if (oldFileInfo == newFileInfo) {
            ++oldIter;
            ++newIter;
            continue;
        }
        if (oldFileInfo < newFileInfo) {
            foreach (const QString &qualifier, m_dirToQualifier.value(canonicalDirPath))
                unregisterQmlFile(oldFileInfo, qualifier);
            m_watcher.removePath(oldFileInfo.filePath());
            ++oldIter;
            continue;
        }
        // oldFileInfo > newFileInfo
        parseFile(newFileInfo.filePath(), addToLibrary, qualification);
        ++newIter;
    }

    while (oldIter != monitoredList.constEnd()) {
        foreach (const QString &qualifier, m_dirToQualifier.value(canonicalDirPath))
            unregisterQmlFile(*oldIter, qualifier);
        ++oldIter;
    }

    while (newIter != newList.constEnd()) {
        parseFile(newIter->filePath(), addToLibrary, qualification);
        if (debug)
            qDebug() << "m_watcher.addPath(" << newIter->filePath() << ')';
        ++newIter;
    }
}

void SubComponentManager::parseFile(const QString &canonicalFilePath, bool addToLibrary, const QString&  qualification)
{
    if (debug)
        qDebug() << Q_FUNC_INFO << canonicalFilePath;

    QFile file(canonicalFilePath);
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        return;
    }

    QString dir = QFileInfo(canonicalFilePath).path();
    foreach (const QString &qualifier, m_dirToQualifier.values(dir)) {
        registerQmlFile(canonicalFilePath, qualifier, addToLibrary);
    }
    registerQmlFile(canonicalFilePath, qualification, addToLibrary);
}

void SubComponentManager::parseFile(const QString &canonicalFilePath)
{
    parseFile(canonicalFilePath, true, QString());
}

// dirInfo must already contain a canonical path
QList<QFileInfo> SubComponentManager::watchedFiles(const QString &canonicalDirPath)
{
    QList<QFileInfo> files;

    foreach (const QString &monitoredFile, m_watcher.files()) {
        QFileInfo fileInfo(monitoredFile);
        if (fileInfo.dir().absolutePath() == canonicalDirPath) {
            files.append(fileInfo);
        }
    }
    return files;
}

void SubComponentManager::unregisterQmlFile(const QFileInfo &fileInfo, const QString &qualifier)
{
    QString componentName = fileInfo.baseName();
    if (!qualifier.isEmpty())
        componentName = qualifier + '.' + componentName;
}

static inline bool isDepricatedQtType(const QString &typeName)
{
    if (typeName.length() < 8)
        return false;

    return typeName.contains("Qt.");
}

void SubComponentManager::registerQmlFile(const QFileInfo &fileInfo, const QString &qualifier,
                                                 bool addToLibrary)
{
    if (!model())
        return;

    QString componentName = fileInfo.baseName();

    if (debug)
        qDebug() << "SubComponentManager" << __FUNCTION__ << componentName;

    if (addToLibrary) {
        // Add file components to the library
        ItemLibraryEntry itemLibraryEntry;
        itemLibraryEntry.setType(componentName, -1, -1);
        itemLibraryEntry.setName(componentName);
        itemLibraryEntry.setCategory("QML Components");
        if (!qualifier.isEmpty()) {
            itemLibraryEntry.setForceImport(true);
            itemLibraryEntry.setRequiredImport(qualifier);
        }

        if (model()->metaInfo(componentName).isValid() && model()->metaInfo(componentName).isSubclassOf("QtQuick.Item", -1, -1) &&
            !model()->metaInfo().itemLibraryInfo()->containsEntry(itemLibraryEntry)) {

            model()->metaInfo().itemLibraryInfo()->addEntry(itemLibraryEntry);
        }
    }
}

Model *SubComponentManager::model() const
{
    return m_model.data();
}

/*!
  \class SubComponentManager

  Detects & monitors (potential) component files in a list of directories, and registers
  these in the metatype system.
*/

QStringList SubComponentManager::directories() const
{
    return m_watcher.directories();
}

QStringList SubComponentManager::qmlFiles() const
{
    return m_watcher.files();
}

void SubComponentManager::update(const QUrl &filePath, const QList<Import> &imports)
{
    if (debug)
        qDebug() << Q_FUNC_INFO << filePath << imports.size();

    QFileInfo oldDir, newDir;

    if (!m_filePath.isEmpty()) {
        const QString file = m_filePath.toLocalFile();
        oldDir = QFileInfo(QFileInfo(file).path());
    }
    if (!filePath.isEmpty()) {
        const QString file = filePath.toLocalFile();
        newDir = QFileInfo(QFileInfo(file).path());
    }

    m_filePath = filePath;

    //
    // (implicit) import of local directory
    //
    if (oldDir != newDir) {
        if (!oldDir.filePath().isEmpty()) {
            m_dirToQualifier.remove(oldDir.canonicalFilePath(), QString());
            if (!m_dirToQualifier.contains(oldDir.canonicalFilePath()))
                m_watcher.removePath(oldDir.filePath());
        }

        if (!newDir.filePath().isEmpty()) {
            m_dirToQualifier.insertMulti(newDir.canonicalFilePath(), QString());
        }
    }

    //
    // Imports
    //

    // skip first list items until the lists differ
    int i = 0;
    while (i < qMin(imports.size(), m_imports.size())) {
        if (!(imports.at(i) == m_imports.at(i)))
            break;
        ++i;
    }

    for (int ii = m_imports.size() - 1; ii >= i; --ii)
        removeImport(ii);

    for (int ii = i; ii < imports.size(); ++ii) {
        addImport(ii, imports.at(ii));
    }

    parseDirectories();
}

} // namespace QmlDesigner

<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Creator.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "maemodeviceconfiglistmodel.h"

#include "maemoconstants.h"

namespace Qt4ProjectManager {
namespace Internal {

MaemoDeviceConfigListModel::MaemoDeviceConfigListModel(QObject *parent)
    : QAbstractListModel(parent), m_currentIndex(-1)
{
    setupList();
    const MaemoDeviceConfigurations &devConfs
        = MaemoDeviceConfigurations::instance();
    if (m_devConfigs.isEmpty())
        setInvalid();
    else
        setCurrentIndex(0);
    connect(&devConfs, SIGNAL(updated()), this,
        SLOT(handleDeviceConfigListChange()));
}

void MaemoDeviceConfigListModel::setupList()
{
    m_devConfigs.clear();
    const MaemoDeviceConfigurations &devConfs
        = MaemoDeviceConfigurations::instance();
    foreach (const MaemoDeviceConfig &devConfig, devConfs.devConfigs()) {
        if (devConfig.freePorts().hasMore())
            m_devConfigs << devConfig;
    }
}

void MaemoDeviceConfigListModel::setCurrentIndex(int index)
{
    const quint64 idForIndex = m_devConfigs.at(index).internalId;
    if (idForIndex != m_currentId) {
        m_currentId = idForIndex;
        m_currentIndex = index;
        emit currentChanged();
    }
}

void MaemoDeviceConfigListModel::resetCurrentIndex()
{
    if (m_devConfigs.isEmpty()) {
        setInvalid();
        return;
    }

    for (int i = 0; i < m_devConfigs.count(); ++i) {
        if (m_devConfigs.at(i).internalId == m_currentId) {
            setCurrentIndex(i);
            return;
        }
    }
    setCurrentIndex(0);
}

void MaemoDeviceConfigListModel::setInvalid()
{
    m_currentIndex = -1;
    m_currentId = MaemoDeviceConfig::InvalidId;
    emit currentChanged();
}

MaemoDeviceConfig MaemoDeviceConfigListModel::current() const
{
    return MaemoDeviceConfigurations::instance().find(m_currentId);
}

QVariantMap MaemoDeviceConfigListModel::toMap() const
{
    QVariantMap map;
    map.insert(DeviceIdKey, current().internalId);
    return map;
}

void MaemoDeviceConfigListModel::fromMap(const QVariantMap &map)
{
    const quint64 oldId = m_currentId;
    m_currentId = map.value(DeviceIdKey, 0).toULongLong();
    resetCurrentIndex();
    if (oldId != m_currentId)
        emit currentChanged();
}

void MaemoDeviceConfigListModel::handleDeviceConfigListChange()
{
    setupList();
    resetCurrentIndex();
    reset();
    emit currentChanged();
}

int MaemoDeviceConfigListModel::rowCount(const QModelIndex &parent) const
{
    return parent.isValid() ? 0 : m_devConfigs.count();
}

QVariant MaemoDeviceConfigListModel::data(const QModelIndex &index, int role) const
{
    if (!index.isValid() || index.row() >= rowCount()
        || role != Qt::DisplayRole)
        return QVariant();
    return m_devConfigs.at(index.row()).name;
}

} // namespace Internal
} // namespace Qt4ProjectManager
<commit_msg>Maemo: Make device config list model a bit more robust.<commit_after>/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Creator.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "maemodeviceconfiglistmodel.h"

#include "maemoconstants.h"

namespace Qt4ProjectManager {
namespace Internal {

MaemoDeviceConfigListModel::MaemoDeviceConfigListModel(QObject *parent)
    : QAbstractListModel(parent), m_currentIndex(-1)
{
    setupList();
    const MaemoDeviceConfigurations &devConfs
        = MaemoDeviceConfigurations::instance();
    if (m_devConfigs.isEmpty())
        setInvalid();
    else
        setCurrentIndex(0);
    connect(&devConfs, SIGNAL(updated()), this,
        SLOT(handleDeviceConfigListChange()));
}

void MaemoDeviceConfigListModel::setupList()
{
    m_devConfigs.clear();
    const MaemoDeviceConfigurations &devConfs
        = MaemoDeviceConfigurations::instance();
    foreach (const MaemoDeviceConfig &devConfig, devConfs.devConfigs()) {
        if (devConfig.freePorts().hasMore())
            m_devConfigs << devConfig;
    }
}

void MaemoDeviceConfigListModel::setCurrentIndex(int index)
{
    m_currentIndex = index;
    m_currentId = m_devConfigs.at(m_currentIndex).internalId;
    emit currentChanged();
}

void MaemoDeviceConfigListModel::resetCurrentIndex()
{
    if (m_devConfigs.isEmpty()) {
        setInvalid();
        return;
    }

    for (int i = 0; i < m_devConfigs.count(); ++i) {
        if (m_devConfigs.at(i).internalId == m_currentId) {
            setCurrentIndex(i);
            return;
        }
    }
    setCurrentIndex(0);
}

void MaemoDeviceConfigListModel::setInvalid()
{
    m_currentIndex = -1;
    m_currentId = MaemoDeviceConfig::InvalidId;
    emit currentChanged();
}

MaemoDeviceConfig MaemoDeviceConfigListModel::current() const
{
    return MaemoDeviceConfigurations::instance().find(m_currentId);
}

QVariantMap MaemoDeviceConfigListModel::toMap() const
{
    QVariantMap map;
    map.insert(DeviceIdKey, current().internalId);
    return map;
}

void MaemoDeviceConfigListModel::fromMap(const QVariantMap &map)
{
    const quint64 oldId = m_currentId;
    m_currentId = map.value(DeviceIdKey, 0).toULongLong();
    resetCurrentIndex();
    if (oldId != m_currentId)
        emit currentChanged();
}

void MaemoDeviceConfigListModel::handleDeviceConfigListChange()
{
    setupList();
    resetCurrentIndex();
    reset();
    emit currentChanged();
}

int MaemoDeviceConfigListModel::rowCount(const QModelIndex &parent) const
{
    return parent.isValid() ? 0 : m_devConfigs.count();
}

QVariant MaemoDeviceConfigListModel::data(const QModelIndex &index, int role) const
{
    if (!index.isValid() || index.row() >= rowCount()
        || role != Qt::DisplayRole)
        return QVariant();
    return m_devConfigs.at(index.row()).name;
}

} // namespace Internal
} // namespace Qt4ProjectManager
<|endoftext|>


<commit_before>#include "classes.h"
#include "win.h"

#include <sycl.hpp>

#include <chrono>
#include <iostream>
#include <string>
#include <vector>
#include <memory>

using std::string;

extern void compute_org(void*, int w, int h, int samps, Ray& cam, Vec& cx, Vec& cy, Vec r, Vec* c);
extern void compute_org_openmp(void*, int w, int h, int samps, Ray& cam, Vec& cx, Vec& cy, Vec r, Vec* c);
extern void compute_org_sp(void*, int w, int h, int samps, Ray& cam, Vec& cx, Vec& cy, Vec r, Vec* c);
extern void compute_org_sp_openmp(void*, int w, int h, int samps, Ray& cam, Vec& cx, Vec& cy, Vec r, Vec* c);
extern void compute_sycl_gtx(void* dev, int w, int h, int samps, Ray& cam_, Vec& cx_, Vec& cy_, Vec r_, Vec* c_);

inline double clamp(double x) {
	return x < 0 ? 0 : x>1 ? 1 : x;
}
inline int toInt(double x) {
	return int(pow(clamp(x), 1 / 2.2) * 255 + .5);
}

void to_file(int w, int h, Vec* c, string filename) {
	FILE* f = fopen(filename.c_str(), "w");         // Write image to PPM file.
	fprintf(f, "P3\n%d %d\n%d\n", w, h, 255);
	for(int i = 0; i < w*h; i++) {
		fprintf(f, "%d %d %d\n", toInt(c[i].x), toInt(c[i].y), toInt(c[i].z));
	}
	fclose(f);
}

using time_point = std::chrono::high_resolution_clock::time_point;

auto now = []() {
	return std::chrono::high_resolution_clock::now();
};
auto duration = [](time_point before) {
	static const float to_seconds = 1e-6f;
	return std::chrono::duration_cast<std::chrono::microseconds>(now() - before).count() * to_seconds;
};

struct testInfo {
	using function_ptr = void(*)(void*, int, int, int, Ray&, Vec&, Vec&, Vec, Vec*);
	string name;
	function_ptr test;
	std::unique_ptr<cl::sycl::device> dev;
	float lastTime = 0;

	static decltype(now()) startTime;
	static float totalTime;

	testInfo(string name, function_ptr test, cl::sycl::device* dev = nullptr)
		: name(name), test(test), dev(dev) {}

	testInfo(const testInfo&) = delete;
	testInfo(testInfo&& move)
		: name(std::move(move.name)), test(move.test), dev(std::move(move.dev)) {}
};
decltype(now()) testInfo::startTime = now();
float testInfo::totalTime = 0;

static std::vector<const testInfo> tests;
static Ray cam(Vec(50, 52, 295.6), Vec(0, -0.042612, -1).norm()); // cam pos, dir

bool tester(int w, int h, int samples, Vec& cx, Vec& cy, int iterations, int from, int to) {
	using namespace std;

	cout << "samples per pixel: " << samples << endl;

	Vec r;
	vector<Vec> empty_vectors(w*h, 0);
	vector<Vec> vectors;
	float time;

	for(int ti = from; ti < to; ++ti) {
		auto& t = tests[ti];

		// Quality of Service
		// Prevent the user from waiting too long
		if(t.lastTime > 40) {
			continue;
		}

		cout << "Running test: " << t.name << endl;
		ns_erand::reset();
#ifndef _DEBUG
		try {
#endif
			auto start = now();
			for(int i = 0; i < iterations; ++i) {
				vectors = empty_vectors;
				t.test(t.dev.get(), w, h, samples, cam, cx, cy, r, vectors.data());
			}
			time = (duration(start) / (float)iterations);

#ifndef _DEBUG
		}
		catch(cl::sycl::exception& e) {
			cerr << "SYCL error while testing: " << e.what() << endl;
			continue;
		}
		catch(exception& e) {
			cerr << "error while testing: " << e.what() << endl;
			continue;
		}
		cout << "time: " << time << endl;
		//to_file(w, h, vectors.data(), string("image_") + t.name + ".ppm");

		t.lastTime = time;

		testInfo::totalTime = duration(testInfo::startTime);
		if(testInfo::totalTime > 300) {
			cout << "exceeded 5 minute limit, stopping" << endl;
			return false;
		}
	}

	return true;
}

struct version {
	int major = 0;
	int minor = 0;

	version(int major, int minor)
		: major(major), minor(minor) {}
	version(const string& v) {
		// https://www.khronos.org/registry/cl/sdk/1.2/docs/man/xhtml/clGetPlatformInfo.html
		using namespace std;
		string search("OpenCL");
		auto pos = v.find(search);
		if(pos != string::npos) {
			pos += search.length() + 1;	// Plus one for space
			try {
				major = (int)v.at(pos) - '0';
				minor = (int)v.at(pos + 2) - '0';; // Plus one for dot
			}
			catch(std::exception&) {}
		}
	}
};

template <class T>
void printInfo(string description, const T& data, int offset = 0) {
	string indent;
	for(int i = 0; i < offset; ++i) {
		indent += '\t';
	}
	std::cout << indent << description << ": " << data << std::endl;
}

void getDevices() {
	using namespace std;

	try {
		using namespace cl::sycl;

		auto platforms = platform::get_platforms();

		version required(1, 2);

		int pNum = 0;
		for(auto& p : platforms) {
			cout << "- OpenCL platform " << pNum << ':' << endl;
			++pNum;

			auto openclVersion = p.get_info<info::platform::version>();

			version platformVersion(openclVersion);

			printInfo("name", p.get_info<info::platform::name>(), 1);
			printInfo("vendor", p.get_info<info::platform::vendor>(), 1);
			printInfo("version", openclVersion, 1);
			printInfo("profile", p.get_info<info::platform::profile>(), 1);
			printInfo("extensions", p.get_info<info::platform::extensions>(), 1);

			auto devices = p.get_devices();
			int dNum = 0;

			for(auto& d : devices) {
				cout << "\t-- OpenCL device " << dNum << ':' << endl;

				auto name = d.get_info<info::device::name>();

				printInfo("name", d.get_info<info::device::name>(), 2);
				printInfo("device_type", (cl_device_type)d.get_info<info::device::device_type>(), 2);
				printInfo("vendor", d.get_info<info::device::vendor>(), 2);
				printInfo("device_version", d.get_info<info::device::device_version>(), 2);
				printInfo("driver_version", d.get_info<info::device::driver_version>(), 2);
#ifdef SYCL_GTX
				printInfo("opencl_version", d.get_info<info::device::opencl_version>(), 2);
				printInfo("single_fp_config", d.get_info<info::device::single_fp_config>(), 2);
				printInfo("double_fp_config", d.get_info<info::device::double_fp_config>(), 2);
#endif
				printInfo("profile", d.get_info<info::device::profile>(), 2);
				printInfo("error_correction_support", d.get_info<info::device::error_correction_support>(), 2);
				printInfo("host_unified_memory", d.get_info<info::device::host_unified_memory>(), 2);
				printInfo("max_clock_frequency", d.get_info<info::device::max_clock_frequency>(), 2);
				printInfo("max_compute_units", d.get_info<info::device::max_compute_units>(), 2);
				printInfo("max_work_item_dimensions", d.get_info<info::device::max_work_item_dimensions>(), 2);
				printInfo("max_work_group_size", d.get_info<info::device::max_work_group_size>(), 2);

				printInfo("address_bits", d.get_info<info::device::address_bits>(), 2);
				printInfo("max_mem_alloc_size", d.get_info<info::device::max_mem_alloc_size>(), 2);
				printInfo("global_mem_cache_line_size", d.get_info<info::device::global_mem_cache_line_size>(), 2);
				printInfo("global_mem_cache_size", d.get_info<info::device::global_mem_cache_size>(), 2);
				printInfo("global_mem_size", d.get_info<info::device::global_mem_size>(), 2);
				printInfo("max_constant_buffer_size", d.get_info<info::device::max_constant_buffer_size>(), 2);
				printInfo("max_constant_args", d.get_info<info::device::max_constant_args>(), 2);
				printInfo("local_mem_size", d.get_info<info::device::local_mem_size>(), 2);
				printInfo("extensions", d.get_info<info::device::extensions>(), 2);

				if(
					platformVersion.major > required.major ||
					(platformVersion.major == required.major && platformVersion.minor >= required.minor)
				) {
					tests.emplace_back(name + ' ' + openclVersion, compute_sycl_gtx, new device(std::move(d)));
				}

				++dNum;
			}
		}
	}
	catch(cl::sycl::exception& e) {
		// TODO
		cout << "OpenCL not available: " << e.what() << endl;
	}
}

int main(int argc, char *argv[]) {
	using namespace std;

	cout << "smallpt SYCL tester" << endl;

	tests.emplace_back("org_single", compute_org_sp);
	tests.emplace_back("openmp_single", compute_org_sp_openmp);
	tests.emplace_back("org", compute_org);
	tests.emplace_back("openmp", compute_org_openmp);

	getDevices();

	int w = 1024;
	int h = 768;
	Vec cx = Vec(w*.5135 / h);
	Vec cy = (cx%cam.d).norm()*.5135;
	auto numTests = tests.size();

	int from = 2;
	int to = numTests;
	if(argc > 1) {
		from = atoi(argv[1]);
		if(argc > 2) {
			to = atoi(argv[2]);
		}
	}

	cout << "Going through tests in range [" << from << ',' << to << ')' << endl;

	if(false) {
		tester(w, h, 1, cx, cy, 1, from, to);
		cout << "Press any key to exit" << endl;
		cin.get();
		return 0;
	}

	// Test suite
	int iterations = 1;
	bool canContinue;

	for(int samples = 5; samples < 10000; samples *= 2) {
		canContinue = tester(w, h, samples, cx, cy, iterations, from, to);
		if(!canContinue) {
			break;
		}
	}

	auto time = duration(testInfo::startTime);
	cout << "total test suite duration: " << time << endl;

	//cout << "Press any key to exit" << endl;
	//cin.get();

	return 0;
}
<commit_msg>smallpt - forgot to include #endif after debugging block<commit_after>#include "classes.h"
#include "win.h"

#include <sycl.hpp>

#include <chrono>
#include <iostream>
#include <string>
#include <vector>
#include <memory>

using std::string;

extern void compute_org(void*, int w, int h, int samps, Ray& cam, Vec& cx, Vec& cy, Vec r, Vec* c);
extern void compute_org_openmp(void*, int w, int h, int samps, Ray& cam, Vec& cx, Vec& cy, Vec r, Vec* c);
extern void compute_org_sp(void*, int w, int h, int samps, Ray& cam, Vec& cx, Vec& cy, Vec r, Vec* c);
extern void compute_org_sp_openmp(void*, int w, int h, int samps, Ray& cam, Vec& cx, Vec& cy, Vec r, Vec* c);
extern void compute_sycl_gtx(void* dev, int w, int h, int samps, Ray& cam_, Vec& cx_, Vec& cy_, Vec r_, Vec* c_);

inline double clamp(double x) {
	return x < 0 ? 0 : x>1 ? 1 : x;
}
inline int toInt(double x) {
	return int(pow(clamp(x), 1 / 2.2) * 255 + .5);
}

void to_file(int w, int h, Vec* c, string filename) {
	FILE* f = fopen(filename.c_str(), "w");         // Write image to PPM file.
	fprintf(f, "P3\n%d %d\n%d\n", w, h, 255);
	for(int i = 0; i < w*h; i++) {
		fprintf(f, "%d %d %d\n", toInt(c[i].x), toInt(c[i].y), toInt(c[i].z));
	}
	fclose(f);
}

using time_point = std::chrono::high_resolution_clock::time_point;

auto now = []() {
	return std::chrono::high_resolution_clock::now();
};
auto duration = [](time_point before) {
	static const float to_seconds = 1e-6f;
	return std::chrono::duration_cast<std::chrono::microseconds>(now() - before).count() * to_seconds;
};

struct testInfo {
	using function_ptr = void(*)(void*, int, int, int, Ray&, Vec&, Vec&, Vec, Vec*);
	string name;
	function_ptr test;
	std::unique_ptr<cl::sycl::device> dev;
	float lastTime = 0;

	static decltype(now()) startTime;
	static float totalTime;

	testInfo(string name, function_ptr test, cl::sycl::device* dev = nullptr)
		: name(name), test(test), dev(dev) {}

	testInfo(const testInfo&) = delete;
	testInfo(testInfo&& move)
		: name(std::move(move.name)), test(move.test), dev(std::move(move.dev)) {}
};
decltype(now()) testInfo::startTime = now();
float testInfo::totalTime = 0;

static std::vector<const testInfo> tests;
static Ray cam(Vec(50, 52, 295.6), Vec(0, -0.042612, -1).norm()); // cam pos, dir

bool tester(int w, int h, int samples, Vec& cx, Vec& cy, int iterations, int from, int to) {
	using namespace std;

	cout << "samples per pixel: " << samples << endl;

	Vec r;
	vector<Vec> empty_vectors(w*h, 0);
	vector<Vec> vectors;
	float time;

	for(int ti = from; ti < to; ++ti) {
		auto& t = tests[ti];

		// Quality of Service
		// Prevent the user from waiting too long
		if(t.lastTime > 40) {
			continue;
		}

		cout << "Running test: " << t.name << endl;
		ns_erand::reset();
#ifndef _DEBUG
		try {
#endif
			auto start = now();
			for(int i = 0; i < iterations; ++i) {
				vectors = empty_vectors;
				t.test(t.dev.get(), w, h, samples, cam, cx, cy, r, vectors.data());
			}
			time = (duration(start) / (float)iterations);

#ifndef _DEBUG
		}
		catch(cl::sycl::exception& e) {
			cerr << "SYCL error while testing: " << e.what() << endl;
			continue;
		}
		catch(exception& e) {
			cerr << "error while testing: " << e.what() << endl;
			continue;
		}
#endif
		cout << "time: " << time << endl;
		//to_file(w, h, vectors.data(), string("image_") + t.name + ".ppm");

		t.lastTime = time;

		testInfo::totalTime = duration(testInfo::startTime);
		if(testInfo::totalTime > 300) {
			cout << "exceeded 5 minute limit, stopping" << endl;
			return false;
		}
	}

	return true;
}

struct version {
	int major = 0;
	int minor = 0;

	version(int major, int minor)
		: major(major), minor(minor) {}
	version(const string& v) {
		// https://www.khronos.org/registry/cl/sdk/1.2/docs/man/xhtml/clGetPlatformInfo.html
		using namespace std;
		string search("OpenCL");
		auto pos = v.find(search);
		if(pos != string::npos) {
			pos += search.length() + 1;	// Plus one for space
			try {
				major = (int)v.at(pos) - '0';
				minor = (int)v.at(pos + 2) - '0';; // Plus one for dot
			}
			catch(std::exception&) {}
		}
	}
};

template <class T>
void printInfo(string description, const T& data, int offset = 0) {
	string indent;
	for(int i = 0; i < offset; ++i) {
		indent += '\t';
	}
	std::cout << indent << description << ": " << data << std::endl;
}

void getDevices() {
	using namespace std;

	try {
		using namespace cl::sycl;

		auto platforms = platform::get_platforms();

		version required(1, 2);

		int pNum = 0;
		for(auto& p : platforms) {
			cout << "- OpenCL platform " << pNum << ':' << endl;
			++pNum;

			auto openclVersion = p.get_info<info::platform::version>();

			version platformVersion(openclVersion);

			printInfo("name", p.get_info<info::platform::name>(), 1);
			printInfo("vendor", p.get_info<info::platform::vendor>(), 1);
			printInfo("version", openclVersion, 1);
			printInfo("profile", p.get_info<info::platform::profile>(), 1);
			printInfo("extensions", p.get_info<info::platform::extensions>(), 1);

			auto devices = p.get_devices();
			int dNum = 0;

			for(auto& d : devices) {
				cout << "\t-- OpenCL device " << dNum << ':' << endl;

				auto name = d.get_info<info::device::name>();

				printInfo("name", d.get_info<info::device::name>(), 2);
				printInfo("device_type", (cl_device_type)d.get_info<info::device::device_type>(), 2);
				printInfo("vendor", d.get_info<info::device::vendor>(), 2);
				printInfo("device_version", d.get_info<info::device::device_version>(), 2);
				printInfo("driver_version", d.get_info<info::device::driver_version>(), 2);
#ifdef SYCL_GTX
				printInfo("opencl_version", d.get_info<info::device::opencl_version>(), 2);
				printInfo("single_fp_config", d.get_info<info::device::single_fp_config>(), 2);
				printInfo("double_fp_config", d.get_info<info::device::double_fp_config>(), 2);
#endif
				printInfo("profile", d.get_info<info::device::profile>(), 2);
				printInfo("error_correction_support", d.get_info<info::device::error_correction_support>(), 2);
				printInfo("host_unified_memory", d.get_info<info::device::host_unified_memory>(), 2);
				printInfo("max_clock_frequency", d.get_info<info::device::max_clock_frequency>(), 2);
				printInfo("max_compute_units", d.get_info<info::device::max_compute_units>(), 2);
				printInfo("max_work_item_dimensions", d.get_info<info::device::max_work_item_dimensions>(), 2);
				printInfo("max_work_group_size", d.get_info<info::device::max_work_group_size>(), 2);

				printInfo("address_bits", d.get_info<info::device::address_bits>(), 2);
				printInfo("max_mem_alloc_size", d.get_info<info::device::max_mem_alloc_size>(), 2);
				printInfo("global_mem_cache_line_size", d.get_info<info::device::global_mem_cache_line_size>(), 2);
				printInfo("global_mem_cache_size", d.get_info<info::device::global_mem_cache_size>(), 2);
				printInfo("global_mem_size", d.get_info<info::device::global_mem_size>(), 2);
				printInfo("max_constant_buffer_size", d.get_info<info::device::max_constant_buffer_size>(), 2);
				printInfo("max_constant_args", d.get_info<info::device::max_constant_args>(), 2);
				printInfo("local_mem_size", d.get_info<info::device::local_mem_size>(), 2);
				printInfo("extensions", d.get_info<info::device::extensions>(), 2);

				if(
					platformVersion.major > required.major ||
					(platformVersion.major == required.major && platformVersion.minor >= required.minor)
				) {
					tests.emplace_back(name + ' ' + openclVersion, compute_sycl_gtx, new device(std::move(d)));
				}

				++dNum;
			}
		}
	}
	catch(cl::sycl::exception& e) {
		// TODO
		cout << "OpenCL not available: " << e.what() << endl;
	}
}

int main(int argc, char *argv[]) {
	using namespace std;

	cout << "smallpt SYCL tester" << endl;

	tests.emplace_back("org_single", compute_org_sp);
	tests.emplace_back("openmp_single", compute_org_sp_openmp);
	tests.emplace_back("org", compute_org);
	tests.emplace_back("openmp", compute_org_openmp);

	getDevices();

	int w = 1024;
	int h = 768;
	Vec cx = Vec(w*.5135 / h);
	Vec cy = (cx%cam.d).norm()*.5135;
	auto numTests = tests.size();

	int from = 2;
	int to = numTests;
	if(argc > 1) {
		from = atoi(argv[1]);
		if(argc > 2) {
			to = atoi(argv[2]);
		}
	}

	cout << "Going through tests in range [" << from << ',' << to << ')' << endl;

	if(false) {
		tester(w, h, 1, cx, cy, 1, from, to);
		cout << "Press any key to exit" << endl;
		cin.get();
		return 0;
	}

	// Test suite
	int iterations = 1;
	bool canContinue;

	for(int samples = 5; samples < 10000; samples *= 2) {
		canContinue = tester(w, h, samples, cx, cy, iterations, from, to);
		if(!canContinue) {
			break;
		}
	}

	auto time = duration(testInfo::startTime);
	cout << "total test suite duration: " << time << endl;

	//cout << "Press any key to exit" << endl;
	//cin.get();

	return 0;
}
<|endoftext|>