<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 --- StringSet Module
 *
 * This module adds support for longest matching prefix string matches.
 *
 * Adds two operators, both of which take a set of strinngs as a space
 * separated list as argument.
 *
 * - `@strmatch` is true iff the input is in the set.  The capture field is
 *   set to the input.
 * - @strmatch_prefix` is true iff a prefix of the input is in the set.  The
 *   capture field is set to the longest matching prefix.
 *
 * @author Christopher Alfeld <calfeld@qualys.com>
 */

#include <ironbee/stringset.h>

#include <ironbeepp/all.hpp>

#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/split.hpp>
#include <boost/bind.hpp>

using namespace std;
using namespace IronBee;

namespace {

//! strmatch operator name.
const char* c_strmatch = "strmatch";
//! strmatch_prefix operator name.
const char* c_strmatch_prefix = "strmatch_prefix";

//! Called on module load.
void module_load(IronBee::Module module);

} // Anonymous

IBPP_BOOTSTRAP_MODULE("constant", module_load)

// Implementation

// Reopen for doxygen; not needed by C++.
namespace {

/**
 * Construct a string set.
 *
 * @param[in] mm Memory manager determining lifetime.
 * @param[in] parameters Space separated list of items.
 * @return String set.
 **/
const ib_stringset_t* construct_set(
    MemoryManager mm,
    const char* parameters
)
{
    vector<string> items;
    boost::split(items, parameters, boost::is_any_of(" "));

    ib_stringset_t* set = mm.allocate<ib_stringset_t>();
    ib_stringset_entry_t* entries =
        mm.allocate<ib_stringset_entry_t>(items.size());

    for (size_t i = 0; i < items.size(); ++i) {
        entries[i].string =
            reinterpret_cast<const char*>(
                mm.memdup(items[i].data(), items[i].size())
            );
        entries[i].length = items[i].size();
        entries[i].data   = NULL;
    }

    throw_if_error(ib_stringset_init(set, entries, items.size()));

    return set;
}

/** Execute @strmatch. */
int strmatch_prefix_execute(
    const ib_stringset_t* set,
    Transaction           tx,
    ConstField            input,
    Field                 capture
)
{
    if (! input) {
        return 0;
    }

    if (input.type() != Field::BYTE_STRING) {
        BOOST_THROW_EXCEPTION(
            einval() << errinfo_what(
                string(c_strmatch) + " requires bytestring input."
            )
        );
    }

    ConstByteString bs = input.value_as_byte_string();
    const ib_stringset_entry_t* result;

    ib_status_t rc =
        ib_stringset_query(set, bs.const_data(), bs.size(), &result);
    if (rc == IB_OK) {
        if (capture) {
            capture.mutable_value_as_list<Field>().push_back(
                Field::create_no_copy_byte_string(
                    tx.memory_manager(),
                    input.name(), input.name_length(),
                    ByteString::create(
                        tx.memory_manager(),
                        result->string, result->length
                    )
                )
            );
        }
        return 1;
    }
    return 0;
}

/** Execute @strmatch_prefix. */
int strmatch_execute(
    const ib_stringset_t* set,
    ConstField input
)
{
    if (! input) {
        return 0;
    }

    if (input.type() != Field::BYTE_STRING) {
        BOOST_THROW_EXCEPTION(
            einval() << errinfo_what(
                string(c_strmatch) + " requires bytestring input."
            )
        );

    }

    ConstByteString bs = input.value_as_byte_string();
    const ib_stringset_entry_t* result;

    ib_status_t rc =
        ib_stringset_query(set, bs.const_data(), bs.size(), &result);

    if (rc == IB_OK && result->length == bs.size()) {
        return 1;
    }
    return 0;
}

/** Generate @strmatch instance. */
Operator::operator_instance_t strmatch_generator(
    Context,
    MemoryManager mm,
    const char* parameters
)
{
    const ib_stringset_t* set = construct_set(mm, parameters);

    return bind(strmatch_execute, set, _2);
}

/** Execute @strmatch_prefix instance. */
Operator::operator_instance_t strmatch_prefix_generator(
    Context,
    MemoryManager mm,
    const char* parameters
)
{
    const ib_stringset_t* set = construct_set(mm, parameters);

    return bind(strmatch_prefix_execute, set, _1, _2, _3);
}

void module_load(IronBee::Module module)
{
    MemoryManager mm = module.engine().main_memory_mm();

    Operator::create(
        mm,
        c_strmatch,
        IB_OP_CAPABILITY_ALLOW_NULL,
        strmatch_generator
    ).register_with(module.engine());

    Operator::create(
        mm,
        c_strmatch_prefix,
        IB_OP_CAPABILITY_CAPTURE | IB_OP_CAPABILITY_ALLOW_NULL,
        strmatch_prefix_generator
    ).register_with(module.engine());
}

} // Anonymous

<commit_msg>modules/stringset.cpp: Minor cleanup.<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 --- StringSet Module
 *
 * This module adds support for longest matching prefix string matches.
 *
 * Adds two operators, both of which take a set of strinngs as a space
 * separated list as argument.
 *
 * - `@strmatch` is true iff the input is in the set.  The capture field is
 *   set to the input.
 * - @strmatch_prefix` is true iff a prefix of the input is in the set.  The
 *   capture field is set to the longest matching prefix.
 *
 * @author Christopher Alfeld <calfeld@qualys.com>
 */

#include <ironbee/stringset.h>

#include <ironbeepp/all.hpp>

#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/split.hpp>
#include <boost/bind.hpp>

using namespace std;
using namespace IronBee;

namespace {

//! strmatch operator name.
const char* c_strmatch = "strmatch";
//! strmatch_prefix operator name.
const char* c_strmatch_prefix = "strmatch_prefix";

//! Called on module load.
void module_load(IronBee::Module module);

} // Anonymous

IBPP_BOOTSTRAP_MODULE("constant", module_load)

// Implementation

// Reopen for doxygen; not needed by C++.
namespace {

/**
 * Construct a string set.
 *
 * @param[in] mm Memory manager determining lifetime.
 * @param[in] parameters Space separated list of items.
 * @return String set.
 **/
const ib_stringset_t* construct_set(
    MemoryManager mm,
    const char* parameters
)
{
    vector<string> items;
    boost::split(items, parameters, boost::is_any_of(" "));

    ib_stringset_t* set = mm.allocate<ib_stringset_t>();
    ib_stringset_entry_t* entries =
        mm.allocate<ib_stringset_entry_t>(items.size());

    for (size_t i = 0; i < items.size(); ++i) {
        entries[i].string =
            reinterpret_cast<const char*>(
                mm.memdup(items[i].data(), items[i].size())
            );
        entries[i].length = items[i].size();
        entries[i].data   = NULL;
    }

    throw_if_error(ib_stringset_init(set, entries, items.size()));

    return set;
}

/** Execute @strmatch. */
int strmatch_prefix_execute(
    const ib_stringset_t* set,
    Transaction           tx,
    ConstField            input,
    Field                 capture
)
{
    if (! input) {
        return 0;
    }

    if (input.type() != Field::BYTE_STRING) {
        BOOST_THROW_EXCEPTION(
            einval() << errinfo_what(
                string(c_strmatch) + " requires bytestring input."
            )
        );
    }

    ConstByteString bs = input.value_as_byte_string();
    const ib_stringset_entry_t* result;

    ib_status_t rc =
        ib_stringset_query(set, bs.const_data(), bs.size(), &result);
    if (rc == IB_OK) {
        if (capture) {
            capture.mutable_value_as_list<Field>().push_back(
                Field::create_no_copy_byte_string(
                    tx.memory_manager(),
                    input.name(), input.name_length(),
                    ByteString::create(
                        tx.memory_manager(),
                        result->string, result->length
                    )
                )
            );
        }
        return 1;
    }
    return 0;
}

/** Execute @strmatch_prefix. */
int strmatch_execute(
    const ib_stringset_t* set,
    ConstField input
)
{
    if (! input) {
        return 0;
    }

    if (input.type() != Field::BYTE_STRING) {
        BOOST_THROW_EXCEPTION(
            einval() << errinfo_what(
                string(c_strmatch) + " requires bytestring input."
            )
        );

    }

    ConstByteString bs = input.value_as_byte_string();
    const ib_stringset_entry_t* result;

    ib_status_t rc =
        ib_stringset_query(set, bs.const_data(), bs.size(), &result);

    if (rc == IB_OK && result->length == bs.size()) {
        return 1;
    }
    return 0;
}

/** Generate @strmatch instance. */
Operator::operator_instance_t strmatch_generator(
    Context,
    MemoryManager mm,
    const char* parameters
)
{
    const ib_stringset_t* set = construct_set(mm, parameters);

    return bind(strmatch_execute, set, _2);
}

/** Execute @strmatch_prefix instance. */
Operator::operator_instance_t strmatch_prefix_generator(
    Context,
    MemoryManager mm,
    const char* parameters
)
{
    const ib_stringset_t* set = construct_set(mm, parameters);

    return bind(strmatch_prefix_execute, set, _1, _2, _3);
}

void module_load(IronBee::Module module)
{
    MemoryManager mm = module.engine().main_memory_mm();

    Operator::create(
        mm,
        c_strmatch,
        IB_OP_CAPABILITY_ALLOW_NULL,
        strmatch_generator
    ).register_with(module.engine());

    Operator::create(
        mm,
        c_strmatch_prefix,
        IB_OP_CAPABILITY_CAPTURE | IB_OP_CAPABILITY_ALLOW_NULL,
        strmatch_prefix_generator
    ).register_with(module.engine());
}

} // Anonymous
<|endoftext|>


<commit_before>/***************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (directui@nokia.com)
**
** This file is part of mcompositor.
**
** If you have questions regarding the use of this file, please contact
** Nokia at directui@nokia.com.
**
** 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
** and appearing in the file LICENSE.LGPL included in the packaging
** of this file.
**
****************************************************************************/

#include "msplashscreen.h"
#include "mcompositemanager.h"
#include "mcompositemanager_p.h"
#include "mdevicestate.h"
#include "mcompositewindowanimation.h"
#include "mcompatoms_p.h"

#include <X11/Xatom.h>

MSplashPropertyCache::MSplashPropertyCache()
    : MWindowPropertyCache(0, &attrs)
{
    memset(&attrs, 0, sizeof(attrs));
    setIsMapped(true);
    type_atoms.append(ATOM(_KDE_NET_WM_WINDOW_TYPE_OVERRIDE));
    setRealGeometry(QApplication::desktop()->geometry());
    has_alpha = 1; // prevent switching off compositing
}

MSplashPropertyCache *MSplashPropertyCache::get()
{
    static MSplashPropertyCache *singleton;

    if (!singleton)
        singleton = new MSplashPropertyCache();
    return singleton;
}

void MSplashPropertyCache::setOrientationAngle(int angle)
{
    orientation_angle = angle;
}

void MSplashPropertyCache::setPid(unsigned pid)
{
    wm_pid = pid;
}

bool MSplashPropertyCache::event(QEvent *e)
{
    // Ignore deleteLater().
    return e->type() == QEvent::DeferredDelete ?
                                true : MWindowPropertyCache::event(e);
}

MSplashScreen::MSplashScreen(unsigned int splash_pid,
                             const QString &splash_p, const QString &splash_l,
                             unsigned int splash_pixmap)
    : MTexturePixmapItem(0, MSplashPropertyCache::get()),
      portrait_file(splash_p),
      landscape_file(splash_l),
      pixmap(splash_pixmap),
      q_pixmap(0),
      fade_animation(false)
{
    MSplashPropertyCache::get()->setPid(splash_pid);

    Display *dpy = QX11Info::display();
    win_id = XCreateWindow(dpy, RootWindow(dpy, 0), 0, 0,
                           ScreenOfDisplay(dpy, DefaultScreen(dpy))->width,
                           ScreenOfDisplay(dpy, DefaultScreen(dpy))->height,
                           0, CopyFromParent,
                           InputOnly, CopyFromParent, 0, 0);
    XStoreName(dpy, win_id, "MSplashScreen");
    XMapWindow(dpy, win_id);

    MCompositeManager *m = (MCompositeManager*)qApp;
    if (!pixmap) {
        int orientation = 270;
        if (!splash_l.size())
            landscape_file = splash_p;
        // TODO: default path for relative file names
        // TODO 2: mirrored textures for bottom/right
        if (m->d->device_state->screenTopEdge() == "top"
            || m->d->device_state->screenTopEdge() == "bottom") {
            q_pixmap = new QPixmap(landscape_file);
            if (q_pixmap->isNull())
                qWarning() << __func__ << "couldn't load" << landscape_file;
            if (portrait_file != landscape_file)
                orientation = 0;
        } else {
            q_pixmap = new QPixmap(portrait_file);
            if (q_pixmap->isNull())
                qWarning() << __func__ << "couldn't load" << portrait_file;
        }
        if (!q_pixmap->isNull())
            pixmap = q_pixmap->handle();

        MSplashPropertyCache::get()->setOrientationAngle(orientation);
    }

    if (pixmap) {
        timer.setSingleShot(true);
        timer.setInterval(m->configInt("splash-timeout-ms"));
        connect(&timer, SIGNAL(timeout()), m->d, SLOT(splashTimeout()));
        timer.start();
    }
    connect(this, SIGNAL(itemIconified(MCompositeWindow*)),
            this, SLOT(iconified()));
}

MSplashScreen::~MSplashScreen()
{
    XDestroyWindow(QX11Info::display(), win_id);
    // NOTE: if pixmap was provided to us, MTexturePixmapItemPrivate frees it.
    // TODO: signal switcher that we freed it

    // return this QPixmap to the QPixmapCache with a valid X pixmap
    delete q_pixmap;
}

QRectF MSplashScreen::boundingRect() const
{
    return QApplication::desktop()->geometry();
}

bool MSplashScreen::matches(MWindowPropertyCache *pc) const
{
    return pc->pid() == MSplashPropertyCache::get()->pid();
}

bool MSplashScreen::same(unsigned pid, const QString &splash_p,
                         const QString &splash_l, unsigned pixmap) const
{
    return pid == MSplashPropertyCache::get()->pid()
            && (!pixmap || pixmap == this->pixmap)
            && (splash_p == portrait_file)
            && (splash_l.isEmpty() || splash_l == landscape_file);
}

void MSplashScreen::endAnimation()
{
    if (fade_animation)
        // cross-fade ended, time to go
        ((MCompositeManager*)qApp)->d->splashTimeout();
}

void MSplashScreen::beginAnimation()
{
    if (windowAnimator()->pendingAnimation()
                              == MCompositeWindowAnimation::CrossFade) {
        fade_animation = true;
        // fade started, stop the timer
        timer.stop();
    }
}

void MSplashScreen::iconified()
{
    ((MCompositeManager*)qApp)->d->splashTimeout();
}

<commit_msg>when device isFlat(), use current app's orientation for splash screens<commit_after>/***************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (directui@nokia.com)
**
** This file is part of mcompositor.
**
** If you have questions regarding the use of this file, please contact
** Nokia at directui@nokia.com.
**
** 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
** and appearing in the file LICENSE.LGPL included in the packaging
** of this file.
**
****************************************************************************/

#include "msplashscreen.h"
#include "mcompositemanager.h"
#include "mcompositemanager_p.h"
#include "mdevicestate.h"
#include "mcompositewindowanimation.h"
#include "mcompatoms_p.h"

#include <X11/Xatom.h>

MSplashPropertyCache::MSplashPropertyCache()
    : MWindowPropertyCache(0, &attrs)
{
    memset(&attrs, 0, sizeof(attrs));
    setIsMapped(true);
    type_atoms.append(ATOM(_KDE_NET_WM_WINDOW_TYPE_OVERRIDE));
    setRealGeometry(QApplication::desktop()->geometry());
    has_alpha = 1; // prevent switching off compositing
}

MSplashPropertyCache *MSplashPropertyCache::get()
{
    static MSplashPropertyCache *singleton;

    if (!singleton)
        singleton = new MSplashPropertyCache();
    return singleton;
}

void MSplashPropertyCache::setOrientationAngle(int angle)
{
    orientation_angle = angle;
}

void MSplashPropertyCache::setPid(unsigned pid)
{
    wm_pid = pid;
}

bool MSplashPropertyCache::event(QEvent *e)
{
    // Ignore deleteLater().
    return e->type() == QEvent::DeferredDelete ?
                                true : MWindowPropertyCache::event(e);
}

MSplashScreen::MSplashScreen(unsigned int splash_pid,
                             const QString &splash_p, const QString &splash_l,
                             unsigned int splash_pixmap)
    : MTexturePixmapItem(0, MSplashPropertyCache::get()),
      portrait_file(splash_p),
      landscape_file(splash_l),
      pixmap(splash_pixmap),
      q_pixmap(0),
      fade_animation(false)
{
    MSplashPropertyCache::get()->setPid(splash_pid);

    Display *dpy = QX11Info::display();
    win_id = XCreateWindow(dpy, RootWindow(dpy, 0), 0, 0,
                           ScreenOfDisplay(dpy, DefaultScreen(dpy))->width,
                           ScreenOfDisplay(dpy, DefaultScreen(dpy))->height,
                           0, CopyFromParent,
                           InputOnly, CopyFromParent, 0, 0);
    XStoreName(dpy, win_id, "MSplashScreen");
    XMapWindow(dpy, win_id);

    MCompositeManager *m = (MCompositeManager*)qApp;
    if (!pixmap) {
        int orientation = 270;
        if (!splash_l.size())
            landscape_file = splash_p;
        // TODO: default path for relative file names
        // TODO 2: mirrored textures for bottom/right
        bool landscape = false;
        if (m->d->device_state->isFlat()) {
            MWindowPropertyCache *pc = m->d->prop_caches.value(
                                                  m->d->current_app, 0);
            if (pc && (pc->orientationAngle() == 0
                       || pc->orientationAngle() == 180))
                landscape = true;
        } else if (m->d->device_state->screenTopEdge() == "top"
                   || m->d->device_state->screenTopEdge() == "bottom")
            landscape = true;
        if (landscape) {
            q_pixmap = new QPixmap(landscape_file);
            if (q_pixmap->isNull())
                qWarning() << __func__ << "couldn't load" << landscape_file;
            if (portrait_file != landscape_file)
                orientation = 0;
        } else {
            q_pixmap = new QPixmap(portrait_file);
            if (q_pixmap->isNull())
                qWarning() << __func__ << "couldn't load" << portrait_file;
        }
        if (!q_pixmap->isNull())
            pixmap = q_pixmap->handle();

        MSplashPropertyCache::get()->setOrientationAngle(orientation);
    }

    if (pixmap) {
        timer.setSingleShot(true);
        timer.setInterval(m->configInt("splash-timeout-ms"));
        connect(&timer, SIGNAL(timeout()), m->d, SLOT(splashTimeout()));
        timer.start();
    }
    connect(this, SIGNAL(itemIconified(MCompositeWindow*)),
            this, SLOT(iconified()));
}

MSplashScreen::~MSplashScreen()
{
    XDestroyWindow(QX11Info::display(), win_id);
    // NOTE: if pixmap was provided to us, MTexturePixmapItemPrivate frees it.
    // TODO: signal switcher that we freed it

    // return this QPixmap to the QPixmapCache with a valid X pixmap
    delete q_pixmap;
}

QRectF MSplashScreen::boundingRect() const
{
    return QApplication::desktop()->geometry();
}

bool MSplashScreen::matches(MWindowPropertyCache *pc) const
{
    return pc->pid() == MSplashPropertyCache::get()->pid();
}

bool MSplashScreen::same(unsigned pid, const QString &splash_p,
                         const QString &splash_l, unsigned pixmap) const
{
    return pid == MSplashPropertyCache::get()->pid()
            && (!pixmap || pixmap == this->pixmap)
            && (splash_p == portrait_file)
            && (splash_l.isEmpty() || splash_l == landscape_file);
}

void MSplashScreen::endAnimation()
{
    if (fade_animation)
        // cross-fade ended, time to go
        ((MCompositeManager*)qApp)->d->splashTimeout();
}

void MSplashScreen::beginAnimation()
{
    if (windowAnimator()->pendingAnimation()
                              == MCompositeWindowAnimation::CrossFade) {
        fade_animation = true;
        // fade started, stop the timer
        timer.stop();
    }
}

void MSplashScreen::iconified()
{
    ((MCompositeManager*)qApp)->d->splashTimeout();
}

<|endoftext|>


<commit_before>#include "ExampleSubsystem.h"
#include "../RobotMap.h"
#include "../Commands/ExampleCommand.h"

ExampleSubsystem::ExampleSubsystem()
	: PIDSubsystem("ExampleSubsystem", 0.0, 0.0, 0.0)
	, m_bSquaredDrive(true)
	, moveSpeed(0)
	, m_drive(LEFTFRONTMOTOR,LEFTBACKMOTOR,RIGHTFRONTMOTOR,RIGHTBACKMOTOR)
{
	m_drive.SetSafetyEnabled(false);
	m_drive.SetInvertedMotor(m_drive.kRearLeftMotor, true);
	m_drive.SetInvertedMotor(m_drive.kRearRightMotor, true);
	m_drive.SetInvertedMotor(m_drive.kFrontLeftMotor, true);
	m_drive.SetInvertedMotor(m_drive.kFrontRightMotor, true);

	m_cEncoderL = new Encoder(DRIVE_ENCODERL_A,DRIVE_ENCODERL_B);
	m_cEncoderR = new Encoder(DRIVE_ENCODERR_A,DRIVE_ENCODERR_B);
	gyro  = new Gyro(C_GYRO);
	m_bIsUsingGyro = true;
	GetPIDController()->Disable();
	gyro->InitGyro();
	gyro->Reset();
	Preferences::GetInstance()->PutDouble("Gyro_PID_P", 0.07);
	Preferences::GetInstance()->PutDouble("Gyro_PID_I", 0);
	Preferences::GetInstance()->PutDouble("Gyro_PID_D", 0.2);
	SmartDashboard::PutNumber("DB/Slider 0", 0.07 / 0.1 );
	SmartDashboard::PutNumber("DB/Slider 1", 0.0 / 0.1 );
	SmartDashboard::PutNumber("DB/Slider 2", 0.2 / 0.1 );
}

ExampleSubsystem::~ExampleSubsystem()
{
	delete gyro;
	delete m_cEncoderL;
	delete m_cEncoderR;
}

void ExampleSubsystem::InitDefaultCommand()
{
	SetDefaultCommand(new ExampleCommand());
}

void ExampleSubsystem::Drive(double move, double turn, bool quad)
{
	m_drive.ArcadeDrive(move, turn, quad);
	if(m_bIsUsingGyro)
	{
		m_bIsUsingGyro = false;
		GetPIDController()->Disable();
	}
}

void ExampleSubsystem::HoldAngle(double angle)
{
	np = SmartDashboard::GetNumber("DB/Slider 0") * 0.1;
	ni = SmartDashboard::GetNumber("DB/Slider 1") * 0.1;
	nd = SmartDashboard::GetNumber("DB/Slider 2") * 0.1;
	GetPIDController()->SetPID(np,ni,nd);
	GetPIDController()->SetSetpoint(GetAngle() + angle);
	GetPIDController()->Enable();
}

void ExampleSubsystem::GyroDrive(double move, bool squaredInputs)
{
	m_bSquaredDrive = squaredInputs;
	moveSpeed = move;
	if(!m_bIsUsingGyro)
	{
		m_bIsUsingGyro = true;
		GetPIDController()->Enable();
	}
}

double ExampleSubsystem::ReturnPIDInput()
{
	return gyro->GetAngle();
}

void ExampleSubsystem::UsePIDOutput(double outputAngle)
{
	m_drive.TankDrive(moveSpeed-outputAngle, moveSpeed+outputAngle, m_bSquaredDrive);
}
<commit_msg>Modified preferences so they aren't overriden.<commit_after>#include "ExampleSubsystem.h"
#include "../RobotMap.h"
#include "../Commands/ExampleCommand.h"

ExampleSubsystem::ExampleSubsystem()
	: PIDSubsystem("ExampleSubsystem", 0.0, 0.0, 0.0)
	, m_bSquaredDrive(true)
	, moveSpeed(0)
	, m_drive(LEFTFRONTMOTOR,LEFTBACKMOTOR,RIGHTFRONTMOTOR,RIGHTBACKMOTOR)
{
	m_drive.SetSafetyEnabled(false);
	m_drive.SetInvertedMotor(m_drive.kRearLeftMotor, true);
	m_drive.SetInvertedMotor(m_drive.kRearRightMotor, true);
	m_drive.SetInvertedMotor(m_drive.kFrontLeftMotor, true);
	m_drive.SetInvertedMotor(m_drive.kFrontRightMotor, true);

	m_cEncoderL = new Encoder(DRIVE_ENCODERL_A,DRIVE_ENCODERL_B);
	m_cEncoderR = new Encoder(DRIVE_ENCODERR_A,DRIVE_ENCODERR_B);
	gyro  = new Gyro(C_GYRO);
	m_bIsUsingGyro = true;
	GetPIDController()->Disable();
	gyro->InitGyro();
	gyro->Reset();
	SmartDashboard::PutNumber("DB/Slider 0", Preferences::GetInstance()->GetDouble("Gyro_PID_P")/0.1);
	SmartDashboard::PutNumber("DB/Slider 1", Preferences::GetInstance()->GetDouble("Gyro_PID_I")/0.1);
	SmartDashboard::PutNumber("DB/Slider 2", Preferences::GetInstance()->GetDouble("Gyro_PID_D")/0.1);
}

ExampleSubsystem::~ExampleSubsystem()
{
	delete gyro;
	delete m_cEncoderL;
	delete m_cEncoderR;
}

void ExampleSubsystem::InitDefaultCommand()
{
	SetDefaultCommand(new ExampleCommand());
}

void ExampleSubsystem::Drive(double move, double turn, bool quad)
{
	m_drive.ArcadeDrive(move, turn, quad);
	if(m_bIsUsingGyro)
	{
		m_bIsUsingGyro = false;
		GetPIDController()->Disable();
	}
}

void ExampleSubsystem::HoldAngle(double angle)
{
	np = SmartDashboard::GetNumber("DB/Slider 0") * 0.1;
	ni = SmartDashboard::GetNumber("DB/Slider 1") * 0.1;
	nd = SmartDashboard::GetNumber("DB/Slider 2") * 0.1;
	GetPIDController()->SetPID(np,ni,nd);
	GetPIDController()->SetSetpoint(GetAngle() + angle);
	GetPIDController()->Enable();
}

void ExampleSubsystem::GyroDrive(double move, bool squaredInputs)
{
	m_bSquaredDrive = squaredInputs;
	moveSpeed = move;
	if(!m_bIsUsingGyro)
	{
		m_bIsUsingGyro = true;
		GetPIDController()->Enable();
	}
}

double ExampleSubsystem::ReturnPIDInput()
{
	return gyro->GetAngle();
}

void ExampleSubsystem::UsePIDOutput(double outputAngle)
{
	m_drive.TankDrive(moveSpeed-outputAngle, moveSpeed+outputAngle, m_bSquaredDrive);
}
<|endoftext|>


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

#include <net/configure.hpp>

#include <net/interfaces.hpp>
#include <info>

#define MYINFO(X,...) INFO("Netconf",X,##__VA_ARGS__)

namespace net {

using Addresses = std::vector<ip4::Addr>;

template <typename T>
Addresses parse_iface(T& obj)
{
  if(not obj.HasMember("address") and not obj.HasMember("netmask"))
    return {};
  Expects(obj.HasMember("address"));
  Expects(obj.HasMember("netmask"));

  ip4::Addr address{obj["address"].GetString()};
  ip4::Addr netmask{obj["netmask"].GetString()};
  ip4::Addr gateway = (obj.HasMember("gateway")) ? ip4::Addr{obj["gateway"].GetString()} : 0;
  ip4::Addr dns = (not obj.HasMember("dns")) ? gateway : ip4::Addr{obj["dns"].GetString()};

  Addresses addresses{address, netmask, gateway, dns};
  return addresses;
}

inline void config_stack(Inet& stack, const Addresses& addrs)
{
  if(addrs.empty()) {
    MYINFO("! WARNING: No config for stack %s", stack.ifname().c_str());
    return;
  }

  Expects((addrs.size() > 2 and addrs.size() < 5)
    && "A network config needs to be between 3 and 4 addresses");

  stack.network_config(
    addrs[0], addrs[1], addrs[2],
    ((addrs.size() == 4) ? addrs[3] : 0)
    );
}

void configure(const rapidjson::Value& net)
{
  MYINFO("Configuring network");

  Expects(net.IsArray() && "Member net is not an array");

  auto configs = net.GetArray();
  if(configs.Size() > Interfaces::get().size())
    MYINFO("! WARNING: Found more configs than there are interfaces");
  // Iterate all interfaces in config
  for(auto& val : configs)
  {
    Expects(val.HasMember("iface")
      && "Missing member iface - don't know which interface to configure");

    auto N = val["iface"].GetInt();

    auto& stack = Interfaces::get(N);

    // if config is not set, just ignore
    if(not val.HasMember("config")) {
      MYINFO("NOTE: Config method not set, ignoring");
      continue;
    }

    std::string method = val["config"].GetString();

    double timeout = (val.HasMember("timeout")) ? val["timeout"].GetDouble() : 10.0;

    if(method == "dhcp")
    {
      stack.negotiate_dhcp(timeout);
    }
    else if(method == "static")
    {
      config_stack(stack, parse_iface(val));
    }
    else if(method == "dhcp-with-fallback")
    {
      auto addresses = parse_iface(val);
      auto static_cfg = [addresses, &stack] (bool timedout)
      {
        if(timedout) {
          MYINFO("DHCP timeout (%s) - falling back to static configuration", stack.ifname().c_str());
          config_stack(stack, addresses);
        }
      };
      stack.negotiate_dhcp(timeout, static_cfg);
    }
  }

  MYINFO("Configuration complete");
}

}
<commit_msg>util: Rewrite network config parsing to support IPv6 and member arrays<commit_after>// This file is a part of the IncludeOS unikernel - www.includeos.org
//
// Copyright 2017 Oslo and Akershus University College of Applied Sciences
// and Alfred Bratterud
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <net/configure.hpp>

#include <net/interfaces.hpp>
#include <info>

#define MYINFO(X,...) INFO("Netconf",X,##__VA_ARGS__)

//#define NETCONF_DEBUG 1
#ifdef NETCONF_DEBUG
#define PRINT(fmt, ...) printf(fmt, ##__VA_ARGS__)
#else
#define PRINT(fmt, ...) /* fmt */
#endif

namespace net {

struct ipv4_res
{
  ip4::Addr addr;
  ip4::Addr netmask;
};

struct ipv6_res
{
  ip6::Addr addr;
  uint8_t prefix;
};

struct v4_config
{
  ip4::Addr addr;
  ip4::Addr netmask;
  ip4::Addr gateway;
  ip4::Addr dns;
};

struct v6_config
{
  std::vector<ipv6_res>  addr;
  std::vector<ip6::Addr> gateway;
  std::vector<ip6::Addr> dns;

  void clear()
  {
    addr.clear();
    gateway.clear();
    dns.clear();
  }
};

inline bool is_v6(const std::string& str)
{
  Expects(not str.empty() && "Address string can't be empty");
  return str.find(':') != std::string::npos;
}

inline ipv4_res parse_addr4(const std::string& str)
{
  if(auto n = str.rfind('/'); n != std::string::npos)
  {
    uint8_t bits = std::stoi(str.substr(n+1));
    ip4::Addr netmask{ntohl(0xFFFFFFFF << (32ul-bits))};
    //PRINT("Bits %u Netmask %s\n", bits, netmask.to_string().c_str());
    return {str.substr(0, n), netmask};
  }
  else
  {
    return {str, 0};
  }
}

inline ipv6_res parse_addr6(const std::string& str)
{
  if(auto n = str.rfind('/'); n != std::string::npos)
  {
    uint8_t prefix = std::stoi(str.substr(n+1));
    return {str.substr(0, n), prefix};
  }
  else
  {
    return {str, 0};
  }
}

inline void parse_addr(v4_config& cfg4, v6_config& cfg6, std::string str)
{
  if(is_v6(str))
  {
    cfg6.addr.push_back(parse_addr6(str));
    PRINT("v6 Addr: %s Prefix: %u\n",
      cfg6.addr.back().addr.to_string().c_str(), cfg6.addr.back().prefix);
  }
  else
  {
    if(cfg4.addr != 0)
    {
      MYINFO("WARN: Multiple v4 addresses not supported: skipping %s", str.c_str());
      return;
    }

    auto [addr, netmask] = parse_addr4(str);
    cfg4.addr = addr;
    cfg4.netmask = netmask;
    PRINT("v4 Addr: %s Netmask: %s\n",
      cfg4.addr.to_string().c_str(), cfg4.netmask.to_string().c_str());
  }
}

inline void parse_gateway(v4_config& cfg4, v6_config& cfg6, std::string str)
{
  if(is_v6(str))
  {
    cfg6.gateway.push_back(parse_addr6(str).addr);
    PRINT("v6 Gateway: %s\n",
      cfg6.gateway.back().to_string().c_str());
  }
  else
  {
    if(cfg4.gateway != 0)
    {
      MYINFO("WARN: Multiple v4 gateways not supported: skipping %s", str.c_str());
      return;
    }

    cfg4.gateway = parse_addr4(str).addr;
    PRINT("v4 Gateway: %s\n",
      cfg4.gateway.to_string().c_str());
  }
}

inline void parse_dns(v4_config& cfg4, v6_config& cfg6, std::string str)
{
  if(is_v6(str))
  {
    cfg6.dns.push_back(parse_addr6(str).addr);
    PRINT("v6 DNS: %s\n",
      cfg6.dns.back().to_string().c_str());
  }
  else
  {
    if(cfg4.dns != 0)
    {
      MYINFO("WARN: Multiple v4 DNS not supported: skipping %s", str.c_str());
      return;
    }

    cfg4.dns = parse_addr4(str).addr;
    PRINT("v4 DNS: %s\n",
      cfg4.dns.to_string().c_str());
  }
}

inline void config4(Inet& stack, const v4_config& cfg)
{
  Expects(cfg.addr != 0 && "Missing address (v4)");
  Expects(cfg.netmask != 0 && "Missing netmask");
  stack.network_config(cfg.addr, cfg.netmask, cfg.gateway, cfg.dns);
}

inline void config6(Inet& stack, const v6_config& cfg)
{
  // add address
  for(const auto& [addr, prefix] : cfg.addr)
    (prefix) ? stack.add_addr(addr, prefix) : stack.add_addr(addr);

  // add routers
  for(const auto& addr : cfg.gateway)
    stack.ndp().add_router(addr, 0xFFFF); // waiting for API to change

  // add dns
  for(const auto& addr : cfg.dns) {
    stack.set_dns_server6(addr);
    break; // currently only support one
  }
}

template <typename Val, typename Func>
inline void parse(const Val& val, v4_config& cfg4, v6_config& cfg6, Func func)
{
  if(val.IsArray())
  {
    PRINT("Member is array\n");
    for(auto& addrstr : val.GetArray()) {
      func(cfg4, cfg6, addrstr.GetString());
    }
  }
  else {
    func(cfg4, cfg6, val.GetString());
  }
}

void configure(const rapidjson::Value& net)
{
  MYINFO("Configuring network");

  Expects(net.IsArray() && "Member net is not an array");

  auto configs = net.GetArray();
  if(configs.Size() > Interfaces::get().size())
    MYINFO("WARN: Found more configs than there are interfaces");
  // Iterate all interfaces in config
  for(auto& val : configs)
  {
    Expects(val.HasMember("iface")
      && "Missing member iface - don't know which interface to configure");

    auto N = val["iface"].GetInt();

    auto& stack = Interfaces::get(N);

    // if config is not set, just ignore
    if(not val.HasMember("config")) {
      MYINFO("WARN: Config method not set, ignoring");
      continue;
    }

    v4_config v4cfg;
    v6_config v6cfg;

    // "address"
    if(val.HasMember("address"))
    {
      parse(val["address"], v4cfg, v6cfg, &parse_addr);
    }

    // "netmask" (ipv4 only)
    if(v4cfg.netmask == 0 and val.HasMember("netmask"))
      v4cfg.netmask = {val["netmask"].GetString()};

    // "gateway"
    if(val.HasMember("gateway"))
    {
      parse(val["gateway"], v4cfg, v6cfg, &parse_gateway);
    }

    // "dns"
    if(val.HasMember("dns"))
    {
      parse(val["dns"], v4cfg, v6cfg, &parse_dns);
    }

    std::vector<std::string> methods;
    const auto& config = val["config"];

    // parse all the config methods
    if(config.IsArray())
    {
      for(const auto& method : val["config"].GetArray())
        methods.push_back(method.GetString());
    }
    else
    {
      methods.push_back(val["config"].GetString());
    }

    for(const auto& method : methods)
    {
      const double timeout = (val.HasMember("timeout")) ? val["timeout"].GetDouble() : 10.0;

      if(method == "dhcp") {
        stack.negotiate_dhcp(timeout);
        // do DHCPv6
      }
      else if(method == "dhcp4") {
        stack.negotiate_dhcp(timeout);
      }
      else if(method == "dhcp6") {
        MYINFO("WARN: DHCPv6 not supported");
      }
      else if(method == "static") {
        config4(stack, v4cfg);
        config6(stack, v6cfg);
        v6cfg.clear();
      }
      else if(method == "static4") {
        config4(stack, v4cfg);
      }
      else if(method == "static6") {
        config6(stack, v6cfg);
        v6cfg.clear();
      }
      else if(method == "slaac") {
        stack.autoconf_v6();
      }
      else if(method == "dhcp-with-fallback") // TBD...
      {
        auto static_cfg = [v4cfg, &stack] (bool timedout)
        {
          if(timedout) {
            MYINFO("DHCP timeout (%s) - falling back to static configuration", stack.ifname().c_str());
            config4(stack, v4cfg);
          }
        };
        stack.negotiate_dhcp(timeout, static_cfg);
      }
      else {
        MYINFO("WARN: Unrecognized config method \"%s\"", method.c_str());
      }
    }
  }

  MYINFO("Configuration complete");
}

}
<|endoftext|>


<commit_before><commit_msg>CID#1202961 init class member<commit_after><|endoftext|>


<commit_before>/***********************************************************************
    created:    Tue Feb 17 2009
    author:     Paul D Turner
*************************************************************************/
/***************************************************************************
 *   Copyright (C) 2004 - 2013 Paul D Turner & The CEGUI Development Team
 *
 *   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 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.
 ***************************************************************************/
#include "CEGUI/RendererModules/Ogre/RenderTarget.h"
#include "CEGUI/GeometryBuffer.h"
#include "CEGUI/RenderQueue.h"
#include "CEGUI/RendererModules/Ogre/GeometryBuffer.h"

#include <OgreRenderSystem.h>
#include <OgreCamera.h>
#include <OgreViewport.h>

// Start of CEGUI namespace section
namespace CEGUI
{
//----------------------------------------------------------------------------//
template <typename T>
OgreRenderTarget<T>::OgreRenderTarget(OgreRenderer& owner,
                                      Ogre::RenderSystem& rs) :
    d_owner(owner),
    d_renderSystem(rs),
    d_area(0, 0, 0, 0),
    d_renderTarget(0),
#ifdef CEGUI_USE_OGRE_COMPOSITOR2
    d_renderTargetUpdated(false),
#else
    d_viewport(0),
    d_ogreViewportDimensions(0, 0, 0, 0),
#endif // CEGUI_USE_OGRE_COMPOSITOR2
    d_matrix(Ogre::Matrix3::ZERO),
    d_matrixValid(false),
    d_viewportValid(false),
    d_viewDistance(0)
{
}

//----------------------------------------------------------------------------//
template <typename T>
OgreRenderTarget<T>::~OgreRenderTarget()
{
#ifdef CEGUI_USE_OGRE_COMPOSITOR2

#else
    delete d_viewport;
#endif // CEGUI_USE_OGRE_COMPOSITOR2
}

//----------------------------------------------------------------------------//
template <typename T>
void OgreRenderTarget<T>::draw(const GeometryBuffer& buffer)
{
    buffer.draw();
}

//----------------------------------------------------------------------------//
template <typename T>
void OgreRenderTarget<T>::draw(const RenderQueue& queue)
{
    queue.draw();
}

//----------------------------------------------------------------------------//
template <typename T>
void OgreRenderTarget<T>::setArea(const Rectf& area)
{
    d_area = area;
#if !defined(CEGUI_USE_OGRE_COMPOSITOR2)
    setOgreViewportDimensions(area);
#endif

    d_matrixValid = false;

    RenderTargetEventArgs args(this);
    T::fireEvent(RenderTarget::EventAreaChanged, args);
}

//----------------------------------------------------------------------------//
#if !defined(CEGUI_USE_OGRE_COMPOSITOR2)
template <typename T>
void OgreRenderTarget<T>::setOgreViewportDimensions(const Rectf& area)
{
    d_ogreViewportDimensions = area;

    if (d_viewport)
        updateOgreViewportDimensions(d_viewport->getTarget());

    d_viewportValid = false;
}
#endif

//----------------------------------------------------------------------------//
#if !defined(CEGUI_USE_OGRE_COMPOSITOR2)
template <typename T>
void OgreRenderTarget<T>::updateOgreViewportDimensions(
                                            const Ogre::RenderTarget* const rt)
{
    if (rt)
    {
        d_viewport->setDimensions(
            d_ogreViewportDimensions.left() / rt->getWidth(),
            d_ogreViewportDimensions.top() / rt->getHeight(),
            d_ogreViewportDimensions.getWidth() / rt->getWidth(),
            d_ogreViewportDimensions.getHeight() / rt->getHeight());
    }
}
#endif

//----------------------------------------------------------------------------//
template <typename T>
const Rectf& OgreRenderTarget<T>::getArea() const
{
    return d_area;
}

//----------------------------------------------------------------------------//
template <typename T>
void OgreRenderTarget<T>::activate()
{
    if (!d_matrixValid)
        updateMatrix();

    if (!d_viewportValid)
        updateViewport();

#ifdef CEGUI_USE_OGRE_COMPOSITOR2

#else
    d_renderSystem._setViewport(d_viewport);
#endif // CEGUI_USE_OGRE_COMPOSITOR2

    d_owner.setProjectionMatrix(d_matrix);
    d_owner.setViewMatrix(Ogre::Matrix4::IDENTITY);
}

//----------------------------------------------------------------------------//
template <typename T>
void OgreRenderTarget<T>::deactivate()
{
    // currently nothing to do in the basic case
}

//----------------------------------------------------------------------------//
template <typename T>
void OgreRenderTarget<T>::unprojectPoint(const GeometryBuffer& buff,
                                      const Vector2f& p_in,
                                      Vector2f& p_out) const
{
    if (!d_matrixValid)
        updateMatrix();

    const OgreGeometryBuffer& gb = static_cast<const OgreGeometryBuffer&>(buff);

    const Ogre::Real midx = d_area.getWidth() * 0.5f;
    const Ogre::Real midy = d_area.getHeight() * 0.5f;

    // viewport matrix
    const Ogre::Matrix4 vpmat(
        midx,    0,    0,    d_area.left() + midx,
         0,    -midy,  0,    d_area.top() + midy,
         0,      0,    1,    0,
         0,      0,    0,    1
    );

    // matrices used for projecting and unprojecting points
    const Ogre::Matrix4 proj(gb.getMatrix() * d_matrix * vpmat);
    const Ogre::Matrix4 unproj(proj.inverse());

    Ogre::Vector3 in;

    // unproject the ends of the ray
    in.x = midx;
    in.y = midy;
    in.z = -d_viewDistance;
    const Ogre::Vector3 r1(unproj * in);
    in.x = p_in.d_x;
    in.y = p_in.d_y;
    in.z = 0;
    // calculate vector of picking ray
    const Ogre::Vector3 rv(r1 - unproj * in);

    // project points to orientate them with GeometryBuffer plane
    in.x = 0.0;
    in.y = 0.0;
    const Ogre::Vector3 p1(proj * in);
    in.x = 1.0;
    in.y = 0.0;
    const Ogre::Vector3 p2(proj * in);
    in.x = 0.0;
    in.y = 1.0;
    const Ogre::Vector3 p3(proj * in);

    // calculate the plane normal
    const Ogre::Vector3 pn((p2 - p1).crossProduct(p3 - p1));
    // calculate distance from origin
    const Ogre::Real plen = pn.length();
    const Ogre::Real dist = -(p1.x * (pn.x / plen) +
                              p1.y * (pn.y / plen) +
                              p1.z * (pn.z / plen));

    // calculate intersection of ray and plane
    const Ogre::Real pn_dot_rv = pn.dotProduct(rv);
    const Ogre::Real tmp = pn_dot_rv != 0.0 ?
                            (pn.dotProduct(r1) + dist) / pn_dot_rv :
                            0.0;

    p_out.d_x = static_cast<float>(r1.x - rv.x * tmp);
    p_out.d_y = static_cast<float>(r1.y - rv.y * tmp);
}

//----------------------------------------------------------------------------//
template <typename T>
void OgreRenderTarget<T>::updateMatrix() const
{
    const float w = d_area.getWidth();
    const float h = d_area.getHeight();
    const float aspect = w / h;
    const float midx = w * 0.5f;
    d_viewDistance = midx / (aspect * 0.267949192431123f);

    const float nearZ = d_viewDistance * 0.5f;
    const float farZ = d_viewDistance * 2.0f;
    const float nr_sub_far = nearZ - farZ;

    Ogre::Matrix4 tmp(Ogre::Matrix4::ZERO);
    tmp[0][0] = 3.732050808f / aspect;
    tmp[0][3] = -d_viewDistance;
    tmp[1][1] = -3.732050808f;
    tmp[1][3] = d_viewDistance;
    tmp[2][2] = -((farZ + nearZ) / nr_sub_far);
    tmp[3][2] = 1.0f;
    tmp[3][3] = d_viewDistance;
    d_renderSystem._convertProjectionMatrix(tmp, d_matrix);

    d_matrixValid = true;
}

//----------------------------------------------------------------------------//
template <typename T>
void OgreRenderTarget<T>::updateViewport()
{
#ifdef CEGUI_USE_OGRE_COMPOSITOR2

#else
    if (!d_viewport)
    {
        d_viewport = OGRE_NEW Ogre::Viewport(0, d_renderTarget, 0, 0, 1, 1, 0);
        updateOgreViewportDimensions(d_renderTarget);
    }

    d_viewport->_updateDimensions();
#endif // CEGUI_USE_OGRE_COMPOSITOR2

    d_viewportValid = true;
}

//----------------------------------------------------------------------------//

} // End of  CEGUI namespace section
<commit_msg>Changes to be more consistent with #if !defined.<commit_after>/***********************************************************************
    created:    Tue Feb 17 2009
    author:     Paul D Turner
*************************************************************************/
/***************************************************************************
 *   Copyright (C) 2004 - 2013 Paul D Turner & The CEGUI Development Team
 *
 *   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 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.
 ***************************************************************************/
#include "CEGUI/RendererModules/Ogre/RenderTarget.h"
#include "CEGUI/GeometryBuffer.h"
#include "CEGUI/RenderQueue.h"
#include "CEGUI/RendererModules/Ogre/GeometryBuffer.h"

#include <OgreRenderSystem.h>
#include <OgreCamera.h>
#include <OgreViewport.h>

// Start of CEGUI namespace section
namespace CEGUI
{
//----------------------------------------------------------------------------//
template <typename T>
OgreRenderTarget<T>::OgreRenderTarget(OgreRenderer& owner,
                                      Ogre::RenderSystem& rs) :
    d_owner(owner),
    d_renderSystem(rs),
    d_area(0, 0, 0, 0),
    d_renderTarget(0),
#ifdef CEGUI_USE_OGRE_COMPOSITOR2
    d_renderTargetUpdated(false),
#else
    d_viewport(0),
    d_ogreViewportDimensions(0, 0, 0, 0),
#endif // CEGUI_USE_OGRE_COMPOSITOR2
    d_matrix(Ogre::Matrix3::ZERO),
    d_matrixValid(false),
    d_viewportValid(false),
    d_viewDistance(0)
{
}

//----------------------------------------------------------------------------//
template <typename T>
OgreRenderTarget<T>::~OgreRenderTarget()
{
#if !defined(CEGUI_USE_OGRE_COMPOSITOR2)
    delete d_viewport;
#endif // CEGUI_USE_OGRE_COMPOSITOR2
}

//----------------------------------------------------------------------------//
template <typename T>
void OgreRenderTarget<T>::draw(const GeometryBuffer& buffer)
{
    buffer.draw();
}

//----------------------------------------------------------------------------//
template <typename T>
void OgreRenderTarget<T>::draw(const RenderQueue& queue)
{
    queue.draw();
}

//----------------------------------------------------------------------------//
template <typename T>
void OgreRenderTarget<T>::setArea(const Rectf& area)
{
    d_area = area;
#if !defined(CEGUI_USE_OGRE_COMPOSITOR2)
    setOgreViewportDimensions(area);
#endif

    d_matrixValid = false;

    RenderTargetEventArgs args(this);
    T::fireEvent(RenderTarget::EventAreaChanged, args);
}

//----------------------------------------------------------------------------//
#if !defined(CEGUI_USE_OGRE_COMPOSITOR2)
template <typename T>
void OgreRenderTarget<T>::setOgreViewportDimensions(const Rectf& area)
{
    d_ogreViewportDimensions = area;

    if (d_viewport)
        updateOgreViewportDimensions(d_viewport->getTarget());

    d_viewportValid = false;
}
#endif

//----------------------------------------------------------------------------//
#if !defined(CEGUI_USE_OGRE_COMPOSITOR2)
template <typename T>
void OgreRenderTarget<T>::updateOgreViewportDimensions(
                                            const Ogre::RenderTarget* const rt)
{
    if (rt)
    {
        d_viewport->setDimensions(
            d_ogreViewportDimensions.left() / rt->getWidth(),
            d_ogreViewportDimensions.top() / rt->getHeight(),
            d_ogreViewportDimensions.getWidth() / rt->getWidth(),
            d_ogreViewportDimensions.getHeight() / rt->getHeight());
    }
}
#endif

//----------------------------------------------------------------------------//
template <typename T>
const Rectf& OgreRenderTarget<T>::getArea() const
{
    return d_area;
}

//----------------------------------------------------------------------------//
template <typename T>
void OgreRenderTarget<T>::activate()
{
    if (!d_matrixValid)
        updateMatrix();

    if (!d_viewportValid)
        updateViewport();

#if !defined(CEGUI_USE_OGRE_COMPOSITOR2)
    d_renderSystem._setViewport(d_viewport);
#endif // CEGUI_USE_OGRE_COMPOSITOR2

    d_owner.setProjectionMatrix(d_matrix);
    d_owner.setViewMatrix(Ogre::Matrix4::IDENTITY);
}

//----------------------------------------------------------------------------//
template <typename T>
void OgreRenderTarget<T>::deactivate()
{
    // currently nothing to do in the basic case
}

//----------------------------------------------------------------------------//
template <typename T>
void OgreRenderTarget<T>::unprojectPoint(const GeometryBuffer& buff,
                                      const Vector2f& p_in,
                                      Vector2f& p_out) const
{
    if (!d_matrixValid)
        updateMatrix();

    const OgreGeometryBuffer& gb = static_cast<const OgreGeometryBuffer&>(buff);

    const Ogre::Real midx = d_area.getWidth() * 0.5f;
    const Ogre::Real midy = d_area.getHeight() * 0.5f;

    // viewport matrix
    const Ogre::Matrix4 vpmat(
        midx,    0,    0,    d_area.left() + midx,
         0,    -midy,  0,    d_area.top() + midy,
         0,      0,    1,    0,
         0,      0,    0,    1
    );

    // matrices used for projecting and unprojecting points
    const Ogre::Matrix4 proj(gb.getMatrix() * d_matrix * vpmat);
    const Ogre::Matrix4 unproj(proj.inverse());

    Ogre::Vector3 in;

    // unproject the ends of the ray
    in.x = midx;
    in.y = midy;
    in.z = -d_viewDistance;
    const Ogre::Vector3 r1(unproj * in);
    in.x = p_in.d_x;
    in.y = p_in.d_y;
    in.z = 0;
    // calculate vector of picking ray
    const Ogre::Vector3 rv(r1 - unproj * in);

    // project points to orientate them with GeometryBuffer plane
    in.x = 0.0;
    in.y = 0.0;
    const Ogre::Vector3 p1(proj * in);
    in.x = 1.0;
    in.y = 0.0;
    const Ogre::Vector3 p2(proj * in);
    in.x = 0.0;
    in.y = 1.0;
    const Ogre::Vector3 p3(proj * in);

    // calculate the plane normal
    const Ogre::Vector3 pn((p2 - p1).crossProduct(p3 - p1));
    // calculate distance from origin
    const Ogre::Real plen = pn.length();
    const Ogre::Real dist = -(p1.x * (pn.x / plen) +
                              p1.y * (pn.y / plen) +
                              p1.z * (pn.z / plen));

    // calculate intersection of ray and plane
    const Ogre::Real pn_dot_rv = pn.dotProduct(rv);
    const Ogre::Real tmp = pn_dot_rv != 0.0 ?
                            (pn.dotProduct(r1) + dist) / pn_dot_rv :
                            0.0;

    p_out.d_x = static_cast<float>(r1.x - rv.x * tmp);
    p_out.d_y = static_cast<float>(r1.y - rv.y * tmp);
}

//----------------------------------------------------------------------------//
template <typename T>
void OgreRenderTarget<T>::updateMatrix() const
{
    const float w = d_area.getWidth();
    const float h = d_area.getHeight();
    const float aspect = w / h;
    const float midx = w * 0.5f;
    d_viewDistance = midx / (aspect * 0.267949192431123f);

    const float nearZ = d_viewDistance * 0.5f;
    const float farZ = d_viewDistance * 2.0f;
    const float nr_sub_far = nearZ - farZ;

    Ogre::Matrix4 tmp(Ogre::Matrix4::ZERO);
    tmp[0][0] = 3.732050808f / aspect;
    tmp[0][3] = -d_viewDistance;
    tmp[1][1] = -3.732050808f;
    tmp[1][3] = d_viewDistance;
    tmp[2][2] = -((farZ + nearZ) / nr_sub_far);
    tmp[3][2] = 1.0f;
    tmp[3][3] = d_viewDistance;
    d_renderSystem._convertProjectionMatrix(tmp, d_matrix);

    d_matrixValid = true;
}

//----------------------------------------------------------------------------//
template <typename T>
void OgreRenderTarget<T>::updateViewport()
{
#if !defined(CEGUI_USE_OGRE_COMPOSITOR2)
    if (!d_viewport)
    {
        d_viewport = OGRE_NEW Ogre::Viewport(0, d_renderTarget, 0, 0, 1, 1, 0);
        updateOgreViewportDimensions(d_renderTarget);
    }

    d_viewport->_updateDimensions();
#endif // CEGUI_USE_OGRE_COMPOSITOR2

    d_viewportValid = true;
}

//----------------------------------------------------------------------------//

} // End of  CEGUI namespace section
<|endoftext|>


<commit_before><commit_msg>INTEGRATION: CWS pchfix02 (1.53.50); FILE MERGED 2006/09/01 17:47:28 kaib 1.53.50.1: #i68856# Added header markers and pch files<commit_after><|endoftext|>


<commit_before><commit_msg>INTEGRATION: CWS pchfix02 (1.24.2); FILE MERGED 2006/09/01 17:52:50 kaib 1.24.2.1: #i68856# Added header markers and pch files<commit_after><|endoftext|>


<commit_before>#include "StringSearch.h"

StringSearch::StringSearch() {
	this->filename = "";
	this->query = "";
	this->occurences = 0;
}

StringSearch::StringSearch(string filename, string query) {
	this->filename = filename;
	this->query = query;
	this->occurences = 0;
}

void StringSearch::read() {
	this->file.open(this->filename, ios::in);
}

void StringSearch::close() {
	this->file.close();
}

void StringSearch::search() {
	this->read();
	cout << endl;
	int lineNum = 1;
	for (string line; !file.eof(); getline(this->file, line)) {
		if (line.find(this->query) != string::npos) {
			if (this->occurences == 0) {
				cout << "Lines containing the queried string:" << endl;
			}
			cout << "Line " << lineNum << ": " << line << endl;
			this->occurences++;
		}
		lineNum++;
	}
	cout << endl << "The queried string occurred: " << this->occurences << " times." << endl;
}

void StringSearch::setFilename(string filename) {
	this->filename = filename;
}

bool StringSearch::exists(string filename) {
	ifstream ifile(filename);
	if (!ifile.good()) {
		cout << endl << "File does not exist. Please try again." << endl << endl;
	}
	return ifile.good();
}

void StringSearch::setQuery(string query) {
	this->query = query;
}<commit_msg>Delete StringSearch.cpp<commit_after><|endoftext|>


<commit_before>#ifndef FXTRIG_H
#define FXTRIG_H

extern void SetGunFlash(short gun_type);
extern void TriggerRicochetSpark(struct GAME_VECTOR* hit_pos, short y_rot, int unk00, int unk01);
extern void TriggerGunShell(long x, long y, long z);
extern void DoBloodSplat(long x, long y, long z, int random, short y_rot, short room_number);
extern void TriggerUnderwaterBlood(int x, int y, int z, int sizeme);

#endif<commit_msg>Fix PSXPC compile.<commit_after>#ifndef FXTRIG_H
#define FXTRIG_H

extern void SetGunFlash(short gun_type);
extern void TriggerRicochetSpark(struct GAME_VECTOR* hit_pos, short y_rot, int unk00, int unk01);
extern void TriggerGunShell(long x, long y, long z);
extern short DoBloodSplat(long x, long y, long z, short random, short y_rot, short room_number);
extern void TriggerUnderwaterBlood(int x, int y, int z, int sizeme);

#endif<|endoftext|>


<commit_before><commit_msg>cleanup<commit_after><|endoftext|>


<commit_before><commit_msg>INTEGRATION: CWS changefileheader (1.6.10); FILE MERGED 2008/03/31 13:06:20 rt 1.6.10.1: #i87441# Change license header to LPGL v3.<commit_after><|endoftext|>


<commit_before><commit_msg>vcl button: Avoid a potential crash.<commit_after><|endoftext|>


<commit_before><commit_msg>INTEGRATION: CWS binfilter (1.71.34); FILE MERGED 2003/10/30 12:16:30 aw 1.71.34.4: RESYNC: (1.71-1.72); FILE MERGED 2003/08/19 15:46:25 aw 1.71.34.3: #110680# Give ServiceManager as const reference and do not keep it as reference locally as member 2003/07/08 17:31:38 aw 1.71.34.2: #110680# 2003/07/07 15:46:13 aw 1.71.34.1: #110680# Changed all components to use the ServiceManager they were created with.<commit_after><|endoftext|>


<commit_before>#include <MyHeaders\ListBox.h>

ListBox::ListBox()
{
	Handle = 0;
}

ListBox::ListBox(const TCHAR *title, const DWORD ID, const HWND parent, const int x, const int y, const int width, const int height, const LBStyle style, const DWORD exstyle)
{
	Create(title, ID, parent, x, y, width, height, style, exstyle);
}

ListBox::operator HWND()
{
	return Handle;
}

bool ListBox::Create(const TCHAR *title, const DWORD ID, const HWND parent, const int x, const int y, const int width, const int height, const LBStyle style, const DWORD exstyle)
{
	return (Handle = CreateWindowEx(exstyle, TEXT("listbox"), title, style.operator unsigned int() | WS_CHILD | WS_VISIBLE, x, y, width, height, parent, (HMENU)ID, GetModuleHandle(0), 0)) != 0;
}

int ListBox::AddString(const TCHAR *str)
{
	return SendMessage(Handle, LB_ADDSTRING, 0, (LPARAM)str);
}

bool ListBox::DeleteString(const int itemIndex)
{
	return SendMessage(Handle, LB_DELETESTRING, (WPARAM)itemIndex, 0) != LB_ERR;
}

int ListBox::FindString(const TCHAR *str, const int Index)
{
	return SendMessage(Handle, LB_FINDSTRING, Index, (WPARAM)str);
}

int ListBox::FindStringExact(const TCHAR *str, const int Index)
{
	return SendMessage(Handle, LB_FINDSTRINGEXACT, Index, (WPARAM)str);
}

int ListBox::GetItemCount()
{
	return SendMessage(Handle, LB_GETCOUNT, 0, 0);
}

int ListBox::GetSelectedItem()
{
	return SendMessage(Handle, LB_GETCURSEL, 0, 0);
}

int ListBox::GetSelectedItems(const int maxcount, int *list)
{
	return SendMessage(Handle, LB_GETSELITEMS, maxcount, (LPARAM)list);
}

int ListBox::GetSelectedItemCount()
{
	return SendMessage(Handle, LB_GETSELCOUNT, 0, 0);
}

bool ListBox::GetString(const int itemIndex, const char *buffer)
{
	return SendMessage(Handle, LB_GETTEXT, itemIndex, (WPARAM)buffer) != LB_ERR;
}

int ListBox::GetStringLength(const int itemIndex)
{
	return SendMessage(Handle, LB_GETTEXTLEN, itemIndex, 0);
}

bool ListBox::InsertString(const TCHAR *str, const int Index)
{
	BOOL res = SendMessage(Handle, LB_INSERTSTRING, Index, (WPARAM)str);
	return (res != LB_ERR && res != LB_ERRSPACE);
}

void ListBox::Clear()
{
	SendMessage(Handle, LB_RESETCONTENT, 0, 0);
}
int ListBox::SelectString(const TCHAR *str, const int Index)
{
	return SendMessage(Handle, LB_SELECTSTRING, Index, (WPARAM)str);
}

BOOL ListBox::sendMessage(UINT msg, LPARAM lp, WPARAM wp)
{
	return SendMessage(Handle, msg, wp, lp);
}

bool ListBox::Destroy()
{
	if (!Handle)
		return true;
	if (!DestroyWindow(Handle))
		return false;

	Handle = 0;
	return true;;
}

ListBox::~ListBox()
{
	Destroy();
}
<commit_msg>Update<commit_after>#include <MyHeaders\ListBox.h>

ListBox::ListBox()
{
	Handle = 0;
}

ListBox::ListBox(const TCHAR *title, const DWORD ID, const HWND parent, const int x, const int y, const int width, const int height, const LBStyle style, const DWORD exstyle)
{
	Create(title, ID, parent, x, y, width, height, style, exstyle);
}

ListBox::operator HWND()
{
	return Handle;
}

bool ListBox::Create(const TCHAR *title, const DWORD ID, const HWND parent, const int x, const int y, const int width, const int height, const LBStyle style, const DWORD exstyle)
{
	return (Handle = CreateWindowEx(exstyle, TEXT("listbox"), title, style.operator unsigned int() | WS_CHILD, x, y, width, height, parent, (HMENU)ID, GetModuleHandle(0), 0)) != 0;
}

int ListBox::AddString(const TCHAR *str)
{
	return SendMessage(Handle, LB_ADDSTRING, 0, (LPARAM)str);
}

bool ListBox::DeleteString(const int itemIndex)
{
	return SendMessage(Handle, LB_DELETESTRING, (WPARAM)itemIndex, 0) != LB_ERR;
}

int ListBox::FindString(const TCHAR *str, const int Index)
{
	return SendMessage(Handle, LB_FINDSTRING, Index, (WPARAM)str);
}

int ListBox::FindStringExact(const TCHAR *str, const int Index)
{
	return SendMessage(Handle, LB_FINDSTRINGEXACT, Index, (WPARAM)str);
}

int ListBox::GetItemCount()
{
	return SendMessage(Handle, LB_GETCOUNT, 0, 0);
}

int ListBox::GetSelectedItem()
{
	return SendMessage(Handle, LB_GETCURSEL, 0, 0);
}

int ListBox::GetSelectedItems(const int maxcount, int *list)
{
	return SendMessage(Handle, LB_GETSELITEMS, maxcount, (LPARAM)list);
}

int ListBox::GetSelectedItemCount()
{
	return SendMessage(Handle, LB_GETSELCOUNT, 0, 0);
}

bool ListBox::GetString(const int itemIndex, const char *buffer)
{
	return SendMessage(Handle, LB_GETTEXT, itemIndex, (WPARAM)buffer) != LB_ERR;
}

int ListBox::GetStringLength(const int itemIndex)
{
	return SendMessage(Handle, LB_GETTEXTLEN, itemIndex, 0);
}

bool ListBox::InsertString(const TCHAR *str, const int Index)
{
	BOOL res = SendMessage(Handle, LB_INSERTSTRING, Index, (WPARAM)str);
	return (res != LB_ERR && res != LB_ERRSPACE);
}

void ListBox::Clear()
{
	SendMessage(Handle, LB_RESETCONTENT, 0, 0);
}
int ListBox::SelectString(const TCHAR *str, const int Index)
{
	return SendMessage(Handle, LB_SELECTSTRING, Index, (WPARAM)str);
}

BOOL ListBox::sendMessage(UINT msg, LPARAM lp, WPARAM wp)
{
	return SendMessage(Handle, msg, wp, lp);
}

bool ListBox::Destroy()
{
	if (!Handle)
		return true;
	if (!DestroyWindow(Handle))
		return false;

	Handle = 0;
	return true;;
}

ListBox::~ListBox()
{
	Destroy();
}
<|endoftext|>


<commit_before>#include "operator_maps.hpp"

namespace lang {
  Variable* resolveNameFrom(ASTNode* localNode, std::string identifier) {
    if (localNode == nullptr) return nullptr; // Reached tree root and didn't find anything.
    try {
      return localNode->getScope()->at(identifier);
    } catch(std::out_of_range& oor) {
      return resolveNameFrom(localNode->getParent(), identifier);
    }
  }

  void concatenateNames(std::string& result, ExpressionChildNode* operatorNode) {
    result.pop_back(); // Remove trailing space
  }

  template<typename... Args>
  void concatenateNames(std::string& result, ExpressionChildNode* operatorNode, Object*& obj, Args&... args) {
    if (obj == nullptr) throw Error("Object has not been defined", "NullPointerError", operatorNode->getLineNumber());
    while (obj->getTypeData() == "Variable") {
      obj = dynamic_cast<Variable*>(obj)->read();
      if (obj == nullptr) throw Error("Variable is empty or has not been defined", "NullPointerError", operatorNode->getLineNumber());
    }
    result += obj->getTypeData() + " ";
    concatenateNames(result, operatorNode, args...);
  }

  template<typename... Args>
  Object* runOperator(ExpressionChildNode* operatorNode, Args... operands) {
    Operator* op = static_cast<Operator*>(operatorNode->t.typeData);
    std::string funSig = "";
    if (op->toString().back() == '=' && op->getPrecedence() == 1) funSig = "Variable Object"; // Intercepts all assignments
    else if (op->toString() == "++" || op->toString() == "--") funSig = "Variable";
    else concatenateNames(funSig, operatorNode, operands...);
    // 1. Get a boost::any instance from the OperatorMap
    // 2. Use boost::any_cast to get a pointer to the operator function
    // 3. Dereference pointer and call function
    try {
      auto result = (*boost::any_cast<std::function<Object*(Args...)>*>(opsMap[*op][funSig]))(operands...);
      return result;
    } catch (boost::bad_any_cast& bac) {
      throw Error("Cannot find operation for '" + op->toString() + "' and operands '" + funSig + "'", "NullPointerError", operatorNode->getLineNumber());
    }
  }

  template<typename... Args>
  Object* runOperator(Operator op, Args... operands) {
    return runOperator(new ExpressionChildNode(Token(&op, OPERATOR, PHONY_TOKEN)), operands...);
  }

  Object* fromExprChildNode(ASTNode* node) {
    return static_cast<Object*>(dynamic_cast<ExpressionChildNode*>(node)->t.typeData);
  }

  Object* runOperator(ExpressionChildNode* operatorNode) {
    auto arity = static_cast<Operator*>(operatorNode->t.typeData)->getArity();
    std::vector<Object*> operands {};
    auto operandCount = operatorNode->getChildren().size();
    for (std::size_t i = operandCount; i != 0; i--) {
      Object* operand;
      ExpressionChildNode* operandNode = dynamic_cast<ExpressionChildNode*>(operatorNode->getChildren()[i - 1]);
      if (operandNode->t.type == VARIABLE) {
        operand = resolveNameFrom(operandNode, operandNode->t.data);
      }
      else operand = fromExprChildNode(operandNode);
      if (operand == nullptr) throw std::runtime_error("Attempt to call operator " + operatorNode->t.data + " with operand " + std::to_string(operandCount - i) + " set to nullptr.");
      operands.push_back(operand);
    }

    if (arity == UNARY) return runOperator(operatorNode, operands[0]);
    else if (arity == BINARY) return runOperator(operatorNode, operands[0], operands[1]);
    else if (arity == TERNARY) return runOperator(operatorNode, operands[0], operands[1], operands[2]);
    else throw std::runtime_error("Attempt to call operator with more than 3 operands(" + std::to_string(arity) + ")");
  }

  // TODO: some operators that affect variables do not change the value of the variable, eg `++i`
  OperatorMap opsMap = {
    // Plain assignment
    {Operator("=", 1, ASSOCIATE_FROM_RIGHT, BINARY), {
      {"Variable Object", boost::any(new Object::BinaryOp([](Object* l, Object* r) {
        auto left = dynamic_cast<Variable*>(l);
        left->assign(r);
        return r;
      }))}
    }},
    // Assignment with extra operation
    MAKE_ASSIGNMENT_OP(+, 10),
    MAKE_ASSIGNMENT_OP(-, 10),
    MAKE_ASSIGNMENT_OP(*, 11),
    MAKE_ASSIGNMENT_OP(/, 11),
    MAKE_ASSIGNMENT_OP(%, 11),
    MAKE_ASSIGNMENT_OP(<<, 9),
    MAKE_ASSIGNMENT_OP(>>, 9),
    MAKE_ASSIGNMENT_OP(&, 6),
    MAKE_ASSIGNMENT_OP(^, 5),
    MAKE_ASSIGNMENT_OP(|, 4),
    // Comparison operators
    {Operator("<=", 8), {
      EXPAND_COMPARISON_OPS(<=)
    }},
    {Operator("<", 8), {
      EXPAND_COMPARISON_OPS(<)
    }},
    {Operator(">=", 8), {
      EXPAND_COMPARISON_OPS(>=)
    }},
    {Operator(">", 8), {
      EXPAND_COMPARISON_OPS(>)
    }},
    {Operator("==", 7), {
      EXPAND_COMPARISON_OPS(==),
      {MAKE_BINARY_OP(String, String, new Boolean(left->toString() == right->toString()) )},
      {MAKE_BINARY_OP(Boolean, Boolean, new Boolean(left->value() == right->value()) )}
    }},
    {Operator("!=", 7), {
      EXPAND_COMPARISON_OPS(!=),
      {MAKE_BINARY_OP(String, String, new Boolean(left->toString() != right->toString()) )},
      {MAKE_BINARY_OP(Boolean, Boolean, new Boolean(left->value() != right->value()) )}
    }},
    // Arithmetic operators
    {Operator("+", 10), {
      {MAKE_BINARY_OP(String, String, new String(left->toString() + right->toString()) )}, // String concatenation
      EXPAND_NUMERIC_OPS(+)
    }},
    {Operator("-", 10), {
      EXPAND_NUMERIC_OPS(-)
    }},
    {Operator("*", 11), {
      EXPAND_NUMERIC_OPS(*)
    }},
    {Operator("/", 11), {
      EXPAND_NUMERIC_OPS(/)
    }},
    {Operator("%", 11), {
      {MAKE_BINARY_OP(Integer, Integer, new Integer(left->getNumber() % right->getNumber()) )}
    }},
    // Bitwise operators
    {Operator(">>", 9), {
      {MAKE_BINARY_OP(Integer, Integer, new Integer(left->getNumber() >> right->getNumber()) )}
    }},
    {Operator("<<", 9), {
      {MAKE_BINARY_OP(Integer, Integer, new Integer(left->getNumber() << right->getNumber()) )}
    }},
    {Operator("&", 6), {
      {MAKE_BINARY_OP(Integer, Integer, new Integer(left->getNumber() & right->getNumber()) )}
    }},
    {Operator("^", 5), {
      {MAKE_BINARY_OP(Integer, Integer, new Integer(left->getNumber() ^ right->getNumber()) )}
    }},
    {Operator("|", 4), {
      {MAKE_BINARY_OP(Integer, Integer, new Integer(left->getNumber() | right->getNumber()) )}
    }},
    {Operator("~", 12, ASSOCIATE_FROM_RIGHT, UNARY), {
      {MAKE_UNARY_OP(Integer, new Integer(~operand->getNumber()) )}
    }},
    // Logical operators
    {Operator("!", 12, ASSOCIATE_FROM_RIGHT, UNARY), {
      {MAKE_UNARY_OP(Boolean, new Boolean(!operand->value()) )},
      {MAKE_UNARY_OP(Integer, new Boolean(!operand->getNumber()) )}
    }},
    {Operator("&&", 3), {
      {MAKE_BINARY_OP(Boolean, Boolean, new Boolean(left->value() && right->value()) )},
      {MAKE_BINARY_OP(Integer, Boolean, new Boolean(left->getNumber() && right->value()) )},
      {MAKE_BINARY_OP(Boolean, Integer, new Boolean(left->value() && right->getNumber()) )},
      {MAKE_BINARY_OP(Integer, Integer, new Boolean(left->getNumber() && right->getNumber()) )}
    }},
    {Operator("||", 2), {
      {MAKE_BINARY_OP(Boolean, Boolean, new Boolean(left->value() || right->value()) )},
      {MAKE_BINARY_OP(Integer, Boolean, new Boolean(left->getNumber() || right->value()) )},
      {MAKE_BINARY_OP(Boolean, Integer, new Boolean(left->value() || right->getNumber()) )},
      {MAKE_BINARY_OP(Integer, Integer, new Boolean(left->getNumber() || right->getNumber()) )}
    }},
    // Signum operators
    {Operator("+", 12, ASSOCIATE_FROM_RIGHT, UNARY), {
      {MAKE_UNARY_OP(Integer, new Integer(+operand->getNumber()) )},
      {MAKE_UNARY_OP(Float, new Float(+operand->getNumber()) )}
    }},
    {Operator("-", 12, ASSOCIATE_FROM_RIGHT, UNARY), {
      {MAKE_UNARY_OP(Integer, new Integer(-operand->getNumber()) )},
      {MAKE_UNARY_OP(Float, new Float(-operand->getNumber()) )}
    }},
    // Prefix operators
    {MAKE_MUTATING_UNARY_OP(Operator("++", 12, ASSOCIATE_FROM_RIGHT, UNARY), +, true)},
    {MAKE_MUTATING_UNARY_OP(Operator("--", 12, ASSOCIATE_FROM_RIGHT, UNARY), -, true)},
    // Postfix operators
    {MAKE_MUTATING_UNARY_OP(Operator("++", 13, ASSOCIATE_FROM_LEFT, UNARY), +, false)},
    {MAKE_MUTATING_UNARY_OP(Operator("--", 13, ASSOCIATE_FROM_LEFT, UNARY), -, false)}
    // TODO: member access op
    // TODO: maybe comma op
  };
} /* namespace lang */<commit_msg>Removed old TODO<commit_after>#include "operator_maps.hpp"

namespace lang {
  Variable* resolveNameFrom(ASTNode* localNode, std::string identifier) {
    if (localNode == nullptr) return nullptr; // Reached tree root and didn't find anything.
    try {
      return localNode->getScope()->at(identifier);
    } catch(std::out_of_range& oor) {
      return resolveNameFrom(localNode->getParent(), identifier);
    }
  }

  void concatenateNames(std::string& result, ExpressionChildNode* operatorNode) {
    result.pop_back(); // Remove trailing space
  }

  template<typename... Args>
  void concatenateNames(std::string& result, ExpressionChildNode* operatorNode, Object*& obj, Args&... args) {
    if (obj == nullptr) throw Error("Object has not been defined", "NullPointerError", operatorNode->getLineNumber());
    while (obj->getTypeData() == "Variable") {
      obj = dynamic_cast<Variable*>(obj)->read();
      if (obj == nullptr) throw Error("Variable is empty or has not been defined", "NullPointerError", operatorNode->getLineNumber());
    }
    result += obj->getTypeData() + " ";
    concatenateNames(result, operatorNode, args...);
  }

  template<typename... Args>
  Object* runOperator(ExpressionChildNode* operatorNode, Args... operands) {
    Operator* op = static_cast<Operator*>(operatorNode->t.typeData);
    std::string funSig = "";
    if (op->toString().back() == '=' && op->getPrecedence() == 1) funSig = "Variable Object"; // Intercepts all assignments
    else if (op->toString() == "++" || op->toString() == "--") funSig = "Variable";
    else concatenateNames(funSig, operatorNode, operands...);
    // 1. Get a boost::any instance from the OperatorMap
    // 2. Use boost::any_cast to get a pointer to the operator function
    // 3. Dereference pointer and call function
    try {
      auto result = (*boost::any_cast<std::function<Object*(Args...)>*>(opsMap[*op][funSig]))(operands...);
      return result;
    } catch (boost::bad_any_cast& bac) {
      throw Error("Cannot find operation for '" + op->toString() + "' and operands '" + funSig + "'", "NullPointerError", operatorNode->getLineNumber());
    }
  }

  template<typename... Args>
  Object* runOperator(Operator op, Args... operands) {
    return runOperator(new ExpressionChildNode(Token(&op, OPERATOR, PHONY_TOKEN)), operands...);
  }

  Object* fromExprChildNode(ASTNode* node) {
    return static_cast<Object*>(dynamic_cast<ExpressionChildNode*>(node)->t.typeData);
  }

  Object* runOperator(ExpressionChildNode* operatorNode) {
    auto arity = static_cast<Operator*>(operatorNode->t.typeData)->getArity();
    std::vector<Object*> operands {};
    auto operandCount = operatorNode->getChildren().size();
    for (std::size_t i = operandCount; i != 0; i--) {
      Object* operand;
      ExpressionChildNode* operandNode = dynamic_cast<ExpressionChildNode*>(operatorNode->getChildren()[i - 1]);
      if (operandNode->t.type == VARIABLE) {
        operand = resolveNameFrom(operandNode, operandNode->t.data);
      }
      else operand = fromExprChildNode(operandNode);
      if (operand == nullptr) throw std::runtime_error("Attempt to call operator " + operatorNode->t.data + " with operand " + std::to_string(operandCount - i) + " set to nullptr.");
      operands.push_back(operand);
    }

    if (arity == UNARY) return runOperator(operatorNode, operands[0]);
    else if (arity == BINARY) return runOperator(operatorNode, operands[0], operands[1]);
    else if (arity == TERNARY) return runOperator(operatorNode, operands[0], operands[1], operands[2]);
    else throw std::runtime_error("Attempt to call operator with more than 3 operands(" + std::to_string(arity) + ")");
  }

  OperatorMap opsMap = {
    // Plain assignment
    {Operator("=", 1, ASSOCIATE_FROM_RIGHT, BINARY), {
      {"Variable Object", boost::any(new Object::BinaryOp([](Object* l, Object* r) {
        auto left = dynamic_cast<Variable*>(l);
        left->assign(r);
        return r;
      }))}
    }},
    // Assignment with extra operation
    MAKE_ASSIGNMENT_OP(+, 10),
    MAKE_ASSIGNMENT_OP(-, 10),
    MAKE_ASSIGNMENT_OP(*, 11),
    MAKE_ASSIGNMENT_OP(/, 11),
    MAKE_ASSIGNMENT_OP(%, 11),
    MAKE_ASSIGNMENT_OP(<<, 9),
    MAKE_ASSIGNMENT_OP(>>, 9),
    MAKE_ASSIGNMENT_OP(&, 6),
    MAKE_ASSIGNMENT_OP(^, 5),
    MAKE_ASSIGNMENT_OP(|, 4),
    // Comparison operators
    {Operator("<=", 8), {
      EXPAND_COMPARISON_OPS(<=)
    }},
    {Operator("<", 8), {
      EXPAND_COMPARISON_OPS(<)
    }},
    {Operator(">=", 8), {
      EXPAND_COMPARISON_OPS(>=)
    }},
    {Operator(">", 8), {
      EXPAND_COMPARISON_OPS(>)
    }},
    {Operator("==", 7), {
      EXPAND_COMPARISON_OPS(==),
      {MAKE_BINARY_OP(String, String, new Boolean(left->toString() == right->toString()) )},
      {MAKE_BINARY_OP(Boolean, Boolean, new Boolean(left->value() == right->value()) )}
    }},
    {Operator("!=", 7), {
      EXPAND_COMPARISON_OPS(!=),
      {MAKE_BINARY_OP(String, String, new Boolean(left->toString() != right->toString()) )},
      {MAKE_BINARY_OP(Boolean, Boolean, new Boolean(left->value() != right->value()) )}
    }},
    // Arithmetic operators
    {Operator("+", 10), {
      {MAKE_BINARY_OP(String, String, new String(left->toString() + right->toString()) )}, // String concatenation
      EXPAND_NUMERIC_OPS(+)
    }},
    {Operator("-", 10), {
      EXPAND_NUMERIC_OPS(-)
    }},
    {Operator("*", 11), {
      EXPAND_NUMERIC_OPS(*)
    }},
    {Operator("/", 11), {
      EXPAND_NUMERIC_OPS(/)
    }},
    {Operator("%", 11), {
      {MAKE_BINARY_OP(Integer, Integer, new Integer(left->getNumber() % right->getNumber()) )}
    }},
    // Bitwise operators
    {Operator(">>", 9), {
      {MAKE_BINARY_OP(Integer, Integer, new Integer(left->getNumber() >> right->getNumber()) )}
    }},
    {Operator("<<", 9), {
      {MAKE_BINARY_OP(Integer, Integer, new Integer(left->getNumber() << right->getNumber()) )}
    }},
    {Operator("&", 6), {
      {MAKE_BINARY_OP(Integer, Integer, new Integer(left->getNumber() & right->getNumber()) )}
    }},
    {Operator("^", 5), {
      {MAKE_BINARY_OP(Integer, Integer, new Integer(left->getNumber() ^ right->getNumber()) )}
    }},
    {Operator("|", 4), {
      {MAKE_BINARY_OP(Integer, Integer, new Integer(left->getNumber() | right->getNumber()) )}
    }},
    {Operator("~", 12, ASSOCIATE_FROM_RIGHT, UNARY), {
      {MAKE_UNARY_OP(Integer, new Integer(~operand->getNumber()) )}
    }},
    // Logical operators
    {Operator("!", 12, ASSOCIATE_FROM_RIGHT, UNARY), {
      {MAKE_UNARY_OP(Boolean, new Boolean(!operand->value()) )},
      {MAKE_UNARY_OP(Integer, new Boolean(!operand->getNumber()) )}
    }},
    {Operator("&&", 3), {
      {MAKE_BINARY_OP(Boolean, Boolean, new Boolean(left->value() && right->value()) )},
      {MAKE_BINARY_OP(Integer, Boolean, new Boolean(left->getNumber() && right->value()) )},
      {MAKE_BINARY_OP(Boolean, Integer, new Boolean(left->value() && right->getNumber()) )},
      {MAKE_BINARY_OP(Integer, Integer, new Boolean(left->getNumber() && right->getNumber()) )}
    }},
    {Operator("||", 2), {
      {MAKE_BINARY_OP(Boolean, Boolean, new Boolean(left->value() || right->value()) )},
      {MAKE_BINARY_OP(Integer, Boolean, new Boolean(left->getNumber() || right->value()) )},
      {MAKE_BINARY_OP(Boolean, Integer, new Boolean(left->value() || right->getNumber()) )},
      {MAKE_BINARY_OP(Integer, Integer, new Boolean(left->getNumber() || right->getNumber()) )}
    }},
    // Signum operators
    {Operator("+", 12, ASSOCIATE_FROM_RIGHT, UNARY), {
      {MAKE_UNARY_OP(Integer, new Integer(+operand->getNumber()) )},
      {MAKE_UNARY_OP(Float, new Float(+operand->getNumber()) )}
    }},
    {Operator("-", 12, ASSOCIATE_FROM_RIGHT, UNARY), {
      {MAKE_UNARY_OP(Integer, new Integer(-operand->getNumber()) )},
      {MAKE_UNARY_OP(Float, new Float(-operand->getNumber()) )}
    }},
    // Prefix operators
    {MAKE_MUTATING_UNARY_OP(Operator("++", 12, ASSOCIATE_FROM_RIGHT, UNARY), +, true)},
    {MAKE_MUTATING_UNARY_OP(Operator("--", 12, ASSOCIATE_FROM_RIGHT, UNARY), -, true)},
    // Postfix operators
    {MAKE_MUTATING_UNARY_OP(Operator("++", 13, ASSOCIATE_FROM_LEFT, UNARY), +, false)},
    {MAKE_MUTATING_UNARY_OP(Operator("--", 13, ASSOCIATE_FROM_LEFT, UNARY), -, false)}
    // TODO: member access op
    // TODO: maybe comma op
  };
} /* namespace lang */<|endoftext|>