<commit_before>//////////////////////////////////////////////////////////////////////////////
// Licensed to Qualys, Inc. (QUALYS) under one or more
// contributor license agreements.  See the NOTICE file distributed with
// this work for additional information regarding copyright ownership.
// QUALYS licenses this file to You 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.
//////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////
/// @file
/// @brief IronBee - Byte String Test Functions
///
/// @author Brian Rectanus <brectanus@qualys.com>
//////////////////////////////////////////////////////////////////////////////

#include "ironbee_config_auto.h"

#include "gtest/gtest.h"
#include "gtest/gtest-spi.h"

#include "util/util.c"
#include "util/mpool.c"
#include "util/bytestr.c"
#include "util/debug.c"

/* -- Tests -- */

/// @test Test util bytestr library - ib_bytestr_create() and ib_bytestr_destroy()
TEST(TestIBUtilByteStr, test_bytestr_create_and_destroy)
{
    ib_mpool_t *mp;
    ib_bytestr_t *bs;
    ib_status_t rc;

    atexit(ib_shutdown);
    rc = ib_initialize();
    ASSERT_TRUE(rc == IB_OK) << "ib_initialize() failed - rc != IB_OK";
    rc = ib_mpool_create(&mp, NULL);
    ASSERT_TRUE(rc == IB_OK) << "ib_mpool_create() failed - rc != IB_OK";

    rc = ib_bytestr_create(&bs, mp, 10);
    ASSERT_TRUE(rc == IB_OK) << "ib_bytestr_create() failed - rc != IB_OK";
    ASSERT_TRUE(bs != NULL) << "ib_bytestr_create() failed - NULL value";
    ASSERT_TRUE(ib_bytestr_length(bs) == 0) << "ib_bytestr_create() failed - wrong length ";
    ASSERT_TRUE(ib_bytestr_size(bs) == 10) << "ib_bytestr_create() failed - wrong size";

    ib_mpool_destroy(mp);
}

/// @test Test util bytestr library - ib_bytestr_dup_mem()
TEST(TestIBUtilByteStr, test_bytestr_dup_mem)
{
    ib_mpool_t *mp;
    ib_bytestr_t *bs;
    ib_status_t rc;
    uint8_t data[] = { 'a', 'b', 'c', 'd', 'e', 'f' };
    uint8_t *ptr;

    atexit(ib_shutdown);
    rc = ib_initialize();
    ASSERT_TRUE(rc == IB_OK) << "ib_initialize() failed - rc != IB_OK";
    rc = ib_mpool_create(&mp, NULL);
    ASSERT_TRUE(rc == IB_OK) << "ib_mpool_create() failed - rc != IB_OK";

    rc = ib_bytestr_dup_mem(&bs, mp, data, sizeof(data));
    ASSERT_TRUE(rc == IB_OK) << "ib_bytestr_dup_mem() failed - rc != IB_OK";
    ASSERT_TRUE(bs != NULL) << "ib_bytestr_dup_mem() failed - NULL value";
    ASSERT_TRUE(ib_bytestr_length(bs) == 6) << "ib_bytestr_dup_mem() failed - wrong length";
    ASSERT_TRUE(ib_bytestr_size(bs) == 6) << "ib_bytestr_dup_mem() failed - wrong size";
    ptr = ib_bytestr_ptr(bs);
    ASSERT_TRUE(ptr != data) << "ib_bytestr_dup_mem() failed - not a copy";
    ASSERT_TRUE(strncmp("abcdef", (char *)ptr, 6) == 0) << "ib_bytestr_dup_mem() failed - wrong data";

    ib_mpool_destroy(mp);
}

/// @test Test util bytestr library - ib_bytestr_dup_nulstr()
TEST(TestIBUtilByteStr, test_bytestr_dup_nulstr)
{
    ib_mpool_t *mp;
    ib_bytestr_t *bs;
    ib_status_t rc;
    char data[] = "abcdef";
    uint8_t *ptr;

    atexit(ib_shutdown);
    rc = ib_initialize();
    ASSERT_TRUE(rc == IB_OK) << "ib_initialize() failed - rc != IB_OK";
    rc = ib_mpool_create(&mp, NULL);
    ASSERT_TRUE(rc == IB_OK) << "ib_mpool_create() failed - rc != IB_OK";

    rc = ib_bytestr_dup_nulstr(&bs, mp, data);
    ASSERT_TRUE(rc == IB_OK) << "ib_bytestr_dup_nulstr() failed - rc != IB_OK";
    ASSERT_TRUE(bs != NULL) << "ib_bytestr_dup_nulstr() failed - NULL value";
    ASSERT_TRUE(ib_bytestr_length(bs) == 6) << "ib_bytestr_dup_nulstr() failed - wrong length";
    ASSERT_TRUE(ib_bytestr_size(bs) == 6) << "ib_bytestr_dup_nulstr() failed - wrong size";
    ptr = ib_bytestr_ptr(bs);
    ASSERT_TRUE(ptr != (uint8_t *)data) << "ib_bytestr_dup_nulstr() failed - not a copy";
    ASSERT_TRUE(strncmp("abcdef", (char *)ptr, 6) == 0) << "ib_bytestr_dup_nulstr() failed - wrong data: " << ptr;

    ib_mpool_destroy(mp);
}

/// @test Test util bytestr library - ib_bytestr_alias_mem()
TEST(TestIBUtilByteStr, test_bytestr_alias_mem)
{
    ib_mpool_t *mp;
    ib_bytestr_t *bs;
    ib_status_t rc;
    uint8_t data[] = { 'a', 'b', 'c', 'd', 'e', 'f' };
    uint8_t *ptr;

    atexit(ib_shutdown);
    rc = ib_initialize();
    ASSERT_TRUE(rc == IB_OK) << "ib_initialize() failed - rc != IB_OK";
    rc = ib_mpool_create(&mp, NULL);
    ASSERT_TRUE(rc == IB_OK) << "ib_mpool_create() failed - rc != IB_OK";

    rc = ib_bytestr_alias_mem(&bs, mp, data, sizeof(data));
    ASSERT_TRUE(rc == IB_OK) << "ib_bytestr_alias_mem() failed - rc != IB_OK";
    ASSERT_TRUE(bs != NULL) << "ib_bytestr_alias_mem() failed - NULL value";
    ASSERT_TRUE(ib_bytestr_length(bs) == 6) << "ib_bytestr_alias_mem() failed - wrong length";
    ASSERT_TRUE(ib_bytestr_size(bs) == 6) << "ib_bytestr_alias_mem() failed - wrong size";
    ptr = ib_bytestr_ptr(bs);
    ASSERT_TRUE(ptr == data) << "ib_bytestr_alias_mem() failed - copied";
    ASSERT_TRUE(strncmp("abcdef", (char *)ptr, 6) == 0) << "ib_bytestr_alias_mem() failed - wrong data";
    rc = ib_bytestr_append_nulstr(bs, "foo");
    ASSERT_TRUE(rc == IB_EINVAL) << "ib_bytestr_alias_mem() failed - read/write";

    ib_mpool_destroy(mp);
}

/// @test Test util bytestr library - ib_bytestr_alias_nulstr()
TEST(TestIBUtilByteStr, test_bytestr_alias_nulstr)
{
    ib_mpool_t *mp;
    ib_bytestr_t *bs;
    ib_status_t rc;
    char data[] = "abcdef";
    uint8_t *ptr;

    atexit(ib_shutdown);
    rc = ib_initialize();
    ASSERT_TRUE(rc == IB_OK) << "ib_initialize() failed - rc != IB_OK";
    rc = ib_mpool_create(&mp, NULL);
    ASSERT_TRUE(rc == IB_OK) << "ib_mpool_create() failed - rc != IB_OK";

    rc = ib_bytestr_alias_nulstr(&bs, mp, data);
    ASSERT_TRUE(rc == IB_OK) << "ib_bytestr_alias_nulstr() failed - rc != IB_OK";
    ASSERT_TRUE(bs != NULL) << "ib_bytestr_alias_nulstr() failed - NULL value";
    ASSERT_TRUE(ib_bytestr_length(bs) == 6) << "ib_bytestr_alias_nulstr() failed - wrong length";
    ASSERT_TRUE(ib_bytestr_size(bs) == 6) << "ib_bytestr_alias_nulstr() failed - wrong size";
    ptr = ib_bytestr_ptr(bs);
    ASSERT_TRUE(ptr == (uint8_t *)data) << "ib_bytestr_alias_nulstr() failed - copied";
    ASSERT_TRUE(strncmp("abcdef", (char *)ptr, 6) == 0) << "ib_bytestr_alias_nulstr() failed - wrong data";
    rc = ib_bytestr_append_nulstr(bs, "foo");
    ASSERT_TRUE(rc == IB_EINVAL) << "ib_bytestr_alias_nulstr() failed - read/write";

    ib_mpool_destroy(mp);
}

/// @test Test util bytestr library - ib_bytestr_append_*()
TEST(TestIBUtilByteStr, test_bytestr_append)
{
    ib_mpool_t *mp;
    ib_bytestr_t *bs1;
    ib_bytestr_t *bs2;
    ib_status_t rc;
    char data1[] = "abcdef";
    char data2[] = "ghijkl";
    char data3[] = "foo";
    uint8_t data4[] = { 'b', 'a', 'r' };
    uint8_t *ptr;

    atexit(ib_shutdown);
    rc = ib_initialize();
    ASSERT_TRUE(rc == IB_OK) << "ib_initialize() failed - rc != IB_OK";
    rc = ib_mpool_create(&mp, NULL);
    ASSERT_TRUE(rc == IB_OK) << "ib_mpool_create() failed - rc != IB_OK";

    rc = ib_bytestr_dup_nulstr(&bs1, mp, data1);
    ASSERT_TRUE(rc == IB_OK) << "ib_bytestr_append() failed - rc != IB_OK";
    ASSERT_TRUE(bs1 != NULL) << "ib_bytestr_append() failed - NULL value";
    ASSERT_TRUE(ib_bytestr_length(bs1) == 6) << "ib_bytestr_append() failed - wrong length";
    ASSERT_TRUE(ib_bytestr_size(bs1) == 6) << "ib_bytestr_append() failed - wrong size";
    ptr = ib_bytestr_ptr(bs1);
    ASSERT_TRUE(strncmp("abcdef", (char *)ptr, 6) == 0) << "ib_bytestr_append() failed - wrong data";

    rc = ib_bytestr_dup_nulstr(&bs2, mp, data2);
    ASSERT_TRUE(rc == IB_OK) << "ib_bytestr_append() failed - rc != IB_OK";
    ASSERT_TRUE(bs2 != NULL) << "ib_bytestr_append() failed - NULL value";
    ASSERT_TRUE(ib_bytestr_length(bs2) == 6) << "ib_bytestr_append() failed - wrong length";
    ASSERT_TRUE(ib_bytestr_size(bs2) == 6) << "ib_bytestr_append() failed - wrong size";
    ptr = ib_bytestr_ptr(bs2);
    ASSERT_TRUE(strncmp("ghijkl", (char *)ptr, 6) == 0) << "ib_bytestr_append() failed - wrong data";

    rc = ib_bytestr_append(bs1, bs2);
    ASSERT_TRUE(rc == IB_OK) << "ib_bytestr_append() failed - rc != IB_OK";
    ASSERT_TRUE(bs1 != NULL) << "ib_bytestr_append() failed - NULL value";
    ASSERT_TRUE(ib_bytestr_length(bs1) == 12) << "ib_bytestr_append() failed - wrong length";
    ASSERT_TRUE(ib_bytestr_size(bs1) == 12) << "ib_bytestr_append() failed - wrong size";
    ptr = ib_bytestr_ptr(bs1);
    ASSERT_TRUE(strncmp("abcdefghijkl", (char *)ptr, 12) == 0) << "ib_bytestr_append() failed - wrong data";

    rc = ib_bytestr_append_nulstr(bs1, data3);
    ASSERT_TRUE(rc == IB_OK) << "ib_bytestr_append() failed - rc != IB_OK";
    ASSERT_TRUE(bs1 != NULL) << "ib_bytestr_append() failed - NULL value";
    ASSERT_TRUE(ib_bytestr_length(bs1) == 15) << "ib_bytestr_append() failed - wrong length";
    ASSERT_TRUE(ib_bytestr_size(bs1) == 15) << "ib_bytestr_append() failed - wrong size";
    ptr = ib_bytestr_ptr(bs1);
    ASSERT_TRUE(strncmp("abcdefghijklfoo", (char *)ptr, 15) == 0) << "ib_bytestr_append() failed - wrong data";

    rc = ib_bytestr_append_mem(bs1, data4, sizeof(data4));
    ASSERT_TRUE(rc == IB_OK) << "ib_bytestr_append() failed - rc != IB_OK";
    ASSERT_TRUE(bs1 != NULL) << "ib_bytestr_append() failed - NULL value";
    ASSERT_TRUE(ib_bytestr_length(bs1) == 18) << "ib_bytestr_append() failed - wrong length";
    ASSERT_TRUE(ib_bytestr_size(bs1) == 18) << "ib_bytestr_append() failed - wrong size";
    ptr = ib_bytestr_ptr(bs1);
    ASSERT_TRUE(strncmp("abcdefghijklfoobar", (char *)ptr, 18) == 0) << "ib_bytestr_append() failed - wrong data";

    ib_mpool_destroy(mp);
}
<commit_msg>test_util_bytestr: Clean up.<commit_after>//////////////////////////////////////////////////////////////////////////////
// Licensed to Qualys, Inc. (QUALYS) under one or more
// contributor license agreements.  See the NOTICE file distributed with
// this work for additional information regarding copyright ownership.
// QUALYS licenses this file to You 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.
//////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////
/// @file
/// @brief IronBee - Byte String Test Functions
///
/// @author Brian Rectanus <brectanus@qualys.com>
//////////////////////////////////////////////////////////////////////////////

#include "ironbee_config_auto.h"

#include <ironbee/mpool.h>
#include <ironbee/util.h>
#include <ironbee/bytestr.h>

#include "gtest/gtest.h"
#include "gtest/gtest-spi.h"

#include <stdexcept>

class TestIBUtilByteStr : public ::testing::Test
{
public:
    TestIBUtilByteStr()
    {
        ib_status_t rc;

        ib_initialize();
        rc = ib_mpool_create(&m_pool, NULL, NULL);
        if (rc != IB_OK) {
            throw std::runtime_error("Could not create mpool.");
        }
    }

    ~TestIBUtilByteStr()
    {
        ib_shutdown();
    }

protected:
    ib_mpool_t* m_pool;
};

/* -- Tests -- */

/// @test Test util bytestr library - ib_bytestr_create() and ib_bytestr_destroy()
TEST_F(TestIBUtilByteStr, test_bytestr_create_and_destroy)
{
    ib_bytestr_t *bs;
    ib_status_t rc;

    rc = ib_bytestr_create(&bs, m_pool, 10);
    ASSERT_EQ(IB_OK, rc);
    ASSERT_TRUE(bs);
    ASSERT_EQ(0UL, ib_bytestr_length(bs));
    ASSERT_EQ(10UL, ib_bytestr_size(bs));
}

/// @test Test util bytestr library - ib_bytestr_dup_mem()
TEST_F(TestIBUtilByteStr, test_bytestr_dup_mem)
{
    ib_bytestr_t *bs;
    ib_status_t rc;
    uint8_t data[] = { 'a', 'b', 'c', 'd', 'e', 'f' };
    uint8_t *ptr;

    rc = ib_bytestr_dup_mem(&bs, m_pool, data, sizeof(data));
    ASSERT_EQ(IB_OK, rc);
    ASSERT_TRUE(bs);
    ASSERT_EQ(6UL, ib_bytestr_length(bs));
    ASSERT_EQ(6UL, ib_bytestr_size(bs));
    ptr = ib_bytestr_ptr(bs);
    ASSERT_NE(data, ptr);
    ASSERT_EQ(0, strncmp("abcdef", (char *)ptr, 6));
}

/// @test Test util bytestr library - ib_bytestr_dup_nulstr()
TEST_F(TestIBUtilByteStr, test_bytestr_dup_nulstr)
{
    ib_bytestr_t *bs;
    ib_status_t rc;
    char data[] = "abcdef";
    uint8_t *ptr;

    rc = ib_bytestr_dup_nulstr(&bs, m_pool, data);
    ASSERT_EQ(IB_OK, rc);
    ASSERT_TRUE(bs);
    ASSERT_EQ(6UL, ib_bytestr_length(bs));
    ASSERT_EQ(6UL, ib_bytestr_size(bs));
    ptr = ib_bytestr_ptr(bs);
    ASSERT_NE(data, ptr);
    ASSERT_EQ(0, strncmp("abcdef", (char *)ptr, 6));
}

/// @test Test util bytestr library - ib_bytestr_alias_mem()
TEST_F(TestIBUtilByteStr, test_bytestr_alias_mem)
{
    ib_bytestr_t *bs;
    ib_status_t rc;
    uint8_t data[] = { 'a', 'b', 'c', 'd', 'e', 'f' };
    uint8_t *ptr;

    rc = ib_bytestr_alias_mem(&bs, m_pool, data, sizeof(data));
    ASSERT_EQ(IB_OK, rc);
    ASSERT_TRUE(bs);
    ASSERT_EQ(6UL, ib_bytestr_length(bs));
    ASSERT_EQ(6UL, ib_bytestr_size(bs));
    ptr = ib_bytestr_ptr(bs);
    ASSERT_EQ(data, ptr);
    ASSERT_EQ(0, strncmp("abcdef", (char *)ptr, 6));
    rc = ib_bytestr_append_nulstr(bs, "foo");
    ASSERT_EQ(IB_EINVAL, rc);
}

/// @test Test util bytestr library - ib_bytestr_alias_nulstr()
TEST_F(TestIBUtilByteStr, test_bytestr_alias_nulstr)
{
    ib_mpool_t *m_pool;
    ib_bytestr_t *bs;
    ib_status_t rc;
    char data[] = "abcdef";
    uint8_t *ptr;

    rc = ib_bytestr_alias_nulstr(&bs, m_pool, data);
    ASSERT_EQ(IB_OK, rc);
    ASSERT_TRUE(bs);
    ASSERT_EQ(6UL, ib_bytestr_length(bs));
    ASSERT_EQ(6UL, ib_bytestr_size(bs));
    ptr = ib_bytestr_ptr(bs);
    ASSERT_EQ((uint8_t *, ptr);
    ASSERT_EQ(0, strncmp("abcdef", (char *)ptr, 6));
    rc = ib_bytestr_append_nulstr(bs, "foo");
    ASSERT_EQ(IB_EINVAL, rc);
}

/// @test Test util bytestr library - ib_bytestr_append_*()
TEST_F(TestIBUtilByteStr, test_bytestr_append)
{
    ib_bytestr_t *bs1;
    ib_bytestr_t *bs2;
    ib_status_t rc;
    char data1[] = "abcdef";
    char data2[] = "ghijkl";
    char data3[] = "foo";
    uint8_t data4[] = { 'b', 'a', 'r' };
    uint8_t *ptr;

    rc = ib_bytestr_dup_nulstr(&bs1, m_pool, data1);
    ASSERT_EQ(IB_OK, rc);
    ASSERT_TRUE(bs1);
    ASSERT_EQ(6UL, ib_bytestr_length(bs1));
    ASSERT_EQ(6UL, ib_bytestr_size(bs1));
    ptr = ib_bytestr_ptr(bs1);
    ASSERT_EQ(0, strncmp("abcdef", (char *)ptr, 6));

    rc = ib_bytestr_dup_nulstr(&bs2, m_pool, data2);
    ASSERT_EQ(IB_OK, rc);
    ASSERT_TRUE(bs2);
    ASSERT_EQ(6UL, ib_bytestr_length(bs2));
    ASSERT_EQ(6UL, ib_bytestr_size(bs2));
    ptr = ib_bytestr_ptr(bs2);
    ASSERT_EQ(0, strncmp("ghijkl", (char *)ptr, 6));

    rc = ib_bytestr_append(bs1, bs2);
    ASSERT_EQ(IB_OK, rc);
    ASSERT_TRUE(bs1);
    ASSERT_EQ(12UL, ib_bytestr_length(bs1));
    ASSERT_EQ(12UL, ib_bytestr_size(bs1));
    ptr = ib_bytestr_ptr(bs1);
    ASSERT_EQ(0, strncmp("abcdefghijkl", (char *)ptr, 12));

    rc = ib_bytestr_append_nulstr(bs1, data3);
    ASSERT_EQ(IB_OK, rc);
    ASSERT_TRUE(bs1);
    ASSERT_EQ(15UL, ib_bytestr_length(bs1));
    ASSERT_EQ(15UL, ib_bytestr_size(bs1));
    ptr = ib_bytestr_ptr(bs1);
    ASSERT_EQ(0, strncmp("abcdefghijklfoo", (char *)ptr, 15));

    rc = ib_bytestr_append_mem(bs1, data4, sizeof(data4));
    ASSERT_EQ(IB_OK, rc);
    ASSERT_TRUE(bs1);
    ASSERT_EQ(18UL, ib_bytestr_length(bs1));
    ASSERT_EQ(18UL, ib_bytestr_size(bs1));
    ptr = ib_bytestr_ptr(bs1);
    ASSERT_EQ(0, strncmp("abcdefghijklfoobar", (char *)ptr, 18));
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2021-present ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * Scylla is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scylla 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 Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <boost/algorithm/string/join.hpp>
#include <boost/program_options.hpp>
#include <string>
#include <vector>
#include <fmt/format.h>

namespace tools::utils {

template<typename Op>
concept Operation = requires(Op op) {
    { op.name() }; // returns some string
};

template <Operation Op>
const Op& get_selected_operation(boost::program_options::variables_map& app_config, const std::vector<Op>& operations, std::string_view alias) {
    std::vector<const Op*> found_operations;
    for (const auto& op : operations) {
        if (app_config.contains(op.name())) {
            found_operations.push_back(&op);
        }
    }
    if (found_operations.size() == 1) {
        return *found_operations.front();
    }

    const auto all_operation_names = boost::algorithm::join(operations | boost::adaptors::transformed(
            [] (const Op& op) { return format("--{}", op.name()); } ), ", ");

    if (found_operations.empty()) {
        throw std::invalid_argument(fmt::format("error: missing {}, exactly one of {} should be specified", alias, all_operation_names));
    }
    throw std::invalid_argument(fmt::format("error: need exactly one {}, cannot specify more then one of {}", alias, all_operation_names));
}

} // namespace tools::utils
<commit_msg>tools/utils.hh: make self-sufficient<commit_after>/*
 * Copyright (C) 2021-present ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * Scylla is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scylla 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 Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <boost/algorithm/string/join.hpp>
#include <boost/range/adaptor/transformed.hpp>
#include <boost/program_options.hpp>
#include <string>
#include <vector>
#include <fmt/format.h>

namespace tools::utils {

template<typename Op>
concept Operation = requires(Op op) {
    { op.name() }; // returns some string
};

template <Operation Op>
const Op& get_selected_operation(boost::program_options::variables_map& app_config, const std::vector<Op>& operations, std::string_view alias) {
    std::vector<const Op*> found_operations;
    for (const auto& op : operations) {
        if (app_config.contains(op.name())) {
            found_operations.push_back(&op);
        }
    }
    if (found_operations.size() == 1) {
        return *found_operations.front();
    }

    const auto all_operation_names = boost::algorithm::join(operations | boost::adaptors::transformed(
            [] (const Op& op) { return format("--{}", op.name()); } ), ", ");

    if (found_operations.empty()) {
        throw std::invalid_argument(fmt::format("error: missing {}, exactly one of {} should be specified", alias, all_operation_names));
    }
    throw std::invalid_argument(fmt::format("error: need exactly one {}, cannot specify more then one of {}", alias, all_operation_names));
}

} // namespace tools::utils
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2007 Digital Bazaar, Inc.  All rights reserved.
 */
#include "db/data/AbstractDataFormatInspector.h"

using namespace db::data;

AbstractDataFormatInspector::AbstractDataFormatInspector()
{
   mDataSatisfied = false;
   mFormatRecognized = false;
   mInspectAfterSatisfied = false;
   mBytesInspected = 0;
   mSkipBytes = 0;
}

AbstractDataFormatInspector::~AbstractDataFormatInspector()
{
}

void AbstractDataFormatInspector::setFormatRecognized(bool recognized)
{
   mFormatRecognized = recognized;
   mDataSatisfied = true;
}

void AbstractDataFormatInspector::setSkipBytes(long long count)
{
   mSkipBytes = count;
}

int AbstractDataFormatInspector::inspectData(const char* b, int length)
{
   int rval = 0;

   // inspect data if not satisfied or if keep-inspecting enabled
   if(!isDataSatisfied() || (keepInspecting() && isFormatRecognized()))
   {
      // skip bytes as appropriate
      if(mSkipBytes > 0)
      {
         int sb = (mSkipBytes > Math::MAX_INT_VALUE ?
            Math::MAX_INT_VALUE : mSkipBytes);
         rval = (sb < length ? sb : length);
         mSkipBytes -= rval;
      }
      else
      {
         // try to detect format
         rval = detectFormat(b, length);
      }

      // increase number of inspected bytes
      mBytesInspected += rval;
   }
   else
   {
      // consider all data inspected
      rval = length;
   }

   return rval;
}

bool AbstractDataFormatInspector::isDataSatisfied()
{
   return mDataSatisfied;
}

bool AbstractDataFormatInspector::isFormatRecognized()
{
   return mFormatRecognized;
}

void AbstractDataFormatInspector::setKeepInspecting(bool inspect)
{
   mInspectAfterSatisfied = inspect;
}

bool AbstractDataFormatInspector::keepInspecting()
{
   return mInspectAfterSatisfied;
}

unsigned long long AbstractDataFormatInspector::getBytesInspected()
{
   return mBytesInspected;
}
<commit_msg>Fix last commit.<commit_after>/*
 * Copyright (c) 2007 Digital Bazaar, Inc.  All rights reserved.
 */
#include "db/data/AbstractDataFormatInspector.h"

#include "db/util/Math.h"

using namespace db::data;
using namespace db::util;

AbstractDataFormatInspector::AbstractDataFormatInspector()
{
   mDataSatisfied = false;
   mFormatRecognized = false;
   mInspectAfterSatisfied = false;
   mBytesInspected = 0;
   mSkipBytes = 0;
}

AbstractDataFormatInspector::~AbstractDataFormatInspector()
{
}

void AbstractDataFormatInspector::setFormatRecognized(bool recognized)
{
   mFormatRecognized = recognized;
   mDataSatisfied = true;
}

void AbstractDataFormatInspector::setSkipBytes(long long count)
{
   mSkipBytes = count;
}

int AbstractDataFormatInspector::inspectData(const char* b, int length)
{
   int rval = 0;

   // inspect data if not satisfied or if keep-inspecting enabled
   if(!isDataSatisfied() || (keepInspecting() && isFormatRecognized()))
   {
      // skip bytes as appropriate
      if(mSkipBytes > 0)
      {
         int sb = (mSkipBytes > (unsigned long long)Math::MAX_INT_VALUE ?
            Math::MAX_INT_VALUE : mSkipBytes);
         rval = (sb < length ? sb : length);
         mSkipBytes -= rval;
      }
      else
      {
         // try to detect format
         rval = detectFormat(b, length);
      }

      // increase number of inspected bytes
      mBytesInspected += rval;
   }
   else
   {
      // consider all data inspected
      rval = length;
   }

   return rval;
}

bool AbstractDataFormatInspector::isDataSatisfied()
{
   return mDataSatisfied;
}

bool AbstractDataFormatInspector::isFormatRecognized()
{
   return mFormatRecognized;
}

void AbstractDataFormatInspector::setKeepInspecting(bool inspect)
{
   mInspectAfterSatisfied = inspect;
}

bool AbstractDataFormatInspector::keepInspecting()
{
   return mInspectAfterSatisfied;
}

unsigned long long AbstractDataFormatInspector::getBytesInspected()
{
   return mBytesInspected;
}
<|endoftext|>


<commit_before>#ifndef MANIFOLDS_FUNCTIONS_UNARY_MINUS_HH
#define MANIFOLDS_FUNCTIONS_UNARY_MINUS_HH

#include "full_function_defs.hh"
#include "function.hh"

namespace manifolds {

template <class Func>
struct UnaryMinusImpl : MultiFunction
{

  UnaryMinusImpl(){}
  UnaryMinusImpl(const Func & f):f(f){}

  template <class ... Args>
  auto operator()(Args && ... args) const
  {
    return -f(args...);
  }

private:
  Func f;
};

  DEF_FF_STEMPLATE(UnaryMinus)
}
#endif
<commit_msg>Added getter and streamer<commit_after>#ifndef MANIFOLDS_FUNCTIONS_UNARY_MINUS_HH
#define MANIFOLDS_FUNCTIONS_UNARY_MINUS_HH

#include "full_function_defs.hh"
#include "function.hh"

namespace manifolds {

template <class Func>
struct UnaryMinusImpl : MultiFunction
{

  UnaryMinusImpl(){}
  UnaryMinusImpl(const Func & f):f(f){}

  template <class ... Args>
  auto operator()(Args && ... args) const
  {
    return -f(args...);
  }

  auto GetFunction() const
  {
    return f;
  }

  auto GetFunctions() const
  {
    return std::make_tuple(f);
  }

private:
  Func f;
};

  DEF_FF_STEMPLATE(UnaryMinus)

  template <class T>
  std::ostream & operator<<(std::ostream & s,
			    UnaryMinus<T> u)
  {
    return s << '-' << u.GetFunction();
  }

  template <class T, class U>
  bool operator==(UnaryMinus<T>, U)
  {
    return false;
  }

  template <class T>
  bool operator==(UnaryMinus<T> u1, UnaryMinus<T> u2)
  {
    return u1.f == u2.f;
  }
}
#endif
<|endoftext|>


<commit_before>#include <FancyMeshComponent.hpp>

#include <iostream>

#include <Core/String/StringUtils.hpp>
#include <Core/Mesh/MeshUtils.hpp>

#include <Core/Geometry/Normal/Normal.hpp>

#include <Engine/Renderer/RenderObject/RenderObjectManager.hpp>
#include <Engine/Managers/ComponentMessenger/ComponentMessenger.hpp>

#include <Engine/Renderer/Mesh/Mesh.hpp>
#include <Engine/Renderer/RenderObject/RenderObject.hpp>
#include <Engine/Renderer/RenderObject/RenderObjectTypes.hpp>
#include <Engine/Renderer/RenderTechnique/RenderTechnique.hpp>
#include <Engine/Renderer/RenderTechnique/ShaderConfiguration.hpp>
#include <Engine/Renderer/RenderTechnique/ShaderProgramManager.hpp>
#include <Engine/Renderer/RenderObject/Primitives/DrawPrimitives.hpp>

#include <Engine/Assets/FileData.hpp>
#include <Engine/Assets/GeometryData.hpp>

using Ra::Engine::ComponentMessenger;

namespace FancyMeshPlugin
{
    FancyMeshComponent::FancyMeshComponent(const std::string& name , bool deformable)
        : Ra::Engine::Component( name  ) , m_deformable(deformable)
    {
    }

    FancyMeshComponent::~FancyMeshComponent()
    {
    }

    void FancyMeshComponent::initialize()
    {
    }

    void FancyMeshComponent::addMeshRenderObject( const Ra::Core::TriangleMesh& mesh, const std::string& name )
    {
        Ra::Engine::RenderTechnique* technique = new Ra::Engine::RenderTechnique;
        technique->material = new Ra::Engine::Material( "Default" );
        technique->shaderConfig = Ra::Engine::ShaderConfiguration( "Default", "../Shaders" );

        addMeshRenderObject(mesh, name, technique);
    }

    void FancyMeshComponent::addMeshRenderObject( const Ra::Core::TriangleMesh& mesh,
                                                  const std::string& name,
                                                  Ra::Engine::RenderTechnique* technique )
    {
        setupIO(name);

        Ra::Engine::RenderObject* renderObject = new Ra::Engine::RenderObject( name, this, Ra::Engine::RenderObjectType::Fancy );
        renderObject->setVisible( true );
        renderObject->setRenderTechnique( technique );

        std::shared_ptr<Ra::Engine::Mesh> displayMesh( new Ra::Engine::Mesh( name ) );
        displayMesh->loadGeometry( mesh );
        renderObject->setMesh( displayMesh );
        addRenderObject( renderObject );
    }

    void FancyMeshComponent::handleMeshLoading( const Ra::Asset::GeometryData* data )
    {
        std::string name( m_name );
        name.append( "_" + data->getName() );

        std::string roName = name;
        roName.append( "_RO" );

        std::string meshName = name;
        meshName.append( "_Mesh" );

        std::string matName = name;
        matName.append( "_Mat" );

        m_contentName = data->getName();

        Ra::Engine::RenderObject* renderObject = new Ra::Engine::RenderObject( roName, this, Ra::Engine::RenderObjectType::Fancy );
        renderObject->setVisible( true );

        std::shared_ptr<Ra::Engine::Mesh> displayMesh( new Ra::Engine::Mesh( meshName ) );

        Ra::Core::TriangleMesh mesh;
        for( const auto& v : data->getVertices() )
        {
            mesh.m_vertices.push_back( data->getFrame() * v );
        }
        for( const auto& face : data->getFaces() ) {
            mesh.m_triangles.push_back( {uint(face[0]), uint(face[1]), uint(face[2]) } );
        }

#if defined(LOAD_TEXTURES)
        for (const auto& v : data->getNormals())
        {
            mesh.m_normals.push_back(v);
        }
#else
        Ra::Core::Geometry::uniformNormal( mesh.m_vertices, mesh.m_triangles, mesh.m_normals );
#endif

        setupIO( data->getName());

        displayMesh->loadGeometry(mesh);

        Ra::Core::Vector3Array tangents;
        Ra::Core::Vector3Array bitangents;
        Ra::Core::Vector3Array texcoords;

        Ra::Core::Vector4Array colors;

        for ( const auto& v : data->getTangents() )     tangents.push_back( v );
        for ( const auto& v : data->getBiTangents() )   bitangents.push_back( v );
        for ( const auto& v : data->getTexCoords() )    texcoords.push_back( v );
        for ( const auto& v : data->getColors() )       colors.push_back( v );

        displayMesh->addData( Ra::Engine::Mesh::VERTEX_TANGENT, tangents );
        displayMesh->addData( Ra::Engine::Mesh::VERTEX_BITANGENT, bitangents );
        displayMesh->addData( Ra::Engine::Mesh::VERTEX_TEXCOORD, texcoords );
        displayMesh->addData( Ra::Engine::Mesh::VERTEX_COLOR, colors );
        // FIXME(Charly): Should not weights be part of the geometry ?
        //        mesh->addData( Ra::Engine::Mesh::VERTEX_WEIGHTS, meshData.weights );

        renderObject->setMesh( displayMesh );

        m_meshIndex = addRenderObject(renderObject);

        Ra::Engine::RenderTechnique* rt = new Ra::Engine::RenderTechnique;
        Ra::Engine::Material* mat = new Ra::Engine::Material( matName );
        auto m = data->getMaterial();
        if ( m.hasDiffuse() )   mat->setKd( m.m_diffuse );
        if ( m.hasSpecular() )  mat->setKs( m.m_specular );
        if ( m.hasShininess() ) mat->setNs( m.m_shininess );
#ifdef LOAD_TEXTURES
        if ( m.hasDiffuseTexture() ) mat->addTexture( Ra::Engine::Material::TextureType::TEX_DIFFUSE, m.m_texDiffuse );
#endif
        //if ( m.hasSpecularTexture() ) mat->addTexture( Ra::Engine::Material::TextureType::TEX_SPECULAR, m.m_texSpecular );
        //if ( m.hasShininessTexture() ) mat->addTexture( Ra::Engine::Material::TextureType::TEX_SHININESS, m.m_texShininess );
        //if ( m.hasOpacityTexture() ) mat->addTexture( Ra::Engine::Material::TextureType::TEX_ALPHA, m.m_texOpacity );
        //if ( m.hasNormalTexture() ) mat->addTexture( Ra::Engine::Material::TextureType::TEX_NORMAL, m.m_texNormal );

        rt->material = mat;
        rt->shaderConfig = Ra::Engine::ShaderConfiguration( "BlinnPhong", "../Shaders" );

        renderObject->setRenderTechnique( rt );
    }

    Ra::Core::Index FancyMeshComponent::getRenderObjectIndex() const
    {
        return m_meshIndex;
    }

    const Ra::Core::TriangleMesh& FancyMeshComponent::getMesh() const
    {
        return getDisplayMesh().getGeometry();
    }

    void FancyMeshComponent::setupIO(const std::string& id)
    {
        Ra::Engine::ComponentMessenger::GetterCallback cbOut = std::bind( &FancyMeshComponent::getMeshOutput, this );
        Ra::Engine::ComponentMessenger::getInstance()->registerOutput<Ra::Core::TriangleMesh>( getEntity(), this, id, cbOut);

        if( m_deformable)
        {
            ComponentMessenger::SetterCallback cbIn = std::bind( &FancyMeshComponent::setMeshInput, this, std::placeholders::_1 );
            ComponentMessenger::getInstance()->registerInput<Ra::Core::TriangleMesh>( getEntity(), this, id, cbIn);

            ComponentMessenger::ReadWriteCallback vRW = std::bind( &FancyMeshComponent::getVerticesRw, this);
            ComponentMessenger::getInstance()->registerReadWrite<Ra::Core::Vector3Array>( getEntity(), this, id+"v", vRW);

            ComponentMessenger::ReadWriteCallback nRW = std::bind( &FancyMeshComponent::getNormalsRw, this);
            ComponentMessenger::getInstance()->registerReadWrite<Ra::Core::Vector3Array>( getEntity(), this, id+"n", nRW);

            ComponentMessenger::ReadWriteCallback tRW = std::bind( &FancyMeshComponent::getTrianglesRw, this);
            ComponentMessenger::getInstance()->registerReadWrite<Ra::Core::Vector3Array>( getEntity(), this, id+"t", tRW);
        }

    }

    const Ra::Engine::Mesh& FancyMeshComponent::getDisplayMesh() const
    {
        return *(getRoMgr()->getRenderObject(getRenderObjectIndex())->getMesh());
    }

    Ra::Engine::Mesh& FancyMeshComponent::getDisplayMesh()
    {
        return *(getRoMgr()->getRenderObject(getRenderObjectIndex())->getMesh());
    }

    const void* FancyMeshComponent::getMeshOutput() const
    {
        return &(getMesh());
    }

    void FancyMeshComponent::setMeshInput(const void *meshptr)
    {

        CORE_ASSERT( meshptr, " Input is null");
        CORE_ASSERT( m_deformable, "Mesh is not deformable");

        Ra::Core::TriangleMesh mesh = *(static_cast<const Ra::Core::TriangleMesh*>(meshptr));

        Ra::Engine::Mesh& displayMesh = getDisplayMesh();
        displayMesh.loadGeometry( mesh );
    }

    void* FancyMeshComponent::getVerticesRw()
    {
        getDisplayMesh().setDirty( Ra::Engine::Mesh::VERTEX_POSITION);
        return &(getDisplayMesh().getGeometry().m_vertices);
    }

    void* FancyMeshComponent::getNormalsRw()
    {
        getDisplayMesh().setDirty( Ra::Engine::Mesh::VERTEX_NORMAL);
        return &(getDisplayMesh().getGeometry().m_normals);
    }

    void* FancyMeshComponent::getTrianglesRw()
    {
        getDisplayMesh().setDirty( Ra::Engine::Mesh::INDEX);
        return &(getDisplayMesh().getGeometry().m_triangles);
    }

    void FancyMeshComponent::rayCastQuery( const Ra::Core::Ray& r) const
    {
        auto result  = Ra::Core::MeshUtils::castRay( getMesh(), r );
        int tidx = result.m_hitTriangle;
        if (tidx >= 0)
        {
            LOG(logINFO) << " Hit triangle " << tidx;
            LOG(logINFO) << " Nearest vertex " << result.m_nearestVertex;
        }
    }

} // namespace FancyMeshPlugin
<commit_msg>fancy mesh uses loaded normals instead of recomputing them<commit_after>#include <FancyMeshComponent.hpp>

#include <iostream>

#include <Core/String/StringUtils.hpp>
#include <Core/Mesh/MeshUtils.hpp>

#include <Core/Geometry/Normal/Normal.hpp>

#include <Engine/Renderer/RenderObject/RenderObjectManager.hpp>
#include <Engine/Managers/ComponentMessenger/ComponentMessenger.hpp>

#include <Engine/Renderer/Mesh/Mesh.hpp>
#include <Engine/Renderer/RenderObject/RenderObject.hpp>
#include <Engine/Renderer/RenderObject/RenderObjectTypes.hpp>
#include <Engine/Renderer/RenderTechnique/RenderTechnique.hpp>
#include <Engine/Renderer/RenderTechnique/ShaderConfiguration.hpp>
#include <Engine/Renderer/RenderTechnique/ShaderProgramManager.hpp>
#include <Engine/Renderer/RenderObject/Primitives/DrawPrimitives.hpp>

#include <Engine/Assets/FileData.hpp>
#include <Engine/Assets/GeometryData.hpp>

using Ra::Engine::ComponentMessenger;

namespace FancyMeshPlugin
{
    FancyMeshComponent::FancyMeshComponent(const std::string& name , bool deformable)
        : Ra::Engine::Component( name  ) , m_deformable(deformable)
    {
    }

    FancyMeshComponent::~FancyMeshComponent()
    {
    }

    void FancyMeshComponent::initialize()
    {
    }

    void FancyMeshComponent::addMeshRenderObject( const Ra::Core::TriangleMesh& mesh, const std::string& name )
    {
        Ra::Engine::RenderTechnique* technique = new Ra::Engine::RenderTechnique;
        technique->material = new Ra::Engine::Material( "Default" );
        technique->shaderConfig = Ra::Engine::ShaderConfiguration( "Default", "../Shaders" );

        addMeshRenderObject(mesh, name, technique);
    }

    void FancyMeshComponent::addMeshRenderObject( const Ra::Core::TriangleMesh& mesh,
                                                  const std::string& name,
                                                  Ra::Engine::RenderTechnique* technique )
    {
        setupIO(name);

        Ra::Engine::RenderObject* renderObject = new Ra::Engine::RenderObject( name, this, Ra::Engine::RenderObjectType::Fancy );
        renderObject->setVisible( true );
        renderObject->setRenderTechnique( technique );

        std::shared_ptr<Ra::Engine::Mesh> displayMesh( new Ra::Engine::Mesh( name ) );
        displayMesh->loadGeometry( mesh );
        renderObject->setMesh( displayMesh );
        addRenderObject( renderObject );
    }

    void FancyMeshComponent::handleMeshLoading( const Ra::Asset::GeometryData* data )
    {
        std::string name( m_name );
        name.append( "_" + data->getName() );

        std::string roName = name;
        roName.append( "_RO" );

        std::string meshName = name;
        meshName.append( "_Mesh" );

        std::string matName = name;
        matName.append( "_Mat" );

        m_contentName = data->getName();

        Ra::Engine::RenderObject* renderObject = new Ra::Engine::RenderObject( roName, this, Ra::Engine::RenderObjectType::Fancy );
        renderObject->setVisible( true );

        std::shared_ptr<Ra::Engine::Mesh> displayMesh( new Ra::Engine::Mesh( meshName ) );

        Ra::Core::TriangleMesh mesh;
        for (size_t i = 0; i < data->getVerticesSize(); ++i)
        {
            mesh.m_vertices.push_back(data->getFrame() * data->getVertices()[i]);
            mesh.m_normals.push_back(data->getNormals()[i]);
        }

        for (const auto& face : data->getFaces())
        {
            mesh.m_triangles.push_back(face.head<3>());
        }

        setupIO( data->getName());

        displayMesh->loadGeometry(mesh);

        Ra::Core::Vector3Array tangents;
        Ra::Core::Vector3Array bitangents;
        Ra::Core::Vector3Array texcoords;

        Ra::Core::Vector4Array colors;

        for ( const auto& v : data->getTangents() )     tangents.push_back( v );
        for ( const auto& v : data->getBiTangents() )   bitangents.push_back( v );
        for ( const auto& v : data->getTexCoords() )    texcoords.push_back( v );
        for ( const auto& v : data->getColors() )       colors.push_back( v );

        displayMesh->addData( Ra::Engine::Mesh::VERTEX_TANGENT, tangents );
        displayMesh->addData( Ra::Engine::Mesh::VERTEX_BITANGENT, bitangents );
        displayMesh->addData( Ra::Engine::Mesh::VERTEX_TEXCOORD, texcoords );
        displayMesh->addData( Ra::Engine::Mesh::VERTEX_COLOR, colors );
        // FIXME(Charly): Should not weights be part of the geometry ?
        //        mesh->addData( Ra::Engine::Mesh::VERTEX_WEIGHTS, meshData.weights );

        renderObject->setMesh( displayMesh );

        m_meshIndex = addRenderObject(renderObject);

        Ra::Engine::RenderTechnique* rt = new Ra::Engine::RenderTechnique;
        Ra::Engine::Material* mat = new Ra::Engine::Material( matName );
        auto m = data->getMaterial();
        if ( m.hasDiffuse() )   mat->setKd( m.m_diffuse );
        if ( m.hasSpecular() )  mat->setKs( m.m_specular );
        if ( m.hasShininess() ) mat->setNs( m.m_shininess );
#ifdef LOAD_TEXTURES
        if ( m.hasDiffuseTexture() ) mat->addTexture( Ra::Engine::Material::TextureType::TEX_DIFFUSE, m.m_texDiffuse );
#endif
        //if ( m.hasSpecularTexture() ) mat->addTexture( Ra::Engine::Material::TextureType::TEX_SPECULAR, m.m_texSpecular );
        //if ( m.hasShininessTexture() ) mat->addTexture( Ra::Engine::Material::TextureType::TEX_SHININESS, m.m_texShininess );
        //if ( m.hasOpacityTexture() ) mat->addTexture( Ra::Engine::Material::TextureType::TEX_ALPHA, m.m_texOpacity );
        //if ( m.hasNormalTexture() ) mat->addTexture( Ra::Engine::Material::TextureType::TEX_NORMAL, m.m_texNormal );

        rt->material = mat;
        rt->shaderConfig = Ra::Engine::ShaderConfiguration( "BlinnPhong", "../Shaders" );

        renderObject->setRenderTechnique( rt );
    }

    Ra::Core::Index FancyMeshComponent::getRenderObjectIndex() const
    {
        return m_meshIndex;
    }

    const Ra::Core::TriangleMesh& FancyMeshComponent::getMesh() const
    {
        return getDisplayMesh().getGeometry();
    }

    void FancyMeshComponent::setupIO(const std::string& id)
    {
        Ra::Engine::ComponentMessenger::GetterCallback cbOut = std::bind( &FancyMeshComponent::getMeshOutput, this );
        Ra::Engine::ComponentMessenger::getInstance()->registerOutput<Ra::Core::TriangleMesh>( getEntity(), this, id, cbOut);

        if( m_deformable)
        {
            ComponentMessenger::SetterCallback cbIn = std::bind( &FancyMeshComponent::setMeshInput, this, std::placeholders::_1 );
            ComponentMessenger::getInstance()->registerInput<Ra::Core::TriangleMesh>( getEntity(), this, id, cbIn);

            ComponentMessenger::ReadWriteCallback vRW = std::bind( &FancyMeshComponent::getVerticesRw, this);
            ComponentMessenger::getInstance()->registerReadWrite<Ra::Core::Vector3Array>( getEntity(), this, id+"v", vRW);

            ComponentMessenger::ReadWriteCallback nRW = std::bind( &FancyMeshComponent::getNormalsRw, this);
            ComponentMessenger::getInstance()->registerReadWrite<Ra::Core::Vector3Array>( getEntity(), this, id+"n", nRW);

            ComponentMessenger::ReadWriteCallback tRW = std::bind( &FancyMeshComponent::getTrianglesRw, this);
            ComponentMessenger::getInstance()->registerReadWrite<Ra::Core::Vector3Array>( getEntity(), this, id+"t", tRW);
        }

    }

    const Ra::Engine::Mesh& FancyMeshComponent::getDisplayMesh() const
    {
        return *(getRoMgr()->getRenderObject(getRenderObjectIndex())->getMesh());
    }

    Ra::Engine::Mesh& FancyMeshComponent::getDisplayMesh()
    {
        return *(getRoMgr()->getRenderObject(getRenderObjectIndex())->getMesh());
    }

    const void* FancyMeshComponent::getMeshOutput() const
    {
        return &(getMesh());
    }

    void FancyMeshComponent::setMeshInput(const void *meshptr)
    {

        CORE_ASSERT( meshptr, " Input is null");
        CORE_ASSERT( m_deformable, "Mesh is not deformable");

        Ra::Core::TriangleMesh mesh = *(static_cast<const Ra::Core::TriangleMesh*>(meshptr));

        Ra::Engine::Mesh& displayMesh = getDisplayMesh();
        displayMesh.loadGeometry( mesh );
    }

    void* FancyMeshComponent::getVerticesRw()
    {
        getDisplayMesh().setDirty( Ra::Engine::Mesh::VERTEX_POSITION);
        return &(getDisplayMesh().getGeometry().m_vertices);
    }

    void* FancyMeshComponent::getNormalsRw()
    {
        getDisplayMesh().setDirty( Ra::Engine::Mesh::VERTEX_NORMAL);
        return &(getDisplayMesh().getGeometry().m_normals);
    }

    void* FancyMeshComponent::getTrianglesRw()
    {
        getDisplayMesh().setDirty( Ra::Engine::Mesh::INDEX);
        return &(getDisplayMesh().getGeometry().m_triangles);
    }

    void FancyMeshComponent::rayCastQuery( const Ra::Core::Ray& r) const
    {
        auto result  = Ra::Core::MeshUtils::castRay( getMesh(), r );
        int tidx = result.m_hitTriangle;
        if (tidx >= 0)
        {
            LOG(logINFO) << " Hit triangle " << tidx;
            LOG(logINFO) << " Nearest vertex " << result.m_nearestVertex;
        }
    }

} // namespace FancyMeshPlugin
<|endoftext|>


<commit_before>/**
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

#include "TurboModule.h"

using namespace facebook;

namespace facebook {
namespace react {

TurboModule::TurboModule(const std::string &name, std::shared_ptr<JSCallInvoker> jsInvoker)
  : name_(name),
    jsInvoker_(jsInvoker) {}

TurboModule::~TurboModule() {
  invalidate();
}

void TurboModule::invalidate() {}

jsi::Value TurboModule::get(jsi::Runtime& runtime, const jsi::PropNameID& propName) {
  std::string propNameUtf8 = propName.utf8(runtime);
  auto p = methodMap_.find(propNameUtf8);
  if (p == methodMap_.end()) {
    throw std::runtime_error("Function '" + propNameUtf8 + "' cannot be found on module: " + name_);
  }
  MethodMetadata meta = p->second;
  return jsi::Function::createFromHostFunction(
    runtime,
    propName,
    meta.argCount,
    [this, meta](facebook::jsi::Runtime &rt, const facebook::jsi::Value &thisVal, const facebook::jsi::Value *args, size_t count) {
      return meta.invoker(rt, *this, args, count);
    });
}

jsi::Value TurboModule::invokeMethod(
    jsi::Runtime &runtime,
    TurboModuleMethodValueKind valueKind,
    const std::string &methodName,
    const jsi::Value *args,
    size_t count) {
  return jsi::Value::undefined();
}

} // namespace react
} // namespace facebook
<commit_msg>TM iOS C++: don't throw if a method is not found<commit_after>/**
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

#include "TurboModule.h"

using namespace facebook;

namespace facebook {
namespace react {

TurboModule::TurboModule(const std::string &name, std::shared_ptr<JSCallInvoker> jsInvoker)
  : name_(name),
    jsInvoker_(jsInvoker) {}

TurboModule::~TurboModule() {
  invalidate();
}

void TurboModule::invalidate() {}

jsi::Value TurboModule::get(jsi::Runtime& runtime, const jsi::PropNameID& propName) {
  std::string propNameUtf8 = propName.utf8(runtime);
  auto p = methodMap_.find(propNameUtf8);
  if (p == methodMap_.end()) {
    // Method was not found, let JS decide what to do.
    return jsi::Value::undefined();
  }
  MethodMetadata meta = p->second;
  return jsi::Function::createFromHostFunction(
    runtime,
    propName,
    meta.argCount,
    [this, meta](facebook::jsi::Runtime &rt, const facebook::jsi::Value &thisVal, const facebook::jsi::Value *args, size_t count) {
      return meta.invoker(rt, *this, args, count);
    });
}

jsi::Value TurboModule::invokeMethod(
    jsi::Runtime &runtime,
    TurboModuleMethodValueKind valueKind,
    const std::string &methodName,
    const jsi::Value *args,
    size_t count) {
  return jsi::Value::undefined();
}

} // namespace react
} // namespace facebook
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: propertycomposer.hxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: ihi $ $Date: 2008-01-14 15:00:06 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    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., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef EXTENSIONS_SOURCE_PROPCTRLR_PROPERTYCOMPOSER_HXX
#define EXTENSIONS_SOURCE_PROPCTRLR_PROPERTYCOMPOSER_HXX

#ifndef _EXTENSIONS_PROPCTRLR_PCRCOMMON_HXX_
#include "pcrcommon.hxx"
#endif
#ifndef _EXTENSIONS_FORMSCTRLR_FORMBROWSERTOOLS_HXX_
#include "formbrowsertools.hxx"
#endif
#ifndef EXTENSIONS_SOURCE_PROPCTRLR_COMPOSEDUIUPDATE_HXX
#include "composeduiupdate.hxx"
#endif
#ifndef _EXTENSIONS_FORMSCTRLR_FORMBROWSERTOOLS_HXX_
#include "formbrowsertools.hxx"
#endif

/** === begin UNO includes === **/
#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
#include <com/sun/star/beans/XPropertySet.hpp>
#endif
#ifndef _COM_SUN_STAR_INSPECTION_XPROPERTYHANDLER_HPP_
#include <com/sun/star/inspection/XPropertyHandler.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_DISPOSEDEXCEPTION_HPP_
#include <com/sun/star/lang/DisposedException.hpp>
#endif
/** === end UNO includes === **/

#ifndef _CPPUHELPER_COMPBASE2_HXX_
#include <cppuhelper/compbase2.hxx>
#endif
#ifndef _COMPHELPER_BROADCASTHELPER_HXX_
#include <comphelper/broadcasthelper.hxx>
#endif
#ifndef COMPHELPER_INC_COMPHELPER_LISTENERNOTIFICATION_HXX
#include <comphelper/listenernotification.hxx>
#endif

#include <vector>
#include <set>

//........................................................................
namespace pcr
{
//........................................................................

    //====================================================================
    //= PropertyComposer
    //====================================================================
    typedef ::cppu::WeakComponentImplHelper2    <   ::com::sun::star::inspection::XPropertyHandler
                                                ,   ::com::sun::star::beans::XPropertyChangeListener
                                                >   PropertyComposer_Base;
    /** implements an <type>XPropertyHandler</type> which composes it's information
        from a set of other property handlers
    */
    class PropertyComposer  :public PropertyComposer_Base
                            ,public ::comphelper::OBaseMutex
                            ,public IPropertyExistenceCheck
    {
    public:
        typedef ::std::vector< ::com::sun::star::uno::Reference< ::com::sun::star::inspection::XPropertyHandler > >
                                                            HandlerArray;

    private:
        HandlerArray                                    m_aSlaveHandlers;
        ::std::auto_ptr< ComposedPropertyUIUpdate >     m_pUIRequestComposer;
        PropertyChangeListeners                         m_aPropertyListeners;
        bool                                            m_bSupportedPropertiesAreKnown;
        PropertyBag                                     m_aSupportedProperties;

    public:
        /** constructs an <type>XPropertyHandler</type> which composes it's information from a set
            of other property handlers

            @param _rSlaveHandlers
                the set of slave handlers to invoke. Must not be <NULL/>
        */
        PropertyComposer( const ::std::vector< ::com::sun::star::uno::Reference< ::com::sun::star::inspection::XPropertyHandler > >& _rSlaveHandlers );

    public:
        // XPropertyHandler overridables
        virtual void                                SAL_CALL inspect( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _rxIntrospectee ) throw (::com::sun::star::lang::NullPointerException, ::com::sun::star::uno::RuntimeException);
        virtual ::com::sun::star::uno::Any          SAL_CALL getPropertyValue( const ::rtl::OUString& _rPropertyName ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException);
        virtual void                                SAL_CALL setPropertyValue( const ::rtl::OUString& _rPropertyName, const ::com::sun::star::uno::Any& _rValue ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException);
        virtual ::com::sun::star::uno::Any SAL_CALL convertToPropertyValue( const ::rtl::OUString& _rPropertyName, const ::com::sun::star::uno::Any& _rControlValue ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException);
        virtual ::com::sun::star::uno::Any SAL_CALL convertToControlValue( const ::rtl::OUString& _rPropertyName, const ::com::sun::star::uno::Any& _rPropertyValue, const ::com::sun::star::uno::Type& _rControlValueType ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException);
        virtual ::com::sun::star::beans::PropertyState
                                                    SAL_CALL getPropertyState( const ::rtl::OUString& _rPropertyName ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException);
        virtual void                                SAL_CALL addPropertyChangeListener( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& _rxListener ) throw (::com::sun::star::uno::RuntimeException);
        virtual void                                SAL_CALL removePropertyChangeListener( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& _rxListener ) throw (::com::sun::star::uno::RuntimeException);
        virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >
                                                    SAL_CALL getSupportedProperties() throw (::com::sun::star::uno::RuntimeException);
        virtual ::com::sun::star::uno::Sequence< ::rtl::OUString >
                                                    SAL_CALL getSupersededProperties( ) throw (::com::sun::star::uno::RuntimeException);
        virtual ::com::sun::star::uno::Sequence< ::rtl::OUString >
                                                    SAL_CALL getActuatingProperties( ) throw (::com::sun::star::uno::RuntimeException);
        virtual ::com::sun::star::inspection::LineDescriptor
                                                    SAL_CALL describePropertyLine( const ::rtl::OUString& _rPropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::inspection::XPropertyControlFactory >& _rxControlFactory ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::NullPointerException, ::com::sun::star::uno::RuntimeException);
        virtual ::sal_Bool                          SAL_CALL isComposable( const ::rtl::OUString& _rPropertyName ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException);
        virtual ::com::sun::star::inspection::InteractiveSelectionResult
                                                    SAL_CALL onInteractivePropertySelection( const ::rtl::OUString& _rPropertyName, sal_Bool _bPrimary, ::com::sun::star::uno::Any& _rData, const ::com::sun::star::uno::Reference< ::com::sun::star::inspection::XObjectInspectorUI >& _rxInspectorUI ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::NullPointerException, ::com::sun::star::uno::RuntimeException);
        virtual void                                SAL_CALL actuatingPropertyChanged( const ::rtl::OUString& _rActuatingPropertyName, const ::com::sun::star::uno::Any& _rNewValue, const ::com::sun::star::uno::Any& _rOldValue, const ::com::sun::star::uno::Reference< ::com::sun::star::inspection::XObjectInspectorUI >& _rxInspectorUI, sal_Bool _bFirstTimeInit ) throw (::com::sun::star::lang::NullPointerException, ::com::sun::star::uno::RuntimeException);
        virtual sal_Bool                            SAL_CALL suspend( sal_Bool _bSuspend ) throw (::com::sun::star::uno::RuntimeException);

        // XComponent
        DECLARE_XCOMPONENT()
        virtual void                                SAL_CALL disposing();

        // XPropertyChangeListener
        virtual void SAL_CALL propertyChange( const ::com::sun::star::beans::PropertyChangeEvent& evt ) throw (::com::sun::star::uno::RuntimeException);

        // XEventListener
        virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw (::com::sun::star::uno::RuntimeException);

        // IPropertyExistenceCheck
        virtual ::sal_Bool SAL_CALL hasPropertyByName( const ::rtl::OUString& _rName ) throw (::com::sun::star::uno::RuntimeException);

    private:
        /** ensures that m_pUIRequestComposer exists
        */
        void    impl_ensureUIRequestComposer( const ::com::sun::star::uno::Reference< ::com::sun::star::inspection::XObjectInspectorUI >& _rxInspectorUI );

        /** checks whether a given property exists in <member>m_aSupportedProperties</member>
        */
        bool    impl_isSupportedProperty_nothrow( const ::rtl::OUString& _rPropertyName )
        {
            ::com::sun::star::beans::Property aDummy; aDummy.Name = _rPropertyName;
            return m_aSupportedProperties.find( aDummy ) != m_aSupportedProperties.end();
        }

    private:
        class MethodGuard;
        friend class MethodGuard;
        class MethodGuard : public ::osl::MutexGuard
        {
        public:
            MethodGuard( PropertyComposer& _rInstance )
                : ::osl::MutexGuard( _rInstance.m_aMutex )
            {
                if ( _rInstance.m_aSlaveHandlers.empty() )
                    throw ::com::sun::star::lang::DisposedException( ::rtl::OUString(), *(&_rInstance) );
            }
        };
    };

//........................................................................
} // namespace pcr
//........................................................................

#endif // EXTENSIONS_SOURCE_PROPCTRLR_PROPERTYCOMPOSER_HXX

<commit_msg>INTEGRATION: CWS changefileheader (1.8.48); FILE MERGED 2008/04/01 15:15:19 thb 1.8.48.3: #i85898# Stripping all external header guards 2008/04/01 12:29:51 thb 1.8.48.2: #i85898# Stripping all external header guards 2008/03/31 12:31:53 rt 1.8.48.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: propertycomposer.hxx,v $
 * $Revision: 1.9 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef EXTENSIONS_SOURCE_PROPCTRLR_PROPERTYCOMPOSER_HXX
#define EXTENSIONS_SOURCE_PROPCTRLR_PROPERTYCOMPOSER_HXX

#include "pcrcommon.hxx"
#include "formbrowsertools.hxx"
#include "composeduiupdate.hxx"
#include "formbrowsertools.hxx"

/** === begin UNO includes === **/
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/inspection/XPropertyHandler.hpp>
#include <com/sun/star/lang/DisposedException.hpp>
/** === end UNO includes === **/
#include <cppuhelper/compbase2.hxx>
#include <comphelper/broadcasthelper.hxx>
#include <comphelper/listenernotification.hxx>

#include <vector>
#include <set>

//........................................................................
namespace pcr
{
//........................................................................

    //====================================================================
    //= PropertyComposer
    //====================================================================
    typedef ::cppu::WeakComponentImplHelper2    <   ::com::sun::star::inspection::XPropertyHandler
                                                ,   ::com::sun::star::beans::XPropertyChangeListener
                                                >   PropertyComposer_Base;
    /** implements an <type>XPropertyHandler</type> which composes it's information
        from a set of other property handlers
    */
    class PropertyComposer  :public PropertyComposer_Base
                            ,public ::comphelper::OBaseMutex
                            ,public IPropertyExistenceCheck
    {
    public:
        typedef ::std::vector< ::com::sun::star::uno::Reference< ::com::sun::star::inspection::XPropertyHandler > >
                                                            HandlerArray;

    private:
        HandlerArray                                    m_aSlaveHandlers;
        ::std::auto_ptr< ComposedPropertyUIUpdate >     m_pUIRequestComposer;
        PropertyChangeListeners                         m_aPropertyListeners;
        bool                                            m_bSupportedPropertiesAreKnown;
        PropertyBag                                     m_aSupportedProperties;

    public:
        /** constructs an <type>XPropertyHandler</type> which composes it's information from a set
            of other property handlers

            @param _rSlaveHandlers
                the set of slave handlers to invoke. Must not be <NULL/>
        */
        PropertyComposer( const ::std::vector< ::com::sun::star::uno::Reference< ::com::sun::star::inspection::XPropertyHandler > >& _rSlaveHandlers );

    public:
        // XPropertyHandler overridables
        virtual void                                SAL_CALL inspect( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _rxIntrospectee ) throw (::com::sun::star::lang::NullPointerException, ::com::sun::star::uno::RuntimeException);
        virtual ::com::sun::star::uno::Any          SAL_CALL getPropertyValue( const ::rtl::OUString& _rPropertyName ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException);
        virtual void                                SAL_CALL setPropertyValue( const ::rtl::OUString& _rPropertyName, const ::com::sun::star::uno::Any& _rValue ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException);
        virtual ::com::sun::star::uno::Any SAL_CALL convertToPropertyValue( const ::rtl::OUString& _rPropertyName, const ::com::sun::star::uno::Any& _rControlValue ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException);
        virtual ::com::sun::star::uno::Any SAL_CALL convertToControlValue( const ::rtl::OUString& _rPropertyName, const ::com::sun::star::uno::Any& _rPropertyValue, const ::com::sun::star::uno::Type& _rControlValueType ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException);
        virtual ::com::sun::star::beans::PropertyState
                                                    SAL_CALL getPropertyState( const ::rtl::OUString& _rPropertyName ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException);
        virtual void                                SAL_CALL addPropertyChangeListener( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& _rxListener ) throw (::com::sun::star::uno::RuntimeException);
        virtual void                                SAL_CALL removePropertyChangeListener( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& _rxListener ) throw (::com::sun::star::uno::RuntimeException);
        virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >
                                                    SAL_CALL getSupportedProperties() throw (::com::sun::star::uno::RuntimeException);
        virtual ::com::sun::star::uno::Sequence< ::rtl::OUString >
                                                    SAL_CALL getSupersededProperties( ) throw (::com::sun::star::uno::RuntimeException);
        virtual ::com::sun::star::uno::Sequence< ::rtl::OUString >
                                                    SAL_CALL getActuatingProperties( ) throw (::com::sun::star::uno::RuntimeException);
        virtual ::com::sun::star::inspection::LineDescriptor
                                                    SAL_CALL describePropertyLine( const ::rtl::OUString& _rPropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::inspection::XPropertyControlFactory >& _rxControlFactory ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::NullPointerException, ::com::sun::star::uno::RuntimeException);
        virtual ::sal_Bool                          SAL_CALL isComposable( const ::rtl::OUString& _rPropertyName ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException);
        virtual ::com::sun::star::inspection::InteractiveSelectionResult
                                                    SAL_CALL onInteractivePropertySelection( const ::rtl::OUString& _rPropertyName, sal_Bool _bPrimary, ::com::sun::star::uno::Any& _rData, const ::com::sun::star::uno::Reference< ::com::sun::star::inspection::XObjectInspectorUI >& _rxInspectorUI ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::NullPointerException, ::com::sun::star::uno::RuntimeException);
        virtual void                                SAL_CALL actuatingPropertyChanged( const ::rtl::OUString& _rActuatingPropertyName, const ::com::sun::star::uno::Any& _rNewValue, const ::com::sun::star::uno::Any& _rOldValue, const ::com::sun::star::uno::Reference< ::com::sun::star::inspection::XObjectInspectorUI >& _rxInspectorUI, sal_Bool _bFirstTimeInit ) throw (::com::sun::star::lang::NullPointerException, ::com::sun::star::uno::RuntimeException);
        virtual sal_Bool                            SAL_CALL suspend( sal_Bool _bSuspend ) throw (::com::sun::star::uno::RuntimeException);

        // XComponent
        DECLARE_XCOMPONENT()
        virtual void                                SAL_CALL disposing();

        // XPropertyChangeListener
        virtual void SAL_CALL propertyChange( const ::com::sun::star::beans::PropertyChangeEvent& evt ) throw (::com::sun::star::uno::RuntimeException);

        // XEventListener
        virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw (::com::sun::star::uno::RuntimeException);

        // IPropertyExistenceCheck
        virtual ::sal_Bool SAL_CALL hasPropertyByName( const ::rtl::OUString& _rName ) throw (::com::sun::star::uno::RuntimeException);

    private:
        /** ensures that m_pUIRequestComposer exists
        */
        void    impl_ensureUIRequestComposer( const ::com::sun::star::uno::Reference< ::com::sun::star::inspection::XObjectInspectorUI >& _rxInspectorUI );

        /** checks whether a given property exists in <member>m_aSupportedProperties</member>
        */
        bool    impl_isSupportedProperty_nothrow( const ::rtl::OUString& _rPropertyName )
        {
            ::com::sun::star::beans::Property aDummy; aDummy.Name = _rPropertyName;
            return m_aSupportedProperties.find( aDummy ) != m_aSupportedProperties.end();
        }

    private:
        class MethodGuard;
        friend class MethodGuard;
        class MethodGuard : public ::osl::MutexGuard
        {
        public:
            MethodGuard( PropertyComposer& _rInstance )
                : ::osl::MutexGuard( _rInstance.m_aMutex )
            {
                if ( _rInstance.m_aSlaveHandlers.empty() )
                    throw ::com::sun::star::lang::DisposedException( ::rtl::OUString(), *(&_rInstance) );
            }
        };
    };

//........................................................................
} // namespace pcr
//........................................................................

#endif // EXTENSIONS_SOURCE_PROPCTRLR_PROPERTYCOMPOSER_HXX

<|endoftext|>


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

/// \file
/// Tests for the Group class.

#include "SurgSim/Graphics/UnitTests/MockObjects.h"
#include "SurgSim/Graphics/UnitTests/MockOsgObjects.h"

#include "SurgSim/Graphics/OsgGroup.h"

#include "gtest/gtest.h"

using SurgSim::Graphics::Actor;
using SurgSim::Graphics::Group;
using SurgSim::Graphics::OsgActor;
using SurgSim::Graphics::OsgGroup;

TEST(OsgGroupTests, InitTest)
{
	ASSERT_NO_THROW({std::shared_ptr<Group> group = std::make_shared<OsgGroup>("test name");});
}

TEST(OsgGroupTests, OsgNodesTest)
{
	std::shared_ptr<OsgGroup> osgGroup = std::make_shared<OsgGroup>("test group");

	osg::ref_ptr<osg::Switch> osgSwitch = dynamic_cast<osg::Switch*>(osgGroup->getOsgGroup().get());
	ASSERT_TRUE(osgSwitch.valid()) << "Group's OSG node should be a switch!";
}

TEST(OsgGroupTests, VisibilityTest)
{
	std::shared_ptr<OsgGroup> osgGroup = std::make_shared<OsgGroup>("test group");
	std::shared_ptr<Group> group = osgGroup;

	EXPECT_TRUE(group->isVisible());

	group->setVisible(true);
	EXPECT_TRUE(group->isVisible());
}

TEST(OsgGroupTests, AddRemoveTest)
{
	std::shared_ptr<OsgGroup> osgGroup = std::make_shared<OsgGroup>("test group");
	std::shared_ptr<Group> group = osgGroup;

	EXPECT_EQ(0u, group->getActors().size());
	EXPECT_EQ(0u, group->getGroups().size());

	osg::ref_ptr<osg::Switch> osgSwitch = dynamic_cast<osg::Switch*>(osgGroup->getOsgGroup().get());
	ASSERT_TRUE(osgSwitch.valid()) << "Group's OSG node should be a switch!";
	EXPECT_EQ(0u, osgSwitch->getNumChildren());

	/// Add an actor and make sure the osg::Switch value for it is set correctly (should be true)
	std::shared_ptr<OsgActor> actor1 = std::make_shared<MockOsgActor>("test actor 1");
	group->addActor(actor1);
	EXPECT_EQ(1u, group->getActors().size());
	EXPECT_EQ(1u, osgSwitch->getNumChildren());
	EXPECT_EQ(0u, osgSwitch->getChildIndex(actor1->getOsgNode()));
	EXPECT_TRUE(osgSwitch->getChildValue(actor1->getOsgNode())) << "Actor 1 should be visible!";

	/// Set group to not visible and check the osg::Switch values
	group->setVisible(false);
	EXPECT_FALSE(group->isVisible());
	EXPECT_FALSE(osgSwitch->getChildValue(actor1->getOsgNode())) << "Actor 1 should not be visible!";

	/// Add another actor and make sure the osg::Switch value for it is set correctly (should be false)
	std::shared_ptr<OsgActor> actor2 = std::make_shared<MockOsgActor>("test actor 2");
	group->addActor(actor2);
	EXPECT_EQ(2u, group->getActors().size());
	EXPECT_EQ(2u, osgSwitch->getNumChildren());
	EXPECT_EQ(1u, osgSwitch->getChildIndex(actor2->getOsgNode()));
	EXPECT_FALSE(osgSwitch->getChildValue(actor2->getOsgNode())) << "Actor 2 should not be visible!";

	/// Set group to visible and check the osg::Switch values
	group->setVisible(true);
	EXPECT_TRUE(group->isVisible());
	EXPECT_TRUE(osgSwitch->getChildValue(actor1->getOsgNode())) << "Actor 1 should be visible!";
	EXPECT_TRUE(osgSwitch->getChildValue(actor2->getOsgNode())) << "Actor 2 should be visible!";

	/// Add a group and make sure the osg::Switch value for it is set correctly (should be true)
	std::shared_ptr<OsgGroup> subGroup1 = std::make_shared<OsgGroup>("test sub-group 1");
	group->addGroup(subGroup1);
	EXPECT_EQ(1u, group->getGroups().size());
	EXPECT_EQ(3u, osgSwitch->getNumChildren());
	EXPECT_EQ(2u, osgSwitch->getChildIndex(subGroup1->getOsgGroup()));
	EXPECT_TRUE(osgSwitch->getChildValue(subGroup1->getOsgGroup())) << "Group 1 should be visible!";

	/// Set group to not visible and check the osg::Switch values
	group->setVisible(false);
	EXPECT_FALSE(group->isVisible());
	EXPECT_FALSE(osgSwitch->getChildValue(actor1->getOsgNode())) << "Actor 1 should not be visible!";
	EXPECT_FALSE(osgSwitch->getChildValue(actor2->getOsgNode())) << "Actor 1 should not be visible!";
	EXPECT_FALSE(osgSwitch->getChildValue(subGroup1->getOsgGroup())) << "Group 1 should not be visible!";

	/// Add another group and make sure the osg::Switch value for it is set correctly (should be false)
	std::shared_ptr<OsgGroup> subGroup2 = std::make_shared<OsgGroup>("test sub-group 1");
	group->addGroup(subGroup2);
	EXPECT_EQ(2u, group->getGroups().size());
	EXPECT_EQ(4u, osgSwitch->getNumChildren());
	EXPECT_EQ(3u, osgSwitch->getChildIndex(subGroup2->getOsgGroup()));
	EXPECT_FALSE(osgSwitch->getChildValue(subGroup2->getOsgGroup())) << "Group 2 should not be visible!";

	/// Set group to visible and check the osg::Switch values
	group->setVisible(true);
	EXPECT_TRUE(group->isVisible());
	EXPECT_TRUE(osgSwitch->getChildValue(actor1->getOsgNode())) << "Actor 1 should be visible!";
	EXPECT_TRUE(osgSwitch->getChildValue(actor2->getOsgNode())) << "Actor 2 should be visible!";
	EXPECT_TRUE(osgSwitch->getChildValue(subGroup1->getOsgGroup())) << "Group 1 should be visible!";
	EXPECT_TRUE(osgSwitch->getChildValue(subGroup2->getOsgGroup())) << "Group 2 should be visible!";

	/// Try to add a duplicate actor
	EXPECT_FALSE(group->addActor(actor1));
	EXPECT_EQ(2u, group->getActors().size());
	EXPECT_EQ(4u, osgSwitch->getNumChildren());

	/// Try to add a duplicate group
	EXPECT_FALSE(group->addGroup(subGroup2));
	EXPECT_EQ(2u, group->getGroups().size());
	EXPECT_EQ(4u, osgSwitch->getNumChildren());

	/// Remove a group
	EXPECT_TRUE(group->removeGroup(subGroup2));
	EXPECT_EQ(3u, osgSwitch->getNumChildren());
	EXPECT_EQ(3u, osgSwitch->getChildIndex(subGroup2->getOsgGroup()));

	/// Remove an actor
	EXPECT_TRUE(group->removeActor(actor1));
	EXPECT_EQ(2u, osgSwitch->getNumChildren());
	EXPECT_EQ(2u, osgSwitch->getChildIndex(actor1->getOsgNode()));

	/// Try to remove a group that is not in the group
	EXPECT_FALSE(group->removeGroup(subGroup2));
	EXPECT_EQ(2u, osgSwitch->getChildIndex(subGroup2->getOsgGroup()));

	/// Try to remove an actor that is not in the group
	EXPECT_FALSE(group->removeActor(actor1));
	EXPECT_EQ(2u, osgSwitch->getChildIndex(actor1->getOsgNode()));

	/// Try to add a non-OSG actor
	std::shared_ptr<MockActor> nonOsgActor = std::make_shared<MockActor>("non-osg actor");
	EXPECT_FALSE(group->addActor(nonOsgActor)) << "OsgGroup should only succeed on actors that derive from OsgActor!";
	EXPECT_EQ(1u, group->getActors().size());
	EXPECT_EQ(group->getActors().end(), std::find(group->getActors().begin(), group->getActors().end(), nonOsgActor));
	EXPECT_EQ(2u, osgSwitch->getNumChildren());

	/// Try to add a non-OSG group
	std::shared_ptr<MockGroup> nonOsgSubgroup = std::make_shared<MockGroup>("non-osg group");
	EXPECT_FALSE(group->addGroup(nonOsgSubgroup)) <<
		"OsgGroup should only succeed on groups that derive from OsgGroup!";
	EXPECT_EQ(1u, group->getGroups().size());
	EXPECT_EQ(group->getGroups().end(), std::find(group->getGroups().begin(),group->getGroups().end(), nonOsgSubgroup));
	EXPECT_EQ(2u, osgSwitch->getNumChildren());
}

TEST(OsgGroupTests, ClearTests)
{
    std::shared_ptr<OsgGroup> osgGroup = std::make_shared<OsgGroup>("test name");
	std::shared_ptr<Group> group = osgGroup;

	std::shared_ptr<Actor> actor1 = std::make_shared<MockOsgActor>("test actor 1");
	std::shared_ptr<Actor> actor2 = std::make_shared<MockOsgActor>("test actor 2");
	std::shared_ptr<Group> group1 = std::make_shared<OsgGroup>("test group 1");
	std::shared_ptr<Group> group2 = std::make_shared<OsgGroup>("test group 2");

    osg::ref_ptr<osg::Switch> osgSwitch = dynamic_cast<osg::Switch*>(osgGroup->getOsgGroup().get());
	ASSERT_TRUE(osgSwitch.valid()) << "Group's OSG node should be a switch!";

	EXPECT_EQ(0u, group->getActors().size());
	EXPECT_EQ(0u, group->getGroups().size());
    EXPECT_EQ(0u, osgSwitch->getNumChildren());

    // Add actors and groups
    group->addActor(actor1);
    group->addActor(actor2);
    group->addGroup(group1);
    group->addGroup(group2);
    EXPECT_EQ(2u, group->getActors().size());
	EXPECT_EQ(2u, group->getGroups().size());
    EXPECT_EQ(4u, osgSwitch->getNumChildren());

    // Remove all actors
    group->clearActors();
    EXPECT_EQ(0u, group->getActors().size());
	EXPECT_EQ(2u, group->getGroups().size());
    EXPECT_EQ(2u, osgSwitch->getNumChildren());

    // Add actors again
    group->addActor(actor1);
    group->addActor(actor2);
    EXPECT_EQ(2u, group->getActors().size());
	EXPECT_EQ(2u, group->getGroups().size());
    EXPECT_EQ(4u, osgSwitch->getNumChildren());

    // Remove all groups
    group->clearGroups();
    EXPECT_EQ(2u, group->getActors().size());
	EXPECT_EQ(0u, group->getGroups().size());
    EXPECT_EQ(2u, osgSwitch->getNumChildren());

    // Add groups again
    group->addGroup(group1);
    group->addGroup(group2);
    EXPECT_EQ(2u, group->getActors().size());
	EXPECT_EQ(2u, group->getGroups().size());
    EXPECT_EQ(4u, osgSwitch->getNumChildren());

    // Remove everything
    group->clear();
    EXPECT_EQ(0u, group->getActors().size());
	EXPECT_EQ(0u, group->getGroups().size());
    EXPECT_EQ(0u, osgSwitch->getNumChildren());
}<commit_msg>Fix spacing in OsgGroupTests<commit_after>// This file is a part of the OpenSurgSim project.
// Copyright 2012-2013, SimQuest Solutions Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/// \file
/// Tests for the Group class.

#include "SurgSim/Graphics/UnitTests/MockObjects.h"
#include "SurgSim/Graphics/UnitTests/MockOsgObjects.h"

#include "SurgSim/Graphics/OsgGroup.h"

#include "gtest/gtest.h"

using SurgSim::Graphics::Actor;
using SurgSim::Graphics::Group;
using SurgSim::Graphics::OsgActor;
using SurgSim::Graphics::OsgGroup;

TEST(OsgGroupTests, InitTest)
{
	ASSERT_NO_THROW({std::shared_ptr<Group> group = std::make_shared<OsgGroup>("test name");});
}

TEST(OsgGroupTests, OsgNodesTest)
{
	std::shared_ptr<OsgGroup> osgGroup = std::make_shared<OsgGroup>("test group");

	osg::ref_ptr<osg::Switch> osgSwitch = dynamic_cast<osg::Switch*>(osgGroup->getOsgGroup().get());
	ASSERT_TRUE(osgSwitch.valid()) << "Group's OSG node should be a switch!";
}

TEST(OsgGroupTests, VisibilityTest)
{
	std::shared_ptr<OsgGroup> osgGroup = std::make_shared<OsgGroup>("test group");
	std::shared_ptr<Group> group = osgGroup;

	EXPECT_TRUE(group->isVisible());

	group->setVisible(true);
	EXPECT_TRUE(group->isVisible());
}

TEST(OsgGroupTests, AddRemoveTest)
{
	std::shared_ptr<OsgGroup> osgGroup = std::make_shared<OsgGroup>("test group");
	std::shared_ptr<Group> group = osgGroup;

	EXPECT_EQ(0u, group->getActors().size());
	EXPECT_EQ(0u, group->getGroups().size());

	osg::ref_ptr<osg::Switch> osgSwitch = dynamic_cast<osg::Switch*>(osgGroup->getOsgGroup().get());
	ASSERT_TRUE(osgSwitch.valid()) << "Group's OSG node should be a switch!";
	EXPECT_EQ(0u, osgSwitch->getNumChildren());

	/// Add an actor and make sure the osg::Switch value for it is set correctly (should be true)
	std::shared_ptr<OsgActor> actor1 = std::make_shared<MockOsgActor>("test actor 1");
	group->addActor(actor1);
	EXPECT_EQ(1u, group->getActors().size());
	EXPECT_EQ(1u, osgSwitch->getNumChildren());
	EXPECT_EQ(0u, osgSwitch->getChildIndex(actor1->getOsgNode()));
	EXPECT_TRUE(osgSwitch->getChildValue(actor1->getOsgNode())) << "Actor 1 should be visible!";

	/// Set group to not visible and check the osg::Switch values
	group->setVisible(false);
	EXPECT_FALSE(group->isVisible());
	EXPECT_FALSE(osgSwitch->getChildValue(actor1->getOsgNode())) << "Actor 1 should not be visible!";

	/// Add another actor and make sure the osg::Switch value for it is set correctly (should be false)
	std::shared_ptr<OsgActor> actor2 = std::make_shared<MockOsgActor>("test actor 2");
	group->addActor(actor2);
	EXPECT_EQ(2u, group->getActors().size());
	EXPECT_EQ(2u, osgSwitch->getNumChildren());
	EXPECT_EQ(1u, osgSwitch->getChildIndex(actor2->getOsgNode()));
	EXPECT_FALSE(osgSwitch->getChildValue(actor2->getOsgNode())) << "Actor 2 should not be visible!";

	/// Set group to visible and check the osg::Switch values
	group->setVisible(true);
	EXPECT_TRUE(group->isVisible());
	EXPECT_TRUE(osgSwitch->getChildValue(actor1->getOsgNode())) << "Actor 1 should be visible!";
	EXPECT_TRUE(osgSwitch->getChildValue(actor2->getOsgNode())) << "Actor 2 should be visible!";

	/// Add a group and make sure the osg::Switch value for it is set correctly (should be true)
	std::shared_ptr<OsgGroup> subGroup1 = std::make_shared<OsgGroup>("test sub-group 1");
	group->addGroup(subGroup1);
	EXPECT_EQ(1u, group->getGroups().size());
	EXPECT_EQ(3u, osgSwitch->getNumChildren());
	EXPECT_EQ(2u, osgSwitch->getChildIndex(subGroup1->getOsgGroup()));
	EXPECT_TRUE(osgSwitch->getChildValue(subGroup1->getOsgGroup())) << "Group 1 should be visible!";

	/// Set group to not visible and check the osg::Switch values
	group->setVisible(false);
	EXPECT_FALSE(group->isVisible());
	EXPECT_FALSE(osgSwitch->getChildValue(actor1->getOsgNode())) << "Actor 1 should not be visible!";
	EXPECT_FALSE(osgSwitch->getChildValue(actor2->getOsgNode())) << "Actor 1 should not be visible!";
	EXPECT_FALSE(osgSwitch->getChildValue(subGroup1->getOsgGroup())) << "Group 1 should not be visible!";

	/// Add another group and make sure the osg::Switch value for it is set correctly (should be false)
	std::shared_ptr<OsgGroup> subGroup2 = std::make_shared<OsgGroup>("test sub-group 1");
	group->addGroup(subGroup2);
	EXPECT_EQ(2u, group->getGroups().size());
	EXPECT_EQ(4u, osgSwitch->getNumChildren());
	EXPECT_EQ(3u, osgSwitch->getChildIndex(subGroup2->getOsgGroup()));
	EXPECT_FALSE(osgSwitch->getChildValue(subGroup2->getOsgGroup())) << "Group 2 should not be visible!";

	/// Set group to visible and check the osg::Switch values
	group->setVisible(true);
	EXPECT_TRUE(group->isVisible());
	EXPECT_TRUE(osgSwitch->getChildValue(actor1->getOsgNode())) << "Actor 1 should be visible!";
	EXPECT_TRUE(osgSwitch->getChildValue(actor2->getOsgNode())) << "Actor 2 should be visible!";
	EXPECT_TRUE(osgSwitch->getChildValue(subGroup1->getOsgGroup())) << "Group 1 should be visible!";
	EXPECT_TRUE(osgSwitch->getChildValue(subGroup2->getOsgGroup())) << "Group 2 should be visible!";

	/// Try to add a duplicate actor
	EXPECT_FALSE(group->addActor(actor1));
	EXPECT_EQ(2u, group->getActors().size());
	EXPECT_EQ(4u, osgSwitch->getNumChildren());

	/// Try to add a duplicate group
	EXPECT_FALSE(group->addGroup(subGroup2));
	EXPECT_EQ(2u, group->getGroups().size());
	EXPECT_EQ(4u, osgSwitch->getNumChildren());

	/// Remove a group
	EXPECT_TRUE(group->removeGroup(subGroup2));
	EXPECT_EQ(3u, osgSwitch->getNumChildren());
	EXPECT_EQ(3u, osgSwitch->getChildIndex(subGroup2->getOsgGroup()));

	/// Remove an actor
	EXPECT_TRUE(group->removeActor(actor1));
	EXPECT_EQ(2u, osgSwitch->getNumChildren());
	EXPECT_EQ(2u, osgSwitch->getChildIndex(actor1->getOsgNode()));

	/// Try to remove a group that is not in the group
	EXPECT_FALSE(group->removeGroup(subGroup2));
	EXPECT_EQ(2u, osgSwitch->getChildIndex(subGroup2->getOsgGroup()));

	/// Try to remove an actor that is not in the group
	EXPECT_FALSE(group->removeActor(actor1));
	EXPECT_EQ(2u, osgSwitch->getChildIndex(actor1->getOsgNode()));

	/// Try to add a non-OSG actor
	std::shared_ptr<MockActor> nonOsgActor = std::make_shared<MockActor>("non-osg actor");
	EXPECT_FALSE(group->addActor(nonOsgActor)) << "OsgGroup should only succeed on actors that derive from OsgActor!";
	EXPECT_EQ(1u, group->getActors().size());
	EXPECT_EQ(group->getActors().end(), std::find(group->getActors().begin(), group->getActors().end(), nonOsgActor));
	EXPECT_EQ(2u, osgSwitch->getNumChildren());

	/// Try to add a non-OSG group
	std::shared_ptr<MockGroup> nonOsgSubgroup = std::make_shared<MockGroup>("non-osg group");
	EXPECT_FALSE(group->addGroup(nonOsgSubgroup)) <<
		"OsgGroup should only succeed on groups that derive from OsgGroup!";
	EXPECT_EQ(1u, group->getGroups().size());
	EXPECT_EQ(group->getGroups().end(), std::find(group->getGroups().begin(),group->getGroups().end(), nonOsgSubgroup));
	EXPECT_EQ(2u, osgSwitch->getNumChildren());
}

TEST(OsgGroupTests, ClearTests)
{
	std::shared_ptr<OsgGroup> osgGroup = std::make_shared<OsgGroup>("test name");
	std::shared_ptr<Group> group = osgGroup;

	std::shared_ptr<Actor> actor1 = std::make_shared<MockOsgActor>("test actor 1");
	std::shared_ptr<Actor> actor2 = std::make_shared<MockOsgActor>("test actor 2");
	std::shared_ptr<Group> group1 = std::make_shared<OsgGroup>("test group 1");
	std::shared_ptr<Group> group2 = std::make_shared<OsgGroup>("test group 2");

	osg::ref_ptr<osg::Switch> osgSwitch = dynamic_cast<osg::Switch*>(osgGroup->getOsgGroup().get());
	ASSERT_TRUE(osgSwitch.valid()) << "Group's OSG node should be a switch!";

	EXPECT_EQ(0u, group->getActors().size());
	EXPECT_EQ(0u, group->getGroups().size());
	EXPECT_EQ(0u, osgSwitch->getNumChildren());

	// Add actors and groups
	group->addActor(actor1);
	group->addActor(actor2);
	group->addGroup(group1);
	group->addGroup(group2);
	EXPECT_EQ(2u, group->getActors().size());
	EXPECT_EQ(2u, group->getGroups().size());
	EXPECT_EQ(4u, osgSwitch->getNumChildren());

	// Remove all actors
	group->clearActors();
	EXPECT_EQ(0u, group->getActors().size());
	EXPECT_EQ(2u, group->getGroups().size());
	EXPECT_EQ(2u, osgSwitch->getNumChildren());

	// Add actors again
	group->addActor(actor1);
	group->addActor(actor2);
	EXPECT_EQ(2u, group->getActors().size());
	EXPECT_EQ(2u, group->getGroups().size());
	EXPECT_EQ(4u, osgSwitch->getNumChildren());

	// Remove all groups
	group->clearGroups();
	EXPECT_EQ(2u, group->getActors().size());
	EXPECT_EQ(0u, group->getGroups().size());
	EXPECT_EQ(2u, osgSwitch->getNumChildren());

	// Add groups again
	group->addGroup(group1);
	group->addGroup(group2);
	EXPECT_EQ(2u, group->getActors().size());
	EXPECT_EQ(2u, group->getGroups().size());
	EXPECT_EQ(4u, osgSwitch->getNumChildren());

	// Remove everything
	group->clear();
	EXPECT_EQ(0u, group->getActors().size());
	EXPECT_EQ(0u, group->getGroups().size());
	EXPECT_EQ(0u, osgSwitch->getNumChildren());
}<|endoftext|>