<commit_before>// -*- mode: c++; c-basic-offset:4 -*-

// This file is part of libdap, A C++ implementation of the OPeNDAP Data
// Access Protocol.

// Copyright (c) 2002,2003 OPeNDAP, Inc.
// Author: James Gallagher <jgallagher@opendap.org>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//
// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.

#include "config.h"

#include <cppunit/TextTestRunner.h>
#include <cppunit/extensions/TestFactoryRegistry.h>
#include <cppunit/extensions/HelperMacros.h>

// Tests for Byte. Tests features of BaseType, too. 7/19/2001 jhrg

#include <sstream>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <string.h>

#include "crc.h"
#include "Byte.h"
#include "Int8.h"
#include "Int16.h"
#include "UInt16.h"
#include "Int32.h"
#include "UInt32.h"
#include "Float32.h"
#include "Float64.h"
#include "Str.h"
#include "Url.h"
#include "Array.h"
#include "ce_expr.tab.hh"

#include "GetOpt.h" // Added jhrg

#include "testFile.h"

/// Added jhrg
static bool debug = false;

#undef DBG
#define DBG(x) do { if (debug) (x); } while(false);
/// jhrg

using namespace CppUnit;
using namespace std;
using namespace libdap;

class ByteTest: public TestFixture {
private:
    Byte * tb1;
    Byte *tb2;
    Byte *tb3;
    Byte *tb4;
    Byte *tb5;
    char a[1024];

public:
    ByteTest()
    {
    }
    ~ByteTest()
    {
    }

    void setUp()
    {
        tb1 = new Byte("tb1");
        tb2 = new Byte("tb2 name with spaces");
        tb3 = new Byte("tb3 %");
        tb4 = new Byte("tb4 #");
        tb5 = new Byte("a", "b");
    }

    void tearDown()
    {
        delete tb1;
        tb1 = 0;
        delete tb2;
        tb2 = 0;
        delete tb3;
        tb3 = 0;
        delete tb4;
        tb4 = 0;
        delete tb5;
        tb5 = 0;
    }

    CPPUNIT_TEST_SUITE(ByteTest);

    CPPUNIT_TEST(cons_test);
    CPPUNIT_TEST(equals_test);
    CPPUNIT_TEST(checksum_test);
    CPPUNIT_TEST(val2buf_test);
    CPPUNIT_TEST(buf2val_test);
    CPPUNIT_TEST(dump_test);
    CPPUNIT_TEST(print_test);
    CPPUNIT_TEST(type_compare_test);
    CPPUNIT_TEST(name_mangling_test);
    CPPUNIT_TEST(decl_mangling_test);
    CPPUNIT_TEST(basetype_test);

    CPPUNIT_TEST_SUITE_END();

    void cons_test()
    {
        CPPUNIT_ASSERT(tb5->value() == 0 && tb5->dataset() == "b" && tb5->name() == "a" &&
                       tb5->type() == dods_byte_c);
        CPPUNIT_ASSERT(tb2->value() == 0);
    }

    void equals_test()
    {
        Byte b3 = Byte("a", "b");
        Byte b4 = Byte("e");

        CPPUNIT_ASSERT(b3.set_value(42) && b3.value() == 42);
        b4 = b3;
        CPPUNIT_ASSERT(b3.value() == 42);
        b4 = b4;
        CPPUNIT_ASSERT(b4.value() == 42);
    }

    void checksum_test()
    {
        Crc32 cs;
        tb5->compute_checksum(cs);
    }

    void val2buf_test()
    {
        char i = 3;
        tb3->val2buf(&i, true);
        CPPUNIT_ASSERT(tb3->value() == 3);
        CPPUNIT_ASSERT_THROW(tb3->val2buf(NULL, true), InternalErr);
    }

    void buf2val_test()
    {
        char i = 42;
        void *v = &i;
        void *v2 = NULL;
        CPPUNIT_ASSERT(tb1->set_value(6));
        CPPUNIT_ASSERT(tb1->buf2val(&v) == 1 && i == 6);
        CPPUNIT_ASSERT_THROW(tb1->buf2val(NULL), InternalErr);
        CPPUNIT_ASSERT(tb1->buf2val(&v2) == 1 && *(int *)v2 == 6);
    }

    void dump_test()
    {
        ofstream ofs("ByteTest_dump.output", ios::trunc);
        tb1->set_value(21);
        tb1->dump(ofs);
        ofs.close();
        ifstream ifs("ByteTest_dump.output");
        while(!ifs.eof())
            ifs >> a;
        ifs.close();
        CPPUNIT_ASSERT(a[0] == 21);
    }

    void print_test()
    {
        FILE *fp;
        CPPUNIT_ASSERT(fp = fopen("ByteTest.output", "w"));
        tb1->set_value(22);
        tb1->print_val(fp, " ", true);
        fclose(fp);
        ifstream ifs("ByteTest.output");
        while(!ifs.eof())
            ifs >> a;
        ifs.close();
        CPPUNIT_ASSERT(!strcmp(a, "22;"));
    }

    void type_compare_test()
    {
        Byte b1 = Byte("a");
        Int8 i8 = Int8("a");
        Int16 i16 = Int16("a");
        UInt16 ui16 = UInt16("a");
        Int32 i32 = Int32("a", "b");
        UInt32 ui32 = UInt32("a", "b");
        Float32 f32 = Float32("a");
        Float64 f64 = Float64("a");
        Url url = Url("a");
        Str str = Str("a");
        Array array = Array("a", &i16, true);

        b1.set_value(42);
        i8.set_value(42);
        i16.set_value(42);
        ui16.set_value(42);
        i32.set_value(42);
        ui32.set_value(42);
        f32.set_value(42);
        f64.set_value(42);
        CPPUNIT_ASSERT(b1.value() == 42);
        CPPUNIT_ASSERT(b1.ops(&b1, SCAN_EQUAL));
        CPPUNIT_ASSERT(b1.d4_ops(&b1, SCAN_EQUAL));
        CPPUNIT_ASSERT(b1.d4_ops(&i8, SCAN_EQUAL));
        CPPUNIT_ASSERT(b1.d4_ops(&i16, SCAN_EQUAL));
        CPPUNIT_ASSERT(b1.d4_ops(&ui16, SCAN_EQUAL));
        CPPUNIT_ASSERT(b1.d4_ops(&i32, SCAN_EQUAL));
        CPPUNIT_ASSERT(b1.d4_ops(&ui32, SCAN_EQUAL));
        CPPUNIT_ASSERT(b1.d4_ops(&f32, SCAN_EQUAL));
        CPPUNIT_ASSERT(b1.d4_ops(&f64, SCAN_EQUAL));

        CPPUNIT_ASSERT_THROW(b1.d4_ops(&url, SCAN_EQUAL), Error);
        CPPUNIT_ASSERT_THROW(b1.d4_ops(&str, SCAN_EQUAL), Error);
        CPPUNIT_ASSERT_THROW(b1.d4_ops(&array, SCAN_EQUAL), Error);
    }

    void name_mangling_test()
    {
        CPPUNIT_ASSERT(tb1->name() == "tb1");
        CPPUNIT_ASSERT(tb2->name() == "tb2 name with spaces");
        CPPUNIT_ASSERT(tb3->name() == "tb3 %");
        CPPUNIT_ASSERT(tb4->name() == "tb4 #");
    }

    void decl_mangling_test()
    {
        ostringstream sof;
        tb1->print_decl(sof, "", false);
        CPPUNIT_ASSERT(sof.str().find("Byte tb1") != string::npos);

        tb2->print_decl(sof, "", false);
        CPPUNIT_ASSERT(sof.str().find("Byte tb2%20name%20with%20spaces") != string::npos);

        tb3->print_decl(sof, "", false);
        CPPUNIT_ASSERT(sof.str().find("Byte tb3%20%") != string::npos);

        tb4->print_decl(sof, "", false);
        CPPUNIT_ASSERT(sof.str().find("Byte tb4%20%23") != string::npos);
    }

    void basetype_test()
    {
        BaseType *bt = static_cast<BaseType*>(tb1);
        bt->width(false);
        CPPUNIT_ASSERT(!bt->synthesized_p());
        bt->set_synthesized_p(true);
        CPPUNIT_ASSERT(bt->synthesized_p());
        CPPUNIT_ASSERT_THROW(bt->add_var(bt), InternalErr);
        CPPUNIT_ASSERT_THROW(bt->add_var_nocopy(bt), InternalErr);
        CPPUNIT_ASSERT_THROW(bt->ops(bt, SCAN_EQUAL), InternalErr);
//        CPPUNIT_ASSERT_THROW(bt->width(false), InternalErr);
    }

};

CPPUNIT_TEST_SUITE_REGISTRATION (ByteTest);

int main(int argc, char *argv[])
{
    GetOpt getopt(argc, argv, "dh");
    int option_char;

    while ((option_char = getopt()) != -1)
        switch (option_char) {
        case 'd':
            debug = 1;  // debug is a static global
            break;

        case 'h': {     // help - show test names
            cerr << "Usage: ByteTest has the following tests:" << endl;
            // Since the ByteTest class is not in the namespace 'libdap' using the ns
            // prefix is a compiler error. Somce of the tests do put the code in a ns
            // and then you will need to use the match prefix. jhrg
            const std::vector<Test*> &tests = /*libdap:: jhrg*/ByteTest::suite()->getTests();
            unsigned int prefix_len = /*libdap:: jhrg*/ByteTest::suite()->getName().append("::").length();
            for (std::vector<Test*>::const_iterator i = tests.begin(), e = tests.end(); i != e; ++i) {
                cerr << (*i)->getName().replace(0, prefix_len, "") << endl;
            }
            break;
        }

        default:
            break;
        }

    CppUnit::TextTestRunner runner;
    runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest());

    bool wasSuccessful = true;
    string test = "";
    int i = getopt.optind;
    if (i == argc) {
        // run them all
        wasSuccessful = runner.run("");
    }
    else {
        for (; i < argc; ++i) {
            if (debug) cerr << "Running " << argv[i] << endl;
            test = /*libdap:: jhrg*/ByteTest::suite()->getName().append("::").append(argv[i]);
            wasSuccessful = wasSuccessful && runner.run(test);
        }
    }

    return wasSuccessful ? 0 : 1;
}
<commit_msg>trying to fix header issue<commit_after>// -*- mode: c++; c-basic-offset:4 -*-

// This file is part of libdap, A C++ implementation of the OPeNDAP Data
// Access Protocol.

// Copyright (c) 2002,2003 OPeNDAP, Inc.
// Author: James Gallagher <jgallagher@opendap.org>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//
// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.

#include "config.h"

#include <cppunit/TextTestRunner.h>
#include <cppunit/extensions/TestFactoryRegistry.h>
#include <cppunit/extensions/HelperMacros.h>

// Tests for Byte. Tests features of BaseType, too. 7/19/2001 jhrg

#include <sstream>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <string.h>

#include "Byte.h"
#include "Int8.h"
#include "Int16.h"
#include "UInt16.h"
#include "Int32.h"
#include "UInt32.h"
#include "Float32.h"
#include "Float64.h"
#include "Str.h"
#include "Url.h"
#include "Array.h"
#include "ce_expr.tab.hh"
#include "crc.h"

#include "GetOpt.h" // Added jhrg

#include "testFile.h"

/// Added jhrg
static bool debug = false;

#undef DBG
#define DBG(x) do { if (debug) (x); } while(false);
/// jhrg

using namespace CppUnit;
using namespace std;
using namespace libdap;

class ByteTest: public TestFixture {
private:
    Byte * tb1;
    Byte *tb2;
    Byte *tb3;
    Byte *tb4;
    Byte *tb5;
    char a[1024];

public:
    ByteTest()
    {
    }
    ~ByteTest()
    {
    }

    void setUp()
    {
        tb1 = new Byte("tb1");
        tb2 = new Byte("tb2 name with spaces");
        tb3 = new Byte("tb3 %");
        tb4 = new Byte("tb4 #");
        tb5 = new Byte("a", "b");
    }

    void tearDown()
    {
        delete tb1;
        tb1 = 0;
        delete tb2;
        tb2 = 0;
        delete tb3;
        tb3 = 0;
        delete tb4;
        tb4 = 0;
        delete tb5;
        tb5 = 0;
    }

    CPPUNIT_TEST_SUITE(ByteTest);

    CPPUNIT_TEST(cons_test);
    CPPUNIT_TEST(equals_test);
    CPPUNIT_TEST(checksum_test);
    CPPUNIT_TEST(val2buf_test);
    CPPUNIT_TEST(buf2val_test);
    CPPUNIT_TEST(dump_test);
    CPPUNIT_TEST(print_test);
    CPPUNIT_TEST(type_compare_test);
    CPPUNIT_TEST(name_mangling_test);
    CPPUNIT_TEST(decl_mangling_test);
    CPPUNIT_TEST(basetype_test);

    CPPUNIT_TEST_SUITE_END();

    void cons_test()
    {
        CPPUNIT_ASSERT(tb5->value() == 0 && tb5->dataset() == "b" && tb5->name() == "a" &&
                       tb5->type() == dods_byte_c);
        CPPUNIT_ASSERT(tb2->value() == 0);
    }

    void equals_test()
    {
        Byte b3 = Byte("a", "b");
        Byte b4 = Byte("e");

        CPPUNIT_ASSERT(b3.set_value(42) && b3.value() == 42);
        b4 = b3;
        CPPUNIT_ASSERT(b3.value() == 42);
        b4 = b4;
        CPPUNIT_ASSERT(b4.value() == 42);
    }

    void checksum_test()
    {
        Crc32 cs;
        tb5->compute_checksum(cs);
    }

    void val2buf_test()
    {
        char i = 3;
        tb3->val2buf(&i, true);
        CPPUNIT_ASSERT(tb3->value() == 3);
        CPPUNIT_ASSERT_THROW(tb3->val2buf(NULL, true), InternalErr);
    }

    void buf2val_test()
    {
        char i = 42;
        void *v = &i;
        void *v2 = NULL;
        CPPUNIT_ASSERT(tb1->set_value(6));
        CPPUNIT_ASSERT(tb1->buf2val(&v) == 1 && i == 6);
        CPPUNIT_ASSERT_THROW(tb1->buf2val(NULL), InternalErr);
        CPPUNIT_ASSERT(tb1->buf2val(&v2) == 1 && *(int *)v2 == 6);
    }

    void dump_test()
    {
        ofstream ofs("ByteTest_dump.output", ios::trunc);
        tb1->set_value(21);
        tb1->dump(ofs);
        ofs.close();
        ifstream ifs("ByteTest_dump.output");
        while(!ifs.eof())
            ifs >> a;
        ifs.close();
        CPPUNIT_ASSERT(a[0] == 21);
    }

    void print_test()
    {
        FILE *fp;
        CPPUNIT_ASSERT(fp = fopen("ByteTest.output", "w"));
        tb1->set_value(22);
        tb1->print_val(fp, " ", true);
        fclose(fp);
        ifstream ifs("ByteTest.output");
        while(!ifs.eof())
            ifs >> a;
        ifs.close();
        CPPUNIT_ASSERT(!strcmp(a, "22;"));
    }

    void type_compare_test()
    {
        Byte b1 = Byte("a");
        Int8 i8 = Int8("a");
        Int16 i16 = Int16("a");
        UInt16 ui16 = UInt16("a");
        Int32 i32 = Int32("a", "b");
        UInt32 ui32 = UInt32("a", "b");
        Float32 f32 = Float32("a");
        Float64 f64 = Float64("a");
        Url url = Url("a");
        Str str = Str("a");
        Array array = Array("a", &i16, true);

        b1.set_value(42);
        i8.set_value(42);
        i16.set_value(42);
        ui16.set_value(42);
        i32.set_value(42);
        ui32.set_value(42);
        f32.set_value(42);
        f64.set_value(42);
        CPPUNIT_ASSERT(b1.value() == 42);
        CPPUNIT_ASSERT(b1.ops(&b1, SCAN_EQUAL));
        CPPUNIT_ASSERT(b1.d4_ops(&b1, SCAN_EQUAL));
        CPPUNIT_ASSERT(b1.d4_ops(&i8, SCAN_EQUAL));
        CPPUNIT_ASSERT(b1.d4_ops(&i16, SCAN_EQUAL));
        CPPUNIT_ASSERT(b1.d4_ops(&ui16, SCAN_EQUAL));
        CPPUNIT_ASSERT(b1.d4_ops(&i32, SCAN_EQUAL));
        CPPUNIT_ASSERT(b1.d4_ops(&ui32, SCAN_EQUAL));
        CPPUNIT_ASSERT(b1.d4_ops(&f32, SCAN_EQUAL));
        CPPUNIT_ASSERT(b1.d4_ops(&f64, SCAN_EQUAL));

        CPPUNIT_ASSERT_THROW(b1.d4_ops(&url, SCAN_EQUAL), Error);
        CPPUNIT_ASSERT_THROW(b1.d4_ops(&str, SCAN_EQUAL), Error);
        CPPUNIT_ASSERT_THROW(b1.d4_ops(&array, SCAN_EQUAL), Error);
    }

    void name_mangling_test()
    {
        CPPUNIT_ASSERT(tb1->name() == "tb1");
        CPPUNIT_ASSERT(tb2->name() == "tb2 name with spaces");
        CPPUNIT_ASSERT(tb3->name() == "tb3 %");
        CPPUNIT_ASSERT(tb4->name() == "tb4 #");
    }

    void decl_mangling_test()
    {
        ostringstream sof;
        tb1->print_decl(sof, "", false);
        CPPUNIT_ASSERT(sof.str().find("Byte tb1") != string::npos);

        tb2->print_decl(sof, "", false);
        CPPUNIT_ASSERT(sof.str().find("Byte tb2%20name%20with%20spaces") != string::npos);

        tb3->print_decl(sof, "", false);
        CPPUNIT_ASSERT(sof.str().find("Byte tb3%20%") != string::npos);

        tb4->print_decl(sof, "", false);
        CPPUNIT_ASSERT(sof.str().find("Byte tb4%20%23") != string::npos);
    }

    void basetype_test()
    {
        BaseType *bt = static_cast<BaseType*>(tb1);
        bt->width(false);
        CPPUNIT_ASSERT(!bt->synthesized_p());
        bt->set_synthesized_p(true);
        CPPUNIT_ASSERT(bt->synthesized_p());
        CPPUNIT_ASSERT_THROW(bt->add_var(bt), InternalErr);
        CPPUNIT_ASSERT_THROW(bt->add_var_nocopy(bt), InternalErr);
        CPPUNIT_ASSERT_THROW(bt->ops(bt, SCAN_EQUAL), InternalErr);
//        CPPUNIT_ASSERT_THROW(bt->width(false), InternalErr);
    }

};

CPPUNIT_TEST_SUITE_REGISTRATION (ByteTest);

int main(int argc, char *argv[])
{
    GetOpt getopt(argc, argv, "dh");
    int option_char;

    while ((option_char = getopt()) != -1)
        switch (option_char) {
        case 'd':
            debug = 1;  // debug is a static global
            break;

        case 'h': {     // help - show test names
            cerr << "Usage: ByteTest has the following tests:" << endl;
            // Since the ByteTest class is not in the namespace 'libdap' using the ns
            // prefix is a compiler error. Somce of the tests do put the code in a ns
            // and then you will need to use the match prefix. jhrg
            const std::vector<Test*> &tests = /*libdap:: jhrg*/ByteTest::suite()->getTests();
            unsigned int prefix_len = /*libdap:: jhrg*/ByteTest::suite()->getName().append("::").length();
            for (std::vector<Test*>::const_iterator i = tests.begin(), e = tests.end(); i != e; ++i) {
                cerr << (*i)->getName().replace(0, prefix_len, "") << endl;
            }
            break;
        }

        default:
            break;
        }

    CppUnit::TextTestRunner runner;
    runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest());

    bool wasSuccessful = true;
    string test = "";
    int i = getopt.optind;
    if (i == argc) {
        // run them all
        wasSuccessful = runner.run("");
    }
    else {
        for (; i < argc; ++i) {
            if (debug) cerr << "Running " << argv[i] << endl;
            test = /*libdap:: jhrg*/ByteTest::suite()->getName().append("::").append(argv[i]);
            wasSuccessful = wasSuccessful && runner.run(test);
        }
    }

    return wasSuccessful ? 0 : 1;
}
<|endoftext|>


<commit_before>#ifndef BART_SRC_CONVERGENCE_CONVERGENCE_CHECKER_I_HPP_
#define BART_SRC_CONVERGENCE_CONVERGENCE_CHECKER_I_HPP_

#include <optional>

//! Tools for checking the convergence of variables
namespace bart::convergence {

/*! \brief Checks for convergence between two provided values.
 * Convergence is determined by calculating a delta between the two values,
 * and comparing them to a maximum allowed delta.
 *
 * \tparam CompareT type of value to compare.
 * \tparam DeltaT type of delta that will be used to determine comparison, default double.
 */

template <typename CompareT, typename DeltaT>
class ConvergenceCheckerI {
 public:
  virtual ~ConvergenceCheckerI() = default;
  /*! \brief Checks for convergence of two provided values */
  virtual auto IsConverged(const CompareT& current_iteration, const CompareT& previous_iteration) -> bool = 0;
  /*! \brief Returns status of convergence (from last call to IsConverged */
  virtual auto is_converged() const -> bool = 0;
  /*! \brief Set the threshold value for convergence check */
  virtual auto SetMaxDelta(const DeltaT& to_set) -> void = 0;
  /*! \brief Get the threshold value for convergence check */
  virtual auto max_delta() const -> DeltaT = 0;
  /*! \brief Get the delta value from the last convergence check. May be empty
   * if convergence has not be checked. */
  virtual auto delta() const -> std::optional<DeltaT> = 0;
};

} // namespace bart::convergence

#endif // BART_SRC_CONVERGENCE_CONVERGENCE_CHECKER_I_HPP_<commit_msg>Added default value for DeltaT in convergence::ConvergenceCheckerI.<commit_after>#ifndef BART_SRC_CONVERGENCE_CONVERGENCE_CHECKER_I_HPP_
#define BART_SRC_CONVERGENCE_CONVERGENCE_CHECKER_I_HPP_

#include <optional>

//! Tools for checking the convergence of variables
namespace bart::convergence {

/*! \brief Checks for convergence between two provided values.
 * Convergence is determined by calculating a delta between the two values,
 * and comparing them to a maximum allowed delta.
 *
 * \tparam CompareT type of value to compare.
 * \tparam DeltaT type of delta that will be used to determine comparison, default double.
 */

template <typename CompareT, typename DeltaT = double>
class ConvergenceCheckerI {
 public:
  virtual ~ConvergenceCheckerI() = default;
  /*! \brief Checks for convergence of two provided values */
  virtual auto IsConverged(const CompareT& current_iteration, const CompareT& previous_iteration) -> bool = 0;
  /*! \brief Returns status of convergence (from last call to IsConverged */
  virtual auto is_converged() const -> bool = 0;
  /*! \brief Set the threshold value for convergence check */
  virtual auto SetMaxDelta(const DeltaT& to_set) -> void = 0;
  /*! \brief Get the threshold value for convergence check */
  virtual auto max_delta() const -> DeltaT = 0;
  /*! \brief Get the delta value from the last convergence check. May be empty
   * if convergence has not be checked. */
  virtual auto delta() const -> std::optional<DeltaT> = 0;
};

} // namespace bart::convergence

#endif // BART_SRC_CONVERGENCE_CONVERGENCE_CHECKER_I_HPP_<|endoftext|>


<commit_before>// ======================================================================== //
// Copyright 2009-2014 Intel Corporation                                    //
//                                                                          //
// 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 "bvh4.h"
#include "bvh4_statistics.h"
#include "bvh4_builder_generic.h"

#include "algorithms/parallel_for_for.h"
#include "algorithms/parallel_for_for_prefix_sum.h"

#include "geometry/triangle4.h"

#define PROFILE

namespace embree
{
  namespace isa
  {
    __aligned(64) LinearAllocatorPerThread::ThreadAllocator* g_alloc;

    struct CreateBVH4Node
    {
      __forceinline CreateBVH4Node (BVH4* bvh) : bvh(bvh) {}

      __forceinline BVH4::NodeRef operator() (BuildRecord<BVH4::NodeRef>* children, const size_t N)
      {
        FastAllocator::Thread& alloc = *bvh->alloc2.instance();
        BVH4::Node* node = (BVH4::Node*) alloc.malloc(sizeof(BVH4::Node)); node->clear();
        //BVH4::Node* node = (BVH4::Node*) g_alloc->malloc(sizeof(BVH4::Node)); node->clear();
        for (size_t i=0; i<N; i++) {
          node->set(i,children[i].geomBounds);
          children[i].parent = &node->child(i);
        }
        return bvh->encodeNode(node);
      }

      BVH4* bvh;
    };

    template<typename Primitive>
    struct CreateLeaf
    {
      __forceinline CreateLeaf (BVH4* bvh) : bvh(bvh) {}

      __forceinline BVH4::NodeRef operator() (const BuildRecord<BVH4::NodeRef>& current, PrimRef* prims)
      {
        size_t items = Primitive::blocks(current.size());
        size_t start = current.begin;
        FastAllocator::Thread& alloc = *bvh->alloc2.instance();
        Primitive* accel = (Primitive*) alloc.malloc(items*sizeof(Primitive));
        //Primitive* accel = (Primitive*) g_alloc->malloc(items*sizeof(Primitive));
        BVH4::NodeRef node = bvh->encodeLeaf((char*)accel,items);
        for (size_t i=0; i<items; i++) {
          accel[i].fill(prims,start,current.end,bvh->scene,false);
        }
        return node;
      }

      BVH4* bvh;
    };

    template<typename Ty, size_t timeSteps>
    PrimInfo CreatePrimRefArray(Scene* scene, vector_t<PrimRef>& prims)
    {
      ParallelForForPrefixSumState<PrimInfo> pstate;
      Scene::Iterator<Ty,timeSteps> iter(scene);

      /* first try */
      pstate.init(iter,size_t(1024));
      PrimInfo pinfo = parallel_for_for_prefix_sum( pstate, iter, PrimInfo(empty), [&](Ty* mesh, const range<size_t>& r, size_t k, const PrimInfo& base) -> PrimInfo
      {
        PrimInfo pinfo(empty);
        for (ssize_t j=r.begin(); j<r.end(); j++)
        {
          BBox3fa bounds = empty;
          if (!mesh->valid(j,&bounds)) continue;
          const PrimRef prim(bounds,mesh->id,j);
          pinfo.add(prim.bounds(),prim.center2());
          prims[k++] = prim;
        }
        return pinfo;
      }, [](const PrimInfo& a, const PrimInfo& b) -> PrimInfo { return PrimInfo::merge(a,b); });

      /* if we need to filter out geometry, run again */
      if (pinfo.size() != prims.size())
      {
        pinfo = parallel_for_for_prefix_sum( pstate, iter, PrimInfo(empty), [&](Ty* mesh, const range<size_t>& r, size_t k, const PrimInfo& base) -> PrimInfo
        {
          k = base.begin;
          PrimInfo pinfo(empty);
          for (ssize_t j=r.begin(); j<r.end(); j++)
          {
            BBox3fa bounds = empty;
            if (!mesh->valid(j,&bounds)) continue;
            const PrimRef prim(bounds,mesh->id,j);
            pinfo.add(prim.bounds(),prim.center2());
            prims[k++] = prim;
          }
          return pinfo;
        }, [](const PrimInfo& a, const PrimInfo& b) -> PrimInfo { return PrimInfo::merge(a,b); });
      }
      return pinfo;
    }

    struct BVH4Triangle4BuilderFastClass : public Builder
    {
      BVH4* bvh;
      Scene* scene;
      vector_t<PrimRef> prims; // FIXME: use os_malloc in vector_t for large allocations

      BVH4Triangle4BuilderFastClass (BVH4* bvh, Scene* scene)
        : bvh(bvh), scene(scene) {}

      void build(size_t threadIndex, size_t threadCount)
      {
         /* start measurement */
        double t0 = 0.0f;
        if (g_verbose >= 1) t0 = getSeconds();

        /* calculate scene size */
        const size_t numPrimitives = scene->numTriangles;

        /* skip build for empty scene */
        if (numPrimitives == 0) {
          prims.resize(numPrimitives);
          bvh->set(BVH4::emptyNode,empty,0);
          return;
        }

        /* verbose mode */
        if (g_verbose >= 1)
          std::cout << "building BVH4<" << bvh->primTy.name << "> with " << TOSTRING(isa) "::BVH4BuilderFastNew ... " << std::flush;

#if defined(PROFILE)

      double dt_min = pos_inf;
      double dt_avg = 0.0f;
      double dt_max = neg_inf;
      for (size_t i=0; i<20; i++)
      {
        double t0 = getSeconds();
#endif

        //bvh->init(sizeof(BVH4::Node),numPrimitives,1);
        //g_alloc = new LinearAllocatorPerThread::ThreadAllocator(&bvh->alloc);
        bvh->alloc2.init(numPrimitives*sizeof(PrimRef),numPrimitives*sizeof(BVH4::Node));

        /* build BVH */
        prims.resize(numPrimitives);
        //memset(prims.data(),0,prims.size()*sizeof(PrimRef));

        vector_t<PrimRef> tmp; tmp.resize(numPrimitives);
        PrimRef* tmp_prims = (PrimRef*) tmp.data();
        //PrimRef* tmp_prims = (PrimRef*) bvh->alloc.curPtr();

        //double T0 = getSeconds();
        PrimInfo pinfo = CreatePrimRefArray<TriangleMesh,1>(scene,prims);
        //double T1 = getSeconds();
        CreateBVH4Node createNode(bvh);
        CreateLeaf<Triangle4> createLeaf(bvh);
        BVHBuilderGeneric<BVH4::NodeRef,CreateBVH4Node,CreateLeaf<Triangle4> > builder(createNode,createLeaf,prims.data(),tmp_prims,pinfo,BVH4::N,BVH4::maxBuildDepthLeaf,2,4,4*BVH4::maxLeafBlocks);
        BVH4::NodeRef root = builder();
        //double T2 = getSeconds();
        bvh->set(root,pinfo.geomBounds,pinfo.size());

#if defined(PROFILE)
        double dt = getSeconds()-t0;
        dt_min = min(dt_min,dt);
        dt_avg = dt_avg + dt;
        dt_max = max(dt_max,dt);
      }
      dt_avg /= double(20);

      std::cout << "[DONE]" << std::endl;
      std::cout << "  min = " << 1000.0f*dt_min << "ms (" << numPrimitives/dt_min*1E-6 << " Mtris/s)" << std::endl;
      std::cout << "  avg = " << 1000.0f*dt_avg << "ms (" << numPrimitives/dt_avg*1E-6 << " Mtris/s)" << std::endl;
      std::cout << "  max = " << 1000.0f*dt_max << "ms (" << numPrimitives/dt_max*1E-6 << " Mtris/s)" << std::endl;
      std::cout << BVH4Statistics(bvh).str();
#endif

        /* stop measurement */
        double dt = 0.0f;
        if (g_verbose >= 1) dt = getSeconds()-t0;

        /* verbose mode */
        if (g_verbose >= 1) {
          std::cout << "[DONE] " << 1000.0f*dt << "ms (" << numPrimitives/dt*1E-6 << " Mtris/s)" << std::endl;
          std::cout << "  bvh4::alloc : "; bvh->alloc.print_statistics();
          std::cout << "  bvh4::alloc2: "; bvh->alloc2.print_statistics();
        }
        if (g_verbose >= 2)
          std::cout << BVH4Statistics(bvh).str();
      }
    };

    Builder* BVH4Triangle4BuilderFastNew  (void* bvh, Scene* scene, size_t mode) { return new class BVH4Triangle4BuilderFastClass((BVH4*)bvh,scene); }
  }
}
<commit_msg>adding alloc2.reset<commit_after>// ======================================================================== //
// Copyright 2009-2014 Intel Corporation                                    //
//                                                                          //
// 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 "bvh4.h"
#include "bvh4_statistics.h"
#include "bvh4_builder_generic.h"

#include "algorithms/parallel_for_for.h"
#include "algorithms/parallel_for_for_prefix_sum.h"

#include "geometry/triangle4.h"

#define PROFILE

namespace embree
{
  namespace isa
  {
    __aligned(64) LinearAllocatorPerThread::ThreadAllocator* g_alloc;

    struct CreateBVH4Node
    {
      __forceinline CreateBVH4Node (BVH4* bvh) : bvh(bvh) {}

      __forceinline BVH4::NodeRef operator() (BuildRecord<BVH4::NodeRef>* children, const size_t N)
      {
        FastAllocator::Thread& alloc = *bvh->alloc2.instance();
        BVH4::Node* node = (BVH4::Node*) alloc.malloc(sizeof(BVH4::Node)); node->clear();
        //BVH4::Node* node = (BVH4::Node*) g_alloc->malloc(sizeof(BVH4::Node)); node->clear();
        for (size_t i=0; i<N; i++) {
          node->set(i,children[i].geomBounds);
          children[i].parent = &node->child(i);
        }
        return bvh->encodeNode(node);
      }

      BVH4* bvh;
    };

    template<typename Primitive>
    struct CreateLeaf
    {
      __forceinline CreateLeaf (BVH4* bvh) : bvh(bvh) {}

      __forceinline BVH4::NodeRef operator() (const BuildRecord<BVH4::NodeRef>& current, PrimRef* prims)
      {
        size_t items = Primitive::blocks(current.size());
        size_t start = current.begin;
        FastAllocator::Thread& alloc = *bvh->alloc2.instance();
        Primitive* accel = (Primitive*) alloc.malloc(items*sizeof(Primitive));
        //Primitive* accel = (Primitive*) g_alloc->malloc(items*sizeof(Primitive));
        BVH4::NodeRef node = bvh->encodeLeaf((char*)accel,items);
        for (size_t i=0; i<items; i++) {
          accel[i].fill(prims,start,current.end,bvh->scene,false);
        }
        return node;
      }

      BVH4* bvh;
    };

    template<typename Ty, size_t timeSteps>
    PrimInfo CreatePrimRefArray(Scene* scene, vector_t<PrimRef>& prims)
    {
      ParallelForForPrefixSumState<PrimInfo> pstate;
      Scene::Iterator<Ty,timeSteps> iter(scene);

      /* first try */
      pstate.init(iter,size_t(1024));
      PrimInfo pinfo = parallel_for_for_prefix_sum( pstate, iter, PrimInfo(empty), [&](Ty* mesh, const range<size_t>& r, size_t k, const PrimInfo& base) -> PrimInfo
      {
        PrimInfo pinfo(empty);
        for (ssize_t j=r.begin(); j<r.end(); j++)
        {
          BBox3fa bounds = empty;
          if (!mesh->valid(j,&bounds)) continue;
          const PrimRef prim(bounds,mesh->id,j);
          pinfo.add(prim.bounds(),prim.center2());
          prims[k++] = prim;
        }
        return pinfo;
      }, [](const PrimInfo& a, const PrimInfo& b) -> PrimInfo { return PrimInfo::merge(a,b); });

      /* if we need to filter out geometry, run again */
      if (pinfo.size() != prims.size())
      {
        pinfo = parallel_for_for_prefix_sum( pstate, iter, PrimInfo(empty), [&](Ty* mesh, const range<size_t>& r, size_t k, const PrimInfo& base) -> PrimInfo
        {
          k = base.begin;
          PrimInfo pinfo(empty);
          for (ssize_t j=r.begin(); j<r.end(); j++)
          {
            BBox3fa bounds = empty;
            if (!mesh->valid(j,&bounds)) continue;
            const PrimRef prim(bounds,mesh->id,j);
            pinfo.add(prim.bounds(),prim.center2());
            prims[k++] = prim;
          }
          return pinfo;
        }, [](const PrimInfo& a, const PrimInfo& b) -> PrimInfo { return PrimInfo::merge(a,b); });
      }
      return pinfo;
    }

    struct BVH4Triangle4BuilderFastClass : public Builder
    {
      BVH4* bvh;
      Scene* scene;
      vector_t<PrimRef> prims; // FIXME: use os_malloc in vector_t for large allocations

      BVH4Triangle4BuilderFastClass (BVH4* bvh, Scene* scene)
        : bvh(bvh), scene(scene) {}

      void build(size_t threadIndex, size_t threadCount)
      {
         /* start measurement */
        double t0 = 0.0f;
        if (g_verbose >= 1) t0 = getSeconds();

        /* calculate scene size */
        const size_t numPrimitives = scene->numTriangles;

        /* skip build for empty scene */
        if (numPrimitives == 0) {
          prims.resize(numPrimitives);
          bvh->set(BVH4::emptyNode,empty,0);
          return;
        }

        /* verbose mode */
        if (g_verbose >= 1)
          std::cout << "building BVH4<" << bvh->primTy.name << "> with " << TOSTRING(isa) "::BVH4BuilderFastNew ... " << std::flush;

        bvh->alloc2.init(numPrimitives*sizeof(PrimRef),numPrimitives*sizeof(BVH4::Node));

#if defined(PROFILE)

      double dt_min = pos_inf;
      double dt_avg = 0.0f;
      double dt_max = neg_inf;
      for (size_t i=0; i<20; i++)
      {
        double t0 = getSeconds();
#endif

        //bvh->init(sizeof(BVH4::Node),numPrimitives,1);
        //g_alloc = new LinearAllocatorPerThread::ThreadAllocator(&bvh->alloc);
        bvh->alloc2.reset();

        /* build BVH */
        prims.resize(numPrimitives);
        //memset(prims.data(),0,prims.size()*sizeof(PrimRef));

        vector_t<PrimRef> tmp; tmp.resize(numPrimitives);
        PrimRef* tmp_prims = (PrimRef*) tmp.data();
        //PrimRef* tmp_prims = (PrimRef*) bvh->alloc.curPtr();

        //double T0 = getSeconds();
        PrimInfo pinfo = CreatePrimRefArray<TriangleMesh,1>(scene,prims);
        //double T1 = getSeconds();
        CreateBVH4Node createNode(bvh);
        CreateLeaf<Triangle4> createLeaf(bvh);
        BVHBuilderGeneric<BVH4::NodeRef,CreateBVH4Node,CreateLeaf<Triangle4> > builder(createNode,createLeaf,prims.data(),tmp_prims,pinfo,BVH4::N,BVH4::maxBuildDepthLeaf,2,4,4*BVH4::maxLeafBlocks);
        BVH4::NodeRef root = builder();
        //double T2 = getSeconds();
        bvh->set(root,pinfo.geomBounds,pinfo.size());

#if defined(PROFILE)
        double dt = getSeconds()-t0;
        dt_min = min(dt_min,dt);
        dt_avg = dt_avg + dt;
        dt_max = max(dt_max,dt);
      }
      dt_avg /= double(20);

      std::cout << "[DONE]" << std::endl;
      std::cout << "  min = " << 1000.0f*dt_min << "ms (" << numPrimitives/dt_min*1E-6 << " Mtris/s)" << std::endl;
      std::cout << "  avg = " << 1000.0f*dt_avg << "ms (" << numPrimitives/dt_avg*1E-6 << " Mtris/s)" << std::endl;
      std::cout << "  max = " << 1000.0f*dt_max << "ms (" << numPrimitives/dt_max*1E-6 << " Mtris/s)" << std::endl;
      std::cout << BVH4Statistics(bvh).str();
#endif

        /* stop measurement */
        double dt = 0.0f;
        if (g_verbose >= 1) dt = getSeconds()-t0;

        /* verbose mode */
        if (g_verbose >= 1) {
          std::cout << "[DONE] " << 1000.0f*dt << "ms (" << numPrimitives/dt*1E-6 << " Mtris/s)" << std::endl;
          std::cout << "  bvh4::alloc : "; bvh->alloc.print_statistics();
          std::cout << "  bvh4::alloc2: "; bvh->alloc2.print_statistics();
        }
        if (g_verbose >= 2)
          std::cout << BVH4Statistics(bvh).str();
      }
    };

    Builder* BVH4Triangle4BuilderFastNew  (void* bvh, Scene* scene, size_t mode) { return new class BVH4Triangle4BuilderFastClass((BVH4*)bvh,scene); }
  }
}
<|endoftext|>


<commit_before>/* contactsconfig.cc			KPilot
**
** Copyright (C) 2008 by Bertjan Broeksema <b.broeksema@kdemail.net>
*/

/*
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
** the Free Software Foundation; either version 2.1 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser General Public License
** along with this program in a file called COPYING; if not, write to
** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
** MA 02110-1301, USA.
*/

/*
** Bug reports and questions can be sent to kde-pim@kde.org
*/

#include "contactsconfig.h"

#include <kaboutdata.h>

#include "akonadisetupwidget.h"
#include "options.h"
#include "contactssettings.h"

static KAboutData *createAbout()
{
	KAboutData *fAbout = new KAboutData( "To-do conduit", 0
		, ki18n( "To-do Conduit for KPilot" )
		, KPILOT_VERSION
		, ki18n( "Configures the To-do Conduit for KPilot" )
		, KAboutData::License_GPL
		, ki18n( "(C) 2008, Bertjan Broeksema" )
	);

	fAbout->addAuthor( ki18n( "Bertjan Broeksema" )
		, ki18n( "Rewrite and port to Akonadi and Base libraries" )
		, "b.broeksema@kdemail.net"
		, "http://bertjan.broeksemaatjes.nl"
	);

	fAbout->addCredit( ki18n( "Dan Pilone" ), ki18n( "Original author of the old conduit" ) );
	fAbout->addCredit( ki18n( "Preston Brown" ), ki18n( "Original author of the old conduit" ) );
	fAbout->addCredit( ki18n( "Herwin-Jan Steenhouwer" ), ki18n( "Original author of the old conduit" ) );
	fAbout->addCredit( ki18n( "Adriaan de Groot" ), ki18n( "Maintainer" ) );
	fAbout->addCredit( ki18n( "Reinhold Kainhofer" ), ki18n( "Maintainer" ) );

	return fAbout;
}

ContactsConfig::ContactsConfig( QWidget* w, const QVariantList& ) : ConduitConfigBase( w )
{
	FUNCTIONSETUP;

	fConduitName = i18n( "To-do" );
	fWidget = new QWidget( w );
	fUi.setupUi( fWidget );

	// Set up the akonadi tab.
	QWidget* akonadiTab = fUi.fTabWidget->widget( 0 );
	QStringList mimeTypes;
	mimeTypes << "text/directory" << "text/x-vcard" << "text/vcard";

	fAkonadiWidget = new AkonadiSetupWidget( akonadiTab );
	fAkonadiWidget->setCollectionLabel( i18n( "Select Addresbook: " ) );
	fAkonadiWidget->setMimeTypes( mimeTypes );

	fLayout = new QGridLayout( akonadiTab );
	fLayout->addWidget( fAkonadiWidget );

	connect( fAkonadiWidget, SIGNAL( collectionChanged() ), SLOT( modified() ) );

	// Add the about page.
	addAboutPage( fUi.fTabWidget, createAbout() );
}

ContactsConfig::~ContactsConfig()
{
}

void ContactsConfig::load()
{
	ContactsSettings::self()->readConfig();
	fAkonadiWidget->setCollection( ContactsSettings::akonadiCollection() );

	// General page
	//fConfigWidget->fArchive->setChecked(AbbrowserSettings::archiveDeleted());

	// Conflicts page
	//fUi.fConflictResolution->setCurrentItem(
	//  ContactsSettings::conflictResolution() - SyncAction::eCROffset );

	// Fields page
	fUi.fOtherPhone->setCurrentIndex( ContactsSettings::pilotOther() );
	fUi.fAddress->setCurrentIndex( ContactsSettings::pilotStreet() );
	fUi.fFax->setCurrentIndex( ContactsSettings::pilotFax() );

	// Custom fields page
	fUi.fCustom0->setCurrentIndex( ContactsSettings::custom0() );
	fUi.fCustom1->setCurrentIndex( ContactsSettings::custom1() );
	fUi.fCustom2->setCurrentIndex( ContactsSettings::custom2() );
	fUi.fCustom3->setCurrentIndex( ContactsSettings::custom3() );
	QString datefmt = ContactsSettings::customDateFormat();

	if( datefmt.isEmpty() )
	{
		fUi.fCustomDate->setCurrentIndex( 0 );
	}
	else
	{
		QAbstractItemModel* model = fUi.fCustomDate->model();
		QModelIndexList i = model->match( model->index( 0, 0 ), Qt::DisplayRole
			, QVariant( datefmt ), Qt::MatchCaseSensitive );
		fUi.fCustomDate->setCurrentIndex( i.first().row() );
	}

	unmodified();
}

void ContactsConfig::commit()
{
	// Akonadi page.
	// *Only* save the collection if the user selected another one.
	if( fAkonadiWidget->modified() )
	{
		ContactsSettings::setAkonadiCollection( fAkonadiWidget->collection() );
	}

	ContactsSettings::self()->writeConfig();
	unmodified();
}
<commit_msg>SVN_SILENT: Fix wrong conduit name.<commit_after>/* contactsconfig.cc			KPilot
**
** Copyright (C) 2008 by Bertjan Broeksema <b.broeksema@kdemail.net>
*/

/*
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
** the Free Software Foundation; either version 2.1 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser General Public License
** along with this program in a file called COPYING; if not, write to
** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
** MA 02110-1301, USA.
*/

/*
** Bug reports and questions can be sent to kde-pim@kde.org
*/

#include "contactsconfig.h"

#include <kaboutdata.h>

#include "akonadisetupwidget.h"
#include "options.h"
#include "contactssettings.h"

static KAboutData *createAbout()
{
	KAboutData *fAbout = new KAboutData( "To-do conduit", 0
		, ki18n( "To-do Conduit for KPilot" )
		, KPILOT_VERSION
		, ki18n( "Configures the To-do Conduit for KPilot" )
		, KAboutData::License_GPL
		, ki18n( "(C) 2008, Bertjan Broeksema" )
	);

	fAbout->addAuthor( ki18n( "Bertjan Broeksema" )
		, ki18n( "Rewrite and port to Akonadi and Base libraries" )
		, "b.broeksema@kdemail.net"
		, "http://bertjan.broeksemaatjes.nl"
	);

	fAbout->addCredit( ki18n( "Dan Pilone" ), ki18n( "Original author of the old conduit" ) );
	fAbout->addCredit( ki18n( "Preston Brown" ), ki18n( "Original author of the old conduit" ) );
	fAbout->addCredit( ki18n( "Herwin-Jan Steenhouwer" ), ki18n( "Original author of the old conduit" ) );
	fAbout->addCredit( ki18n( "Adriaan de Groot" ), ki18n( "Maintainer" ) );
	fAbout->addCredit( ki18n( "Reinhold Kainhofer" ), ki18n( "Maintainer" ) );

	return fAbout;
}

ContactsConfig::ContactsConfig( QWidget* w, const QVariantList& ) : ConduitConfigBase( w )
{
	FUNCTIONSETUP;

	fConduitName = i18n( "Contacts" );
	fWidget = new QWidget( w );
	fUi.setupUi( fWidget );

	// Set up the akonadi tab.
	QWidget* akonadiTab = fUi.fTabWidget->widget( 0 );
	QStringList mimeTypes;
	mimeTypes << "text/directory" << "text/x-vcard" << "text/vcard";

	fAkonadiWidget = new AkonadiSetupWidget( akonadiTab );
	fAkonadiWidget->setCollectionLabel( i18n( "Select Addresbook: " ) );
	fAkonadiWidget->setMimeTypes( mimeTypes );

	fLayout = new QGridLayout( akonadiTab );
	fLayout->addWidget( fAkonadiWidget );

	connect( fAkonadiWidget, SIGNAL( collectionChanged() ), SLOT( modified() ) );

	// Add the about page.
	addAboutPage( fUi.fTabWidget, createAbout() );
}

ContactsConfig::~ContactsConfig()
{
}

void ContactsConfig::load()
{
	ContactsSettings::self()->readConfig();
	fAkonadiWidget->setCollection( ContactsSettings::akonadiCollection() );

	// General page
	//fConfigWidget->fArchive->setChecked(AbbrowserSettings::archiveDeleted());

	// Conflicts page
	//fUi.fConflictResolution->setCurrentItem(
	//  ContactsSettings::conflictResolution() - SyncAction::eCROffset );

	// Fields page
	fUi.fOtherPhone->setCurrentIndex( ContactsSettings::pilotOther() );
	fUi.fAddress->setCurrentIndex( ContactsSettings::pilotStreet() );
	fUi.fFax->setCurrentIndex( ContactsSettings::pilotFax() );

	// Custom fields page
	fUi.fCustom0->setCurrentIndex( ContactsSettings::custom0() );
	fUi.fCustom1->setCurrentIndex( ContactsSettings::custom1() );
	fUi.fCustom2->setCurrentIndex( ContactsSettings::custom2() );
	fUi.fCustom3->setCurrentIndex( ContactsSettings::custom3() );
	QString datefmt = ContactsSettings::customDateFormat();

	if( datefmt.isEmpty() )
	{
		fUi.fCustomDate->setCurrentIndex( 0 );
	}
	else
	{
		QAbstractItemModel* model = fUi.fCustomDate->model();
		QModelIndexList i = model->match( model->index( 0, 0 ), Qt::DisplayRole
			, QVariant( datefmt ), Qt::MatchCaseSensitive );
		fUi.fCustomDate->setCurrentIndex( i.first().row() );
	}

	unmodified();
}

void ContactsConfig::commit()
{
	// Akonadi page.
	// *Only* save the collection if the user selected another one.
	if( fAkonadiWidget->modified() )
	{
		ContactsSettings::setAkonadiCollection( fAkonadiWidget->collection() );
	}

	ContactsSettings::self()->writeConfig();
	unmodified();
}
<|endoftext|>


<commit_before>#include <QtGui/QApplication>
#include <QtCore/QDir>
#include <QtCore/QFile>
#include "MainWindow.h"
#include "Settings.h"

#ifdef WIN32
#include <windows.h>
BOOL WINAPI my_handler(DWORD signal)
{
    if (signal == CTRL_C_EVENT)
	{
        printf("\nCtrl-C caught! Quitting application...\n");
		QApplication::quit();
	}
    return TRUE;
}
#else
#include <signal.h>
void my_handler(int s)
{
	printf("\nCtrl-C caught! Quitting application...\n");
	QApplication::quit();
}
#endif

void showUsage()
{
	printf("\nUsage:\n"
#ifdef WIN32
			"  Find-Object.exe [options]\n"
#else
			"  find_object [options]\n"
#endif
			"Options:\n"
			"  -console          Don't use the GUI (by default the camera will be\n"
			"                    started automatically). Option -objs must also be\n"
			"                    used with valid objects.\n"
			"  -objs \"path\"      Directory of the objects to detect.\n"
			"  -config \"path\"    Path to configuration file (default: %s).\n"
			"  -help or --help   Show usage.\n", Settings::iniDefaultPath().toStdString().c_str());
	exit(-1);
}

int main(int argc, char* argv[])
{
	QApplication app(argc, argv);

	// parse options
	bool guiMode = true;
	QString objectsPath = "";
	QString configPath = Settings::iniDefaultPath();

	for(int i=1; i<argc; ++i)
	{
		if(strcmp(argv[i], "-objs") == 0)
		{
			++i;
			if(i < argc)
			{
				objectsPath = argv[i];
				if(objectsPath.contains('~'))
				{
					objectsPath.replace('~', QDir::homePath());
				}
				if(!QDir(objectsPath).exists())
				{
					printf("[ERROR] Path not valid : %s\n", objectsPath.toStdString().c_str());
					showUsage();
				}
			}
			else
			{
				showUsage();
			}
			continue;
		}
		if(strcmp(argv[i], "-config") == 0)
		{
			++i;
			if(i < argc)
			{
				configPath = argv[i];
				if(configPath.contains('~'))
				{
					configPath.replace('~', QDir::homePath());
				}
				if(!QFile::exists(configPath))
				{
					printf("[ERROR] Configuration file doesn't exist : %s\n", configPath.toStdString().c_str());
					showUsage();
				}
			}
			else
			{
				showUsage();
			}
			continue;
		}
		if(strcmp(argv[i], "-console") == 0)
		{
			guiMode = false;
			continue;
		}
		if(strcmp(argv[i], "-help") == 0 || strcmp(argv[i], "--help") == 0)
		{
			showUsage();
		}

		printf("[ERROR] Unrecognized option : %s\n", argv[i]);
		showUsage();
	}

	printf("Options:\n");
	printf("   GUI mode = %s\n", guiMode?"true":false);
	printf("   Objects path: \"%s\"\n", objectsPath.toStdString().c_str());
	printf("   Settings path: \"%s\"\n", configPath.toStdString().c_str());

	MainWindow mainWindow(0, configPath);

	int objectsLoaded = 0;
	if(!objectsPath.isEmpty())
	{
		objectsLoaded = mainWindow.loadObjects(objectsPath);
		if(!objectsLoaded)
		{
			printf("[WARNING] No objects loaded from \"%s\"\n", objectsPath.toStdString().c_str());
		}
	}

	if(objectsLoaded == 0 && !guiMode)
	{
		printf("[ERROR] In console mode, at least one object must be loaded! See -console option.\n");
		showUsage();
	}

	if(guiMode)
	{
		app.connect( &app, SIGNAL( lastWindowClosed() ), &app, SLOT( quit() ) );
		mainWindow.show();
	}
	else
	{
		mainWindow.startProcessing();
	}

	if(!guiMode)
	{
		// Catch ctrl-c to close the gui
#ifdef WIN32
		if (!SetConsoleCtrlHandler(my_handler, TRUE))
		{
			printf("\nERROR: Could not set control handler");
			return 1;
		}
#else
		struct sigaction sigIntHandler;
		sigIntHandler.sa_handler = my_handler;
		sigemptyset(&sigIntHandler.sa_mask);
		sigIntHandler.sa_flags = 0;
		sigaction(SIGINT, &sigIntHandler, NULL);
#endif
	}

    return app.exec();
}
<commit_msg>fixed typo<commit_after>#include <QtGui/QApplication>
#include <QtCore/QDir>
#include <QtCore/QFile>
#include "MainWindow.h"
#include "Settings.h"

#ifdef WIN32
#include <windows.h>
BOOL WINAPI my_handler(DWORD signal)
{
    if (signal == CTRL_C_EVENT)
	{
        printf("\nCtrl-C caught! Quitting application...\n");
		QApplication::quit();
	}
    return TRUE;
}
#else
#include <signal.h>
void my_handler(int s)
{
	printf("\nCtrl-C caught! Quitting application...\n");
	QApplication::quit();
}
#endif

void showUsage()
{
	printf("\nUsage:\n"
#ifdef WIN32
			"  Find-Object.exe [options]\n"
#else
			"  find_object [options]\n"
#endif
			"Options:\n"
			"  -console          Don't use the GUI (by default the camera will be\n"
			"                    started automatically). Option -objs must also be\n"
			"                    used with valid objects.\n"
			"  -objs \"path\"      Directory of the objects to detect.\n"
			"  -config \"path\"    Path to configuration file (default: %s).\n"
			"  -help or --help   Show usage.\n", Settings::iniDefaultPath().toStdString().c_str());
	exit(-1);
}

int main(int argc, char* argv[])
{
	QApplication app(argc, argv);

	// parse options
	bool guiMode = true;
	QString objectsPath = "";
	QString configPath = Settings::iniDefaultPath();

	for(int i=1; i<argc; ++i)
	{
		if(strcmp(argv[i], "-objs") == 0)
		{
			++i;
			if(i < argc)
			{
				objectsPath = argv[i];
				if(objectsPath.contains('~'))
				{
					objectsPath.replace('~', QDir::homePath());
				}
				if(!QDir(objectsPath).exists())
				{
					printf("[ERROR] Path not valid : %s\n", objectsPath.toStdString().c_str());
					showUsage();
				}
			}
			else
			{
				showUsage();
			}
			continue;
		}
		if(strcmp(argv[i], "-config") == 0)
		{
			++i;
			if(i < argc)
			{
				configPath = argv[i];
				if(configPath.contains('~'))
				{
					configPath.replace('~', QDir::homePath());
				}
				if(!QFile::exists(configPath))
				{
					printf("[ERROR] Configuration file doesn't exist : %s\n", configPath.toStdString().c_str());
					showUsage();
				}
			}
			else
			{
				showUsage();
			}
			continue;
		}
		if(strcmp(argv[i], "-console") == 0)
		{
			guiMode = false;
			continue;
		}
		if(strcmp(argv[i], "-help") == 0 || strcmp(argv[i], "--help") == 0)
		{
			showUsage();
		}

		printf("[ERROR] Unrecognized option : %s\n", argv[i]);
		showUsage();
	}

	printf("Options:\n");
	printf("   GUI mode = %s\n", guiMode?"true":"false");
	printf("   Objects path: \"%s\"\n", objectsPath.toStdString().c_str());
	printf("   Settings path: \"%s\"\n", configPath.toStdString().c_str());

	MainWindow mainWindow(0, configPath);

	int objectsLoaded = 0;
	if(!objectsPath.isEmpty())
	{
		objectsLoaded = mainWindow.loadObjects(objectsPath);
		if(!objectsLoaded)
		{
			printf("[WARNING] No objects loaded from \"%s\"\n", objectsPath.toStdString().c_str());
		}
	}

	if(objectsLoaded == 0 && !guiMode)
	{
		printf("[ERROR] In console mode, at least one object must be loaded! See -console option.\n");
		showUsage();
	}

	if(guiMode)
	{
		app.connect( &app, SIGNAL( lastWindowClosed() ), &app, SLOT( quit() ) );
		mainWindow.show();
	}
	else
	{
		mainWindow.startProcessing();
	}

	if(!guiMode)
	{
		// Catch ctrl-c to close the gui
#ifdef WIN32
		if (!SetConsoleCtrlHandler(my_handler, TRUE))
		{
			printf("\nERROR: Could not set control handler");
			return 1;
		}
#else
		struct sigaction sigIntHandler;
		sigIntHandler.sa_handler = my_handler;
		sigemptyset(&sigIntHandler.sa_mask);
		sigIntHandler.sa_flags = 0;
		sigaction(SIGINT, &sigIntHandler, NULL);
#endif
	}

    return app.exec();
}
<|endoftext|>


<commit_before>#ifndef QUAD_TREE_HPP
#define QUAD_TREE_HPP

#include <map>
#include <vector>

struct Rectangle
{
	std::size_t topLeftX;
	std::size_t topLeftY;
	std::size_t width;
	std::size_t height;
};

class QuadTree
{
	public:
		QuadTree(std::size_t tlx, std::size_t tly, std::size_t w, std::size_t h);
		~QuadTree();

		void add(const Rectangle& rect);

	private:
		enum class Corner
		{
			TopLeft,
			TopRight,
			BotRight,
			BotLeft,
			Parent,
		};

		Corner index(const Rectangle& rect);
		void split();

		static constexpr std::size_t maxObjects = 4;

		std::size_t topLeftX;
		std::size_t topLeftY;
		std::size_t width;
		std::size_t height;

		// 0 = top left, 1 = top right, 2 = bottom right, 3 = bottom left
		std::map<Corner, QuadTree> children;

		std::vector<const Rectangle&> objects;
};

#endif
<commit_msg>Moved some stuff around.<commit_after>#ifndef QUAD_TREE_HPP
#define QUAD_TREE_HPP

#include <functional>
#include <map>
#include <vector>

struct Rectangle
{
	std::size_t topLeftX;
	std::size_t topLeftY;
	std::size_t width;
	std::size_t height;
};

class QuadTree
{
	public:
		using ObjectsArray = std::vector<std::reference_wrapper<const Rectangle>>;

		QuadTree();
		QuadTree(std::size_t w, std::size_t h);
		QuadTree(std::size_t tlx, std::size_t tly, std::size_t w, std::size_t h);

		void add(const Rectangle& rect);

		ObjectsArray& objects();

	private:
		enum class Corner : std::size_t
		{
			TopLeft,
			TopRight,
			BotRight,
			BotLeft,
			Parent,
		};

		Corner index(const Rectangle& rect);
		void split();

		static constexpr std::size_t maxObjects = 4;

		std::size_t topLeftX;
		std::size_t topLeftY;
		std::size_t width;
		std::size_t height;

		// 0 = top left, 1 = top right, 2 = bottom right, 3 = bottom left
		std::map<Corner, QuadTree> children;

		ObjectsArray objectsArr;
};

#endif
<|endoftext|>


<commit_before>#include "catch.hpp"

// mapnik vector tile
#include "vector_tile_datasource_pbf.hpp"

// libprotobuf
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#pragma GCC diagnostic ignored "-Wsign-conversion"
#include "vector_tile.pb.h"
#pragma GCC diagnostic pop

TEST_CASE( "cannot create datasource from layer pbf without name" )
{
    unsigned tile_size = 256;

    vector_tile::Tile_Layer layer;

    std::string buffer;
    layer.SerializePartialToString(&buffer);
    protozero::pbf_reader pbf_layer(buffer);

    CHECK_THROWS_AS(mapnik::vector_tile_impl::tile_datasource_pbf ds(pbf_layer,0,0,0,tile_size), std::runtime_error);
}
<commit_msg>Add tests for missing name<commit_after>#include "catch.hpp"

// mapnik vector tile
#include "vector_tile_datasource_pbf.hpp"
#include "vector_tile_projection.hpp"

// libprotobuf
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#pragma GCC diagnostic ignored "-Wsign-conversion"
#include "vector_tile.pb.h"
#pragma GCC diagnostic pop

// Boost
#include <boost/optional.hpp>

TEST_CASE( "cannot create datasource from layer pbf without name" )
{
    unsigned tile_size = 256;

    SECTION("VT Spec v1")
    {
        vector_tile::Tile_Layer layer;
        layer.set_version(1);

        std::string buffer;
        layer.SerializePartialToString(&buffer);
        protozero::pbf_reader pbf_layer(buffer);

        try
        {
            mapnik::vector_tile_impl::tile_datasource_pbf ds(pbf_layer,0,0,0,tile_size);
            FAIL( "expected exception" );
        }
        catch(std::exception const& ex)
        {
            CHECK(std::string(ex.what()) == "The required name field is missing in a vector tile layer.");
        }
    }

    SECTION("VT Spec v2")
    {
        vector_tile::Tile_Layer layer;
        layer.set_version(2);

        std::string buffer;
        layer.SerializePartialToString(&buffer);
        protozero::pbf_reader pbf_layer(buffer);

        try
        {
            mapnik::vector_tile_impl::tile_datasource_pbf ds(pbf_layer,0,0,0,tile_size);
            FAIL( "expected exception" );
        }
        catch(std::exception const& ex)
        {
            CHECK(std::string(ex.what()) == "The required name field is missing in a vector tile layer. Tile does not comply with Version 2 of the Mapbox Vector Tile Specification.");
        }
    }
}

TEST_CASE( "can create datasource from layer pbf with name but without extent" )
{
    unsigned tile_size = 256;

    SECTION("VT Spec v1")
    {
        vector_tile::Tile_Layer layer;
        layer.set_version(1);
        layer.set_name("test_name");

        std::string buffer;
        layer.SerializePartialToString(&buffer);
        protozero::pbf_reader pbf_layer(buffer);

        mapnik::vector_tile_impl::tile_datasource_pbf ds(pbf_layer,0,0,0,tile_size);

        CHECK(ds.get_name() == "test_name");

        // Check that layer extent is the default 4096
        // by querying features? (Not sure what to do here)
    }

    SECTION("VT Spec v2")
    {
        vector_tile::Tile_Layer layer;
        layer.set_version(2);
        layer.set_name("test_name");

        std::string buffer;
        layer.SerializePartialToString(&buffer);
        protozero::pbf_reader pbf_layer(buffer);

        try
        {
            mapnik::vector_tile_impl::tile_datasource_pbf ds(pbf_layer,0,0,0,tile_size);
            FAIL( "expected exception" );
        }
        catch(std::exception const& ex)
        {
            CHECK(std::string(ex.what()) == "The required extent field is missing in the layer test_name. Tile does not comply with Version 2 of the Mapbox Vector Tile Specification.");
        }
    }
}

TEST_CASE( "can create datasource from layer pbf with name but and extent" )
{
    unsigned tile_size = 256;

    SECTION("VT Spec v1")
    {
        vector_tile::Tile_Layer layer;
        layer.set_version(1);
        layer.set_name("test_name");
        layer.set_extent(2048);

        std::string buffer;
        layer.SerializePartialToString(&buffer);
        protozero::pbf_reader pbf_layer(buffer);

        mapnik::vector_tile_impl::tile_datasource_pbf ds(pbf_layer,0,0,0,tile_size);

        CHECK(ds.get_name() == "test_name");

        // Check that extent is 2048
        // by querying features? (Not sure what to do here)
    }

    SECTION("VT Spec v2")
    {
        vector_tile::Tile_Layer layer;
        layer.set_version(2);
        layer.set_name("test_name");
        layer.set_extent(2048);

        std::string buffer;
        layer.SerializePartialToString(&buffer);
        protozero::pbf_reader pbf_layer(buffer);

        mapnik::vector_tile_impl::tile_datasource_pbf ds(pbf_layer,0,0,0,tile_size);

        CHECK(ds.get_name() == "test_name");

        // Check that extent is 2048
        // by querying features? (Not sure what to do here)
    }
}
<|endoftext|>


<commit_before>#pragma once

#include "../parse/jsd_core.hpp"

#include <stdexcept>
#include <type_traits>
#include <functional>
#include <iostream>

#include <boost/version.hpp>

#ifndef BOOST_VERSION
#   error "BOOST_VERSION macro undefined, even though boost/version.hpp is included (broken boost installation?)"
#endif // BOOST_VERSION

#if BOOST_VERSION < 105600 && !defined(__BORLANDC__)
#   warning "Polymorphic adaptation is disabled, because the boost version is too old."
#   define DISABLE_POLY_JSON
#else
#   include <boost/type_index.hpp>
#   include <boost/preprocessor/seq/enum.hpp>
#   include "tmp_util/fundamental/pack.hpp"
#endif // BOOST_VERSION

#ifdef __BORLANDC__
#	include <boost/algorithm/string/replace.hpp>
#endif

/**
 *  WARNING! This does not work if you can construct a polymorphic type with the base class.
 *  This only works with abstract base classes or interfaces.
 *  This restriction is not made here explicitly (using static_assert), because you could still
 *  not instantiate the base by choice, even though it is not abstract.
 */

namespace JSON
{
    struct no_poly;

    template <typename T>
    struct polydecls
    {
        using type = no_poly;
    };

    template <typename T>
    struct is_polydecl
    {
        static constexpr bool const value = !std::is_same <typename polydecls <T>::type, no_poly>::value;
	};

#ifndef DISABLE_POLY_JSON
	template <typename T>
	std::string type_name_factory()
	{
#if defined(JSON_TYPENAME_PATCH)
		return JSONPatch::type_name_factory <T>();
#elif defined(__BORLANDC__)
        auto name = boost::typeindex::type_id_with_cvr <T>().pretty_name();
		boost::replace_all(name, "@", "::");
        return name.substr(1, name.length() - 1);
#else
		return boost::typeindex::type_id_with_cvr <T>().pretty_name();
#endif
    }

    template <typename BaseT, typename PackT>
	struct dyn_cast_test {};

    template <typename BaseT, typename Head, typename... Tail>
    struct dyn_cast_test <BaseT, pack<Head, Tail...>>
    {
        static bool is_exact_type(BaseT const* poly_ptr)
        {
            return (dynamic_cast <Head const*> (poly_ptr) != nullptr);
        }
        static std::string find_type(BaseT const* poly_ptr)
        {
            if (!is_exact_type(poly_ptr))
                return dyn_cast_test <BaseT, pack<Tail...>>::find_type(poly_ptr);
            else
				return type_name_factory <Head>();
        }
        static BaseT* create(std::string const& type_name)
        {
			if (type_name_factory <Head>() == type_name)
            {
                return new Head;
            }
            else
                return dyn_cast_test <BaseT, pack<Tail...>>::create(type_name);
        }
        template <template <typename...> class T, typename... List> \
        static void smart_pointer_get(T<List...>& smart, std::string const& type_name, std::string const& name,\
                                      PropertyTree const& tree, ParsingOptions const& options)
		{
			if (type_name_factory <Head>() == type_name)
			{
                smart.reset(new Head);
                //static_cast <Head*> (smart.get())->Head::parse(name, tree, options);
                dynamic_cast <Head*> (smart.get())->Head::parse(name, tree, options);
            }
            else
                dyn_cast_test <BaseT, pack<Tail...>>::smart_pointer_get(smart, type_name, name, tree, options);
        }
        template <template <typename...> class T, typename... List>
        static void smart_pointer_set(T<List...> const& smart, std::ostream& stream, StringificationOptions const& options)
        {
            if (is_exact_type(smart.get()))
            {
                //static_cast <Head*> (smart.get())->template stringify <BaseT>(stream, options);
                dynamic_cast <Head*> (smart.get())->template stringify <BaseT>(stream, options);
            }
            else {
                dyn_cast_test <BaseT, pack<Tail...>>::smart_pointer_set(smart, stream, options);
            }
        }
    };

    template <typename BaseT>
    struct dyn_cast_test <BaseT, pack <>>
    {
        static std::string find_type(BaseT const*)
        {
            throw std::runtime_error("dynamic cast cannot find any subclass");
        }
        static BaseT* create(std::string const&)
        {
            throw std::runtime_error("subclass not found, could not instantiate type with given type");
        }
        template <template <typename...> class T, typename... List>
        static void smart_pointer_get(T<List...>&, std::string const&, std::string const&,
                                      PropertyTree const&, ParsingOptions const&)
        {
            throw std::runtime_error("subclass not found, could not reset smart pointer with given type");
        }
        template <template <typename...> class T, typename... List>
        static void smart_pointer_set(T<List...> const&, std::ostream&, StringificationOptions const&)
        {
            throw std::runtime_error("subclass not found, could not find stringify function");
        }
    };
}

#define JSON_DECLARE_POLYMORPHIC(interface, deriv_sequence) \
namespace JSON \
{ \
    template <> \
    struct polydecls <interface> \
    { \
        using type = pack <\
            BOOST_PP_SEQ_ENUM(deriv_sequence) \
        >; \
        \
        static std::string identify_type(interface const* poly_ptr) \
        { \
            return dyn_cast_test <interface, type>::find_type(poly_ptr); \
        } \
        \
        template <typename U> \
        static interface* create(std::string const& type_name) \
        { \
            return dyn_cast_test <interface, type>::create(type_name); \
        } \
        \
        template <template <typename...> class T, typename... List> \
        static void smart_pointer_get(T<List...>& smart, std::string const& type_name, std::string const& name,\
                                      PropertyTree const& tree, ParsingOptions const& options) \
        { \
            dyn_cast_test <interface, type>::smart_pointer_get(smart, type_name, name, tree, options); \
        } \
        \
        template <template <typename...> class T, typename... List> \
        static void smart_pointer_set(T<List...> const& smart, std::ostream& stream, StringificationOptions const& options) \
        { \
            dyn_cast_test <interface, type>::smart_pointer_set(smart, stream, options); \
        } \
    }; \
}
#else
}
#endif // DISABLE_POLY_JSON
<commit_msg>Added option to disable warning, since it looks dirty.<commit_after>#pragma once

#include "../parse/jsd_core.hpp"

#include <stdexcept>
#include <type_traits>
#include <functional>
#include <iostream>

#include <boost/version.hpp>

#ifndef BOOST_VERSION
#   error "BOOST_VERSION macro undefined, even though boost/version.hpp is included (broken boost installation?)"
#endif // BOOST_VERSION

#if BOOST_VERSION < 105600 && !defined(__BORLANDC__) && !defined(JS_DISABLE_BOOST_WARNING)
#   warning "Polymorphic adaptation is disabled, because the boost version is too old."
#   define DISABLE_POLY_JSON
#else
#   include <boost/type_index.hpp>
#   include <boost/preprocessor/seq/enum.hpp>
#   include "tmp_util/fundamental/pack.hpp"
#endif // BOOST_VERSION

#ifdef __BORLANDC__
#	include <boost/algorithm/string/replace.hpp>
#endif

/**
 *  WARNING! This does not work if you can construct a polymorphic type with the base class.
 *  This only works with abstract base classes or interfaces.
 *  This restriction is not made here explicitly (using static_assert), because you could still
 *  not instantiate the base by choice, even though it is not abstract.
 */

namespace JSON
{
    struct no_poly;

    template <typename T>
    struct polydecls
    {
        using type = no_poly;
    };

    template <typename T>
    struct is_polydecl
    {
        static constexpr bool const value = !std::is_same <typename polydecls <T>::type, no_poly>::value;
	};

#ifndef DISABLE_POLY_JSON
	template <typename T>
	std::string type_name_factory()
	{
#if defined(JSON_TYPENAME_PATCH)
		return JSONPatch::type_name_factory <T>();
#elif defined(__BORLANDC__)
        auto name = boost::typeindex::type_id_with_cvr <T>().pretty_name();
		boost::replace_all(name, "@", "::");
        return name.substr(1, name.length() - 1);
#else
		return boost::typeindex::type_id_with_cvr <T>().pretty_name();
#endif
    }

    template <typename BaseT, typename PackT>
	struct dyn_cast_test {};

    template <typename BaseT, typename Head, typename... Tail>
    struct dyn_cast_test <BaseT, pack<Head, Tail...>>
    {
        static bool is_exact_type(BaseT const* poly_ptr)
        {
            return (dynamic_cast <Head const*> (poly_ptr) != nullptr);
        }
        static std::string find_type(BaseT const* poly_ptr)
        {
            if (!is_exact_type(poly_ptr))
                return dyn_cast_test <BaseT, pack<Tail...>>::find_type(poly_ptr);
            else
				return type_name_factory <Head>();
        }
        static BaseT* create(std::string const& type_name)
        {
			if (type_name_factory <Head>() == type_name)
            {
                return new Head;
            }
            else
                return dyn_cast_test <BaseT, pack<Tail...>>::create(type_name);
        }
        template <template <typename...> class T, typename... List> \
        static void smart_pointer_get(T<List...>& smart, std::string const& type_name, std::string const& name,\
                                      PropertyTree const& tree, ParsingOptions const& options)
		{
			if (type_name_factory <Head>() == type_name)
			{
                smart.reset(new Head);
                //static_cast <Head*> (smart.get())->Head::parse(name, tree, options);
                dynamic_cast <Head*> (smart.get())->Head::parse(name, tree, options);
            }
            else
                dyn_cast_test <BaseT, pack<Tail...>>::smart_pointer_get(smart, type_name, name, tree, options);
        }
        template <template <typename...> class T, typename... List>
        static void smart_pointer_set(T<List...> const& smart, std::ostream& stream, StringificationOptions const& options)
        {
            if (is_exact_type(smart.get()))
            {
                //static_cast <Head*> (smart.get())->template stringify <BaseT>(stream, options);
                dynamic_cast <Head*> (smart.get())->template stringify <BaseT>(stream, options);
            }
            else {
                dyn_cast_test <BaseT, pack<Tail...>>::smart_pointer_set(smart, stream, options);
            }
        }
    };

    template <typename BaseT>
    struct dyn_cast_test <BaseT, pack <>>
    {
        static std::string find_type(BaseT const*)
        {
            throw std::runtime_error("dynamic cast cannot find any subclass");
        }
        static BaseT* create(std::string const&)
        {
            throw std::runtime_error("subclass not found, could not instantiate type with given type");
        }
        template <template <typename...> class T, typename... List>
        static void smart_pointer_get(T<List...>&, std::string const&, std::string const&,
                                      PropertyTree const&, ParsingOptions const&)
        {
            throw std::runtime_error("subclass not found, could not reset smart pointer with given type");
        }
        template <template <typename...> class T, typename... List>
        static void smart_pointer_set(T<List...> const&, std::ostream&, StringificationOptions const&)
        {
            throw std::runtime_error("subclass not found, could not find stringify function");
        }
    };
}

#define JSON_DECLARE_POLYMORPHIC(interface, deriv_sequence) \
namespace JSON \
{ \
    template <> \
    struct polydecls <interface> \
    { \
        using type = pack <\
            BOOST_PP_SEQ_ENUM(deriv_sequence) \
        >; \
        \
        static std::string identify_type(interface const* poly_ptr) \
        { \
            return dyn_cast_test <interface, type>::find_type(poly_ptr); \
        } \
        \
        template <typename U> \
        static interface* create(std::string const& type_name) \
        { \
            return dyn_cast_test <interface, type>::create(type_name); \
        } \
        \
        template <template <typename...> class T, typename... List> \
        static void smart_pointer_get(T<List...>& smart, std::string const& type_name, std::string const& name,\
                                      PropertyTree const& tree, ParsingOptions const& options) \
        { \
            dyn_cast_test <interface, type>::smart_pointer_get(smart, type_name, name, tree, options); \
        } \
        \
        template <template <typename...> class T, typename... List> \
        static void smart_pointer_set(T<List...> const& smart, std::ostream& stream, StringificationOptions const& options) \
        { \
            dyn_cast_test <interface, type>::smart_pointer_set(smart, stream, options); \
        } \
    }; \
}
#else
}
#endif // DISABLE_POLY_JSON
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2012, The University of Oxford
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 * 3. Neither the name of the University of Oxford nor the names of its
 *    contributors may be used to endorse or promote products derived from this
 *    software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include "apps/lib/oskar_settings_load_interferomter.h"
#include "sky/oskar_date_time_to_mjd.h"
#include "utility/oskar_log_error.h"

#include <QtCore/QSettings>
#include <QtCore/QByteArray>
#include <QtCore/QDateTime>
#include <QtCore/QVariant>
#include <QtCore/QDate>
#include <QtCore/QTime>
#include <QtCore/QString>

#include <cmath>
#include <cstdlib>
#include <cstring>

// local (private) methods
static int load_noise(oskar_SettingsSystemNoise* noise, const char* filename);
static int load_noise_freqs(oskar_SettingsSystemNoiseFreq* freq, QSettings& s);
static int load_noise_values(oskar_SettingsSystemNoiseValue* value, QSettings& s);
static int load_noise_type(oskar_SettingsSystemNoiseType* stddev, QSettings& s,
        const QString& name);
static void get_filename(char** filename, const QSettings& s, const QString& key,
        const QString& defaultValue = "");

extern "C"
int oskar_settings_load_interferometer(oskar_SettingsInterferometer* settings,
        const char* filename)
{
    QByteArray t;
    QSettings s(QString(filename), QSettings::IniFormat);

    s.beginGroup("interferometer");
    {
        settings->channel_bandwidth_hz = s.value("channel_bandwidth_hz").toDouble();
        settings->time_average_sec = s.value("time_average_sec", 0.0).toDouble();
        settings->num_vis_ave      = s.value("num_vis_ave", 1).toInt();
        settings->num_fringe_ave   = s.value("num_fringe_ave", 1).toInt();
        settings->use_common_sky   = s.value("use_common_sky", true).toBool();

        // Get output visibility file name.
        t = s.value("oskar_vis_filename", "").toByteArray();
        if (t.size() > 0)
        {
            settings->oskar_vis_filename = (char*)malloc(t.size() + 1);
            strcpy(settings->oskar_vis_filename, t.constData());
        }

        // Get output MS file name.
        t = s.value("ms_filename", "").toByteArray();
        if (t.size() > 0)
        {
            settings->ms_filename = (char*)malloc(t.size() + 1);
            strcpy(settings->ms_filename, t.constData());
        }

        settings->image_interferometer_output = s.value("image_output", false).toBool();
    }
    s.endGroup();

    // Range checks.
    if (settings->num_vis_ave <= 0) settings->num_vis_ave = 1;
    if (settings->num_fringe_ave <= 0) settings->num_fringe_ave = 1;

    int status = load_noise(&settings->noise, filename);
    if (status) return status;

    return OSKAR_SUCCESS;
}

static int load_noise(oskar_SettingsSystemNoise* noise, const char* filename)
{
    QByteArray t;
    QString temp;
    QSettings s(QString(filename), QSettings::IniFormat);
    int error = OSKAR_SUCCESS;

    s.beginGroup("interferometer");
    {
        s.beginGroup("noise");
        {
            /* Enable / disable */
            noise->enable = s.value("enable", false).toBool();

            /* Seed */
            temp = s.value("seed").toString().toUpper();
            noise->seed = (temp == "TIME" || temp.toInt() < 0) ?
                    (int)time(NULL) : temp.toInt();

            /* Load frequency settings */
            error = load_noise_freqs(&noise->freq, s);
            if (error) return error;

            /* Values */
            error = load_noise_values(&noise->value, s);
            if (error) return error;
        }
        s.endGroup(); // noise
    }
    s.endGroup(); // interferometer

    return error;
}

static int load_noise_freqs(oskar_SettingsSystemNoiseFreq* freq,
        QSettings& s)
{
    QString temp = s.value("freq", "T").toString().toUpper();
    if (temp.startsWith("T"))
        freq->specification = OSKAR_SYSTEM_NOISE_TELESCOPE_MODEL;
    else if (temp.startsWith("O"))
        freq->specification = OSKAR_SYSTEM_NOISE_OBS_SETTINGS;
    else if (temp.startsWith("D"))
        freq->specification = OSKAR_SYSTEM_NOISE_DATA_FILE;
    else if (temp.startsWith("R"))
        freq->specification = OSKAR_SYSTEM_NOISE_RANGE;
    else
        return OSKAR_ERR_SETTINGS_INTERFEROMETER_NOISE;

    s.beginGroup("freq");
    {
        get_filename(&freq->file, s, "file");
        s.beginGroup("range");
        {
            freq->number = s.value("number").toInt();
            freq->start  = s.value("start").toDouble();
            freq->inc    = s.value("inc").toDouble();
        }
        s.endGroup(); // range
    }
    s.endGroup(); // freq

    return OSKAR_SUCCESS;
}

static int load_noise_values(oskar_SettingsSystemNoiseValue* value,
        QSettings& s)
{
    int error = OSKAR_SUCCESS;

    QString temp = s.value("values", "TEL").toString().toUpper();
    if (temp.startsWith("TEL"))
        value->specification = OSKAR_SYSTEM_NOISE_TELESCOPE_MODEL;
    else if (temp.startsWith("R"))
        value->specification = OSKAR_SYSTEM_NOISE_RMS;
    else if (temp.startsWith("S"))
        value->specification = OSKAR_SYSTEM_NOISE_SENSITIVITY;
    else if(temp.startsWith("TEMP"))
        value->specification = OSKAR_SYSTEM_NOISE_SYS_TEMP;
    else
        return OSKAR_ERR_SETTINGS_INTERFEROMETER_NOISE;

    s.beginGroup("values");
    {
        error = load_noise_type(&value->rms, s, "rms");
        if (error) return error;

        error = load_noise_type(&value->sensitivity, s, "sensitivity");
        if (error) return error;

        s.beginGroup("components");
        {
            error = load_noise_type(&value->t_sys, s, "t_sys");
            if (error) return error;

            error = load_noise_type(&value->area, s, "area");
            if (error) return error;

            error = load_noise_type(&value->efficiency, s, "efficiency");
            if (value->efficiency.start < 0.0 || value->efficiency.start > 1.0)
                return OSKAR_ERR_SETTINGS_INTERFEROMETER;
            if (value->efficiency.end < 0.0 || value->efficiency.end > 1.0)
                 return OSKAR_ERR_SETTINGS_INTERFEROMETER;
            if (value->efficiency.start > value->efficiency.end)
                return OSKAR_ERR_SETTINGS_INTERFEROMETER;
            if (error) return error;
        }
        s.endGroup();
    }
    s.endGroup(); // spec

    return error;
}

static int load_noise_type(oskar_SettingsSystemNoiseType* type, QSettings& s,
        const QString& name)
{
    QString temp = s.value(name, "N").toString().toUpper();
    if (temp.startsWith("N"))
        type->override = OSKAR_SYSTEM_NOISE_NO_OVERRIDE;
    else if (temp.startsWith("D"))
        type->override = OSKAR_SYSTEM_NOISE_DATA_FILE;
    else if (temp.startsWith("R"))
        type->override = OSKAR_SYSTEM_NOISE_RANGE;
    else
        return OSKAR_ERR_SETTINGS_INTERFEROMETER_NOISE;

    s.beginGroup(name);
    {
        get_filename(&type->file, s, "file");
        type->start  = s.value("start").toDouble();
        type->end    = s.value("end").toDouble();
    }
    s.endGroup();

    return OSKAR_SUCCESS;
}

static void get_filename(char** filename, const QSettings& s,
        const QString& key, const QString& defaultValue)
{
    QByteArray t = s.value(key, defaultValue).toByteArray();
    if (t.size() > 0)
    {
        *filename = (char*)malloc(t.size() + 1);
        strcpy(*filename, t.constData());
    }
}
<commit_msg>Fixed noise loader for frequency range data<commit_after>/*
 * Copyright (c) 2012, The University of Oxford
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 * 3. Neither the name of the University of Oxford nor the names of its
 *    contributors may be used to endorse or promote products derived from this
 *    software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include "apps/lib/oskar_settings_load_interferomter.h"
#include "sky/oskar_date_time_to_mjd.h"
#include "utility/oskar_log_error.h"

#include <QtCore/QSettings>
#include <QtCore/QByteArray>
#include <QtCore/QDateTime>
#include <QtCore/QVariant>
#include <QtCore/QDate>
#include <QtCore/QTime>
#include <QtCore/QString>

#include <cmath>
#include <cstdlib>
#include <cstring>

// local (private) methods
static int load_noise(oskar_SettingsSystemNoise* noise, const char* filename);
static int load_noise_freqs(oskar_SettingsSystemNoiseFreq* freq, QSettings& s);
static int load_noise_values(oskar_SettingsSystemNoiseValue* value, QSettings& s);
static int load_noise_type(oskar_SettingsSystemNoiseType* stddev, QSettings& s,
        const QString& name);
static void get_filename(char** filename, const QSettings& s, const QString& key,
        const QString& defaultValue = "");

extern "C"
int oskar_settings_load_interferometer(oskar_SettingsInterferometer* settings,
        const char* filename)
{
    QByteArray t;
    QSettings s(QString(filename), QSettings::IniFormat);

    s.beginGroup("interferometer");
    {
        settings->channel_bandwidth_hz = s.value("channel_bandwidth_hz").toDouble();
        settings->time_average_sec = s.value("time_average_sec", 0.0).toDouble();
        settings->num_vis_ave      = s.value("num_vis_ave", 1).toInt();
        settings->num_fringe_ave   = s.value("num_fringe_ave", 1).toInt();
        settings->use_common_sky   = s.value("use_common_sky", true).toBool();

        // Get output visibility file name.
        t = s.value("oskar_vis_filename", "").toByteArray();
        if (t.size() > 0)
        {
            settings->oskar_vis_filename = (char*)malloc(t.size() + 1);
            strcpy(settings->oskar_vis_filename, t.constData());
        }

        // Get output MS file name.
        t = s.value("ms_filename", "").toByteArray();
        if (t.size() > 0)
        {
            settings->ms_filename = (char*)malloc(t.size() + 1);
            strcpy(settings->ms_filename, t.constData());
        }

        settings->image_interferometer_output = s.value("image_output", false).toBool();
    }
    s.endGroup();

    // Range checks.
    if (settings->num_vis_ave <= 0) settings->num_vis_ave = 1;
    if (settings->num_fringe_ave <= 0) settings->num_fringe_ave = 1;

    int status = load_noise(&settings->noise, filename);
    if (status) return status;

    return OSKAR_SUCCESS;
}

static int load_noise(oskar_SettingsSystemNoise* noise, const char* filename)
{
    QByteArray t;
    QString temp;
    QSettings s(QString(filename), QSettings::IniFormat);
    int error = OSKAR_SUCCESS;

    s.beginGroup("interferometer");
    {
        s.beginGroup("noise");
        {
            /* Enable / disable */
            noise->enable = s.value("enable", false).toBool();

            /* Seed */
            temp = s.value("seed").toString().toUpper();
            noise->seed = (temp == "TIME" || temp.toInt() < 0) ?
                    (int)time(NULL) : temp.toInt();

            /* Load frequency settings */
            error = load_noise_freqs(&noise->freq, s);
            if (error) return error;

            /* Values */
            error = load_noise_values(&noise->value, s);
            if (error) return error;
        }
        s.endGroup(); // noise
    }
    s.endGroup(); // interferometer

    return error;
}

static int load_noise_freqs(oskar_SettingsSystemNoiseFreq* freq,
        QSettings& s)
{
    QString temp = s.value("freq", "T").toString().toUpper();
    if (temp.startsWith("T"))
        freq->specification = OSKAR_SYSTEM_NOISE_TELESCOPE_MODEL;
    else if (temp.startsWith("O"))
        freq->specification = OSKAR_SYSTEM_NOISE_OBS_SETTINGS;
    else if (temp.startsWith("D"))
        freq->specification = OSKAR_SYSTEM_NOISE_DATA_FILE;
    else if (temp.startsWith("R"))
        freq->specification = OSKAR_SYSTEM_NOISE_RANGE;
    else
        return OSKAR_ERR_SETTINGS_INTERFEROMETER_NOISE;

    s.beginGroup("freq");
    {
        get_filename(&freq->file, s, "file");
        freq->number = s.value("number").toInt();
        freq->start  = s.value("start").toDouble();
        freq->inc    = s.value("inc").toDouble();
    }
    s.endGroup(); // freq

    return OSKAR_SUCCESS;
}

static int load_noise_values(oskar_SettingsSystemNoiseValue* value,
        QSettings& s)
{
    int error = OSKAR_SUCCESS;

    QString temp = s.value("values", "TEL").toString().toUpper();
    if (temp.startsWith("TEL"))
        value->specification = OSKAR_SYSTEM_NOISE_TELESCOPE_MODEL;
    else if (temp.startsWith("R"))
        value->specification = OSKAR_SYSTEM_NOISE_RMS;
    else if (temp.startsWith("S"))
        value->specification = OSKAR_SYSTEM_NOISE_SENSITIVITY;
    else if(temp.startsWith("TEMP"))
        value->specification = OSKAR_SYSTEM_NOISE_SYS_TEMP;
    else
        return OSKAR_ERR_SETTINGS_INTERFEROMETER_NOISE;

    s.beginGroup("values");
    {
        error = load_noise_type(&value->rms, s, "rms");
        if (error) return error;

        error = load_noise_type(&value->sensitivity, s, "sensitivity");
        if (error) return error;

        s.beginGroup("components");
        {
            error = load_noise_type(&value->t_sys, s, "t_sys");
            if (error) return error;

            error = load_noise_type(&value->area, s, "area");
            if (error) return error;

            error = load_noise_type(&value->efficiency, s, "efficiency");
            if (value->efficiency.start < 0.0 || value->efficiency.start > 1.0)
                return OSKAR_ERR_SETTINGS_INTERFEROMETER;
            if (value->efficiency.end < 0.0 || value->efficiency.end > 1.0)
                 return OSKAR_ERR_SETTINGS_INTERFEROMETER;
            if (value->efficiency.start > value->efficiency.end)
                return OSKAR_ERR_SETTINGS_INTERFEROMETER;
            if (error) return error;
        }
        s.endGroup();
    }
    s.endGroup(); // spec

    return error;
}

static int load_noise_type(oskar_SettingsSystemNoiseType* type, QSettings& s,
        const QString& name)
{
    QString temp = s.value(name, "N").toString().toUpper();
    if (temp.startsWith("N"))
        type->override = OSKAR_SYSTEM_NOISE_NO_OVERRIDE;
    else if (temp.startsWith("D"))
        type->override = OSKAR_SYSTEM_NOISE_DATA_FILE;
    else if (temp.startsWith("R"))
        type->override = OSKAR_SYSTEM_NOISE_RANGE;
    else
        return OSKAR_ERR_SETTINGS_INTERFEROMETER_NOISE;

    s.beginGroup(name);
    {
        get_filename(&type->file, s, "file");
        type->start  = s.value("start").toDouble();
        type->end    = s.value("end").toDouble();
    }
    s.endGroup();

    return OSKAR_SUCCESS;
}

static void get_filename(char** filename, const QSettings& s,
        const QString& key, const QString& defaultValue)
{
    QByteArray t = s.value(key, defaultValue).toByteArray();
    if (t.size() > 0)
    {
        *filename = (char*)malloc(t.size() + 1);
        strcpy(*filename, t.constData());
    }
}
<|endoftext|>


<commit_before>#include "common.h"
#include "PlayerController.h"
#include "EventManager.h"
#include "PositionComponent.h"
#include "OrientationComponent.h"
#include "BoundingComponent.h"
#include "ModelComponent.h"

void PlayerController::Init() {
	const std::vector<Triangle> triangles = {
		std::make_tuple(Point3(-0.375, -0.85,  0.25), Point3( 0.375, -0.85,  0.25), Point3(-0.375,  0.85,  0.25)),
		std::make_tuple(Point3( 0.375, -0.85,  0.25), Point3( 0.375,  0.85,  0.25), Point3(-0.375,  0.85,  0.25)),
		std::make_tuple(Point3(-0.375,  0.85,  0.25), Point3( 0.375,  0.85,  0.25), Point3(-0.375,  0.85, -0.25)),
		std::make_tuple(Point3( 0.375,  0.85,  0.25), Point3( 0.375,  0.85, -0.25), Point3(-0.375,  0.85, -0.25)),
		std::make_tuple(Point3(-0.375,  0.85, -0.25), Point3( 0.375,  0.85, -0.25), Point3(-0.375, -0.85, -0.25)),
		std::make_tuple(Point3( 0.375,  0.85, -0.25), Point3( 0.375, -0.85, -0.25), Point3(-0.375, -0.85, -0.25)),
		std::make_tuple(Point3(-0.375, -0.85, -0.25), Point3( 0.375, -0.85, -0.25), Point3(-0.375, -0.85,  0.25)),
		std::make_tuple(Point3( 0.375, -0.85, -0.25), Point3( 0.375, -0.85,  0.25), Point3(-0.375, -0.85,  0.25)),
		std::make_tuple(Point3( 0.375, -0.85,  0.25), Point3( 0.375, -0.85, -0.25), Point3( 0.375,  0.85,  0.25)),
		std::make_tuple(Point3( 0.375, -0.85, -0.25), Point3( 0.375,  0.85, -0.25), Point3( 0.375,  0.85,  0.25)),
		std::make_tuple(Point3(-0.375, -0.85, -0.25), Point3(-0.375, -0.85,  0.25), Point3(-0.375,  0.85, -0.25)),
		std::make_tuple(Point3(-0.375, -0.85,  0.25), Point3(-0.375,  0.85,  0.25), Point3(-0.375,  0.85, -0.25))
	};

	object = engine->AddObject();
	engine->AddComponent<PositionComponent>(object);
	engine->AddComponent<OrientationComponent>(object);
	engine->AddComponent<BoundingComponent>(object, Point3(-0.375f, -0.85f, -0.25f), Point3(0.75f, 1.7f, 0.5f));
	engine->AddComponent<ModelComponent>(object, triangles);
	InitObject();

	auto ownPos = engine->GetComponent<PositionComponent>(object);
	auto ownBounds = engine->GetComponent<BoundingComponent>(object);

	/* gravity */
	ownPos->position.Derivative(1) = Point3(0, -9.8f, 0);

	/* collision detection and response */
	engine->systems.Get<EventManager>()->ListenFor("integrator", "ticked", [this, ownPos, ownBounds] (Arg delta) {
		auto &prev = ownPos->position.GetPrevious();
		auto &curr = *ownPos->position;
		auto &vel = *ownPos->position.Derivative();

		Point3 normal;
		float entryTime = 0.0f;

		auto pair = engine->objects.right.equal_range(&typeid(BoundingComponent));

		/* loop until all collisions have been resolved */
		while(entryTime != 1.0f) {
			auto tickVel = vel * delta.float_;
			entryTime = 1.0f;

			/* find collision with soonest entry time */
			for(auto it = pair.first; it != pair.second; ++it) {
				auto id = it->get_left();

				/* don't check for collisions with self */
				if(id == object) { continue; }

				auto objPos = engine->GetComponent<PositionComponent>(id);
				if(objPos != nullptr) {
					auto objBounds = engine->GetComponent<BoundingComponent>(id);
					if(objBounds != nullptr) {
						auto r = ownBounds->box.AABBSwept(objBounds->box, std::make_tuple(prev, curr, tickVel), *objPos->position);
						if(std::get<0>(r) < entryTime) { std::tie(entryTime, normal) = r; }
					}
				}
			}

			/* respond to collision */
			if(entryTime < 1.0f) {
				/* project previous position to point of entry of collision */
				prev += tickVel * entryTime;

				/* project position onto surface by subtracting surface-to-end vector */
				curr -= normal * glm::dot(tickVel, normal);

				/* project velocity onto surface too
				 * y is given a bounce factor of 0.125
				 */
				vel -= normal * glm::dot(Point3(vel.x, vel.y * 1.125f, vel.z), normal);
			}
		}
	});
}

void PlayerController::Update(DeltaTicks &dt) {
	auto ownPos = engine->GetComponent<PositionComponent>(object);
	auto ownOrient = engine->GetComponent<OrientationComponent>(object);

	auto rel = glm::normalize(Point4((moveLeft ? -1 : 0) + (moveRight ? 1 : 0), 0, (moveForward ? -1 : 0) + (moveBackward ? 1 : 0), 1));
	auto abs = (glm::inverse(ownOrient->orientation) * rel) * 3.5f;

	ownPos->position.Derivative()->x = abs.x;
	//pos->position.Derivative()->y = abs.y;
	ownPos->position.Derivative()->z = abs.z;
}
<commit_msg>Crack the crack problem once and for all<commit_after>#include "common.h"
#include "PlayerController.h"
#include "EventManager.h"
#include "PositionComponent.h"
#include "OrientationComponent.h"
#include "BoundingComponent.h"
#include "ModelComponent.h"

void PlayerController::Init() {
	const std::vector<Triangle> triangles = {
		std::make_tuple(Point3(-0.375, -0.85,  0.25), Point3( 0.375, -0.85,  0.25), Point3(-0.375,  0.85,  0.25)),
		std::make_tuple(Point3( 0.375, -0.85,  0.25), Point3( 0.375,  0.85,  0.25), Point3(-0.375,  0.85,  0.25)),
		std::make_tuple(Point3(-0.375,  0.85,  0.25), Point3( 0.375,  0.85,  0.25), Point3(-0.375,  0.85, -0.25)),
		std::make_tuple(Point3( 0.375,  0.85,  0.25), Point3( 0.375,  0.85, -0.25), Point3(-0.375,  0.85, -0.25)),
		std::make_tuple(Point3(-0.375,  0.85, -0.25), Point3( 0.375,  0.85, -0.25), Point3(-0.375, -0.85, -0.25)),
		std::make_tuple(Point3( 0.375,  0.85, -0.25), Point3( 0.375, -0.85, -0.25), Point3(-0.375, -0.85, -0.25)),
		std::make_tuple(Point3(-0.375, -0.85, -0.25), Point3( 0.375, -0.85, -0.25), Point3(-0.375, -0.85,  0.25)),
		std::make_tuple(Point3( 0.375, -0.85, -0.25), Point3( 0.375, -0.85,  0.25), Point3(-0.375, -0.85,  0.25)),
		std::make_tuple(Point3( 0.375, -0.85,  0.25), Point3( 0.375, -0.85, -0.25), Point3( 0.375,  0.85,  0.25)),
		std::make_tuple(Point3( 0.375, -0.85, -0.25), Point3( 0.375,  0.85, -0.25), Point3( 0.375,  0.85,  0.25)),
		std::make_tuple(Point3(-0.375, -0.85, -0.25), Point3(-0.375, -0.85,  0.25), Point3(-0.375,  0.85, -0.25)),
		std::make_tuple(Point3(-0.375, -0.85,  0.25), Point3(-0.375,  0.85,  0.25), Point3(-0.375,  0.85, -0.25))
	};

	object = engine->AddObject();
	engine->AddComponent<PositionComponent>(object);
	engine->AddComponent<OrientationComponent>(object);
	engine->AddComponent<BoundingComponent>(object, Point3(-0.375f, -0.85f, -0.25f), Point3(0.75f, 1.7f, 0.5f));
	engine->AddComponent<ModelComponent>(object, triangles);
	InitObject();

	auto ownPos = engine->GetComponent<PositionComponent>(object);
	auto ownBounds = engine->GetComponent<BoundingComponent>(object);

	/* gravity */
	ownPos->position.Derivative(1) = Point3(0, -9.8f, 0);

	/* collision detection and response */
	engine->systems.Get<EventManager>()->ListenFor("integrator", "ticked", [this, ownPos, ownBounds] (Arg delta) {
		auto &prev = ownPos->position.GetPrevious();
		auto &curr = *ownPos->position;
		auto &vel = *ownPos->position.Derivative();

		Point3 normal;
		float entryTime = 0.0f;

		auto pair = engine->objects.right.equal_range(&typeid(BoundingComponent));

		/* loop until all collisions have been resolved */
		while(entryTime != 1.0f) {
			auto tickVel = vel * delta.float_;
			entryTime = 1.0f;

			/* find collision with soonest entry time */
			for(auto it = pair.first; it != pair.second; ++it) {
				auto id = it->get_left();

				/* don't check for collisions with self */
				if(id == object) { continue; }

				auto objPos = engine->GetComponent<PositionComponent>(id);
				if(objPos != nullptr) {
					auto objBounds = engine->GetComponent<BoundingComponent>(id);
					if(objBounds != nullptr) {
						auto r = ownBounds->box.AABBSwept(objBounds->box, std::make_tuple(prev, curr, tickVel), *objPos->position);
						if(std::get<0>(r) < entryTime) { std::tie(entryTime, normal) = r; }
					}
				}
			}

			if(entryTime < 1.0f) {
				/* project velocity onto surface of collider (impulse)
				* y is given a bounce factor of 0.125
				*/
				vel -= normal * glm::dot(Point3(vel.x, vel.y * 1.125f, vel.z), normal);

				/* set current position to just before point of entry */
				curr = prev + tickVel * (entryTime - 0.0001f);

				/* set previous position to here too */
				prev += tickVel * entryTime;

				/* slide current position along surface multiplied by remaining time */
				curr += vel * delta.float_ * (1.0f - entryTime);
			}
		}
	});
}

void PlayerController::Update(DeltaTicks &dt) {
	auto ownPos = engine->GetComponent<PositionComponent>(object);
	auto ownOrient = engine->GetComponent<OrientationComponent>(object);

	auto rel = glm::normalize(Point4((moveLeft ? -1 : 0) + (moveRight ? 1 : 0), 0, (moveForward ? -1 : 0) + (moveBackward ? 1 : 0), 1));
	auto abs = (glm::inverse(ownOrient->orientation) * rel) * 3.5f;

	ownPos->position.Derivative()->x = abs.x;
	//pos->position.Derivative()->y = abs.y;
	ownPos->position.Derivative()->z = abs.z;
}
<|endoftext|>