<commit_before>#include <QDebug>
#include "tangramwidget.h"

#include <tangram.h>
#include <curl/curl.h>
#include <cstdlib>
#include <QOpenGLContext>
#include <QOpenGLFunctions>
#include "platform_qt.h"
#include <GL/gl.h>
#include <GL/glx.h>
#include <QRunnable>

PFNGLBINDVERTEXARRAYPROC glBindVertexArrayOESEXT = 0;
PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArraysOESEXT = 0;
PFNGLGENVERTEXARRAYSPROC glGenVertexArraysOESEXT = 0;

TangramWidget::TangramWidget(QWidget *parent)
    : QOpenGLWidget(parent)
    , m_sceneFile("scene.yaml")
    , m_lastMousePos(-1, -1)
{
    // Initialize cURL
    curl_global_init(CURL_GLOBAL_DEFAULT);

    grabGesture(Qt::PanGesture);
}

TangramWidget::~TangramWidget()
{
    curl_global_cleanup();
}

void TangramWidget::initializeGL()
{
    qDebug() << Q_FUNC_INFO << ".--------------";
    glBindVertexArrayOESEXT = (PFNGLBINDVERTEXARRAYPROC)context()->getProcAddress("glBindVertexArray");
    glDeleteVertexArraysOESEXT = (PFNGLDELETEVERTEXARRAYSPROC)context()->getProcAddress("glDeleteVertexArrays");
    glGenVertexArraysOESEXT = (PFNGLGENVERTEXARRAYSPROC)context()->getProcAddress("glGenVertexArrays");

    qDebug() << Q_FUNC_INFO << glBindVertexArrayOESEXT << glDeleteVertexArraysOESEXT << glGenVertexArraysOESEXT;
    QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
    qDebug() << "Version:" << f->glGetString(GL_VERSION);
    f->glClearColor(1.0f, 1.0f, 1.0f, 1.0f);

    Tangram::initialize(m_sceneFile.fileName().toStdString().c_str());
    Tangram::setupGL();
    Tangram::resize(width(),
                    height());

    data_source = std::make_shared<Tangram::ClientGeoJsonSource>("touch", "");
    Tangram::addDataSource(data_source);
}

void TangramWidget::paintGL()
{
    QDateTime now = QDateTime::currentDateTime();
    Tangram::update(1.f);
    Tangram::render();
    m_lastRendering = now;
}

void TangramWidget::resizeGL(int w, int h)
{
    Tangram::resize(w,
                    h);
}

void TangramWidget::mousePressEvent(QMouseEvent *event)
{
    Tangram::handlePanGesture(0.0f, 0.0f, 0.0f, 0.0f);
    m_lastMousePos = event->pos();
}

void TangramWidget::mouseMoveEvent(QMouseEvent *event)
{
    Tangram::handlePanGesture(m_lastMousePos.x(), m_lastMousePos.y(),
                              event->x(), event->y());
    m_lastMousePos = event->pos();
}

void TangramWidget::grabGestures(const QList<Qt::GestureType> &gestures)
{
    foreach (Qt::GestureType gesture, gestures)
        grabGesture(gesture);
}

bool TangramWidget::event(QEvent *e)
{
    if (e->type() == QEvent::Gesture)
        return gestureEvent(static_cast<QGestureEvent*>(e));
    else if (e->type() == QEvent::Wheel)
        return mouseWheelEvent(static_cast<QWheelEvent*>(e));
    else if (e->type() == TANGRAM_REQ_RENDER_EVENT_TYPE)
        return renderRequestEvent();
    return QWidget::event(e);
}

bool TangramWidget::renderRequestEvent()
{
    qDebug() << Q_FUNC_INFO;
    processNetworkQueue();
    update();
    return true;
}

bool TangramWidget::mouseWheelEvent(QWheelEvent *ev)
{
}

bool TangramWidget::gestureEvent(QGestureEvent *ev)
{
    if (QGesture *swipe = ev->gesture(Qt::SwipeGesture))
        swipeTriggered(static_cast<QSwipeGesture*>(swipe));
    else if (QGesture *pan = ev->gesture(Qt::PanGesture))
        panTriggered(static_cast<QPanGesture *>(pan));
    if (QGesture *pinch = ev->gesture(Qt::PinchGesture))
        pinchTriggered(static_cast<QPinchGesture *>(pinch));
    return true;
}

void TangramWidget::panTriggered(QPanGesture *gesture)
{
#ifndef QT_NO_CURSOR
    switch (gesture->state()) {
        case Qt::GestureStarted:
        case Qt::GestureUpdated:
            setCursor(Qt::SizeAllCursor);
            break;
        default:
            setCursor(Qt::ArrowCursor);
    }
#endif
    QPointF delta = gesture->delta();
    qDebug() << "panTriggered():" << gesture;
    horizontalOffset += delta.x();
    verticalOffset += delta.y();
    update();
}

void TangramWidget::pinchTriggered(QPinchGesture *gesture)
{
    QPinchGesture::ChangeFlags changeFlags = gesture->changeFlags();
    if (changeFlags & QPinchGesture::RotationAngleChanged) {
        qreal rotationDelta = gesture->rotationAngle() - gesture->lastRotationAngle();
        rotationAngle += rotationDelta;
        qDebug() << "pinchTriggered(): rotate by" <<
            rotationDelta << "->" << rotationAngle;
    }
    if (changeFlags & QPinchGesture::ScaleFactorChanged) {
        currentStepScaleFactor = gesture->totalScaleFactor();
        qDebug() << "pinchTriggered(): zoom by" <<
            gesture->scaleFactor() << "->" << currentStepScaleFactor;
    }
    if (gesture->state() == Qt::GestureFinished) {
        scaleFactor *= currentStepScaleFactor;
        currentStepScaleFactor = 1;
    }
    update();
}

void TangramWidget::swipeTriggered(QSwipeGesture *gesture)
{
    if (gesture->state() == Qt::GestureFinished) {
        if (gesture->horizontalDirection() == QSwipeGesture::Left
            || gesture->verticalDirection() == QSwipeGesture::Up) {
            qDebug() << "swipeTriggered(): swipe to previous";
        } else {
            qDebug() << "swipeTriggered(): swipe to next";
        }
        update();
    }
}

class UrlRunner : public QRunnable
{
public:
    UrlRunner(QUrl url, UrlCallback callback) {
        m_url = url;
        m_callback = callback;
    }

    void run() {

    }

private:
    QUrl m_url;
    UrlCallback m_callback;
};

void TangramWidget::startUrlRequest(const std::__cxx11::string &url, UrlCallback callback)
{

}

void TangramWidget::cancelUrlRequest(const std::__cxx11::string &url)
{

}

void TangramWidget::handleCallback(UrlCallback callback)
{

}
<commit_msg>Add rotate, shov and zoom to scroll wheel events.<commit_after>#include <QDebug>
#include "tangramwidget.h"

#include <tangram.h>
#include <curl/curl.h>
#include <cstdlib>
#include <QOpenGLContext>
#include <QOpenGLFunctions>
#include "platform_qt.h"
#include <GL/gl.h>
#include <GL/glx.h>
#include <QRunnable>

PFNGLBINDVERTEXARRAYPROC glBindVertexArrayOESEXT = 0;
PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArraysOESEXT = 0;
PFNGLGENVERTEXARRAYSPROC glGenVertexArraysOESEXT = 0;

TangramWidget::TangramWidget(QWidget *parent)
    : QOpenGLWidget(parent)
    , m_sceneFile("scene.yaml")
    , m_lastMousePos(-1, -1)
{
    // Initialize cURL
    curl_global_init(CURL_GLOBAL_DEFAULT);

    grabGesture(Qt::PanGesture);
}

TangramWidget::~TangramWidget()
{
    curl_global_cleanup();
}

void TangramWidget::initializeGL()
{
    qDebug() << Q_FUNC_INFO << ".--------------";
    glBindVertexArrayOESEXT = (PFNGLBINDVERTEXARRAYPROC)context()->getProcAddress("glBindVertexArray");
    glDeleteVertexArraysOESEXT = (PFNGLDELETEVERTEXARRAYSPROC)context()->getProcAddress("glDeleteVertexArrays");
    glGenVertexArraysOESEXT = (PFNGLGENVERTEXARRAYSPROC)context()->getProcAddress("glGenVertexArrays");

    qDebug() << Q_FUNC_INFO << glBindVertexArrayOESEXT << glDeleteVertexArraysOESEXT << glGenVertexArraysOESEXT;
    QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
    qDebug() << "Version:" << f->glGetString(GL_VERSION);
    f->glClearColor(1.0f, 1.0f, 1.0f, 1.0f);

    Tangram::initialize(m_sceneFile.fileName().toStdString().c_str());
    Tangram::setupGL();
    Tangram::resize(width(),
                    height());

    data_source = std::make_shared<Tangram::ClientGeoJsonSource>("touch", "");
    Tangram::addDataSource(data_source);
}

void TangramWidget::paintGL()
{
    QDateTime now = QDateTime::currentDateTime();
    Tangram::update(1.f);
    Tangram::render();
    m_lastRendering = now;
}

void TangramWidget::resizeGL(int w, int h)
{
    Tangram::resize(w,
                    h);
}

void TangramWidget::mousePressEvent(QMouseEvent *event)
{
    Tangram::handlePanGesture(0.0f, 0.0f, 0.0f, 0.0f);
    m_lastMousePos = event->pos();
}

void TangramWidget::mouseMoveEvent(QMouseEvent *event)
{
    Tangram::handlePanGesture(m_lastMousePos.x(), m_lastMousePos.y(),
                              event->x(), event->y());
    m_lastMousePos = event->pos();
}

void TangramWidget::grabGestures(const QList<Qt::GestureType> &gestures)
{
    foreach (Qt::GestureType gesture, gestures)
        grabGesture(gesture);
}

bool TangramWidget::event(QEvent *e)
{
    if (e->type() == QEvent::Gesture)
        return gestureEvent(static_cast<QGestureEvent*>(e));
    else if (e->type() == QEvent::Wheel)
        return mouseWheelEvent(static_cast<QWheelEvent*>(e));
    else if (e->type() == TANGRAM_REQ_RENDER_EVENT_TYPE)
        return renderRequestEvent();
    return QWidget::event(e);
}

bool TangramWidget::renderRequestEvent()
{
    processNetworkQueue();
    update();
    return true;
}

bool TangramWidget::mouseWheelEvent(QWheelEvent *ev)
{
    double x = ev->posF().x();
    double y = ev->posF().y();

    if (ev->modifiers() & Qt::ControlModifier)
        Tangram::handleShoveGesture(0.05 * ev->angleDelta().y());
    else if (ev->modifiers() & Qt::AltModifier) {
        Tangram::handleRotateGesture(x, y, 0.0005 * ev->angleDelta().y());
    } else
        Tangram::handlePinchGesture(x, y, 1.0 + 0.0005 * ev->angleDelta().y(), 0.f);
}

bool TangramWidget::gestureEvent(QGestureEvent *ev)
{
    if (QGesture *swipe = ev->gesture(Qt::SwipeGesture))
        swipeTriggered(static_cast<QSwipeGesture*>(swipe));
    else if (QGesture *pan = ev->gesture(Qt::PanGesture))
        panTriggered(static_cast<QPanGesture *>(pan));
    if (QGesture *pinch = ev->gesture(Qt::PinchGesture))
        pinchTriggered(static_cast<QPinchGesture *>(pinch));
    return true;
}

void TangramWidget::panTriggered(QPanGesture *gesture)
{
#ifndef QT_NO_CURSOR
    switch (gesture->state()) {
        case Qt::GestureStarted:
        case Qt::GestureUpdated:
            setCursor(Qt::SizeAllCursor);
            break;
        default:
            setCursor(Qt::ArrowCursor);
    }
#endif
    QPointF delta = gesture->delta();
    qDebug() << "panTriggered():" << gesture;
    horizontalOffset += delta.x();
    verticalOffset += delta.y();
    update();
}

void TangramWidget::pinchTriggered(QPinchGesture *gesture)
{
    QPinchGesture::ChangeFlags changeFlags = gesture->changeFlags();
    if (changeFlags & QPinchGesture::RotationAngleChanged) {
        qreal rotationDelta = gesture->rotationAngle() - gesture->lastRotationAngle();
        rotationAngle += rotationDelta;
        qDebug() << "pinchTriggered(): rotate by" <<
            rotationDelta << "->" << rotationAngle;
    }
    if (changeFlags & QPinchGesture::ScaleFactorChanged) {
        currentStepScaleFactor = gesture->totalScaleFactor();
        qDebug() << "pinchTriggered(): zoom by" <<
            gesture->scaleFactor() << "->" << currentStepScaleFactor;
    }
    if (gesture->state() == Qt::GestureFinished) {
        scaleFactor *= currentStepScaleFactor;
        currentStepScaleFactor = 1;
    }
    update();
}

void TangramWidget::swipeTriggered(QSwipeGesture *gesture)
{
    if (gesture->state() == Qt::GestureFinished) {
        if (gesture->horizontalDirection() == QSwipeGesture::Left
            || gesture->verticalDirection() == QSwipeGesture::Up) {
            qDebug() << "swipeTriggered(): swipe to previous";
        } else {
            qDebug() << "swipeTriggered(): swipe to next";
        }
        update();
    }
}

class UrlRunner : public QRunnable
{
public:
    UrlRunner(QUrl url, UrlCallback callback) {
        m_url = url;
        m_callback = callback;
    }

    void run() {

    }

private:
    QUrl m_url;
    UrlCallback m_callback;
};

void TangramWidget::startUrlRequest(const std::__cxx11::string &url, UrlCallback callback)
{

}

void TangramWidget::cancelUrlRequest(const std::__cxx11::string &url)
{

}

void TangramWidget::handleCallback(UrlCallback callback)
{

}
<|endoftext|>


<commit_before>//******************************************************************************************************
//  CompactMeasurementParser.cpp - Gbtc
//
//  Copyright  2018, Grid Protection Alliance.  All Rights Reserved.
//
//  Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
//  the NOTICE file distributed with this work for additional information regarding copyright ownership.
//  The GPA licenses this file to you under the MIT License (MIT), the "License"; you may not use this
//  file except in compliance with the License. You may obtain a copy of the License at:
//
//      http://opensource.org/licenses/MIT
//
//  Unless agreed to in writing, the subject software distributed under the License is distributed on an
//  "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
//  License for the specific language governing permissions and limitations.
//
//  Code Modification History:
//  ----------------------------------------------------------------------------------------------------
//  03/09/2012 - Stephen C. Wills
//       Generated original version of source code.
//
//******************************************************************************************************

#include "CompactMeasurement.h"
#include "../Common/EndianConverter.h"

using namespace std;
using namespace GSF::TimeSeries;
using namespace GSF::TimeSeries::Transport;

// These constants represent each flag in the 8-bit compact measurement state flags.
static const uint8_t CompactDataRangeFlag = 0x01;
static const uint8_t CompactDataQualityFlag = 0x02;
static const uint8_t CompactTimeQualityFlag = 0x04;
static const uint8_t CompactSystemIssueFlag = 0x08;
static const uint8_t CompactCalculatedValueFlag = 0x10;
static const uint8_t CompactDiscardedValueFlag = 0x20;
static const uint8_t CompactBaseTimeOffsetFlag = 0x40;
static const uint8_t CompactTimeIndexFlag = 0x80;

// These constants are masks used to set flags within the full 32-bit measurement state flags.
static const uint32_t DataRangeMask = 0x000000FC;
static const uint32_t DataQualityMask = 0x0000EF03;
static const uint32_t TimeQualityMask = 0x00BF0000;
static const uint32_t SystemIssueMask = 0xE0000000;
static const uint32_t CalculatedValueMask = 0x00001000;
static const uint32_t DiscardedValueMask = 0x00400000;

// Takes the 8-bit compact measurement flags and maps
// them to the full 32-bit measurement flags format.
inline uint32_t MapToFullFlags(uint8_t compactFlags)
{
    uint32_t fullFlags = 0U;

    if ((compactFlags & CompactDataRangeFlag) > 0)
        fullFlags |= DataRangeMask;

    if ((compactFlags & CompactDataQualityFlag) > 0)
        fullFlags |= DataQualityMask;

    if ((compactFlags & CompactTimeQualityFlag) > 0)
        fullFlags |= TimeQualityMask;

    if ((compactFlags & CompactSystemIssueFlag) > 0)
        fullFlags |= SystemIssueMask;

    if ((compactFlags & CompactCalculatedValueFlag) > 0)
        fullFlags |= CalculatedValueMask;

    if ((compactFlags & CompactDiscardedValueFlag) > 0)
        fullFlags |= DiscardedValueMask;

    return fullFlags;
}

// Takes the full 32-bit measurement flags format and
// maps them to the 8-bit compact measurement flags.
inline uint32_t MapToCompactFlags(uint32_t fullFlags)
{
    uint32_t compactFlags = 0U;

    if ((fullFlags & DataRangeMask) > 0)
        compactFlags |= CompactDataRangeFlag;

    if ((fullFlags & DataQualityMask) > 0)
        compactFlags |= CompactDataQualityFlag;

    if ((fullFlags & TimeQualityMask) > 0)
        compactFlags |= CompactTimeQualityFlag;

    if ((fullFlags & SystemIssueMask) > 0)
        compactFlags |= CompactSystemIssueFlag;

    if ((fullFlags & CalculatedValueMask) > 0)
        compactFlags |= CompactCalculatedValueFlag;

    if ((fullFlags & DiscardedValueMask) > 0)
        compactFlags |= CompactDiscardedValueFlag;

    return compactFlags;
}

CompactMeasurement::CompactMeasurement(SignalIndexCache& signalIndexCache, int64_t* baseTimeOffsets, bool includeTime, bool useMillisecondResolution, int32_t timeIndex) :
    m_signalIndexCache(signalIndexCache),
    m_baseTimeOffsets(baseTimeOffsets),
    m_includeTime(includeTime),
    m_useMillisecondResolution(useMillisecondResolution),
    m_timeIndex(timeIndex)
{
}

// Gets the byte length of measurements parsed by this parser.
uint32_t CompactMeasurement::GetMeasurementByteLength(const bool usingBaseTimeOffset) const
{
    uint32_t byteLength = 7;

    if (m_includeTime)
    {
        if (usingBaseTimeOffset)
        {
            if (m_useMillisecondResolution)
                byteLength += 2; // Use two bytes for millisecond resolution timestamp with valid offset
            else
                byteLength += 4; // Use four bytes for tick resolution timestamp with valid offset
        }
        else
        {
            byteLength += 8; // Use eight bytes for full fidelity time
        }
    }

    return byteLength;
}

// Attempts to parse a measurement from the buffer. Return value of false indicates
// that there is not enough data to parse the measurement. Offset and length will be
// updated by this method to indicate how many bytes were used when parsing.
bool CompactMeasurement::TryParseMeasurement(uint8_t* data, uint32_t& offset, uint32_t length, MeasurementPtr& measurement) const
{
    // Ensure that we at least have enough
    // data to read the compact state flags
    if (length - offset < 1)
        return false;

    // Read the compact state flags to determine
    // the size of the measurement being parsed
    const uint8_t compactFlags = data[offset] & 0xFF;
    const int32_t timeIndex = compactFlags & CompactTimeIndexFlag ? 1 : 0;
    const bool usingBaseTimeOffset = (compactFlags & CompactBaseTimeOffsetFlag) != 0;

    // If we are using base time offsets, ensure that it is defined
    if (usingBaseTimeOffset && (m_baseTimeOffsets == nullptr || m_baseTimeOffsets[timeIndex] == 0))
        return false;

    // Ensure that we have enough data to read the rest of the measurement
    if (length - offset < GetMeasurementByteLength(usingBaseTimeOffset))
        return false;

    // Read the signal index from the buffer
    const uint16_t signalIndex = EndianConverter::ToBigEndian<uint16_t>(data, offset + 1);

    // If the signal index is not found in the cache, we cannot parse the measurement
    if (!m_signalIndexCache.Contains(signalIndex))
        return false;

    Guid signalID;
    string measurementSource;
    uint32_t measurementID;
    int64_t timestamp = 0;

    // Now that we've validated our failure conditions we can safely start advancing the offset
    m_signalIndexCache.GetMeasurementKey(signalIndex, signalID, measurementSource, measurementID);
    offset += 3;

    // Read the measurement value from the buffer
    const float32_t measurementValue = EndianConverter::ToBigEndian<float32_t>(data, offset);
    offset += 4;

    if (m_includeTime)
    {
        if (!usingBaseTimeOffset)
        {
            // Read full 8-byte timestamp from the buffer
            timestamp = EndianConverter::ToBigEndian<int64_t>(data, offset);
            offset += 8;
        }
        else if (!m_useMillisecondResolution)
        {
            // Read 4-byte offset from the buffer and apply the appropriate base time offset
            timestamp = EndianConverter::ToBigEndian<uint32_t>(data, offset);
            timestamp += m_baseTimeOffsets[timeIndex]; //-V522
            offset += 4;
        }
        else
        {
            // Read 2-byte offset from the buffer, convert from milliseconds to ticks, and apply the appropriate base time offset
            timestamp = EndianConverter::ToBigEndian<uint16_t>(data, offset);
            timestamp *= 10000;
            timestamp += m_baseTimeOffsets[timeIndex];
            offset += 2;
        }
    }

    measurement = NewSharedPtr<Measurement>();
    measurement->Flags = MapToFullFlags(compactFlags);
    measurement->SignalID = signalID;
    measurement->Source = measurementSource;
    measurement->ID = measurementID;
    measurement->Value = measurementValue;
    measurement->Timestamp = timestamp;

    return true;
}

void CompactMeasurement::SerializeMeasurement(const MeasurementPtr& measurement, vector<uint8_t>& buffer) const
{
    // Define the compact state flags
    uint8_t compactFlags = MapToCompactFlags(measurement->Flags);

    int64_t difference = 0L;
    bool usingBaseTimeOffset = false;

    if (m_baseTimeOffsets != nullptr)
    {
        // See if timestamp will fit within space allowed for active base offset. We cache result so that post call
        // to binary length, result will speed other subsequent parsing operations by not having to reevaluate.
        difference = measurement->Timestamp - m_baseTimeOffsets[m_timeIndex];

        usingBaseTimeOffset = difference > 0 ?
            (m_useMillisecondResolution ? difference / Ticks::PerMillisecond < UInt16::MaxValue : difference < UInt16::MaxValue) : false;
    }

    if (usingBaseTimeOffset)
        compactFlags |= CompactBaseTimeOffsetFlag;

    if (m_timeIndex != 0)
        compactFlags |= CompactTimeIndexFlag;

    // Added encoded compact state flags to beginning of buffer
    buffer.push_back(compactFlags);

    // Encode runtime ID
    EndianConverter::WriteBigEndianBytes(buffer, m_signalIndexCache.GetSignalIndex(measurement->SignalID));

    // Encode adjusted value (accounts for adder and multiplier)
    EndianConverter::WriteBigEndianBytes(buffer, static_cast<float32_t>(measurement->AdjustedValue()));

    if (!m_includeTime)
        return;

    if (usingBaseTimeOffset)
    {
        if (m_useMillisecondResolution)
        {
            // Encode 2-byte millisecond offset timestamp
            EndianConverter::WriteBigEndianBytes(buffer, static_cast<uint16_t>(difference / Ticks::PerMillisecond));
        }
        else
        {
            // Encode 4-byte ticks offset timestamp
            EndianConverter::WriteBigEndianBytes(buffer, static_cast<uint32_t>(difference));
        }
    }
    else
    {
        // Encode 8-byte full fidelity timestamp
        EndianConverter::WriteBigEndianBytes(buffer, measurement->Timestamp);
    }
}
<commit_msg>Update CompactMeasurement.cpp<commit_after>//******************************************************************************************************
//  CompactMeasurement.cpp - Gbtc
//
//  Copyright © 2018, Grid Protection Alliance.  All Rights Reserved.
//
//  Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
//  the NOTICE file distributed with this work for additional information regarding copyright ownership.
//  The GPA licenses this file to you under the MIT License (MIT), the "License"; you may not use this
//  file except in compliance with the License. You may obtain a copy of the License at:
//
//      http://opensource.org/licenses/MIT
//
//  Unless agreed to in writing, the subject software distributed under the License is distributed on an
//  "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
//  License for the specific language governing permissions and limitations.
//
//  Code Modification History:
//  ----------------------------------------------------------------------------------------------------
//  03/09/2012 - Stephen C. Wills
//       Generated original version of source code.
//
//******************************************************************************************************

#include "CompactMeasurement.h"
#include "../Common/EndianConverter.h"

using namespace std;
using namespace GSF::TimeSeries;
using namespace GSF::TimeSeries::Transport;

// These constants represent each flag in the 8-bit compact measurement state flags.
static const uint8_t CompactDataRangeFlag = 0x01;
static const uint8_t CompactDataQualityFlag = 0x02;
static const uint8_t CompactTimeQualityFlag = 0x04;
static const uint8_t CompactSystemIssueFlag = 0x08;
static const uint8_t CompactCalculatedValueFlag = 0x10;
static const uint8_t CompactDiscardedValueFlag = 0x20;
static const uint8_t CompactBaseTimeOffsetFlag = 0x40;
static const uint8_t CompactTimeIndexFlag = 0x80;

// These constants are masks used to set flags within the full 32-bit measurement state flags.
static const uint32_t DataRangeMask = 0x000000FC;
static const uint32_t DataQualityMask = 0x0000EF03;
static const uint32_t TimeQualityMask = 0x00BF0000;
static const uint32_t SystemIssueMask = 0xE0000000;
static const uint32_t CalculatedValueMask = 0x00001000;
static const uint32_t DiscardedValueMask = 0x00400000;

// Takes the 8-bit compact measurement flags and maps
// them to the full 32-bit measurement flags format.
inline uint32_t MapToFullFlags(uint8_t compactFlags)
{
    uint32_t fullFlags = 0U;

    if ((compactFlags & CompactDataRangeFlag) > 0)
        fullFlags |= DataRangeMask;

    if ((compactFlags & CompactDataQualityFlag) > 0)
        fullFlags |= DataQualityMask;

    if ((compactFlags & CompactTimeQualityFlag) > 0)
        fullFlags |= TimeQualityMask;

    if ((compactFlags & CompactSystemIssueFlag) > 0)
        fullFlags |= SystemIssueMask;

    if ((compactFlags & CompactCalculatedValueFlag) > 0)
        fullFlags |= CalculatedValueMask;

    if ((compactFlags & CompactDiscardedValueFlag) > 0)
        fullFlags |= DiscardedValueMask;

    return fullFlags;
}

// Takes the full 32-bit measurement flags format and
// maps them to the 8-bit compact measurement flags.
inline uint32_t MapToCompactFlags(uint32_t fullFlags)
{
    uint32_t compactFlags = 0U;

    if ((fullFlags & DataRangeMask) > 0)
        compactFlags |= CompactDataRangeFlag;

    if ((fullFlags & DataQualityMask) > 0)
        compactFlags |= CompactDataQualityFlag;

    if ((fullFlags & TimeQualityMask) > 0)
        compactFlags |= CompactTimeQualityFlag;

    if ((fullFlags & SystemIssueMask) > 0)
        compactFlags |= CompactSystemIssueFlag;

    if ((fullFlags & CalculatedValueMask) > 0)
        compactFlags |= CompactCalculatedValueFlag;

    if ((fullFlags & DiscardedValueMask) > 0)
        compactFlags |= CompactDiscardedValueFlag;

    return compactFlags;
}

CompactMeasurement::CompactMeasurement(SignalIndexCache& signalIndexCache, int64_t* baseTimeOffsets, bool includeTime, bool useMillisecondResolution, int32_t timeIndex) :
    m_signalIndexCache(signalIndexCache),
    m_baseTimeOffsets(baseTimeOffsets),
    m_includeTime(includeTime),
    m_useMillisecondResolution(useMillisecondResolution),
    m_timeIndex(timeIndex)
{
}

// Gets the byte length of measurements parsed by this parser.
uint32_t CompactMeasurement::GetMeasurementByteLength(const bool usingBaseTimeOffset) const
{
    uint32_t byteLength = 7;

    if (m_includeTime)
    {
        if (usingBaseTimeOffset)
        {
            if (m_useMillisecondResolution)
                byteLength += 2; // Use two bytes for millisecond resolution timestamp with valid offset
            else
                byteLength += 4; // Use four bytes for tick resolution timestamp with valid offset
        }
        else
        {
            byteLength += 8; // Use eight bytes for full fidelity time
        }
    }

    return byteLength;
}

// Attempts to parse a measurement from the buffer. Return value of false indicates
// that there is not enough data to parse the measurement. Offset and length will be
// updated by this method to indicate how many bytes were used when parsing.
bool CompactMeasurement::TryParseMeasurement(uint8_t* data, uint32_t& offset, uint32_t length, MeasurementPtr& measurement) const
{
    // Ensure that we at least have enough
    // data to read the compact state flags
    if (length - offset < 1)
        return false;

    // Read the compact state flags to determine
    // the size of the measurement being parsed
    const uint8_t compactFlags = data[offset] & 0xFF;
    const int32_t timeIndex = compactFlags & CompactTimeIndexFlag ? 1 : 0;
    const bool usingBaseTimeOffset = (compactFlags & CompactBaseTimeOffsetFlag) != 0;

    // If we are using base time offsets, ensure that it is defined
    if (usingBaseTimeOffset && (m_baseTimeOffsets == nullptr || m_baseTimeOffsets[timeIndex] == 0))
        return false;

    // Ensure that we have enough data to read the rest of the measurement
    if (length - offset < GetMeasurementByteLength(usingBaseTimeOffset))
        return false;

    // Read the signal index from the buffer
    const uint16_t signalIndex = EndianConverter::ToBigEndian<uint16_t>(data, offset + 1);

    // If the signal index is not found in the cache, we cannot parse the measurement
    if (!m_signalIndexCache.Contains(signalIndex))
        return false;

    Guid signalID;
    string measurementSource;
    uint32_t measurementID;
    int64_t timestamp = 0;

    // Now that we've validated our failure conditions we can safely start advancing the offset
    m_signalIndexCache.GetMeasurementKey(signalIndex, signalID, measurementSource, measurementID);
    offset += 3;

    // Read the measurement value from the buffer
    const float32_t measurementValue = EndianConverter::ToBigEndian<float32_t>(data, offset);
    offset += 4;

    if (m_includeTime)
    {
        if (!usingBaseTimeOffset)
        {
            // Read full 8-byte timestamp from the buffer
            timestamp = EndianConverter::ToBigEndian<int64_t>(data, offset);
            offset += 8;
        }
        else if (!m_useMillisecondResolution)
        {
            // Read 4-byte offset from the buffer and apply the appropriate base time offset
            timestamp = EndianConverter::ToBigEndian<uint32_t>(data, offset);
            timestamp += m_baseTimeOffsets[timeIndex]; //-V522
            offset += 4;
        }
        else
        {
            // Read 2-byte offset from the buffer, convert from milliseconds to ticks, and apply the appropriate base time offset
            timestamp = EndianConverter::ToBigEndian<uint16_t>(data, offset);
            timestamp *= 10000;
            timestamp += m_baseTimeOffsets[timeIndex];
            offset += 2;
        }
    }

    measurement = NewSharedPtr<Measurement>();
    measurement->Flags = MapToFullFlags(compactFlags);
    measurement->SignalID = signalID;
    measurement->Source = measurementSource;
    measurement->ID = measurementID;
    measurement->Value = measurementValue;
    measurement->Timestamp = timestamp;

    return true;
}

void CompactMeasurement::SerializeMeasurement(const MeasurementPtr& measurement, vector<uint8_t>& buffer) const
{
    // Define the compact state flags
    uint8_t compactFlags = MapToCompactFlags(measurement->Flags);

    int64_t difference = 0L;
    bool usingBaseTimeOffset = false;

    if (m_baseTimeOffsets != nullptr)
    {
        // See if timestamp will fit within space allowed for active base offset. We cache result so that post call
        // to binary length, result will speed other subsequent parsing operations by not having to reevaluate.
        difference = measurement->Timestamp - m_baseTimeOffsets[m_timeIndex];

        usingBaseTimeOffset = difference > 0 ?
            (m_useMillisecondResolution ? difference / Ticks::PerMillisecond < UInt16::MaxValue : difference < UInt16::MaxValue) : false;
    }

    if (usingBaseTimeOffset)
        compactFlags |= CompactBaseTimeOffsetFlag;

    if (m_timeIndex != 0)
        compactFlags |= CompactTimeIndexFlag;

    // Added encoded compact state flags to beginning of buffer
    buffer.push_back(compactFlags);

    // Encode runtime ID
    EndianConverter::WriteBigEndianBytes(buffer, m_signalIndexCache.GetSignalIndex(measurement->SignalID));

    // Encode adjusted value (accounts for adder and multiplier)
    EndianConverter::WriteBigEndianBytes(buffer, static_cast<float32_t>(measurement->AdjustedValue()));

    if (!m_includeTime)
        return;

    if (usingBaseTimeOffset)
    {
        if (m_useMillisecondResolution)
        {
            // Encode 2-byte millisecond offset timestamp
            EndianConverter::WriteBigEndianBytes(buffer, static_cast<uint16_t>(difference / Ticks::PerMillisecond));
        }
        else
        {
            // Encode 4-byte ticks offset timestamp
            EndianConverter::WriteBigEndianBytes(buffer, static_cast<uint32_t>(difference));
        }
    }
    else
    {
        // Encode 8-byte full fidelity timestamp
        EndianConverter::WriteBigEndianBytes(buffer, measurement->Timestamp);
    }
}
<|endoftext|>


<commit_before>// A C++ Program to generate test cases for
// an unweighted tree
#include<bits/stdc++.h>
using namespace std;

// Define the number of runs for the test data
// generated
#define RUN 10000

// Define the maximum number of nodes of the tree
#define MAXNODE 100

int main()
{
	set<pair<int, int>> container;
	set<pair<int, int>>::iterator it;

	freopen ("Test_Cases_Unweighted_Tree.in", "w", stdout);

	//For random values every time
	srand(time(NULL));

	int NUM;	// Number of Vertices/Nodes

	for (int i=1; i<=RUN; i++)
	{
		NUM = 1 + rand() % MAXNODE;

		// First print the number of vertices/nodes
		printf("%d\n", NUM);

		// Then print the edges of the form (a b)
		// where 'a' is connected to 'b'
		for (int j=1; j<=NUM-1; j++)
		{
			int a = 1 + rand() % NUM;
			int b = 1 + rand() % NUM;
			pair<int, int> p = make_pair(a, b);
			pair<int, int> reverse_p = make_pair(b, a);

			// Search for a random "new" edge everytime
			// Note - In a tree the edge (a, b) is same
			// as the edge (b, a)
			while (container.find(p) != container.end() ||
				container.find(reverse_p) != container.end())
			{
				a = 1 + rand() % NUM;
				b = 1 + rand() % NUM;
				p = make_pair(a, b);
				reverse_p = make_pair(b, a);
			}
			container.insert(p);
		}

		for (it=container.begin(); it!=container.end(); ++it)
			printf("%d %d\n", it->first, it->second);

		container.clear();
		printf("\n");
	}

	fclose(stdout);
	return(0);
}

<commit_msg>Delete Test_Case_Generator_Unweighted_Tree.cpp<commit_after><|endoftext|>


<commit_before>#include "./qimage_drawer.h"
#include <QPainter>
#include <vector>

namespace Graphics
{

QImageDrawer::QImageDrawer(int width, int height)
{
  image = std::make_shared<QImage>(width, height, QImage::Format_Grayscale8);
}

void drawPolygon(QPainter &painter, std::vector<QPointF> &points)
{
  if (points.size() < 3)
    return;

  QPointF triangle[3];
  triangle[0] = points[0];
  for (size_t i = 2; i < points.size(); ++i)
  {
    triangle[1] = points[i - 1];
    triangle[2] = points[i];
    painter.drawConvexPolygon(triangle, 3);
  }
  points.clear();
}

void QImageDrawer::drawElementVector(std::vector<float> positions, float color)
{
  QPainter painter;
  painter.begin(image.get());
  QColor brushColor = QColor::fromRgbF(color, color, color, color);
  painter.setBrush(QBrush(brushColor));
  painter.setPen(brushColor);

  std::vector<QPointF> points;
  size_t i = 0;
  if (positions[0] == positions[2] && positions[1] == positions[3])
    i = 1;

  for (; i < positions.size() / 2; ++i)
  {
    float x = positions[i * 2];
    float y = image->height() - positions[i * 2 + 1];
    if (i * 2 + 3 < positions.size() && x == positions[i * 2 + 2] &&
        y == positions[i * 2 + 3])
    {
      drawPolygon(painter, points);
      points.clear();
      i += 2;
    }
    points.push_back(QPointF(x, y));
  }
  drawPolygon(painter, points);
  painter.end();
}

void QImageDrawer::clear()
{
  image->fill(Qt::GlobalColor::black);
}

}  // namespace Graphics
<commit_msg>Don't use transparency in QImageDrawer.<commit_after>#include "./qimage_drawer.h"
#include <QPainter>
#include <vector>

namespace Graphics
{

QImageDrawer::QImageDrawer(int width, int height)
{
  image = std::make_shared<QImage>(width, height, QImage::Format_Grayscale8);
}

void drawPolygon(QPainter &painter, std::vector<QPointF> &points)
{
  if (points.size() < 3)
    return;

  QPointF triangle[3];
  triangle[0] = points[0];
  for (size_t i = 2; i < points.size(); ++i)
  {
    triangle[1] = points[i - 1];
    triangle[2] = points[i];
    painter.drawConvexPolygon(triangle, 3);
  }
  points.clear();
}

void QImageDrawer::drawElementVector(std::vector<float> positions, float color)
{
  QPainter painter;
  painter.begin(image.get());
  QColor brushColor = QColor::fromRgbF(color, color, color, 1.0f);
  painter.setBrush(QBrush(brushColor));
  painter.setPen(brushColor);

  std::vector<QPointF> points;
  size_t i = 0;
  if (positions[0] == positions[2] && positions[1] == positions[3])
    i = 1;

  for (; i < positions.size() / 2; ++i)
  {
    float x = positions[i * 2];
    float y = image->height() - positions[i * 2 + 1];
    if (i * 2 + 3 < positions.size() && x == positions[i * 2 + 2] &&
        y == positions[i * 2 + 3])
    {
      drawPolygon(painter, points);
      points.clear();
      i += 2;
    }
    points.push_back(QPointF(x, y));
  }
  drawPolygon(painter, points);
  painter.end();
}

void QImageDrawer::clear()
{
  image->fill(Qt::GlobalColor::black);
}

}  // namespace Graphics
<|endoftext|>


<commit_before>///
/// @file   l1d_cache_size.cpp
/// @brief  Get the L1 cache size in kilobytes on Windows
///         and most Unix-like operating systems.
///
/// Copyright (C) 2015 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License.
///

#include <cstdlib>

#if defined(_WIN32) || defined(_WIN64)

#include <windows.h>

typedef BOOL (WINAPI *LPFN_GLPI)(PSYSTEM_LOGICAL_PROCESSOR_INFORMATION, PDWORD);

/// Get the CPU's L1 data cache size (per core) in kilobytes.
/// Successfully tested on Windows x64.
/// @return L1 data cache size in kilobytes or -1 if an error occurred.
///
int get_l1d_cache_size()
{
  LPFN_GLPI glpi = (LPFN_GLPI) GetProcAddress(GetModuleHandle(TEXT("kernel32")), "GetLogicalProcessorInformation");

  // GetLogicalProcessorInformation not supported
  if (glpi == NULL)
    return -1;

  DWORD buffer_bytes = 0;
  int cache_size = 0;

  glpi(0, &buffer_bytes);
  std::size_t size = buffer_bytes / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION);
  SYSTEM_LOGICAL_PROCESSOR_INFORMATION* buffer = new SYSTEM_LOGICAL_PROCESSOR_INFORMATION[size];
  glpi(buffer, &buffer_bytes);

  for (std::size_t i = 0; i < size; i++)
  {
    if (buffer[i].Relationship == RelationCache &&
        buffer[i].Cache.Level == 1)
    {
      cache_size = (int) buffer[i].Cache.Size;
      break;
    }
  }

  delete buffer;

  return cache_size / 1024;
}

#else

/// Get the CPU's L1 data cache size (per core) in kilobytes.
/// Successfully tested on Linux and Mac OS X.
/// @return L1 data cache size in kilobytes or -1 if an error occurred.
///
int get_l1d_cache_size()
{
  // Posix shell script for UNIX like OSes,
  // Returns log2 of L1_DCACHE_SIZE in kilobytes.
  // The script tries to get the L1 cache size using 3 different approaches:
  // 1) getconf LEVEL1_DCACHE_SIZE
  // 2) cat /sys/devices/system/cpu/cpu0/cache/index0/size
  // 3) sysctl hw.l1dcachesize

  const char* shell_script =
    "command -v getconf >/dev/null 2>/dev/null;                                                        \n"
    "if [ $? -eq 0 ];                                                                                \n"
    "then                                                                                \n"
    "    # Returns L1 cache size in bytes                                                              \n"
    "    L1_DCACHE_BYTES=$(getconf LEVEL1_DCACHE_SIZE 2>/dev/null);                                    \n"
    "fi;                                                                                \n"
    "                                                                                \n"
    "if test \"x$L1_DCACHE_BYTES\" = \"x\" || test \"$L1_DCACHE_BYTES\" = \"0\";                       \n"
    "then                                                                                \n"
    "    # Returns L1 cache size like e.g. 32K, 1M                                                     \n"
    "    L1_DCACHE_BYTES=$(cat /sys/devices/system/cpu/cpu0/cache/index0/size 2>/dev/null);            \n"
    "                                                                                \n"
    "    if test \"x$L1_DCACHE_BYTES\" != \"x\";                                                       \n"
    "    then                                                                                \n"
    "        is_kilobytes=$(echo $L1_DCACHE_BYTES | grep K);                                           \n"
    "        if test \"x$is_kilobytes\" != \"x\";                                                      \n"
    "        then                                                                                \n"
    "            L1_DCACHE_BYTES=$(expr $(echo $L1_DCACHE_BYTES | sed -e s'/K$//') '*' 1024);          \n"
    "        fi;                                                                                \n"
    "        is_megabytes=$(echo $L1_DCACHE_BYTES | grep M);                                           \n"
    "        if test \"x$is_megabytes\" != \"x\";                                                      \n"
    "        then                                                                                \n"
    "            L1_DCACHE_BYTES=$(expr $(echo $L1_DCACHE_BYTES | sed -e s'/M$//') '*' 1024 '*' 1024); \n"
    "        fi;                                                                                \n"
    "    else                                                                                \n"
    "        # This method works on OS X                                                               \n"
    "        command -v sysctl >/dev/null 2>/dev/null;                                                 \n"
    "        if [ $? -eq 0 ];                                                                          \n"
    "        then                                                                                \n"
    "            # Returns L1 cache size in bytes                                                      \n"
    "            L1_DCACHE_BYTES=$(sysctl hw.l1dcachesize 2>/dev/null | sed -e 's/^.* //');            \n"
    "        fi;                                                                                \n"
    "    fi;                                                                                \n"
    "fi;                                                                                \n"
    "                                                                                \n"
    "if test \"x$L1_DCACHE_BYTES\" != \"x\";                                                           \n"
    "then                                                                                \n"
    "    if [ $L1_DCACHE_BYTES -ge 1024 2>/dev/null ];                                                 \n"
    "    then                                                                                \n"
    "        # Convert to kilobytes                                                                    \n"
    "        L1_DCACHE_SIZE=$(expr $L1_DCACHE_BYTES '/' 1024);                                         \n"
    "    fi;                                                                                \n"
    "fi;                                                                                \n"
    "                                                                                \n"
    "if test \"x$L1_DCACHE_SIZE\" = \"x\";                                                             \n"
    "then                                                                                \n"
    "   exit 1;                                                                                \n"
    "fi;                                                                                \n"
    "                                                                                \n"
    "LOG2_L1_DCACHE_SIZE=0;                                                                            \n"
    "while [ $L1_DCACHE_SIZE -ge 2 ];                                                                  \n"
    "do                                                                                \n"
    "   L1_DCACHE_SIZE=$(expr $L1_DCACHE_SIZE '/' 2);                                                  \n"
    "   LOG2_L1_DCACHE_SIZE=$(expr $LOG2_L1_DCACHE_SIZE '+' 1);                                        \n"
    "done;                                                                                \n"
    "                                                                                \n"
    "exit $LOG2_L1_DCACHE_SIZE;                                                                        \n";

  int exit_code = std::system(shell_script);
  exit_code = WEXITSTATUS(exit_code);

  // check if shell script executed without any errors
  if (exit_code <= 2)
    return -1;

  int l1d_cache_size = 1 << exit_code;

  return l1d_cache_size;
}

#endif
<commit_msg>Fix delete bug<commit_after>///
/// @file   l1d_cache_size.cpp
/// @brief  Get the L1 cache size in kilobytes on Windows
///         and most Unix-like operating systems.
///
/// Copyright (C) 2017 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License.
///

#include <cstdlib>

#if defined(_WIN32) || defined(_WIN64)

#include <windows.h>

typedef BOOL (WINAPI *LPFN_GLPI)(PSYSTEM_LOGICAL_PROCESSOR_INFORMATION, PDWORD);

/// Get the CPU's L1 data cache size (per core) in kilobytes.
/// Successfully tested on Windows x64.
/// @return L1 data cache size in kilobytes or -1 if an error occurred.
///
int get_l1d_cache_size()
{
  LPFN_GLPI glpi = (LPFN_GLPI) GetProcAddress(GetModuleHandle(TEXT("kernel32")), "GetLogicalProcessorInformation");

  // GetLogicalProcessorInformation not supported
  if (glpi == NULL)
    return -1;

  DWORD buffer_bytes = 0;
  int cache_size = 0;

  glpi(0, &buffer_bytes);
  std::size_t size = buffer_bytes / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION);
  SYSTEM_LOGICAL_PROCESSOR_INFORMATION* buffer = new SYSTEM_LOGICAL_PROCESSOR_INFORMATION[size];
  glpi(buffer, &buffer_bytes);

  for (std::size_t i = 0; i < size; i++)
  {
    if (buffer[i].Relationship == RelationCache &&
        buffer[i].Cache.Level == 1)
    {
      cache_size = (int) buffer[i].Cache.Size;
      break;
    }
  }

  delete[] buffer;

  return cache_size / 1024;
}

#else

/// Get the CPU's L1 data cache size (per core) in kilobytes.
/// Successfully tested on Linux and Mac OS X.
/// @return L1 data cache size in kilobytes or -1 if an error occurred.
///
int get_l1d_cache_size()
{
  // Posix shell script for UNIX like OSes,
  // Returns log2 of L1_DCACHE_SIZE in kilobytes.
  // The script tries to get the L1 cache size using 3 different approaches:
  // 1) getconf LEVEL1_DCACHE_SIZE
  // 2) cat /sys/devices/system/cpu/cpu0/cache/index0/size
  // 3) sysctl hw.l1dcachesize

  const char* shell_script =
    "command -v getconf >/dev/null 2>/dev/null;                                                        \n"
    "if [ $? -eq 0 ];                                                                                \n"
    "then                                                                                \n"
    "    # Returns L1 cache size in bytes                                                              \n"
    "    L1_DCACHE_BYTES=$(getconf LEVEL1_DCACHE_SIZE 2>/dev/null);                                    \n"
    "fi;                                                                                \n"
    "                                                                                \n"
    "if test \"x$L1_DCACHE_BYTES\" = \"x\" || test \"$L1_DCACHE_BYTES\" = \"0\";                       \n"
    "then                                                                                \n"
    "    # Returns L1 cache size like e.g. 32K, 1M                                                     \n"
    "    L1_DCACHE_BYTES=$(cat /sys/devices/system/cpu/cpu0/cache/index0/size 2>/dev/null);            \n"
    "                                                                                \n"
    "    if test \"x$L1_DCACHE_BYTES\" != \"x\";                                                       \n"
    "    then                                                                                \n"
    "        is_kilobytes=$(echo $L1_DCACHE_BYTES | grep K);                                           \n"
    "        if test \"x$is_kilobytes\" != \"x\";                                                      \n"
    "        then                                                                                \n"
    "            L1_DCACHE_BYTES=$(expr $(echo $L1_DCACHE_BYTES | sed -e s'/K$//') '*' 1024);          \n"
    "        fi;                                                                                \n"
    "        is_megabytes=$(echo $L1_DCACHE_BYTES | grep M);                                           \n"
    "        if test \"x$is_megabytes\" != \"x\";                                                      \n"
    "        then                                                                                \n"
    "            L1_DCACHE_BYTES=$(expr $(echo $L1_DCACHE_BYTES | sed -e s'/M$//') '*' 1024 '*' 1024); \n"
    "        fi;                                                                                \n"
    "    else                                                                                \n"
    "        # This method works on OS X                                                               \n"
    "        command -v sysctl >/dev/null 2>/dev/null;                                                 \n"
    "        if [ $? -eq 0 ];                                                                          \n"
    "        then                                                                                \n"
    "            # Returns L1 cache size in bytes                                                      \n"
    "            L1_DCACHE_BYTES=$(sysctl hw.l1dcachesize 2>/dev/null | sed -e 's/^.* //');            \n"
    "        fi;                                                                                \n"
    "    fi;                                                                                \n"
    "fi;                                                                                \n"
    "                                                                                \n"
    "if test \"x$L1_DCACHE_BYTES\" != \"x\";                                                           \n"
    "then                                                                                \n"
    "    if [ $L1_DCACHE_BYTES -ge 1024 2>/dev/null ];                                                 \n"
    "    then                                                                                \n"
    "        # Convert to kilobytes                                                                    \n"
    "        L1_DCACHE_SIZE=$(expr $L1_DCACHE_BYTES '/' 1024);                                         \n"
    "    fi;                                                                                \n"
    "fi;                                                                                \n"
    "                                                                                \n"
    "if test \"x$L1_DCACHE_SIZE\" = \"x\";                                                             \n"
    "then                                                                                \n"
    "   exit 1;                                                                                \n"
    "fi;                                                                                \n"
    "                                                                                \n"
    "LOG2_L1_DCACHE_SIZE=0;                                                                            \n"
    "while [ $L1_DCACHE_SIZE -ge 2 ];                                                                  \n"
    "do                                                                                \n"
    "   L1_DCACHE_SIZE=$(expr $L1_DCACHE_SIZE '/' 2);                                                  \n"
    "   LOG2_L1_DCACHE_SIZE=$(expr $LOG2_L1_DCACHE_SIZE '+' 1);                                        \n"
    "done;                                                                                \n"
    "                                                                                \n"
    "exit $LOG2_L1_DCACHE_SIZE;                                                                        \n";

  int exit_code = std::system(shell_script);
  exit_code = WEXITSTATUS(exit_code);

  // check if shell script executed without any errors
  if (exit_code <= 2)
    return -1;

  int l1d_cache_size = 1 << exit_code;

  return l1d_cache_size;
}

#endif
<|endoftext|>


<commit_before>/*
 *
 * $Id$
 *
 * History:
 *
 * Bernd Wuebben, wuebben@math.cornell.edu:
 *
 * Much of this  is taken from the pppd sources in particular
 * /pppstat/pppstat.c, and modified to suit the needs of kppp.
 *
 *
 * Here the original history of pppstat.c:
 *
 * perkins@cps.msu.edu: Added compression statistics and alternate
 *                display. 11/94
 *
 * Brad Parker (brad@cayman.com) 6/92
 *
 * from the original "slstats" by Van Jaconson
 *
 * Copyright (c) 1989 Regents of the University of California.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms are permitted
 * provided that the above copyright notice and this paragraph are
 * duplicated in all such forms and that any documentation,
 * advertising materials, and other materials related to such
 * distribution and use acknowledge that the software was developed
 * by the University of California, Berkeley.  The name of the
 * University may not be used to endorse or promote products derived
 * from this software without specific prior written permission.
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 *
 *	Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989:
 *	- Initial distribution.
 */

#include "pppstats.h"

#include <ctype.h>
#include <errno.h>

#include <stdio.h>
#include <signal.h>
#include <fcntl.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <string.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <netinet/in.h>

#ifndef STREAMS
#if defined(__linux__) && defined(__powerpc__) \
    && (__GLIBC__ == 2 && __GLIBC_MINOR__ == 0)
/* kludge alert! */
#undef __GLIBC__
#endif
#include <sys/socket.h>		/* *BSD, Linux, NeXT, Ultrix etc. */
#ifndef HAVE_NET_IF_PPP_H
#ifdef HAVE_LINUX_IF_PPP_H
#include <linux/if_ppp.h>
#endif
#else
#include <net/ppp_defs.h>
#include <net/if.h>
#include <net/if_ppp.h>
#endif

#else	/* STREAMS */
#include <sys/socket.h>
#include <sys/stropts.h>	/* SVR4, Solaris 2, SunOS 4, OSF/1, etc. */
#include <net/ppp_defs.h>
#include <net/pppio.h>
#include <net/if.h>
#include <sys/sockio.h>

#endif	/* STREAMS */

#include <qtimer.h>
#include <kdebug.h>
#include "pppstats.h"

PPPStats::PPPStats() {
  timer = new QTimer;
  connect(timer, SIGNAL(timeout()), SLOT(timerClick()));
}

PPPStats::~PPPStats() {
  stop();
  delete timer;
}

void PPPStats::timerClick() {
  enum IOStatus newStatus;

  doStats();

  if((ibytes != ibytes_last) && (obytes != obytes_last))
    newStatus = BytesBoth;
  else if(ibytes != ibytes_last)
    newStatus = BytesIn;
  else if(obytes != obytes_last)
    newStatus = BytesOut;
  else
    newStatus = BytesNone;

  if(newStatus != ioStatus)
    emit statsChanged(ioStatus = newStatus);

  ibytes_last = ibytes;
  obytes_last = obytes;
}

void PPPStats::setUnit(int u) {
  unit = u;
  sprintf(unitName, "ppp%d", unit);
}

void PPPStats::start() {
  timer->start(PPP_STATS_INTERVAL);
}

void PPPStats::stop() {
  emit statsChanged(BytesNone);
  timer->stop();
}

bool PPPStats::ifIsUp() {
  bool is_up;
  struct ifreq ifr;

#if defined(__svr4__ )
  usleep(500000); // Needed for Solaris ?!
#endif

#ifdef STREAMS
    if ((t = open("/dev/ppp", O_RDONLY)) < 0) {
	perror("pppstats: Couldn't open /dev/ppp: ");
	return false;
    }
    if (!strioctl(t, PPPIO_ATTACH, (char*)&unit, sizeof(int), 0)) {
	fprintf(stderr, "pppstats: ppp%d is not available\n", unit);
	::close(t);
	return false;
    }
    // TODO: close t somewhere again
#endif
    if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
	perror("Couldn't create IP socket");
	return false;
    }

    strncpy(ifr.ifr_name, unitName, sizeof(ifr.ifr_name));

    if(ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
        if (errno)
          fprintf(stderr, "Couldn't find interface %s: %s\n",
                  unitName, strerror(errno));
	::close(s);
	s = 0;
	return 0;
    }

    if ((ifr.ifr_flags & (IFF_UP|IFF_RUNNING)) != 0) {
	is_up = true;
	kdDebug(5002) << "Interface is up" << endl;
    }
    else{
      is_up = false;
      ::close(s);
      s = 0;
      kdDebug(5002) << "Interface is down" << endl;
    }

    return is_up;
}

bool PPPStats::initStats() {

  struct sockaddr_in *sinp;
  struct ifreq ifr;

  ibytes = 0;
  ipackets = 0;
  ibytes_last = 0;
  obytes_last = 0;
  compressedin = 0;
  uncompressedin = 0;
  errorin = 0;
  obytes = 0;
  opackets = 0;
  compressed = 0;
  packetsunc = 0;
  packetsoutunc = 0;
  ioStatus = BytesNone;

  strcpy(ifr.ifr_name, unitName);

  if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
  }

  sinp = (struct sockaddr_in*)&ifr.ifr_addr;

  if(sinp->sin_addr.s_addr)
    local_ip_address = inet_ntoa(sinp->sin_addr);
  else
    local_ip_address = "";
  kdDebug(5002) << "Local IP: " << local_ip_address << endl;

  if (ioctl(s, SIOCGIFDSTADDR, &ifr) < 0)
    ;

  sinp = (struct sockaddr_in*)&ifr.ifr_dstaddr;

  if(sinp->sin_addr.s_addr)
    remote_ip_address = inet_ntoa(sinp->sin_addr);
  else
    remote_ip_address = "";
  kdDebug(5002) << "Remote IP: " << remote_ip_address << endl;

  return true;

}

bool PPPStats::doStats() {
  struct ppp_stats cur;

  if(! get_ppp_stats(&cur)){
    return false;
  }

  // "in"  "pack"  "comp"  "uncomp"  "err"
  // IN    PACK    VJCOMP  VJUNC     VJERR

  ibytes =   cur.p.ppp_ibytes; 			// bytes received
  ipackets =   cur.p.ppp_ipackets; 		// packets recieved
  compressedin =  cur.vj.vjs_compressedin; 	// inbound compressed packets
  uncompressedin =   cur.vj.vjs_uncompressedin; // inbound uncompressed packets
  errorin =  cur.vj.vjs_errorin; 		//receive errors

  //  "out"  "pack"  "comp"  "uncomp"  "ip"
  // OUT       PACK   JCOMP   VJUNC    NON-VJ

  obytes =  cur.p.ppp_obytes; 		       	// raw bytes sent
  opackets =  cur.p.ppp_opackets; 		// packets sent
  compressed =  cur.vj.vjs_compressed; 		//outbound compressed packets

  // outbound packets - outbound compressed packets
  packetsunc =  cur.vj.vjs_packets - cur.vj.vjs_compressed;

  // packets sent - oubount compressed
  packetsoutunc = cur.p.ppp_opackets - cur.vj.vjs_packets;

  return true;
}

#ifndef STREAMS
bool PPPStats::get_ppp_stats(struct ppp_stats *curp){

  struct ifpppstatsreq req;

    if(s==0)
      return false;

#ifdef __linux__
    req.stats_ptr = (caddr_t) &req.stats;
    sprintf(req.ifr__name, "ppp%d", unit);
#else
    sprintf(req.ifr_name, "ppp%d", unit);
#endif
    if (ioctl(s, SIOCGPPPSTATS, &req) < 0) {
	if (errno == ENOTTY)
	    fprintf(stderr, "pppstats: kernel support missing\n");
	else
	    perror("ioctl(SIOCGPPPSTATS)");
	return false;
    }
    *curp = req.stats;
    return true;
}

#else	/* STREAMS */
bool PPPStats::get_ppp_stats( struct ppp_stats *curp){

    if (!strioctl(t, PPPIO_GETSTAT, (char*)curp, 0, sizeof(*curp))) {
	if (errno == EINVAL)
	    fprintf(stderr, "pppstats: kernel support missing\n");
	else
	    perror("pppstats: Couldn't get statistics");
	return false;
    }
    return true;
}

bool PPPStats::strioctl(int fd, int cmd, char* ptr, int ilen, int olen){

    struct strioctl str;

    str.ic_cmd = cmd;
    str.ic_timout = 0;
    str.ic_len = ilen;
    str.ic_dp = ptr;
    if (ioctl(fd, I_STR, &str) == -1)
	return false;
    if (str.ic_len != olen)
	fprintf(stderr, "strioctl: expected %d bytes, got %d for cmd %x\n",
	       olen, str.ic_len, cmd);
    return true;
}
#endif /* STREAMS */

#include "pppstats.moc"

<commit_msg>#include <net/ppp_defs.h> for every system. Didn't get any feedback from a tester, yet, but I saw this in older versions in the cvs, too.<commit_after>/*
 *
 * $Id$
 *
 * History:
 *
 * Bernd Wuebben, wuebben@math.cornell.edu:
 *
 * Much of this  is taken from the pppd sources in particular
 * /pppstat/pppstat.c, and modified to suit the needs of kppp.
 *
 *
 * Here the original history of pppstat.c:
 *
 * perkins@cps.msu.edu: Added compression statistics and alternate
 *                display. 11/94
 *
 * Brad Parker (brad@cayman.com) 6/92
 *
 * from the original "slstats" by Van Jaconson
 *
 * Copyright (c) 1989 Regents of the University of California.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms are permitted
 * provided that the above copyright notice and this paragraph are
 * duplicated in all such forms and that any documentation,
 * advertising materials, and other materials related to such
 * distribution and use acknowledge that the software was developed
 * by the University of California, Berkeley.  The name of the
 * University may not be used to endorse or promote products derived
 * from this software without specific prior written permission.
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 *
 *	Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989:
 *	- Initial distribution.
 */

#include "pppstats.h"

#include <ctype.h>
#include <errno.h>

#include <stdio.h>
#include <signal.h>
#include <fcntl.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <string.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <netinet/in.h>
#include <net/ppp_defs.h>

#ifndef STREAMS
#if defined(__linux__) && defined(__powerpc__) \
    && (__GLIBC__ == 2 && __GLIBC_MINOR__ == 0)
/* kludge alert! */
#undef __GLIBC__
#endif
#include <sys/socket.h>		/* *BSD, Linux, NeXT, Ultrix etc. */
#ifndef HAVE_NET_IF_PPP_H
#ifdef HAVE_LINUX_IF_PPP_H
#include <linux/if.h>
#include <linux/if_ppp.h>
#endif
#else
#include <net/if.h>
#include <net/if_ppp.h>
#endif

#else	/* STREAMS */
#include <sys/socket.h>
#include <sys/stropts.h>	/* SVR4, Solaris 2, SunOS 4, OSF/1, etc. */
#include <net/ppp_defs.h>
#include <net/pppio.h>
#include <net/if.h>
#include <sys/sockio.h>

#endif	/* STREAMS */

#include <qtimer.h>
#include <kdebug.h>
#include "pppstats.h"

PPPStats::PPPStats() {
  timer = new QTimer;
  connect(timer, SIGNAL(timeout()), SLOT(timerClick()));
}

PPPStats::~PPPStats() {
  stop();
  delete timer;
}

void PPPStats::timerClick() {
  enum IOStatus newStatus;

  doStats();

  if((ibytes != ibytes_last) && (obytes != obytes_last))
    newStatus = BytesBoth;
  else if(ibytes != ibytes_last)
    newStatus = BytesIn;
  else if(obytes != obytes_last)
    newStatus = BytesOut;
  else
    newStatus = BytesNone;

  if(newStatus != ioStatus)
    emit statsChanged(ioStatus = newStatus);

  ibytes_last = ibytes;
  obytes_last = obytes;
}

void PPPStats::setUnit(int u) {
  unit = u;
  sprintf(unitName, "ppp%d", unit);
}

void PPPStats::start() {
  timer->start(PPP_STATS_INTERVAL);
}

void PPPStats::stop() {
  emit statsChanged(BytesNone);
  timer->stop();
}

bool PPPStats::ifIsUp() {
  bool is_up;
  struct ifreq ifr;

#if defined(__svr4__ )
  usleep(500000); // Needed for Solaris ?!
#endif

#ifdef STREAMS
    if ((t = open("/dev/ppp", O_RDONLY)) < 0) {
	perror("pppstats: Couldn't open /dev/ppp: ");
	return false;
    }
    if (!strioctl(t, PPPIO_ATTACH, (char*)&unit, sizeof(int), 0)) {
	fprintf(stderr, "pppstats: ppp%d is not available\n", unit);
	::close(t);
	return false;
    }
    // TODO: close t somewhere again
#endif
    if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
	perror("Couldn't create IP socket");
	return false;
    }

    strncpy(ifr.ifr_name, unitName, sizeof(ifr.ifr_name));

    if(ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
        if (errno)
          fprintf(stderr, "Couldn't find interface %s: %s\n",
                  unitName, strerror(errno));
	::close(s);
	s = 0;
	return 0;
    }

    if ((ifr.ifr_flags & (IFF_UP|IFF_RUNNING)) != 0) {
	is_up = true;
	kdDebug(5002) << "Interface is up" << endl;
    }
    else{
      is_up = false;
      ::close(s);
      s = 0;
      kdDebug(5002) << "Interface is down" << endl;
    }

    return is_up;
}

bool PPPStats::initStats() {

  struct sockaddr_in *sinp;
  struct ifreq ifr;

  ibytes = 0;
  ipackets = 0;
  ibytes_last = 0;
  obytes_last = 0;
  compressedin = 0;
  uncompressedin = 0;
  errorin = 0;
  obytes = 0;
  opackets = 0;
  compressed = 0;
  packetsunc = 0;
  packetsoutunc = 0;
  ioStatus = BytesNone;

  strcpy(ifr.ifr_name, unitName);

  if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
  }

  sinp = (struct sockaddr_in*)&ifr.ifr_addr;

  if(sinp->sin_addr.s_addr)
    local_ip_address = inet_ntoa(sinp->sin_addr);
  else
    local_ip_address = "";
  kdDebug(5002) << "Local IP: " << local_ip_address << endl;

  if (ioctl(s, SIOCGIFDSTADDR, &ifr) < 0)
    ;

  sinp = (struct sockaddr_in*)&ifr.ifr_dstaddr;

  if(sinp->sin_addr.s_addr)
    remote_ip_address = inet_ntoa(sinp->sin_addr);
  else
    remote_ip_address = "";
  kdDebug(5002) << "Remote IP: " << remote_ip_address << endl;

  return true;

}

bool PPPStats::doStats() {
  struct ppp_stats cur;

  if(! get_ppp_stats(&cur)){
    return false;
  }

  // "in"  "pack"  "comp"  "uncomp"  "err"
  // IN    PACK    VJCOMP  VJUNC     VJERR

  ibytes =   cur.p.ppp_ibytes; 			// bytes received
  ipackets =   cur.p.ppp_ipackets; 		// packets recieved
  compressedin =  cur.vj.vjs_compressedin; 	// inbound compressed packets
  uncompressedin =   cur.vj.vjs_uncompressedin; // inbound uncompressed packets
  errorin =  cur.vj.vjs_errorin; 		//receive errors

  //  "out"  "pack"  "comp"  "uncomp"  "ip"
  // OUT       PACK   JCOMP   VJUNC    NON-VJ

  obytes =  cur.p.ppp_obytes; 		       	// raw bytes sent
  opackets =  cur.p.ppp_opackets; 		// packets sent
  compressed =  cur.vj.vjs_compressed; 		//outbound compressed packets

  // outbound packets - outbound compressed packets
  packetsunc =  cur.vj.vjs_packets - cur.vj.vjs_compressed;

  // packets sent - oubount compressed
  packetsoutunc = cur.p.ppp_opackets - cur.vj.vjs_packets;

  return true;
}

#ifndef STREAMS
bool PPPStats::get_ppp_stats(struct ppp_stats *curp){

  struct ifpppstatsreq req;

    if(s==0)
      return false;

#ifdef __linux__
    req.stats_ptr = (caddr_t) &req.stats;
    sprintf(req.ifr__name, "ppp%d", unit);
#else
    sprintf(req.ifr_name, "ppp%d", unit);
#endif
    if (ioctl(s, SIOCGPPPSTATS, &req) < 0) {
	if (errno == ENOTTY)
	    fprintf(stderr, "pppstats: kernel support missing\n");
	else
	    perror("ioctl(SIOCGPPPSTATS)");
	return false;
    }
    *curp = req.stats;
    return true;
}

#else	/* STREAMS */
bool PPPStats::get_ppp_stats( struct ppp_stats *curp){

    if (!strioctl(t, PPPIO_GETSTAT, (char*)curp, 0, sizeof(*curp))) {
	if (errno == EINVAL)
	    fprintf(stderr, "pppstats: kernel support missing\n");
	else
	    perror("pppstats: Couldn't get statistics");
	return false;
    }
    return true;
}

bool PPPStats::strioctl(int fd, int cmd, char* ptr, int ilen, int olen){

    struct strioctl str;

    str.ic_cmd = cmd;
    str.ic_timout = 0;
    str.ic_len = ilen;
    str.ic_dp = ptr;
    if (ioctl(fd, I_STR, &str) == -1)
	return false;
    if (str.ic_len != olen)
	fprintf(stderr, "strioctl: expected %d bytes, got %d for cmd %x\n",
	       olen, str.ic_len, cmd);
    return true;
}
#endif /* STREAMS */

#include "pppstats.moc"

<|endoftext|>


<commit_before>/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield
 *
 * This library is open source and may be redistributed and/or modified under
 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
 * (at your option) any later version.  The full license is in LICENSE file
 * included with this distribution, and on the openscenegraph.org website.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * OpenSceneGraph Public License for more details.
*/
#include <osgSim/MultiSwitch>

#include <algorithm>

using namespace osgSim;

MultiSwitch::MultiSwitch():
    _newChildDefaultValue(true),
    _activeSwitchSet(0)
{
}

MultiSwitch::MultiSwitch(const MultiSwitch& sw,const osg::CopyOp& copyop):
    osg::Group(sw,copyop),
    _newChildDefaultValue(sw._newChildDefaultValue),
    _values(sw._values)
{
}

void MultiSwitch::traverse(osg::NodeVisitor& nv)
{
    if (nv.getTraversalMode()==osg::NodeVisitor::TRAVERSE_ACTIVE_CHILDREN)
    {

        if (_activeSwitchSet<_values.size())
        {
            for(unsigned int pos=0;pos<_children.size();++pos)
            {
                if (_values[_activeSwitchSet][pos]) _children[pos]->accept(nv);
            }
        }
    }
    else
    {
        Group::traverse(nv);
    }
}

bool MultiSwitch::addChild( osg::Node *child)
{
    unsigned int childPosition = _children.size();
    if (Group::addChild(child))
    {
        for(SwitchSetList::iterator itr=_values.begin();
            itr!=_values.end();
            ++itr)
        {
            ValueList& values = *itr;
            if (_children.size()>_values.size())
	    {
	        values.resize(_children.size(),_newChildDefaultValue);
	        values[childPosition]=_newChildDefaultValue;
	    }
        }
	return true;
    }
    return false;
}

bool MultiSwitch::insertChild( unsigned int index, osg::Node *child)
{
    if (Group::insertChild(index,child))
    {
        for(SwitchSetList::iterator itr=_values.begin();
            itr!=_values.end();
            ++itr)
        {
            ValueList& values = *itr;
            if (index>=_values.size())
	    {
	        values.push_back(_newChildDefaultValue);
	    }
            else
            {
	        values.insert(values.begin()+index, _newChildDefaultValue);
            }
        }

	return true;
    }
    return false;
}

bool MultiSwitch::removeChild( osg::Node *child )
{
    // find the child's position.
    unsigned int pos=getChildIndex(child);
    if (pos==_children.size()) return false;

    for(SwitchSetList::iterator itr=_values.begin();
        itr!=_values.end();
        ++itr)
    {
        ValueList& values = *itr;
        values.erase(values.begin()+pos);
    }

    return Group::removeChild(child);
}

void MultiSwitch::setValue(unsigned int switchSet, unsigned int pos,bool value)
{
    expandToEncompassSwitchSet(switchSet);

    ValueList& values = _values[switchSet];
    if (pos>=values.size()) values.resize(pos+1,_newChildDefaultValue);
    values[pos]=value;
}

void MultiSwitch::setChildValue(const osg::Node* child,unsigned int switchSet, bool value)
{
    expandToEncompassSwitchSet(switchSet);

    // find the child's position.
    unsigned int pos=getChildIndex(child);
    if (pos==_children.size()) return;

    ValueList& values = _values[switchSet];
    values[pos]=value;
}

bool MultiSwitch::getValue(unsigned int switchSet, unsigned int pos) const
{
    if (switchSet>=_values.size()) return false;

    const ValueList& values = _values[switchSet];
    if (pos>=values.size()) return false;

    return values[pos];
}

bool MultiSwitch::getChildValue(const osg::Node* child, unsigned int switchSet) const
{
    if (switchSet>=_values.size()) return false;

    // find the child's position.
    unsigned int pos=getChildIndex(child);
    if (pos==_children.size()) return false;

    const ValueList& values = _values[switchSet];
    return values[pos];
}

void MultiSwitch::expandToEncompassSwitchSet(unsigned int switchSet)
{
    if (switchSet>=_values.size())
    {
        // need to expand arrays.
        unsigned int originalSize = _values.size();
        _values.resize(switchSet+1);
        for(unsigned int i=originalSize;i<=switchSet;++i)
        {
            ValueList& values = _values[switchSet];
            values.resize(_children.size(),_newChildDefaultValue);
        }
    }
}

bool MultiSwitch::setAllChildrenOff(unsigned int switchSet)
{
    _newChildDefaultValue = false;

    expandToEncompassSwitchSet(switchSet);

    ValueList& values = _values[switchSet];
    for(ValueList::iterator itr=values.begin();
        itr!=values.end();
        ++itr)
    {
        *itr = false;
    }
    return true;
}

bool MultiSwitch::setAllChildrenOn(unsigned int switchSet)
{
    _newChildDefaultValue = true;

    expandToEncompassSwitchSet(switchSet);

    ValueList& values = _values[switchSet];
    for(ValueList::iterator itr=values.begin();
        itr!=values.end();
        ++itr)
    {
        *itr = true;
    }
    return true;
}

bool MultiSwitch::setSingleChildOn(unsigned int switchSet, unsigned int pos)
{
    expandToEncompassSwitchSet(switchSet);

    ValueList& values = _values[switchSet];
    for(ValueList::iterator itr=values.begin();
        itr!=values.end();
        ++itr)
    {
        *itr = false;
    }
    setValue(switchSet, pos,true);
    return true;
}
<commit_msg>Added _activeSwitchSet(sw._activeSwitchSet) into the copy constructor.<commit_after>/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield
 *
 * This library is open source and may be redistributed and/or modified under
 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
 * (at your option) any later version.  The full license is in LICENSE file
 * included with this distribution, and on the openscenegraph.org website.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * OpenSceneGraph Public License for more details.
*/
#include <osgSim/MultiSwitch>

#include <algorithm>

using namespace osgSim;

MultiSwitch::MultiSwitch():
    _newChildDefaultValue(true),
    _activeSwitchSet(0)
{
}

MultiSwitch::MultiSwitch(const MultiSwitch& sw,const osg::CopyOp& copyop):
    osg::Group(sw,copyop),
    _newChildDefaultValue(sw._newChildDefaultValue),
    _activeSwitchSet(sw._activeSwitchSet),
    _values(sw._values)
{
}

void MultiSwitch::traverse(osg::NodeVisitor& nv)
{
    if (nv.getTraversalMode()==osg::NodeVisitor::TRAVERSE_ACTIVE_CHILDREN)
    {

        if (_activeSwitchSet<_values.size())
        {
            for(unsigned int pos=0;pos<_children.size();++pos)
            {
                if (_values[_activeSwitchSet][pos]) _children[pos]->accept(nv);
            }
        }
    }
    else
    {
        Group::traverse(nv);
    }
}

bool MultiSwitch::addChild( osg::Node *child)
{
    unsigned int childPosition = _children.size();
    if (Group::addChild(child))
    {
        for(SwitchSetList::iterator itr=_values.begin();
            itr!=_values.end();
            ++itr)
        {
            ValueList& values = *itr;
            if (_children.size()>_values.size())
	    {
	        values.resize(_children.size(),_newChildDefaultValue);
	        values[childPosition]=_newChildDefaultValue;
	    }
        }
	return true;
    }
    return false;
}

bool MultiSwitch::insertChild( unsigned int index, osg::Node *child)
{
    if (Group::insertChild(index,child))
    {
        for(SwitchSetList::iterator itr=_values.begin();
            itr!=_values.end();
            ++itr)
        {
            ValueList& values = *itr;
            if (index>=_values.size())
	    {
	        values.push_back(_newChildDefaultValue);
	    }
            else
            {
	        values.insert(values.begin()+index, _newChildDefaultValue);
            }
        }

	return true;
    }
    return false;
}

bool MultiSwitch::removeChild( osg::Node *child )
{
    // find the child's position.
    unsigned int pos=getChildIndex(child);
    if (pos==_children.size()) return false;

    for(SwitchSetList::iterator itr=_values.begin();
        itr!=_values.end();
        ++itr)
    {
        ValueList& values = *itr;
        values.erase(values.begin()+pos);
    }

    return Group::removeChild(child);
}

void MultiSwitch::setValue(unsigned int switchSet, unsigned int pos,bool value)
{
    expandToEncompassSwitchSet(switchSet);

    ValueList& values = _values[switchSet];
    if (pos>=values.size()) values.resize(pos+1,_newChildDefaultValue);
    values[pos]=value;
}

void MultiSwitch::setChildValue(const osg::Node* child,unsigned int switchSet, bool value)
{
    expandToEncompassSwitchSet(switchSet);

    // find the child's position.
    unsigned int pos=getChildIndex(child);
    if (pos==_children.size()) return;

    ValueList& values = _values[switchSet];
    values[pos]=value;
}

bool MultiSwitch::getValue(unsigned int switchSet, unsigned int pos) const
{
    if (switchSet>=_values.size()) return false;

    const ValueList& values = _values[switchSet];
    if (pos>=values.size()) return false;

    return values[pos];
}

bool MultiSwitch::getChildValue(const osg::Node* child, unsigned int switchSet) const
{
    if (switchSet>=_values.size()) return false;

    // find the child's position.
    unsigned int pos=getChildIndex(child);
    if (pos==_children.size()) return false;

    const ValueList& values = _values[switchSet];
    return values[pos];
}

void MultiSwitch::expandToEncompassSwitchSet(unsigned int switchSet)
{
    if (switchSet>=_values.size())
    {
        // need to expand arrays.
        unsigned int originalSize = _values.size();
        _values.resize(switchSet+1);
        for(unsigned int i=originalSize;i<=switchSet;++i)
        {
            ValueList& values = _values[switchSet];
            values.resize(_children.size(),_newChildDefaultValue);
        }
    }
}

bool MultiSwitch::setAllChildrenOff(unsigned int switchSet)
{
    _newChildDefaultValue = false;

    expandToEncompassSwitchSet(switchSet);

    ValueList& values = _values[switchSet];
    for(ValueList::iterator itr=values.begin();
        itr!=values.end();
        ++itr)
    {
        *itr = false;
    }
    return true;
}

bool MultiSwitch::setAllChildrenOn(unsigned int switchSet)
{
    _newChildDefaultValue = true;

    expandToEncompassSwitchSet(switchSet);

    ValueList& values = _values[switchSet];
    for(ValueList::iterator itr=values.begin();
        itr!=values.end();
        ++itr)
    {
        *itr = true;
    }
    return true;
}

bool MultiSwitch::setSingleChildOn(unsigned int switchSet, unsigned int pos)
{
    expandToEncompassSwitchSet(switchSet);

    ValueList& values = _values[switchSet];
    for(ValueList::iterator itr=values.begin();
        itr!=values.end();
        ++itr)
    {
        *itr = false;
    }
    setValue(switchSet, pos,true);
    return true;
}
<|endoftext|>


<commit_before>/*
 * ProbeActivityLinear.cpp
 *
 *  Created on: Mar 7, 2009
 *      Author: rasmussn
 */

#include "LinearActivityProbe.hpp"

namespace PV {

/**
 * @hc
 * @dim
 * @kLoc
 * @f
 */
LinearActivityProbe::LinearActivityProbe(HyPerCol * hc, PVDimType dim, int linePos, int f)
   : PVLayerProbe()
{
   this->parent = hc;
   this->dim = dim;
   this->linePos = linePos;
   this->f   = f;
}

/**
 * @filename
 * @hc
 * @dim
 * @kLoc
 * @f
 */
LinearActivityProbe::LinearActivityProbe(const char * filename, HyPerCol * hc, PVDimType dim, int linePos, int f)
    : PVLayerProbe(filename)
{
   this->parent = hc;
   this->dim = dim;
   this->linePos = linePos;
   this->f   = f;
}

/**
 * @time
 * @l
 */
int LinearActivityProbe::outputState(float time, PVLayer * l)
{
   int width, sLine, k, kex;
   float * line;

   float * activity = l->activity->data;

   const int nx = l->loc.nx;
   const int ny = l->loc.ny;
   const int nf = l->numFeatures;

   const int marginWidth = l->loc.nPad;

   float dt = parent->getDeltaTime();

   double sum = 0.0;
   float freq;

   if (dim == DimX) {
      width = nx + 2*marginWidth;
      line = l->activity->data + (linePos+marginWidth) * width * nf;
      sLine = nf;
   }
   else {
      width = ny + 2*marginWidth;
      line = l->activity->data + (linePos+marginWidth)*nf;
      sLine = nf * (nx + 2*marginWidth);

   }

   for (int k = 0; k < width; k++) {
     float a = line[f + k * sLine];
     sum += a;
   }

   freq = sum / (width * dt * 0.001);
   fprintf(fp, "t=%6.1f sum=%3d f=%6.1f Hz :", time, (int)sum, freq);

   for (int k = 0; k < width; k++) {
     float a = line[f + k * sLine];
     if (a > 0.0) fprintf(fp, "*");
     else         fprintf(fp, " ");
   }
   fprintf(fp, ":\n");
   fflush(fp);

   return 0;
}

} // namespace PV
<commit_msg>LayerProbe now uses HyPerLayer rather than just PVLayer.  Also renamed PVLayerProbe to LayerProbe.<commit_after>/*
 * ProbeActivityLinear.cpp
 *
 *  Created on: Mar 7, 2009
 *      Author: rasmussn
 */

#include "LinearActivityProbe.hpp"

namespace PV {

/**
 * @hc
 * @dim
 * @kLoc
 * @f
 */
LinearActivityProbe::LinearActivityProbe(HyPerCol * hc, PVDimType dim, int linePos, int f)
   : LayerProbe()
{
   this->parent = hc;
   this->dim = dim;
   this->linePos = linePos;
   this->f   = f;
}

/**
 * @filename
 * @hc
 * @dim
 * @kLoc
 * @f
 */
LinearActivityProbe::LinearActivityProbe(const char * filename, HyPerCol * hc, PVDimType dim, int linePos, int f)
    : LayerProbe(filename)
{
   this->parent = hc;
   this->dim = dim;
   this->linePos = linePos;
   this->f   = f;
}

/**
 * @time
 * @l
 */
int LinearActivityProbe::outputState(float time, HyPerLayer * l)
{
   int width, sLine, k, kex;
   float * line;

   const PVLayer * clayer = l->clayer;

   float * activity = clayer->activity->data;

   const int nx = clayer->loc.nx;
   const int ny = clayer->loc.ny;
   const int nf = clayer->numFeatures;

   const int marginWidth = clayer->loc.nPad;

   float dt = parent->getDeltaTime();

   double sum = 0.0;
   float freq;

   if (dim == DimX) {
      width = nx + 2*marginWidth;
      line = clayer->activity->data + (linePos+marginWidth) * width * nf;
      sLine = nf;
   }
   else {
      width = ny + 2*marginWidth;
      line = clayer->activity->data + (linePos+marginWidth)*nf;
      sLine = nf * (nx + 2*marginWidth);

   }

   for (int k = 0; k < width; k++) {
     float a = line[f + k * sLine];
     sum += a;
   }

   freq = sum / (width * dt * 0.001);
   fprintf(fp, "t=%6.1f sum=%3d f=%6.1f Hz :", time, (int)sum, freq);

   for (int k = 0; k < width; k++) {
     float a = line[f + k * sLine];
     if (a > 0.0) fprintf(fp, "*");
     else         fprintf(fp, " ");
   }
   fprintf(fp, ":\n");
   fflush(fp);

   return 0;
}

} // namespace PV
<|endoftext|>