<commit_before>//
//  conflict.cpp
//  Parse
//
//  Created by Andrew Hunter on 04/06/2011.
//  Copyright 2011 __MyCompanyName__. All rights reserved.
//

#include "TameParse/Lr/conflict.h"

using namespace std;
using namespace contextfree;
using namespace lr;

/// \brief Creates a new conflict object (describing a non-conflict)
conflict::conflict(int stateId, const item_container& token)
: m_StateId(stateId)
, m_Token(token) {
}

/// \brief Copy constructor
conflict::conflict(const conflict& copyFrom)
: m_StateId(copyFrom.m_StateId)
, m_Token(copyFrom.m_Token)
, m_Shift(copyFrom.m_Shift)
, m_Reduce(copyFrom.m_Reduce) {
}

/// \brief Destroys this conflict object
conflict::~conflict() { }

/// \brief Clones this conflict
conflict* conflict::clone() const {
    return new conflict(*this);
}

/// \brief Returns true if conflict a is less than conflict b
bool conflict::compare(const conflict* a, const conflict* b) {
    if (a == b) return false;
    if (!a) return true;
    if (!b) return false;

    return (*a) < (*b);
}

/// \brief Orders this conflict relative to another
bool conflict::operator<(const conflict& compareTo) const {
    if (m_StateId < compareTo.m_StateId)    return true;
    if (m_StateId > compareTo.m_StateId)    return false;

    if (m_Token < compareTo.m_Token)        return true;
    if (compareTo.m_Token < m_Token)        return false;

    if (m_Shift < compareTo.m_Shift)        return true;
    if (m_Shift > compareTo.m_Shift)        return false;

    if (m_Reduce < compareTo.m_Reduce)      return true;

    return false;
}

/// \brief Adds an LR(0) item that will be followed if the token is shifted
void conflict::add_shift_item(const lr0_item_container& item) {
    m_Shift.insert(item);
}

/// \brief Adds an LR(0) item that will be reduced if the token is in the lookahead
///
/// This returns an item that the caller can add the set of reduce states for this item
conflict::possible_reduce_states& conflict::add_reduce_item(const lr0_item_container& item) {
    return m_Reduce[item];
}

/// \brief Adds the conflicts found in a single state of the specified LALR builder to the given target list
static void find_conflicts(const lalr_builder& builder, int stateId, conflict_list& target) {
    // Get the actions in this state
    const lr_action_set& actions = builder.actions_for_state(stateId);

    // Run through these actions, and find places where there are conflicts (two actions for a single symbol)
    typedef map<item_container, lr_action_set> items_to_actions;
    items_to_actions actionsForItem;

    for (lr_action_set::const_iterator nextAction = actions.begin(); nextAction != actions.end(); nextAction++) {
        // Ignore actions that don't cause conflicts
        bool ignore;
        switch ((*nextAction)->type()) {
            case lr_action::act_goto:
            case lr_action::act_ignore:
            case lr_action::act_accept:
                ignore = true;
                break;

            default:
                ignore = false;
                break;
        }
        if (ignore) continue;

        // Add this as an action for this item
        actionsForItem[(*nextAction)->item()].insert(*nextAction);
    }

    // Generate conflicts for any item with multiple actions
    for (items_to_actions::iterator nextItem = actionsForItem.begin(); nextItem != actionsForItem.end(); nextItem++) {
        // Ignore items with just one action (or no actions, if that's ever possible)
        if (nextItem->second.size() < 2) continue;

        // Ignore items if all but one of the items are 'weak'
        int numWeak = 0;
        for (lr_action_set::const_iterator nextAction = nextItem->second.begin(); nextAction != nextItem->second.end(); nextAction++) {
            switch ((*nextAction)->type()) {
                case lr_action::act_guard:
                case lr_action::act_weakreduce:
                case lr_action::act_ignore:
                    numWeak++;
                    break;

                default:
                    break;
            }
        }

        if (nextItem->second.size() - numWeak < 2) continue;

        // Create a new conflict for this action
        const item_container&   conflictToken = *nextItem->first;
        conflict_container      newConf(new conflict(stateId, conflictToken), true);

        // Fetch the items in this state
        const lalr_state& thisState = *builder.machine().state_with_id(stateId);

        // Get the closure of this state
        lr1_item_set closure;
        builder.generate_closure(thisState, closure, &builder.gram());

        // Describe the actions resulting in this conflict by going through the items in the closure of the state
        const grammar*    gram = &builder.gram();

        // Iterate through the closure to get the items that can be shifted as part of this conflict
        for (lr1_item_set::const_iterator nextItem = closure.begin(); nextItem != closure.end(); nextItem++) {
            if (!(*nextItem)->at_end()) {
                // This item will result in a shift: add it to the list if it can shift our item
                const item_set& firstItems = gram->first((*nextItem)->rule()->items()[(*nextItem)->offset()]);

                if (firstItems.contains(conflictToken)) {
                    // This item can result in a shift of the specified token
                    newConf->add_shift_item(**nextItem);
                }
            }
        }

        // Iterate through the items in the state to look for the reduce actions
        for (int itemId = 0; itemId < thisState.count_items(); itemId++) {
            // Get the item that this refers to
            const lalr_state::container& thisItem = thisState[itemId];

            // Get the lookahead for this item
            const lr1_item::lookahead_set& la = *thisState.lookahead_for(thisItem);

            // If this state isn't a reducing state, then compute the closure to see if it produces any reducing states on the conflicted nonterminal
            if (!thisItem->at_end()) {
                // Fetch the rule for this item
                const rule& rule    = *thisItem->rule();
                int         offset  = thisItem->offset();

                // Generate the closure for this item
                lr1_item        nextItem(thisItem, la);
                lr1_item_set    itemClosure;

                rule.items()[offset]->cache_closure(nextItem, itemClosure, *gram);

                // For any items in the closure that are at the end and have a reduce action, generate some reduce information
                for (lr1_item_set::iterator closureItem = itemClosure.begin(); closureItem != itemClosure.end(); closureItem++) {
                    // Ignore items that are not at the end of the closure
                    if (!(*closureItem)->at_end()) continue;

                    // Ignore items that do not contain the closure item in their lookahead
                    if (!(*closureItem)->lookahead().contains(conflictToken)) continue;

                    // This item is part of the conflict: add a new reduce item
                    conflict::possible_reduce_states& reduceTo = newConf->add_reduce_item(**closureItem);

                    // Add a reduction action for this (for this nonterminal, we just end up in the same state)
                    reduceTo.insert(conflict::lr_item_id(stateId, itemId));
                }

                // TODO: if the symbols following the current state can be reduced to the empty symbol then we need to indicate where the rest of the lookahead comes from
                continue;
            }

            // This is a reducing state

            // This isn't part of the conflict if it isn't being reduced based on the
            if (!la.contains(conflictToken)) continue;

            // Add a conflict for this item
            conflict::possible_reduce_states& reduceTo = newConf->add_reduce_item(thisItem);

            // Work out which states can be reached by looking at the spontaneous and lookahead propagation
            typedef set<conflict::lr_item_id>  lr_item_id_set;
            lr_item_id_set sourceItems;
            builder.find_lookahead_source(stateId, itemId, conflictToken, sourceItems);

            // Add to the reduce set
            reduceTo.insert(sourceItems.begin(), sourceItems.end());
        }

        // Add the new conflict to the list
        target.push_back(newConf);
    }
}

/// \brief Adds the conflicts found in the specified LALR builder object to the passed in list
void conflict::find_conflicts(const lalr_builder& builder, conflict_list& target) {
    // Iterate through the states in the builder
    for (int stateId=0; stateId < builder.count_states(); stateId++) {
        ::find_conflicts(builder, stateId, target);
    }
}

<commit_msg>Will no longer add empty conflicts to the results. I'm assuming these are down to weak symbols being spontaneously generated for some actions.<commit_after>//
//  conflict.cpp
//  Parse
//
//  Created by Andrew Hunter on 04/06/2011.
//  Copyright 2011 __MyCompanyName__. All rights reserved.
//

#include "TameParse/Lr/conflict.h"

using namespace std;
using namespace contextfree;
using namespace lr;

/// \brief Creates a new conflict object (describing a non-conflict)
conflict::conflict(int stateId, const item_container& token)
: m_StateId(stateId)
, m_Token(token) {
}

/// \brief Copy constructor
conflict::conflict(const conflict& copyFrom)
: m_StateId(copyFrom.m_StateId)
, m_Token(copyFrom.m_Token)
, m_Shift(copyFrom.m_Shift)
, m_Reduce(copyFrom.m_Reduce) {
}

/// \brief Destroys this conflict object
conflict::~conflict() { }

/// \brief Clones this conflict
conflict* conflict::clone() const {
    return new conflict(*this);
}

/// \brief Returns true if conflict a is less than conflict b
bool conflict::compare(const conflict* a, const conflict* b) {
    if (a == b) return false;
    if (!a) return true;
    if (!b) return false;

    return (*a) < (*b);
}

/// \brief Orders this conflict relative to another
bool conflict::operator<(const conflict& compareTo) const {
    if (m_StateId < compareTo.m_StateId)    return true;
    if (m_StateId > compareTo.m_StateId)    return false;

    if (m_Token < compareTo.m_Token)        return true;
    if (compareTo.m_Token < m_Token)        return false;

    if (m_Shift < compareTo.m_Shift)        return true;
    if (m_Shift > compareTo.m_Shift)        return false;

    if (m_Reduce < compareTo.m_Reduce)      return true;

    return false;
}

/// \brief Adds an LR(0) item that will be followed if the token is shifted
void conflict::add_shift_item(const lr0_item_container& item) {
    m_Shift.insert(item);
}

/// \brief Adds an LR(0) item that will be reduced if the token is in the lookahead
///
/// This returns an item that the caller can add the set of reduce states for this item
conflict::possible_reduce_states& conflict::add_reduce_item(const lr0_item_container& item) {
    return m_Reduce[item];
}

/// \brief Adds the conflicts found in a single state of the specified LALR builder to the given target list
static void find_conflicts(const lalr_builder& builder, int stateId, conflict_list& target) {
    // Get the actions in this state
    const lr_action_set& actions = builder.actions_for_state(stateId);

    // Run through these actions, and find places where there are conflicts (two actions for a single symbol)
    typedef map<item_container, lr_action_set> items_to_actions;
    items_to_actions actionsForItem;

    for (lr_action_set::const_iterator nextAction = actions.begin(); nextAction != actions.end(); nextAction++) {
        // Ignore actions that don't cause conflicts
        bool ignore;
        switch ((*nextAction)->type()) {
            case lr_action::act_goto:
            case lr_action::act_ignore:
            case lr_action::act_accept:
                ignore = true;
                break;

            default:
                ignore = false;
                break;
        }
        if (ignore) continue;

        // Add this as an action for this item
        actionsForItem[(*nextAction)->item()].insert(*nextAction);
    }

    // Generate conflicts for any item with multiple actions
    for (items_to_actions::iterator nextItem = actionsForItem.begin(); nextItem != actionsForItem.end(); nextItem++) {
        // Ignore items with just one action (or no actions, if that's ever possible)
        if (nextItem->second.size() < 2) continue;

        // Ignore items if all but one of the items are 'weak'
        int numWeak = 0;
        for (lr_action_set::const_iterator nextAction = nextItem->second.begin(); nextAction != nextItem->second.end(); nextAction++) {
            switch ((*nextAction)->type()) {
                case lr_action::act_guard:
                case lr_action::act_weakreduce:
                case lr_action::act_ignore:
                    numWeak++;
                    break;

                default:
                    break;
            }
        }

        if (nextItem->second.size() - numWeak < 2) continue;

        // Create a new conflict for this action
        const item_container&   conflictToken = *nextItem->first;
        conflict_container      newConf(new conflict(stateId, conflictToken), true);

        // Fetch the items in this state
        const lalr_state& thisState = *builder.machine().state_with_id(stateId);

        // Get the closure of this state
        lr1_item_set closure;
        builder.generate_closure(thisState, closure, &builder.gram());

        // Describe the actions resulting in this conflict by going through the items in the closure of the state
        const grammar*    gram = &builder.gram();

        // Iterate through the closure to get the items that can be shifted as part of this conflict
        for (lr1_item_set::const_iterator nextItem = closure.begin(); nextItem != closure.end(); nextItem++) {
            if (!(*nextItem)->at_end()) {
                // This item will result in a shift: add it to the list if it can shift our item
                const item_set& firstItems = gram->first((*nextItem)->rule()->items()[(*nextItem)->offset()]);

                if (firstItems.contains(conflictToken)) {
                    // This item can result in a shift of the specified token
                    newConf->add_shift_item(**nextItem);
                }
            }
        }

        // Iterate through the items in the state to look for the reduce actions
        for (int itemId = 0; itemId < thisState.count_items(); itemId++) {
            // Get the item that this refers to
            const lalr_state::container& thisItem = thisState[itemId];

            // Get the lookahead for this item
            const lr1_item::lookahead_set& la = *thisState.lookahead_for(thisItem);

            // If this state isn't a reducing state, then compute the closure to see if it produces any reducing states on the conflicted nonterminal
            if (!thisItem->at_end()) {
                // Fetch the rule for this item
                const rule& rule    = *thisItem->rule();
                int         offset  = thisItem->offset();

                // Generate the closure for this item
                lr1_item        nextItem(thisItem, la);
                lr1_item_set    itemClosure;

                rule.items()[offset]->cache_closure(nextItem, itemClosure, *gram);

                // For any items in the closure that are at the end and have a reduce action, generate some reduce information
                for (lr1_item_set::iterator closureItem = itemClosure.begin(); closureItem != itemClosure.end(); closureItem++) {
                    // Ignore items that are not at the end of the closure
                    if (!(*closureItem)->at_end()) continue;

                    // Ignore items that do not contain the closure item in their lookahead
                    if (!(*closureItem)->lookahead().contains(conflictToken)) continue;

                    // This item is part of the conflict: add a new reduce item
                    conflict::possible_reduce_states& reduceTo = newConf->add_reduce_item(**closureItem);

                    // Add a reduction action for this (for this nonterminal, we just end up in the same state)
                    reduceTo.insert(conflict::lr_item_id(stateId, itemId));
                }

                // TODO: if the symbols following the current state can be reduced to the empty symbol then we need to indicate where the rest of the lookahead comes from
                continue;
            }

            // This is a reducing state

            // This isn't part of the conflict if it isn't being reduced based on the
            if (!la.contains(conflictToken)) continue;

            // Add a conflict for this item
            conflict::possible_reduce_states& reduceTo = newConf->add_reduce_item(thisItem);

            // Work out which states can be reached by looking at the spontaneous and lookahead propagation
            typedef set<conflict::lr_item_id>  lr_item_id_set;
            lr_item_id_set sourceItems;
            builder.find_lookahead_source(stateId, itemId, conflictToken, sourceItems);

            // Add to the reduce set
            reduceTo.insert(sourceItems.begin(), sourceItems.end());
        }

        // Ignore conflicts that contain no items at all
        if (newConf->first_reduce_item() == newConf->last_reduce_item() && newConf->first_shift_item() == newConf->last_shift_item()) {
            // These items are generally caused by things like weak symbols where the action was generated spontaneously from a strong symbol
            continue;
        }

        // Add the new conflict to the list
        target.push_back(newConf);
    }
}

/// \brief Adds the conflicts found in the specified LALR builder object to the passed in list
void conflict::find_conflicts(const lalr_builder& builder, conflict_list& target) {
    // Iterate through the states in the builder
    for (int stateId=0; stateId < builder.count_states(); stateId++) {
        ::find_conflicts(builder, stateId, target);
    }
}

<|endoftext|>


<commit_before>/******************************************************************
This is the primary class for the Patriot IoT library.

It aggregates all the other classes, and provides
a common API for adding and configuring devices.

This class coordinates realtime events.
It subscribes to Particle.io notifications, and
        distributes them to devices and activities.

http://www.github.com/rlisle/Patriot

Written by Ron Lisle

BSD license, check LICENSE for more information.
All text above must be included in any redistribution.

Changelog:
2017-10-22: Convert to scene-like behavior
2017-10-12: Add control using device names
2017-05-15: Make devices generic
2017-03-24: Rename Patriot
2017-03-05: Convert to v2 particle library
2016-11-24: Initial version
******************************************************************/
#include "IoT.h"

void mqttHandler(char* topic, byte* payload, unsigned int length);

/**
 * Global subscribe handler
 * Called by particle.io when events are published.
 *
 * @param eventName
 * @param rawData
 */
void globalSubscribeHandler(const char *eventName, const char *rawData) {
    IoT* iot = IoT::getInstance();
    iot->subscribeHandler(eventName,rawData);
}

/**
 * Supported Activities variable
 * This variable is updated to contain a comma separated list of
 * the activity names supported by this controller.
 * This allows applications to automatically determine activity names
 */
String supportedActivitiesVariable;

/**
 * Publish Name variable
 * This variable communicates the Particle.io publish event name.
 * This allows applications to automatically determine the event name
 * to use when publishing or subscribing to events to/from this device.
 *
 * It is also used by plugins when publishing events.
 *
 * Note: Do not change this or the Alexa and iOS apps my not work.
 *       This will be fixed in the future.
 */
String publishNameVariable;

/**
 * Singleton IoT instance
 * Use getInstance() instead of constructor
 */
IoT* IoT::getInstance()
{
    if(_instance == NULL)
    {
        _instance = new IoT();
    }
    return _instance;
}
IoT* IoT::_instance = NULL;

/**
 * Helper log method
 * Simply passes msg along to Serial.println, but also provides
 * a spot to add more extensive logging or analytics
 * @param msg
 */
void IoT::log(String msg)
{
    Serial.println(msg);
    Particle.publish("LOG", msg, 60, PRIVATE);
}

/**
 * Constructor.
 */
IoT::IoT()
{
    // be sure not to call anything that requires hardware be initialized here, put those in begin()
    _hasBegun               = false;
    publishNameVariable     = kDefaultPublishName;
    _numSupportedActivities = 0;
}

/**
 * This function is used to change the particle.io publish
 * event name. Currently the event name is hardcoded to
 * 'patriot' in the Alexa skills and iOS apps.
 * In the future they will determine this from the Photon.
 * Until then, do not use this function.
 *
 * @param publishName
 */
void IoT::setPublishName(String publishName)
{
    publishNameVariable = publishName;
}

/**
 * Begin gets everything going.
 * It must be called exactly once by the sketch
 */
void IoT::begin()
{
    if(_hasBegun) return;
    _hasBegun = true;

    Serial.begin(57600);

    _activities = new Activities();
    _behaviors = new Behaviors();
    _devices = new Devices();
    _deviceNames = new DeviceNames();

    Particle.subscribe(publishNameVariable, globalSubscribeHandler, MY_DEVICES);
    if(!Particle.variable(kSupportedActivitiesVariableName, supportedActivitiesVariable))
    {
        log("Unable to expose "+String(kSupportedActivitiesVariableName)+" variable");
        return;
    }
    if(!Particle.variable(kPublishVariableName, publishNameVariable))
    {
        log("Unable to expose publishName variable");
        return;
    }

    // connect to MQTT broker
    mqtt.connect(publishNameVariable);  // argument ignored?
    if (mqtt.isConnected()) {
//        mqtt.publish("outTopic/message","hello world");
        mqtt.subscribe(publishNameVariable);
    }
}

void IoT::connectMQTT(char *brokerIP)
{
    _mqtt = MQTT(brokerIP, 1883, callback);
    _mqtt.connect(publishNameVariable);  // argument ignored?
    if (_mqtt.isConnected()) {
        _mqtt.subscribe(publishNameVariable);
    }
}

/**
 * Loop method must be called periodically,
 * typically from the sketch loop() method.
 */
void IoT::loop()
{
    if(!_hasBegun) return;

    _devices->loop();
}

// Add a Device
void IoT::addDevice(Device *device)
{
    _devices->addDevice(device);
    if(device->name() != "") {
        Serial.println("IoT adding device: "+device->name()+".");
        _deviceNames->addDevice(device->name());
    }
    else
    {
        Serial.println("IoT adding unnamed device. (Probably an input only device)");
    }
}

// Activities
void IoT::addBehavior(Behavior *behavior)
{
    _behaviors->addBehavior(behavior);
    addToListOfSupportedActivities(behavior->activityName);
}

void IoT::addToListOfSupportedActivities(String activity)
{
    for(int i=0; i<_numSupportedActivities; i++) {
        if(activity.equalsIgnoreCase(_supportedActivities[i])) return;
    }
    if(_numSupportedActivities < kMaxNumberActivities-1) {
        _supportedActivities[_numSupportedActivities++] = activity;
    }
    buildSupportedActivitiesVariable();
}

void IoT::buildSupportedActivitiesVariable()
{
    String newVariable = "";
    for(int i=0; i<_numSupportedActivities; i++)
    {
        newVariable += _supportedActivities[i];
        if (i < _numSupportedActivities-1) {
            newVariable += ",";
        }
    }
    if(newVariable.length() < kMaxVariableStringLength) {
        if(newVariable != supportedActivitiesVariable) {
            log("Supported activities = "+newVariable);
            supportedActivitiesVariable = newVariable;
        }
    } else {
        log("Supported activities variable is too long. Need to extend to a 2nd variable");
    }
}

/*************************************/
/*** Particle.io Subscribe Handler ***/
/*************************************/
void IoT::subscribeHandler(const char *eventName, const char *rawData)
{
    String data(rawData);
    String event(eventName);
    Serial.println("Subscribe handler event: " + event + ", data: " + data);
    int colonPosition = data.indexOf(':');
    String name = data.substring(0,colonPosition);
    String state = data.substring(colonPosition+1);

    // See if this is a device name. If so, update it.
     Device* device = _devices->getDeviceWithName(name);
     if(device)
     {
       int percent = state.toInt();
       Serial.println(" percent = "+String(percent));
       device->setPercent(percent);
       return;
     }

    // If it wasn't a device name, it must be an activity.
    int value = state.toInt();
    log("   performing activity " + name + " = " + String(value));
    _behaviors->performActivity(name, value);
}

/******************************/
/*** MQTT Subscribe Handler ***/
/******************************/
void IoT::mqttHandler(char* topic, byte* payload, unsigned int length) {
//    char p[length + 1];
//    memcpy(p, payload, length);
//    p[length] = NULL;
    String data(payload);
    String event(topic);
    Serial.println("MQTT handler event: " + event + ", data: " + data);
    int colonPosition = data.indexOf(':');
    String name = data.substring(0,colonPosition);
    String state = data.substring(colonPosition+1);

    // See if this is a device name. If so, update it.
    Device* device = _devices->getDeviceWithName(name);
    if(device)
    {
        int percent = state.toInt();
        Serial.println(" percent = "+String(percent));
        device->setPercent(percent);
        return;
    }

    // If it wasn't a device name, it must be an activity.
    int value = state.toInt();
    log("   performing activity " + name + " = " + String(value));
    _behaviors->performActivity(name, value);
}
<commit_msg>Partial MQTT support.<commit_after>/******************************************************************
This is the primary class for the Patriot IoT library.

It aggregates all the other classes, and provides
a common API for adding and configuring devices.

This class coordinates realtime events.
It subscribes to Particle.io notifications, and
        distributes them to devices and activities.

http://www.github.com/rlisle/Patriot

Written by Ron Lisle

BSD license, check LICENSE for more information.
All text above must be included in any redistribution.

Changelog:
2018-03-16: Add MQTT support
2017-10-22: Convert to scene-like behavior
2017-10-12: Add control using device names
2017-05-15: Make devices generic
2017-03-24: Rename Patriot
2017-03-05: Convert to v2 particle library
2016-11-24: Initial version
******************************************************************/
#include "IoT.h"

void mqttHandler(char* topic, byte* payload, unsigned int length);

/**
 * Global subscribe handler
 * Called by particle.io when events are published.
 *
 * @param eventName
 * @param rawData
 */
void globalSubscribeHandler(const char *eventName, const char *rawData) {
    IoT* iot = IoT::getInstance();
    iot->subscribeHandler(eventName,rawData);
}

/**
 * Supported Activities variable
 * This variable is updated to contain a comma separated list of
 * the activity names supported by this controller.
 * This allows applications to automatically determine activity names
 */
String supportedActivitiesVariable;

/**
 * Publish Name variable
 * This variable communicates the Particle.io publish event name.
 * This allows applications to automatically determine the event name
 * to use when publishing or subscribing to events to/from this device.
 *
 * It is also used by plugins when publishing events.
 *
 * Note: Do not change this or the Alexa and iOS apps my not work.
 *       This will be fixed in the future.
 */
String publishNameVariable;

/**
 * Singleton IoT instance
 * Use getInstance() instead of constructor
 */
IoT* IoT::getInstance()
{
    if(_instance == NULL)
    {
        _instance = new IoT();
    }
    return _instance;
}
IoT* IoT::_instance = NULL;

/**
 * Helper log method
 * Simply passes msg along to Serial.println, but also provides
 * a spot to add more extensive logging or analytics
 * @param msg
 */
void IoT::log(String msg)
{
    Serial.println(msg);
    Particle.publish("LOG", msg, 60, PRIVATE);
}

/**
 * Constructor.
 */
IoT::IoT()
{
    // be sure not to call anything that requires hardware be initialized here, put those in begin()
    _hasBegun               = false;
    publishNameVariable     = kDefaultPublishName;
    _numSupportedActivities = 0;
}

/**
 * This function is used to change the particle.io publish
 * event name. Currently the event name is hardcoded to
 * 'patriot' in the Alexa skills and iOS apps.
 * In the future they will determine this from the Photon.
 * Until then, do not use this function.
 *
 * @param publishName
 */
void IoT::setPublishName(String publishName)
{
    publishNameVariable = publishName;
}

/**
 * Begin gets everything going.
 * It must be called exactly once by the sketch
 */
void IoT::begin()
{
    if(_hasBegun) return;
    _hasBegun = true;

    Serial.begin(57600);

    _activities = new Activities();
    _behaviors = new Behaviors();
    _devices = new Devices();
    _deviceNames = new DeviceNames();

    Particle.subscribe(publishNameVariable, globalSubscribeHandler, MY_DEVICES);
    if(!Particle.variable(kSupportedActivitiesVariableName, supportedActivitiesVariable))
    {
        log("Unable to expose "+String(kSupportedActivitiesVariableName)+" variable");
        return;
    }
    if(!Particle.variable(kPublishVariableName, publishNameVariable))
    {
        log("Unable to expose publishName variable");
        return;
    }
}

void IoT::connectMQTT(char *brokerIP)
{
    // Do we need to disconnect if previously connected?
    _mqtt = MQTT(brokerIP, 1883, callback);
    _mqtt.connect(publishNameVariable);  // argument ignored?
    if (_mqtt.isConnected()) {
        _mqtt.subscribe(publishNameVariable);
    }
}

/**
 * Loop method must be called periodically,
 * typically from the sketch loop() method.
 */
void IoT::loop()
{
    if(!_hasBegun) return;

    _devices->loop();
}

// Add a Device
void IoT::addDevice(Device *device)
{
    _devices->addDevice(device);
    if(device->name() != "") {
        Serial.println("IoT adding device: "+device->name()+".");
        _deviceNames->addDevice(device->name());
    }
    else
    {
        Serial.println("IoT adding unnamed device. (Probably an input only device)");
    }
}

// Activities
void IoT::addBehavior(Behavior *behavior)
{
    _behaviors->addBehavior(behavior);
    addToListOfSupportedActivities(behavior->activityName);
}

void IoT::addToListOfSupportedActivities(String activity)
{
    for(int i=0; i<_numSupportedActivities; i++) {
        if(activity.equalsIgnoreCase(_supportedActivities[i])) return;
    }
    if(_numSupportedActivities < kMaxNumberActivities-1) {
        _supportedActivities[_numSupportedActivities++] = activity;
    }
    buildSupportedActivitiesVariable();
}

void IoT::buildSupportedActivitiesVariable()
{
    String newVariable = "";
    for(int i=0; i<_numSupportedActivities; i++)
    {
        newVariable += _supportedActivities[i];
        if (i < _numSupportedActivities-1) {
            newVariable += ",";
        }
    }
    if(newVariable.length() < kMaxVariableStringLength) {
        if(newVariable != supportedActivitiesVariable) {
            log("Supported activities = "+newVariable);
            supportedActivitiesVariable = newVariable;
        }
    } else {
        log("Supported activities variable is too long. Need to extend to a 2nd variable");
    }
}

/*************************************/
/*** Particle.io Subscribe Handler ***/
/*************************************/
void IoT::subscribeHandler(const char *eventName, const char *rawData)
{
    String data(rawData);
    String event(eventName);
    Serial.println("Subscribe handler event: " + event + ", data: " + data);
    int colonPosition = data.indexOf(':');
    String name = data.substring(0,colonPosition);
    String state = data.substring(colonPosition+1);

    // See if this is a device name. If so, update it.
     Device* device = _devices->getDeviceWithName(name);
     if(device)
     {
       int percent = state.toInt();
       Serial.println(" percent = "+String(percent));
       device->setPercent(percent);
       return;
     }

    // If it wasn't a device name, it must be an activity.
    int value = state.toInt();
    log("   performing activity " + name + " = " + String(value));
    _behaviors->performActivity(name, value);
}

/******************************/
/*** MQTT Subscribe Handler ***/
/******************************/
void IoT::mqttHandler(char* topic, byte* payload, unsigned int length) {
//    char p[length + 1];
//    memcpy(p, payload, length);
//    p[length] = NULL;
    String data(payload);
    String event(topic);
    Serial.println("MQTT handler event: " + event + ", data: " + data);
    int colonPosition = data.indexOf(':');
    String name = data.substring(0,colonPosition);
    String state = data.substring(colonPosition+1);

    // See if this is a device name. If so, update it.
    Device* device = _devices->getDeviceWithName(name);
    if(device)
    {
        int percent = state.toInt();
        Serial.println(" percent = "+String(percent));
        device->setPercent(percent);
        return;
    }

    // If it wasn't a device name, it must be an activity.
    int value = state.toInt();
    log("   performing activity " + name + " = " + String(value));
    _behaviors->performActivity(name, value);
}
<|endoftext|>


<commit_before>#include "Pong/States/GameState.hpp"

#include <iostream>

#include "Pong/Application.hpp"

#include "Pong/States/GameOverState.hpp"

#include "Pong/GameObjects/Ball.hpp"
#include "Pong/GameObjects/Racket.hpp"
#include "Pong/GameObjects/Wall.hpp"
#include "Pong/GameObjects/Midfield.hpp"
#include "Pong/GameObjects/PlayerRacket.hpp"
#include "Pong/GameObjects/ComputerRacket.hpp"

namespace pong {

void GameState::create() {
    setupGameWorld();
    setupGameObjects();
}

void GameState::update() {
    gameWorld_.update();

    ball_->update();
    leftRacket_->update();
    rightRacket_->update();
    scoreBoard_->update();

    if (scoreBoard_->isGameOver()) {
        ScoreBoard::Winner winner = scoreBoard_->winner();
        GameOverState* gameOver = new GameOverState(app_, this, winner);
        gameOver->create();
        app_->pushState(gameOver);
    }
}

void GameState::enter() {
    shade_->visible = false;
}

void GameState::exit() {
    shade_->visible = true;
}

void GameState::reset() {
    Ball* ball = static_cast<Ball*>(ball_.get());
    ball->reset();
}

void GameState::setupGameWorld() {
    gameWorld_.create();
    gameWorld_.start();

#ifndef NDEBUG
    debugDraw_.reset(new mxg::SFMLDebugDraw(app_->window(), PIXELS_PER_METER));
    gameWorld_.setDebugDraw(debugDraw_.get());
    debugDraw_->SetFlags(b2Draw::e_shapeBit);
#endif /* ifndef NDEBUG */
}

void GameState::setupGameObjects() {
    midfield_.reset(new Midfield());
    midfield_->create();

    Ball* ball = new Ball(gameWorld_);
    ball_.reset(ball);
    ball_->create();
    gameWorld_.addScoreListener(ball);

    leftRacket_.reset(new PlayerRacket(gameWorld_.leftRacket()));
    leftRacket_->create();

    ComputerRacket* computerRacket = new ComputerRacket(
        gameWorld_.rightRacket(),
        gameWorld_.ball()
    );
    computerRacket->xMaxDistance = (WINDOW_HALF_WIDTH - RACKET_WIDTH) / PIXELS_PER_METER;
    computerRacket->yMaxDistance = (RACKET_HALF_HEIGHT - 20.0f) / PIXELS_PER_METER;
    rightRacket_.reset(computerRacket);
    rightRacket_->create();

    topWall_.reset(new Wall(gameWorld_.topWall()));
    topWall_->create();
    bottomWall_.reset(new Wall(gameWorld_.bottomWall()));
    bottomWall_->create();

    ScoreBoard* scoreBoard = new ScoreBoard(app_->assets().defaultFont());
    gameWorld_.addScoreListener(scoreBoard);
    scoreBoard_.reset(scoreBoard);
    scoreBoard_->create();

    shade_.reset(new Shade());
    shade_->create();
}

void GameState::processEvent(const sf::Event& event) {
    DefaultState::processEvent(event);
}

void GameState::render(sf::RenderTarget& renderTarget) {
    renderTarget.draw(*midfield_);
    renderTarget.draw(*ball_);
    renderTarget.draw(*leftRacket_);
    renderTarget.draw(*rightRacket_);
    renderTarget.draw(*topWall_);
    renderTarget.draw(*bottomWall_);
    renderTarget.draw(*scoreBoard_);
    renderTarget.draw(*shade_);

#ifndef NDEBUG
    gameWorld_.drawDebugData();
#endif /* ifndef NDEBUG  */
}

} /* namespace pong */
<commit_msg>Draw scoreboard over the shade<commit_after>#include "Pong/States/GameState.hpp"

#include <iostream>

#include "Pong/Application.hpp"

#include "Pong/States/GameOverState.hpp"

#include "Pong/GameObjects/Ball.hpp"
#include "Pong/GameObjects/Racket.hpp"
#include "Pong/GameObjects/Wall.hpp"
#include "Pong/GameObjects/Midfield.hpp"
#include "Pong/GameObjects/PlayerRacket.hpp"
#include "Pong/GameObjects/ComputerRacket.hpp"

namespace pong {

void GameState::create() {
    setupGameWorld();
    setupGameObjects();
}

void GameState::update() {
    gameWorld_.update();

    ball_->update();
    leftRacket_->update();
    rightRacket_->update();
    scoreBoard_->update();

    if (scoreBoard_->isGameOver()) {
        ScoreBoard::Winner winner = scoreBoard_->winner();
        GameOverState* gameOver = new GameOverState(app_, this, winner);
        gameOver->create();
        app_->pushState(gameOver);
    }
}

void GameState::enter() {
    shade_->visible = false;
}

void GameState::exit() {
    shade_->visible = true;
}

void GameState::reset() {
    Ball* ball = static_cast<Ball*>(ball_.get());
    ball->reset();
}

void GameState::setupGameWorld() {
    gameWorld_.create();
    gameWorld_.start();

#ifndef NDEBUG
    debugDraw_.reset(new mxg::SFMLDebugDraw(app_->window(), PIXELS_PER_METER));
    gameWorld_.setDebugDraw(debugDraw_.get());
    debugDraw_->SetFlags(b2Draw::e_shapeBit);
#endif /* ifndef NDEBUG */
}

void GameState::setupGameObjects() {
    midfield_.reset(new Midfield());
    midfield_->create();

    Ball* ball = new Ball(gameWorld_);
    ball_.reset(ball);
    ball_->create();
    gameWorld_.addScoreListener(ball);

    leftRacket_.reset(new PlayerRacket(gameWorld_.leftRacket()));
    leftRacket_->create();

    ComputerRacket* computerRacket = new ComputerRacket(
        gameWorld_.rightRacket(),
        gameWorld_.ball()
    );
    computerRacket->xMaxDistance = (WINDOW_HALF_WIDTH - RACKET_WIDTH) / PIXELS_PER_METER;
    computerRacket->yMaxDistance = (RACKET_HALF_HEIGHT - 20.0f) / PIXELS_PER_METER;
    rightRacket_.reset(computerRacket);
    rightRacket_->create();

    topWall_.reset(new Wall(gameWorld_.topWall()));
    topWall_->create();
    bottomWall_.reset(new Wall(gameWorld_.bottomWall()));
    bottomWall_->create();

    ScoreBoard* scoreBoard = new ScoreBoard(app_->assets().defaultFont());
    gameWorld_.addScoreListener(scoreBoard);
    scoreBoard_.reset(scoreBoard);
    scoreBoard_->create();

    shade_.reset(new Shade());
    shade_->create();
}

void GameState::processEvent(const sf::Event& event) {
    DefaultState::processEvent(event);
}

void GameState::render(sf::RenderTarget& renderTarget) {
    renderTarget.draw(*midfield_);
    renderTarget.draw(*ball_);
    renderTarget.draw(*leftRacket_);
    renderTarget.draw(*rightRacket_);
    renderTarget.draw(*topWall_);
    renderTarget.draw(*bottomWall_);
    if (scoreBoard_->isGameOver()) {
        renderTarget.draw(*shade_);
        renderTarget.draw(*scoreBoard_);
    } else {
        renderTarget.draw(*scoreBoard_);
        renderTarget.draw(*shade_);
    }

#ifndef NDEBUG
    gameWorld_.drawDebugData();
#endif /* ifndef NDEBUG  */
}

} /* namespace pong */
<|endoftext|>


<commit_before>/* Copyright (c) 2009, Simeon Bird <spb41@cam.ac.uk>
 *               Based on code (c) 2005 by J. Bolton
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */

#ifndef NOGREAD

#include <math.h>
#include "global_vars.h"
#include "gadgetreader.hpp"

/* Snapshot information */
#define PARTTYPE 0/* Particle type required */

int load_header(const char *fname,double  *atime, double *redshift, double * Hz, double *box100, double *h100)
{
#ifndef SPLIT_NE
  GadgetReader::GSnap snap(fname);
#else
  const std::string blocks[14]={"HEAD","POS ","VEL ","ID  ","MASS","U   ","RHO ","NHP ","NHEP","NHEQ","NH  ","NHE ","HSML","SFR "};
  std::vector<std::string> BlockNames(blocks,blocks+14);
  GadgetReader::GSnap snap(fname, true,&BlockNames);
#endif
  if(snap.GetNumFiles() <= 0)
          return -1;
  (*atime)= snap.GetHeader().time;
  (*redshift)= snap.GetHeader().redshift;
  (*box100) = snap.GetHeader().BoxSize;
  (*h100) = snap.GetHeader().HubbleParam;
  (*Hz)=100.0*(*h100) * sqrt(1.+snap.GetHeader().Omega0*(1./(*atime)-1.)+snap.GetHeader().OmegaLambda*((pow(*atime,2)) -1.))/(*atime);
  printf("NumPart=[%ld,%ld,%ld,%ld,%ld,%ld), ",snap.GetNpart(0),snap.GetNpart(1),snap.GetNpart(2),snap.GetNpart(3),snap.GetNpart(4),snap.GetNpart(5));
  printf("Masses=[%g %g %g %g %g %g], ",snap.GetHeader().mass[0],snap.GetHeader().mass[1],snap.GetHeader().mass[2],snap.GetHeader().mass[3],snap.GetHeader().mass[4],snap.GetHeader().mass[5]);
  printf("Redshift=%g, Ω_M=%g Ω_L=%g\n",(*redshift),snap.GetHeader().Omega0,snap.GetHeader().OmegaLambda);
  printf("Expansion factor = %f\n",(*atime));
  printf("Hubble = %g Box=%g \n",(*h100),(*box100));
  return 0;

}

/* this routine loads particle data from Gadget's default
 * binary file format. (A snapshot may be distributed
 * into multiple files. */
int64_t load_snapshot(const char *fname,int64_t StartPart, pdata *P)
{
#ifndef SPLIT_NE
  GadgetReader::GSnap snap(fname);
#else
  const std::string blocks[14]={"HEAD","POS ","VEL ","ID  ","MASS","U   ","RHO ","NHP ","NHEP","NHEQ","NH  ","NHE ","HSML","SFR "};
  std::vector<std::string> BlockNames(blocks,blocks+14);
  GadgetReader::GSnap snap(fname, true,&BlockNames);
#endif
  const int64_t NumPart = snap.GetNpart(PARTTYPE)-StartPart;
  if(NumPart ==0)
          return 0;
  if(!(alloc_parts(P,NumPart)))
  {
    fprintf(stderr,"failed to allocate memory.\n\n");
    exit(1);
  }
  printf("Reading from %ld to %ld\n",StartPart,StartPart+NumPart);
  snap.GetBlock("POS ",(*P).Pos,NumPart,StartPart, (1<<N_TYPE)-1-(1<<PARTTYPE));
  snap.GetBlock("VEL ",(*P).Vel,NumPart,StartPart, (1<<N_TYPE)-1-(1<<PARTTYPE));
  /* Particles masses  */
  if(snap.GetHeader().mass[PARTTYPE])
        for(int i=0; i< NumPart;i++)
           (*P).Mass[i] = snap.GetHeader().mass[PARTTYPE];
  else{
        /*Set up types to skip; skip all types not in the mass array*/
        int skip = (1<<N_TYPE)-1-(1<<PARTTYPE);
        for(int i=0; i< N_TYPE; i++)
           if(snap.GetHeader().mass[i])
                   skip-=1<<i;
        snap.GetBlock("MASS",(*P).Mass,NumPart,StartPart, skip);
  }
  for(int i=0; i< NumPart;i++)
  if ((*P).Mass[i] != (*P).Mass[0]){
        fprintf(stderr, "i=%d N = %ld Mass change: %g\n",i,NumPart, (*P).Mass[i]);
        exit(0);
  }
  /*Seek past the last masses*/
  if(PARTTYPE == 0)
    {
      /*The internal energy of all the Sph particles is read in */
      snap.GetBlock("U   ",(*P).U,NumPart,StartPart,0);
      /* The free electron fraction */
      if(snap.GetHeader().flag_cooling)
        {
          /* Some versions of Gadget have Ne, some have NHP, NHEP and NHEPP,
           * which I map to NHEQ.*/
          /* Use that the universe is neutral, so
           * NE = NHP + NHEP +2 NHEPP*/
      #ifdef SPLIT_NE
          snap.GetBlock("NHP ",(*P).Ne,NumPart,StartPart,0);
          /*Use the space for HSML as temp space*/
          snap.GetBlock("NHEP",(*P).h,NumPart,StartPart,0);
          for(int k=0;k<NumPart;k++){
                  (*P).Ne[k]+=(*P).h[k];
          }
          snap.GetBlock("NHEQ",(*P).h,NumPart,StartPart,0);
          for(int k=0;k<NumPart;k++){
                  (*P).Ne[k]+=2*(*P).h[k];
          }
      #else
          snap.GetBlock("NE  ",(*P).Ne,NumPart,StartPart,0);
      #endif
      #ifdef HELIUM
          snap.GetBlock("NHE ",(*P).NHep,NumPart,StartPart,0);
      #endif
          /* The HI fraction, nHI/nH */
          snap.GetBlock("NH  ",(*P).fraction,NumPart,StartPart,0);
          /*An NHE block*/
        }
     /* The smoothing length */
     snap.GetBlock("HSML",(*P).h,NumPart,StartPart,0);
    }

  if(StartPart==0){
        printf("P[%d].Pos = [%g %g %g]\n", 0, (*P).Pos[0], (*P).Pos[1],(*P).Pos[2]);
        printf("P[%d].Vel = [%g %g %g]\n", 0, (*P).Vel[0], (*P).Vel[1],(*P).Vel[2]);
        printf("P[%ld].Mass = %e\n\n", NumPart, (*P).Mass[0]);
        printf("P[%ld].U = %f\n\n", NumPart, (*P).U[NumPart-1]);
        printf("P[%ld].Ne = %e\n", NumPart, (*P).Ne[NumPart-1]);
        printf("P[%ld].NH0 = %e\n", NumPart, (*P).fraction[NumPart-1]);
        printf("P[%ld].h = %f\n",NumPart, (*P).h[NumPart-1]);
  }
  return NumPart;
}

#endif //NOGREAD
<commit_msg>For gadget 2 type snapshots, use the RHO array directly instead of computing from the mass<commit_after>/* Copyright (c) 2009, Simeon Bird <spb41@cam.ac.uk>
 *               Based on code (c) 2005 by J. Bolton
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */

#ifndef NOGREAD

#include <math.h>
#include "global_vars.h"
#include "gadgetreader.hpp"

/* Snapshot information */
#define PARTTYPE 0/* Particle type required */

int load_header(const char *fname,double  *atime, double *redshift, double * Hz, double *box100, double *h100)
{
#ifndef SPLIT_NE
  GadgetReader::GSnap snap(fname);
#else
  const std::string blocks[14]={"HEAD","POS ","VEL ","ID  ","MASS","U   ","RHO ","NHP ","NHEP","NHEQ","NH  ","NHE ","HSML","SFR "};
  std::vector<std::string> BlockNames(blocks,blocks+14);
  GadgetReader::GSnap snap(fname, true,&BlockNames);
#endif
  if(snap.GetNumFiles() <= 0)
          return -1;
  (*atime)= snap.GetHeader().time;
  (*redshift)= snap.GetHeader().redshift;
  (*box100) = snap.GetHeader().BoxSize;
  (*h100) = snap.GetHeader().HubbleParam;
  (*Hz)=100.0*(*h100) * sqrt(1.+snap.GetHeader().Omega0*(1./(*atime)-1.)+snap.GetHeader().OmegaLambda*((pow(*atime,2)) -1.))/(*atime);
  printf("NumPart=[%ld,%ld,%ld,%ld,%ld,%ld), ",snap.GetNpart(0),snap.GetNpart(1),snap.GetNpart(2),snap.GetNpart(3),snap.GetNpart(4),snap.GetNpart(5));
  printf("Masses=[%g %g %g %g %g %g], ",snap.GetHeader().mass[0],snap.GetHeader().mass[1],snap.GetHeader().mass[2],snap.GetHeader().mass[3],snap.GetHeader().mass[4],snap.GetHeader().mass[5]);
  printf("Redshift=%g, Ω_M=%g Ω_L=%g\n",(*redshift),snap.GetHeader().Omega0,snap.GetHeader().OmegaLambda);
  printf("Expansion factor = %f\n",(*atime));
  printf("Hubble = %g Box=%g \n",(*h100),(*box100));
  return 0;

}

/* this routine loads particle data from Gadget's default
 * binary file format. (A snapshot may be distributed
 * into multiple files. */
int64_t load_snapshot(const char *fname,int64_t StartPart, pdata *P)
{
#ifndef SPLIT_NE
  GadgetReader::GSnap snap(fname);
#else
  const std::string blocks[14]={"HEAD","POS ","VEL ","ID  ","MASS","U   ","RHO ","NHP ","NHEP","NHEQ","NH  ","NHE ","HSML","SFR "};
  std::vector<std::string> BlockNames(blocks,blocks+14);
  GadgetReader::GSnap snap(fname, true,&BlockNames);
#endif
  const int64_t NumPart = snap.GetNpart(PARTTYPE)-StartPart;
  if(NumPart ==0)
          return 0;
  if(!(alloc_parts(P,NumPart)))
  {
    fprintf(stderr,"failed to allocate memory.\n\n");
    exit(1);
  }
  printf("Reading from %ld to %ld\n",StartPart,StartPart+NumPart);
  snap.GetBlock("POS ",(*P).Pos,NumPart,StartPart, (1<<N_TYPE)-1-(1<<PARTTYPE));
  snap.GetBlock("VEL ",(*P).Vel,NumPart,StartPart, (1<<N_TYPE)-1-(1<<PARTTYPE));
  /* Particle densities */
  snap.GetBlock("RHO ",(*P).Mass,NumPart,StartPart, (1<<N_TYPE)-1-(1<<PARTTYPE));
  for(int i=0; i< NumPart;i++)
  if ((*P).Mass[i] != (*P).Mass[0]){
        fprintf(stderr, "i=%d N = %ld Mass change: %g\n",i,NumPart, (*P).Mass[i]);
        exit(0);
  }
  /*Seek past the last masses*/
  if(PARTTYPE == 0)
    {
      /*The internal energy of all the Sph particles is read in */
      snap.GetBlock("U   ",(*P).U,NumPart,StartPart,0);
      /* The free electron fraction */
      if(snap.GetHeader().flag_cooling)
        {
          /* Some versions of Gadget have Ne, some have NHP, NHEP and NHEPP,
           * which I map to NHEQ.*/
          /* Use that the universe is neutral, so
           * NE = NHP + NHEP +2 NHEPP*/
      #ifdef SPLIT_NE
          snap.GetBlock("NHP ",(*P).Ne,NumPart,StartPart,0);
          /*Use the space for HSML as temp space*/
          snap.GetBlock("NHEP",(*P).h,NumPart,StartPart,0);
          for(int k=0;k<NumPart;k++){
                  (*P).Ne[k]+=(*P).h[k];
          }
          snap.GetBlock("NHEQ",(*P).h,NumPart,StartPart,0);
          for(int k=0;k<NumPart;k++){
                  (*P).Ne[k]+=2*(*P).h[k];
          }
      #else
          snap.GetBlock("NE  ",(*P).Ne,NumPart,StartPart,0);
      #endif
      #ifdef HELIUM
          snap.GetBlock("NHE ",(*P).NHep,NumPart,StartPart,0);
      #endif
          /* The HI fraction, nHI/nH */
          snap.GetBlock("NH  ",(*P).fraction,NumPart,StartPart,0);
          /*An NHE block*/
        }
     /* The smoothing length */
     snap.GetBlock("HSML",(*P).h,NumPart,StartPart,0);
    }

  if(StartPart==0){
        printf("P[%d].Pos = [%g %g %g]\n", 0, (*P).Pos[0], (*P).Pos[1],(*P).Pos[2]);
        printf("P[%d].Vel = [%g %g %g]\n", 0, (*P).Vel[0], (*P).Vel[1],(*P).Vel[2]);
        printf("P[%ld].Mass = %e\n\n", NumPart, (*P).Mass[0]);
        printf("P[%ld].U = %f\n\n", NumPart, (*P).U[NumPart-1]);
        printf("P[%ld].Ne = %e\n", NumPart, (*P).Ne[NumPart-1]);
        printf("P[%ld].NH0 = %e\n", NumPart, (*P).fraction[NumPart-1]);
        printf("P[%ld].h = %f\n",NumPart, (*P).h[NumPart-1]);
  }
  return NumPart;
}

#endif //NOGREAD
<|endoftext|>


<commit_before>// @(#)root/rfio:$Name:  $:$Id: TRFIOFile.cxx,v 1.15 2001/09/27 17:57:25 rdm Exp $
// Author: Fons Rademakers   20/01/99

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TRFIOFile                                                            //
//                                                                      //
// A TRFIOFile is like a normal TFile except that it reads and writes   //
// its data via a rfiod server (for more on the rfiod daemon see        //
// http://wwwinfo.cern.ch/pdp/serv/shift.html). TRFIOFile file names    //
// are in standard URL format with protocol "rfio". The following are   //
// valid TRFIOFile URL's:                                               //
//                                                                      //
//    rfio:/afs/cern.ch/user/r/rdm/galice.root                          //
//         where galice.root is a symlink of the type /shift/.../...    //
//    rfio:na49db1:/data1/raw.root                                      //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "TRFIOFile.h"
#include "TSystem.h"
#include "TROOT.h"
#include <sys/stat.h>
#ifndef R__WIN32
#include <unistd.h>
#endif

extern "C" {
   int   rfio_open(char *filepath, int flags, int mode);
   int   rfio_close(int s);
   int   rfio_read(int s, char *ptr, int size);
   int   rfio_write(int s, char *ptr, int size);
   int   rfio_lseek(int s, int offset, int how);
   int   rfio_access(char *filepath, int mode);
   int   rfio_unlink(char *filepath);
   int   rfio_parse(char *name, char **host, char **path);
   int   rfio_fstat(int s, struct stat *statbuf);
   void  rfio_perror(const char *msg);
   char *rfio_serror();
#ifdef R__WIN32
   int  *C__serrno(void);
   int  *C__rfio_errno (void);
#endif
};

#ifdef R__WIN32

// Thread safe rfio_errno. Note, C__rfio_errno is defined in Cglobals.c rather
// than rfio/error.c.
#define rfio_errno (*C__rfio_errno())

// Thread safe serrno. Note, C__serrno is defined in Cglobals.c rather
// rather than serror.c.
#define serrno (*C__serrno())

#else

extern int rfio_errno;
extern int serrno;

#endif

ClassImp(TRFIOFile)

//______________________________________________________________________________
TRFIOFile::TRFIOFile(const char *url, Option_t *option, const char *ftitle,
                     Int_t compress)
         : TFile(url, "NET", ftitle, compress), fUrl(url)
{
   // Create a RFIO file object. A RFIO file is the same as a TFile
   // except that it is being accessed via a rfiod server. The url
   // argument must be of the form: rfio:/path/file.root (where file.root
   // is a symlink of type /shift/aaa/bbb/ccc) or rfio:server:/path/file.root.
   // If the file specified in the URL does not exist, is not accessable
   // or can not be created the kZombie bit will be set in the TRFIOFile
   // object. Use IsZombie() to see if the file is accessable.
   // For a description of the option and other arguments see the TFile ctor.
   // The preferred interface to this constructor is via TFile::Open().

   fOption = option;
   fOffset = 0;

   Bool_t create = kFALSE;
   if (!fOption.CompareTo("NEW", TString::kIgnoreCase) ||
       !fOption.CompareTo("CREATE", TString::kIgnoreCase))
       create = kTRUE;
   Bool_t recreate = fOption.CompareTo("RECREATE", TString::kIgnoreCase)
                    ? kFALSE : kTRUE;
   Bool_t update   = fOption.CompareTo("UPDATE", TString::kIgnoreCase)
                    ? kFALSE : kTRUE;
   Bool_t read     = fOption.CompareTo("READ", TString::kIgnoreCase)
                    ? kFALSE : kTRUE;
   if (!create && !recreate && !update && !read) {
      read    = kTRUE;
      fOption = "READ";
   }

   TString stmp;
   char *fname;
   if ((fname = gSystem->ExpandPathName(fUrl.GetFile()))) {
      if (!strstr(fname, ":/")) {
         char *host;
         char *name;
         if (::rfio_parse(fname, &host, &name))
            stmp = Form("%s:%s", host, name);
         else
            stmp = fname;
      } else
         stmp = fname;
      delete [] fname;
      fname = (char *)stmp.Data();
   } else {
      Error("TRFIOFile", "error expanding path %s", fUrl.GetFile());
      goto zombie;
   }

   if (recreate) {
      if (::rfio_access(fname, kFileExists) == 0)
         ::rfio_unlink(fname);
      recreate = kFALSE;
      create   = kTRUE;
      fOption  = "CREATE";
   }
   if (create && ::rfio_access(fname, kFileExists) == 0) {
      Error("TRFIOFile", "file %s already exists", fname);
      goto zombie;
   }
   if (update) {
      if (::rfio_access(fname, kFileExists) != 0) {
         update = kFALSE;
         create = kTRUE;
      }
      if (update && ::rfio_access(fname, kWritePermission) != 0) {
         Error("TRFIOFile", "no write permission, could not open file %s", fname);
         goto zombie;
      }
   }
   if (read) {
      if (::rfio_access(fname, kFileExists) != 0) {
         Error("TRFIOFile", "file %s does not exist", fname);
         goto zombie;
      }
      if (::rfio_access(fname, kReadPermission) != 0) {
         Error("TRFIOFile", "no read permission, could not open file %s", fname);
         goto zombie;
      }
   }

   if (create || update) {
#ifndef WIN32
      fD = SysOpen(fname, O_RDWR | O_CREAT, 0644);
#else
      fD = SysOpen(fname, O_RDWR | O_CREAT | O_BINARY, S_IREAD | S_IWRITE);
#endif
      if (fD == -1) {
         SysError("TRFIOFile", "file %s can not be opened", fname);
         goto zombie;
      }
      fWritable = kTRUE;
   } else {
#ifndef WIN32
      fD = SysOpen(fname, O_RDONLY, 0644);
#else
      fD = SysOpen(fname, O_RDONLY | O_BINARY, S_IREAD | S_IWRITE);
#endif
      if (fD == -1) {
         SysError("TRFIOFile", "file %s can not be opened for reading", fname);
         goto zombie;
      }
      fWritable = kFALSE;
   }

   Init(create);

   return;

zombie:
   // error in file opening occured, make this object a zombie
   MakeZombie();
   gDirectory = gROOT;
}

//______________________________________________________________________________
TRFIOFile::~TRFIOFile()
{
   // RFIO file dtor. Close and flush directory structure.

   Close();
}

//______________________________________________________________________________
Int_t TRFIOFile::SysOpen(const char *pathname, Int_t flags, UInt_t mode)
{
   // Interface to system open. All arguments like in "man 2 open".

   Int_t ret = ::rfio_open((char *)pathname, flags, (Int_t) mode);
   if (ret < 0)
      gSystem->SetErrorStr(::rfio_serror());
   return ret;
}

//______________________________________________________________________________
Int_t TRFIOFile::SysClose(Int_t fd)
{
   // Interface to system close. All arguments like in "man 2 close".

   Int_t ret = ::rfio_close(fd);
   if (ret < 0)
      gSystem->SetErrorStr(::rfio_serror());
   return ret;
}

//______________________________________________________________________________
Int_t TRFIOFile::SysRead(Int_t fd, void *buf, Int_t len)
{
   // Interface to system read. All arguments like in "man 2 read".

   fOffset += len;
   Int_t ret = ::rfio_read(fd, (char *)buf, len);
   if (ret < 0)
      gSystem->SetErrorStr(::rfio_serror());
   return ret;
}

//______________________________________________________________________________
Int_t TRFIOFile::SysWrite(Int_t fd, const void *buf, Int_t len)
{
   // Interface to system write. All arguments like in "man 2 write".

   fOffset += len;
   Int_t ret = ::rfio_write(fd, (char *)buf, len);
   if (ret < 0)
      gSystem->SetErrorStr(::rfio_serror());
   return ret;
}

//______________________________________________________________________________
Seek_t TRFIOFile::SysSeek(Int_t fd, Seek_t offset, Int_t whence)
{
   // Interface to system lseek. All arguments like in "man 2 lseek"
   // except that the offset and return value are Long_t to be able to
   // handle 64 bit file systems.

   switch (whence) {
   case SEEK_SET:
      if (offset == fOffset)
         return 0;
      else
         fOffset = offset;
      break;
   case SEEK_CUR:
      fOffset += offset;
      break;
   case SEEK_END:
      fOffset = fEND + offset;
      break;
   }

   Seek_t ret = ::rfio_lseek(fd, offset, whence);
   if (ret < 0)
      gSystem->SetErrorStr(::rfio_serror());
   return ret;
}

//______________________________________________________________________________
Int_t TRFIOFile::SysStat(Int_t fd, Long_t *id, Long_t *size, Long_t *flags,
                         Long_t *modtime)
{
   // Interface to TSystem:GetPathInfo(). Generally implemented via
   // stat() or fstat().

   struct stat statbuf;

   if (::rfio_fstat(fd, &statbuf) >= 0) {
      if (id)
#if defined(R__KCC) && defined(R__LINUX)
         *id = (statbuf.st_dev.__val[0] << 24) + statbuf.st_ino;
#else
         *id = (statbuf.st_dev << 24) + statbuf.st_ino;
#endif
      if (size)
         *size = statbuf.st_size;
      if (modtime)
         *modtime = statbuf.st_mtime;
      if (flags) {
         *flags = 0;
         if (statbuf.st_mode & ((S_IEXEC)|(S_IEXEC>>3)|(S_IEXEC>>6)))
            *flags |= 1;
         if ((statbuf.st_mode & S_IFMT) == S_IFDIR)
            *flags |= 2;
         if ((statbuf.st_mode & S_IFMT) != S_IFREG &&
             (statbuf.st_mode & S_IFMT) != S_IFDIR)
            *flags |= 4;
      }
      return 0;
   }

   gSystem->SetErrorStr(::rfio_serror());
   return 1;
}

//______________________________________________________________________________
Bool_t TRFIOFile::ReadBuffer(char *buf, Int_t len)
{
   // Read specified byte range from remote file via rfiod daemon.
   // Returns kTRUE in case of error.

   if (fCache) {
      Int_t st;
      Seek_t off = fOffset;
      if ((st = fCache->ReadBuffer(fOffset, buf, len)) < 0) {
         Error("ReadBuffer", "error reading from cache");
         return kTRUE;
      }
      if (st > 0) {
         // fOffset might have been changed via TCache::ReadBuffer(), reset it
         fOffset = off + len;
         return kFALSE;
      }
   }

   return TFile::ReadBuffer(buf, len);
}

//______________________________________________________________________________
Bool_t TRFIOFile::WriteBuffer(const char *buf, Int_t len)
{
   // Write specified byte range to remote file via rootd daemon.
   // Returns kTRUE in case of error.

   if (!IsOpen() || !fWritable) return kTRUE;

   if (fCache) {
      Int_t st;
      Seek_t off = fOffset;
      if ((st = fCache->WriteBuffer(fOffset, buf, len)) < 0) {
         Error("WriteBuffer", "error writing to cache");
         return kTRUE;
      }
      if (st > 0) {
         // fOffset might have been changed via TCache::WriteBuffer(), reset it
         fOffset = off + len;
         return kFALSE;
      }
   }

   return TFile::WriteBuffer(buf, len);
}

//______________________________________________________________________________
Int_t TRFIOFile::GetErrno() const
{
   // Method returning rfio_errno. For RFIO files must use this
   // function since we need to check rfio_errno then serrno and finally errno.

   if (rfio_errno)
      return rfio_errno;
   if (serrno)
      return serrno;
   return TSystem::GetErrno();
}

//______________________________________________________________________________
void TRFIOFile::ResetErrno() const
{
   // Method resetting the rfio_errno, serrno and errno.

   rfio_errno = 0;
   serrno = 0;
   TSystem::ResetErrno();
}
<commit_msg>use rfiosetopt() to turn of buffered reading. ROOT buffers itself.<commit_after>// @(#)root/rfio:$Name:  $:$Id: TRFIOFile.cxx,v 1.16 2002/01/27 17:23:19 rdm Exp $
// Author: Fons Rademakers   20/01/99

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TRFIOFile                                                            //
//                                                                      //
// A TRFIOFile is like a normal TFile except that it reads and writes   //
// its data via a rfiod server (for more on the rfiod daemon see        //
// http://wwwinfo.cern.ch/pdp/serv/shift.html). TRFIOFile file names    //
// are in standard URL format with protocol "rfio". The following are   //
// valid TRFIOFile URL's:                                               //
//                                                                      //
//    rfio:/afs/cern.ch/user/r/rdm/galice.root                          //
//         where galice.root is a symlink of the type /shift/.../...    //
//    rfio:na49db1:/data1/raw.root                                      //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "TRFIOFile.h"
#include "TSystem.h"
#include "TROOT.h"
#include <sys/stat.h>
#ifndef R__WIN32
#include <unistd.h>
#endif

extern "C" {
   int   rfio_open(char *filepath, int flags, int mode);
   int   rfio_close(int s);
   int   rfio_read(int s, char *ptr, int size);
   int   rfio_write(int s, char *ptr, int size);
   int   rfio_lseek(int s, int offset, int how);
   int   rfio_access(char *filepath, int mode);
   int   rfio_unlink(char *filepath);
   int   rfio_parse(char *name, char **host, char **path);
   int   rfio_fstat(int s, struct stat *statbuf);
   void  rfio_perror(const char *msg);
   char *rfio_serror();
   int   rfiosetopt(int opt, int *pval, int len);
#ifdef R__WIN32
   int  *C__serrno(void);
   int  *C__rfio_errno (void);
#endif
};

#ifndef RFIO_READOPT
#define RFIO_READOPT 1
#endif

#ifdef R__WIN32

// Thread safe rfio_errno. Note, C__rfio_errno is defined in Cglobals.c rather
// than rfio/error.c.
#define rfio_errno (*C__rfio_errno())

// Thread safe serrno. Note, C__serrno is defined in Cglobals.c rather
// rather than serror.c.
#define serrno (*C__serrno())

#else

extern int rfio_errno;
extern int serrno;

#endif

ClassImp(TRFIOFile)

//______________________________________________________________________________
TRFIOFile::TRFIOFile(const char *url, Option_t *option, const char *ftitle,
                     Int_t compress)
         : TFile(url, "NET", ftitle, compress), fUrl(url)
{
   // Create a RFIO file object. A RFIO file is the same as a TFile
   // except that it is being accessed via a rfiod server. The url
   // argument must be of the form: rfio:/path/file.root (where file.root
   // is a symlink of type /shift/aaa/bbb/ccc) or rfio:server:/path/file.root.
   // If the file specified in the URL does not exist, is not accessable
   // or can not be created the kZombie bit will be set in the TRFIOFile
   // object. Use IsZombie() to see if the file is accessable.
   // For a description of the option and other arguments see the TFile ctor.
   // The preferred interface to this constructor is via TFile::Open().

   fOption = option;
   fOffset = 0;

   // tell RFIO to not read large buffers, ROOT does own buffering
   Int_t readopt = 0;
   ::rfiosetopt(RFIO_READOPT, &readopt, 4);

   Bool_t create = kFALSE;
   if (!fOption.CompareTo("NEW", TString::kIgnoreCase) ||
       !fOption.CompareTo("CREATE", TString::kIgnoreCase))
       create = kTRUE;
   Bool_t recreate = fOption.CompareTo("RECREATE", TString::kIgnoreCase)
                    ? kFALSE : kTRUE;
   Bool_t update   = fOption.CompareTo("UPDATE", TString::kIgnoreCase)
                    ? kFALSE : kTRUE;
   Bool_t read     = fOption.CompareTo("READ", TString::kIgnoreCase)
                    ? kFALSE : kTRUE;
   if (!create && !recreate && !update && !read) {
      read    = kTRUE;
      fOption = "READ";
   }

   TString stmp;
   char *fname;
   if ((fname = gSystem->ExpandPathName(fUrl.GetFile()))) {
      if (!strstr(fname, ":/")) {
         char *host;
         char *name;
         if (::rfio_parse(fname, &host, &name))
            stmp = Form("%s:%s", host, name);
         else
            stmp = fname;
      } else
         stmp = fname;
      delete [] fname;
      fname = (char *)stmp.Data();
   } else {
      Error("TRFIOFile", "error expanding path %s", fUrl.GetFile());
      goto zombie;
   }

   if (recreate) {
      if (::rfio_access(fname, kFileExists) == 0)
         ::rfio_unlink(fname);
      recreate = kFALSE;
      create   = kTRUE;
      fOption  = "CREATE";
   }
   if (create && ::rfio_access(fname, kFileExists) == 0) {
      Error("TRFIOFile", "file %s already exists", fname);
      goto zombie;
   }
   if (update) {
      if (::rfio_access(fname, kFileExists) != 0) {
         update = kFALSE;
         create = kTRUE;
      }
      if (update && ::rfio_access(fname, kWritePermission) != 0) {
         Error("TRFIOFile", "no write permission, could not open file %s", fname);
         goto zombie;
      }
   }
   if (read) {
      if (::rfio_access(fname, kFileExists) != 0) {
         Error("TRFIOFile", "file %s does not exist", fname);
         goto zombie;
      }
      if (::rfio_access(fname, kReadPermission) != 0) {
         Error("TRFIOFile", "no read permission, could not open file %s", fname);
         goto zombie;
      }
   }

   if (create || update) {
#ifndef WIN32
      fD = SysOpen(fname, O_RDWR | O_CREAT, 0644);
#else
      fD = SysOpen(fname, O_RDWR | O_CREAT | O_BINARY, S_IREAD | S_IWRITE);
#endif
      if (fD == -1) {
         SysError("TRFIOFile", "file %s can not be opened", fname);
         goto zombie;
      }
      fWritable = kTRUE;
   } else {
#ifndef WIN32
      fD = SysOpen(fname, O_RDONLY, 0644);
#else
      fD = SysOpen(fname, O_RDONLY | O_BINARY, S_IREAD | S_IWRITE);
#endif
      if (fD == -1) {
         SysError("TRFIOFile", "file %s can not be opened for reading", fname);
         goto zombie;
      }
      fWritable = kFALSE;
   }

   Init(create);

   return;

zombie:
   // error in file opening occured, make this object a zombie
   MakeZombie();
   gDirectory = gROOT;
}

//______________________________________________________________________________
TRFIOFile::~TRFIOFile()
{
   // RFIO file dtor. Close and flush directory structure.

   Close();
}

//______________________________________________________________________________
Int_t TRFIOFile::SysOpen(const char *pathname, Int_t flags, UInt_t mode)
{
   // Interface to system open. All arguments like in "man 2 open".

   Int_t ret = ::rfio_open((char *)pathname, flags, (Int_t) mode);
   if (ret < 0)
      gSystem->SetErrorStr(::rfio_serror());
   return ret;
}

//______________________________________________________________________________
Int_t TRFIOFile::SysClose(Int_t fd)
{
   // Interface to system close. All arguments like in "man 2 close".

   Int_t ret = ::rfio_close(fd);
   if (ret < 0)
      gSystem->SetErrorStr(::rfio_serror());
   return ret;
}

//______________________________________________________________________________
Int_t TRFIOFile::SysRead(Int_t fd, void *buf, Int_t len)
{
   // Interface to system read. All arguments like in "man 2 read".

   fOffset += len;
   Int_t ret = ::rfio_read(fd, (char *)buf, len);
   if (ret < 0)
      gSystem->SetErrorStr(::rfio_serror());
   return ret;
}

//______________________________________________________________________________
Int_t TRFIOFile::SysWrite(Int_t fd, const void *buf, Int_t len)
{
   // Interface to system write. All arguments like in "man 2 write".

   fOffset += len;
   Int_t ret = ::rfio_write(fd, (char *)buf, len);
   if (ret < 0)
      gSystem->SetErrorStr(::rfio_serror());
   return ret;
}

//______________________________________________________________________________
Seek_t TRFIOFile::SysSeek(Int_t fd, Seek_t offset, Int_t whence)
{
   // Interface to system lseek. All arguments like in "man 2 lseek"
   // except that the offset and return value are Long_t to be able to
   // handle 64 bit file systems.

   switch (whence) {
   case SEEK_SET:
      if (offset == fOffset)
         return 0;
      else
         fOffset = offset;
      break;
   case SEEK_CUR:
      fOffset += offset;
      break;
   case SEEK_END:
      fOffset = fEND + offset;
      break;
   }

   Seek_t ret = ::rfio_lseek(fd, offset, whence);
   if (ret < 0)
      gSystem->SetErrorStr(::rfio_serror());
   return ret;
}

//______________________________________________________________________________
Int_t TRFIOFile::SysStat(Int_t fd, Long_t *id, Long_t *size, Long_t *flags,
                         Long_t *modtime)
{
   // Interface to TSystem:GetPathInfo(). Generally implemented via
   // stat() or fstat().

   struct stat statbuf;

   if (::rfio_fstat(fd, &statbuf) >= 0) {
      if (id)
#if defined(R__KCC) && defined(R__LINUX)
         *id = (statbuf.st_dev.__val[0] << 24) + statbuf.st_ino;
#else
         *id = (statbuf.st_dev << 24) + statbuf.st_ino;
#endif
      if (size)
         *size = statbuf.st_size;
      if (modtime)
         *modtime = statbuf.st_mtime;
      if (flags) {
         *flags = 0;
         if (statbuf.st_mode & ((S_IEXEC)|(S_IEXEC>>3)|(S_IEXEC>>6)))
            *flags |= 1;
         if ((statbuf.st_mode & S_IFMT) == S_IFDIR)
            *flags |= 2;
         if ((statbuf.st_mode & S_IFMT) != S_IFREG &&
             (statbuf.st_mode & S_IFMT) != S_IFDIR)
            *flags |= 4;
      }
      return 0;
   }

   gSystem->SetErrorStr(::rfio_serror());
   return 1;
}

//______________________________________________________________________________
Bool_t TRFIOFile::ReadBuffer(char *buf, Int_t len)
{
   // Read specified byte range from remote file via rfiod daemon.
   // Returns kTRUE in case of error.

   if (fCache) {
      Int_t st;
      Seek_t off = fOffset;
      if ((st = fCache->ReadBuffer(fOffset, buf, len)) < 0) {
         Error("ReadBuffer", "error reading from cache");
         return kTRUE;
      }
      if (st > 0) {
         // fOffset might have been changed via TCache::ReadBuffer(), reset it
         fOffset = off + len;
         return kFALSE;
      }
   }

   return TFile::ReadBuffer(buf, len);
}

//______________________________________________________________________________
Bool_t TRFIOFile::WriteBuffer(const char *buf, Int_t len)
{
   // Write specified byte range to remote file via rootd daemon.
   // Returns kTRUE in case of error.

   if (!IsOpen() || !fWritable) return kTRUE;

   if (fCache) {
      Int_t st;
      Seek_t off = fOffset;
      if ((st = fCache->WriteBuffer(fOffset, buf, len)) < 0) {
         Error("WriteBuffer", "error writing to cache");
         return kTRUE;
      }
      if (st > 0) {
         // fOffset might have been changed via TCache::WriteBuffer(), reset it
         fOffset = off + len;
         return kFALSE;
      }
   }

   return TFile::WriteBuffer(buf, len);
}

//______________________________________________________________________________
Int_t TRFIOFile::GetErrno() const
{
   // Method returning rfio_errno. For RFIO files must use this
   // function since we need to check rfio_errno then serrno and finally errno.

   if (rfio_errno)
      return rfio_errno;
   if (serrno)
      return serrno;
   return TSystem::GetErrno();
}

//______________________________________________________________________________
void TRFIOFile::ResetErrno() const
{
   // Method resetting the rfio_errno, serrno and errno.

   rfio_errno = 0;
   serrno = 0;
   TSystem::ResetErrno();
}
<|endoftext|>


<commit_before>/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * Written (W) 2011 Heiko Strathmann
 * Copyright (C) 2011 Berlin Institute of Technology and Max-Planck-Society
 */

#include <shogun/labels/BinaryLabels.h>
#include <shogun/features/DenseFeatures.h>
#include <shogun/kernel/GaussianKernel.h>
#include <shogun/classifier/svm/LibSVM.h>
#include <shogun/base/init.h>
#include <shogun/lib/common.h>
#include <shogun/io/SGIO.h>

using namespace shogun;

void print_message(FILE* target, const char* str)
{
	fprintf(target, "%s", str);
}

/* number of features and their dimension, number of kernels */
const int32_t n=7;

int main(int argc, char** argv)
{
	init_shogun(&print_message);

	/* create some random data and hand it to each kernel */
	SGMatrix<float64_t> matrix(n,n);
	for (int32_t k=0; k<n*n; ++k)
		matrix.matrix[k]=CMath::random((float64_t) -n, (float64_t) n);

	SG_SPRINT("feature data:\n");
	SGMatrix<float64_t>::display_matrix(matrix.matrix, n, n);

	CDenseFeatures<float64_t>* features=new CDenseFeatures<float64_t>(matrix);

	/* create n kernels with n features each */
	CGaussianKernel** kernels=SG_MALLOC(CGaussianKernel*, n);
	for (int32_t i=0; i<n; ++i)
	{
		kernels[i]=new CGaussianKernel(10, CMath::random(0.0, (float64_t)n*n));

		/* hand data to kernel */
		kernels[i]->init(features, features);
	}

	/* create n parameter instances, each with one kernel */
	Parameter** parameters=SG_MALLOC(Parameter*, n);
	for (int32_t i=0; i<n; ++i)
	{
		parameters[i]=new Parameter();
		parameters[i]->add((CSGObject**)&kernels[i], "kernel", "");
	}

	/* create n labels (+1,-1,+1,-1,...) */
	CBinaryLabels* labels=new CBinaryLabels(n);
	for (int32_t i=0; i<n; ++i)
		labels->set_label(i, i%2==0 ? +1 : -1);

	/* create libsvm with C=10 and produced labels */
	CLibSVM* svm=new CLibSVM(10, NULL, labels);

	/* iterate over all parameter instances and set them as subkernel */
	for (int32_t k=0; k<n; ++k)
	{
		SG_SPRINT("\nkernel %d has width %f\n", k, kernels[k]->get_width());

		/* change kernel, old one is UNREF'ed, new one is REF'ed */
		svm->m_parameters->set_from_parameters(parameters[k]);

		/* train and classify with the different kernels */
		svm->train();
		for (int32_t i=0; i<n; ++i)
			SG_SPRINT("output[%d]=%f\treal[%d]=%f\n", i,
					svm->apply_one(i), i, labels->get_label(i));
	}

	/* free up memory: delete all Parameter instances */
	for (int32_t i=0; i<n; ++i)
		delete parameters[i];

	/* delete created arrays */
	SG_FREE(kernels);
	SG_FREE(parameters);

	/* this also handles features, labels, and last kernel in kernels[n-1] */
	SG_UNREF(svm);

	exit_shogun();
	return 0;
}
<commit_msg>move n into local context to fix warning<commit_after>/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * Written (W) 2011 Heiko Strathmann
 * Copyright (C) 2011 Berlin Institute of Technology and Max-Planck-Society
 */

#include <shogun/labels/BinaryLabels.h>
#include <shogun/features/DenseFeatures.h>
#include <shogun/kernel/GaussianKernel.h>
#include <shogun/classifier/svm/LibSVM.h>
#include <shogun/base/init.h>
#include <shogun/lib/common.h>
#include <shogun/io/SGIO.h>

using namespace shogun;

void print_message(FILE* target, const char* str)
{
	fprintf(target, "%s", str);
}

/* number of features and their dimension, number of kernels */
int main(int argc, char** argv)
{
	const int32_t n=7;

	init_shogun(&print_message);

	/* create some random data and hand it to each kernel */
	SGMatrix<float64_t> matrix(n,n);
	for (int32_t k=0; k<n*n; ++k)
		matrix.matrix[k]=CMath::random((float64_t) -n, (float64_t) n);

	SG_SPRINT("feature data:\n");
	SGMatrix<float64_t>::display_matrix(matrix.matrix, n, n);

	CDenseFeatures<float64_t>* features=new CDenseFeatures<float64_t>(matrix);

	/* create n kernels with n features each */
	CGaussianKernel** kernels=SG_MALLOC(CGaussianKernel*, n);
	for (int32_t i=0; i<n; ++i)
	{
		kernels[i]=new CGaussianKernel(10, CMath::random(0.0, (float64_t)n*n));

		/* hand data to kernel */
		kernels[i]->init(features, features);
	}

	/* create n parameter instances, each with one kernel */
	Parameter** parameters=SG_MALLOC(Parameter*, n);
	for (int32_t i=0; i<n; ++i)
	{
		parameters[i]=new Parameter();
		parameters[i]->add((CSGObject**)&kernels[i], "kernel", "");
	}

	/* create n labels (+1,-1,+1,-1,...) */
	CBinaryLabels* labels=new CBinaryLabels(n);
	for (int32_t i=0; i<n; ++i)
		labels->set_label(i, i%2==0 ? +1 : -1);

	/* create libsvm with C=10 and produced labels */
	CLibSVM* svm=new CLibSVM(10, NULL, labels);

	/* iterate over all parameter instances and set them as subkernel */
	for (int32_t k=0; k<n; ++k)
	{
		SG_SPRINT("\nkernel %d has width %f\n", k, kernels[k]->get_width());

		/* change kernel, old one is UNREF'ed, new one is REF'ed */
		svm->m_parameters->set_from_parameters(parameters[k]);

		/* train and classify with the different kernels */
		svm->train();
		for (int32_t i=0; i<n; ++i)
			SG_SPRINT("output[%d]=%f\treal[%d]=%f\n", i,
					svm->apply_one(i), i, labels->get_label(i));
	}

	/* free up memory: delete all Parameter instances */
	for (int32_t i=0; i<n; ++i)
		delete parameters[i];

	/* delete created arrays */
	SG_FREE(kernels);
	SG_FREE(parameters);

	/* this also handles features, labels, and last kernel in kernels[n-1] */
	SG_UNREF(svm);

	exit_shogun();
	return 0;
}
<|endoftext|>


<commit_before>/*******************************************************************************
*       SOFA, Simulation Open-Framework Architecture, version 1.0 beta 1       *
*                (c) 2006-2007 MGH, INRIA, USTL, UJF, CNRS                     *
*                                                                              *
* This library is free software; you can redistribute it and/or modify it      *
* under the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation; either version 2.1 of the License, or (at your     *
* option) any later version.                                                   *
*                                                                              *
* This library is distributed in the hope that it will be useful, but WITHOUT  *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or        *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License  *
* for more details.                                                            *
*                                                                              *
* You should have received a copy of the GNU Lesser General Public License     *
* along with this library; if not, write to the Free Software Foundation,      *
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.           *
*                                                                              *
* Contact information: contact@sofa-framework.org                              *
*                                                                              *
* Authors: J. Allard, P-J. Bensoussan, S. Cotin, C. Duriez, H. Delingette,     *
* F. Faure, S. Fonteneau, L. Heigeas, C. Mendoza, M. Nesme, P. Neumann,        *
* and F. Poyer                                                                 *
*******************************************************************************/
#include <sofa/helper/io/bvh/BVHLoader.h>
#include <iostream>

namespace sofa
{

namespace helper
{

namespace io
{

namespace bvh
{

BVHJoint *BVHLoader::load(const char *filename)
{
    FILE *file = fopen(filename, "r");

    if (file)
    {
        BVHJoint *retBVHJoint;
        char buf[256];

        while (fscanf(file, "%s", buf) != EOF)
        {
            if (strcmp(buf, "ROOT") == 0)
                retBVHJoint = parseJoint(file);
            else if (strcmp(buf, "MOTION") == 0)
                parseMotion(file, retBVHJoint);
        }

        return retBVHJoint;
    }

    std::cout << "File " << filename << " not found\n";
    return NULL;
}

BVHJoint *BVHLoader::parseJoint(FILE *f, bool isEndSite, BVHJoint *parent)
{
    char buf[256];

    if (!isEndSite)
        fscanf(f,"%s",buf);

    BVHJoint *j = new BVHJoint(buf, isEndSite, parent);

    fscanf(f,"%s",buf);

    while (!(strcmp(buf,"}") == 0))
    {
        if (strcmp(buf,"OFFSET") == 0)
        {
            j->setOffset(parseOffset(f));
        }
        else if (strcmp(buf,"CHANNELS") == 0)
        {
            j->setChannels(parseChannels(f));
        }
        else if (strcmp(buf,"JOINT") == 0)
        {
            j->addChild(parseJoint(f, false, j));
        }
        else if (strcmp(buf,"End") == 0)
        {
            fscanf(f,"%s",buf);
            if (strcmp(buf, "Site") == 0)
                j->addChild(parseJoint(f, true, j));
        }

        fscanf(f,"%s",buf);
    }

    return j;
}

BVHOffset *BVHLoader::parseOffset(FILE *f)
{
    double x(0);
    double y(0);
    double z(0);

    fscanf(f,"%lf",&x);
    fscanf(f,"%lf",&y);
    fscanf(f,"%lf",&z);

    return new BVHOffset(x,y,z);
}

BVHChannels *BVHLoader::parseChannels(FILE *f)
{
    int cSize(0);
    fscanf(f,"%d",&cSize);

    if (cSize <= 0)
        return NULL;

    BVHChannels *c = new BVHChannels(cSize);
    char buf[256];

    for (int i=0; i<cSize; i++)
    {
        fscanf(f,"%s",buf);

        if (strcmp(buf, "Xposition") == 0)
            c->addChannel(BVHChannels::Xposition);
        else if (strcmp(buf, "Yposition") == 0)
            c->addChannel(BVHChannels::Yposition);
        else if (strcmp(buf, "Zposition") == 0)
            c->addChannel(BVHChannels::Zposition);
        else if (strcmp(buf, "Xrotation") == 0)
            c->addChannel(BVHChannels::Xrotation);
        else if (strcmp(buf, "Yrotation") == 0)
            c->addChannel(BVHChannels::Yrotation);
        else if (strcmp(buf, "Zrotation") == 0)
            c->addChannel(BVHChannels::Zrotation);
        else
            c->addChannel(BVHChannels::NOP);
    }

    return c;
}

void BVHLoader::parseMotion(FILE *f, BVHJoint *j)
{
    if (j == NULL)
        return;

    char buf[256];
    bool framesFound(false);
    bool frameTimeFound(false);
    int frameCount;
    double frameTime;

    while (!framesFound || !frameTimeFound)
    {
        fscanf(f,"%s",buf);

        if (strcmp(buf,"Frames:") == 0)
        {
            fscanf(f,"%d",&(frameCount));
            framesFound = true;
        }
        else if (strcmp(buf, "Time:") == 0)
        {
            fscanf(f,"%lf",&(frameTime));
            frameTimeFound = true;
        }
    }

    j->initMotion(frameTime, frameCount);

    for (int i=0; i < frameCount; i++)
        parseFrames(j, i, f);
}

void BVHLoader::parseFrames(BVHJoint *joint, unsigned int frameIndex, FILE *f)
{
    if (joint->getChannels() != NULL)
        for (unsigned int i=0; i < joint->getChannels()->size; i++)
            fscanf(f,"%lf",&joint->getMotion()->frames[frameIndex][i]);

    for (unsigned int i=0; i < joint->getChildren().size(); i++)
        parseFrames(joint->getChildren()[i], frameIndex, f);
}

} // namespace bvh

} // namespace io

} // namespace helper

} // namespace sofa
<commit_msg>r1568/sofa-dev : Remove Warning in BVHLoader<commit_after>/*******************************************************************************
*       SOFA, Simulation Open-Framework Architecture, version 1.0 beta 1       *
*                (c) 2006-2007 MGH, INRIA, USTL, UJF, CNRS                     *
*                                                                              *
* This library is free software; you can redistribute it and/or modify it      *
* under the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation; either version 2.1 of the License, or (at your     *
* option) any later version.                                                   *
*                                                                              *
* This library is distributed in the hope that it will be useful, but WITHOUT  *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or        *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License  *
* for more details.                                                            *
*                                                                              *
* You should have received a copy of the GNU Lesser General Public License     *
* along with this library; if not, write to the Free Software Foundation,      *
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.           *
*                                                                              *
* Contact information: contact@sofa-framework.org                              *
*                                                                              *
* Authors: J. Allard, P-J. Bensoussan, S. Cotin, C. Duriez, H. Delingette,     *
* F. Faure, S. Fonteneau, L. Heigeas, C. Mendoza, M. Nesme, P. Neumann,        *
* and F. Poyer                                                                 *
*******************************************************************************/
#include <sofa/helper/io/bvh/BVHLoader.h>
#include <iostream>

namespace sofa
{

namespace helper
{

namespace io
{

namespace bvh
{

BVHJoint *BVHLoader::load(const char *filename)
{
    FILE *file = fopen(filename, "r");

    if (file)
    {
        BVHJoint *retBVHJoint = NULL;
        char buf[256];

        while (fscanf(file, "%s", buf) != EOF)
        {
            if (strcmp(buf, "ROOT") == 0)
                retBVHJoint = parseJoint(file);
            else if (strcmp(buf, "MOTION") == 0)
                parseMotion(file, retBVHJoint);
        }

        return retBVHJoint;
    }

    std::cout << "File " << filename << " not found\n";
    return NULL;
}

BVHJoint *BVHLoader::parseJoint(FILE *f, bool isEndSite, BVHJoint *parent)
{
    char buf[256];

    if (!isEndSite)
        fscanf(f,"%s",buf);

    BVHJoint *j = new BVHJoint(buf, isEndSite, parent);

    fscanf(f,"%s",buf);

    while (!(strcmp(buf,"}") == 0))
    {
        if (strcmp(buf,"OFFSET") == 0)
        {
            j->setOffset(parseOffset(f));
        }
        else if (strcmp(buf,"CHANNELS") == 0)
        {
            j->setChannels(parseChannels(f));
        }
        else if (strcmp(buf,"JOINT") == 0)
        {
            j->addChild(parseJoint(f, false, j));
        }
        else if (strcmp(buf,"End") == 0)
        {
            fscanf(f,"%s",buf);
            if (strcmp(buf, "Site") == 0)
                j->addChild(parseJoint(f, true, j));
        }

        fscanf(f,"%s",buf);
    }

    return j;
}

BVHOffset *BVHLoader::parseOffset(FILE *f)
{
    double x(0);
    double y(0);
    double z(0);

    fscanf(f,"%lf",&x);
    fscanf(f,"%lf",&y);
    fscanf(f,"%lf",&z);

    return new BVHOffset(x,y,z);
}

BVHChannels *BVHLoader::parseChannels(FILE *f)
{
    int cSize(0);
    fscanf(f,"%d",&cSize);

    if (cSize <= 0)
        return NULL;

    BVHChannels *c = new BVHChannels(cSize);
    char buf[256];

    for (int i=0; i<cSize; i++)
    {
        fscanf(f,"%s",buf);

        if (strcmp(buf, "Xposition") == 0)
            c->addChannel(BVHChannels::Xposition);
        else if (strcmp(buf, "Yposition") == 0)
            c->addChannel(BVHChannels::Yposition);
        else if (strcmp(buf, "Zposition") == 0)
            c->addChannel(BVHChannels::Zposition);
        else if (strcmp(buf, "Xrotation") == 0)
            c->addChannel(BVHChannels::Xrotation);
        else if (strcmp(buf, "Yrotation") == 0)
            c->addChannel(BVHChannels::Yrotation);
        else if (strcmp(buf, "Zrotation") == 0)
            c->addChannel(BVHChannels::Zrotation);
        else
            c->addChannel(BVHChannels::NOP);
    }

    return c;
}

void BVHLoader::parseMotion(FILE *f, BVHJoint *j)
{
    if (j == NULL)
        return;

    char buf[256];
    bool framesFound(false);
    bool frameTimeFound(false);
    int frameCount;
    double frameTime;

    while (!framesFound || !frameTimeFound)
    {
        fscanf(f,"%s",buf);

        if (strcmp(buf,"Frames:") == 0)
        {
            fscanf(f,"%d",&(frameCount));
            framesFound = true;
        }
        else if (strcmp(buf, "Time:") == 0)
        {
            fscanf(f,"%lf",&(frameTime));
            frameTimeFound = true;
        }
    }

    j->initMotion(frameTime, frameCount);

    for (int i=0; i < frameCount; i++)
        parseFrames(j, i, f);
}

void BVHLoader::parseFrames(BVHJoint *joint, unsigned int frameIndex, FILE *f)
{
    if (joint->getChannels() != NULL)
        for (unsigned int i=0; i < joint->getChannels()->size; i++)
            fscanf(f,"%lf",&joint->getMotion()->frames[frameIndex][i]);

    for (unsigned int i=0; i < joint->getChildren().size(); i++)
        parseFrames(joint->getChildren()[i], frameIndex, f);
}

} // namespace bvh

} // namespace io

} // namespace helper

} // namespace sofa
<|endoftext|>


<commit_before>#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int inf = 0x3f3f3f3f;
typedef long long ll;
ll book[2000];
bool done[2000];
int main(){
    int T,n,m;
    scanf("%d",&T);
    while(T--){
        scanf("%d%d",&n,&m);
        int t,h,mi;
        char str[3];
        int ans1 = 0;
        ll ans2 = 0;
        memset(book,0,sizeof(book));
        memset(done,0,sizeof(done));
        for(int i = 0;i<m;i++){
            scanf("%d %d:%d %s",&t,&h,&mi,str);
            mi += h * 60;
            if(str[0] == 'A'){
                if(done[t])
                    continue;
                else{
                    done[t] = 1;
                    ans1++;
                    ans2 += mi + book[t];
                }
            }else{
                if(!done[t])
                    book[t] += 20;
            }
        }
        printf("%d %lld\n",ans1,ans2);
    }

}<commit_msg>Delete a.cpp<commit_after><|endoftext|>


<commit_before><commit_msg>add tolerance to bounding box check in IsPointInsideShape<commit_after><|endoftext|>