<commit_before>/*
 * Copyright 2009-2015 The VOTCA Development Team (http://www.votca.org)
 *
 * 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.
 *
 */

#ifndef HAVE_NO_CONFIG
#include <votca_config.h>
#endif

#include <iostream>
#include "gmxtopologyreader.h"

#include <gromacs/fileio/tpxio.h>
#include <gromacs/topology/atoms.h>
#include <gromacs/topology/topology.h>
#include <gromacs/mdtypes/inputrec.h>

// this one is needed because of bool is defined in one of the headers included by gmx
#undef bool

namespace votca { namespace csg {

bool GMXTopologyReader::ReadTopology(string file, Topology &top)
{
    gmx_mtop_t mtop;

    int natoms;
    // cleanup topology to store new data
    top.Cleanup();

    t_inputrec ir;
    ::matrix gbox;

    (void)read_tpx((char *)file.c_str(),&ir,gbox,&natoms,NULL,NULL,&mtop);

    int count=0;
    for(int iblock=0; iblock<mtop.nmolblock; ++iblock)
        count+=mtop.molblock[iblock].nmol;

    if(count != mtop.mols.nr  ) {
        throw runtime_error("gromacs topology contains inconsistency in molecule definitons\n\n"
                "A possible reason is an outdated .tpr file. Please rerun grompp to generate a new tpr file.\n"
                "If the problem remains or "
                "you're missing the files to rerun grompp,\n contact the votca mailing list for a solution.");
    }

    int ifirstatom = 0;
    for(int iblock=0; iblock<mtop.nmolblock; ++iblock) {
        gmx_moltype_t *mol
                = &(mtop.moltype[mtop.molblock[iblock].type]);

        string molname =  *(mol->name);

        int res_offset = top.ResidueCount();

        t_atoms *atoms=&(mol->atoms);

        for(int i=0; i < atoms->nres; i++) {
                top.CreateResidue(*(atoms->resinfo[i].name));
        }

        for(int imol=0; imol<mtop.molblock[iblock].nmol; ++imol) {
            Molecule *mi = top.CreateMolecule(molname);

            // read the atoms
            for(int iatom=0; iatom<mtop.molblock[iblock].natoms_mol; iatom++) {
                t_atom *a = &(atoms->atom[iatom]);

                BeadType *type = top.GetOrCreateBeadType(*(atoms->atomtype[iatom]));
                Bead *bead = top.CreateBead(1, *(atoms->atomname[iatom]), type, a->resind + res_offset, a->m, a->q);

                stringstream nm;
                nm << bead->getResnr() + 1 - res_offset << ":" <<  top.getResidue(bead->getResnr())->getName() << ":" << bead->getName();
                mi->AddBead(bead, nm.str());
            }

            // add exclusions
            for(int iatom=0; iatom<mtop.molblock[iblock].natoms_mol; iatom++) {
                // read exclusions
                t_blocka * excl = &(mol->excls);
                // insert exclusions
                list<Bead *> excl_list;
                for(int k=excl->index[iatom]; k<excl->index[iatom+1]; k++) {
                	excl_list.push_back(top.getBead(excl->a[k]+ifirstatom));
                }
                top.InsertExclusion(top.getBead(iatom+ifirstatom), excl_list);
            }
            ifirstatom+=mtop.molblock[iblock].natoms_mol;
        }
    }

    matrix m;
    for(int i=0; i<3; i++)
        for(int j=0; j<3; j++)
            m[i][j] = gbox[j][i];
    top.setBox(m);

    return true;
}

}}
<commit_msg>gmxtopologyreader: remove ancient warning about tpr<commit_after>/*
 * Copyright 2009-2015 The VOTCA Development Team (http://www.votca.org)
 *
 * 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.
 *
 */

#ifndef HAVE_NO_CONFIG
#include <votca_config.h>
#endif

#include <iostream>
#include "gmxtopologyreader.h"

#include <gromacs/fileio/tpxio.h>
#include <gromacs/topology/atoms.h>
#include <gromacs/topology/topology.h>
#include <gromacs/mdtypes/inputrec.h>

// this one is needed because of bool is defined in one of the headers included by gmx
#undef bool

namespace votca { namespace csg {

bool GMXTopologyReader::ReadTopology(string file, Topology &top)
{
    gmx_mtop_t mtop;

    int natoms;
    // cleanup topology to store new data
    top.Cleanup();

    t_inputrec ir;
    ::matrix gbox;

    (void)read_tpx((char *)file.c_str(),&ir,gbox,&natoms,NULL,NULL,&mtop);

    int count=0;
    for(int iblock=0; iblock<mtop.nmolblock; ++iblock)
        count+=mtop.molblock[iblock].nmol;

    int ifirstatom = 0;
    for(int iblock=0; iblock<mtop.nmolblock; ++iblock) {
        gmx_moltype_t *mol
                = &(mtop.moltype[mtop.molblock[iblock].type]);

        string molname =  *(mol->name);

        int res_offset = top.ResidueCount();

        t_atoms *atoms=&(mol->atoms);

        for(int i=0; i < atoms->nres; i++) {
                top.CreateResidue(*(atoms->resinfo[i].name));
        }

        for(int imol=0; imol<mtop.molblock[iblock].nmol; ++imol) {
            Molecule *mi = top.CreateMolecule(molname);

            // read the atoms
            for(int iatom=0; iatom<mtop.molblock[iblock].natoms_mol; iatom++) {
                t_atom *a = &(atoms->atom[iatom]);

                BeadType *type = top.GetOrCreateBeadType(*(atoms->atomtype[iatom]));
                Bead *bead = top.CreateBead(1, *(atoms->atomname[iatom]), type, a->resind + res_offset, a->m, a->q);

                stringstream nm;
                nm << bead->getResnr() + 1 - res_offset << ":" <<  top.getResidue(bead->getResnr())->getName() << ":" << bead->getName();
                mi->AddBead(bead, nm.str());
            }

            // add exclusions
            for(int iatom=0; iatom<mtop.molblock[iblock].natoms_mol; iatom++) {
                // read exclusions
                t_blocka * excl = &(mol->excls);
                // insert exclusions
                list<Bead *> excl_list;
                for(int k=excl->index[iatom]; k<excl->index[iatom+1]; k++) {
                	excl_list.push_back(top.getBead(excl->a[k]+ifirstatom));
                }
                top.InsertExclusion(top.getBead(iatom+ifirstatom), excl_list);
            }
            ifirstatom+=mtop.molblock[iblock].natoms_mol;
        }
    }

    matrix m;
    for(int i=0; i<3; i++)
        for(int j=0; j<3; j++)
            m[i][j] = gbox[j][i];
    top.setBox(m);

    return true;
}

}}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 * REALM CONFIDENTIAL
 * __________________
 *
 *  [2011] - [2015] Realm Inc
 *  All Rights Reserved.
 *
 * NOTICE:  All information contained herein is, and remains
 * the property of Realm Incorporated and its suppliers,
 * if any.  The intellectual and technical concepts contained
 * herein are proprietary to Realm Incorporated
 * and its suppliers and may be covered by U.S. and Foreign Patents,
 * patents in process, and are protected by trade secret or copyright law.
 * Dissemination of this information or reproduction of this material
 * is strictly forbidden unless prior written permission is obtained
 * from Realm Incorporated.
 *
 **************************************************************************/
#ifndef REALM_COLUMN_DATETIME_HPP
#define REALM_COLUMN_DATETIME_HPP

#include <realm/column.hpp>

namespace realm {

struct NewDate {
    NewDate(int64_t seconds, uint32_t nanoseconds) : m_seconds(seconds), m_nanoseconds(nanoseconds), m_is_null(false)
    {
        REALM_ASSERT_3(nanoseconds, <, 1000000000);
    }
    NewDate(const null&) : m_is_null(true) { }
    NewDate() : NewDate(null()) { }

    bool is_null() const { return m_is_null; }

    // Note that nullability is handeled by query system. These operators are only invoked for non-null dates.
    bool operator==(const NewDate& rhs) const { return m_seconds == rhs.m_seconds && m_nanoseconds == rhs.m_nanoseconds; }
    bool operator!=(const NewDate& rhs) const { return m_seconds != rhs.m_seconds || m_nanoseconds != rhs.m_nanoseconds; }
    bool operator>(const NewDate& rhs) const { return (m_seconds > rhs.m_seconds) || (m_seconds == rhs.m_seconds && m_nanoseconds > rhs.m_nanoseconds); }
    bool operator<(const NewDate& rhs) const { return (m_seconds < rhs.m_seconds) || (m_seconds == rhs.m_seconds && m_nanoseconds < rhs.m_nanoseconds); }
    bool operator<=(const NewDate& rhs) const { return *this < rhs || *this == rhs; }
    bool operator>=(const NewDate& rhs) const { return *this > rhs || *this == rhs; }
    NewDate& operator=(const NewDate& rhs) = default;

    template<class Ch, class Tr>
    friend std::basic_ostream<Ch, Tr>& operator<<(std::basic_ostream<Ch, Tr>& out, const NewDate&);

    int64_t m_seconds;
    uint32_t m_nanoseconds;
    bool m_is_null;
};

template<class C, class T>
inline std::basic_ostream<C, T>& operator<<(std::basic_ostream<C, T>& out, const NewDate& d)
{
    out << "NewDate(" << d.m_seconds << ", " << d.m_nanoseconds << ")";
    return out;
}

// Inherits from ColumnTemplate to get a compare_values() that can be called without knowing the
// column type
class DateTimeColumn : public ColumnBaseSimple, public ColumnTemplate<NewDate> {
public:
    DateTimeColumn(Allocator& alloc, ref_type ref);
    ~DateTimeColumn() noexcept override;

    static ref_type create(Allocator& alloc, size_t size = 0);

    /// Get the number of entries in this column. This operation is relatively
    /// slow.
    size_t size() const noexcept override;
    /// Whether or not this column is nullable.
    bool is_nullable() const noexcept override;
    /// Whether or not the value at \a row_ndx is NULL. If the column is not
    /// nullable, always returns false.
    bool is_null(size_t row_ndx) const noexcept override;
    /// Sets the value at \a row_ndx to be NULL.
    /// \throw LogicError Thrown if this column is not nullable.
    void set_null(size_t row_ndx) override;
    void insert_rows(size_t row_ndx, size_t num_rows_to_insert, size_t prior_num_rows, bool nullable) override;
    void erase_rows(size_t row_ndx, size_t num_rows_to_erase, size_t prior_num_rows,
                    bool broken_reciprocal_backlinks) override;
    void move_last_row_over(size_t row_ndx, size_t prior_num_rows,
                            bool broken_reciprocal_backlinks) override;
    void clear(size_t num_rows, bool broken_reciprocal_backlinks) override;
    void swap_rows(size_t row_ndx_1, size_t row_ndx_2) override;
    void destroy() noexcept override;
    StringData get_index_data(size_t, StringIndex::StringConversionBuffer& buffer) const noexcept override;
    MemRef clone_deep(Allocator& alloc) const override;
    ref_type write(size_t slice_offset, size_t slice_size, size_t table_size, _impl::OutputStream&) const override;
    void update_from_parent(size_t old_baseline) noexcept override;
    void refresh_accessor_tree(size_t new_col_ndx, const Spec&) override;
#ifdef REALM_DEBUG
    void verify() const override;
    void to_dot(std::ostream&, StringData title = StringData()) const override;
    void do_dump_node_structure(std::ostream&, int level) const override;
    void leaf_to_dot(MemRef, ArrayParent*, size_t ndx_in_parent, std::ostream&) const override;
#endif
    void add(const NewDate& ndt = NewDate{});
    NewDate get(size_t row_ndx) const noexcept;
    NewDate get_val(size_t row_ndx) const noexcept { return get(row_ndx); }
    void set(size_t row_ndx, const NewDate& ndt);
    bool compare(const DateTimeColumn& c) const noexcept;
    void erase(size_t ndx, bool is_last) {
        m_seconds.erase(ndx, is_last);
        m_nanoseconds.erase(ndx, is_last);
    }

private:

    IntNullColumn m_seconds;
    IntegerColumn m_nanoseconds;

};

} // namespace realm

#endif // REALM_COLUMN_DATETIME_HPP
<commit_msg>Added missing override.<commit_after>/*************************************************************************
 *
 * REALM CONFIDENTIAL
 * __________________
 *
 *  [2011] - [2015] Realm Inc
 *  All Rights Reserved.
 *
 * NOTICE:  All information contained herein is, and remains
 * the property of Realm Incorporated and its suppliers,
 * if any.  The intellectual and technical concepts contained
 * herein are proprietary to Realm Incorporated
 * and its suppliers and may be covered by U.S. and Foreign Patents,
 * patents in process, and are protected by trade secret or copyright law.
 * Dissemination of this information or reproduction of this material
 * is strictly forbidden unless prior written permission is obtained
 * from Realm Incorporated.
 *
 **************************************************************************/
#ifndef REALM_COLUMN_DATETIME_HPP
#define REALM_COLUMN_DATETIME_HPP

#include <realm/column.hpp>

namespace realm {

struct NewDate {
    NewDate(int64_t seconds, uint32_t nanoseconds) : m_seconds(seconds), m_nanoseconds(nanoseconds), m_is_null(false)
    {
        REALM_ASSERT_3(nanoseconds, <, 1000000000);
    }
    NewDate(const null&) : m_is_null(true) { }
    NewDate() : NewDate(null()) { }

    bool is_null() const { return m_is_null; }

    // Note that nullability is handeled by query system. These operators are only invoked for non-null dates.
    bool operator==(const NewDate& rhs) const { return m_seconds == rhs.m_seconds && m_nanoseconds == rhs.m_nanoseconds; }
    bool operator!=(const NewDate& rhs) const { return m_seconds != rhs.m_seconds || m_nanoseconds != rhs.m_nanoseconds; }
    bool operator>(const NewDate& rhs) const { return (m_seconds > rhs.m_seconds) || (m_seconds == rhs.m_seconds && m_nanoseconds > rhs.m_nanoseconds); }
    bool operator<(const NewDate& rhs) const { return (m_seconds < rhs.m_seconds) || (m_seconds == rhs.m_seconds && m_nanoseconds < rhs.m_nanoseconds); }
    bool operator<=(const NewDate& rhs) const { return *this < rhs || *this == rhs; }
    bool operator>=(const NewDate& rhs) const { return *this > rhs || *this == rhs; }
    NewDate& operator=(const NewDate& rhs) = default;

    template<class Ch, class Tr>
    friend std::basic_ostream<Ch, Tr>& operator<<(std::basic_ostream<Ch, Tr>& out, const NewDate&);

    int64_t m_seconds;
    uint32_t m_nanoseconds;
    bool m_is_null;
};

template<class C, class T>
inline std::basic_ostream<C, T>& operator<<(std::basic_ostream<C, T>& out, const NewDate& d)
{
    out << "NewDate(" << d.m_seconds << ", " << d.m_nanoseconds << ")";
    return out;
}

// Inherits from ColumnTemplate to get a compare_values() that can be called without knowing the
// column type
class DateTimeColumn : public ColumnBaseSimple, public ColumnTemplate<NewDate> {
public:
    DateTimeColumn(Allocator& alloc, ref_type ref);
    ~DateTimeColumn() noexcept override;

    static ref_type create(Allocator& alloc, size_t size = 0);

    /// Get the number of entries in this column. This operation is relatively
    /// slow.
    size_t size() const noexcept override;
    /// Whether or not this column is nullable.
    bool is_nullable() const noexcept override;
    /// Whether or not the value at \a row_ndx is NULL. If the column is not
    /// nullable, always returns false.
    bool is_null(size_t row_ndx) const noexcept override;
    /// Sets the value at \a row_ndx to be NULL.
    /// \throw LogicError Thrown if this column is not nullable.
    void set_null(size_t row_ndx) override;
    void insert_rows(size_t row_ndx, size_t num_rows_to_insert, size_t prior_num_rows, bool nullable) override;
    void erase_rows(size_t row_ndx, size_t num_rows_to_erase, size_t prior_num_rows,
                    bool broken_reciprocal_backlinks) override;
    void move_last_row_over(size_t row_ndx, size_t prior_num_rows,
                            bool broken_reciprocal_backlinks) override;
    void clear(size_t num_rows, bool broken_reciprocal_backlinks) override;
    void swap_rows(size_t row_ndx_1, size_t row_ndx_2) override;
    void destroy() noexcept override;
    StringData get_index_data(size_t, StringIndex::StringConversionBuffer& buffer) const noexcept override;
    MemRef clone_deep(Allocator& alloc) const override;
    ref_type write(size_t slice_offset, size_t slice_size, size_t table_size, _impl::OutputStream&) const override;
    void update_from_parent(size_t old_baseline) noexcept override;
    void refresh_accessor_tree(size_t new_col_ndx, const Spec&) override;
#ifdef REALM_DEBUG
    void verify() const override;
    void to_dot(std::ostream&, StringData title = StringData()) const override;
    void do_dump_node_structure(std::ostream&, int level) const override;
    void leaf_to_dot(MemRef, ArrayParent*, size_t ndx_in_parent, std::ostream&) const override;
#endif
    void add(const NewDate& ndt = NewDate{});
    NewDate get(size_t row_ndx) const noexcept;
    NewDate get_val(size_t row_ndx) const noexcept override { return get(row_ndx); }
    void set(size_t row_ndx, const NewDate& ndt);
    bool compare(const DateTimeColumn& c) const noexcept;
    void erase(size_t ndx, bool is_last) {
        m_seconds.erase(ndx, is_last);
        m_nanoseconds.erase(ndx, is_last);
    }

private:

    IntNullColumn m_seconds;
    IntegerColumn m_nanoseconds;

};

} // namespace realm

#endif // REALM_COLUMN_DATETIME_HPP
<|endoftext|>


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

#include "chrome/renderer/paint_aggregator.h"

#include "base/histogram.h"
#include "base/logging.h"

// ----------------------------------------------------------------------------
// ALGORITHM NOTES
//
// We attempt to maintain a scroll rect in the presence of invalidations that
// are contained within the scroll rect.  If an invalidation crosses a scroll
// rect, then we just treat the scroll rect as an invalidation rect.
//
// For invalidations performed prior to scrolling and contained within the
// scroll rect, we offset the invalidation rects to account for the fact that
// the consumer will perform scrolling before painting.
//
// We only support scrolling along one axis at a time.  A diagonal scroll will
// therefore be treated as an invalidation.
// ----------------------------------------------------------------------------

// If the combined area of paint rects contained within the scroll rect grows
// too large, then we might as well just treat the scroll rect as a paint rect.
// This constant sets the max ratio of paint rect area to scroll rect area that
// we will tolerate before downgrading the scroll into a repaint.
static const float kMaxRedundantPaintToScrollArea = 0.8f;

// The maximum number of paint rects.  If we exceed this limit, then we'll
// start combining paint rects (see CombinePaintRects).  This limiting is
// important since the WebKit code associated with deciding what to paint given
// a paint rect can be significant.
static const size_t kMaxPaintRects = 10;

gfx::Rect PaintAggregator::PendingUpdate::GetScrollDamage() const {
  // Should only be scrolling in one direction at a time.
  DCHECK(!(scroll_delta.x() && scroll_delta.y()));

  gfx::Rect damaged_rect;

  // Compute the region we will expose by scrolling, and paint that into a
  // shared memory section.
  if (scroll_delta.x()) {
    int dx = scroll_delta.x();
    damaged_rect.set_y(scroll_rect.y());
    damaged_rect.set_height(scroll_rect.height());
    if (dx > 0) {
      damaged_rect.set_x(scroll_rect.x());
      damaged_rect.set_width(dx);
    } else {
      damaged_rect.set_x(scroll_rect.right() + dx);
      damaged_rect.set_width(-dx);
    }
  } else {
    int dy = scroll_delta.y();
    damaged_rect.set_x(scroll_rect.x());
    damaged_rect.set_width(scroll_rect.width());
    if (dy > 0) {
      damaged_rect.set_y(scroll_rect.y());
      damaged_rect.set_height(dy);
    } else {
      damaged_rect.set_y(scroll_rect.bottom() + dy);
      damaged_rect.set_height(-dy);
    }
  }

  // In case the scroll offset exceeds the width/height of the scroll rect
  return scroll_rect.Intersect(damaged_rect);
}

gfx::Rect PaintAggregator::PendingUpdate::GetPaintBounds() const {
  gfx::Rect bounds;
  for (size_t i = 0; i < paint_rects.size(); ++i)
    bounds = bounds.Union(paint_rects[i]);
  return bounds;
}

bool PaintAggregator::HasPendingUpdate() const {
  return !update_.scroll_rect.IsEmpty() || !update_.paint_rects.empty();
}

void PaintAggregator::ClearPendingUpdate() {
  update_ = PendingUpdate();
}

void PaintAggregator::InvalidateRect(const gfx::Rect& rect) {
  // Combine overlapping paints using smallest bounding box.
  for (size_t i = 0; i < update_.paint_rects.size(); ++i) {
    const gfx::Rect& existing_rect = update_.paint_rects[i];
    if (existing_rect.Contains(rect))  // Optimize out redundancy.
      return;
    if (rect.Intersects(existing_rect) || rect.SharesEdgeWith(existing_rect)) {
      // Re-invalidate in case the union intersects other paint rects.
      gfx::Rect combined_rect = existing_rect.Union(rect);
      update_.paint_rects.erase(update_.paint_rects.begin() + i);
      InvalidateRect(combined_rect);
      return;
    }
  }

  // Add a non-overlapping paint.
  update_.paint_rects.push_back(rect);

  // If the new paint overlaps with a scroll, then it forces an invalidation of
  // the scroll.  If the new paint is contained by a scroll, then trim off the
  // scroll damage to avoid redundant painting.
  if (!update_.scroll_rect.IsEmpty()) {
    if (ShouldInvalidateScrollRect(rect)) {
      InvalidateScrollRect();
    } else if (update_.scroll_rect.Contains(rect)) {
      update_.paint_rects[update_.paint_rects.size() - 1] =
          rect.Subtract(update_.GetScrollDamage());
      if (update_.paint_rects[update_.paint_rects.size() - 1].IsEmpty())
        update_.paint_rects.erase(update_.paint_rects.end() - 1);
    }
  }

  if (update_.paint_rects.size() > kMaxPaintRects)
    CombinePaintRects();

  // Track how large the paint_rects vector grows during an invalidation
  // sequence.  Note: A subsequent invalidation may end up being combined
  // with all existing paints, which means that tracking the size of
  // paint_rects at the time when GetPendingUpdate() is called may mask
  // certain performance problems.
  HISTOGRAM_COUNTS_100("MPArch.RW_IntermediatePaintRectCount",
                       update_.paint_rects.size());
}

void PaintAggregator::ScrollRect(int dx, int dy, const gfx::Rect& clip_rect) {
  // We only support scrolling along one axis at a time.
  if (dx != 0 && dy != 0) {
    InvalidateRect(clip_rect);
    return;
  }

  // We can only scroll one rect at a time.
  if (!update_.scroll_rect.IsEmpty() &&
      !update_.scroll_rect.Equals(clip_rect)) {
    InvalidateRect(clip_rect);
    return;
  }

  // Again, we only support scrolling along one axis at a time.  Make sure this
  // update doesn't scroll on a different axis than any existing one.
  if ((dx && update_.scroll_delta.y()) || (dy && update_.scroll_delta.x())) {
    InvalidateRect(clip_rect);
    return;
  }

  // The scroll rect is new or isn't changing (though the scroll amount may
  // be changing).
  update_.scroll_rect = clip_rect;
  update_.scroll_delta.Offset(dx, dy);

  // Adjust any contained paint rects and check for any overlapping paints.
  for (size_t i = 0; i < update_.paint_rects.size(); ++i) {
    if (update_.scroll_rect.Contains(update_.paint_rects[i])) {
      update_.paint_rects[i] = ScrollPaintRect(update_.paint_rects[i], dx, dy);
      // The rect may have been scrolled out of view.
      if (update_.paint_rects[i].IsEmpty()) {
        update_.paint_rects.erase(update_.paint_rects.begin() + i);
        i--;
      }
    } else if (update_.scroll_rect.Intersects(update_.paint_rects[i])) {
      InvalidateScrollRect();
      return;
    }
  }

  // If the new scroll overlaps too much with contained paint rects, then force
  // an invalidation of the scroll.
  if (ShouldInvalidateScrollRect(gfx::Rect()))
    InvalidateScrollRect();
}

gfx::Rect PaintAggregator::ScrollPaintRect(const gfx::Rect& paint_rect,
                                           int dx, int dy) const {
  gfx::Rect result = paint_rect;

  result.Offset(dx, dy);
  result = update_.scroll_rect.Intersect(result);

  // Subtract out the scroll damage rect to avoid redundant painting.
  return result.Subtract(update_.GetScrollDamage());
}

bool PaintAggregator::ShouldInvalidateScrollRect(const gfx::Rect& rect) const {
  if (!rect.IsEmpty()) {
    if (!update_.scroll_rect.Intersects(rect))
      return false;

    if (!update_.scroll_rect.Contains(rect))
      return true;
  }

  // Check if the combined area of all contained paint rects plus this new
  // rect comes too close to the area of the scroll_rect.  If so, then we
  // might as well invalidate the scroll rect.

  int paint_area = rect.size().GetArea();
  for (size_t i = 0; i < update_.paint_rects.size(); ++i) {
    const gfx::Rect& existing_rect = update_.paint_rects[i];
    if (update_.scroll_rect.Contains(existing_rect))
      paint_area += existing_rect.size().GetArea();
  }
  int scroll_area = update_.scroll_rect.size().GetArea();
  if (float(paint_area) / float(scroll_area) > kMaxRedundantPaintToScrollArea)
    return true;

  return false;
}

void PaintAggregator::InvalidateScrollRect() {
  gfx::Rect scroll_rect = update_.scroll_rect;
  update_.scroll_rect = gfx::Rect();
  update_.scroll_delta = gfx::Point();
  InvalidateRect(scroll_rect);
}

void PaintAggregator::CombinePaintRects() {
  // Combine paint rects down to at most two rects: one inside the scroll_rect
  // and one outside the scroll_rect.  If there is no scroll_rect, then just
  // use the smallest bounding box for all paint rects.
  //
  // NOTE: This is a fairly simple algorithm.  We could get fancier by only
  // combining two rects to get us under the kMaxPaintRects limit, but if we
  // reach this method then it means we're hitting a rare case, so there's no
  // need to over-optimize it.
  //
  if (update_.scroll_rect.IsEmpty()) {
    gfx::Rect bounds = update_.GetPaintBounds();
    update_.paint_rects.clear();
    update_.paint_rects.push_back(bounds);
  } else {
    gfx::Rect inner, outer;
    for (size_t i = 0; i < update_.paint_rects.size(); ++i) {
      const gfx::Rect& existing_rect = update_.paint_rects[i];
      if (update_.scroll_rect.Contains(existing_rect)) {
        inner = inner.Union(existing_rect);
      } else {
        outer = outer.Union(existing_rect);
      }
    }
    update_.paint_rects.clear();
    update_.paint_rects.push_back(inner);
    update_.paint_rects.push_back(outer);
  }
}
<commit_msg>Reduce kMaxPaintRects to test impact on single-core bot.<commit_after>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/renderer/paint_aggregator.h"

#include "base/histogram.h"
#include "base/logging.h"

// ----------------------------------------------------------------------------
// ALGORITHM NOTES
//
// We attempt to maintain a scroll rect in the presence of invalidations that
// are contained within the scroll rect.  If an invalidation crosses a scroll
// rect, then we just treat the scroll rect as an invalidation rect.
//
// For invalidations performed prior to scrolling and contained within the
// scroll rect, we offset the invalidation rects to account for the fact that
// the consumer will perform scrolling before painting.
//
// We only support scrolling along one axis at a time.  A diagonal scroll will
// therefore be treated as an invalidation.
// ----------------------------------------------------------------------------

// If the combined area of paint rects contained within the scroll rect grows
// too large, then we might as well just treat the scroll rect as a paint rect.
// This constant sets the max ratio of paint rect area to scroll rect area that
// we will tolerate before downgrading the scroll into a repaint.
static const float kMaxRedundantPaintToScrollArea = 0.8f;

// The maximum number of paint rects.  If we exceed this limit, then we'll
// start combining paint rects (see CombinePaintRects).  This limiting is
// important since the WebKit code associated with deciding what to paint given
// a paint rect can be significant.
static const size_t kMaxPaintRects = 5;

gfx::Rect PaintAggregator::PendingUpdate::GetScrollDamage() const {
  // Should only be scrolling in one direction at a time.
  DCHECK(!(scroll_delta.x() && scroll_delta.y()));

  gfx::Rect damaged_rect;

  // Compute the region we will expose by scrolling, and paint that into a
  // shared memory section.
  if (scroll_delta.x()) {
    int dx = scroll_delta.x();
    damaged_rect.set_y(scroll_rect.y());
    damaged_rect.set_height(scroll_rect.height());
    if (dx > 0) {
      damaged_rect.set_x(scroll_rect.x());
      damaged_rect.set_width(dx);
    } else {
      damaged_rect.set_x(scroll_rect.right() + dx);
      damaged_rect.set_width(-dx);
    }
  } else {
    int dy = scroll_delta.y();
    damaged_rect.set_x(scroll_rect.x());
    damaged_rect.set_width(scroll_rect.width());
    if (dy > 0) {
      damaged_rect.set_y(scroll_rect.y());
      damaged_rect.set_height(dy);
    } else {
      damaged_rect.set_y(scroll_rect.bottom() + dy);
      damaged_rect.set_height(-dy);
    }
  }

  // In case the scroll offset exceeds the width/height of the scroll rect
  return scroll_rect.Intersect(damaged_rect);
}

gfx::Rect PaintAggregator::PendingUpdate::GetPaintBounds() const {
  gfx::Rect bounds;
  for (size_t i = 0; i < paint_rects.size(); ++i)
    bounds = bounds.Union(paint_rects[i]);
  return bounds;
}

bool PaintAggregator::HasPendingUpdate() const {
  return !update_.scroll_rect.IsEmpty() || !update_.paint_rects.empty();
}

void PaintAggregator::ClearPendingUpdate() {
  update_ = PendingUpdate();
}

void PaintAggregator::InvalidateRect(const gfx::Rect& rect) {
  // Combine overlapping paints using smallest bounding box.
  for (size_t i = 0; i < update_.paint_rects.size(); ++i) {
    const gfx::Rect& existing_rect = update_.paint_rects[i];
    if (existing_rect.Contains(rect))  // Optimize out redundancy.
      return;
    if (rect.Intersects(existing_rect) || rect.SharesEdgeWith(existing_rect)) {
      // Re-invalidate in case the union intersects other paint rects.
      gfx::Rect combined_rect = existing_rect.Union(rect);
      update_.paint_rects.erase(update_.paint_rects.begin() + i);
      InvalidateRect(combined_rect);
      return;
    }
  }

  // Add a non-overlapping paint.
  update_.paint_rects.push_back(rect);

  // If the new paint overlaps with a scroll, then it forces an invalidation of
  // the scroll.  If the new paint is contained by a scroll, then trim off the
  // scroll damage to avoid redundant painting.
  if (!update_.scroll_rect.IsEmpty()) {
    if (ShouldInvalidateScrollRect(rect)) {
      InvalidateScrollRect();
    } else if (update_.scroll_rect.Contains(rect)) {
      update_.paint_rects[update_.paint_rects.size() - 1] =
          rect.Subtract(update_.GetScrollDamage());
      if (update_.paint_rects[update_.paint_rects.size() - 1].IsEmpty())
        update_.paint_rects.erase(update_.paint_rects.end() - 1);
    }
  }

  if (update_.paint_rects.size() > kMaxPaintRects)
    CombinePaintRects();

  // Track how large the paint_rects vector grows during an invalidation
  // sequence.  Note: A subsequent invalidation may end up being combined
  // with all existing paints, which means that tracking the size of
  // paint_rects at the time when GetPendingUpdate() is called may mask
  // certain performance problems.
  HISTOGRAM_COUNTS_100("MPArch.RW_IntermediatePaintRectCount",
                       update_.paint_rects.size());
}

void PaintAggregator::ScrollRect(int dx, int dy, const gfx::Rect& clip_rect) {
  // We only support scrolling along one axis at a time.
  if (dx != 0 && dy != 0) {
    InvalidateRect(clip_rect);
    return;
  }

  // We can only scroll one rect at a time.
  if (!update_.scroll_rect.IsEmpty() &&
      !update_.scroll_rect.Equals(clip_rect)) {
    InvalidateRect(clip_rect);
    return;
  }

  // Again, we only support scrolling along one axis at a time.  Make sure this
  // update doesn't scroll on a different axis than any existing one.
  if ((dx && update_.scroll_delta.y()) || (dy && update_.scroll_delta.x())) {
    InvalidateRect(clip_rect);
    return;
  }

  // The scroll rect is new or isn't changing (though the scroll amount may
  // be changing).
  update_.scroll_rect = clip_rect;
  update_.scroll_delta.Offset(dx, dy);

  // Adjust any contained paint rects and check for any overlapping paints.
  for (size_t i = 0; i < update_.paint_rects.size(); ++i) {
    if (update_.scroll_rect.Contains(update_.paint_rects[i])) {
      update_.paint_rects[i] = ScrollPaintRect(update_.paint_rects[i], dx, dy);
      // The rect may have been scrolled out of view.
      if (update_.paint_rects[i].IsEmpty()) {
        update_.paint_rects.erase(update_.paint_rects.begin() + i);
        i--;
      }
    } else if (update_.scroll_rect.Intersects(update_.paint_rects[i])) {
      InvalidateScrollRect();
      return;
    }
  }

  // If the new scroll overlaps too much with contained paint rects, then force
  // an invalidation of the scroll.
  if (ShouldInvalidateScrollRect(gfx::Rect()))
    InvalidateScrollRect();
}

gfx::Rect PaintAggregator::ScrollPaintRect(const gfx::Rect& paint_rect,
                                           int dx, int dy) const {
  gfx::Rect result = paint_rect;

  result.Offset(dx, dy);
  result = update_.scroll_rect.Intersect(result);

  // Subtract out the scroll damage rect to avoid redundant painting.
  return result.Subtract(update_.GetScrollDamage());
}

bool PaintAggregator::ShouldInvalidateScrollRect(const gfx::Rect& rect) const {
  if (!rect.IsEmpty()) {
    if (!update_.scroll_rect.Intersects(rect))
      return false;

    if (!update_.scroll_rect.Contains(rect))
      return true;
  }

  // Check if the combined area of all contained paint rects plus this new
  // rect comes too close to the area of the scroll_rect.  If so, then we
  // might as well invalidate the scroll rect.

  int paint_area = rect.size().GetArea();
  for (size_t i = 0; i < update_.paint_rects.size(); ++i) {
    const gfx::Rect& existing_rect = update_.paint_rects[i];
    if (update_.scroll_rect.Contains(existing_rect))
      paint_area += existing_rect.size().GetArea();
  }
  int scroll_area = update_.scroll_rect.size().GetArea();
  if (float(paint_area) / float(scroll_area) > kMaxRedundantPaintToScrollArea)
    return true;

  return false;
}

void PaintAggregator::InvalidateScrollRect() {
  gfx::Rect scroll_rect = update_.scroll_rect;
  update_.scroll_rect = gfx::Rect();
  update_.scroll_delta = gfx::Point();
  InvalidateRect(scroll_rect);
}

void PaintAggregator::CombinePaintRects() {
  // Combine paint rects down to at most two rects: one inside the scroll_rect
  // and one outside the scroll_rect.  If there is no scroll_rect, then just
  // use the smallest bounding box for all paint rects.
  //
  // NOTE: This is a fairly simple algorithm.  We could get fancier by only
  // combining two rects to get us under the kMaxPaintRects limit, but if we
  // reach this method then it means we're hitting a rare case, so there's no
  // need to over-optimize it.
  //
  if (update_.scroll_rect.IsEmpty()) {
    gfx::Rect bounds = update_.GetPaintBounds();
    update_.paint_rects.clear();
    update_.paint_rects.push_back(bounds);
  } else {
    gfx::Rect inner, outer;
    for (size_t i = 0; i < update_.paint_rects.size(); ++i) {
      const gfx::Rect& existing_rect = update_.paint_rects[i];
      if (update_.scroll_rect.Contains(existing_rect)) {
        inner = inner.Union(existing_rect);
      } else {
        outer = outer.Union(existing_rect);
      }
    }
    update_.paint_rects.clear();
    update_.paint_rects.push_back(inner);
    update_.paint_rects.push_back(outer);
  }
}
<|endoftext|>


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

#include "base/at_exit.h"
#include "chrome/test/ui/ui_test_suite.h"

int main(int argc, char **argv) {
  // Some tests may use base::Singleton<>, thus we need to instanciate
  // the AtExitManager or else we will leak objects.
  base::AtExitManager at_exit_manager;

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

#include "base/at_exit.h"
#include "base/platform_thread.h"
#include "chrome/test/ui/ui_test_suite.h"

int main(int argc, char **argv) {
  // Some tests may use base::Singleton<>, thus we need to instanciate
  // the AtExitManager or else we will leak objects.
  base::AtExitManager at_exit_manager;

  PlatformThread::SetName(PlatformThread::CurrentId(), "Tests_Main");
  return UITestSuite(argc, argv).Run();
}
<|endoftext|>


<commit_before>
#include <cppexpose/function/Function.h>

#include <cppexpose/function/StaticFunction.h>
#include <cppexpose/function/MemberFunction.h>

namespace cppexpose
{

Function::Function(std::unique_ptr<AbstractFunction> && func)
: m_func(std::move(func))
{
}

Function::Function(const Function & other)
: m_func(other.m_func ? other.m_func->clone() : nullptr)
{
}

Function::~Function()
{
}

Function & Function::operator=(const Function & other)
{
    // Copy function
    m_func = other.m_func ? other.m_func->clone() : nullptr;
    return *this;
}

bool Function::isEmpty() const
{
    return m_func != nullptr;
}

Variant Function::call(const std::vector<Variant> & args)
{
    // Call function
    if (m_func) {
        return m_func->call(args);
    }

    // Empty function
    return Variant();
}

} // namespace cppexpose
<commit_msg>Fix stupid error<commit_after>
#include <cppexpose/function/Function.h>

#include <cppexpose/function/StaticFunction.h>
#include <cppexpose/function/MemberFunction.h>

namespace cppexpose
{

Function::Function(std::unique_ptr<AbstractFunction> && func)
: m_func(std::move(func))
{
}

Function::Function(const Function & other)
: m_func(other.m_func ? other.m_func->clone() : nullptr)
{
}

Function::~Function()
{
}

Function & Function::operator=(const Function & other)
{
    // Copy function
    m_func = other.m_func ? other.m_func->clone() : nullptr;
    return *this;
}

bool Function::isEmpty() const
{
    return m_func == nullptr;
}

Variant Function::call(const std::vector<Variant> & args)
{
    // Call function
    if (m_func) {
        return m_func->call(args);
    }

    // Empty function
    return Variant();
}

} // namespace cppexpose
<|endoftext|>


<commit_before>
#include <gloperate-glfw/RenderWindow.h>

#define GLFW_INCLUDE_NONE
#include <GLFW/glfw3.h>

#include <gloperate/viewer/input.h>
#include <gloperate/viewer/RenderSurface.h>

#include <gloperate-glfw/WindowEvent.h>
#include <gloperate-glfw/GLContext.h>
#include <gloperate-glfw/input.h>

using namespace gloperate;

namespace gloperate_glfw
{

RenderWindow::RenderWindow(
    gloperate::ViewerContext * viewerContext
  , const std::string & title
  , int width
  , int height)
: RenderWindow(viewerContext, title, width, height, new gloperate::RenderSurface(viewerContext))
{
}

RenderWindow::~RenderWindow()
{
    delete m_surface;
}

gloperate::ViewerContext * RenderWindow::viewerContext() const
{
    return m_viewerContext;
}

gloperate::Surface * RenderWindow::surface() const
{
    return m_surface;
}

RenderWindow::RenderWindow(
    gloperate::ViewerContext * viewerContext
  , const std::string & title
  , int width
  , int height
  , gloperate::Surface * surface)
: Window(title, width, height, surface->requiredFormat())
, m_viewerContext(viewerContext)
, m_surface(surface)
{
}

void RenderWindow::onContextInit()
{
    m_surface->setOpenGLContext(m_context);
}

void RenderWindow::onContextDeinit()
{
    m_surface->setOpenGLContext(nullptr);
}

void RenderWindow::onIdle()
{
    m_surface->onIdle();
}

void RenderWindow::onResize(ResizeEvent & event)
{
    m_virtualSize = event.size();

    m_surface->onResize(m_deviceSize, m_virtualSize);
}

void RenderWindow::onFramebufferResize(ResizeEvent & event)
{
    m_deviceSize = event.size();

    m_surface->onResize(m_deviceSize, m_virtualSize);
}

void RenderWindow::onMove(MoveEvent &)
{
}

void RenderWindow::onPaint(PaintEvent &)
{
    m_surface->onRender();
}

void RenderWindow::onKeyPress(KeyEvent & event)
{
    m_surface->onKeyPress(
        fromGLFWKeyCode(event.key())
    );
}

void RenderWindow::onKeyRelease(KeyEvent & event)
{
    m_surface->onKeyRelease(
        fromGLFWKeyCode(event.key())
    );
}

void RenderWindow::onMousePress(MouseEvent & event)
{
    m_surface->onMousePress(
        fromGLFWMouseButton(event.button())
      , event.pos()
    );
}

void RenderWindow::onMouseRelease(MouseEvent & event)
{
    m_surface->onMouseRelease(
        fromGLFWMouseButton(event.button())
      , event.pos()
    );
}

void RenderWindow::onMouseMove(MouseEvent & event)
{
    m_surface->onMouseMove(event.pos());
}

void RenderWindow::onMouseEnter(MouseEnterEvent &)
{
}

void RenderWindow::onMouseLeave(MouseLeaveEvent &)
{
}

void RenderWindow::onScroll(ScrollEvent & event)
{
    m_surface->onMouseWheel(
        event.offset()
      , event.pos()
    );
}

void RenderWindow::onFocus(FocusEvent &)
{
}

void RenderWindow::onIconify(IconifyEvent &)
{
}

void RenderWindow::onTimer(TimerEvent &)
{
}

} // namespace gloperate_glfw
<commit_msg>Add fullscreen mode to F11 for gloperate-glfw (does not yet work as intended)<commit_after>
#include <gloperate-glfw/RenderWindow.h>

#define GLFW_INCLUDE_NONE
#include <GLFW/glfw3.h>

#include <gloperate/viewer/input.h>
#include <gloperate/viewer/RenderSurface.h>

#include <gloperate-glfw/WindowEvent.h>
#include <gloperate-glfw/GLContext.h>
#include <gloperate-glfw/input.h>

using namespace gloperate;

namespace gloperate_glfw
{

RenderWindow::RenderWindow(
    gloperate::ViewerContext * viewerContext
  , const std::string & title
  , int width
  , int height)
: RenderWindow(viewerContext, title, width, height, new gloperate::RenderSurface(viewerContext))
{
}

RenderWindow::~RenderWindow()
{
    delete m_surface;
}

gloperate::ViewerContext * RenderWindow::viewerContext() const
{
    return m_viewerContext;
}

gloperate::Surface * RenderWindow::surface() const
{
    return m_surface;
}

RenderWindow::RenderWindow(
    gloperate::ViewerContext * viewerContext
  , const std::string & title
  , int width
  , int height
  , gloperate::Surface * surface)
: Window(title, width, height, surface->requiredFormat())
, m_viewerContext(viewerContext)
, m_surface(surface)
{
}

void RenderWindow::onContextInit()
{
    m_surface->setOpenGLContext(m_context);
}

void RenderWindow::onContextDeinit()
{
    m_surface->setOpenGLContext(nullptr);
}

void RenderWindow::onIdle()
{
    m_surface->onIdle();
}

void RenderWindow::onResize(ResizeEvent & event)
{
    m_virtualSize = event.size();

    m_surface->onResize(m_deviceSize, m_virtualSize);
}

void RenderWindow::onFramebufferResize(ResizeEvent & event)
{
    m_deviceSize = event.size();

    m_surface->onResize(m_deviceSize, m_virtualSize);
}

void RenderWindow::onMove(MoveEvent &)
{
}

void RenderWindow::onPaint(PaintEvent &)
{
    m_surface->onRender();
}

void RenderWindow::onKeyPress(KeyEvent & event)
{
    if (event.key() == GLFW_KEY_F11)
    {
      setFullscreen(!isFullscreen());
    }

    m_surface->onKeyPress(
        fromGLFWKeyCode(event.key())
    );
}

void RenderWindow::onKeyRelease(KeyEvent & event)
{
    m_surface->onKeyRelease(
        fromGLFWKeyCode(event.key())
    );
}

void RenderWindow::onMousePress(MouseEvent & event)
{
    m_surface->onMousePress(
        fromGLFWMouseButton(event.button())
      , event.pos()
    );
}

void RenderWindow::onMouseRelease(MouseEvent & event)
{
    m_surface->onMouseRelease(
        fromGLFWMouseButton(event.button())
      , event.pos()
    );
}

void RenderWindow::onMouseMove(MouseEvent & event)
{
    m_surface->onMouseMove(event.pos());
}

void RenderWindow::onMouseEnter(MouseEnterEvent &)
{
}

void RenderWindow::onMouseLeave(MouseLeaveEvent &)
{
}

void RenderWindow::onScroll(ScrollEvent & event)
{
    m_surface->onMouseWheel(
        event.offset()
      , event.pos()
    );
}

void RenderWindow::onFocus(FocusEvent &)
{
}

void RenderWindow::onIconify(IconifyEvent &)
{
}

void RenderWindow::onTimer(TimerEvent &)
{
}

} // namespace gloperate_glfw
<|endoftext|>


<commit_before>// Test.cpp
// Sean Jones

#define GLFW_INCLUDE_GLU
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>
#include <glm/gtx/constants.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtx/transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <glm/core/type_vec3.hpp>
#include <vector>
#include <random>
#include <chrono>
#include <array>
// For Debug
#include <iostream>

using namespace glm;
using namespace std;
using namespace std::chrono;

GLFWwindow* window;

bool running = true;

// Vector containing vector data
vector<vec2> vertices;

/*
 * triangle()
 *
 * Helper function to create a triangle
 */
void triangle(const vec2& a, const vec2& b, const vec2& c)
{
  // Push the vertices onto the vector
  vertices.push_back(a);
  vertices.push_back(b);
  vertices.push_back(c);
} // Triangle

void divide_triangle(const vec2& a, const vec2& b, const vec2& c, int count)
{
}

/*
 * Initialise()
 *
 * Initialises the application
 */
bool initialise()
{
  // Set background to cyan.
  glClearColor(0.0f, 1.0f, 1.0f, 1.0f);
  // Enable face culling
  glEnable(GL_CULL_FACE);
  // Enable depth testing
  glEnable(GL_DEPTH_TEST);
  // Enable vertex arrays
  glEnableClientState(GL_VERTEX_ARRAY);

  // Starting vertices - edge of the screen
  array<vec2, 3> v =
      {
       vec2(1.0f, -1.0f),
       vec2(0.0f, 1.0f),
       vec2(-1.0f, -1.0f)
      };

  // Divide the triangle first - you will need to modify this
  divide_triangle(v[0], v[1], v[2], 0);

  return true;
} // initialise

/*
 * update()
 *
 * Updates the application state
 */
void update(double deltaTime) {

  // Check if escape pressed or window is closed
  running = !glfwGetKey(window, GLFW_KEY_ESCAPE) &&
      !glfwWindowShouldClose(window);

} // update

/*
 * render()
 *
 * renders the application
 */
void render()
{
  // Clear the screen
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  // Point to the internal array of the vector
  glVertexPointer(2, GL_FLOAT, 0, &vertices[0]);

  // Set the colour
  glColor3f(1.0f, 0.0f, 0.0f);

  // Draw the arrays - start at 0 and have n vertices
  glDrawArrays(GL_TRIANGLES, 0, vertices.size());

  // Swap front and back buffers
  glfwSwapBuffers(window);

  // Set transform matrix to identity (no transform)
  glLoadIdentity();

} // render

int main(void)
{
  /* Initialise the library */
  if (!glfwInit())
  {
    return -1;
  }

  /* Create a windowed mode window and its OpenGL context */
  window = glfwCreateWindow(640, 480, "Sierpinski", NULL, NULL);
  if (!window)
  {
    glfwTerminate();
    return -1;
  }

  /* Make the window's context current */
  glfwMakeContextCurrent(window);
  /* Set the function for the key callback */

  //initialise the window
  if (!initialise())
  {
    glfwTerminate();
    return -1;
  }

  // Monitor the elapsed time per frame
  auto currentTimeStamp = system_clock::now();
  auto prevTimeStamp = system_clock::now();

  /* Loop until the user closes the window */
  while (!glfwWindowShouldClose(window))
  {
    // Get current time
    currentTimeStamp = system_clock::now();
    // Calculate elapsed time
    auto elapsed = duration_cast<milliseconds>(currentTimeStamp
                                               - prevTimeStamp);
    //Convert to fractions of a second
    auto seconds = double(elapsed.count()) / 1000.0;

    // Update Application
    update(seconds);
    //Render scene
    render();

    /* Swap front and back buffers */
    glfwSwapBuffers(window);

    /* Poll for and process events */
    glfwPollEvents();

    // set the previous time stamp to current time stamp
    prevTimeStamp = currentTimeStamp;
  } // Main Loop

  glfwTerminate();
  return 0;
} // main
<commit_msg>Added initial divide_triangle<commit_after>// Test.cpp
// Sean Jones

#define GLFW_INCLUDE_GLU
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>
#include <glm/gtx/constants.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtx/transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <glm/core/type_vec3.hpp>
#include <vector>
#include <random>
#include <chrono>
#include <array>
// For Debug
#include <iostream>

using namespace glm;
using namespace std;
using namespace std::chrono;

GLFWwindow* window;

bool running = true;

// Vector containing vector data
vector<vec2> vertices;

/*
 * triangle()
 *
 * Helper function to create a triangle
 */
void triangle(const vec2& a, const vec2& b, const vec2& c)
{
  // Push the vertices onto the vector
  vertices.push_back(a);
  vertices.push_back(b);
  vertices.push_back(c);
} // Triangle

void divide_triangle(const vec2& a, const vec2& b, const vec2& c, int count)
{
  // If subdivisions (count) is zero just output the triangle defined it initialise
  if (count == 0) {
    triangle(a, b, c);
  }
}

/*
 * Initialise()
 *
 * Initialises the application
 */
bool initialise()
{
  // Set background to cyan.
  glClearColor(0.0f, 1.0f, 1.0f, 1.0f);
  // Enable face culling
  glEnable(GL_CULL_FACE);
  // Enable depth testing
  glEnable(GL_DEPTH_TEST);
  // Enable vertex arrays
  glEnableClientState(GL_VERTEX_ARRAY);

  // Starting vertices - edge of the screen
  array<vec2, 3> v =
      {
       vec2(1.0f, -1.0f),
       vec2(0.0f, 1.0f),
       vec2(-1.0f, -1.0f)
      };

  // Divide the triangle first - you will need to modify this
  divide_triangle(v[0], v[1], v[2], 0);

  return true;
} // initialise

/*
 * update()
 *
 * Updates the application state
 */
void update(double deltaTime) {

  // Check if escape pressed or window is closed
  running = !glfwGetKey(window, GLFW_KEY_ESCAPE) &&
      !glfwWindowShouldClose(window);

} // update

/*
 * render()
 *
 * renders the application
 */
void render()
{
  // Clear the screen
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  // Point to the internal array of the vector
  glVertexPointer(2, GL_FLOAT, 0, &vertices[0]);

  // Set the colour
  glColor3f(1.0f, 0.0f, 0.0f);

  // Draw the arrays - start at 0 and have n vertices
  glDrawArrays(GL_TRIANGLES, 0, vertices.size());

  // Swap front and back buffers
  glfwSwapBuffers(window);

  // Set transform matrix to identity (no transform)
  glLoadIdentity();

} // render

int main(void)
{
  /* Initialise the library */
  if (!glfwInit())
  {
    return -1;
  }

  /* Create a windowed mode window and its OpenGL context */
  window = glfwCreateWindow(640, 480, "Sierpinski", NULL, NULL);
  if (!window)
  {
    glfwTerminate();
    return -1;
  }

  /* Make the window's context current */
  glfwMakeContextCurrent(window);
  /* Set the function for the key callback */

  //initialise the window
  if (!initialise())
  {
    glfwTerminate();
    return -1;
  }

  // Monitor the elapsed time per frame
  auto currentTimeStamp = system_clock::now();
  auto prevTimeStamp = system_clock::now();

  /* Loop until the user closes the window */
  while (!glfwWindowShouldClose(window))
  {
    // Get current time
    currentTimeStamp = system_clock::now();
    // Calculate elapsed time
    auto elapsed = duration_cast<milliseconds>(currentTimeStamp
                                               - prevTimeStamp);
    //Convert to fractions of a second
    auto seconds = double(elapsed.count()) / 1000.0;

    // Update Application
    update(seconds);
    //Render scene
    render();

    /* Swap front and back buffers */
    glfwSwapBuffers(window);

    /* Poll for and process events */
    glfwPollEvents();

    // set the previous time stamp to current time stamp
    prevTimeStamp = currentTimeStamp;
  } // Main Loop

  glfwTerminate();
  return 0;
} // main
<|endoftext|>


<commit_before>
#include <gloperate-qtquick/QmlEngine.h>

#include <cstring>

#include <QVariant>
#include <QQmlContext>
#include <QJSValueIterator>
#include <QBuffer>
#include <QImage>

#include <cppexpose/reflection/Property.h>
#include <cppexpose/typed/DirectValue.h>
#include <cppexpose/function/Function.h>

#include <cppassist/fs/FilePath.h>
#include <cppassist/logging/logging.h>

#include <gloperate/gloperate.h>
#include <gloperate/base/Environment.h>
#include <gloperate/rendering/Image.h>

#include <gloperate-qtquick/RenderItem.h>
#include <gloperate-qtquick/TextureItem.h>
#include <gloperate-qtquick/VideoProfile.h>
#include <gloperate-qtquick/TextController.h>
#include <gloperate-qtquick/QmlScriptFunction.h>
#include <gloperate-qtquick/QmlObjectWrapper.h>

namespace gloperate_qtquick
{

const char * s_qmlObjectPointerKey   = "_obj";

QmlEngine::QmlEngine(gloperate::Environment * environment)
: qmltoolbox::QmlApplicationEngine()
, m_environment(environment)
{
    // Get data path
    m_gloperateQmlPath = QString::fromStdString(gloperate::dataPath()) + "/gloperate/qml";

    // Import gloperate qml module
    addImportPath(m_gloperateQmlPath);

    // Register QML types
    qmlRegisterType<RenderItem>    ("gloperate.rendering", 1, 0, "RenderItem");
    qmlRegisterType<TextureItem>   ("gloperate.rendering", 1, 0, "TextureItem");
    qmlRegisterType<TextController>("gloperate.base",      1, 0, "TextController");
    qmlRegisterType<VideoProfile>  ("gloperate.base",      1, 0, "VideoProfile");

    // Register global functions and properties
    rootContext()->setContextObject(this);
}

QmlEngine::~QmlEngine()
{
    // Disconnect from Object::beforeDestroy signals
    for (auto & objectWrapper : m_objectWrappers)
    {
        objectWrapper.second.second.disconnect();
    }

    // m_objectWrappers are deleted through the Qt object hierarchy
}

const gloperate::Environment * QmlEngine::environment() const
{
    return m_environment;
}

gloperate::Environment * QmlEngine::environment()
{
    return m_environment;
}

void QmlEngine::addGlobalObject(cppexpose::Object * obj)
{
    // Create object wrapper
    const auto wrapper = getOrCreateObjectWrapper(obj);

    // Add global object
    rootContext()->setContextProperty(QString::fromStdString(obj->name()), QVariant::fromValue(wrapper->wrapObject()));
}

void QmlEngine::removeGlobalObject(cppexpose::Object * obj)
{
    // Remove global object by setting it to null
    rootContext()->setContextProperty(QString::fromStdString(obj->name()), QVariant{});
}

QString QmlEngine::executeScript(const QString & code)
{
    return QString::fromStdString(
        m_environment->executeScript(code.toStdString()).value<std::string>()
    );
}

cppexpose::Variant QmlEngine::fromScriptValue(const QJSValue & value)
{
    if (value.isBool()) {
        return cppexpose::Variant(value.toBool());
    }

    else if (value.isNumber()) {
        return cppexpose::Variant(value.toNumber());
    }

    else if (value.isString()) {
        return cppexpose::Variant(value.toString().toStdString());
    }

    else if (value.isRegExp()) {
        return cppexpose::Variant(value.toString().toStdString());
    }

    else if (value.isError()) {
        return cppexpose::Variant(value.toString().toStdString());
    }

    else if (value.isDate()) {
        return cppexpose::Variant(value.toString().toStdString());
    }

    else if (value.isCallable()) {
        cppexpose::Function function(cppassist::make_unique<QmlScriptFunction>(this, value));
        return cppexpose::Variant::fromValue<cppexpose::Function>(function);
    }

    else if (value.isArray()) {
        cppexpose::VariantArray array;

        QJSValueIterator it(value);
        while (it.next())
        {
            if (it.hasNext()) // Skip last item (length)
            {
                array.push_back(fromScriptValue(it.value()));
            }
        }

        return array;
    }

    else if (value.isObject())
    {
        cppexpose::VariantMap obj;

        QJSValueIterator it(value);
        while (it.next())
        {
            // If a property s_qmlObjectPointerKey exists, the object is a cppexpose::Object.
            // In this case, extract the pointer and return that.
            // Otherwise, continue to build a key-value map of the object's properties
            if (it.name() == s_qmlObjectPointerKey)
            {
                assert(it.value().isQObject());
                const auto objWrapper = static_cast<QmlObjectWrapper *>(it.value().toQObject());

                return cppexpose::Variant::fromValue(objWrapper->object());
            }
            else
            {
                obj[it.name().toStdString()] = fromScriptValue(it.value());
            }
        }

        return obj;
    }

    else {
        return cppexpose::Variant();
    }
}

QJSValue QmlEngine::toScriptValue(const cppexpose::Variant & var)
{
    if (var.hasType<char>()) {
        return QJSValue(var.value<char>());
    }

    else if (var.hasType<unsigned char>()) {
        return QJSValue(var.value<unsigned char>());
    }

    else if (var.hasType<short>()) {
        return QJSValue(var.value<short>());
    }

    else if (var.hasType<unsigned short>()) {
        return QJSValue(var.value<unsigned short>());
    }

    else if (var.hasType<int>()) {
        return QJSValue(var.value<int>());
    }

    else if (var.hasType<unsigned int>()) {
        return QJSValue(var.value<unsigned int>());
    }

    else if (var.hasType<long>()) {
        return QJSValue(var.value<int>());
    }

    else if (var.hasType<unsigned long>()) {
        return QJSValue(var.value<unsigned int>());
    }

    else if (var.hasType<long long>()) {
        return QJSValue(var.value<int>());
    }

    else if (var.hasType<unsigned long long>()) {
        return QJSValue(var.value<unsigned int>());
    }

    else if (var.hasType<float>()) {
        return QJSValue(var.value<float>());
    }

    else if (var.hasType<double>()) {
        return QJSValue(var.value<double>());
    }

    else if (var.hasType<char*>()) {
        return QJSValue(var.value<char*>());
    }

    else if (var.hasType<std::string>()) {
        return QJSValue(var.value<std::string>().c_str());
    }

    else if (var.hasType<bool>()) {
        return QJSValue(var.value<bool>());
    }

    else if (var.hasType<cppassist::FilePath>()) {
        return QJSValue(var.value<cppassist::FilePath>().path().c_str());
    }

    else if (var.isBool()) {
        return QJSValue(var.toBool());
    }

    else if (var.isUnsignedIntegral()) {
        return QJSValue((unsigned int)var.toULongLong());
    }

    else if (var.isSignedIntegral() || var.isIntegral()) {
        return QJSValue((int)var.toLongLong());
    }

    else if (var.isFloatingPoint()) {
        return QJSValue(var.toDouble());
    }

    else if (var.isString()) {
        return QJSValue(var.toString().c_str());
    }

    else if (var.hasType<gloperate::Image>()) {
        const gloperate::Image * image = var.ptr<gloperate::Image>();

        QImage conversion((unsigned char *) image->data(), image->width(), image->height(), QImage::Format_RGB32);

        QByteArray byteArray;
        QBuffer buffer(&byteArray);
        buffer.open(QIODevice::WriteOnly);
        conversion.save(&buffer, "PNG", 0);
        QString imgBase64 = QString::fromLatin1(byteArray.toBase64().data());

        return toScriptValue("data:image/png;base64," + imgBase64.toStdString());
    }

    else if (var.hasType<cppexpose::VariantArray>()) {
        QJSValue array = newArray();

        cppexpose::VariantArray variantArray = var.value<cppexpose::VariantArray>();
        for (unsigned int i=0; i<variantArray.size(); i++) {
            array.setProperty(i, toScriptValue(variantArray.at(i)));
        }

        return array;
    }

    else if (var.hasType<cppexpose::VariantMap>()) {
        QJSValue obj = newObject();

        cppexpose::VariantMap variantMap = var.value<cppexpose::VariantMap>();
        for (const std::pair<std::string, cppexpose::Variant> & pair : variantMap)
        {
            obj.setProperty(pair.first.c_str(), toScriptValue(pair.second));
        }

        return obj;
    }

    else if (var.hasType<cppexpose::Object *>()) {
        const auto object = var.value<cppexpose::Object *>();

        return getOrCreateObjectWrapper(object)->wrapObject();
    }

    else {
        return QJSValue();
    }
}

cppexpose::Variant QmlEngine::fromQVariant(const QVariant & value)
{
    if (value.type() == QVariant::Bool) {
        return cppexpose::Variant(value.toBool());
    }

    else if (value.type() == QVariant::Char || value.type() == QVariant::Int) {
        return cppexpose::Variant(value.toInt());
    }

    else if (value.type() == QVariant::UInt) {
        return cppexpose::Variant(value.toUInt());
    }

    else if (value.type() == QVariant::LongLong) {
        return cppexpose::Variant(value.toLongLong());
    }

    else if (value.type() == QVariant::ULongLong) {
        return cppexpose::Variant(value.toULongLong());
    }

    else if (value.type() == QVariant::Double) {
        return cppexpose::Variant(value.toDouble());
    }

    else if (value.type() == QVariant::StringList)
    {
        cppexpose::VariantArray array;

        QStringList list = value.toStringList();
        for (QStringList::iterator it = list.begin(); it != list.end(); ++it)
        {
            array.push_back(cppexpose::Variant((*it).toStdString()) );
        }

        return array;
    }

    else if (value.type() == QVariant::List)
    {
        cppexpose::VariantArray array;

        QList<QVariant> list = value.toList();
        for (QList<QVariant>::iterator it = list.begin(); it != list.end(); ++it)
        {
            array.push_back(fromQVariant(*it));
        }

        return array;
    }

    else if (value.type() == QVariant::Map)
    {
        cppexpose::VariantMap obj;

        QMap<QString, QVariant> map = value.toMap();
        for (QMap<QString, QVariant>::iterator it = map.begin(); it != map.end(); ++it)
        {
            std::string key = it.key().toStdString();
            obj[key] = fromQVariant(it.value());
        }

        return obj;
    }

    else if (value.type() == QVariant::String || value.canConvert(QVariant::String))
    {
        return cppexpose::Variant(value.toString().toStdString());
    }

    else if (value.canConvert<QJSValue>())
    {
        return fromScriptValue(value.value<QJSValue>());
    }

    else {
        return cppexpose::Variant();
    }
}

const QString & QmlEngine::gloperateModulePath() const
{
    return m_gloperateQmlPath;
}

QmlObjectWrapper * QmlEngine::getOrCreateObjectWrapper(cppexpose::Object * object)
{
    // Check if wrapper exists
    const auto itr = m_objectWrappers.find(object);
    if (itr != m_objectWrappers.end())
    {
        return itr->second.first;
    }

    // Wrap object
    const auto wrapper = new QmlObjectWrapper(this, object);

    // Delete wrapper when object is destroyed
    // The connection will be deleted when this backend is destroyed
    const auto beforeDestroy = object->beforeDestroy.connect([this, object](cppexpose::AbstractProperty *)
    {
        delete m_objectWrappers[object].first;
        m_objectWrappers.erase(object);
    });

    // Save wrapper for later
    m_objectWrappers[object] = {wrapper, beforeDestroy};

    return wrapper;
}

} // namespace gloperate_qtquick
<commit_msg>Avoid loop to list properties if a wrapped object is found<commit_after>
#include <gloperate-qtquick/QmlEngine.h>

#include <cstring>

#include <QVariant>
#include <QQmlContext>
#include <QJSValueIterator>
#include <QBuffer>
#include <QImage>

#include <cppexpose/reflection/Property.h>
#include <cppexpose/typed/DirectValue.h>
#include <cppexpose/function/Function.h>

#include <cppassist/fs/FilePath.h>
#include <cppassist/logging/logging.h>

#include <gloperate/gloperate.h>
#include <gloperate/base/Environment.h>
#include <gloperate/rendering/Image.h>

#include <gloperate-qtquick/RenderItem.h>
#include <gloperate-qtquick/TextureItem.h>
#include <gloperate-qtquick/VideoProfile.h>
#include <gloperate-qtquick/TextController.h>
#include <gloperate-qtquick/QmlScriptFunction.h>
#include <gloperate-qtquick/QmlObjectWrapper.h>

namespace gloperate_qtquick
{

const char * s_qmlObjectPointerKey   = "_obj";

QmlEngine::QmlEngine(gloperate::Environment * environment)
: qmltoolbox::QmlApplicationEngine()
, m_environment(environment)
{
    // Get data path
    m_gloperateQmlPath = QString::fromStdString(gloperate::dataPath()) + "/gloperate/qml";

    // Import gloperate qml module
    addImportPath(m_gloperateQmlPath);

    // Register QML types
    qmlRegisterType<RenderItem>    ("gloperate.rendering", 1, 0, "RenderItem");
    qmlRegisterType<TextureItem>   ("gloperate.rendering", 1, 0, "TextureItem");
    qmlRegisterType<TextController>("gloperate.base",      1, 0, "TextController");
    qmlRegisterType<VideoProfile>  ("gloperate.base",      1, 0, "VideoProfile");

    // Register global functions and properties
    rootContext()->setContextObject(this);
}

QmlEngine::~QmlEngine()
{
    // Disconnect from Object::beforeDestroy signals
    for (auto & objectWrapper : m_objectWrappers)
    {
        objectWrapper.second.second.disconnect();
    }

    // m_objectWrappers are deleted through the Qt object hierarchy
}

const gloperate::Environment * QmlEngine::environment() const
{
    return m_environment;
}

gloperate::Environment * QmlEngine::environment()
{
    return m_environment;
}

void QmlEngine::addGlobalObject(cppexpose::Object * obj)
{
    // Create object wrapper
    const auto wrapper = getOrCreateObjectWrapper(obj);

    // Add global object
    rootContext()->setContextProperty(QString::fromStdString(obj->name()), QVariant::fromValue(wrapper->wrapObject()));
}

void QmlEngine::removeGlobalObject(cppexpose::Object * obj)
{
    // Remove global object by setting it to null
    rootContext()->setContextProperty(QString::fromStdString(obj->name()), QVariant{});
}

QString QmlEngine::executeScript(const QString & code)
{
    return QString::fromStdString(
        m_environment->executeScript(code.toStdString()).value<std::string>()
    );
}

cppexpose::Variant QmlEngine::fromScriptValue(const QJSValue & value)
{
    if (value.isBool()) {
        return cppexpose::Variant(value.toBool());
    }

    else if (value.isNumber()) {
        return cppexpose::Variant(value.toNumber());
    }

    else if (value.isString()) {
        return cppexpose::Variant(value.toString().toStdString());
    }

    else if (value.isRegExp()) {
        return cppexpose::Variant(value.toString().toStdString());
    }

    else if (value.isError()) {
        return cppexpose::Variant(value.toString().toStdString());
    }

    else if (value.isDate()) {
        return cppexpose::Variant(value.toString().toStdString());
    }

    else if (value.isCallable()) {
        cppexpose::Function function(cppassist::make_unique<QmlScriptFunction>(this, value));
        return cppexpose::Variant::fromValue<cppexpose::Function>(function);
    }

    else if (value.isArray()) {
        cppexpose::VariantArray array;

        QJSValueIterator it(value);
        while (it.next())
        {
            if (it.hasNext()) // Skip last item (length)
            {
                array.push_back(fromScriptValue(it.value()));
            }
        }

        return array;
    }

    else if (value.isObject())
    {
        // If a property s_qmlObjectPointerKey exists, the object is a cppexpose::Object.
        // In this case, extract the pointer and return that.
        // Otherwise, build a key-value map of the object's properties.
        if (value.hasOwnProperty(s_qmlObjectPointerKey))
        {
            assert(it.value().isQObject());
            const auto objWrapper = static_cast<QmlObjectWrapper *>(value.property(s_qmlObjectPointerKey).toQObject());

            return cppexpose::Variant::fromValue(objWrapper->object());
        }

        else
        {
            cppexpose::VariantMap obj;

            QJSValueIterator it(value);
            while (it.next())
            {
                if (it.name() == s_qmlObjectPointerKey)
                {
                }
                else
                {
                    obj[it.name().toStdString()] = fromScriptValue(it.value());
                }
            }

            return obj;
        }
    }

    else {
        return cppexpose::Variant();
    }
}

QJSValue QmlEngine::toScriptValue(const cppexpose::Variant & var)
{
    if (var.hasType<char>()) {
        return QJSValue(var.value<char>());
    }

    else if (var.hasType<unsigned char>()) {
        return QJSValue(var.value<unsigned char>());
    }

    else if (var.hasType<short>()) {
        return QJSValue(var.value<short>());
    }

    else if (var.hasType<unsigned short>()) {
        return QJSValue(var.value<unsigned short>());
    }

    else if (var.hasType<int>()) {
        return QJSValue(var.value<int>());
    }

    else if (var.hasType<unsigned int>()) {
        return QJSValue(var.value<unsigned int>());
    }

    else if (var.hasType<long>()) {
        return QJSValue(var.value<int>());
    }

    else if (var.hasType<unsigned long>()) {
        return QJSValue(var.value<unsigned int>());
    }

    else if (var.hasType<long long>()) {
        return QJSValue(var.value<int>());
    }

    else if (var.hasType<unsigned long long>()) {
        return QJSValue(var.value<unsigned int>());
    }

    else if (var.hasType<float>()) {
        return QJSValue(var.value<float>());
    }

    else if (var.hasType<double>()) {
        return QJSValue(var.value<double>());
    }

    else if (var.hasType<char*>()) {
        return QJSValue(var.value<char*>());
    }

    else if (var.hasType<std::string>()) {
        return QJSValue(var.value<std::string>().c_str());
    }

    else if (var.hasType<bool>()) {
        return QJSValue(var.value<bool>());
    }

    else if (var.hasType<cppassist::FilePath>()) {
        return QJSValue(var.value<cppassist::FilePath>().path().c_str());
    }

    else if (var.isBool()) {
        return QJSValue(var.toBool());
    }

    else if (var.isUnsignedIntegral()) {
        return QJSValue((unsigned int)var.toULongLong());
    }

    else if (var.isSignedIntegral() || var.isIntegral()) {
        return QJSValue((int)var.toLongLong());
    }

    else if (var.isFloatingPoint()) {
        return QJSValue(var.toDouble());
    }

    else if (var.isString()) {
        return QJSValue(var.toString().c_str());
    }

    else if (var.hasType<gloperate::Image>()) {
        const gloperate::Image * image = var.ptr<gloperate::Image>();

        QImage conversion((unsigned char *) image->data(), image->width(), image->height(), QImage::Format_RGB32);

        QByteArray byteArray;
        QBuffer buffer(&byteArray);
        buffer.open(QIODevice::WriteOnly);
        conversion.save(&buffer, "PNG", 0);
        QString imgBase64 = QString::fromLatin1(byteArray.toBase64().data());

        return toScriptValue("data:image/png;base64," + imgBase64.toStdString());
    }

    else if (var.hasType<cppexpose::VariantArray>()) {
        QJSValue array = newArray();

        cppexpose::VariantArray variantArray = var.value<cppexpose::VariantArray>();
        for (unsigned int i=0; i<variantArray.size(); i++) {
            array.setProperty(i, toScriptValue(variantArray.at(i)));
        }

        return array;
    }

    else if (var.hasType<cppexpose::VariantMap>()) {
        QJSValue obj = newObject();

        cppexpose::VariantMap variantMap = var.value<cppexpose::VariantMap>();
        for (const std::pair<std::string, cppexpose::Variant> & pair : variantMap)
        {
            obj.setProperty(pair.first.c_str(), toScriptValue(pair.second));
        }

        return obj;
    }

    else if (var.hasType<cppexpose::Object *>()) {
        const auto object = var.value<cppexpose::Object *>();

        return getOrCreateObjectWrapper(object)->wrapObject();
    }

    else {
        return QJSValue();
    }
}

cppexpose::Variant QmlEngine::fromQVariant(const QVariant & value)
{
    if (value.type() == QVariant::Bool) {
        return cppexpose::Variant(value.toBool());
    }

    else if (value.type() == QVariant::Char || value.type() == QVariant::Int) {
        return cppexpose::Variant(value.toInt());
    }

    else if (value.type() == QVariant::UInt) {
        return cppexpose::Variant(value.toUInt());
    }

    else if (value.type() == QVariant::LongLong) {
        return cppexpose::Variant(value.toLongLong());
    }

    else if (value.type() == QVariant::ULongLong) {
        return cppexpose::Variant(value.toULongLong());
    }

    else if (value.type() == QVariant::Double) {
        return cppexpose::Variant(value.toDouble());
    }

    else if (value.type() == QVariant::StringList)
    {
        cppexpose::VariantArray array;

        QStringList list = value.toStringList();
        for (QStringList::iterator it = list.begin(); it != list.end(); ++it)
        {
            array.push_back(cppexpose::Variant((*it).toStdString()) );
        }

        return array;
    }

    else if (value.type() == QVariant::List)
    {
        cppexpose::VariantArray array;

        QList<QVariant> list = value.toList();
        for (QList<QVariant>::iterator it = list.begin(); it != list.end(); ++it)
        {
            array.push_back(fromQVariant(*it));
        }

        return array;
    }

    else if (value.type() == QVariant::Map)
    {
        cppexpose::VariantMap obj;

        QMap<QString, QVariant> map = value.toMap();
        for (QMap<QString, QVariant>::iterator it = map.begin(); it != map.end(); ++it)
        {
            std::string key = it.key().toStdString();
            obj[key] = fromQVariant(it.value());
        }

        return obj;
    }

    else if (value.type() == QVariant::String || value.canConvert(QVariant::String))
    {
        return cppexpose::Variant(value.toString().toStdString());
    }

    else if (value.canConvert<QJSValue>())
    {
        return fromScriptValue(value.value<QJSValue>());
    }

    else {
        return cppexpose::Variant();
    }
}

const QString & QmlEngine::gloperateModulePath() const
{
    return m_gloperateQmlPath;
}

QmlObjectWrapper * QmlEngine::getOrCreateObjectWrapper(cppexpose::Object * object)
{
    // Check if wrapper exists
    const auto itr = m_objectWrappers.find(object);
    if (itr != m_objectWrappers.end())
    {
        return itr->second.first;
    }

    // Wrap object
    const auto wrapper = new QmlObjectWrapper(this, object);

    // Delete wrapper when object is destroyed
    // The connection will be deleted when this backend is destroyed
    const auto beforeDestroy = object->beforeDestroy.connect([this, object](cppexpose::AbstractProperty *)
    {
        delete m_objectWrappers[object].first;
        m_objectWrappers.erase(object);
    });

    // Save wrapper for later
    m_objectWrappers[object] = {wrapper, beforeDestroy};

    return wrapper;
}

} // namespace gloperate_qtquick
<|endoftext|>


<commit_before>
/*
 *  client.cpp
 *
 *  Handles the client env.
 *
 *  Created by Ryan Faulkner on 2014-06-08
 *  Copyright (c) 2014. All rights reserved.
 */

#include <iostream>
#include <string>
#include <vector>
#include <regex>
#include <assert.h>

#include "column_types.h"
#include "redis.h"
#include "md5.h"
#include "index.h"

#define REDISHOST "127.0.0.1"
#define REDISPORT 6379

using namespace std;

/** Test to ensure that redis keys are correctly returned */
void testRedisSet() {
    RedisHandler r;
    r.connect();
    r.write("foo", "bar");
}

/** Test to ensure that redis keys are correctly returned */
void testRedisGet() {
    RedisHandler r;
    r.connect();
    cout << endl << "VALUE FOR KEY foo" << endl;
    cout << r.read("foo") << endl << endl;
}

/** Test to ensure that redis keys are correctly returned */
void testRedisKeys() {
    RedisHandler r;
    std::vector<std::string> vec;

    r.connect();
    vec = r.keys("*");
    cout << "KEY LIST FOR *" << endl;
    for (std::vector<std::string>::iterator it = vec.begin() ; it != vec.end(); ++it) {
        cout << *it << endl;
    }
    cout << endl;
}

/** Test to ensure that redis keys are correctly returned */
void testRedisIO() {
    RedisHandler r;
    std::vector<string>* vec;
    std::string outTrue, outFalse = "";

    r.connect();
    r.write("test_key", "test value");
    outTrue = r.read("test_key");
    assert(std::strcmp(outTrue.c_str(), "test value") == 0);
    r.deleteKey("test_key");
    assert(!r.exists("test_key"));
}

/** Test to ensure that md5 hashing works */
void testMd5Hashing() {
    cout << endl << "md5 of 'mykey': " << md5("mykey") << endl;
}

/** Test to ensure that md5 hashing works */
void testRegexForTypes() {
    IntegerColumn ic;
    FloatColumn fc;
    assert(ic.validate("1981"));
    assert(fc.validate("5.2"));
    cout << "Passed regex tests." << endl;
}

/** Test to ensure that md5 hashing works */
void testOrderPairAlphaNumeric() {
    IndexHandler ih;
    assert(std::strcmp(ih.orderPairAlphaNumeric("b", "a").c_str(), "a_b") == 0);
    cout << "Passed orderPairAlphaNumeric tests." << endl;
}

/**
 * Test to ensure that relation entities are encoded properly
 */
void testJSONEntityEncoding() {
    IndexHandler ih;
    Json::Value* ret;
    std::vector<std::pair<ColumnBase*, std::string>>* fields_ent = new vector<std::pair<ColumnBase*, std::string>>;
    fields_ent->push_back(std::make_pair(getColumnType("integer"), "a"));
    ih.writeEntity("test", fields_ent);
    // Fetch the entity representation
    ret = ih.fetchEntity("test");
    cout << ret->toStyledString() << endl;

    // TODO - assert
    // TODO - remove entity
}

/**
 * Test to ensure that relation fields are encoded properly
 */
void testRelationJSONRelationEncoding() {
//    IndexHandler ih;
//    std::vector<std::pair<ColumnBase*, std::string>>* fields_ent_1 = new vector<std::pair<ColumnBase*, std::string>>;
//    std::vector<std::pair<ColumnBase*, std::string>>* fields_ent_2 = new vector<std::pair<ColumnBase*, std::string>>;
//    std::vector<std::pair<std::string, std::string>>* fields_rel_1 = new vector<std::pair<ColumnBase*, std::string>>;
//    std::vector<std::pair<std::string, std::string>>* fields_rel_2 = new vector<std::pair<ColumnBase*, std::string>>;
//
//    // Popualate fields
//    fields_ent_1->push_back(std::make_pair(getColumnType("integer"), "a"));
//    fields_ent_2->push_back(std::make_pair(getColumnType("string"), "b"));
//    fields_rel_1->push_back(std::make_pair("a", "1"));
//    fields_rel_2->push_back(std::make_pair("b", "hello"));
//
//    // Create entities
//    ih.writeEntity("test_1", fields_ent_1);
//    ih.writeEntity("test_2", fields_ent_1);
//
//    // Create relation in redis
//    ih.writeRelation("test_1", "test_2", fields_rel_1, fields_rel_2)

    // Fetch the entity representation

    // assert
}

int main() {
    cout << "-- TESTS BEGIN --" << endl << endl;

//    testRedisSet();
//    testRedisGet();
//    testRedisKeys();
//    md5Hashing();
//    testRedisIO();
//    testRegexForTypes();
//    testOrderPairAlphaNumeric();
    testJSONEntityEncoding();

    cout << endl << "-- TESTS END --" << endl;

    return 0;
}
<commit_msg>flesh out functional portion of json encoding for relation test<commit_after>
/*
 *  client.cpp
 *
 *  Handles the client env.
 *
 *  Created by Ryan Faulkner on 2014-06-08
 *  Copyright (c) 2014. All rights reserved.
 */

#include <iostream>
#include <string>
#include <vector>
#include <regex>
#include <assert.h>

#include "column_types.h"
#include "redis.h"
#include "md5.h"
#include "index.h"

#define REDISHOST "127.0.0.1"
#define REDISPORT 6379

using namespace std;

/** Test to ensure that redis keys are correctly returned */
void testRedisSet() {
    RedisHandler r;
    r.connect();
    r.write("foo", "bar");
}

/** Test to ensure that redis keys are correctly returned */
void testRedisGet() {
    RedisHandler r;
    r.connect();
    cout << endl << "VALUE FOR KEY foo" << endl;
    cout << r.read("foo") << endl << endl;
}

/** Test to ensure that redis keys are correctly returned */
void testRedisKeys() {
    RedisHandler r;
    std::vector<std::string> vec;

    r.connect();
    vec = r.keys("*");
    cout << "KEY LIST FOR *" << endl;
    for (std::vector<std::string>::iterator it = vec.begin() ; it != vec.end(); ++it) {
        cout << *it << endl;
    }
    cout << endl;
}

/** Test to ensure that redis keys are correctly returned */
void testRedisIO() {
    RedisHandler r;
    std::vector<string>* vec;
    std::string outTrue, outFalse = "";

    r.connect();
    r.write("test_key", "test value");
    outTrue = r.read("test_key");
    assert(std::strcmp(outTrue.c_str(), "test value") == 0);
    r.deleteKey("test_key");
    assert(!r.exists("test_key"));
}

/** Test to ensure that md5 hashing works */
void testMd5Hashing() {
    cout << endl << "md5 of 'mykey': " << md5("mykey") << endl;
}

/** Test to ensure that md5 hashing works */
void testRegexForTypes() {
    IntegerColumn ic;
    FloatColumn fc;
    assert(ic.validate("1981"));
    assert(fc.validate("5.2"));
    cout << "Passed regex tests." << endl;
}

/** Test to ensure that md5 hashing works */
void testOrderPairAlphaNumeric() {
    IndexHandler ih;
    assert(std::strcmp(ih.orderPairAlphaNumeric("b", "a").c_str(), "a_b") == 0);
    cout << "Passed orderPairAlphaNumeric tests." << endl;
}

/**
 * Test to ensure that relation entities are encoded properly
 */
void testJSONEntityEncoding() {
    IndexHandler ih;
    Json::Value* ret;
    std::vector<std::pair<ColumnBase*, std::string>>* fields_ent = new vector<std::pair<ColumnBase*, std::string>>;
    fields_ent->push_back(std::make_pair(getColumnType("integer"), "a"));
    ih.writeEntity("test", fields_ent);
    // Fetch the entity representation
    ret = ih.fetchEntity("test");
    cout << ret->toStyledString() << endl;

    // TODO - assert
    // TODO - remove entity
}

/**
 * Test to ensure that relation fields are encoded properly
 */
void testJSONRelationEncoding() {
    IndexHandler ih;
    std::vector<Json::Value> ret;
    std::vector<std::pair<ColumnBase*, std::string>>* fields_ent_1 = new vector<std::pair<ColumnBase*, std::string>>;
    std::vector<std::pair<ColumnBase*, std::string>>* fields_ent_2 = new vector<std::pair<ColumnBase*, std::string>>;
    std::vector<std::pair<std::string, std::string>>* fields_rel_1 = new vector<std::pair<std::string, std::string>>;
    std::vector<std::pair<std::string, std::string>>* fields_rel_2 = new vector<std::pair<std::string, std::string>>;

    // Popualate fields
    fields_ent_1->push_back(std::make_pair(getColumnType("integer"), "a"));
    fields_ent_2->push_back(std::make_pair(getColumnType("string"), "b"));
    fields_rel_1->push_back(std::make_pair("a", "1"));
    fields_rel_2->push_back(std::make_pair("b", "hello"));

    // Create entities
    ih.writeEntity("test_1", fields_ent_1);
    ih.writeEntity("test_2", fields_ent_1);

    // Create relation in redis
    ih.writeRelation("test_1", "test_2", fields_rel_1, fields_rel_2);

    // Fetch the entity representation
    ret = ih.fetchRelationPrefix("test_1", "test_2");
    for (std::vector<Json::Value>::iterator it = ret.begin(); it != ret.end(); ++it)
        cout << (*it).toStyledString() << endl;

    // assert
}

int main() {
    cout << "-- TESTS BEGIN --" << endl << endl;

//    testRedisSet();
//    testRedisGet();
//    testRedisKeys();
//    md5Hashing();
//    testRedisIO();
//    testRegexForTypes();
//    testOrderPairAlphaNumeric();
    testJSONEntityEncoding();

    cout << endl << "-- TESTS END --" << endl;

    return 0;
}
<|endoftext|>


<commit_before>/**
 **
 ** This is free software: you can redistribute it and/or modify
 ** it under the terms of the GNU General Public License as published by
 ** the Free Software Foundation, either version 3 of the License, or
 ** (at your option) any later version.
 **
 ** This software is distributed in the hope that it will be useful,
 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 ** GNU General Public License for more details.
 **
 ** You should have received a copy of the GNU General Public License
 ** along with this software. If not, see <http://www.gnu.org/licenses/>.
 **
 **/
#include "codeclean.h"
#include "cstdout_test.h"
#include "cstdin_test.h"
#include "bag_test.h"
#include "edge_test.h"

using com::goffersoft::codeclean::codeclean;
using com::goffersoft::codeclean::testsuite;
using edu::princeton::cs::algs4::cstdout_testsuite;
using edu::princeton::cs::algs4::cstdin_testsuite;
using edu::princeton::cs::algs4::bag_testsuite;
using edu::princeton::cs::algs4::edge_testsuite;

int test_main(int argc, const char **argv) {
    codeclean tests;
    tests.add_testsuite(cstdout_testsuite());
    tests.add_testsuite(cstdin_testsuite());
    tests.add_testsuite(bag_testsuite());
    tests.add_testsuite(edge_testsuite());
    tests.run();
    tests.print_report();

    return 0;
}
<commit_msg>add graph testsuite<commit_after>/**
 **
 ** This is free software: you can redistribute it and/or modify
 ** it under the terms of the GNU General Public License as published by
 ** the Free Software Foundation, either version 3 of the License, or
 ** (at your option) any later version.
 **
 ** This software is distributed in the hope that it will be useful,
 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 ** GNU General Public License for more details.
 **
 ** You should have received a copy of the GNU General Public License
 ** along with this software. If not, see <http://www.gnu.org/licenses/>.
 **
 **/
#include "codeclean.h"
#include "cstdout_test.h"
#include "cstdin_test.h"
#include "bag_test.h"
#include "edge_test.h"
#include "graph_test.h"

using com::goffersoft::codeclean::codeclean;
using com::goffersoft::codeclean::testsuite;
using edu::princeton::cs::algs4::cstdout_testsuite;
using edu::princeton::cs::algs4::cstdin_testsuite;
using edu::princeton::cs::algs4::bag_testsuite;
using edu::princeton::cs::algs4::edge_testsuite;
using edu::princeton::cs::algs4::graph_testsuite;

int test_main(int argc, const char **argv) {
    codeclean tests;
    tests.add_testsuite(cstdout_testsuite());
    tests.add_testsuite(cstdin_testsuite());
    tests.add_testsuite(bag_testsuite());
    tests.add_testsuite(edge_testsuite());
    tests.add_testsuite(graph_testsuite());
    tests.run();
    tests.print_report();

    return 0;
}
<|endoftext|>