<commit_before>/** \copyright
 * Copyright (c) 2013, Balazs Racz
 * 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.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * \file client.cxx
 *
 * A fake application meant to be compiled into a .js library. This library can
 * be included in html pages to add an OpenLCB stack running in the browser.
 *
 * @author Balazs Racz
 * @date 13 Sep 2015
 */

#include <emscripten.h>
#include <emscripten/bind.h>
#include <emscripten/val.h>

#include <memory>

#include "os/os.h"
#include "can_frame.h"
#include "nmranet_config.h"

#include "os/TempFile.hxx"
#include "nmranet/SimpleStack.hxx"
#include "nmranet/SimpleNodeInfoMockUserFile.hxx"
#include "nmranet/EventHandlerTemplates.hxx"
#include "utils/JSWebsocketClient.hxx"

const nmranet::NodeID NODE_ID = 0x0501010114DFULL;

nmranet::SimpleCanStack stack(NODE_ID);

nmranet::MockSNIPUserFile snip_user_file("Default user name",
                                         "Default user description");
const char *const nmranet::SNIP_DYNAMIC_FILENAME =
    nmranet::MockSNIPUserFile::snip_user_file_path;

void start_stack()
{
    emscripten_cancel_main_loop();
    stack.loop_executor();
    EM_ASM(console.log('stack start done'););
}

void ignore_function()
{
}

class JSBitEventPC : private nmranet::BitEventInterface
{
public:
    JSBitEventPC(std::string event_on, emscripten::val fn_on_cb,
                 std::string event_off, emscripten::val fn_off_cb)
        : BitEventInterface(parse_event_id(event_on), parse_event_id(event_off))
        , eventOnCallback_(fn_on_cb)
        , eventOffCallback_(fn_off_cb)
        , consumer_(this)
    {
    }

private:
    static uint64_t parse_event_id(const string &s)
    {
        return strtoll(s.c_str(), nullptr, 16);
    }

    nmranet::Node *node() OVERRIDE
    {
        return stack.node();
    }

    void SetState(bool new_value) OVERRIDE {
        lastValue_ = new_value;
        if (new_value) {
            eventOnCallback_();
        } else {
            eventOffCallback_();
        }
    }

    bool GetCurrentState() OVERRIDE {
        return lastValue_;
    }

    bool lastValue_{false};
    emscripten::val eventOnCallback_;
    emscripten::val eventOffCallback_;
    nmranet::BitEventPC consumer_;
};

/** Entry point to application.
 * @param argc number of command line arguments
 * @param argv array of command line arguments
 * @return 0, should never return
 */
int appl_main(int argc, char *argv[])
{
    new JSWebsocketClient(stack.can_hub(), "ws://localhost:50003");

    // We delay the start of the stack until the connection is established.
    emscripten_set_main_loop(&ignore_function, 0, true);
    return 0;
}

EMSCRIPTEN_BINDINGS(js_client_main)
{
    emscripten::function("startStack", &start_stack);
    emscripten::class_<JSBitEventPC>("BitEventPC")
        .constructor<std::string, emscripten::val, std::string,
                     emscripten::val>();
}
<commit_msg>Adds two features to the javascript binding: - avoids resetting event state to zero at startup. - queries all event states upon startup. - allows javascript to toggle the bit by producing the necessary event.<commit_after>/** \copyright
 * Copyright (c) 2013, Balazs Racz
 * 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.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * \file client.cxx
 *
 * A fake application meant to be compiled into a .js library. This library can
 * be included in html pages to add an OpenLCB stack running in the browser.
 *
 * @author Balazs Racz
 * @date 13 Sep 2015
 */

#include <emscripten.h>
#include <emscripten/bind.h>
#include <emscripten/val.h>

#include <memory>
#include <set>

#include "os/os.h"
#include "can_frame.h"
#include "nmranet_config.h"

#include "os/TempFile.hxx"
#include "nmranet/Defs.hxx"
#include "nmranet/SimpleStack.hxx"
#include "nmranet/SimpleNodeInfoMockUserFile.hxx"
#include "nmranet/EventHandlerTemplates.hxx"
#include "utils/JSWebsocketClient.hxx"

const nmranet::NodeID NODE_ID = 0x0501010114DFULL;

nmranet::SimpleCanStack stack(NODE_ID);

nmranet::MockSNIPUserFile snip_user_file(
    "Default user name", "Default user description");
const char *const nmranet::SNIP_DYNAMIC_FILENAME =
    nmranet::MockSNIPUserFile::snip_user_file_path;

void start_stack()
{
    emscripten_cancel_main_loop();
    stack.loop_executor();
    EM_ASM(console.log('stack start done'););
}

void ignore_function()
{
}

class QueryFlow : public StateFlowBase
{
public:
    QueryFlow()
        : StateFlowBase(stack.service())
    {
        start_flow(STATE(wait_for_initialized));
    }

    void add_event(uint64_t event_id)
    {
        /// @TODO (balazs.racz) handle the case when events are insnerted after
        /// the iteration has begun.
        events_.insert(event_id);
    }

private:
    Action wait_for_initialized()
    {
        if (!stack.node()->is_initialized())
        {
            return sleep_and_call(
                &timer_, SEC_TO_NSEC(1), STATE(wait_for_initialized));
        }
        return call_immediately(STATE(start_iteration));
    }

    Action start_iteration()
    {
        nextEvent_ = events_.begin();
        return call_immediately(STATE(iterate));
    }

    Action iterate()
    {
        if (nextEvent_ == events_.end())
        {
            return exit();
        }
        return allocate_and_call(
            stack.node()->interface()->global_message_write_flow(),
            STATE(send_query));
    }

    Action send_query()
    {
        auto *f = stack.node()->interface()->global_message_write_flow();
        auto *b = get_allocation_result(f);
        b->data()->reset(nmranet::Defs::MTI_PRODUCER_IDENTIFY, stack.node()->node_id(),
                         nmranet::eventid_to_buffer(*nextEvent_));
        b->data()->set_flag_dst(nmranet::NMRAnetMessage::WAIT_FOR_LOCAL_LOOPBACK);
        b->set_done(n_.reset(this));
        f->send(b);
        nextEvent_++;
        return wait_and_call(STATE(delay_before_iterate));
    }

    Action delay_before_iterate() {
        return sleep_and_call(&timer_, MSEC_TO_NSEC(5), STATE(iterate));
    }

    using EventList = std::set<uint64_t>;
    EventList events_;
    EventList::iterator nextEvent_;
    BarrierNotifiable n_;
    StateFlowTimer timer_{this};
} g_query_flow;

class JSBitEventPC : private nmranet::BitEventInterface
{
public:
    JSBitEventPC(std::string event_on, emscripten::val fn_on_cb,
        std::string event_off, emscripten::val fn_off_cb)
        : BitEventInterface(parse_event_id(event_on), parse_event_id(event_off))
        , eventOnCallback_(fn_on_cb)
        , eventOffCallback_(fn_off_cb)
        , consumer_(this)
    {
        g_query_flow.add_event(BitEventInterface::event_on());
    }

    void toggleState()
    {
        if (!hasValue_)
        {
            return;
        }
        /// @TODO(balazs.racz) ideally we should be able to just call
        /// SendEventReport. However, that requires a WriteHelper and there is
        /// no option to allocate a buffer dynamically.
        lastValue_ = !lastValue_;
        auto *f = stack.node()->interface()->global_message_write_flow();
        auto *b = f->alloc();
        b->data()->reset(nmranet::Defs::MTI_EVENT_REPORT,
            stack.node()->node_id(),
            nmranet::eventid_to_buffer(lastValue_ ? event_on() : event_off()));
        f->send(b);
    }

private:
    static uint64_t parse_event_id(const string &s)
    {
        return strtoll(s.c_str(), nullptr, 16);
    }

    nmranet::Node *node() OVERRIDE
    {
        return stack.node();
    }

    void SetState(bool new_value) OVERRIDE
    {
        lastValue_ = new_value;
        hasValue_ = true;
        if (new_value)
        {
            eventOnCallback_();
        }
        else
        {
            eventOffCallback_();
        }
    }

    nmranet::EventState GetCurrentState() OVERRIDE
    {
        using nmranet::EventState;
        if (!hasValue_)
            return EventState::UNKNOWN;
        return lastValue_ ? EventState::VALID : EventState::INVALID;
    }

    bool hasValue_{false};
    bool lastValue_{false};
    emscripten::val eventOnCallback_;
    emscripten::val eventOffCallback_;
    nmranet::BitEventPC consumer_;
};

/** Entry point to application.
 * @param argc number of command line arguments
 * @param argv array of command line arguments
 * @return 0, should never return
 */
int appl_main(int argc, char *argv[])
{
    new JSWebsocketClient(stack.can_hub(), "ws://localhost:50003");

    // We delay the start of the stack until the connection is established.
    emscripten_set_main_loop(&ignore_function, 0, true);
    return 0;
}

EMSCRIPTEN_BINDINGS(js_client_main)
{
    emscripten::function("startStack", &start_stack);
    emscripten::class_<JSBitEventPC>("BitEventPC")
        .constructor<std::string, emscripten::val, std::string,
            emscripten::val>()
        .function("toggleState", &JSBitEventPC::toggleState);
}
<|endoftext|>


<commit_before>// Copyright (c) 2010 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 "base/command_line.h"
#include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/common/chrome_switches.h"

#if defined(TOOLKIT_VIEWS) || defined(OS_MACOSX)
#define MAYBE_Infobars Infobars
#else
// Need to finish port to Linux. See http://crbug.com/39916 for details.
#define MAYBE_Infobars DISABLED_Infobars
#endif

IN_PROC_BROWSER_TEST_F(ExtensionApiTest, MAYBE_Infobars) {
  // TODO(finnur): Remove once infobars are no longer experimental (bug 39511).
  CommandLine::ForCurrentProcess()->AppendSwitch(
      switches::kEnableExperimentalExtensionApis);

  ASSERT_TRUE(RunExtensionTest("infobars")) << message_;
}
<commit_msg>Marking ExtensionApiTest.Infobars as FAILS until 10.5 issue is resolved. BUG=60990<commit_after>// Copyright (c) 2010 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 "base/command_line.h"
#include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/common/chrome_switches.h"

#if defined(TOOLKIT_VIEWS)
#define MAYBE_Infobars Infobars
#elif defined(OS_MACOSX)
// Temporarily marking as FAILS. See http://crbug.com/60990 for details.
#define MAYBE_Infobars FAILS_Infobars
#else
// Need to finish port to Linux. See http://crbug.com/39916 for details.
#define MAYBE_Infobars DISABLED_Infobars
#endif

IN_PROC_BROWSER_TEST_F(ExtensionApiTest, MAYBE_Infobars) {
  // TODO(finnur): Remove once infobars are no longer experimental (bug 39511).
  CommandLine::ForCurrentProcess()->AppendSwitch(
      switches::kEnableExperimentalExtensionApis);

  ASSERT_TRUE(RunExtensionTest("infobars")) << message_;
}
<|endoftext|>


<commit_before>/* -------------------------------------------------------------------------- *
 *                      SimTK Core: SimTKcommon                               *
 * -------------------------------------------------------------------------- *
 * This is part of the SimTK Core biosimulation toolkit originating from      *
 * Simbios, the NIH National Center for Physics-Based Simulation of           *
 * Biological Structures at Stanford, funded under the NIH Roadmap for        *
 * Medical Research, grant U54 GM072970. See https://simtk.org.               *
 *                                                                            *
 * Portions copyright (c) 2010 Stanford University and the Authors.           *
 * Authors: Michael Sherman                                                   *
 * Contributors:                                                              *
 *                                                                            *
 * Permission is hereby granted, free of charge, to any person obtaining a    *
 * copy of this software and associated documentation files (the "Software"), *
 * to deal in the Software without restriction, including without limitation  *
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,   *
 * and/or sell copies of the Software, and to permit persons to whom the      *
 * Software is furnished to do so, subject to the following conditions:       *
 *                                                                            *
 * The above copyright notice and this permission notice shall be included in *
 * all copies or substantial portions of the Software.                        *
 *                                                                            *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   *
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    *
 * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,    *
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR      *
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE  *
 * USE OR OTHER DEALINGS IN THE SOFTWARE.                                     *
 * -------------------------------------------------------------------------- */

/*
 * These are regression tests for the SimTK::Array_<T,X> class.
 */

#include "SimTKcommon.h"
#include "SimTKcommon/Testing.h"

#include <vector>
#include <iostream>
using std::cout;
using std::endl;

template <class T>
std::ostream& operator<<(std::ostream& o, std::vector<T>& v) {
    o << '<';
    if (!v.empty()) {
        o << v.front();
        for (unsigned i=1; i < v.size(); ++i)
            o << ' ' << v[i];
    }
    return o << '>';
}

using namespace SimTK;

template <class T>
class OtherArray_ : public Array_<T> {
public:
    typedef typename Array_<T>::size_type size_type;

    OtherArray_() : Array_<T>() {}
    OtherArray_(size_type n, const T& v) : Array_<T>(n,v) {}
};

SimTK_DEFINE_UNIQUE_INDEX_TYPE(TestIx);

class SmallIx {
public:
    SmallIx() : ix(0xff) {}
    explicit SmallIx(unsigned char i) : ix(i) {}

    SmallIx& operator++()
    {   assert(ix<max_size); ++ix; return *this;}
    SmallIx operator++(int)
    {   assert(ix<max_size); const SmallIx x=*this; ++ix; return x;}
    SmallIx& operator--()
    {   assert(ix>0); --ix; return *this;}
    SmallIx operator--(int)
    {   assert(ix>0); const SmallIx x=*this; ++ix; return x;}
    operator unsigned char() const
    {   return ix;}

    typedef unsigned char index_type;
    typedef unsigned char size_type;
    typedef signed char   difference_type;
    static const size_type max_size = 4;
    static const char* index_name() {return "SmallIx";}
private:
    unsigned char ix;
};

class Counter {
public:
    Counter() : count(0) {}
    Counter& operator=(int i) {count=i; return *this;}
    Counter& operator++() {++count; return *this;}
    Counter operator++(int) {const Counter c=*this; ++count; return c;}
    Counter& reset() {count=0; return *this;}
    operator int() const {return count;}
private:
    mutable int count;
};
inline std::ostream&
operator<<(std::ostream& o, const Counter& c) {
    return o << (int)c;
}

template <class T>
struct Count {
    Count() {++defCtor;}
    Count(const T& t) : val(t) {++initCtor;}
    Count(const Count& c) : val(c.val) {++copyCtor;}
    ~Count() {++dtor;}

    static void dumpCounts(const char* msg) {
        cout << msg << ":";
        cout << " def=" << Count<int>::defCtor;
        cout << " init=" << Count<int>::initCtor;
        cout << " copy=" << Count<int>::copyCtor;
        cout << " dtor=" << Count<int>::dtor;
        cout << endl;
    }

    T val;

    static void reset() {defCtor=initCtor=copyCtor=dtor=0;}
    static Counter defCtor;
    static Counter initCtor;
    static Counter copyCtor;
    static Counter dtor;
};
template <class T> inline std::ostream&
operator<<(std::ostream& o, const Count<T>& c) {
    return o << c.val;
}
template <class T> Counter Count<T>::defCtor;
template <class T> Counter Count<T>::initCtor;
template <class T> Counter Count<T>::copyCtor;
template <class T> Counter Count<T>::dtor;

// Instantiate the whole class to check for compilation problems.
template class Array_<int>;
template class Array_<std::string, unsigned char>;

#ifdef _MSC_VER // gcc 4.1.2 had trouble with this
// Instantiate templatized methods
typedef std::set<float>::const_iterator inputIt; // not a random access iterator

// Constructors.
template Array_<float,int>::Array_(const Array_<float,int>&);
template Array_<float,int>::Array_(const float*,const float*);

// Assignment.
template Array_<float,int>&
Array_<float,int>::assign(const float*,const float*);
template Array_<double,int>&
Array_<double,int>::assign(const inputIt&, const inputIt&);
template Array_<float,int>&
Array_<float,int>::operator=(const Array_<float,int>&);
template Array_<double,int>&
Array_<double,int>::operator=(const std::vector<float>&);

// Comparison
template bool SimTK::operator==(const ConstArray_<float,int>&,
                                const ConstArray_<float,unsigned>&);
#endif

void testConstruction() {
    const int data[] = {5,3,-2,27,9};
    const char uchar[] = {'f','i','t','z'};
    Array_<int> nothing;
    Array_<int> def(5);
    Array_<int> intWithInt(data, data+5);
    Array_<char> charWithChar(uchar, uchar+4);
    Array_<int>  intWithChar(uchar, uchar+4);
    Array_<char>  charWithInt(data, data+5);
    cout << "nothing=" << nothing << endl;
    cout << "def=" << def << endl;
    cout << "intWithInt=" << intWithInt << endl;
    cout << "charWithChar=" << charWithChar << endl;
    cout << "intWithChar=" << intWithChar << endl;
    cout << "charWithInt=" << charWithInt << endl;

    Array_< Count<int> > cint(data, data+5);
    Count<int>::dumpCounts("cint(data,data+5)");
    Count<int>::reset();

    const Count<int> counts[] = {3,4,5};
    Count<int>::reset();
    Array_< Count<int> > ccnt(counts, counts+3);
    Count<int>::dumpCounts("ccnt(counts,counts+3)");
    Count<int>::reset();

    Array_< Count<int> > cint2(cint);
    Count<int>::dumpCounts("cint2(cint)");
    Count<int>::reset();

    cint2 = ccnt;
    Count<int>::dumpCounts("cint2=ccnt");
    Count<int>::reset();
    cout << "cint2=" << cint2 << endl;

    Array_<int,SmallIx> ismall0;
    cout << "default constructed Array_<int> begin()=" << ismall0.begin()
         << " end()=" << ismall0.end()
         << " capacity()=" << (int)ismall0.capacity()
         << endl;

    std::vector<int> ivec0;
    cout << "default constructed std::vector<int>"
         << " capacity()=" << ivec0.capacity()
         << endl;

    Array_<int,SmallIx> ismall(3);
    Array_<int,SmallIx> imaxsz(data, data+4);
    cout << "ismall0=" << ismall0 << endl;
    cout << "ismall=" << ismall << endl;
    cout << "imaxsz=" << imaxsz << endl;

    new(ismall.raw_push_back()) int(27);
    cout << "ismall after raw_push_back():" << ismall << endl;

    // Check null assignments.
    ismall = ismall0; // src is null
    ismall0 = imaxsz; // dest was null
    ismall = Array_<int,SmallIx>(); // both null

    cout << "sizeof(Array_<int,short>)=" << sizeof(Array_<int,short>) << endl;
    cout << "sizeof(Array_<int>)=" << sizeof(Array_<int>) << endl;
    cout << "sizeof(std::vector<int>)=" << sizeof(std::vector<int>) << endl;

    Array_<String, TestIx> strings(6, "woohoo");
    cout << "strings=" << strings << endl;
    strings.push_back("last");
    for (int i=0; i<5; ++i) {
        strings.insert(strings.end(), 2, "ins" + String(i));
        cout << strings.size() << ":" << strings.capacity()
                               << ":" << strings << endl;
    }
    cout << "strings=" << strings << endl;

    Array_<String, TestIx>::reverse_iterator p = strings.rbegin();
    while (p != strings.rend())
        cout << " " << *p++;
    cout << endl;

    const int ownerData[] = {7, 77, 777, 7777, 77777};
    std::vector<int> owner(ownerData, ownerData+5);
    std::vector<unsigned> unowner(owner.begin(), owner.end());
    Array_<int> shared; shared.shareData(&owner[1], &owner[4]);
    cout << "vector before=" << owner << endl;
    cout << "shared before=" << shared << endl;
    shared[2] = 29;
    cout << "shared after=" << shared << endl;
    cout << "vector after=" << owner << endl;
    cout << "shared(1,2)=" << shared(1,2) << endl;

    Array_<int> copyOfOwner(owner);
    cout << "copyOfOwner=" << copyOfOwner << endl;
    Array_<unsigned short,char> weirdCopy(owner);
    cout << "weirdCopy=" << weirdCopy << endl;
    copyOfOwner = unowner;
    cout << "copyOfOwner=unowner=" << copyOfOwner << endl;

    Array_<unsigned> shareOfUnowner(unowner, DontCopy());
    cout << "shareOfUnowner=" << shareOfUnowner << endl;

    shareOfUnowner(1,3) = Array_<unsigned>(3,88);
    cout << "shareOfUnowner=" << shareOfUnowner << endl;

    OtherArray_<int> oa(5, -4);
    cout << "oa=" << oa << endl;
}

int main() {
    SimTK_START_TEST("TestArray");

        SimTK_SUBTEST(testConstruction);

    SimTK_END_TEST();
}

<commit_msg>added some conversion tests<commit_after>/* -------------------------------------------------------------------------- *
 *                      SimTK Core: SimTKcommon                               *
 * -------------------------------------------------------------------------- *
 * This is part of the SimTK Core biosimulation toolkit originating from      *
 * Simbios, the NIH National Center for Physics-Based Simulation of           *
 * Biological Structures at Stanford, funded under the NIH Roadmap for        *
 * Medical Research, grant U54 GM072970. See https://simtk.org.               *
 *                                                                            *
 * Portions copyright (c) 2010 Stanford University and the Authors.           *
 * Authors: Michael Sherman                                                   *
 * Contributors:                                                              *
 *                                                                            *
 * Permission is hereby granted, free of charge, to any person obtaining a    *
 * copy of this software and associated documentation files (the "Software"), *
 * to deal in the Software without restriction, including without limitation  *
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,   *
 * and/or sell copies of the Software, and to permit persons to whom the      *
 * Software is furnished to do so, subject to the following conditions:       *
 *                                                                            *
 * The above copyright notice and this permission notice shall be included in *
 * all copies or substantial portions of the Software.                        *
 *                                                                            *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   *
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    *
 * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,    *
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR      *
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE  *
 * USE OR OTHER DEALINGS IN THE SOFTWARE.                                     *
 * -------------------------------------------------------------------------- */

/*
 * These are regression tests for the SimTK::Array_<T,X> class.
 */

#include "SimTKcommon.h"
#include "SimTKcommon/Testing.h"

#include <vector>
#include <iostream>
using std::cout;
using std::endl;

template <class T>
std::ostream& operator<<(std::ostream& o, std::vector<T>& v) {
    o << '<';
    if (!v.empty()) {
        o << v.front();
        for (unsigned i=1; i < v.size(); ++i)
            o << ' ' << v[i];
    }
    return o << '>';
}

using namespace SimTK;

template <class T>
class OtherArray_ : public Array_<T> {
public:
    typedef typename Array_<T>::size_type size_type;

    OtherArray_() : Array_<T>() {}
    OtherArray_(size_type n, const T& v) : Array_<T>(n,v) {}
};

SimTK_DEFINE_UNIQUE_INDEX_TYPE(TestIx);

class SmallIx {
public:
    SmallIx() : ix(0xff) {}
    explicit SmallIx(unsigned char i) : ix(i) {}

    SmallIx& operator++()
    {   assert(ix<max_size); ++ix; return *this;}
    SmallIx operator++(int)
    {   assert(ix<max_size); const SmallIx x=*this; ++ix; return x;}
    SmallIx& operator--()
    {   assert(ix>0); --ix; return *this;}
    SmallIx operator--(int)
    {   assert(ix>0); const SmallIx x=*this; ++ix; return x;}
    operator unsigned char() const
    {   return ix;}

    typedef unsigned char index_type;
    typedef unsigned char size_type;
    typedef signed char   difference_type;
    static const size_type max_size = 4;
    static const char* index_name() {return "SmallIx";}
private:
    unsigned char ix;
};

class Counter {
public:
    Counter() : count(0) {}
    Counter& operator=(int i) {count=i; return *this;}
    Counter& operator++() {++count; return *this;}
    Counter operator++(int) {const Counter c=*this; ++count; return c;}
    Counter& reset() {count=0; return *this;}
    operator int() const {return count;}
private:
    mutable int count;
};
inline std::ostream&
operator<<(std::ostream& o, const Counter& c) {
    return o << (int)c;
}

template <class T>
struct Count {
    Count() {++defCtor;}
    Count(const T& t) : val(t) {++initCtor;}
    Count(const Count& c) : val(c.val) {++copyCtor;}
    ~Count() {++dtor;}

    static void dumpCounts(const char* msg) {
        cout << msg << ":";
        cout << " def=" << Count<int>::defCtor;
        cout << " init=" << Count<int>::initCtor;
        cout << " copy=" << Count<int>::copyCtor;
        cout << " dtor=" << Count<int>::dtor;
        cout << endl;
    }

    T val;

    static void reset() {defCtor=initCtor=copyCtor=dtor=0;}
    static Counter defCtor;
    static Counter initCtor;
    static Counter copyCtor;
    static Counter dtor;
};
template <class T> inline std::ostream&
operator<<(std::ostream& o, const Count<T>& c) {
    return o << c.val;
}
template <class T> Counter Count<T>::defCtor;
template <class T> Counter Count<T>::initCtor;
template <class T> Counter Count<T>::copyCtor;
template <class T> Counter Count<T>::dtor;

// Instantiate the whole class to check for compilation problems.
template class Array_<int>;
template class Array_<std::string, unsigned char>;

#ifdef _MSC_VER // gcc 4.1.2 had trouble with this
// Instantiate templatized methods
typedef std::set<float>::const_iterator inputIt; // not a random access iterator

// Constructors.
template Array_<float,int>::Array_(const Array_<float,int>&);
template Array_<float,int>::Array_(const float*,const float*);

// Assignment.
template Array_<float,int>&
Array_<float,int>::assign(const float*,const float*);
template Array_<double,int>&
Array_<double,int>::assign(const inputIt&, const inputIt&);
template Array_<float,int>&
Array_<float,int>::operator=(const Array_<float,int>&);
template Array_<double,int>&
Array_<double,int>::operator=(const std::vector<float>&);

// Comparison
template bool SimTK::operator==(const ConstArray_<float,int>&,
                                const ConstArray_<float,unsigned>&);
#endif

void testConstruction() {
    const int data[] = {5,3,-2,27,9};
    const char uchar[] = {'f','i','t','z'};
    Array_<int> nothing;
    Array_<int> def(5);
    Array_<int> intWithInt(data, data+5);
    Array_<char> charWithChar(uchar, uchar+4);
    Array_<int>  intWithChar(uchar, uchar+4);
    Array_<char>  charWithInt(data, data+5);
    cout << "nothing=" << nothing << endl;
    cout << "def=" << def << endl;
    cout << "intWithInt=" << intWithInt << endl;
    cout << "charWithChar=" << charWithChar << endl;
    cout << "intWithChar=" << intWithChar << endl;
    cout << "charWithInt=" << charWithInt << endl;

    Array_< Count<int> > cint(data, data+5);
    Count<int>::dumpCounts("cint(data,data+5)");
    Count<int>::reset();

    const Count<int> counts[] = {3,4,5};
    Count<int>::reset();
    Array_< Count<int> > ccnt(counts, counts+3);
    Count<int>::dumpCounts("ccnt(counts,counts+3)");
    Count<int>::reset();

    Array_< Count<int> > cint2(cint);
    Count<int>::dumpCounts("cint2(cint)");
    Count<int>::reset();

    cint2 = ccnt;
    Count<int>::dumpCounts("cint2=ccnt");
    Count<int>::reset();
    cout << "cint2=" << cint2 << endl;

    Array_<int,SmallIx> ismall0;
    cout << "default constructed Array_<int> begin()=" << ismall0.begin()
         << " end()=" << ismall0.end()
         << " capacity()=" << (int)ismall0.capacity()
         << endl;

    std::vector<int> ivec0;
    cout << "default constructed std::vector<int>"
         << " capacity()=" << ivec0.capacity()
         << endl;

    Array_<int,SmallIx> ismall(3);
    Array_<int,SmallIx> imaxsz(data, data+4);
    cout << "ismall0=" << ismall0 << endl;
    cout << "ismall=" << ismall << endl;
    cout << "imaxsz=" << imaxsz << endl;

    new(ismall.raw_push_back()) int(27);
    cout << "ismall after raw_push_back():" << ismall << endl;

    // Check null assignments.
    ismall = ismall0; // src is null
    ismall0 = imaxsz; // dest was null
    ismall = Array_<int,SmallIx>(); // both null

    cout << "sizeof(Array_<int,short>)=" << sizeof(Array_<int,short>) << endl;
    cout << "sizeof(Array_<int>)=" << sizeof(Array_<int>) << endl;
    cout << "sizeof(std::vector<int>)=" << sizeof(std::vector<int>) << endl;

    Array_<String, TestIx> strings(6, "woohoo");
    cout << "strings=" << strings << endl;
    strings.push_back("last");
    for (int i=0; i<5; ++i) {
        strings.insert(strings.end(), 2, "ins" + String(i));
        cout << strings.size() << ":" << strings.capacity()
                               << ":" << strings << endl;
    }
    cout << "strings=" << strings << endl;

    Array_<String, TestIx>::reverse_iterator p = strings.rbegin();
    while (p != strings.rend())
        cout << " " << *p++;
    cout << endl;

    const int ownerData[] = {7, 77, 777, 7777, 77777};
    std::vector<int> owner(ownerData, ownerData+5);
    std::vector<unsigned> unowner(owner.begin(), owner.end());
    Array_<int> shared; shared.shareData(&owner[1], &owner[4]);
    cout << "vector before=" << owner << endl;
    cout << "shared before=" << shared << endl;
    shared[2] = 29;
    cout << "shared after=" << shared << endl;
    cout << "vector after=" << owner << endl;
    cout << "shared(1,2)=" << shared(1,2) << endl;

    Array_<int> copyOfOwner(owner);
    cout << "copyOfOwner=" << copyOfOwner << endl;
    Array_<unsigned short,char> weirdCopy(owner);
    cout << "weirdCopy=" << weirdCopy << endl;
    copyOfOwner = unowner;
    cout << "copyOfOwner=unowner=" << copyOfOwner << endl;

    Array_<unsigned> shareOfUnowner(unowner, DontCopy());
    cout << "shareOfUnowner=" << shareOfUnowner << endl;

    shareOfUnowner(1,3) = Array_<unsigned>(3,88);
    cout << "shareOfUnowner=" << shareOfUnowner << endl;

    OtherArray_<int> oa(5, -4);
    cout << "oa=" << oa << endl;
}

static void toArray(const Array_<int>& a) {
    cout << "toArray=     "  << a  << "  &a[0]="  << &a[0] << endl;
}
static void toArrayView(const ArrayView_<int>& av) {
    cout << "toArrayView= "  << av  << " &av[0]="  << &av[0] << endl;
}
static void toConstArray(const ConstArray_<int>& ca) {
    cout << "toConstArray="  << ca  << " &ca[0]="  << &ca[0] << endl;
}
void testConversion() {
    const int p[] = {1,2,3,4,5,6};
    std::vector<int> v(p,p+6);
    cout << "v=" << v << " &v[0]=" << &v[0] << endl;
    Array_<int> a(v);
    ArrayView_<int> av(v);
    ConstArray_<int> ca(v);
    cout << "a= "  << a  << "  &a[0]="  << &a[0] << endl;
    cout << "av=" << av << " &av[0]=" << &av[0] << endl;
    cout << "ca=" << ca << " &ca[0]=" << &ca[0] << endl;

    toArray(ArrayView_<int>(v));
    toArrayView(v);
    toConstArray(v);
}

int main() {
    SimTK_START_TEST("TestArray");

        SimTK_SUBTEST(testConstruction);
        SimTK_SUBTEST(testConversion);

    SimTK_END_TEST();
}

<|endoftext|>


<commit_before>/*
 * opencog/atoms/core/PutLink.cc
 *
 * Copyright (C) 2015 Linas Vepstas
 * All Rights Reserved
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License v3 as
 * published by the Put Software Foundation and including the exceptions
 * at http://opencog.org/wiki/Licenses
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program; if not, write to:
 * Put Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include <opencog/atomspace/atom_types.h>
#include <opencog/atomspace/ClassServer.h>
#include "FreeLink.h"
#include "LambdaLink.h"
#include "PutLink.h"

using namespace opencog;

PutLink::PutLink(const HandleSeq& oset,
                 TruthValuePtr tv,
                 AttentionValuePtr av)
    : LambdaLink(PUT_LINK, oset, tv, av)
{
	init();
}

PutLink::PutLink(const Handle& a,
                 TruthValuePtr tv,
                 AttentionValuePtr av)
    : LambdaLink(PUT_LINK, a, tv, av)
{
	init();
}

PutLink::PutLink(Type t, const HandleSeq& oset,
                 TruthValuePtr tv,
                 AttentionValuePtr av)
    : LambdaLink(t, oset, tv, av)
{
	if (not classserver().isA(t, PUT_LINK))
		throw InvalidParamException(TRACE_INFO, "Expecting a PutLink");
	init();
}

PutLink::PutLink(Type t, const Handle& a,
                 TruthValuePtr tv,
                 AttentionValuePtr av)
    : LambdaLink(t, a, tv, av)
{
	if (not classserver().isA(t, PUT_LINK))
		throw InvalidParamException(TRACE_INFO, "Expecting a PutLink");
	init();
}

PutLink::PutLink(Type t, const Handle& a, const Handle& b,
                 TruthValuePtr tv,
                 AttentionValuePtr av)
    : LambdaLink(t, {a, b}, tv, av)
{
	if (not classserver().isA(t, PUT_LINK))
		throw InvalidParamException(TRACE_INFO, "Expecting a PutLink");
	init();
}

PutLink::PutLink(Link& l)
    : LambdaLink(l)
{
	Type tscope = l.getType();
	if (not classserver().isA(tscope, PUT_LINK))
		throw InvalidParamException(TRACE_INFO, "Expecting a PutLink");
	init();
}

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

/// PutLink expects a very strict format: an arity-2 link, with
/// the first part being a pattern, and the second a list or set
/// of values. If the pattern has N variables, then the seccond
/// part must have N values.  Furthermore, any type restrictions on
/// the variables must be satisfied by the values.
///
/// The following formats are understood:
///
///    PutLink
///       <pattern with 1 variable>
///       <any single atom>
///
///    PutLink
///       <pattern with N variables>
///       ListLink     ;; must have arity N
///          <atom 1>
///          ...
///          <atom N>
///
/// The below is a handy-dandy easy-to-use form. When it is reduced,
/// it will result in the creation of a set of reduced forms, not
/// just one (the two sets haveing the same arity). Unfortunately,
/// this trick cannot work for N=1 unless the variable is cosntrained
/// to not be a set.
///
///    PutLink
///       <pattern with N variables>
///       SetLink        ;; Must hold a set of ListLinks
///          ListLink    ;; must have arity N
///             <atom 1>
///             ...
///             <atom N>
///
void PutLink::init(void)
{
	extract_variables(_outgoing);

	// If threre are initial variable declarations, they will be
	// in position 0, the body will be at 1, and the values at 2.
	// Otherwise, the body is at 0, and the values at 1.
	size_t sz = _outgoing.size();
	if (_outgoing[0] == _body)
	{
		if (2 != sz)
			throw InvalidParamException(TRACE_INFO,
				"Expecting an outgoing set size of two, got %d", sz);
		_values = _outgoing[1];
	}
	else
	{
		if (3 != sz)
			throw InvalidParamException(TRACE_INFO,
				"Expecting an outgoing set size of three, got %d", sz);
		_values = _outgoing[2];
	}
	typecheck_values();
}

/// Check that the values in the PutLink obey the type constraints.
// XXX FIXME .. this is wrong, if, for example, the values are dynamic
// i.e. produce run-time values. In that case, the type checking can
// only be performed at run-time!
void PutLink::typecheck_values(void)
{
	size_t sz = _varlist.varseq.size();
	Type vtype = _values->getType();

	if (1 == sz)
	{
		if (not _varlist.is_type(_values)
		    and SET_LINK != vtype)
		{
				throw InvalidParamException(TRACE_INFO,
					"PutLink mismatched type!");
		}
		return;
	}

	LinkPtr lval(LinkCast(_values));
	if (LIST_LINK == vtype)
	{
		if (not _varlist.is_type(lval->getOutgoingSet()))
			throw InvalidParamException(TRACE_INFO,
				"PutLink has mismatched value list!");
		return;
	}

	// GetLinks are evaluated dynamically, later.
	if (GET_LINK == vtype)
		return;

	if (SET_LINK != vtype)
		throw InvalidParamException(TRACE_INFO,
			"PutLink was expecting a ListLink, SetLink or GetLink!");

	if (1 < sz)
	{
		for (const Handle& h : lval->getOutgoingSet())
		{
			LinkPtr lse(LinkCast(h));
			// If the arity is greater than one, then the values must be in a list.
		   if (lse->getType() != LIST_LINK)
				throw InvalidParamException(TRACE_INFO,
					"PutLink expected value list!");

			if (not _varlist.is_type(lval->getOutgoingSet()))
				throw InvalidParamException(TRACE_INFO,
					"PutLink bad value list!");
		}
		return;
	}

	// If the arity is one, the values must obey type constraint.
	for (const Handle& h : lval->getOutgoingSet())
	{
		if (not _varlist.is_type(h))
			throw InvalidParamException(TRACE_INFO,
					"PutLink bad type!");
	}
}
/* ================================================================= */

/**
 * Perform the actual beta reduction --
 *
 * Substitute values for the variables in the pattern tree.
 * This is a lot like applying the function fun to the argument list
 * args, except that no actual evaluation is performed; only
 * substitution.  The resulting tree is NOT placed into any atomspace,
 * either. If you want that, you must do it youself.  If you want
 * evaluation or execution to happen during or after sustitution, use
 * either the EvaluationLink, the ExecutionOutputLink, or the Instantiator.
 *
 * So, for example, if this PutLink looks like this:
 *
 *   PutLink
 *      EvaluationLink
 *         PredicateNode "is a kind of"
 *         ListLink
 *            VariableNode $a
 *            ConceptNode "hot patootie"
 *      ConceptNode "cowpie"
 *
 * then the reduced value will be
 *
 *   EvaluationLink
 *      PredicateNode "is a kind of"
 *      ListLink
 *         ConceptNode "cowpie"
 *         ConceptNode "hot patootie"
 *
 * Again, only a substitution is performed, there is no evaluation.
 * Note also that the resulting tree is NOT placed into any atomspace!
 */

// XXX FIXME, if the values are dynamically generated, then type-checking
// must be done at run-time, and not at definition-time.
Handle PutLink::do_reduce(void) const
{
	Type vtype = _values->getType();

	if (1 == _varlist.varseq.size())
	{
		// Well, we should accept the SetLink here only if it was
		// dynamically generated... but I'm too lazy to code this up.
		if (SET_LINK != vtype)
		{
			HandleSeq oset;
			oset.push_back(_values);
			return _varlist.substitute_nocheck(_body, oset);
		}

		// Iterate over the set...
		HandleSeq bset;
		for (Handle h : LinkCast(_values)->getOutgoingSet())
		{
			HandleSeq oset;
			oset.push_back(h);
			bset.push_back(_varlist.substitute_nocheck(_body, oset));
		}
		return Handle(createLink(SET_LINK, bset));
	}
	if (LIST_LINK == vtype)
	{
		const HandleSeq& oset = LinkCast(_values)->getOutgoingSet();
		return _varlist.substitute_nocheck(_body, oset);
	}

	OC_ASSERT(SET_LINK == vtype,
		"Should have caught this earlier, in the ctor");

	HandleSeq bset;
	for (Handle h : LinkCast(_values)->getOutgoingSet())
	{
		const HandleSeq& oset = LinkCast(h)->getOutgoingSet();
		bset.push_back(_varlist.substitute_nocheck(_body, oset));
	}
	return Handle(createLink(SET_LINK, bset));
}

Handle PutLink::reduce(void)
{
	return do_reduce();
}

/* ===================== END OF FILE ===================== */
<commit_msg>Bug fix<commit_after>/*
 * opencog/atoms/core/PutLink.cc
 *
 * Copyright (C) 2015 Linas Vepstas
 * All Rights Reserved
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License v3 as
 * published by the Put Software Foundation and including the exceptions
 * at http://opencog.org/wiki/Licenses
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program; if not, write to:
 * Put Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include <opencog/atomspace/atom_types.h>
#include <opencog/atomspace/ClassServer.h>
#include "FreeLink.h"
#include "LambdaLink.h"
#include "PutLink.h"

using namespace opencog;

PutLink::PutLink(const HandleSeq& oset,
                 TruthValuePtr tv,
                 AttentionValuePtr av)
    : LambdaLink(PUT_LINK, oset, tv, av)
{
	init();
}

PutLink::PutLink(const Handle& a,
                 TruthValuePtr tv,
                 AttentionValuePtr av)
    : LambdaLink(PUT_LINK, a, tv, av)
{
	init();
}

PutLink::PutLink(Type t, const HandleSeq& oset,
                 TruthValuePtr tv,
                 AttentionValuePtr av)
    : LambdaLink(t, oset, tv, av)
{
	if (not classserver().isA(t, PUT_LINK))
		throw InvalidParamException(TRACE_INFO, "Expecting a PutLink");
	init();
}

PutLink::PutLink(Type t, const Handle& a,
                 TruthValuePtr tv,
                 AttentionValuePtr av)
    : LambdaLink(t, a, tv, av)
{
	if (not classserver().isA(t, PUT_LINK))
		throw InvalidParamException(TRACE_INFO, "Expecting a PutLink");
	init();
}

PutLink::PutLink(Type t, const Handle& a, const Handle& b,
                 TruthValuePtr tv,
                 AttentionValuePtr av)
    : LambdaLink(t, {a, b}, tv, av)
{
	if (not classserver().isA(t, PUT_LINK))
		throw InvalidParamException(TRACE_INFO, "Expecting a PutLink");
	init();
}

PutLink::PutLink(Link& l)
    : LambdaLink(l)
{
	Type tscope = l.getType();
	if (not classserver().isA(tscope, PUT_LINK))
		throw InvalidParamException(TRACE_INFO, "Expecting a PutLink");
	init();
}

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

/// PutLink expects a very strict format: an arity-2 link, with
/// the first part being a pattern, and the second a list or set
/// of values. If the pattern has N variables, then the seccond
/// part must have N values.  Furthermore, any type restrictions on
/// the variables must be satisfied by the values.
///
/// The following formats are understood:
///
///    PutLink
///       <pattern with 1 variable>
///       <any single atom>
///
///    PutLink
///       <pattern with N variables>
///       ListLink     ;; must have arity N
///          <atom 1>
///          ...
///          <atom N>
///
/// The below is a handy-dandy easy-to-use form. When it is reduced,
/// it will result in the creation of a set of reduced forms, not
/// just one (the two sets haveing the same arity). Unfortunately,
/// this trick cannot work for N=1 unless the variable is cosntrained
/// to not be a set.
///
///    PutLink
///       <pattern with N variables>
///       SetLink        ;; Must hold a set of ListLinks
///          ListLink    ;; must have arity N
///             <atom 1>
///             ...
///             <atom N>
///
void PutLink::init(void)
{
	extract_variables(_outgoing);

	// If threre are initial variable declarations, they will be
	// in position 0, the body will be at 1, and the values at 2.
	// Otherwise, the body is at 0, and the values at 1.
	size_t sz = _outgoing.size();
	if (_outgoing[0] == _body)
	{
		if (2 != sz)
			throw InvalidParamException(TRACE_INFO,
				"Expecting an outgoing set size of two, got %d", sz);
		_values = _outgoing[1];
	}
	else
	{
		if (3 != sz)
			throw InvalidParamException(TRACE_INFO,
				"Expecting an outgoing set size of three, got %d", sz);
		_values = _outgoing[2];
	}
	typecheck_values();
}

/// Check that the values in the PutLink obey the type constraints.
// XXX FIXME .. this is wrong, if, for example, the values are dynamic
// i.e. produce run-time values. In that case, the type checking can
// only be performed at run-time!
void PutLink::typecheck_values(void)
{
	size_t sz = _varlist.varseq.size();
	Type vtype = _values->getType();

	if (1 == sz)
	{
		if (not _varlist.is_type(_values)
		    and SET_LINK != vtype)
		{
				throw InvalidParamException(TRACE_INFO,
					"PutLink mismatched type!");
		}
		return;
	}

	LinkPtr lval(LinkCast(_values));
	if (LIST_LINK == vtype)
	{
		if (not _varlist.is_type(lval->getOutgoingSet()))
			throw InvalidParamException(TRACE_INFO,
				"PutLink has mismatched value list!");
		return;
	}

	// GetLinks are evaluated dynamically, later.
	if (GET_LINK == vtype)
		return;

	if (SET_LINK != vtype)
		throw InvalidParamException(TRACE_INFO,
			"PutLink was expecting a ListLink, SetLink or GetLink!");

	if (1 < sz)
	{
		for (const Handle& h : lval->getOutgoingSet())
		{
			LinkPtr lse(LinkCast(h));
			// If the arity is greater than one, then the values must be in a list.
		   if (lse->getType() != LIST_LINK)
				throw InvalidParamException(TRACE_INFO,
					"PutLink expected value list!");

			if (not _varlist.is_type(lse->getOutgoingSet()))
				throw InvalidParamException(TRACE_INFO,
					"PutLink bad value list!");
		}
		return;
	}

	// If the arity is one, the values must obey type constraint.
	for (const Handle& h : lval->getOutgoingSet())
	{
		if (not _varlist.is_type(h))
			throw InvalidParamException(TRACE_INFO,
					"PutLink bad type!");
	}
}
/* ================================================================= */

/**
 * Perform the actual beta reduction --
 *
 * Substitute values for the variables in the pattern tree.
 * This is a lot like applying the function fun to the argument list
 * args, except that no actual evaluation is performed; only
 * substitution.  The resulting tree is NOT placed into any atomspace,
 * either. If you want that, you must do it youself.  If you want
 * evaluation or execution to happen during or after sustitution, use
 * either the EvaluationLink, the ExecutionOutputLink, or the Instantiator.
 *
 * So, for example, if this PutLink looks like this:
 *
 *   PutLink
 *      EvaluationLink
 *         PredicateNode "is a kind of"
 *         ListLink
 *            VariableNode $a
 *            ConceptNode "hot patootie"
 *      ConceptNode "cowpie"
 *
 * then the reduced value will be
 *
 *   EvaluationLink
 *      PredicateNode "is a kind of"
 *      ListLink
 *         ConceptNode "cowpie"
 *         ConceptNode "hot patootie"
 *
 * Again, only a substitution is performed, there is no evaluation.
 * Note also that the resulting tree is NOT placed into any atomspace!
 */

// XXX FIXME, if the values are dynamically generated, then type-checking
// must be done at run-time, and not at definition-time.
Handle PutLink::do_reduce(void) const
{
	Type vtype = _values->getType();

	if (1 == _varlist.varseq.size())
	{
		// Well, we should accept the SetLink here only if it was
		// dynamically generated... but I'm too lazy to code this up.
		if (SET_LINK != vtype)
		{
			HandleSeq oset;
			oset.push_back(_values);
			return _varlist.substitute_nocheck(_body, oset);
		}

		// Iterate over the set...
		HandleSeq bset;
		for (Handle h : LinkCast(_values)->getOutgoingSet())
		{
			HandleSeq oset;
			oset.push_back(h);
			bset.push_back(_varlist.substitute_nocheck(_body, oset));
		}
		return Handle(createLink(SET_LINK, bset));
	}
	if (LIST_LINK == vtype)
	{
		const HandleSeq& oset = LinkCast(_values)->getOutgoingSet();
		return _varlist.substitute_nocheck(_body, oset);
	}

	OC_ASSERT(SET_LINK == vtype,
		"Should have caught this earlier, in the ctor");

	HandleSeq bset;
	for (Handle h : LinkCast(_values)->getOutgoingSet())
	{
		const HandleSeq& oset = LinkCast(h)->getOutgoingSet();
		bset.push_back(_varlist.substitute_nocheck(_body, oset));
	}
	return Handle(createLink(SET_LINK, bset));
}

Handle PutLink::reduce(void)
{
	return do_reduce();
}

/* ===================== END OF FILE ===================== */
<|endoftext|>


<commit_before>/*
 Copyright 2015 Nervana Systems 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.
*/

#pragma once

#include <assert.h>

#include <vector>
#include <cstdio>
#include <iostream>
#include <chrono>
#include <utility>
#include <algorithm>

#include "pyBackendWrapper.hpp"
#include "threadpool.hpp"
#include "batch_loader.hpp"
#include "batch_iterator.hpp"
#include "manifest.hpp"
#include "provider_factory.hpp"
#include "buffer_pool_in.hpp"
#include "buffer_pool_out.hpp"

/* DecodeThreadPool
 *
 * DecodeThreadPool takes data from the BufferPool `in`, transforms it
 * using `count` threads with a Media::transform built from
 * `mediaParams`.  Each minibatch is transposed by a manager thread and
 * then copied to the `device`.
 *
 */
class pyDecodeThreadPool : public ThreadPool {
public:
    pyDecodeThreadPool(int count,
                       const std::shared_ptr<buffer_pool_in>& in,
                       const std::shared_ptr<buffer_pool_out>& out,
                       const std::shared_ptr<pyBackendWrapper>& pbe);

    virtual ~pyDecodeThreadPool();
    virtual void start();
    virtual void stop();
    void add_provider(std::shared_ptr<nervana::provider_interface> prov);

protected:
    virtual void run(int id);
    virtual void work(int id);
    void produce();
    void consume();
    void manage();

private:
    pyDecodeThreadPool();
    pyDecodeThreadPool(const pyDecodeThreadPool&);

    int                         _itemsPerThread;
    std::shared_ptr<buffer_pool_in> _in;
    std::shared_ptr<buffer_pool_out> _out;
    std::shared_ptr<pyBackendWrapper> _pbe;
    std::mutex                  _mutex;
    std::condition_variable     _started;
    std::condition_variable     _ended;
    int                         _endSignaled    = 0;
    std::thread*                _manager        = 0;
    bool                        _stopManager    = false;
    bool                        _managerStopped = false;
    buffer_in_array*            _inputBuf       = 0;
    int                         _bufferIndex    = 0;
    int                         _batchSize;

    std::vector<std::shared_ptr<nervana::provider_interface>> _providers;

    std::vector<int>            _startSignaled;
    std::vector<int>            _startInds;
    std::vector<int>            _endInds;
};

class pyLoaderConfig : public nervana::json_config_parser {
public:
    std::string manifest_filename;
    int minibatch_size;

    std::string cache_directory = "";
    int macrobatch_size      = 0;
    bool shuffle_every_epoch = false;
    bool shuffle_manifest    = false;
    bool single_thread       = false;
    int subset_percent        = 100;
    int random_seed           = 0;

    pyLoaderConfig(nlohmann::json js)
    {
        parse_value(manifest_filename, "manifest_filename", js, mode::REQUIRED);
        parse_value(minibatch_size,    "minibatch_size", js, mode::REQUIRED);

        parse_value(single_thread,       "single_thread", js);
        parse_value(cache_directory,     "cache_directory", js);
        parse_value(macrobatch_size,     "macrobatch_size", js);
        parse_value(shuffle_every_epoch, "shuffle_every_epoch", js);
        parse_value(shuffle_manifest,    "shuffle_manifest", js);
        parse_value(subset_percent,      "subset_percent", js);
        parse_value(random_seed,         "random_seed", js);

        if(macrobatch_size == 0) {
            macrobatch_size = minibatch_size;
        }

        validate();
    }

private:
    pyLoaderConfig() = delete;
    bool validate() { return true; }
};

/*
 * The ReadThread wraps BatchIterator in a thread an coordinates work
 * with other threads via locks on the output BufferPool `out`
 *
 */

class ReadThread: public ThreadPool {
public:
    ReadThread(const std::shared_ptr<buffer_pool_in>& out,
               const std::shared_ptr<BatchIterator>& batch_iterator);

protected:
    virtual void work(int id);

private:
    ReadThread();
    ReadThread(const ReadThread&);
    std::shared_ptr<buffer_pool_in> _out;
    std::shared_ptr<BatchIterator> _batch_iterator;
};

/* PyLoader
 *
 * The PyLoader instantiates and then coordinates the effort of loading ingested data, caching
 * blocks of it in contiguous disk (using cpio file format), transforming the data and finally
 * loading the data into device memory
*/

class PyLoader {
public:
    PyLoader(const char* PyloaderConfigString, PyObject *pbe);

    virtual ~PyLoader() {}
    int start();
    void stop();
    int reset();
    PyObject* shapes();
    PyObject* next(int bufIdx);

    std::shared_ptr<BatchIterator> getBatchIterator() { return _batch_iterator; }
    int itemCount() { return _manifest->getSize(); }

private:
    void drain();

private:
    PyLoader();
    PyLoader(const PyLoader&);

    bool                                _first = true;

    std::shared_ptr<buffer_pool_in>     _readBufs = nullptr;
    std::shared_ptr<buffer_pool_out>    _decodeBufs = nullptr;
    std::unique_ptr<ReadThread>         _readThread = nullptr;
    std::unique_ptr<pyDecodeThreadPool> _decodeThreads = nullptr;
    std::shared_ptr<BatchLoader>        _batchLoader = nullptr;
    std::shared_ptr<BatchIterator>      _batch_iterator = nullptr;
    std::shared_ptr<Manifest>           _manifest = nullptr;
    std::shared_ptr<pyLoaderConfig>     _lcfg = nullptr;

    std::vector<std::shared_ptr<nervana::interface::config>> _provider_configs;

    int                                 _batchSize;
    nlohmann::json                      _lcfg_json;
    PyObject*                           _pbe;
    std::shared_ptr<pyBackendWrapper>   _pyBackend;
};
<commit_msg>use _batchLoader->objectCount instead of _manifest->getSize<commit_after>/*
 Copyright 2015 Nervana Systems 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.
*/

#pragma once

#include <assert.h>

#include <vector>
#include <cstdio>
#include <iostream>
#include <chrono>
#include <utility>
#include <algorithm>

#include "pyBackendWrapper.hpp"
#include "threadpool.hpp"
#include "batch_loader.hpp"
#include "batch_iterator.hpp"
#include "manifest.hpp"
#include "provider_factory.hpp"
#include "buffer_pool_in.hpp"
#include "buffer_pool_out.hpp"

/* DecodeThreadPool
 *
 * DecodeThreadPool takes data from the BufferPool `in`, transforms it
 * using `count` threads with a Media::transform built from
 * `mediaParams`.  Each minibatch is transposed by a manager thread and
 * then copied to the `device`.
 *
 */
class pyDecodeThreadPool : public ThreadPool {
public:
    pyDecodeThreadPool(int count,
                       const std::shared_ptr<buffer_pool_in>& in,
                       const std::shared_ptr<buffer_pool_out>& out,
                       const std::shared_ptr<pyBackendWrapper>& pbe);

    virtual ~pyDecodeThreadPool();
    virtual void start();
    virtual void stop();
    void add_provider(std::shared_ptr<nervana::provider_interface> prov);

protected:
    virtual void run(int id);
    virtual void work(int id);
    void produce();
    void consume();
    void manage();

private:
    pyDecodeThreadPool();
    pyDecodeThreadPool(const pyDecodeThreadPool&);

    int                         _itemsPerThread;
    std::shared_ptr<buffer_pool_in> _in;
    std::shared_ptr<buffer_pool_out> _out;
    std::shared_ptr<pyBackendWrapper> _pbe;
    std::mutex                  _mutex;
    std::condition_variable     _started;
    std::condition_variable     _ended;
    int                         _endSignaled    = 0;
    std::thread*                _manager        = 0;
    bool                        _stopManager    = false;
    bool                        _managerStopped = false;
    buffer_in_array*            _inputBuf       = 0;
    int                         _bufferIndex    = 0;
    int                         _batchSize;

    std::vector<std::shared_ptr<nervana::provider_interface>> _providers;

    std::vector<int>            _startSignaled;
    std::vector<int>            _startInds;
    std::vector<int>            _endInds;
};

class pyLoaderConfig : public nervana::json_config_parser {
public:
    std::string manifest_filename;
    int minibatch_size;

    std::string cache_directory = "";
    int macrobatch_size      = 0;
    bool shuffle_every_epoch = false;
    bool shuffle_manifest    = false;
    bool single_thread       = false;
    int subset_percent        = 100;
    int random_seed           = 0;

    pyLoaderConfig(nlohmann::json js)
    {
        parse_value(manifest_filename, "manifest_filename", js, mode::REQUIRED);
        parse_value(minibatch_size,    "minibatch_size", js, mode::REQUIRED);

        parse_value(single_thread,       "single_thread", js);
        parse_value(cache_directory,     "cache_directory", js);
        parse_value(macrobatch_size,     "macrobatch_size", js);
        parse_value(shuffle_every_epoch, "shuffle_every_epoch", js);
        parse_value(shuffle_manifest,    "shuffle_manifest", js);
        parse_value(subset_percent,      "subset_percent", js);
        parse_value(random_seed,         "random_seed", js);

        if(macrobatch_size == 0) {
            macrobatch_size = minibatch_size;
        }

        validate();
    }

private:
    pyLoaderConfig() = delete;
    bool validate() { return true; }
};

/*
 * The ReadThread wraps BatchIterator in a thread an coordinates work
 * with other threads via locks on the output BufferPool `out`
 *
 */

class ReadThread: public ThreadPool {
public:
    ReadThread(const std::shared_ptr<buffer_pool_in>& out,
               const std::shared_ptr<BatchIterator>& batch_iterator);

protected:
    virtual void work(int id);

private:
    ReadThread();
    ReadThread(const ReadThread&);
    std::shared_ptr<buffer_pool_in> _out;
    std::shared_ptr<BatchIterator> _batch_iterator;
};

/* PyLoader
 *
 * The PyLoader instantiates and then coordinates the effort of loading ingested data, caching
 * blocks of it in contiguous disk (using cpio file format), transforming the data and finally
 * loading the data into device memory
*/

class PyLoader {
public:
    PyLoader(const char* PyloaderConfigString, PyObject *pbe);

    virtual ~PyLoader() {}
    int start();
    void stop();
    int reset();
    PyObject* shapes();
    PyObject* next(int bufIdx);

    std::shared_ptr<BatchIterator> getBatchIterator() { return _batch_iterator; }
    int itemCount() { return _batchLoader->objectCount(); }

private:
    void drain();

private:
    PyLoader();
    PyLoader(const PyLoader&);

    bool                                _first = true;

    std::shared_ptr<buffer_pool_in>     _readBufs = nullptr;
    std::shared_ptr<buffer_pool_out>    _decodeBufs = nullptr;
    std::unique_ptr<ReadThread>         _readThread = nullptr;
    std::unique_ptr<pyDecodeThreadPool> _decodeThreads = nullptr;
    std::shared_ptr<BatchLoader>        _batchLoader = nullptr;
    std::shared_ptr<BatchIterator>      _batch_iterator = nullptr;
    std::shared_ptr<Manifest>           _manifest = nullptr;
    std::shared_ptr<pyLoaderConfig>     _lcfg = nullptr;

    std::vector<std::shared_ptr<nervana::interface::config>> _provider_configs;

    int                                 _batchSize;
    nlohmann::json                      _lcfg_json;
    PyObject*                           _pbe;
    std::shared_ptr<pyBackendWrapper>   _pyBackend;
};
<|endoftext|>


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

  Program:   Visualization Toolkit
  Module:    vtkImageMapper.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$
  Thanks:    Thanks to Matt Turek who developed this class.

Copyright (c) 1993-1995 Ken Martin, Will Schroeder, Bill Lorensen.

This software is copyrighted by Ken Martin, Will Schroeder and Bill Lorensen.
The following terms apply to all files associated with the software unless
explicitly disclaimed in individual files. This copyright specifically does
not apply to the related textbook "The Visualization Toolkit" ISBN
013199837-4 published by Prentice Hall which is covered by its own copyright.

The authors hereby grant permission to use, copy, and distribute this
software and its documentation for any purpose, provided that existing
copyright notices are retained in all copies and that this notice is included
verbatim in any distributions. Additionally, the authors grant permission to
modify this software and its documentation for any purpose, provided that
such modifications are not distributed without the explicit consent of the
authors and that existing copyright notices are retained in all copies. Some
of the algorithms implemented by this software are patented, observe all
applicable patent law.

IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR
DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF,
EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE IS PROVIDED ON AN
"AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE
MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.

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

#include "vtkImageMapper.h"
#include "vtkImageCache.h"

#ifdef _WIN32
  #include "vtkWin32ImageMapper.h"
#else
  #include "vtkXImageMapper.h"
#endif

#include "vtkActor2D.h"
#include "vtkImager.h"
#include "vtkViewport.h"
#include "vtkWindow.h"
#include "vtkImageData.h"

vtkImageMapper::vtkImageMapper()
{
  vtkDebugMacro(<< "vtkImageMapper::vtkImageMapper" );

  this->Input = (vtkImageCache*) NULL;

  //this->ColorWindow = 255.0;
  //this->ColorLevel = 127.0;

  this->ColorWindow = 2000;
  this->ColorLevel = 1000;

  this->ZSlice = 0;
}

void vtkImageMapper::PrintSelf(ostream& os, vtkIndent indent)
{
  this->vtkMapper2D::PrintSelf(os, indent);

  os << indent << "Input: " << this->Input << "\n";
  os << indent << "Color Window: " << this->ColorWindow << "\n";
  os << indent << "Color Level: " << this->ColorLevel << "\n";
  os << indent << "ZSlice: " << this->ZSlice << "\n";
}

vtkImageMapper* vtkImageMapper::New()
{
  #ifdef _WIN32
    return vtkWin32ImageMapper::New();
  #else
    return vtkXImageMapper::New();
  #endif

}

float vtkImageMapper::GetColorShift()
{
  return this->ColorWindow /2.0 - this->ColorLevel;
}

float vtkImageMapper::GetColorScale()
{
  return 255.0 / this->ColorWindow;
}

void vtkImageMapper::Render(vtkViewport* viewport, vtkActor2D* actor)
{
  vtkDebugMacro(<< "vtkImageMapper::Render");

  vtkImageData *data;
  int displayExtent[6];
  int wholeExtent[6];

  if (!viewport)
    {
    vtkErrorMacro (<< "vtkImageMapper::Render - Null viewport argument");
    return;
    }

  if (!actor)
    {
    vtkErrorMacro (<<"vtkImageMapper::Render - Null actor argument");
    return;
    }

  if (!this->Input)
    {
    vtkDebugMacro(<< "vtkImageMapper::Render - Please Set the input.");
    return;
    }

  this->Input->UpdateImageInformation();
  // start with the wholeExtent
  memcpy(wholeExtent,this->Input->GetWholeExtent(),6*sizeof(int));
  memcpy(displayExtent,this->Input->GetWholeExtent(),6*sizeof(int));

  // Set The z values to the zslice
  displayExtent[4] = this->ZSlice;
  displayExtent[5] = this->ZSlice;

  // scale the extent
  //float *scale = actor->GetScale();
  //displayExtent[0] *= scale[0];
  //displayExtent[1] *= scale[0];
  //displayExtent[2] *= scale[1];
  //displayExtent[3] *= scale[1];

  // position the extent
  int *pos = actor->GetComputedViewportPixelPosition(viewport);
  //displayExtent[0] += pos[0];
  //displayExtent[1] += pos[0];
  //displayExtent[2] += pos[1];
  //displayExtent[3] += pos[1];

  // Get the viewport coordinates
  float* vpt = viewport->GetViewport();

  // Get the window size
  vtkWindow* window = viewport->GetVTKWindow();
  int* winSize = window->GetSize();

  // if we clip based on 0,0 then we need to store the amount we
  // adjusted by so that we can take that into account in the
  // positioning of the actor
  // Now clip to imager extents
  // initialize PositionAdjustment to zero
  this->PositionAdjustment[0] = 0;
  this->PositionAdjustment[1] = 0;
  if (pos[0] < 0)
    {
    this->PositionAdjustment[0] = -1*pos[0];
    displayExtent[0] -= pos[0];
    }
  if ((pos[0]+wholeExtent[1] - wholeExtent[0] + 1) >
      (winSize[0] - 1)*(vpt[XMAX]-vpt[XMIN]))
    {
    displayExtent[1] = displayExtent[1] -
      (pos[0]+wholeExtent[1] - wholeExtent[0] + 1) +
      (winSize[0] - 1)*(vpt[XMAX]-vpt[XMIN]);
    //    displayExtent[1] = (int)((winSize[0] - 1)*(vpt[XMAX]-vpt[XMIN]));
    }
  if (pos[1] < 0)
    {
    this->PositionAdjustment[1] = -1*pos[1];
    displayExtent[2] -= pos[0];
    }
  if ((pos[1] + wholeExtent[3] - wholeExtent[2] + 1) >
      (winSize[1] - 1)*(vpt[YMAX]-vpt[YMIN]))
    {
    displayExtent[3] = displayExtent[3] -
      (pos[1]+wholeExtent[3] - wholeExtent[2] + 1) +
      (winSize[1] - 1)*(vpt[YMAX]-vpt[YMIN]);
    //displayExtent[3] = (int)((winSize[1] - 1)*(vpt[YMAX] - vpt[YMIN]));
    }

  // now add back in the position to determine the update Extent
  //displayExtent[0] -= pos[0];
  //displayExtent[1] -= pos[0];
  //displayExtent[2] -= pos[1];
  //displayExtent[3] -= pos[1];

  this->Input->SetUpdateExtent(displayExtent);

  // Get the region from the input
  data = this->Input->UpdateAndReturnData();
  if ( !data)
    {
    vtkErrorMacro(<< "Render: Could not get data from input.");
    return;
    }

  this->RenderData(viewport, data, actor);
}

//----------------------------------------------------------------------------
int vtkImageMapper::GetWholeZMin()
{
  int *extent;

  if ( ! this->Input)
    {
    return 0;
    }
  this->Input->UpdateImageInformation();
  extent = this->Input->GetWholeExtent();
  return extent[4];
}

//----------------------------------------------------------------------------
int vtkImageMapper::GetWholeZMax()
{
  int *extent;

  if ( ! this->Input)
    {
    return 0;
    }
  this->Input->UpdateImageInformation();
  extent = this->Input->GetWholeExtent();
  return extent[5];
}

<commit_msg>ERR: Render method had un index mismach<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkImageMapper.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$
  Thanks:    Thanks to Matt Turek who developed this class.

Copyright (c) 1993-1995 Ken Martin, Will Schroeder, Bill Lorensen.

This software is copyrighted by Ken Martin, Will Schroeder and Bill Lorensen.
The following terms apply to all files associated with the software unless
explicitly disclaimed in individual files. This copyright specifically does
not apply to the related textbook "The Visualization Toolkit" ISBN
013199837-4 published by Prentice Hall which is covered by its own copyright.

The authors hereby grant permission to use, copy, and distribute this
software and its documentation for any purpose, provided that existing
copyright notices are retained in all copies and that this notice is included
verbatim in any distributions. Additionally, the authors grant permission to
modify this software and its documentation for any purpose, provided that
such modifications are not distributed without the explicit consent of the
authors and that existing copyright notices are retained in all copies. Some
of the algorithms implemented by this software are patented, observe all
applicable patent law.

IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR
DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF,
EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE IS PROVIDED ON AN
"AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE
MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.

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

#include "vtkImageMapper.h"
#include "vtkImageCache.h"

#ifdef _WIN32
  #include "vtkWin32ImageMapper.h"
#else
  #include "vtkXImageMapper.h"
#endif

#include "vtkActor2D.h"
#include "vtkImager.h"
#include "vtkViewport.h"
#include "vtkWindow.h"
#include "vtkImageData.h"

vtkImageMapper::vtkImageMapper()
{
  vtkDebugMacro(<< "vtkImageMapper::vtkImageMapper" );

  this->Input = (vtkImageCache*) NULL;

  //this->ColorWindow = 255.0;
  //this->ColorLevel = 127.0;

  this->ColorWindow = 2000;
  this->ColorLevel = 1000;

  this->ZSlice = 0;
}

void vtkImageMapper::PrintSelf(ostream& os, vtkIndent indent)
{
  this->vtkMapper2D::PrintSelf(os, indent);

  os << indent << "Input: " << this->Input << "\n";
  os << indent << "Color Window: " << this->ColorWindow << "\n";
  os << indent << "Color Level: " << this->ColorLevel << "\n";
  os << indent << "ZSlice: " << this->ZSlice << "\n";
}

vtkImageMapper* vtkImageMapper::New()
{
  #ifdef _WIN32
    return vtkWin32ImageMapper::New();
  #else
    return vtkXImageMapper::New();
  #endif

}

float vtkImageMapper::GetColorShift()
{
  return this->ColorWindow /2.0 - this->ColorLevel;
}

float vtkImageMapper::GetColorScale()
{
  return 255.0 / this->ColorWindow;
}

void vtkImageMapper::Render(vtkViewport* viewport, vtkActor2D* actor)
{
  vtkDebugMacro(<< "vtkImageMapper::Render");

  vtkImageData *data;
  int displayExtent[6];
  int wholeExtent[6];

  if (!viewport)
    {
    vtkErrorMacro (<< "vtkImageMapper::Render - Null viewport argument");
    return;
    }

  if (!actor)
    {
    vtkErrorMacro (<<"vtkImageMapper::Render - Null actor argument");
    return;
    }

  if (!this->Input)
    {
    vtkDebugMacro(<< "vtkImageMapper::Render - Please Set the input.");
    return;
    }

  this->Input->UpdateImageInformation();
  // start with the wholeExtent
  memcpy(wholeExtent,this->Input->GetWholeExtent(),6*sizeof(int));
  memcpy(displayExtent,this->Input->GetWholeExtent(),6*sizeof(int));

  // Set The z values to the zslice
  displayExtent[4] = this->ZSlice;
  displayExtent[5] = this->ZSlice;

  // scale the extent
  //float *scale = actor->GetScale();
  //displayExtent[0] *= scale[0];
  //displayExtent[1] *= scale[0];
  //displayExtent[2] *= scale[1];
  //displayExtent[3] *= scale[1];

  // position the extent
  int *pos = actor->GetComputedViewportPixelPosition(viewport);
  //displayExtent[0] += pos[0];
  //displayExtent[1] += pos[0];
  //displayExtent[2] += pos[1];
  //displayExtent[3] += pos[1];

  // Get the viewport coordinates
  float* vpt = viewport->GetViewport();

  // Get the window size
  vtkWindow* window = viewport->GetVTKWindow();
  int* winSize = window->GetSize();

  // if we clip based on 0,0 then we need to store the amount we
  // adjusted by so that we can take that into account in the
  // positioning of the actor
  // Now clip to imager extents
  // initialize PositionAdjustment to zero
  this->PositionAdjustment[0] = 0;
  this->PositionAdjustment[1] = 0;
  if (pos[0] < 0)
    {
    this->PositionAdjustment[0] = -1*pos[0];
    displayExtent[0] -= pos[0];
    }
  if ((pos[0]+wholeExtent[1] - wholeExtent[0] + 1) >
      (winSize[0] - 1)*(vpt[XMAX]-vpt[XMIN]))
    {
    displayExtent[1] = displayExtent[1] -
      (pos[0]+wholeExtent[1] - wholeExtent[0] + 1) +
      (winSize[0] - 1)*(vpt[XMAX]-vpt[XMIN]);
    //    displayExtent[1] = (int)((winSize[0] - 1)*(vpt[XMAX]-vpt[XMIN]));
    }
  if (pos[1] < 0)
    {
    this->PositionAdjustment[1] = -1*pos[1];
    displayExtent[2] -= pos[1];
    }
  if ((pos[1] + wholeExtent[3] - wholeExtent[2] + 1) >
      (winSize[1] - 1)*(vpt[YMAX]-vpt[YMIN]))
    {
    displayExtent[3] = displayExtent[3] -
      (pos[1]+wholeExtent[3] - wholeExtent[2] + 1) +
      (winSize[1] - 1)*(vpt[YMAX]-vpt[YMIN]);
    //displayExtent[3] = (int)((winSize[1] - 1)*(vpt[YMAX] - vpt[YMIN]));
    }

  // now add back in the position to determine the update Extent
  //displayExtent[0] -= pos[0];
  //displayExtent[1] -= pos[0];
  //displayExtent[2] -= pos[1];
  //displayExtent[3] -= pos[1];

  this->Input->SetUpdateExtent(displayExtent);

  // Get the region from the input
  data = this->Input->UpdateAndReturnData();
  if ( !data)
    {
    vtkErrorMacro(<< "Render: Could not get data from input.");
    return;
    }

  this->RenderData(viewport, data, actor);
}

//----------------------------------------------------------------------------
int vtkImageMapper::GetWholeZMin()
{
  int *extent;

  if ( ! this->Input)
    {
    return 0;
    }
  this->Input->UpdateImageInformation();
  extent = this->Input->GetWholeExtent();
  return extent[4];
}

//----------------------------------------------------------------------------
int vtkImageMapper::GetWholeZMax()
{
  int *extent;

  if ( ! this->Input)
    {
    return 0;
    }
  this->Input->UpdateImageInformation();
  extent = this->Input->GetWholeExtent();
  return extent[5];
}

<|endoftext|>


<commit_before>#pragma once

#include <Systems/System.h>
#include <Entities/EntityData.hh>
#include <Components/Collision.hpp>
#include <Context/SdlContext.hh>
#include <Systems/CameraSystem.hpp>
#include <Components/RigidBody.hpp>
#include <MyTags.hpp>

class PistolSystem : public System
{
public:
	PistolSystem(std::weak_ptr<AScene> scene)
		: System(scene)
		, _bullets(scene)
		, _characterController(scene)
	{}

	virtual ~PistolSystem()
	{}

private:
	EntityFilter _bullets;
	EntityFilter _characterController;
	std::shared_ptr<Input> _inputs;

	virtual void updateBegin(double time)
	{}

	virtual void updateEnd(double time)
	{}

	virtual void mainUpdate(double time)
	{
		float ftime = (float)(time);
		static float delay = 0.0f;
		auto scene = _scene.lock();
		if (_inputs->getKey(SDLK_r) && delay <= 0.0f)
		{
			for (auto controller : _characterController.getCollection())
			{
				glm::vec3 from, to;
				scene->getSystem<CameraSystem>()->getRayFromCenterOfScreen(from, to);
				auto e = scene->createEntity();
				e->setLocalTransform(glm::translate(e->getLocalTransform(), glm::vec3(from + to * 1.5f)));
				e->setLocalTransform(glm::scale(e->getLocalTransform(), glm::vec3(0.23f)));
				auto mesh = e->addComponent<Component::MeshRenderer>(scene->getInstance<AssetsManager>()->get<ObjFile>("obj__ball"));
				mesh->setShader("MaterialBasic");
				auto rigidBody = e->addComponent<Component::RigidBody>(0.4f);
				rigidBody->setCollisionShape(Component::RigidBody::SPHERE);
				rigidBody->getBody().applyCentralImpulse(convertGLMVectorToBullet(to * 8.0f));
				rigidBody->getBody().setFriction(1.0f);
				rigidBody->getBody().setRestitution(0.9f);
				e->addTag(MyTags::BULLET_TAG);
			}
			delay = 0.1f;
		}
		if (delay >= 0.0f)
			delay -= ftime;
	}

	virtual bool initialize()
	{
		_bullets.requireTag(MyTags::BULLET_TAG);
		_characterController.requireTag(MyTags::HEROS_TAG);
		_inputs = _scene.lock()->getInstance<Input>();
		if (!_inputs)
			return false;
		return true;
	}

	virtual bool activate()
	{
		return true;
	}

	virtual bool deactivate()
	{
		auto collection = _bullets.getCollection();
		auto scene = _scene.lock();
		for (auto &it = std::begin(collection); it != std::end(collection);)
		{
			auto e = *it;
			++it;
			scene->destroy(e);
		}
		return true;
	}
};<commit_msg>limit added to pistol<commit_after>#pragma once

#include <Systems/System.h>
#include <Entities/EntityData.hh>
#include <Components/Collision.hpp>
#include <Context/SdlContext.hh>
#include <Systems/CameraSystem.hpp>
#include <Components/RigidBody.hpp>
#include <MyTags.hpp>

class PistolSystem : public System
{
public:
	PistolSystem(std::weak_ptr<AScene> scene)
		: System(scene)
		, _characterController(scene)
	{}

	virtual ~PistolSystem()
	{}

private:
	EntityFilter _characterController;
	std::queue<Entity> _shots;
	std::shared_ptr<Input> _inputs;

	virtual void updateBegin(double time)
	{}

	virtual void updateEnd(double time)
	{}

	virtual void mainUpdate(double time)
	{
		float ftime = (float)(time);
		static float delay = 0.0f;
		auto scene = _scene.lock();
		if (_inputs->getKey(SDLK_r) && delay <= 0.0f)
		{
			for (auto controller : _characterController.getCollection())
			{
				glm::vec3 from, to;
				scene->getSystem<CameraSystem>()->getRayFromCenterOfScreen(from, to);
				auto e = scene->createEntity();
				e->setLocalTransform(glm::translate(e->getLocalTransform(), glm::vec3(from + to * 1.5f)));
				e->setLocalTransform(glm::scale(e->getLocalTransform(), glm::vec3(0.23f)));
				auto mesh = e->addComponent<Component::MeshRenderer>(scene->getInstance<AssetsManager>()->get<ObjFile>("obj__ball"));
				mesh->setShader("MaterialBasic");
				auto rigidBody = e->addComponent<Component::RigidBody>(0.4f);
				rigidBody->setCollisionShape(Component::RigidBody::SPHERE);
				rigidBody->getBody().applyCentralImpulse(convertGLMVectorToBullet(to * 8.0f));
				rigidBody->getBody().setFriction(1.0f);
				rigidBody->getBody().setRestitution(0.9f);
				e->addTag(MyTags::BULLET_TAG);
				_shots.push(e);
			}
			delay = 0.1f;
		}
		if (delay >= 0.0f)
			delay -= ftime;

		while (_shots.size() > 50)
		{
			scene->destroy(_shots.front());
			_shots.pop();
		}
	}

	virtual bool initialize()
	{
		_characterController.requireTag(MyTags::HEROS_TAG);
		_inputs = _scene.lock()->getInstance<Input>();
		if (!_inputs)
			return false;
		return true;
	}

	virtual bool activate()
	{
		return true;
	}

	virtual bool deactivate()
	{
		auto scene = _scene.lock();
		while (_shots.size() > 0)
		{
			scene->destroy(_shots.front());
			_shots.pop();
		}
		return true;
	}
};<|endoftext|>


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

#include "build/build_config.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/test/automation/tab_proxy.h"
#include "chrome/test/ui/ui_layout_test.h"

// TODO(jorlow): Enable all of these tests, eventually...
static const char* kEventsFiles[] = {
  //"complex-values.html",
  //"iframe-events.html",
  //"index-get-and-set.html",
  //"onstorage-attribute-markup.html",
  //"onstorage-attribute-setattribute.html",
  //"onstorage-attribute-setwindow.html",
  "simple-events.html",
  //"string-conversion.html",
  //"window-open.html",
  NULL
};

static const char* kTopLevelFiles[] = {
  "clear.html",
  "quota.html",
  "remove-item.html",
  //"window-attributes-exist.html",
  NULL
};

static const char* kNoEventsFiles[] = {
  //"complex-keys.html",
  "delete-removal.html",
  "enumerate-storage.html",
  "enumerate-with-length-and-key.html",
  "simple-usage.html",
  NULL
};

static const char* kLocalStorageFiles[] = {
  //  "quota.html",
  NULL
};

static const char* kSessionStorageFiles[] = {
  //  "no-quota.html",
  NULL
};

class DOMStorageTest : public UILayoutTest {
 protected:
  DOMStorageTest()
      : UILayoutTest(),
        test_dir_(FilePath().AppendASCII("LayoutTests").
                  AppendASCII("storage").AppendASCII("domstorage")) {
  }

  virtual ~DOMStorageTest() { }

  virtual void SetUp() {
    launch_arguments_.AppendSwitch(switches::kDisablePopupBlocking);
    launch_arguments_.AppendSwitch(switches::kEnableLocalStorage);
    launch_arguments_.AppendSwitch(switches::kEnableSessionStorage);
    UILayoutTest::SetUp();
  }

  // We require fast/js/resources and storage/domstorage/script-tests for most
  // of the DOM Storage layout tests.  Add those to the list to be copied.
  void AddResources() {
    // Add other paths our tests require.
    FilePath js_dir = FilePath().AppendASCII("LayoutTests").
                      AppendASCII("fast").AppendASCII("js");
    AddResourceForLayoutTest(js_dir, FilePath().AppendASCII("resources"));
    AddResourceForLayoutTest(test_dir_, FilePath().AppendASCII("script-tests"));
  }

  // This is somewhat of a hack because we're running a real browser that
  // actually persists the LocalStorage state vs. DRT and TestShell which don't.
  // The correct fix is to fix the LayoutTests, but similar patches have been
  // rejected in the past.
  void ClearDOMStorage() {
    scoped_refptr<TabProxy> tab(GetActiveTab());
    ASSERT_TRUE(tab.get());

    GURL url = GetTestUrl(L"layout_tests", L"clear_dom_storage.html");
    ASSERT_TRUE(tab->NavigateToURL(url));

    WaitUntilCookieNonEmpty(tab.get(), url, "cleared", kTestIntervalMs,
                            kTestWaitTimeoutMs);
  }

  // Runs each test in an array of strings until it hits a NULL.
  void RunTests(const char** files) {
    while (*files) {
      ClearDOMStorage();
      RunLayoutTest(*files, false);
      ++files;
    }
  }

  FilePath test_dir_;
};

TEST_F(DOMStorageTest, DOMStorageLayoutTests) {
  InitializeForLayoutTest(test_dir_, FilePath(), false);
  AddResources();
  RunTests(kTopLevelFiles);
}

// http://code.google.com/p/chromium/issues/detail?id=24145
// Remove build_config.h include when this is removed.
#if defined(OS_WIN)
#define MAYBE_LocalStorageLayoutTests FLAKY_LocalStorageLayoutTests
#else
#define MAYBE_LocalStorageLayoutTests LocalStorageLayoutTests
#endif  // defined(OS_WIN)

TEST_F(DOMStorageTest, MAYBE_LocalStorageLayoutTests) {
  InitializeForLayoutTest(test_dir_, FilePath().AppendASCII("localstorage"),
                          false);
  AddResources();
  RunTests(kNoEventsFiles);
  RunTests(kEventsFiles);
  RunTests(kLocalStorageFiles);
}

TEST_F(DOMStorageTest, SessionStorageLayoutTests) {
  InitializeForLayoutTest(test_dir_, FilePath().AppendASCII("sessionstorage"),
                          false);
  AddResources();
  RunTests(kNoEventsFiles);
  //RunTests(kEventsFiles);
  RunTests(kSessionStorageFiles);
}
<commit_msg>Adjust flakiness settings to match the adjustments I made to the tests.<commit_after>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "build/build_config.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/test/automation/tab_proxy.h"
#include "chrome/test/ui/ui_layout_test.h"

// TODO(jorlow): Enable all of these tests, eventually...
static const char* kEventsFiles[] = {
  //"complex-values.html",
  //"iframe-events.html",
  //"index-get-and-set.html",
  //"onstorage-attribute-markup.html",
  //"onstorage-attribute-setattribute.html",
  //"onstorage-attribute-setwindow.html",
  "simple-events.html",
  //"string-conversion.html",
  //"window-open.html",
  NULL
};

static const char* kTopLevelFiles[] = {
  "clear.html",
  "quota.html",
  "remove-item.html",
  //"window-attributes-exist.html",
  NULL
};

static const char* kNoEventsFiles[] = {
  //"complex-keys.html",
  "delete-removal.html",
  "enumerate-storage.html",
  "enumerate-with-length-and-key.html",
  "simple-usage.html",
  NULL
};

static const char* kLocalStorageFiles[] = {
  //  "quota.html",
  NULL
};

static const char* kSessionStorageFiles[] = {
  //  "no-quota.html",
  NULL
};

class DOMStorageTest : public UILayoutTest {
 protected:
  DOMStorageTest()
      : UILayoutTest(),
        test_dir_(FilePath().AppendASCII("LayoutTests").
                  AppendASCII("storage").AppendASCII("domstorage")) {
  }

  virtual ~DOMStorageTest() { }

  virtual void SetUp() {
    launch_arguments_.AppendSwitch(switches::kDisablePopupBlocking);
    launch_arguments_.AppendSwitch(switches::kEnableLocalStorage);
    launch_arguments_.AppendSwitch(switches::kEnableSessionStorage);
    UILayoutTest::SetUp();
  }

  // We require fast/js/resources and storage/domstorage/script-tests for most
  // of the DOM Storage layout tests.  Add those to the list to be copied.
  void AddResources() {
    // Add other paths our tests require.
    FilePath js_dir = FilePath().AppendASCII("LayoutTests").
                      AppendASCII("fast").AppendASCII("js");
    AddResourceForLayoutTest(js_dir, FilePath().AppendASCII("resources"));
    AddResourceForLayoutTest(test_dir_, FilePath().AppendASCII("script-tests"));
  }

  // This is somewhat of a hack because we're running a real browser that
  // actually persists the LocalStorage state vs. DRT and TestShell which don't.
  // The correct fix is to fix the LayoutTests, but similar patches have been
  // rejected in the past.
  void ClearDOMStorage() {
    scoped_refptr<TabProxy> tab(GetActiveTab());
    ASSERT_TRUE(tab.get());

    GURL url = GetTestUrl(L"layout_tests", L"clear_dom_storage.html");
    ASSERT_TRUE(tab->NavigateToURL(url));

    WaitUntilCookieNonEmpty(tab.get(), url, "cleared", kTestIntervalMs,
                            kTestWaitTimeoutMs);
  }

  // Runs each test in an array of strings until it hits a NULL.
  void RunTests(const char** files) {
    while (*files) {
      ClearDOMStorage();
      RunLayoutTest(*files, false);
      ++files;
    }
  }

  FilePath test_dir_;
};

// http://code.google.com/p/chromium/issues/detail?id=24145
// Remove build_config.h include when this is removed.
#if defined(OS_WIN)
#define MAYBE_LocalStorageLayoutTests FLAKY_LocalStorageLayoutTests
#define MAYBE_DOMStorageLayoutTests FLAKY_DOMStorageLayoutTests
#else
#define MAYBE_LocalStorageLayoutTests LocalStorageLayoutTests
#define MAYBE_DOMStorageLayoutTests DOMStorageLayoutTests
#endif  // defined(OS_WIN)

TEST_F(DOMStorageTest, MAYBE_DOMStorageLayoutTests) {
  InitializeForLayoutTest(test_dir_, FilePath(), false);
  AddResources();
  RunTests(kTopLevelFiles);
}

TEST_F(DOMStorageTest, MAYBE_LocalStorageLayoutTests) {
  InitializeForLayoutTest(test_dir_, FilePath().AppendASCII("localstorage"),
                          false);
  AddResources();
  RunTests(kNoEventsFiles);
  RunTests(kEventsFiles);
  RunTests(kLocalStorageFiles);
}

TEST_F(DOMStorageTest, SessionStorageLayoutTests) {
  InitializeForLayoutTest(test_dir_, FilePath().AppendASCII("sessionstorage"),
                          false);
  AddResources();
  RunTests(kNoEventsFiles);
  //RunTests(kEventsFiles);
  RunTests(kSessionStorageFiles);
}
<|endoftext|>