<commit_before>/******************************************************************************
* Copyright (c) 2013, Howard Butler (hobu.inc@gmail.com)
* Copyright (c) 2014, Bradley J Chambers (brad.chambers@gmail.com)
*
* 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 Hobu, Inc. or Flaxen Geo Consulting 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.
****************************************************************************/

#pragma once

#include <pdal/kernel/Kernel.hpp>
#include <pdal/kernel/Delta.hpp>
#include <pdal/kernel/Diff.hpp>
#include <pdal/kernel/Info.hpp>
#include <pdal/kernel/Pipeline.hpp>
#include <pdal/kernel/Query.hpp>
#include <pdal/kernel/Random.hpp>
#include <pdal/kernel/Sort.hpp>
#include <pdal/kernel/Support.hpp>
#include <pdal/kernel/Translate.hpp>
<commit_msg>Query is OBE<commit_after>/******************************************************************************
* Copyright (c) 2013, Howard Butler (hobu.inc@gmail.com)
* Copyright (c) 2014, Bradley J Chambers (brad.chambers@gmail.com)
*
* 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 Hobu, Inc. or Flaxen Geo Consulting 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.
****************************************************************************/

#pragma once

#include <pdal/kernel/Kernel.hpp>
#include <pdal/kernel/Delta.hpp>
#include <pdal/kernel/Diff.hpp>
#include <pdal/kernel/Info.hpp>
#include <pdal/kernel/Pipeline.hpp>
#include <pdal/kernel/Random.hpp>
#include <pdal/kernel/Sort.hpp>
#include <pdal/kernel/Support.hpp>
#include <pdal/kernel/Translate.hpp>
<|endoftext|>


<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2015 Artem Pavlenko
 *
 * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

#include "catch.hpp"

#include <mapnik/map.hpp>
#include <mapnik/datasource.hpp>
#include <mapnik/datasource_cache.hpp>
#include <mapnik/geometry.hpp>
#include <mapnik/util/fs.hpp>

TEST_CASE("geojson") {

    std::string geojson_plugin("./plugins/input/geojson.input");
    if (mapnik::util::exists(geojson_plugin))
    {
        SECTION("json feature cache-feature=\"true\"")
        {
            // Create datasource
            mapnik::parameters params;
            params["type"] = "geojson";
            params["file"] = "./test/data/json/feature.json";
            params["cache-features"] = true;
            auto ds = mapnik::datasource_cache::instance().create(params);
            REQUIRE(bool(ds));
            auto fields = ds->get_descriptor().get_descriptors();
            mapnik::query query(ds->envelope());
            for (auto const &field : fields)
            {
                query.add_property_name(field.get_name());
            }
            auto features = ds->features(query);
            REQUIRE(features != nullptr);
            auto feature = features->next();
            REQUIRE(feature != nullptr);
        }

        SECTION("json feature cache-feature=\"false\"")
        {
            mapnik::parameters params;
            params["type"] = "geojson";
            params["file"] = "./test/data/json/feature.json";
            params["cache-features"] = false;
            auto ds = mapnik::datasource_cache::instance().create(params);
            REQUIRE(bool(ds));
            auto fields = ds->get_descriptor().get_descriptors();
            mapnik::query query(ds->envelope());
            for (auto const &field : fields)
            {
                query.add_property_name(field.get_name());
            }
            auto features = ds->features(query);
            REQUIRE(features != nullptr);
            auto feature = features->next();
            REQUIRE(feature != nullptr);
        }

        SECTION("json extra properties cache-feature=\"true\"")
        {
            // Create datasource
            mapnik::parameters params;
            params["type"] = "geojson";
            params["file"] = "./test/data/json/feature_collection_extra_properties.json";
            params["cache-features"] = true;
            auto ds = mapnik::datasource_cache::instance().create(params);
            REQUIRE(bool(ds));
            auto fields = ds->get_descriptor().get_descriptors();
            mapnik::query query(ds->envelope());
            for (auto const &field : fields)
            {
                query.add_property_name(field.get_name());
            }
            auto features = ds->features(query);
            REQUIRE(features != nullptr);
            auto feature = features->next();
            REQUIRE(feature != nullptr);
            REQUIRE(feature->envelope() == mapnik::box2d<double>(123,456,123,456));
        }

        SECTION("json extra properties cache-feature=\"false\"")
        {
            // Create datasource
            mapnik::parameters params;
            params["type"] = "geojson";
            params["file"] = "./test/data/json/feature_collection_extra_properties.json";
            params["cache-features"] = false;
            auto ds = mapnik::datasource_cache::instance().create(params);
            REQUIRE(bool(ds));
            auto fields = ds->get_descriptor().get_descriptors();
            mapnik::query query(ds->envelope());
            for (auto const &field : fields)
            {
                query.add_property_name(field.get_name());
            }
            auto features = ds->features(query);
            REQUIRE(features != nullptr);
            auto feature = features->next();
            REQUIRE(feature != nullptr);
            REQUIRE(feature->envelope() == mapnik::box2d<double>(123,456,123,456));
        }
        SECTION("json - ensure input fully consumed and throw exception otherwise")
        {
            mapnik::parameters params;
            params["type"] = "geojson";
            params["file"] = "./test/data/json/points-malformed.geojson"; // mismatched parentheses
            params["cache-features"] = false;
            REQUIRE_THROWS(mapnik::datasource_cache::instance().create(params));
            params["cache-features"] = true;
            REQUIRE_THROWS(mapnik::datasource_cache::instance().create(params));
        }
    }
}
<commit_msg>unit test(geojson) - add tests reading all geometry primitives<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2015 Artem Pavlenko
 *
 * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

#include "catch.hpp"

#include <mapnik/map.hpp>
#include <mapnik/datasource.hpp>
#include <mapnik/datasource_cache.hpp>
#include <mapnik/geometry.hpp>
#include <mapnik/geometry_type.hpp>
#include <mapnik/util/fs.hpp>

namespace detail {

mapnik::feature_ptr fetch_first_feature(std::string const& filename, bool cache_features)
{
    mapnik::parameters params;
    params["type"] = "geojson";
    params["file"] = filename;
    params["cache-features"] = cache_features;
    auto ds = mapnik::datasource_cache::instance().create(params);
    auto fields = ds->get_descriptor().get_descriptors();
    mapnik::query query(ds->envelope());
    for (auto const& field : fields)
    {
        query.add_property_name(field.get_name());
    }
    auto features = ds->features(query);
    auto feature = features->next();
    return feature;
}

}

TEST_CASE("geojson") {

    std::string geojson_plugin("./plugins/input/geojson.input");
    if (mapnik::util::exists(geojson_plugin))
    {
        SECTION("GeoJSON Point")
        {
            {
                // cache features in memory
                auto feature = detail::fetch_first_feature("./test/data/json/point.json", true);
                // test
                auto const& geometry = feature->get_geometry();
                REQUIRE(mapnik::geometry::geometry_type(geometry) == mapnik::geometry::Point);
                auto const& pt = mapnik::util::get<mapnik::geometry::point<double> >(geometry);
                REQUIRE(pt.x == 100);
                REQUIRE(pt.y == 0);
            }
            {
                // on-fly in-memory r-tree index + read features from disk
                auto feature = detail::fetch_first_feature("./test/data/json/point.json", false);
                // test
                auto const& geometry = feature->get_geometry();
                REQUIRE(mapnik::geometry::geometry_type(geometry) == mapnik::geometry::Point);
                auto const& pt = mapnik::util::get<mapnik::geometry::point<double> >(geometry);
                REQUIRE(pt.x == 100);
                REQUIRE(pt.y == 0);
            }
        }

        SECTION("GeoJSON LineString")
        {
            mapnik::parameters params;
            params["type"] = "geojson";
            params["file"] = "./test/data/json/linestring.json";

            {
                // cache features in memory
                auto feature = detail::fetch_first_feature("./test/data/json/linestring.json", true);
                // test
                auto const& geometry = feature->get_geometry();
                REQUIRE(mapnik::geometry::geometry_type(geometry) == mapnik::geometry::LineString);
                auto const& line = mapnik::util::get<mapnik::geometry::line_string<double> >(geometry);
                REQUIRE(line.size() == 2);
                REQUIRE(mapnik::geometry::envelope(line) == mapnik::box2d<double>(100,0,101,1));

            }
            {
                // on-fly in-memory r-tree index + read features from disk
                auto feature = detail::fetch_first_feature("./test/data/json/linestring.json", false);
                // test
                auto const& geometry = feature->get_geometry();
                REQUIRE(mapnik::geometry::geometry_type(geometry) == mapnik::geometry::LineString);
                auto const& line = mapnik::util::get<mapnik::geometry::line_string<double> >(geometry);
                REQUIRE(line.size() == 2);
                REQUIRE(mapnik::geometry::envelope(line) == mapnik::box2d<double>(100,0,101,1));
            }
        }

        SECTION("GeoJSON Polygon")
        {
            mapnik::parameters params;
            params["type"] = "geojson";
            params["file"] = "./test/data/json/polygon.json";

            {
                // cache features in memory
                auto feature = detail::fetch_first_feature("./test/data/json/polygon.json", true);
                // test
                auto const& geometry = feature->get_geometry();
                REQUIRE(mapnik::geometry::geometry_type(geometry) == mapnik::geometry::Polygon);
                auto const& poly = mapnik::util::get<mapnik::geometry::polygon<double> >(geometry);
                REQUIRE(poly.num_rings() == 2);
                REQUIRE(poly.exterior_ring.size() == 5);
                REQUIRE(poly.interior_rings.size() == 1);
                REQUIRE(poly.interior_rings[0].size() == 5);
                REQUIRE(mapnik::geometry::envelope(poly) == mapnik::box2d<double>(100,0,101,1));

            }
            {
                // on-fly in-memory r-tree index + read features from disk
                auto feature = detail::fetch_first_feature("./test/data/json/polygon.json", false);
                // test
                auto const& geometry = feature->get_geometry();
                REQUIRE(mapnik::geometry::geometry_type(geometry) == mapnik::geometry::Polygon);
                auto const& poly = mapnik::util::get<mapnik::geometry::polygon<double> >(geometry);
                REQUIRE(poly.num_rings() == 2);
                REQUIRE(poly.exterior_ring.size() == 5);
                REQUIRE(poly.interior_rings.size() == 1);
                REQUIRE(poly.interior_rings[0].size() == 5);
                REQUIRE(mapnik::geometry::envelope(poly) == mapnik::box2d<double>(100,0,101,1));
            }
        }

        SECTION("GeoJSON MultiPoint")
        {
            {
                // cache features in memory
                auto feature = detail::fetch_first_feature("./test/data/json/multipoint.json", true);
                // test
                auto const& geometry = feature->get_geometry();
                REQUIRE(mapnik::geometry::geometry_type(geometry) == mapnik::geometry::MultiPoint);
                auto const& multi_pt = mapnik::util::get<mapnik::geometry::multi_point<double> >(geometry);
                REQUIRE(multi_pt.size() == 2);
                REQUIRE(mapnik::geometry::envelope(multi_pt) == mapnik::box2d<double>(100,0,101,1));
            }
            {
                // on-fly in-memory r-tree index + read features from disk
                auto feature = detail::fetch_first_feature("./test/data/json/multipoint.json", false);
                // test
                auto const& geometry = feature->get_geometry();
                REQUIRE(mapnik::geometry::geometry_type(geometry) == mapnik::geometry::MultiPoint);
                auto const& multi_pt = mapnik::util::get<mapnik::geometry::multi_point<double> >(geometry);
                REQUIRE(multi_pt.size() == 2);
                REQUIRE(mapnik::geometry::envelope(multi_pt) == mapnik::box2d<double>(100,0,101,1));
            }
        }

        SECTION("GeoJSON MultiLineString")
        {
            {
                // cache features in memory
                auto feature = detail::fetch_first_feature("./test/data/json/multilinestring.json", true);
                // test
                auto const& geometry = feature->get_geometry();
                REQUIRE(mapnik::geometry::geometry_type(geometry) == mapnik::geometry::MultiLineString);
                auto const& multi_line = mapnik::util::get<mapnik::geometry::multi_line_string<double> >(geometry);
                REQUIRE(multi_line.size() == 2);
                REQUIRE(multi_line[0].size() == 2);
                REQUIRE(multi_line[1].size() == 2);
                REQUIRE(mapnik::geometry::envelope(multi_line) == mapnik::box2d<double>(100,0,103,3));

            }
            {
                // on-fly in-memory r-tree index + read features from disk
                auto feature = detail::fetch_first_feature("./test/data/json/multilinestring.json", false);
                // test
                auto const& geometry = feature->get_geometry();
                REQUIRE(mapnik::geometry::geometry_type(geometry) == mapnik::geometry::MultiLineString);
                auto const& multi_line = mapnik::util::get<mapnik::geometry::multi_line_string<double> >(geometry);
                REQUIRE(multi_line.size() == 2);
                REQUIRE(multi_line[0].size() == 2);
                REQUIRE(multi_line[1].size() == 2);
                REQUIRE(mapnik::geometry::envelope(multi_line) == mapnik::box2d<double>(100,0,103,3));
            }
        }

        SECTION("GeoJSON MultiPolygon")
        {
            {
                // cache features in memory
                auto feature = detail::fetch_first_feature("./test/data/json/multipolygon.json", true);
                // test
                auto const& geometry = feature->get_geometry();
                REQUIRE(mapnik::geometry::geometry_type(geometry) == mapnik::geometry::MultiPolygon);
                auto const& multi_poly = mapnik::util::get<mapnik::geometry::multi_polygon<double> >(geometry);
                REQUIRE(multi_poly.size() == 2);
                REQUIRE(multi_poly[0].num_rings() == 1);
                REQUIRE(multi_poly[1].num_rings() == 2);
                REQUIRE(mapnik::geometry::envelope(multi_poly) == mapnik::box2d<double>(100,0,103,3));

            }
            {
                // on-fly in-memory r-tree index + read features from disk
                auto feature = detail::fetch_first_feature("./test/data/json/multipolygon.json", false);
                // test
                auto const& geometry = feature->get_geometry();
                REQUIRE(mapnik::geometry::geometry_type(geometry) == mapnik::geometry::MultiPolygon);
                auto const& multi_poly = mapnik::util::get<mapnik::geometry::multi_polygon<double> >(geometry);
                REQUIRE(multi_poly.size() == 2);
                REQUIRE(multi_poly[0].num_rings() == 1);
                REQUIRE(multi_poly[1].num_rings() == 2);
                REQUIRE(mapnik::geometry::envelope(multi_poly) == mapnik::box2d<double>(100,0,103,3));
            }
        }

        SECTION("GeoJSON GeometryCollection")
        {
            {
                // cache features in memory
                auto feature = detail::fetch_first_feature("./test/data/json/geometrycollection.json", true);
                // test
                auto const& geometry = feature->get_geometry();
                REQUIRE(mapnik::geometry::geometry_type(geometry) == mapnik::geometry::GeometryCollection);
                auto const& collection = mapnik::util::get<mapnik::geometry::geometry_collection<double> >(geometry);
                REQUIRE(collection.size() == 2);
                REQUIRE(mapnik::geometry::geometry_type(collection[0]) == mapnik::geometry::Point);
                REQUIRE(mapnik::geometry::geometry_type(collection[1]) == mapnik::geometry::LineString);
                REQUIRE(mapnik::geometry::envelope(collection) == mapnik::box2d<double>(100,0,102,1));
            }
            {
                // cache features in memory
                auto feature = detail::fetch_first_feature("./test/data/json/geometrycollection.json", false);
                // test
                auto const& geometry = feature->get_geometry();
                REQUIRE(mapnik::geometry::geometry_type(geometry) == mapnik::geometry::GeometryCollection);
                auto const& collection = mapnik::util::get<mapnik::geometry::geometry_collection<double> >(geometry);
                REQUIRE(collection.size() == 2);
                REQUIRE(mapnik::geometry::geometry_type(collection[0]) == mapnik::geometry::Point);
                REQUIRE(mapnik::geometry::geometry_type(collection[1]) == mapnik::geometry::LineString);
                REQUIRE(mapnik::geometry::envelope(collection) == mapnik::box2d<double>(100,0,102,1));
            }
        }

        SECTION("json feature cache-feature=\"true\"")
        {
            // Create datasource
            mapnik::parameters params;
            params["type"] = "geojson";
            params["file"] = "./test/data/json/feature.json";
            params["cache-features"] = true;
            auto ds = mapnik::datasource_cache::instance().create(params);
            REQUIRE(bool(ds));
            auto fields = ds->get_descriptor().get_descriptors();
            mapnik::query query(ds->envelope());
            for (auto const& field : fields)
            {
                query.add_property_name(field.get_name());
            }
            auto features = ds->features(query);
            REQUIRE(features != nullptr);
            auto feature = features->next();
            REQUIRE(feature != nullptr);
        }

        SECTION("json feature cache-feature=\"false\"")
        {
            mapnik::parameters params;
            params["type"] = "geojson";
            params["file"] = "./test/data/json/feature.json";
            params["cache-features"] = false;
            auto ds = mapnik::datasource_cache::instance().create(params);
            REQUIRE(bool(ds));
            auto fields = ds->get_descriptor().get_descriptors();
            mapnik::query query(ds->envelope());
            for (auto const& field : fields)
            {
                query.add_property_name(field.get_name());
            }
            auto features = ds->features(query);
            REQUIRE(features != nullptr);
            auto feature = features->next();
            REQUIRE(feature != nullptr);
        }

        SECTION("json extra properties cache-feature=\"true\"")
        {
            // Create datasource
            mapnik::parameters params;
            params["type"] = "geojson";
            params["file"] = "./test/data/json/feature_collection_extra_properties.json";
            params["cache-features"] = true;
            auto ds = mapnik::datasource_cache::instance().create(params);
            REQUIRE(bool(ds));
            auto fields = ds->get_descriptor().get_descriptors();
            mapnik::query query(ds->envelope());
            for (auto const& field : fields)
            {
                query.add_property_name(field.get_name());
            }
            auto features = ds->features(query);
            REQUIRE(features != nullptr);
            auto feature = features->next();
            REQUIRE(feature != nullptr);
            REQUIRE(feature->envelope() == mapnik::box2d<double>(123,456,123,456));
        }

        SECTION("json extra properties cache-feature=\"false\"")
        {
            // Create datasource
            mapnik::parameters params;
            params["type"] = "geojson";
            params["file"] = "./test/data/json/feature_collection_extra_properties.json";
            params["cache-features"] = false;
            auto ds = mapnik::datasource_cache::instance().create(params);
            REQUIRE(bool(ds));
            auto fields = ds->get_descriptor().get_descriptors();
            mapnik::query query(ds->envelope());
            for (auto const& field : fields)
            {
                query.add_property_name(field.get_name());
            }
            auto features = ds->features(query);
            REQUIRE(features != nullptr);
            auto feature = features->next();
            REQUIRE(feature != nullptr);
            REQUIRE(feature->envelope() == mapnik::box2d<double>(123,456,123,456));
        }
        SECTION("json - ensure input fully consumed and throw exception otherwise")
        {
            mapnik::parameters params;
            params["type"] = "geojson";
            params["file"] = "./test/data/json/points-malformed.geojson"; // mismatched parentheses
            params["cache-features"] = false;
            REQUIRE_THROWS(mapnik::datasource_cache::instance().create(params));
            params["cache-features"] = true;
            REQUIRE_THROWS(mapnik::datasource_cache::instance().create(params));
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Fix a bug in TF1Convolution::SetExtraRange<commit_after><|endoftext|>


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

#include "chrome/browser/chromeos/policy/remote_commands/device_command_reboot_job.h"

#include <algorithm>

#include "base/bind.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/sys_info.h"
#include "base/time/time.h"
#include "chromeos/dbus/power_manager_client.h"
#include "policy/proto/device_management_backend.pb.h"

namespace policy {

namespace {

// Determines the time, measured from the time of issue, after which the command
// queue will consider this command expired if the command has not been started.
const int kCommandExpirationTimeInMinutes = 10;

// Determines the minimum uptime after which a reboot might be scheduled. Note:
// |kCommandExpirationTimeInMinutes| >= |kMinimumUptimeInMinutes| as
// otherwise, a valid command issued right after boot may time out.
const int kMinimumUptimeInMinutes = 10;

}  // namespace

DeviceCommandRebootJob::DeviceCommandRebootJob(
    chromeos::PowerManagerClient* power_manager_client)
    : power_manager_client_(power_manager_client), weak_ptr_factory_(this) {
  CHECK(power_manager_client_);
}

DeviceCommandRebootJob::~DeviceCommandRebootJob() {
}

enterprise_management::RemoteCommand_Type DeviceCommandRebootJob::GetType()
    const {
  return enterprise_management::RemoteCommand_Type_DEVICE_REBOOT;
}

bool DeviceCommandRebootJob::IsExpired(base::Time now) {
  return now > issued_time() + base::TimeDelta::FromMinutes(
                                   kCommandExpirationTimeInMinutes);
}

void DeviceCommandRebootJob::RunImpl(
    const SucceededCallback& succeeded_callback,
    const FailedCallback& failed_callback) {
  // Determines the time delta between the command having been issued and the
  // boot time of the system.
  const base::TimeDelta uptime =
      base::TimeDelta::FromMilliseconds(base::SysInfo::Uptime());
  const base::Time boot_time = base::Time::Now() - uptime;
  const base::TimeDelta delta = boot_time - issued_time();
  // If the reboot command was issued before the system booted, we inform the
  // server that the reboot succeeded. Otherwise, the reboot must still be
  // performed and we invoke it. |kMinimumUptimeInMinutes| defines a lower limit
  // on the uptime to avoid uninterruptable reboot loops.
  if (delta > base::TimeDelta()) {
    succeeded_callback.Run(nullptr);
    return;
  }

  const base::TimeDelta kZeroTimeDelta;
  reboot_timer_.Start(
      FROM_HERE,
      std::max(base::TimeDelta::FromMinutes(kMinimumUptimeInMinutes) - uptime,
               kZeroTimeDelta),
      base::Bind(&DeviceCommandRebootJob::Reboot,
                 weak_ptr_factory_.GetWeakPtr()));
}

void DeviceCommandRebootJob::TerminateImpl() {
  weak_ptr_factory_.InvalidateWeakPtrs();
}

base::TimeDelta DeviceCommandRebootJob::GetCommmandTimeout() const {
  return base::TimeDelta::FromMinutes(kMinimumUptimeInMinutes);
}

void DeviceCommandRebootJob::Reboot() const {
  power_manager_client_->RequestRestart();
}

}  // namespace policy
<commit_msg>Call callback asynchronously for device reboot command<commit_after>// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/chromeos/policy/remote_commands/device_command_reboot_job.h"

#include <algorithm>

#include "base/bind.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/single_thread_task_runner.h"
#include "base/sys_info.h"
#include "base/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "chromeos/dbus/power_manager_client.h"
#include "policy/proto/device_management_backend.pb.h"

namespace policy {

namespace {

// Determines the time, measured from the time of issue, after which the command
// queue will consider this command expired if the command has not been started.
const int kCommandExpirationTimeInMinutes = 10;

// Determines the minimum uptime after which a reboot might be scheduled. Note:
// |kCommandExpirationTimeInMinutes| >= |kMinimumUptimeInMinutes| as
// otherwise, a valid command issued right after boot may time out.
const int kMinimumUptimeInMinutes = 10;

}  // namespace

DeviceCommandRebootJob::DeviceCommandRebootJob(
    chromeos::PowerManagerClient* power_manager_client)
    : power_manager_client_(power_manager_client), weak_ptr_factory_(this) {
  CHECK(power_manager_client_);
}

DeviceCommandRebootJob::~DeviceCommandRebootJob() {
}

enterprise_management::RemoteCommand_Type DeviceCommandRebootJob::GetType()
    const {
  return enterprise_management::RemoteCommand_Type_DEVICE_REBOOT;
}

bool DeviceCommandRebootJob::IsExpired(base::Time now) {
  return now > issued_time() + base::TimeDelta::FromMinutes(
                                   kCommandExpirationTimeInMinutes);
}

void DeviceCommandRebootJob::RunImpl(
    const SucceededCallback& succeeded_callback,
    const FailedCallback& failed_callback) {
  // Determines the time delta between the command having been issued and the
  // boot time of the system.
  const base::TimeDelta uptime =
      base::TimeDelta::FromMilliseconds(base::SysInfo::Uptime());
  const base::Time boot_time = base::Time::Now() - uptime;
  const base::TimeDelta delta = boot_time - issued_time();
  // If the reboot command was issued before the system booted, we inform the
  // server that the reboot succeeded. Otherwise, the reboot must still be
  // performed and we invoke it. |kMinimumUptimeInMinutes| defines a lower limit
  // on the uptime to avoid uninterruptable reboot loops.
  if (delta > base::TimeDelta()) {
    base::ThreadTaskRunnerHandle::Get()->PostTask(
        FROM_HERE, base::Bind(succeeded_callback, nullptr));
    return;
  }

  const base::TimeDelta kZeroTimeDelta;
  reboot_timer_.Start(
      FROM_HERE,
      std::max(base::TimeDelta::FromMinutes(kMinimumUptimeInMinutes) - uptime,
               kZeroTimeDelta),
      base::Bind(&DeviceCommandRebootJob::Reboot,
                 weak_ptr_factory_.GetWeakPtr()));
}

void DeviceCommandRebootJob::TerminateImpl() {
  weak_ptr_factory_.InvalidateWeakPtrs();
}

base::TimeDelta DeviceCommandRebootJob::GetCommmandTimeout() const {
  return base::TimeDelta::FromMinutes(kMinimumUptimeInMinutes);
}

void DeviceCommandRebootJob::Reboot() const {
  power_manager_client_->RequestRestart();
}

}  // namespace policy
<|endoftext|>


<commit_before>#include "RTSAttackComponent.h"
#include "RTSPluginPCH.h"

#include "Engine/World.h"
#include "GameFramework/Pawn.h"

#include "RTSProjectile.h"

URTSAttackComponent::URTSAttackComponent(const FObjectInitializer& ObjectInitializer)
	: Super(ObjectInitializer)
{
	PrimaryComponentTick.bCanEverTick = true;
}

void URTSAttackComponent::TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction)
{
	// Update cooldown timer.
	if (RemainingCooldown > 0)
	{
		RemainingCooldown -= DeltaTime;

		if (RemainingCooldown <= 0)
		{
			UE_LOG(LogRTS, Log, TEXT("Actor %s attack is ready again."), *GetOwner()->GetName());

			// Notify listeners.
			OnCooldownReady.Broadcast();
		}
	}
}

void URTSAttackComponent::UseAttack(int32 AttackIndex, AActor* Target)
{
	AActor* Owner = GetOwner();
	APawn* OwnerPawn = Cast<APawn>(Owner);
	AController* OwnerController = OwnerPawn ? OwnerPawn->GetController() : nullptr;

	if (!IsValid(Target))
	{
		return;
	}

	// Check cooldown.
	if (RemainingCooldown > 0)
	{
		return;
	}

	// Use attack.
	UE_LOG(LogRTS, Log, TEXT("Actor %s attacks %s."), *Owner->GetName(), *Target->GetName());

	const FRTSAttackData& Attack = Attacks[0];

	ARTSProjectile* SpawnedProjectile = nullptr;

	if (Attack.ProjectileClass != nullptr)
	{
		// Fire projectile.
		// Build spawn transform.
		FVector SpawnLocation = Owner->GetActorLocation();
		FRotator SpawnRotation = Owner->GetActorRotation();
		FTransform SpawnTransform = FTransform(SpawnRotation, SpawnLocation);

		// Build spawn info.
		FActorSpawnParameters SpawnInfo;
		SpawnInfo.Instigator = OwnerPawn;
		SpawnInfo.ObjectFlags |= RF_Transient;

		// Spawn projectile.
		SpawnedProjectile = GetWorld()->SpawnActor<ARTSProjectile>(Attack.ProjectileClass, SpawnTransform, SpawnInfo);

		if (SpawnedProjectile)
		{
			UE_LOG(LogRTS, Log, TEXT("%s fired projectile %s at target %s."), *Owner->GetName(), *SpawnedProjectile->GetName(), *Target->GetName());

			// Aim at target.
			SpawnedProjectile->FireAt(
				Target,
				Attack.Damage,
				Attack.DamageType,
				OwnerController,
				Owner);
		}
	}
	else
	{
		// Deal damage immediately.
		Target->TakeDamage(Attack.Damage, FDamageEvent(Attack.DamageType), OwnerController, Owner);
	}

	// Start cooldown timer.
	RemainingCooldown = Attack.Cooldown;

	// Notify listeners.
	OnAttackUsed.Broadcast(Attack, Target, SpawnedProjectile);
}
<commit_msg>Move pre-compiled header first in attack component.<commit_after>#include "RTSPluginPCH.h"
#include "RTSAttackComponent.h"

#include "Engine/World.h"
#include "GameFramework/Pawn.h"

#include "RTSProjectile.h"

URTSAttackComponent::URTSAttackComponent(const FObjectInitializer& ObjectInitializer)
	: Super(ObjectInitializer)
{
	PrimaryComponentTick.bCanEverTick = true;
}

void URTSAttackComponent::TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction)
{
	// Update cooldown timer.
	if (RemainingCooldown > 0)
	{
		RemainingCooldown -= DeltaTime;

		if (RemainingCooldown <= 0)
		{
			UE_LOG(LogRTS, Log, TEXT("Actor %s attack is ready again."), *GetOwner()->GetName());

			// Notify listeners.
			OnCooldownReady.Broadcast();
		}
	}
}

void URTSAttackComponent::UseAttack(int32 AttackIndex, AActor* Target)
{
	AActor* Owner = GetOwner();
	APawn* OwnerPawn = Cast<APawn>(Owner);
	AController* OwnerController = OwnerPawn ? OwnerPawn->GetController() : nullptr;

	if (!IsValid(Target))
	{
		return;
	}

	// Check cooldown.
	if (RemainingCooldown > 0)
	{
		return;
	}

	// Use attack.
	UE_LOG(LogRTS, Log, TEXT("Actor %s attacks %s."), *Owner->GetName(), *Target->GetName());

	const FRTSAttackData& Attack = Attacks[0];

	ARTSProjectile* SpawnedProjectile = nullptr;

	if (Attack.ProjectileClass != nullptr)
	{
		// Fire projectile.
		// Build spawn transform.
		FVector SpawnLocation = Owner->GetActorLocation();
		FRotator SpawnRotation = Owner->GetActorRotation();
		FTransform SpawnTransform = FTransform(SpawnRotation, SpawnLocation);

		// Build spawn info.
		FActorSpawnParameters SpawnInfo;
		SpawnInfo.Instigator = OwnerPawn;
		SpawnInfo.ObjectFlags |= RF_Transient;

		// Spawn projectile.
		SpawnedProjectile = GetWorld()->SpawnActor<ARTSProjectile>(Attack.ProjectileClass, SpawnTransform, SpawnInfo);

		if (SpawnedProjectile)
		{
			UE_LOG(LogRTS, Log, TEXT("%s fired projectile %s at target %s."), *Owner->GetName(), *SpawnedProjectile->GetName(), *Target->GetName());

			// Aim at target.
			SpawnedProjectile->FireAt(
				Target,
				Attack.Damage,
				Attack.DamageType,
				OwnerController,
				Owner);
		}
	}
	else
	{
		// Deal damage immediately.
		Target->TakeDamage(Attack.Damage, FDamageEvent(Attack.DamageType), OwnerController, Owner);
	}

	// Start cooldown timer.
	RemainingCooldown = Attack.Cooldown;

	// Notify listeners.
	OnAttackUsed.Broadcast(Attack, Target, SpawnedProjectile);
}
<|endoftext|>


<commit_before>// $Id$
//***************************************************************************
// File:
//	MachineInstr.cpp
//
// Purpose:
//
//
// Strategy:
//
// History:
//	7/2/01	 -  Vikram Adve  -  Created
//**************************************************************************/

#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/ConstPoolVals.h"
#include "llvm/Instruction.h"
#include <strstream>

//************************ Class Implementations **************************/

// Constructor for instructions with fixed #operands (nearly all)
MachineInstr::MachineInstr(MachineOpCode _opCode,
			   OpCodeMask    _opCodeMask)
  : opCode(_opCode),
    opCodeMask(_opCodeMask),
    operands(TargetInstrDescriptors[_opCode].numOperands)
{
  assert(TargetInstrDescriptors[_opCode].numOperands >= 0);
}

// Constructor for instructions with variable #operands
MachineInstr::MachineInstr(MachineOpCode _opCode,
			   unsigned	 numOperands,
			   OpCodeMask    _opCodeMask)
  : opCode(_opCode),
    opCodeMask(_opCodeMask),
    operands(numOperands)
{
}

void
MachineInstr::SetMachineOperand(unsigned int i,
				MachineOperand::MachineOperandType operandType,
				Value* _val, bool isdef=false)
{
  assert(i < operands.size());
  operands[i].Initialize(operandType, _val);
  operands[i].isDef = isdef;
}

void
MachineInstr::SetMachineOperand(unsigned int i,
				MachineOperand::MachineOperandType operandType,
				int64_t intValue, bool isdef=false)
{
  assert(i < operands.size());
  operands[i].InitializeConst(operandType, intValue);
  operands[i].isDef = isdef;
}

void
MachineInstr::SetMachineOperand(unsigned int i,
				unsigned int regNum, bool isdef=false)
{
  assert(i < operands.size());
  operands[i].InitializeReg(regNum);
  operands[i].isDef = isdef;
}

void
MachineInstr::dump(unsigned int indent) const
{
  for (unsigned i=0; i < indent; i++)
    cout << "    ";

  cout << *this;
}

ostream&
operator<< (ostream& os, const MachineInstr& minstr)
{
  os << TargetInstrDescriptors[minstr.opCode].opCodeString;

  for (unsigned i=0, N=minstr.getNumOperands(); i < N; i++)
    os << "\t" << minstr.getOperand(i);

#undef DEBUG_VAL_OP_ITERATOR
#ifdef DEBUG_VAL_OP_ITERATOR
  os << endl << "\tValue operands are: ";
  for (MachineInstr::val_op_const_iterator vo(&minstr); ! vo.done(); ++vo)
    {
      const Value* val = *vo;
      os << val << (vo.isDef()? "(def), " : ", ");
    }
  os << endl;
#endif

  return os;
}

ostream&
operator<< (ostream& os, const MachineOperand& mop)
{
  strstream regInfo;
  if (mop.opType == MachineOperand::MO_VirtualRegister)
    regInfo << "(val " << mop.value << ")" << ends;
  else if (mop.opType == MachineOperand::MO_MachineRegister)
    regInfo << "("       << mop.regNum << ")" << ends;
  else if (mop.opType == MachineOperand::MO_CCRegister)
    regInfo << "(val " << mop.value << ")" << ends;

  switch(mop.opType)
    {
    case MachineOperand::MO_VirtualRegister:
    case MachineOperand::MO_MachineRegister:
      os << "%reg" << regInfo.str();
      free(regInfo.str());
      break;

    case MachineOperand::MO_CCRegister:
      os << "%ccreg" << regInfo.str();
      free(regInfo.str());
      break;

    case MachineOperand::MO_SignExtendedImmed:
      os << mop.immedVal;
      break;

    case MachineOperand::MO_UnextendedImmed:
      os << mop.immedVal;
      break;

    case MachineOperand::MO_PCRelativeDisp:
      os << "%disp(label " << mop.value << ")";
      break;

    default:
      assert(0 && "Unrecognized operand type");
      break;
    }

  return os;
}

//---------------------------------------------------------------------------
// Target-independent utility routines for creating machine instructions
//---------------------------------------------------------------------------

//------------------------------------------------------------------------
// Function Set2OperandsFromInstr
// Function Set3OperandsFromInstr
//
// For the common case of 2- and 3-operand arithmetic/logical instructions,
// set the m/c instr. operands directly from the VM instruction's operands.
// Check whether the first or second operand is 0 and can use a dedicated "0" register.
// Check whether the second operand should use an immediate field or register.
// (First and third operands are never immediates for such instructions.)
//
// Arguments:
// canDiscardResult: Specifies that the result operand can be discarded
//		     by using the dedicated "0"
//
// op1position, op2position and resultPosition: Specify in which position
//		     in the machine instruction the 3 operands (arg1, arg2
//		     and result) should go.
//
// RETURN VALUE: unsigned int flags, where
//	flags & 0x01	=> operand 1 is constant and needs a register
//	flags & 0x02	=> operand 2 is constant and needs a register
//------------------------------------------------------------------------

void
Set2OperandsFromInstr(MachineInstr* minstr,
		      InstructionNode* vmInstrNode,
		      const TargetMachine& target,
		      bool canDiscardResult,
		      int op1Position,
		      int resultPosition)
{
  Set3OperandsFromInstr(minstr, vmInstrNode, target,
			canDiscardResult, op1Position,
			/*op2Position*/ -1, resultPosition);
}

#undef REVERT_TO_EXPLICIT_CONSTANT_CHECKS
#ifdef REVERT_TO_EXPLICIT_CONSTANT_CHECKS
unsigned
Set3OperandsFromInstrJUNK(MachineInstr* minstr,
		      InstructionNode* vmInstrNode,
		      const TargetMachine& target,
		      bool canDiscardResult,
		      int op1Position,
		      int op2Position,
		      int resultPosition)
{
  assert(op1Position >= 0);
  assert(resultPosition >= 0);

  unsigned returnFlags = 0x0;

  // Check if operand 1 is 0 and if so, try to use the register that gives 0, if any.
  Value* op1Value = vmInstrNode->leftChild()->getValue();
  bool isValidConstant;
  int64_t intValue = GetConstantValueAsSignedInt(op1Value, isValidConstant);
  if (isValidConstant && intValue == 0 && target.zeroRegNum >= 0)
    minstr->SetMachineOperand(op1Position, /*regNum*/ target.zeroRegNum);
  else
    {
      if (op1Value->getValueType() == Value::ConstantVal)
	{// value is constant and must be loaded from constant pool
	  returnFlags = returnFlags | (1 << op1Position);
	}
      minstr->SetMachineOperand(op1Position,MachineOperand::MO_VirtualRegister,
					    op1Value);
    }

  // Check if operand 2 (if any) fits in the immediate field of the instruction,
  // of if it is 0 and can use a dedicated machine register
  if (op2Position >= 0)
    {
      Value* op2Value = vmInstrNode->rightChild()->getValue();
      int64_t immedValue;
      unsigned int machineRegNum;

      MachineOperand::MachineOperandType
	op2type = ChooseRegOrImmed(op2Value, minstr->getOpCode(), target,
				   /*canUseImmed*/ true,
				   machineRegNum, immedValue);

      if (op2type == MachineOperand::MO_MachineRegister)
	minstr->SetMachineOperand(op2Position, machineRegNum);
      else if (op2type == MachineOperand::MO_VirtualRegister)
	{
	  if (op2Value->getValueType() == Value::ConstantVal)
	    {// value is constant and must be loaded from constant pool
	      returnFlags = returnFlags | (1 << op2Position);
	    }
	  minstr->SetMachineOperand(op2Position, op2type, op2Value);
	}
      else
	{
	  assert(op2type != MO_CCRegister);
	  minstr->SetMachineOperand(op2Position, op2type, immedValue);
	}
    }

  // If operand 3 (result) can be discarded, use a dead register if one exists
  if (canDiscardResult && target.zeroRegNum >= 0)
    minstr->SetMachineOperand(resultPosition, target.zeroRegNum);
  else
    minstr->SetMachineOperand(resultPosition, MachineOperand::MO_VirtualRegister, vmInstrNode->getValue());

  return returnFlags;
}
#endif

void
Set3OperandsFromInstr(MachineInstr* minstr,
		      InstructionNode* vmInstrNode,
		      const TargetMachine& target,
		      bool canDiscardResult,
		      int op1Position,
		      int op2Position,
		      int resultPosition)
{
  assert(op1Position >= 0);
  assert(resultPosition >= 0);

  // operand 1
  minstr->SetMachineOperand(op1Position, MachineOperand::MO_VirtualRegister,
			    vmInstrNode->leftChild()->getValue());

  // operand 2 (if any)
  if (op2Position >= 0)
    minstr->SetMachineOperand(op2Position, MachineOperand::MO_VirtualRegister,
			      vmInstrNode->rightChild()->getValue());

  // result operand: if it can be discarded, use a dead register if one exists
  if (canDiscardResult && target.zeroRegNum >= 0)
    minstr->SetMachineOperand(resultPosition, target.zeroRegNum);
  else
    minstr->SetMachineOperand(resultPosition, MachineOperand::MO_VirtualRegister, vmInstrNode->getValue());
}

MachineOperand::MachineOperandType
ChooseRegOrImmed(Value* val,
		 MachineOpCode opCode,
		 const TargetMachine& target,
		 bool canUseImmed,
		 unsigned int& getMachineRegNum,
		 int64_t& getImmedValue)
{
  MachineOperand::MachineOperandType opType =
    MachineOperand::MO_VirtualRegister;
  getMachineRegNum = 0;
  getImmedValue = 0;

  // Check for the common case first: argument is not constant
  //
  if (val->getValueType() != Value::ConstantVal)
    return opType;

  // Now get the constant value and check if it fits in the IMMED field.
  // Take advantage of the fact that the max unsigned value will rarely
  // fit into any IMMED field and ignore that case (i.e., cast smaller
  // unsigned constants to signed).
  //
  bool isValidConstant;
  int64_t intValue = GetConstantValueAsSignedInt(val, isValidConstant);

  if (isValidConstant)
    {
      if (intValue == 0 && target.zeroRegNum >= 0)
	{
	  opType = MachineOperand::MO_MachineRegister;
	  getMachineRegNum = target.zeroRegNum;
	}
      else if (canUseImmed &&
	       target.getInstrInfo().constantFitsInImmedField(opCode,intValue))
	{
	  opType = MachineOperand::MO_SignExtendedImmed;
	  getImmedValue = intValue;
	}
    }

  return opType;
}
<commit_msg>Changed SetMachineOpernad calls in Set3OperandsFromInstr so that the result position is a def (i.e., added true to the end of call) -- Ruchira<commit_after>// $Id$
//***************************************************************************
// File:
//	MachineInstr.cpp
//
// Purpose:
//
//
// Strategy:
//
// History:
//	7/2/01	 -  Vikram Adve  -  Created
//**************************************************************************/

#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/ConstPoolVals.h"
#include "llvm/Instruction.h"
#include <strstream>

//************************ Class Implementations **************************/

// Constructor for instructions with fixed #operands (nearly all)
MachineInstr::MachineInstr(MachineOpCode _opCode,
			   OpCodeMask    _opCodeMask)
  : opCode(_opCode),
    opCodeMask(_opCodeMask),
    operands(TargetInstrDescriptors[_opCode].numOperands)
{
  assert(TargetInstrDescriptors[_opCode].numOperands >= 0);
}

// Constructor for instructions with variable #operands
MachineInstr::MachineInstr(MachineOpCode _opCode,
			   unsigned	 numOperands,
			   OpCodeMask    _opCodeMask)
  : opCode(_opCode),
    opCodeMask(_opCodeMask),
    operands(numOperands)
{
}

void
MachineInstr::SetMachineOperand(unsigned int i,
				MachineOperand::MachineOperandType operandType,
				Value* _val, bool isdef=false)
{
  assert(i < operands.size());
  operands[i].Initialize(operandType, _val);
  operands[i].isDef = isdef;
}

void
MachineInstr::SetMachineOperand(unsigned int i,
				MachineOperand::MachineOperandType operandType,
				int64_t intValue, bool isdef=false)
{
  assert(i < operands.size());
  operands[i].InitializeConst(operandType, intValue);
  operands[i].isDef = isdef;
}

void
MachineInstr::SetMachineOperand(unsigned int i,
				unsigned int regNum, bool isdef=false)
{
  assert(i < operands.size());
  operands[i].InitializeReg(regNum);
  operands[i].isDef = isdef;
}

void
MachineInstr::dump(unsigned int indent) const
{
  for (unsigned i=0; i < indent; i++)
    cout << "    ";

  cout << *this;
}

ostream&
operator<< (ostream& os, const MachineInstr& minstr)
{
  os << TargetInstrDescriptors[minstr.opCode].opCodeString;

  for (unsigned i=0, N=minstr.getNumOperands(); i < N; i++)
    os << "\t" << minstr.getOperand(i);

#undef DEBUG_VAL_OP_ITERATOR
#ifdef DEBUG_VAL_OP_ITERATOR
  os << endl << "\tValue operands are: ";
  for (MachineInstr::val_op_const_iterator vo(&minstr); ! vo.done(); ++vo)
    {
      const Value* val = *vo;
      os << val << (vo.isDef()? "(def), " : ", ");
    }
  os << endl;
#endif

  return os;
}

ostream&
operator<< (ostream& os, const MachineOperand& mop)
{
  strstream regInfo;
  if (mop.opType == MachineOperand::MO_VirtualRegister)
    regInfo << "(val " << mop.value << ")" << ends;
  else if (mop.opType == MachineOperand::MO_MachineRegister)
    regInfo << "("       << mop.regNum << ")" << ends;
  else if (mop.opType == MachineOperand::MO_CCRegister)
    regInfo << "(val " << mop.value << ")" << ends;

  switch(mop.opType)
    {
    case MachineOperand::MO_VirtualRegister:
    case MachineOperand::MO_MachineRegister:
      os << "%reg" << regInfo.str();
      free(regInfo.str());
      break;

    case MachineOperand::MO_CCRegister:
      os << "%ccreg" << regInfo.str();
      free(regInfo.str());
      break;

    case MachineOperand::MO_SignExtendedImmed:
      os << mop.immedVal;
      break;

    case MachineOperand::MO_UnextendedImmed:
      os << mop.immedVal;
      break;

    case MachineOperand::MO_PCRelativeDisp:
      os << "%disp(label " << mop.value << ")";
      break;

    default:
      assert(0 && "Unrecognized operand type");
      break;
    }

  return os;
}

//---------------------------------------------------------------------------
// Target-independent utility routines for creating machine instructions
//---------------------------------------------------------------------------

//------------------------------------------------------------------------
// Function Set2OperandsFromInstr
// Function Set3OperandsFromInstr
//
// For the common case of 2- and 3-operand arithmetic/logical instructions,
// set the m/c instr. operands directly from the VM instruction's operands.
// Check whether the first or second operand is 0 and can use a dedicated "0" register.
// Check whether the second operand should use an immediate field or register.
// (First and third operands are never immediates for such instructions.)
//
// Arguments:
// canDiscardResult: Specifies that the result operand can be discarded
//		     by using the dedicated "0"
//
// op1position, op2position and resultPosition: Specify in which position
//		     in the machine instruction the 3 operands (arg1, arg2
//		     and result) should go.
//
// RETURN VALUE: unsigned int flags, where
//	flags & 0x01	=> operand 1 is constant and needs a register
//	flags & 0x02	=> operand 2 is constant and needs a register
//------------------------------------------------------------------------

void
Set2OperandsFromInstr(MachineInstr* minstr,
		      InstructionNode* vmInstrNode,
		      const TargetMachine& target,
		      bool canDiscardResult,
		      int op1Position,
		      int resultPosition)
{
  Set3OperandsFromInstr(minstr, vmInstrNode, target,
			canDiscardResult, op1Position,
			/*op2Position*/ -1, resultPosition);
}

#undef REVERT_TO_EXPLICIT_CONSTANT_CHECKS
#ifdef REVERT_TO_EXPLICIT_CONSTANT_CHECKS
unsigned
Set3OperandsFromInstrJUNK(MachineInstr* minstr,
		      InstructionNode* vmInstrNode,
		      const TargetMachine& target,
		      bool canDiscardResult,
		      int op1Position,
		      int op2Position,
		      int resultPosition)
{
  assert(op1Position >= 0);
  assert(resultPosition >= 0);

  unsigned returnFlags = 0x0;

  // Check if operand 1 is 0 and if so, try to use the register that gives 0, if any.
  Value* op1Value = vmInstrNode->leftChild()->getValue();
  bool isValidConstant;
  int64_t intValue = GetConstantValueAsSignedInt(op1Value, isValidConstant);
  if (isValidConstant && intValue == 0 && target.zeroRegNum >= 0)
    minstr->SetMachineOperand(op1Position, /*regNum*/ target.zeroRegNum);
  else
    {
      if (op1Value->getValueType() == Value::ConstantVal)
	{// value is constant and must be loaded from constant pool
	  returnFlags = returnFlags | (1 << op1Position);
	}
      minstr->SetMachineOperand(op1Position,MachineOperand::MO_VirtualRegister,
					    op1Value);
    }

  // Check if operand 2 (if any) fits in the immediate field of the instruction,
  // of if it is 0 and can use a dedicated machine register
  if (op2Position >= 0)
    {
      Value* op2Value = vmInstrNode->rightChild()->getValue();
      int64_t immedValue;
      unsigned int machineRegNum;

      MachineOperand::MachineOperandType
	op2type = ChooseRegOrImmed(op2Value, minstr->getOpCode(), target,
				   /*canUseImmed*/ true,
				   machineRegNum, immedValue);

      if (op2type == MachineOperand::MO_MachineRegister)
	minstr->SetMachineOperand(op2Position, machineRegNum);
      else if (op2type == MachineOperand::MO_VirtualRegister)
	{
	  if (op2Value->getValueType() == Value::ConstantVal)
	    {// value is constant and must be loaded from constant pool
	      returnFlags = returnFlags | (1 << op2Position);
	    }
	  minstr->SetMachineOperand(op2Position, op2type, op2Value);
	}
      else
	{
	  assert(op2type != MO_CCRegister);
	  minstr->SetMachineOperand(op2Position, op2type, immedValue);
	}
    }

  // If operand 3 (result) can be discarded, use a dead register if one exists
  if (canDiscardResult && target.zeroRegNum >= 0)
    minstr->SetMachineOperand(resultPosition, target.zeroRegNum, true);
  else
    minstr->SetMachineOperand(resultPosition, MachineOperand::MO_VirtualRegister, vmInstrNode->getValue(), true);

  return returnFlags;
}
#endif

void
Set3OperandsFromInstr(MachineInstr* minstr,
		      InstructionNode* vmInstrNode,
		      const TargetMachine& target,
		      bool canDiscardResult,
		      int op1Position,
		      int op2Position,
		      int resultPosition)
{
  assert(op1Position >= 0);
  assert(resultPosition >= 0);

  // operand 1
  minstr->SetMachineOperand(op1Position, MachineOperand::MO_VirtualRegister,
			    vmInstrNode->leftChild()->getValue());

  // operand 2 (if any)
  if (op2Position >= 0)
    minstr->SetMachineOperand(op2Position, MachineOperand::MO_VirtualRegister,
			      vmInstrNode->rightChild()->getValue());

  // result operand: if it can be discarded, use a dead register if one exists
  if (canDiscardResult && target.zeroRegNum >= 0)
    minstr->SetMachineOperand(resultPosition, target.zeroRegNum, true);
  else
    minstr->SetMachineOperand(resultPosition, MachineOperand::MO_VirtualRegister, vmInstrNode->getValue(), true);
}

MachineOperand::MachineOperandType
ChooseRegOrImmed(Value* val,
		 MachineOpCode opCode,
		 const TargetMachine& target,
		 bool canUseImmed,
		 unsigned int& getMachineRegNum,
		 int64_t& getImmedValue)
{
  MachineOperand::MachineOperandType opType =
    MachineOperand::MO_VirtualRegister;
  getMachineRegNum = 0;
  getImmedValue = 0;

  // Check for the common case first: argument is not constant
  //
  if (val->getValueType() != Value::ConstantVal)
    return opType;

  // Now get the constant value and check if it fits in the IMMED field.
  // Take advantage of the fact that the max unsigned value will rarely
  // fit into any IMMED field and ignore that case (i.e., cast smaller
  // unsigned constants to signed).
  //
  bool isValidConstant;
  int64_t intValue = GetConstantValueAsSignedInt(val, isValidConstant);

  if (isValidConstant)
    {
      if (intValue == 0 && target.zeroRegNum >= 0)
	{
	  opType = MachineOperand::MO_MachineRegister;
	  getMachineRegNum = target.zeroRegNum;
	}
      else if (canUseImmed &&
	       target.getInstrInfo().constantFitsInImmedField(opCode,intValue))
	{
	  opType = MachineOperand::MO_SignExtendedImmed;
	  getImmedValue = intValue;
	}
    }

  return opType;
}
<|endoftext|>


<commit_before>/*
 * roimodel.cpp
 *
 * Created on: 02.02.2013
 * @author Ralph Schurade
 */
#include "roimodel.h"

#include "models.h"

#include "roibox.h"
#include "vptr.h"

#include "../gui/gl/glfunctions.h"

#include <QDebug>

ROIModel::ROIModel() :
    m_count( 0 )
{

}

ROIModel::~ROIModel()
{
}

int ROIModel::rowCount( const QModelIndex &parent ) const
{
    if ( parent.isValid() )
    {
        if ( (int)parent.internalId() == - 1 )
        {
            return m_rois[parent.row()].size() - 1;
        }
        else
        {
            return 0;
        }
    }
    else
    {
        return m_rois.size();
    }
}

int ROIModel::columnCount( const QModelIndex &parent ) const
{
    return 1;
}

QModelIndex ROIModel::index( int row, int column, const QModelIndex & parent ) const
{
    if ( parent.isValid() )
    {
        return createIndex( row, column, parent.row() );
    }
    else
    {
        return createIndex( row, column, -1 );
    }
}

QModelIndex ROIModel::parent( const QModelIndex & index ) const
{
    if ( (int)index.internalId() == -1 )
    {
        return QModelIndex();
    }
    else
    {
        return createIndex( index.internalId(), index.column(), -1 );
    }
}

QVariant ROIModel::data( const QModelIndex &index, int role ) const
{
    QVariant roi;
    if ( (int)index.internalId() == -1 )
    {
        if ( index.row() < m_rois.size() )
        {
            if ( m_rois[index.row()].size() > 0 )
            {
                roi = m_rois[index.row()][0];
            }
        }
    }
    else
    {
        if ( (int)index.internalId() < m_rois.size() )
        {
            if ( m_rois[index.internalId()].size() > index.row()+1 )
            {
                roi = m_rois[index.internalId()][index.row()+1];
            }
        }

    }
    switch ( role )
    {
        case Qt::CheckStateRole:
        {
            return VPtr<ROI>::asPtr( roi )->properties()->get( Fn::Property::D_ACTIVE );
            break;
        }
        case Qt::BackgroundColorRole:
        {
            return VPtr<ROI>::asPtr( roi )->properties()->get( Fn::Property::D_COLOR );
            break;
        }
        case Qt::DisplayRole:
        {
            switch ( (Fn::Property)index.column() )
            {
                case Fn::Property::D_POINTER:
                {
                    return roi;
                    break;
                }
                default:
                {
                    return VPtr<ROI>::asPtr( roi )->properties()->get( (Fn::Property)index.column() );
                    break;
                }
            }
            break;
        }
        default:
            break;
    }
    return QVariant();
}

QVariant ROIModel::headerData( int section, Qt::Orientation orientation, int role ) const
{
    switch ( role )
    {
        case Qt::DisplayRole:
        {
            if ( orientation == Qt::Horizontal )
            {
                return QString( Fn::Prop2String::s( (Fn::Property)section ) );
            }
            break;
        }
    }
    return QVariant();
}

bool ROIModel::setData( const QModelIndex &index, const QVariant &value, int role )
{
    switch ( role )
    {
        case Qt::CheckStateRole:
        {
            if ( (int)index.internalId() == -1 )
            {
                VPtr<ROI>::asPtr( m_rois[index.row()][0] )->properties()->set( Fn::Property::D_ACTIVE, !VPtr<ROI>::asPtr( m_rois[index.row()][0] )->properties()->get( Fn::Property::D_ACTIVE ).toBool() );
            }
            else
            {
                VPtr<ROI>::asPtr( m_rois[index.internalId()][index.row()+1] )->properties()->set( Fn::Property::D_ACTIVE, !VPtr<ROI>::asPtr( m_rois[index.internalId()][index.row()+1] )->properties()->get( Fn::Property::D_ACTIVE ).toBool() );
            }
            break;
        }
        case Qt::DisplayRole:
        {
            if ( index.column() == (int)Fn::Property::D_POINTER )
            {
                if ( (int)index.internalId() == -1 )
                {
                    m_rois[index.row()][0] = value;
                }
                else
                {
                    qDebug() << index.internalId() << index.row()+1;
                    m_rois[index.internalId()][index.row()+1] = value;
                }

                emit( dataChanged( QModelIndex(), QModelIndex() ) );
                return true;
            }

            if ( index.column() == (int)Fn::Property::D_UPDATED )
            {
                emit( dataChanged( QModelIndex(), QModelIndex() ) );
                return true;
            }
            if ( (int)index.internalId() == -1 )
            {
                VPtr<ROI>::asPtr( m_rois[index.row()][0] )->properties()->set( (Fn::Property)index.column(), value );
            }
            else
            {
                VPtr<ROI>::asPtr( m_rois[index.internalId()][index.row()+1] )->properties()->set( (Fn::Property)index.column(), value );
            }
            break;
        }
    }

    emit( dataChanged( index, index ) );

    return true;
}

Qt::ItemFlags ROIModel::flags( const QModelIndex& index ) const
{
    if ( !index.isValid() )
    {
        return Qt::ItemIsEnabled | Qt::ItemIsDropEnabled ;
    }

    Qt::ItemFlags defaultFlags = Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDropEnabled;
    if ( index.parent().isValid() )
    {
        defaultFlags |= Qt::ItemIsDragEnabled;
    }
    else
    {
        if ( m_rois.size() > index.row() && m_rois[index.row()].size() == 1 )
        {
            defaultFlags |= Qt::ItemIsDragEnabled;
        }
    }

    if ( index.column() == 0 )
    {
        defaultFlags |= Qt::ItemIsUserCheckable;
    }

    return defaultFlags;
}

bool ROIModel::insertRows( int row, int count, const QModelIndex &parent )
{
    ROI* newROI;
    if ( count == 0 )
    {
        //newROI = new ROIBox();
        newROI = GLFunctions::roi;
    }
    else
    {
        return false;
    }
    connect( newROI, SIGNAL( signalPropChanged( int ) ), this, SLOT( propChanged( int ) ) );

    if ( parent.isValid() )
    {
        // child box
        if ( parent.parent().isValid() )
        {
            // child box selected
            beginInsertRows( parent.parent(), m_rois[parent.parent().row()].size(), m_rois[parent.parent().row()].size() );
            newROI->properties()->set( Fn::Property::D_COLOR, VPtr<ROI>::asPtr( m_rois[parent.parent().row()][0] )->properties()->get( Fn::Property::D_COLOR ) );
            m_rois[parent.parent().row()].push_back( VPtr<ROI>::asQVariant( newROI ) );
            endInsertRows();
        }
        else
        {
            // top box selected
            beginInsertRows( parent, m_rois[parent.row()].size(), m_rois[parent.row()].size() );
            newROI->properties()->set( Fn::Property::D_COLOR, VPtr<ROI>::asPtr( m_rois[parent.row()][0] )->properties()->get( Fn::Property::D_COLOR ) );
            m_rois[parent.row()].push_back( VPtr<ROI>::asQVariant( newROI ) );
            endInsertRows();
        }
    }
    else
    {
        // nothing selected, insert top box
        QList<QVariant>l;
        l.push_back( VPtr<ROI>::asQVariant( newROI ) );
        beginInsertRows( QModelIndex(), m_rois.size(), m_rois.size() );
        m_rois.push_back( l );
        endInsertRows();

    }
    emit ( dataChanged( index( 0, 0 ), index( 0, 0 ) ) );
    return true;
}

bool ROIModel::removeRows( int row, int count, const QModelIndex &parent )
{
    if ( !parent.isValid() )
    {
        beginRemoveRows( QModelIndex(), row, row );
        m_rois.removeAt( row );
        endRemoveRows();
    }
    else
    {
        beginRemoveRows( parent, row, row );
        m_rois[parent.row()].removeAt( row + 1 );
        endRemoveRows();
    }

    emit ( dataChanged( QModelIndex(), QModelIndex() ) );
    return true;
}

void ROIModel::propChanged( int value )
{
    bool found = false;
    int ii = -1;
    int kk = -1;
    for ( int i = 0; i < m_rois.size(); ++i )
    {
        for ( int k = 0; k < m_rois[i].size(); ++k )
        {
            if ( value == VPtr<ROI>::asPtr( m_rois[i][k] )->properties()->get( Fn::Property::D_ID ).toInt() )
            {
                found = true;
                kk = k;
                break;
            }
        }
        if ( found )
        {
            ii = i;
            break;
        }
    }
    if ( found )
    {
        if ( kk == 0 )
        {

            QModelIndex parent;
            QModelIndex index = this->index( ii, 0, parent );
            emit ( dataChanged( index, index ) );
        }
        else
        {
            QModelIndex parent = this->index( ii, 0, QModelIndex() );
            QModelIndex index = this->index( kk - 1, 0, parent );
            emit ( dataChanged( index, index ) );
        }
    }
}

QModelIndexList ROIModel::match( const QModelIndex &start, int role, const QVariant &value, int hits, Qt::MatchFlags flags ) const
{
    QModelIndexList l;

    if ( role == Qt::DisplayRole )
    {
        for ( int i = 0; i < m_rois.size(); ++i )
        {
            for ( int k = 0; k < m_rois[i].size(); ++k )
            {
                if ( value.toInt() == VPtr<ROI>::asPtr( m_rois[i][k] )->properties()->get( Fn::Property::D_PICK_ID ).toInt() )
                {
                    if ( k == 0 )
                    {
                        l.push_back( createIndex( i, 0, -1 ) );
                    }
                    else
                    {
                        l.push_back( createIndex( k-1, 0, i ) );
                    }
                }
            }
        }
    }

    return l;
}

ROI* ROIModel::getRoi( int branch, int pos )
{
    qDebug() << m_rois.size() << m_rois[branch].size() << branch << pos;
    if ( branch < m_rois.size() && pos < m_rois[branch].size() )
    {
        qDebug() << "huhu";
        return VPtr<ROI>::asPtr( m_rois[branch][pos] );
    }
    else
    {
        return NULL;
    }
}
<commit_msg>removed debug messages<commit_after>/*
 * roimodel.cpp
 *
 * Created on: 02.02.2013
 * @author Ralph Schurade
 */
#include "roimodel.h"

#include "models.h"

#include "roibox.h"
#include "vptr.h"

#include "../gui/gl/glfunctions.h"

#include <QDebug>

ROIModel::ROIModel() :
    m_count( 0 )
{

}

ROIModel::~ROIModel()
{
}

int ROIModel::rowCount( const QModelIndex &parent ) const
{
    if ( parent.isValid() )
    {
        if ( (int)parent.internalId() == - 1 )
        {
            return m_rois[parent.row()].size() - 1;
        }
        else
        {
            return 0;
        }
    }
    else
    {
        return m_rois.size();
    }
}

int ROIModel::columnCount( const QModelIndex &parent ) const
{
    return 1;
}

QModelIndex ROIModel::index( int row, int column, const QModelIndex & parent ) const
{
    if ( parent.isValid() )
    {
        return createIndex( row, column, parent.row() );
    }
    else
    {
        return createIndex( row, column, -1 );
    }
}

QModelIndex ROIModel::parent( const QModelIndex & index ) const
{
    if ( (int)index.internalId() == -1 )
    {
        return QModelIndex();
    }
    else
    {
        return createIndex( index.internalId(), index.column(), -1 );
    }
}

QVariant ROIModel::data( const QModelIndex &index, int role ) const
{
    QVariant roi;
    if ( (int)index.internalId() == -1 )
    {
        if ( index.row() < m_rois.size() )
        {
            if ( m_rois[index.row()].size() > 0 )
            {
                roi = m_rois[index.row()][0];
            }
        }
    }
    else
    {
        if ( (int)index.internalId() < m_rois.size() )
        {
            if ( m_rois[index.internalId()].size() > index.row()+1 )
            {
                roi = m_rois[index.internalId()][index.row()+1];
            }
        }

    }
    switch ( role )
    {
        case Qt::CheckStateRole:
        {
            return VPtr<ROI>::asPtr( roi )->properties()->get( Fn::Property::D_ACTIVE );
            break;
        }
        case Qt::BackgroundColorRole:
        {
            return VPtr<ROI>::asPtr( roi )->properties()->get( Fn::Property::D_COLOR );
            break;
        }
        case Qt::DisplayRole:
        {
            switch ( (Fn::Property)index.column() )
            {
                case Fn::Property::D_POINTER:
                {
                    return roi;
                    break;
                }
                default:
                {
                    return VPtr<ROI>::asPtr( roi )->properties()->get( (Fn::Property)index.column() );
                    break;
                }
            }
            break;
        }
        default:
            break;
    }
    return QVariant();
}

QVariant ROIModel::headerData( int section, Qt::Orientation orientation, int role ) const
{
    switch ( role )
    {
        case Qt::DisplayRole:
        {
            if ( orientation == Qt::Horizontal )
            {
                return QString( Fn::Prop2String::s( (Fn::Property)section ) );
            }
            break;
        }
    }
    return QVariant();
}

bool ROIModel::setData( const QModelIndex &index, const QVariant &value, int role )
{
    switch ( role )
    {
        case Qt::CheckStateRole:
        {
            if ( (int)index.internalId() == -1 )
            {
                VPtr<ROI>::asPtr( m_rois[index.row()][0] )->properties()->set( Fn::Property::D_ACTIVE, !VPtr<ROI>::asPtr( m_rois[index.row()][0] )->properties()->get( Fn::Property::D_ACTIVE ).toBool() );
            }
            else
            {
                VPtr<ROI>::asPtr( m_rois[index.internalId()][index.row()+1] )->properties()->set( Fn::Property::D_ACTIVE, !VPtr<ROI>::asPtr( m_rois[index.internalId()][index.row()+1] )->properties()->get( Fn::Property::D_ACTIVE ).toBool() );
            }
            break;
        }
        case Qt::DisplayRole:
        {
            if ( index.column() == (int)Fn::Property::D_POINTER )
            {
                if ( (int)index.internalId() == -1 )
                {
                    m_rois[index.row()][0] = value;
                }
                else
                {
                    qDebug() << index.internalId() << index.row()+1;
                    m_rois[index.internalId()][index.row()+1] = value;
                }

                emit( dataChanged( QModelIndex(), QModelIndex() ) );
                return true;
            }

            if ( index.column() == (int)Fn::Property::D_UPDATED )
            {
                emit( dataChanged( QModelIndex(), QModelIndex() ) );
                return true;
            }
            if ( (int)index.internalId() == -1 )
            {
                VPtr<ROI>::asPtr( m_rois[index.row()][0] )->properties()->set( (Fn::Property)index.column(), value );
            }
            else
            {
                VPtr<ROI>::asPtr( m_rois[index.internalId()][index.row()+1] )->properties()->set( (Fn::Property)index.column(), value );
            }
            break;
        }
    }

    emit( dataChanged( index, index ) );

    return true;
}

Qt::ItemFlags ROIModel::flags( const QModelIndex& index ) const
{
    if ( !index.isValid() )
    {
        return Qt::ItemIsEnabled | Qt::ItemIsDropEnabled ;
    }

    Qt::ItemFlags defaultFlags = Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDropEnabled;
    if ( index.parent().isValid() )
    {
        defaultFlags |= Qt::ItemIsDragEnabled;
    }
    else
    {
        if ( m_rois.size() > index.row() && m_rois[index.row()].size() == 1 )
        {
            defaultFlags |= Qt::ItemIsDragEnabled;
        }
    }

    if ( index.column() == 0 )
    {
        defaultFlags |= Qt::ItemIsUserCheckable;
    }

    return defaultFlags;
}

bool ROIModel::insertRows( int row, int count, const QModelIndex &parent )
{
    ROI* newROI;
    if ( count == 0 )
    {
        //newROI = new ROIBox();
        newROI = GLFunctions::roi;
    }
    else
    {
        return false;
    }
    connect( newROI, SIGNAL( signalPropChanged( int ) ), this, SLOT( propChanged( int ) ) );

    if ( parent.isValid() )
    {
        // child box
        if ( parent.parent().isValid() )
        {
            // child box selected
            beginInsertRows( parent.parent(), m_rois[parent.parent().row()].size(), m_rois[parent.parent().row()].size() );
            newROI->properties()->set( Fn::Property::D_COLOR, VPtr<ROI>::asPtr( m_rois[parent.parent().row()][0] )->properties()->get( Fn::Property::D_COLOR ) );
            m_rois[parent.parent().row()].push_back( VPtr<ROI>::asQVariant( newROI ) );
            endInsertRows();
        }
        else
        {
            // top box selected
            beginInsertRows( parent, m_rois[parent.row()].size(), m_rois[parent.row()].size() );
            newROI->properties()->set( Fn::Property::D_COLOR, VPtr<ROI>::asPtr( m_rois[parent.row()][0] )->properties()->get( Fn::Property::D_COLOR ) );
            m_rois[parent.row()].push_back( VPtr<ROI>::asQVariant( newROI ) );
            endInsertRows();
        }
    }
    else
    {
        // nothing selected, insert top box
        QList<QVariant>l;
        l.push_back( VPtr<ROI>::asQVariant( newROI ) );
        beginInsertRows( QModelIndex(), m_rois.size(), m_rois.size() );
        m_rois.push_back( l );
        endInsertRows();

    }
    emit ( dataChanged( index( 0, 0 ), index( 0, 0 ) ) );
    return true;
}

bool ROIModel::removeRows( int row, int count, const QModelIndex &parent )
{
    if ( !parent.isValid() )
    {
        beginRemoveRows( QModelIndex(), row, row );
        m_rois.removeAt( row );
        endRemoveRows();
    }
    else
    {
        beginRemoveRows( parent, row, row );
        m_rois[parent.row()].removeAt( row + 1 );
        endRemoveRows();
    }

    emit ( dataChanged( QModelIndex(), QModelIndex() ) );
    return true;
}

void ROIModel::propChanged( int value )
{
    bool found = false;
    int ii = -1;
    int kk = -1;
    for ( int i = 0; i < m_rois.size(); ++i )
    {
        for ( int k = 0; k < m_rois[i].size(); ++k )
        {
            if ( value == VPtr<ROI>::asPtr( m_rois[i][k] )->properties()->get( Fn::Property::D_ID ).toInt() )
            {
                found = true;
                kk = k;
                break;
            }
        }
        if ( found )
        {
            ii = i;
            break;
        }
    }
    if ( found )
    {
        if ( kk == 0 )
        {

            QModelIndex parent;
            QModelIndex index = this->index( ii, 0, parent );
            emit ( dataChanged( index, index ) );
        }
        else
        {
            QModelIndex parent = this->index( ii, 0, QModelIndex() );
            QModelIndex index = this->index( kk - 1, 0, parent );
            emit ( dataChanged( index, index ) );
        }
    }
}

QModelIndexList ROIModel::match( const QModelIndex &start, int role, const QVariant &value, int hits, Qt::MatchFlags flags ) const
{
    QModelIndexList l;

    if ( role == Qt::DisplayRole )
    {
        for ( int i = 0; i < m_rois.size(); ++i )
        {
            for ( int k = 0; k < m_rois[i].size(); ++k )
            {
                if ( value.toInt() == VPtr<ROI>::asPtr( m_rois[i][k] )->properties()->get( Fn::Property::D_PICK_ID ).toInt() )
                {
                    if ( k == 0 )
                    {
                        l.push_back( createIndex( i, 0, -1 ) );
                    }
                    else
                    {
                        l.push_back( createIndex( k-1, 0, i ) );
                    }
                }
            }
        }
    }

    return l;
}

ROI* ROIModel::getRoi( int branch, int pos )
{
    if ( branch < m_rois.size() && pos < m_rois[branch].size() )
    {
        return VPtr<ROI>::asPtr( m_rois[branch][pos] );
    }
    else
    {
        return NULL;
    }
}
<|endoftext|>


<commit_before>/**
* @file llspeakbutton.cpp
* @brief LLSpeakButton class implementation
*
* $LicenseInfo:firstyear=2002&license=viewergpl$
*
* Copyright (c) 2002-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab.  Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/

#include "llviewerprecompiledheaders.h" // must be first include

#include "llbutton.h"
#include "llfloaterreg.h"

#include "llagent.h"
#include "llbottomtray.h"
#include "llcallfloater.h"
#include "lloutputmonitorctrl.h"
#include "lltransientfloatermgr.h"

#include "llspeakbutton.h"

static LLDefaultChildRegistry::Register<LLSpeakButton> t1("talk_button");

//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////

LLSpeakButton::Params::Params()
 : speak_button("speak_button")
 , show_button("show_button")
 , monitor("monitor")
{
	// See widgets/talk_button.xml
}

void LLSpeakButton::draw()
{
	// gVoiceClient is the authoritative global source of info regarding our open-mic state, we merely reflect that state.
	bool openmic = gVoiceClient->getUserPTTState();
	mSpeakBtn->setToggleState(openmic);
	LLUICtrl::draw();
}

LLSpeakButton::LLSpeakButton(const Params& p)
: LLUICtrl(p)
, mOutputMonitor(NULL)
, mSpeakBtn(NULL)
, mShowBtn(NULL)
{
	LLRect rect = p.rect();
	LLRect speak_rect(0, rect.getHeight(), rect.getWidth(), 0);
	LLRect show_rect = p.show_button.rect();
	show_rect.set(0, rect.getHeight(), show_rect.getWidth(), 0);

	speak_rect.mRight -= show_rect.getWidth();
	show_rect.mLeft = speak_rect.getWidth();
	show_rect.mRight = rect.getWidth();

	LLButton::Params speak_params = p.speak_button;
	speak_params.rect(speak_rect);
	mSpeakBtn = LLUICtrlFactory::create<LLButton>(speak_params);
	addChild(mSpeakBtn);
	LLTransientFloaterMgr::getInstance()->addControlView(mSpeakBtn);

	mSpeakBtn->setMouseDownCallback(boost::bind(&LLSpeakButton::onMouseDown_SpeakBtn, this));
	mSpeakBtn->setMouseUpCallback(boost::bind(&LLSpeakButton::onMouseUp_SpeakBtn, this));
	mSpeakBtn->setToggleState(FALSE);

	LLButton::Params show_params = p.show_button;
	show_params.rect(show_rect);
	mShowBtn = LLUICtrlFactory::create<LLButton>(show_params);
	addChild(mShowBtn);
	LLTransientFloaterMgr::getInstance()->addControlView(mShowBtn);

// 	mShowBtn->setClickedCallback(boost::bind(&LLSpeakButton::onClick_ShowBtn, this));
// 	mShowBtn->setToggleState(FALSE);

	static const S32 MONITOR_RIGHT_PAD = 2;

	LLRect monitor_rect = p.monitor.rect();
	S32 monitor_height = monitor_rect.getHeight();
	monitor_rect.mLeft = speak_rect.getWidth() - monitor_rect.getWidth() - MONITOR_RIGHT_PAD;
	monitor_rect.mRight = speak_rect.getWidth() - MONITOR_RIGHT_PAD;
	monitor_rect.mBottom = (rect.getHeight() / 2) - (monitor_height / 2);
	monitor_rect.mTop = monitor_rect.mBottom + monitor_height;

	LLOutputMonitorCtrl::Params monitor_params = p.monitor;
	monitor_params.draw_border(false);
	monitor_params.rect(monitor_rect);
	monitor_params.auto_update(true);
	monitor_params.speaker_id(gAgentID);
	mOutputMonitor = LLUICtrlFactory::create<LLOutputMonitorCtrl>(monitor_params);
	mSpeakBtn->addChild(mOutputMonitor);

	// never show "muted" because you can't mute yourself
	mOutputMonitor->setIsMuted(false);
	mOutputMonitor->setIsAgentControl(true);

	//*TODO find a better place to do that
	LLVoiceChannel::setCurrentVoiceChannelChangedCallback(boost::bind(&LLCallFloater::sOnCurrentChannelChanged, _1));
}

LLSpeakButton::~LLSpeakButton()
{
	LLTransientFloaterMgr::getInstance()->removeControlView(mSpeakBtn);
	LLTransientFloaterMgr::getInstance()->removeControlView(mShowBtn);
}

void LLSpeakButton::setSpeakToolTip(const std::string& msg)
{
	mSpeakBtn->setToolTip(msg);
}

void LLSpeakButton::setShowToolTip(const std::string& msg)
{
	mShowBtn->setToolTip(msg);
}

void LLSpeakButton::setLabelVisible(bool visible)
{
	static std::string label_selected = mSpeakBtn->getLabelSelected();
	static std::string label_unselected = mSpeakBtn->getLabelUnselected();

	if (visible)
	{
		mSpeakBtn->setLabelSelected(label_selected);
		mSpeakBtn->setLabelUnselected(label_unselected);
	}
	else
	{
		static LLStringExplicit empty_string("");
		mSpeakBtn->setLabelSelected(empty_string);
		mSpeakBtn->setLabelUnselected(empty_string);
	}
}

//////////////////////////////////////////////////////////////////////////
/// PROTECTED SECTION
//////////////////////////////////////////////////////////////////////////
void LLSpeakButton::onMouseDown_SpeakBtn()
{
	bool down = true;
	gVoiceClient->inputUserControlState(down); // this method knows/care about whether this translates into a toggle-to-talk or down-to-talk
}
void LLSpeakButton::onMouseUp_SpeakBtn()
{
	bool down = false;
	gVoiceClient->inputUserControlState(down);
}

<commit_msg>DEV-44564 'speak' button PTT-toggles and displays voice monitor even when voice disabled, gives wrong impression that you should be able to talk<commit_after>/**
* @file llspeakbutton.cpp
* @brief LLSpeakButton class implementation
*
* $LicenseInfo:firstyear=2002&license=viewergpl$
*
* Copyright (c) 2002-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab.  Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/

#include "llviewerprecompiledheaders.h" // must be first include

#include "llbutton.h"
#include "llfloaterreg.h"

#include "llagent.h"
#include "llbottomtray.h"
#include "llcallfloater.h"
#include "lloutputmonitorctrl.h"
#include "lltransientfloatermgr.h"

#include "llspeakbutton.h"

static LLDefaultChildRegistry::Register<LLSpeakButton> t1("talk_button");

//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////

LLSpeakButton::Params::Params()
 : speak_button("speak_button")
 , show_button("show_button")
 , monitor("monitor")
{
	// See widgets/talk_button.xml
}

void LLSpeakButton::draw()
{
	// gVoiceClient is the authoritative global source of info regarding our open-mic state, we merely reflect that state.
	bool openmic = gVoiceClient->getUserPTTState();
	bool voiceenabled = gVoiceClient->voiceEnabled();
	mSpeakBtn->setToggleState(openmic && voiceenabled);
	mOutputMonitor->setIsMuted(!voiceenabled);
	LLUICtrl::draw();
}

LLSpeakButton::LLSpeakButton(const Params& p)
: LLUICtrl(p)
, mOutputMonitor(NULL)
, mSpeakBtn(NULL)
, mShowBtn(NULL)
{
	LLRect rect = p.rect();
	LLRect speak_rect(0, rect.getHeight(), rect.getWidth(), 0);
	LLRect show_rect = p.show_button.rect();
	show_rect.set(0, rect.getHeight(), show_rect.getWidth(), 0);

	speak_rect.mRight -= show_rect.getWidth();
	show_rect.mLeft = speak_rect.getWidth();
	show_rect.mRight = rect.getWidth();

	LLButton::Params speak_params = p.speak_button;
	speak_params.rect(speak_rect);
	mSpeakBtn = LLUICtrlFactory::create<LLButton>(speak_params);
	addChild(mSpeakBtn);
	LLTransientFloaterMgr::getInstance()->addControlView(mSpeakBtn);

	mSpeakBtn->setMouseDownCallback(boost::bind(&LLSpeakButton::onMouseDown_SpeakBtn, this));
	mSpeakBtn->setMouseUpCallback(boost::bind(&LLSpeakButton::onMouseUp_SpeakBtn, this));
	mSpeakBtn->setToggleState(FALSE);

	LLButton::Params show_params = p.show_button;
	show_params.rect(show_rect);
	mShowBtn = LLUICtrlFactory::create<LLButton>(show_params);
	addChild(mShowBtn);
	LLTransientFloaterMgr::getInstance()->addControlView(mShowBtn);

// 	mShowBtn->setClickedCallback(boost::bind(&LLSpeakButton::onClick_ShowBtn, this));
// 	mShowBtn->setToggleState(FALSE);

	static const S32 MONITOR_RIGHT_PAD = 2;

	LLRect monitor_rect = p.monitor.rect();
	S32 monitor_height = monitor_rect.getHeight();
	monitor_rect.mLeft = speak_rect.getWidth() - monitor_rect.getWidth() - MONITOR_RIGHT_PAD;
	monitor_rect.mRight = speak_rect.getWidth() - MONITOR_RIGHT_PAD;
	monitor_rect.mBottom = (rect.getHeight() / 2) - (monitor_height / 2);
	monitor_rect.mTop = monitor_rect.mBottom + monitor_height;

	LLOutputMonitorCtrl::Params monitor_params = p.monitor;
	monitor_params.draw_border(false);
	monitor_params.rect(monitor_rect);
	monitor_params.auto_update(true);
	monitor_params.speaker_id(gAgentID);
	mOutputMonitor = LLUICtrlFactory::create<LLOutputMonitorCtrl>(monitor_params);
	mSpeakBtn->addChild(mOutputMonitor);

	// never show "muted" because you can't mute yourself
	mOutputMonitor->setIsMuted(false);
	mOutputMonitor->setIsAgentControl(true);

	//*TODO find a better place to do that
	LLVoiceChannel::setCurrentVoiceChannelChangedCallback(boost::bind(&LLCallFloater::sOnCurrentChannelChanged, _1));
}

LLSpeakButton::~LLSpeakButton()
{
	LLTransientFloaterMgr::getInstance()->removeControlView(mSpeakBtn);
	LLTransientFloaterMgr::getInstance()->removeControlView(mShowBtn);
}

void LLSpeakButton::setSpeakToolTip(const std::string& msg)
{
	mSpeakBtn->setToolTip(msg);
}

void LLSpeakButton::setShowToolTip(const std::string& msg)
{
	mShowBtn->setToolTip(msg);
}

void LLSpeakButton::setLabelVisible(bool visible)
{
	static std::string label_selected = mSpeakBtn->getLabelSelected();
	static std::string label_unselected = mSpeakBtn->getLabelUnselected();

	if (visible)
	{
		mSpeakBtn->setLabelSelected(label_selected);
		mSpeakBtn->setLabelUnselected(label_unselected);
	}
	else
	{
		static LLStringExplicit empty_string("");
		mSpeakBtn->setLabelSelected(empty_string);
		mSpeakBtn->setLabelUnselected(empty_string);
	}
}

//////////////////////////////////////////////////////////////////////////
/// PROTECTED SECTION
//////////////////////////////////////////////////////////////////////////
void LLSpeakButton::onMouseDown_SpeakBtn()
{
	bool down = true;
	gVoiceClient->inputUserControlState(down); // this method knows/care about whether this translates into a toggle-to-talk or down-to-talk
}
void LLSpeakButton::onMouseUp_SpeakBtn()
{
	bool down = false;
	gVoiceClient->inputUserControlState(down);
}

<|endoftext|>


<commit_before><commit_msg>p9_htm_setup (L2) - Part 2: HTM setup/reset/start<commit_after><|endoftext|>