<commit_before>#include <iomanip>
#include <string>
#include "Board.h"
#include "Pipe.h"
#include "Log.h"

using namespace std;

const int Board::x_offset = 227;
const int Board::y_offset = 35;
const int Board::slotSize = 48;
const int Board::lines = BOARD_LINES;
const int Board::columns = BOARD_COLUMNS;

Board::Board (SDL_Surface* s, SDL_Rect* c, SDL_Surface* pipe1, SDL_Surface* pipe2)
{
    screen = s;
    coordinates = c;
    pipes_sprite1 = pipe1;
    pipes_sprite2 = pipe2;
    timer = INITIAL_TIMER;
    last_ticks = 0;

    cronometer_text = new Text(screen, CRON_OFFSET_X, CRON_OFFSET_Y, 20);
    score_label_text = new Text(screen, SCORE_LABEL_OFFSET_X, SCORE_LABEL_OFFSET_Y, 20);
    score_value_text = new Text(screen, SCORE_OFFSET_X, SCORE_OFFSET_Y, 20);
    game_over_text = new Text(screen, GAME_OVER_OFFSET_X, GAME_OVER_OFFSET_Y, 30);

    // Game board positions
    for (int line = 0; line < lines; line++) {
        for (int column = 0; column < columns; column++) {
            slots[line][column] = NULL;
        }
    }

    // blocked positions
    for(int i = 0; i < BLOCKED_POSITIONS; i++) {
        int column, line;

        do {
            column = rand() % BOARD_COLUMNS;
            line   = rand() % BOARD_LINES;
        } while(slots[line][column]);

        Pipe* pipe = new Pipe(pipes_sprite1, pipes_sprite2, false, false, false, false);
        pipe->block();

        slots[line][column] = pipe;
    }

    // Pool
    for (int p = 0; p < POOL_SIZE; p++) {
        pool[p] = new Pipe(pipes_sprite1, pipes_sprite2);
    }

    LOG(logDEBUG) << "Created Board";
}

void Board::mouseClick (int x, int y)
{
    int x_min = x_offset, x_max = x_min + (lines * slotSize);
    int y_min = y_offset, y_max = y_min + (columns * slotSize);

    // Check limits
    if (x >= x_min && x <= x_max && y >= y_min && y <= y_max) {
        int line = (x - x_min) / slotSize;
        int column = (y - y_min) / slotSize;
        Pipe **pipe = &slots[line][column];

        if (*pipe) {
            if ((*pipe)->isBlocked())
                return;

            delete *pipe;

            // loses points for replacing pipe
            addScore(-10);
        }

        // Get top of the pool
        *pipe = pool[0];
        rotatePool();
    }
}

void Board::rotatePool (void)
{
    for (int p = 0; p < POOL_SIZE - 1; p++) {
        pool[p] = pool[p + 1];
    }

    pool[POOL_SIZE - 1] = new Pipe(pipes_sprite1, pipes_sprite2);
}

SDL_Rect Board::getSlotScreenPosition (int line, int column)
{
    SDL_Rect pos;

    pos.x = (line * slotSize) + x_offset;
    pos.y = (column * slotSize) + y_offset;

    return pos;
}

Pipe* Board::getPipe(int column, int line) {
    if(column >= BOARD_COLUMNS || column < 0 ||
       line >= BOARD_LINES || line < 0) {
       return NULL;
    } else {
        return slots[column][line];
    }
}

Pipe* Board::getCurrentPipe() {
    return getPipe(current_pipe_column, current_pipe_line);
}

Pipe* Board::getNextPipe(const int direction, int *column, int *line, int *flow) {
    *column = current_pipe_column;
    *line = current_pipe_line;

    switch(direction) {
        case FLOW_TOP:
            *line -= 1;
            *flow = FLOW_DOWN;
            break;
        case FLOW_RIGHT:
            *column += 1;
            *flow = FLOW_LEFT;
            break;
        case FLOW_DOWN:
            *line += 1;
            *flow = FLOW_TOP;
            break;
        case FLOW_LEFT:
            *column -= 1;
            *flow = FLOW_RIGHT;
            break;
    };

    return getPipe(*column, *line);
}

void Board::Update() {
    updateCronometer();
    updatePipes();
    updateStartingFlow();
    updateNextPipe();
}

void Board::updateCronometer() {
    int current_ticks = SDL_GetTicks();

    // decreases every second
    if (current_ticks > last_ticks + 1000) {
        timer -= 1;
        last_ticks = current_ticks;
    }

    if (timer < 0)
        timer = 0;
}

void Board::updatePipes() {
    for (int l = 0; l < lines; l++) {
        for (int c = 0; c < columns; c++) {
            if (slots[l][c] != NULL) {
                slots[l][c]->Update();
            }
        }
    }
}

void Board::updateStartingFlow() {
    if (flow_started == false && timer == 0) {
        if (slots[INITIAL_COLUMN][INITIAL_LINE] != NULL) {
            current_pipe_column = INITIAL_COLUMN;
            current_pipe_line = INITIAL_LINE;
            startCurrentPipeFlow(FLOW_LEFT);
            flow_started = true;
        } else {
            gameOver("No starting pipe");
        }
    }
}

void Board::updateNextPipe() {
    if (flow_started == true && getCurrentPipe()->isFlowFinished()) {
       if (current_pipe_column == FINAL_COLUMN && current_pipe_line == FINAL_LINE && getCurrentPipe()->getFlowTurnPosition() == FLOW_RIGHT && getCurrentPipe()->hasFlowEntry(FLOW_RIGHT)) {
            successfulGameOver();
            return;
        }

        int flow_direction = getCurrentPipe()->getFlowTurnPosition();
        int next_flow;
        int column, line, flow;

        getNextPipe(flow_direction, &column, &line, &flow);
        current_pipe_column = column;
        current_pipe_line = line;
        next_flow = flow;

        // game over if has no next pipe or the next pipe does not have the next_flow entry
        if (getCurrentPipe() == NULL || !getCurrentPipe()->hasFlowEntry(next_flow)) {
            gameOver("No next pipe NULL or next pipe has no flow entry for " + next_flow);
        } else {
            startCurrentPipeFlow(next_flow);
        }
    } else if(flow_started == true && getCurrentPipe()->isFlowHalf()) {
        int next_flow_direction = calculateNextFlowDirection();

        if(next_flow_direction > 0) {
            getCurrentPipe()->setFlowTurnPosition(next_flow_direction);
        } else {
            gameOver("No next flow direction");
        }
    }
}

int Board::calculateNextFlowDirection() {
    if(possibleNextFlowDirection(FLOW_TOP, FLOW_DOWN)) {
        return FLOW_TOP;
    }

    if(possibleNextFlowDirection(FLOW_RIGHT, FLOW_LEFT)) {
        return FLOW_RIGHT;
    }

    if(possibleNextFlowDirection(FLOW_DOWN, FLOW_TOP)) {
        return FLOW_DOWN;
    }

    if(possibleNextFlowDirection(FLOW_LEFT, FLOW_RIGHT)) {
        return FLOW_LEFT;
    }

    // if couldn't find anything, turn to the first possible one
    Pipe* pipe = getCurrentPipe();

    if(current_pipe_column == FINAL_COLUMN && current_pipe_line == FINAL_LINE) {
        return FLOW_RIGHT;
    } else if(pipe->hasFlowEntry(FLOW_TOP) && pipe->getFlowStartPosition() != FLOW_TOP) {
        return FLOW_TOP;
    } else if(pipe->hasFlowEntry(FLOW_RIGHT) && pipe->getFlowStartPosition() != FLOW_RIGHT) {
        return FLOW_RIGHT;
    } else if(pipe->hasFlowEntry(FLOW_DOWN) && pipe->getFlowStartPosition() != FLOW_DOWN) {
        return FLOW_DOWN;
    } else if(pipe->hasFlowEntry(FLOW_LEFT) && pipe->getFlowStartPosition() != FLOW_LEFT) {
        return FLOW_LEFT;
    }

    return 0;
}

bool Board::possibleNextFlowDirection(int outgoing_flow, int incoming_flow) {
    Pipe* pipe = getCurrentPipe();
    Pipe* next_pipe;
    int column, line, flow;

    if (pipe->hasFlowEntry(outgoing_flow) && pipe->getFlowStartPosition() != outgoing_flow) {
        next_pipe = getNextPipe(outgoing_flow, &column, &line, &flow);

        if(next_pipe && next_pipe->hasFlowEntry(incoming_flow)) {
            return true;
        }
    }

    return false;
}

void Board::drawCronometer ()
{
    std::ostringstream out;
    out << "0:" << std::setfill('0') << std::setw(2) << timer;
    cronometer_text->Draw(out.str().c_str());
}

void Board::drawScore ()
{
    std::ostringstream out;
    out << score;
    score_label_text->Draw("Score");
    score_value_text->Draw(out.str().c_str());
}

void Board::drawGameOver() {
    if (game_over_success) {
        game_over_text->Draw("CONGRATULATIONS!");
    } else {
        game_over_text->Draw("GAME OVER!");
    }
}

void Board::Draw ()
{
    // Draw all board pipes
    for (int l = 0; l < lines; l++) {
        for (int c = 0; c < columns; c++) {
            // if != NULL we have a pipe to draw
            if (slots[l][c] != NULL) {
                SDL_Rect pos = getSlotScreenPosition(l, c);

                slots[l][c]->Draw(screen, &pos, isPipeConnected(l, c));
            }
        }
    }

    // Draw pool pipes
    SDL_Rect pos;
    pos.x = POOL_OFFSET_X;
    pos.y = POOL_OFFSET_Y;

    for (int p = POOL_SIZE - 1; p > 0; p--, pos.y += POOL_SPACING) {
        pool[p]->Draw(screen, &pos, false);
    }

    pos.y = POOL_TOP_Y;
    pool[0]->Draw(screen, &pos, false);

    drawCronometer();
    drawScore();

    if (game_over) {
        drawGameOver();
    }
}

bool Board::isPipeConnected(int col, int line) {
    if(col == INITIAL_COLUMN && line == INITIAL_LINE) {
        return true;
    }

    Pipe* current = getPipe(col, line);
    Pipe* pipe;

    // connects on top?
    pipe = getPipe(col, line - 1);
    if(current->hasFlowEntry(FLOW_TOP) && pipe && pipe->hasFlowEntry(FLOW_DOWN)) {
        return true;
    }

    // connects on right?
    pipe = getPipe(col + 1, line);
    if(current->hasFlowEntry(FLOW_RIGHT) && pipe && pipe->hasFlowEntry(FLOW_LEFT)) {
        return true;
    }

    // connects on down?
    pipe = getPipe(col, line + 1);
    if(current->hasFlowEntry(FLOW_DOWN) && pipe && pipe->hasFlowEntry(FLOW_TOP)) {
        return true;
    }

    // connects on left?
    pipe = getPipe(col - 1, line);
    if(current->hasFlowEntry(FLOW_LEFT) && pipe && pipe->hasFlowEntry(FLOW_RIGHT)) {
        return true;
    }

    return false;
}

void Board::startCurrentPipeFlow(int direction) {
    getCurrentPipe()->StartFlow(direction);
    addScore(100);
}

void Board::addScore(int points) {
    score += points;

    if(score < 0)
        score = 0;
}

void Board::gameOver(string reason) {
    LOG(logINFO) << "Game over ! " << reason;
    game_over = true;
}

void Board::successfulGameOver() {
    LOG(logINFO) << "Successful Game over !";
    game_over = true;
    game_over_success = true;
}

bool Board::isGameOver() {
    return game_over;
}

void Board::startGame ()
{
    score = 0;
    game_over = game_over_success = flow_started = false;
    starting_time = SDL_GetTicks();
}
<commit_msg>Gameover when flow starts and there is no connection to the source.<commit_after>#include <iomanip>
#include <string>
#include "Board.h"
#include "Pipe.h"
#include "Log.h"

using namespace std;

const int Board::x_offset = 227;
const int Board::y_offset = 35;
const int Board::slotSize = 48;
const int Board::lines = BOARD_LINES;
const int Board::columns = BOARD_COLUMNS;

Board::Board (SDL_Surface* s, SDL_Rect* c, SDL_Surface* pipe1, SDL_Surface* pipe2)
{
    screen = s;
    coordinates = c;
    pipes_sprite1 = pipe1;
    pipes_sprite2 = pipe2;
    timer = INITIAL_TIMER;
    last_ticks = 0;

    cronometer_text = new Text(screen, CRON_OFFSET_X, CRON_OFFSET_Y, 20);
    score_label_text = new Text(screen, SCORE_LABEL_OFFSET_X, SCORE_LABEL_OFFSET_Y, 20);
    score_value_text = new Text(screen, SCORE_OFFSET_X, SCORE_OFFSET_Y, 20);
    game_over_text = new Text(screen, GAME_OVER_OFFSET_X, GAME_OVER_OFFSET_Y, 30);

    // Game board positions
    for (int line = 0; line < lines; line++) {
        for (int column = 0; column < columns; column++) {
            slots[line][column] = NULL;
        }
    }

    // blocked positions
    for(int i = 0; i < BLOCKED_POSITIONS; i++) {
        int column, line;

        do {
            column = rand() % BOARD_COLUMNS;
            line   = rand() % BOARD_LINES;
        } while(slots[line][column]);

        Pipe* pipe = new Pipe(pipes_sprite1, pipes_sprite2, false, false, false, false);
        pipe->block();

        slots[line][column] = pipe;
    }

    // Pool
    for (int p = 0; p < POOL_SIZE; p++) {
        pool[p] = new Pipe(pipes_sprite1, pipes_sprite2);
    }

    LOG(logDEBUG) << "Created Board";
}

void Board::mouseClick (int x, int y)
{
    int x_min = x_offset, x_max = x_min + (lines * slotSize);
    int y_min = y_offset, y_max = y_min + (columns * slotSize);

    // Check limits
    if (x >= x_min && x <= x_max && y >= y_min && y <= y_max) {
        int line = (x - x_min) / slotSize;
        int column = (y - y_min) / slotSize;
        Pipe **pipe = &slots[line][column];

        if (*pipe) {
            if ((*pipe)->isBlocked())
                return;

            delete *pipe;

            // loses points for replacing pipe
            addScore(-10);
        }

        // Get top of the pool
        *pipe = pool[0];
        rotatePool();
    }
}

void Board::rotatePool (void)
{
    for (int p = 0; p < POOL_SIZE - 1; p++) {
        pool[p] = pool[p + 1];
    }

    pool[POOL_SIZE - 1] = new Pipe(pipes_sprite1, pipes_sprite2);
}

SDL_Rect Board::getSlotScreenPosition (int line, int column)
{
    SDL_Rect pos;

    pos.x = (line * slotSize) + x_offset;
    pos.y = (column * slotSize) + y_offset;

    return pos;
}

Pipe* Board::getPipe(int column, int line) {
    if(column >= BOARD_COLUMNS || column < 0 ||
       line >= BOARD_LINES || line < 0) {
       return NULL;
    } else {
        return slots[column][line];
    }
}

Pipe* Board::getCurrentPipe() {
    return getPipe(current_pipe_column, current_pipe_line);
}

Pipe* Board::getNextPipe(const int direction, int *column, int *line, int *flow) {
    *column = current_pipe_column;
    *line = current_pipe_line;

    switch(direction) {
        case FLOW_TOP:
            *line -= 1;
            *flow = FLOW_DOWN;
            break;
        case FLOW_RIGHT:
            *column += 1;
            *flow = FLOW_LEFT;
            break;
        case FLOW_DOWN:
            *line += 1;
            *flow = FLOW_TOP;
            break;
        case FLOW_LEFT:
            *column -= 1;
            *flow = FLOW_RIGHT;
            break;
    };

    return getPipe(*column, *line);
}

void Board::Update() {
    updateCronometer();
    updatePipes();
    updateStartingFlow();
    updateNextPipe();
}

void Board::updateCronometer() {
    int current_ticks = SDL_GetTicks();

    // decreases every second
    if (current_ticks > last_ticks + 1000) {
        timer -= 1;
        last_ticks = current_ticks;
    }

    if (timer < 0)
        timer = 0;
}

void Board::updatePipes() {
    for (int l = 0; l < lines; l++) {
        for (int c = 0; c < columns; c++) {
            if (slots[l][c] != NULL) {
                slots[l][c]->Update();
            }
        }
    }
}

void Board::updateStartingFlow() {
    if (flow_started == false && timer == 0) {
        Pipe *pipe = slots[INITIAL_COLUMN][INITIAL_LINE];
        if (pipe && pipe->hasFlowEntry(FLOW_LEFT)) {
            current_pipe_column = INITIAL_COLUMN;
            current_pipe_line = INITIAL_LINE;
            startCurrentPipeFlow(FLOW_LEFT);
            flow_started = true;
        } else {
            gameOver("No starting pipe");
        }
    }
}

void Board::updateNextPipe() {
    if (flow_started == true && getCurrentPipe()->isFlowFinished()) {
       if (current_pipe_column == FINAL_COLUMN && current_pipe_line == FINAL_LINE && getCurrentPipe()->getFlowTurnPosition() == FLOW_RIGHT && getCurrentPipe()->hasFlowEntry(FLOW_RIGHT)) {
            successfulGameOver();
            return;
        }

        int flow_direction = getCurrentPipe()->getFlowTurnPosition();
        int next_flow;
        int column, line, flow;

        getNextPipe(flow_direction, &column, &line, &flow);
        current_pipe_column = column;
        current_pipe_line = line;
        next_flow = flow;

        // game over if has no next pipe or the next pipe does not have the next_flow entry
        if (getCurrentPipe() == NULL || !getCurrentPipe()->hasFlowEntry(next_flow)) {
            gameOver("No next pipe NULL or next pipe has no flow entry for " + next_flow);
        } else {
            startCurrentPipeFlow(next_flow);
        }
    } else if(flow_started == true && getCurrentPipe()->isFlowHalf()) {
        int next_flow_direction = calculateNextFlowDirection();

        if(next_flow_direction > 0) {
            getCurrentPipe()->setFlowTurnPosition(next_flow_direction);
        } else {
            gameOver("No next flow direction");
        }
    }
}

int Board::calculateNextFlowDirection() {
    if(possibleNextFlowDirection(FLOW_TOP, FLOW_DOWN)) {
        return FLOW_TOP;
    }

    if(possibleNextFlowDirection(FLOW_RIGHT, FLOW_LEFT)) {
        return FLOW_RIGHT;
    }

    if(possibleNextFlowDirection(FLOW_DOWN, FLOW_TOP)) {
        return FLOW_DOWN;
    }

    if(possibleNextFlowDirection(FLOW_LEFT, FLOW_RIGHT)) {
        return FLOW_LEFT;
    }

    // if couldn't find anything, turn to the first possible one
    Pipe* pipe = getCurrentPipe();

    if(current_pipe_column == FINAL_COLUMN && current_pipe_line == FINAL_LINE) {
        return FLOW_RIGHT;
    } else if(pipe->hasFlowEntry(FLOW_TOP) && pipe->getFlowStartPosition() != FLOW_TOP) {
        return FLOW_TOP;
    } else if(pipe->hasFlowEntry(FLOW_RIGHT) && pipe->getFlowStartPosition() != FLOW_RIGHT) {
        return FLOW_RIGHT;
    } else if(pipe->hasFlowEntry(FLOW_DOWN) && pipe->getFlowStartPosition() != FLOW_DOWN) {
        return FLOW_DOWN;
    } else if(pipe->hasFlowEntry(FLOW_LEFT) && pipe->getFlowStartPosition() != FLOW_LEFT) {
        return FLOW_LEFT;
    }

    return 0;
}

bool Board::possibleNextFlowDirection(int outgoing_flow, int incoming_flow) {
    Pipe* pipe = getCurrentPipe();
    Pipe* next_pipe;
    int column, line, flow;

    if (pipe->hasFlowEntry(outgoing_flow) && pipe->getFlowStartPosition() != outgoing_flow) {
        next_pipe = getNextPipe(outgoing_flow, &column, &line, &flow);

        if(next_pipe && next_pipe->hasFlowEntry(incoming_flow)) {
            return true;
        }
    }

    return false;
}

void Board::drawCronometer ()
{
    std::ostringstream out;
    out << "0:" << std::setfill('0') << std::setw(2) << timer;
    cronometer_text->Draw(out.str().c_str());
}

void Board::drawScore ()
{
    std::ostringstream out;
    out << score;
    score_label_text->Draw("Score");
    score_value_text->Draw(out.str().c_str());
}

void Board::drawGameOver() {
    if (game_over_success) {
        game_over_text->Draw("CONGRATULATIONS!");
    } else {
        game_over_text->Draw("GAME OVER!");
    }
}

void Board::Draw ()
{
    // Draw all board pipes
    for (int l = 0; l < lines; l++) {
        for (int c = 0; c < columns; c++) {
            // if != NULL we have a pipe to draw
            if (slots[l][c] != NULL) {
                SDL_Rect pos = getSlotScreenPosition(l, c);

                slots[l][c]->Draw(screen, &pos, isPipeConnected(l, c));
            }
        }
    }

    // Draw pool pipes
    SDL_Rect pos;
    pos.x = POOL_OFFSET_X;
    pos.y = POOL_OFFSET_Y;

    for (int p = POOL_SIZE - 1; p > 0; p--, pos.y += POOL_SPACING) {
        pool[p]->Draw(screen, &pos, false);
    }

    pos.y = POOL_TOP_Y;
    pool[0]->Draw(screen, &pos, false);

    drawCronometer();
    drawScore();

    if (game_over) {
        drawGameOver();
    }
}

bool Board::isPipeConnected(int col, int line) {
    if(col == INITIAL_COLUMN && line == INITIAL_LINE) {
        return true;
    }

    Pipe* current = getPipe(col, line);
    Pipe* pipe;

    // connects on top?
    pipe = getPipe(col, line - 1);
    if(current->hasFlowEntry(FLOW_TOP) && pipe && pipe->hasFlowEntry(FLOW_DOWN)) {
        return true;
    }

    // connects on right?
    pipe = getPipe(col + 1, line);
    if(current->hasFlowEntry(FLOW_RIGHT) && pipe && pipe->hasFlowEntry(FLOW_LEFT)) {
        return true;
    }

    // connects on down?
    pipe = getPipe(col, line + 1);
    if(current->hasFlowEntry(FLOW_DOWN) && pipe && pipe->hasFlowEntry(FLOW_TOP)) {
        return true;
    }

    // connects on left?
    pipe = getPipe(col - 1, line);
    if(current->hasFlowEntry(FLOW_LEFT) && pipe && pipe->hasFlowEntry(FLOW_RIGHT)) {
        return true;
    }

    return false;
}

void Board::startCurrentPipeFlow(int direction) {
    getCurrentPipe()->StartFlow(direction);
    addScore(100);
}

void Board::addScore(int points) {
    score += points;

    if(score < 0)
        score = 0;
}

void Board::gameOver(string reason) {
    LOG(logINFO) << "Game over ! " << reason;
    game_over = true;
}

void Board::successfulGameOver() {
    LOG(logINFO) << "Successful Game over !";
    game_over = true;
    game_over_success = true;
}

bool Board::isGameOver() {
    return game_over;
}

void Board::startGame ()
{
    score = 0;
    game_over = game_over_success = flow_started = false;
    starting_time = SDL_GetTicks();
}
<|endoftext|>


<commit_before>/*
 * File:   Cache.hpp
 * Copyright: Emanuele Di Pascale (dipascae aT tcd dOt ie)
 *
 * Licensed under the Apache License v2.0 (see attached README.TXT file)
 * Created on 30 April 2013, 11:23
 */

#ifndef CACHE_HPP
#define	CACHE_HPP

#include <map>
#include <set>
#include <assert.h>
#include <iostream>
#include <limits>
#include "RunningAvg.hpp"

/* Policy to use in caches to replace old content and make space for new one
 * LRU = Least Recently Used, LFU = Least Frequently Used
 */
enum CachePolicy {LRU, LFU};

/* Struct to hold the caching parameters associated to each content element;
 * Timestamp must be a scalar which supports std::numeric_limits<Timestamp>::max()
 * Size can be any scalar which supports comparison operators (e.g. <,>,>= etc.)
 * uploads is used to calculate the bandwidth used and to ensure that we do not
 * erase an element which is currently required
 */
template <typename Timestamp, typename Size>
struct CacheEntry {
  Timestamp lastAccessed;
  unsigned int timesServed;
  Size size;
  unsigned int uploads;
};

/* Implements a generic LRU or LFU cache, with a fixed maximum capacity maxSize
 * and elements of type Content which can be of variable size. Implemented over
 * std::map (not optimized for performance!)
 */
template <typename Content, typename Size, typename Timestamp>
class Cache {
  typedef std::map<Content, CacheEntry<Timestamp, Size> > CacheMap;
protected:
  CacheMap cacheMap;
  Size maxSize;
  Size currentSize;
  CachePolicy policy;
  RunningAvg<double, Timestamp> cacheOccupancy;
  void updateOccupancy(Timestamp time) {
    double occ = 100 * currentSize / maxSize;
    bool result = cacheOccupancy.add(occ, time);
    if (!result) {
      std::cerr << "Failed to update the cache occupancy at time "
              << time << ", last timestamp: " << cacheOccupancy.getLastTimestamp()
              << "; aborting. " << std::endl;
      abort();
    }
  }

public:
  friend class CacheTestClass;
  Cache(Size maxSize, CachePolicy policy = LRU);
  std::pair<bool, std::set<Content> > addToCache(Content content,
      Size size, Timestamp time);
  void clearCache();
  // to update metadata about the content (lastAccess, timesAccessed, uploads..)
  bool getFromCache(Content content, Timestamp time);
  bool isCached(Content content);
  void removeFromCache(Content content, Timestamp time); // for expired content
  bool uploadCompleted(Content content); // to decrease the upload counter
  int getCurrentUploads(Content content);
  int getTotalUploads();
  double getAvgOccupancy(Timestamp time) {
    double avg = cacheOccupancy.extract(time);
    return avg;
  }

  void resetOccupancy(Timestamp time) {
    double value = 100 * currentSize / maxSize;
    cacheOccupancy.reset(value, time);
  }

  // to give the optimizer full access to the content of the cache
  CacheMap getCacheMap() const {
    return this->cacheMap;
  }

  unsigned int getNumElementsCached() const {
    return this->cacheMap.size();
  }

  Size getCurrentSize() const {
    return this->currentSize;
  }

  Size getMaxSize() const {
    return maxSize;
  }

  bool fitsInCache(Size size) const {
    if (maxSize - currentSize >= size)
      return true;
    else
      return false;
  }

};

template <typename Content, typename Size, typename Timestamp>
Cache<Content, Size, Timestamp>::Cache(Size maxSize, CachePolicy policy) : cacheOccupancy() {
  this->maxSize = maxSize;
  this->policy = policy;
  this->currentSize = 0;
}

template <typename Content, typename Size, typename Timestamp>
std::pair<bool, std::set<Content> > Cache<Content, Size, Timestamp>::addToCache(
        Content content, Size size, Timestamp time) {
  std::set<Content> deletedElements;
  deletedElements.clear();
  // check if the content was already cached
  typename CacheMap::iterator cIt = cacheMap.find(content);
  if ((cIt != cacheMap.end() && cIt->second.size >= size) // content already cached
      || size > getMaxSize()) { // content cannot possibly fit in the cache
    // already cached or too big to be cached, quit
    return std::make_pair(false, deletedElements);
  }
  else {
    unsigned int oldFreqStat = 0;
    if (cIt!= cacheMap.end()) {
      // the content was cached, but with a smaller chunk, delete it (but save
      // the caching info - after all it's the same content)
      this->currentSize -= cIt->second.size;
      oldFreqStat = cIt->second.timesServed;
      /* FIXME: if something goes wrong and we cannot cache the new element,
       * we will lose the previous (partial) copy
       */
      this->cacheMap.erase(cIt);
    }
    while (currentSize + size > maxSize) {
      // Replace content according to selected policy
      Timestamp minTmp = std::numeric_limits<Timestamp>::max();
      typename CacheMap::iterator minIt = cacheMap.end();
      switch (policy) {
        case LRU:
          for (typename CacheMap::iterator it = cacheMap.begin();
                  it != cacheMap.end(); it++) {
            if (it->second.uploads == 0 && it->second.lastAccessed < minTmp) {
              minTmp = it->second.lastAccessed;
              minIt = it;
            }
          }
          break;
        case LFU:
          for (typename CacheMap::iterator it = cacheMap.begin();
                  it != cacheMap.end(); it++) {
            if (it->second.uploads == 0 && it->second.timesServed < minTmp) {
              minTmp = it->second.timesServed;
              minIt = it;
            }
          }
          break;
        default:
          std::cerr << "ERROR: Cache::addToCache - unrecognized CachePolicy"
                  << std::endl;
      }
      // check that there is an element we can erase (due to uploads)
      if (minIt == cacheMap.end()) {
        // all elements are being used for uploads, cannot cache
        return std::make_pair(false, deletedElements);
      }
      // else remove the identified element from the cache
      currentSize -= minIt->second.size;
      deletedElements.insert(minIt->first);
      cacheMap.erase(minIt);
    }
    // insert new element in the cache
    CacheEntry<Timestamp, Size> entry;
    entry.lastAccessed = time;
    entry.timesServed = oldFreqStat; // 0 if the content is new
    entry.size = size;
    entry.uploads = 0;
    if (cacheMap.insert(std::make_pair(content,entry)).second == true) {
      currentSize += size;
      assert(currentSize <= maxSize);
      updateOccupancy(time);
      return std::make_pair(true, deletedElements);
    } else {
      std::cerr << "WARNING: Cache::addToCache() - Could not insert content "
              << std::endl;
      updateOccupancy(time);
      return std::make_pair(false, deletedElements);
    }
  }
}

template <typename Content, typename Size, typename Timestamp>
void Cache<Content, Size, Timestamp>::clearCache() {
  cacheMap.clear();
  this->currentSize = 0;
  cacheOccupancy.reset(0,0);
}

template <typename Content, typename Size, typename Timestamp>
bool Cache<Content, Size, Timestamp>::getFromCache(Content content, Timestamp time) {
  typename CacheMap::iterator it = cacheMap.find(content);
  if (it != cacheMap.end()) {
    it->second.lastAccessed = time;
    it->second.timesServed++;
    it->second.uploads++;
    return true;
  }
  else
    return false;
}

template <typename Content, typename Size, typename Timestamp>
bool Cache<Content, Size, Timestamp>::isCached(Content content) {
  typename CacheMap::iterator cIt = cacheMap.find(content);
  if (cIt != cacheMap.end())
    return true;
  else // shall we return size instead to allow for multiple sources?
    return false;
}

template <typename Content, typename Size, typename Timestamp>
void Cache<Content, Size, Timestamp>::removeFromCache(Content content, Timestamp time) {
  typename CacheMap::iterator it = cacheMap.find(content);
  if (it != cacheMap.end()) {
    this->currentSize -= it->second.size;
    assert(this->currentSize >= 0);
    cacheMap.erase(it);
    updateOccupancy(time);
  }
}

template <typename Content, typename Size, typename Timestamp>
bool Cache<Content, Size, Timestamp>::uploadCompleted(Content content) {
  typename CacheMap::iterator it = cacheMap.find(content);
  if (it != cacheMap.end()) {
    it->second.uploads = it->second.uploads - 1;
    assert(it->second.uploads >= 0);
    return true;
  } else {
    return false;
  }
}

template <typename Content, typename Size, typename Timestamp>
int Cache<Content, Size, Timestamp>::getCurrentUploads(Content content) {
  typename CacheMap::iterator it = cacheMap.find(content);
  if (it != cacheMap.end()) {
    return it->second.uploads;
  } else {
    return -1;
  }
}

template <typename Content, typename Size, typename Timestamp>
int Cache<Content, Size, Timestamp>::getTotalUploads() {
  int uploads = 0;
  for (typename CacheMap::iterator it = cacheMap.begin(); it != cacheMap.end(); it++)
    uploads += it->second.uploads;
  return uploads;
}

#endif	/* CACHE_HPP */

<commit_msg>getFromCache now accepts a third boolean parameter, local. If local==true, the content is being requested locally and will not be uploaded. This is to prevent a situation where content accessed locally would never be marked as completed in terms of upload, since no data flow was generated.<commit_after>/*
 * File:   Cache.hpp
 * Copyright: Emanuele Di Pascale (dipascae aT tcd dOt ie)
 *
 * Licensed under the Apache License v2.0 (see attached README.TXT file)
 * Created on 30 April 2013, 11:23
 */

#ifndef CACHE_HPP
#define	CACHE_HPP

#include <map>
#include <set>
#include <assert.h>
#include <iostream>
#include <limits>
#include "RunningAvg.hpp"

/* Policy to use in caches to replace old content and make space for new one
 * LRU = Least Recently Used, LFU = Least Frequently Used
 */
enum CachePolicy {LRU, LFU};

/* Struct to hold the caching parameters associated to each content element;
 * Timestamp must be a scalar which supports std::numeric_limits<Timestamp>::max()
 * Size can be any scalar which supports comparison operators (e.g. <,>,>= etc.)
 * uploads is used to calculate the bandwidth used and to ensure that we do not
 * erase an element which is currently required
 */
template <typename Timestamp, typename Size>
struct CacheEntry {
  Timestamp lastAccessed;
  unsigned int timesServed;
  Size size;
  unsigned int uploads;
};

/* Implements a generic LRU or LFU cache, with a fixed maximum capacity maxSize
 * and elements of type Content which can be of variable size. Implemented over
 * std::map (not optimized for performance!)
 */
template <typename Content, typename Size, typename Timestamp>
class Cache {
  typedef std::map<Content, CacheEntry<Timestamp, Size> > CacheMap;
protected:
  CacheMap cacheMap;
  Size maxSize;
  Size currentSize;
  CachePolicy policy;
  RunningAvg<double, Timestamp> cacheOccupancy;
  void updateOccupancy(Timestamp time) {
    double occ = 100 * currentSize / maxSize;
    bool result = cacheOccupancy.add(occ, time);
    if (!result) {
      std::cerr << "Failed to update the cache occupancy at time "
              << time << ", last timestamp: " << cacheOccupancy.getLastTimestamp()
              << "; aborting. " << std::endl;
      abort();
    }
  }

public:
  friend class CacheTestClass;
  Cache(Size maxSize, CachePolicy policy = LRU);
  std::pair<bool, std::set<Content> > addToCache(Content content,
      Size size, Timestamp time);
  void clearCache();
  // to update metadata about the content (lastAccess, timesAccessed, uploads..)
  // if local==true the content is not uploaded (it's the user itself who requested it again)
  bool getFromCache(Content content, Timestamp time, bool local);
  bool isCached(Content content);
  void removeFromCache(Content content, Timestamp time); // for expired content
  bool uploadCompleted(Content content); // to decrease the upload counter
  int getCurrentUploads(Content content);
  int getTotalUploads();
  double getAvgOccupancy(Timestamp time) {
    double avg = cacheOccupancy.extract(time);
    return avg;
  }

  void resetOccupancy(Timestamp time) {
    double value = 100 * currentSize / maxSize;
    cacheOccupancy.reset(value, time);
  }

  // to give the optimizer full access to the content of the cache
  CacheMap getCacheMap() const {
    return this->cacheMap;
  }

  unsigned int getNumElementsCached() const {
    return this->cacheMap.size();
  }

  Size getCurrentSize() const {
    return this->currentSize;
  }

  Size getMaxSize() const {
    return maxSize;
  }

  bool fitsInCache(Size size) const {
    if (maxSize - currentSize >= size)
      return true;
    else
      return false;
  }

};

template <typename Content, typename Size, typename Timestamp>
Cache<Content, Size, Timestamp>::Cache(Size maxSize, CachePolicy policy) : cacheOccupancy() {
  this->maxSize = maxSize;
  this->policy = policy;
  this->currentSize = 0;
}

template <typename Content, typename Size, typename Timestamp>
std::pair<bool, std::set<Content> > Cache<Content, Size, Timestamp>::addToCache(
        Content content, Size size, Timestamp time) {
  std::set<Content> deletedElements;
  deletedElements.clear();
  // check if the content was already cached
  typename CacheMap::iterator cIt = cacheMap.find(content);
  if ((cIt != cacheMap.end() && cIt->second.size >= size) // content already cached
      || size > getMaxSize()) { // content cannot possibly fit in the cache
    // already cached or too big to be cached, quit
    return std::make_pair(false, deletedElements);
  }
  else {
    unsigned int oldFreqStat = 0;
    if (cIt!= cacheMap.end()) {
      // the content was cached, but with a smaller chunk, delete it (but save
      // the caching info - after all it's the same content)
      this->currentSize -= cIt->second.size;
      oldFreqStat = cIt->second.timesServed;
      /* FIXME: if something goes wrong and we cannot cache the new element,
       * we will lose the previous (partial) copy
       */
      this->cacheMap.erase(cIt);
    }
    while (currentSize + size > maxSize) {
      // Replace content according to selected policy
      Timestamp minTmp = std::numeric_limits<Timestamp>::max();
      typename CacheMap::iterator minIt = cacheMap.end();
      switch (policy) {
        case LRU:
          for (typename CacheMap::iterator it = cacheMap.begin();
                  it != cacheMap.end(); it++) {
            if (it->second.uploads == 0 && it->second.lastAccessed < minTmp) {
              minTmp = it->second.lastAccessed;
              minIt = it;
            }
          }
          break;
        case LFU:
          for (typename CacheMap::iterator it = cacheMap.begin();
                  it != cacheMap.end(); it++) {
            if (it->second.uploads == 0 && it->second.timesServed < minTmp) {
              minTmp = it->second.timesServed;
              minIt = it;
            }
          }
          break;
        default:
          std::cerr << "ERROR: Cache::addToCache - unrecognized CachePolicy"
                  << std::endl;
      }
      // check that there is an element we can erase (due to uploads)
      if (minIt == cacheMap.end()) {
        // all elements are being used for uploads, cannot cache
        return std::make_pair(false, deletedElements);
      }
      // else remove the identified element from the cache
      currentSize -= minIt->second.size;
      deletedElements.insert(minIt->first);
      cacheMap.erase(minIt);
    }
    // insert new element in the cache
    CacheEntry<Timestamp, Size> entry;
    entry.lastAccessed = time;
    entry.timesServed = oldFreqStat; // 0 if the content is new
    entry.size = size;
    entry.uploads = 0;
    if (cacheMap.insert(std::make_pair(content,entry)).second == true) {
      currentSize += size;
      assert(currentSize <= maxSize);
      updateOccupancy(time);
      return std::make_pair(true, deletedElements);
    } else {
      std::cerr << "WARNING: Cache::addToCache() - Could not insert content "
              << std::endl;
      updateOccupancy(time);
      return std::make_pair(false, deletedElements);
    }
  }
}

template <typename Content, typename Size, typename Timestamp>
void Cache<Content, Size, Timestamp>::clearCache() {
  cacheMap.clear();
  this->currentSize = 0;
  cacheOccupancy.reset(0,0);
}

template <typename Content, typename Size, typename Timestamp>
bool Cache<Content, Size, Timestamp>::getFromCache(Content content, Timestamp time,
        bool local) {
  typename CacheMap::iterator it = cacheMap.find(content);
  if (it != cacheMap.end()) {
    it->second.lastAccessed = time;
    it->second.timesServed++;
    if (!local)
      it->second.uploads++;
    return true;
  }
  else
    return false;
}

template <typename Content, typename Size, typename Timestamp>
bool Cache<Content, Size, Timestamp>::isCached(Content content) {
  typename CacheMap::iterator cIt = cacheMap.find(content);
  if (cIt != cacheMap.end())
    return true;
  else // shall we return size instead to allow for multiple sources?
    return false;
}

template <typename Content, typename Size, typename Timestamp>
void Cache<Content, Size, Timestamp>::removeFromCache(Content content, Timestamp time) {
  typename CacheMap::iterator it = cacheMap.find(content);
  if (it != cacheMap.end()) {
    this->currentSize -= it->second.size;
    assert(this->currentSize >= 0);
    cacheMap.erase(it);
    updateOccupancy(time);
  }
}

template <typename Content, typename Size, typename Timestamp>
bool Cache<Content, Size, Timestamp>::uploadCompleted(Content content) {
  typename CacheMap::iterator it = cacheMap.find(content);
  if (it != cacheMap.end()) {
    it->second.uploads = it->second.uploads - 1;
    assert(it->second.uploads >= 0);
    return true;
  } else {
    return false;
  }
}

template <typename Content, typename Size, typename Timestamp>
int Cache<Content, Size, Timestamp>::getCurrentUploads(Content content) {
  typename CacheMap::iterator it = cacheMap.find(content);
  if (it != cacheMap.end()) {
    return it->second.uploads;
  } else {
    return -1;
  }
}

template <typename Content, typename Size, typename Timestamp>
int Cache<Content, Size, Timestamp>::getTotalUploads() {
  int uploads = 0;
  for (typename CacheMap::iterator it = cacheMap.begin(); it != cacheMap.end(); it++)
    uploads += it->second.uploads;
  return uploads;
}

#endif	/* CACHE_HPP */

<|endoftext|>


<commit_before>#include "PushBall.h"

using PushBall = commands::PushBall;

// PushBall Command Group:
PushBall::PushBall(Intake *intake) : CommandGroup("PushBall")
{
	intake_ = intake;
	push_ = new Push(intake);
	stop_ = new Stopper(intake);
	timeout_ = 0.0;

	this->AddSequential(push_);
	this->AddSequential(new WaitCommand(timeout_));
	this->AddSequential(stop_);
}

void PushBall::SetTimeout(double timeout)
{
	timeout_ = timeout;
}

double PushBall::GetTimeout() const
{
	return timeout_;
}

// Push Command:
PushBall::Push::Push(Intake *intake)
{
	intake_ = intake;
}

void PushBall::Push::Initialize()
{
	intake_->OutakeBall();
}

bool PushBall::Push::IsFinished()
{
	return !intake_->CheckSwitch();
}

// Stopper Command:
PushBall::Stopper::Stopper(Intake *intake)
{
	intake_ = intake;
}

bool PushBall::Stopper::IsFinished()
{
	return true;
}

void PushBall::Stopper::End()
{
	intake_->Stop();
}
<commit_msg>Modifies existing functions to handle state changes and checks for Intake.<commit_after>#include "PushBall.h"

/**
 * Commands namespace with implementation
 * of PushBall command group, and nested
 * Push and Stopper command classes.
 */
namespace commands
{

// PushBall constructor:
PushBall::PushBall(Intake *intake) : CommandGroup("PushBall")
{
	intake_ = intake;
	push_ = new Push(intake);
	stop_ = new Stopper(intake);
	timeout_ = 0.0;

	SetInterruptible(false);

	this->AddSequential(push_);
	this->AddSequential(new WaitCommand(timeout_));
	this->AddSequential(stop_);
}

// PushBall main functions:
void PushBall::SetTimeout(double timeout)
{
	timeout_ = timeout;
}

double PushBall::GetTimeout() const
{
	return timeout_;
}

// Push constructor:
PushBall::Push::Push(Intake *intake)
{
	intake_ = intake;
	SetInterruptible(false);
}

// Push main functions
void PushBall::Push::Initialize()
{
	if (intake_->GetState() == State_t::HOLDING)
	{
		intake_->SetState(State_t::PUSHING);
		intake_->OutakeBall();
	}
	else
	{
		std::cout << "ERROR: Invalid starting state (should be \"HOLDING\")";
	}
}

bool PushBall::Push::IsFinished()
{
	return !intake_->CheckSwitch();
}

// Stopper constructor:
PushBall::Stopper::Stopper(Intake *intake)
{
	intake_ = intake;
	SetInterruptible(false);
}

// Stopper main functions:
bool PushBall::Stopper::IsFinished()
{
	return true;
}

void PushBall::Stopper::End()
{
	intake_->Stop();
	intake_->SetState(State_t::OFF);
}

} // end namespace commands
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: ldump.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: vg $ $Date: 2007-10-15 13:30:54 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#include "hashtbl.hxx"

#define MAXFILT 200

struct LibExport
{
    char            *cExportName;       // zu exportierende Fkt.
    unsigned long   nOrdinal;           // Nummer der zu export. Fkt.
    bool            bByName;            // NONAME anhaengen
    bool            bExport;            // exportieren oder nicht ?
};

class ExportSet;
class LibDump
{
    ExportSet       *pBaseTab;          // Zugriff auf gemangelte Namen
    ExportSet       *pIndexTab;         // Zugriff auf die Ordinals
    char            *cBName;            // Name der Datenbasis
    char            *cAPrefix;          // Prefix fuer C-Fkts.
    char            *cLibName;          // Name der zu untersuchenden Lib
    char            *cFilterName;       // Name der Filterdatei
    char            *cModName;          // Modulname
    unsigned short  nBegin;             // Nummer des ersten Exports
    unsigned long   nBaseLines;         // Line in Datenbasis
    unsigned long   nFilterLines;       // Line in FilterTabelle
    char            **pFilterLines;     // Filtertabelle
    unsigned long   nDefStart;
    bool            bBase;              // Existenz der DatenBasis;
    bool            bAll;               // Alle Fkts exportieren
    bool            bDef;               // DefFile schreiben ( bei -E )

    bool            CheckDataBase();
    bool            CheckLibrary(char * cName);
    bool            ReadDataBase();
    bool            ReadFilter(char *);
    bool            PrintSym(char *, bool bName = true );
public:
                    LibDump( char *cFileName );
                    ~LibDump();
    bool            Dump();
    bool            SetFilter(char *cFilterName);
    void            SetBeginExport(unsigned short nVal){nBegin = nVal;}
    void            SetCExport( char* pName );
    bool            Filter(char *pName);
    bool            IsFromAnonymousNamespace(char *pName);
    bool            PrintDefFile();
    bool            PrintDataBase();
    static void     DumpError(unsigned long nError);
};

<commit_msg>INTEGRATION: CWS winordinals (1.4.20); FILE MERGED 2008/03/14 10:36:34 vg 1.4.20.1: #i86800# switch to symbol-exporting linking for windows<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: ldump.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: obo $ $Date: 2008-03-25 14:07:48 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#include "hashtbl.hxx"

#define MAXFILT 200

struct LibExport
{
    char            *cExportName;       // zu exportierende Fkt.
    unsigned long   nOrdinal;           // Nummer der zu export. Fkt.
    bool            bByName;            // NONAME anhaengen
    bool            bExport;            // exportieren oder nicht ?
};

class ExportSet;
class LibDump
{
    ExportSet       *pBaseTab;          // Zugriff auf gemangelte Namen
    ExportSet       *pIndexTab;         // Zugriff auf die Ordinals
    char            *cBName;            // Name der Datenbasis
    char            *cAPrefix;          // Prefix fuer C-Fkts.
    char            *cLibName;          // Name der zu untersuchenden Lib
    char            *cFilterName;       // Name der Filterdatei
    char            *cModName;          // Modulname
    unsigned short  nBegin;             // Nummer des ersten Exports
    unsigned long   nBaseLines;         // Line in Datenbasis
    unsigned long   nFilterLines;       // Line in FilterTabelle
    char            **pFilterLines;     // Filtertabelle
    unsigned long   nDefStart;
    bool            bBase;              // Existenz der DatenBasis;
    bool            bAll;               // Alle Fkts exportieren
    bool            bDef;               // DefFile schreiben ( bei -E )
    int             bExportName;        // 0 - export by ordinal; 1 - export by name

    bool            CheckDataBase();
    bool            CheckLibrary(char * cName);
    bool            ReadDataBase();
    bool            ReadFilter(char *);
    bool            PrintSym(char *, bool bName = true );
public:
                    LibDump( char *cFileName, int bExportByName );
                    ~LibDump();
    bool            Dump();
    bool            SetFilter(char *cFilterName);
    void            SetBeginExport(unsigned short nVal){nBegin = nVal;}
    void            SetCExport( char* pName );
    bool            Filter(char *pName);
    bool            IsFromAnonymousNamespace(char *pName);
    bool            PrintDefFile();
    bool            PrintDataBase();
    static void     DumpError(unsigned long nError);
};

<|endoftext|>


<commit_before>/************************************************************************
*
* Flood Project  (2008-201x)
* Licensed under the simplified BSD license. All rights reserved.
*
************************************************************************/

#include "Core/API.h"
#include "Core/Network/Host.h"
#include "Core/Network/Network.h"
#include "Core/Network/Peer.h"
#include "Core/Network/Session.h"
#include "Core/Network/Packet.h"
#include "Core/Network/PacketProcessor.h"
#include "Core/Network/Processors/PacketKeyExchanger.h"
#include "Core/Log.h"

#if defined(PLATFORM_WINDOWS) && !defined(WIN32)
#define WIN32
#endif

#include <enet/enet.h>

NAMESPACE_CORE_BEGIN

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

#define ENET_BANDWIDTH_AUTO 0

static ENetHost* CreateEnetSocket( ENetAddress* address )
{
	int numClients = 32;
	int numChannels = 2;
	int numBandwidthIn = ENET_BANDWIDTH_AUTO;
	int numBandwidthOut = ENET_BANDWIDTH_AUTO;

	ENetHost* host = enet_host_create(address,
		numClients, numChannels, numBandwidthIn, numBandwidthOut);

	if( !host )
	{
		LogError("Error creating ENet host");
		return nullptr;
	}

	return host;
}

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

Host::Host()
	: host(nullptr)
{
}

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

Host::~Host()
{
	destroySocket();
}

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

bool Host::destroySocket()
{
	if( !host ) return false;

	enet_host_destroy(host);
	host = nullptr;

	return true;
}

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

bool Host::hasContext()
{
	return host != nullptr;
}

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

void Host::processEvents(uint32 timeout)
{
	if( !hasContext() ) return;

	ENetEvent event;

	while(enet_host_service(host, &event, timeout) > 0)
	{
		switch(event.type)
		{
		case ENET_EVENT_TYPE_CONNECT:
			handleConnectEvent(&event);
			break;
		case ENET_EVENT_TYPE_DISCONNECT:
			handleDisconnectEvent(&event);
			break;
		case ENET_EVENT_TYPE_RECEIVE:
			handleReceiveEvent(&event);
			break;
		};
	}
}

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

void Host::broadcastPacket(const PacketPtr& packet, uint8 channel)
{
	packet->prepare();
	enet_host_broadcast(host, channel, packet->getPacket());
}

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

void Host::handleConnectEvent(ENetEvent* event)
{
	ENetPeer* peer = event->peer;

	PeerPtr networkPeer = AllocateThis(Peer);
	networkPeer->setPeer(peer);
	networkPeer->setHost(this);

	// Store the network peer as user data.
	peer->data = networkPeer.get();

	networkPeer->setState(PeerState::Connected);
	onPeerConnect(networkPeer);
}

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

void Host::handleDisconnectEvent(ENetEvent* event)
{
	PeerPtr networkPeer = (Peer*) event->peer->data;
	if( !networkPeer ) return;

	networkPeer->setState(PeerState::Disconnected);
	onPeerDisconnect(networkPeer);

	// Reset the peer userdata.
	ENetPeer* peer = event->peer;
	peer->data = nullptr;
}

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

void Host::handleReceiveEvent(ENetEvent* event)
{
	ENetPacket* packet = event->packet;
	Peer* peer = (Peer*) event->peer->data;

	PacketPtr packetPtr = PacketCreate(0);
	packetPtr->setPacket(packet);

	if(peer->processInPacket(packetPtr.get(), event->channelID))
		if(peer->getSession())
			onSessionPacket(peer->getSession(), packetPtr, event->channelID);
}

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

HostClient::HostClient()
{

}

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

bool HostClient::connect( const HostConnectionDetails& details )
{
	if( peer && peer->getState() != PeerState::Disconnected )
		return false;

	peer->setState(PeerState::Connecting);

	host = CreateEnetSocket(nullptr);

	if( !host )
		return false;

	ENetAddress addr;
	addr.host = 0;
	addr.port = details.port;

	auto ret = enet_address_set_host( &addr, details.address.c_str() );
	if(ret < 0)
	{
		LogError("Cannot resolve host address ", details.address.c_str());
		return false;
	}

	enet_uint32 data = 0;

	ENetPeer* newPeer = enet_host_connect(host, &addr, details.channelCount, data);
	if (!newPeer)
	{
		LogError("No available peers for initiating an ENet connection.");
		return false;
	}

	return true;
}

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

void HostClient::onPeerConnect(const PeerPtr& newPeer)
{

	newPeer->setSession(session);
	session->setPeer(newPeer.get());
	peer = newPeer;

	auto keyExchanger = Allocate(AllocatorGetNetwork(), PacketClientKeyExchanger);
	newPeer->addProcessor(keyExchanger);
	keyExchanger->beginKeyExchange(newPeer.get());
}

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

bool HostServer::createSocket( const HostConnectionDetails& details )
{
	ENetAddress addr;
	addr.host = ENET_HOST_ANY;
	addr.port = details.port;

	host = CreateEnetSocket(&addr);

	return (host != nullptr);
}

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

void HostServer::onPeerConnect(const PeerPtr& peer)
{
	peers.push_back(peer);

	auto keyExchanger = Allocate(AllocatorGetNetwork(), PacketServerKeyExchanger);
	peer->addProcessor(keyExchanger);
}

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

void HostServer::onPeerDisconnect(const PeerPtr& peer)
{
	auto it = std::find(peers.begin(), peers.end(), peer);
	assert( it != peers.end() );

	peers.erase(it);
}

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

NAMESPACE_CORE_END<commit_msg>Change onPeerConnect code to use more HostClient::peer instead of parameter newPeer.<commit_after>/************************************************************************
*
* Flood Project  (2008-201x)
* Licensed under the simplified BSD license. All rights reserved.
*
************************************************************************/

#include "Core/API.h"
#include "Core/Network/Host.h"
#include "Core/Network/Network.h"
#include "Core/Network/Peer.h"
#include "Core/Network/Session.h"
#include "Core/Network/Packet.h"
#include "Core/Network/PacketProcessor.h"
#include "Core/Network/Processors/PacketKeyExchanger.h"
#include "Core/Log.h"

#if defined(PLATFORM_WINDOWS) && !defined(WIN32)
#define WIN32
#endif

#include <enet/enet.h>

NAMESPACE_CORE_BEGIN

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

#define ENET_BANDWIDTH_AUTO 0

static ENetHost* CreateEnetSocket( ENetAddress* address )
{
	int numClients = 32;
	int numChannels = 2;
	int numBandwidthIn = ENET_BANDWIDTH_AUTO;
	int numBandwidthOut = ENET_BANDWIDTH_AUTO;

	ENetHost* host = enet_host_create(address,
		numClients, numChannels, numBandwidthIn, numBandwidthOut);

	if( !host )
	{
		LogError("Error creating ENet host");
		return nullptr;
	}

	return host;
}

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

Host::Host()
	: host(nullptr)
{
}

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

Host::~Host()
{
	destroySocket();
}

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

bool Host::destroySocket()
{
	if( !host ) return false;

	enet_host_destroy(host);
	host = nullptr;

	return true;
}

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

bool Host::hasContext()
{
	return host != nullptr;
}

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

void Host::processEvents(uint32 timeout)
{
	if( !hasContext() ) return;

	ENetEvent event;

	while(enet_host_service(host, &event, timeout) > 0)
	{
		switch(event.type)
		{
		case ENET_EVENT_TYPE_CONNECT:
			handleConnectEvent(&event);
			break;
		case ENET_EVENT_TYPE_DISCONNECT:
			handleDisconnectEvent(&event);
			break;
		case ENET_EVENT_TYPE_RECEIVE:
			handleReceiveEvent(&event);
			break;
		};
	}
}

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

void Host::broadcastPacket(const PacketPtr& packet, uint8 channel)
{
	packet->prepare();
	enet_host_broadcast(host, channel, packet->getPacket());
}

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

void Host::handleConnectEvent(ENetEvent* event)
{
	ENetPeer* peer = event->peer;

	PeerPtr networkPeer = AllocateThis(Peer);
	networkPeer->setPeer(peer);
	networkPeer->setHost(this);

	// Store the network peer as user data.
	peer->data = networkPeer.get();

	networkPeer->setState(PeerState::Connected);
	onPeerConnect(networkPeer);
}

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

void Host::handleDisconnectEvent(ENetEvent* event)
{
	PeerPtr networkPeer = (Peer*) event->peer->data;
	if( !networkPeer ) return;

	networkPeer->setState(PeerState::Disconnected);
	onPeerDisconnect(networkPeer);

	// Reset the peer userdata.
	ENetPeer* peer = event->peer;
	peer->data = nullptr;
}

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

void Host::handleReceiveEvent(ENetEvent* event)
{
	ENetPacket* packet = event->packet;
	Peer* peer = (Peer*) event->peer->data;

	PacketPtr packetPtr = PacketCreate(0);
	packetPtr->setPacket(packet);

	if(peer->processInPacket(packetPtr.get(), event->channelID))
		if(peer->getSession())
			onSessionPacket(peer->getSession(), packetPtr, event->channelID);
}

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

HostClient::HostClient()
{

}

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

bool HostClient::connect( const HostConnectionDetails& details )
{
	if( peer && peer->getState() != PeerState::Disconnected )
		return false;

	peer->setState(PeerState::Connecting);

	host = CreateEnetSocket(nullptr);

	if( !host )
		return false;

	ENetAddress addr;
	addr.host = 0;
	addr.port = details.port;

	auto ret = enet_address_set_host( &addr, details.address.c_str() );
	if(ret < 0)
	{
		LogError("Cannot resolve host address ", details.address.c_str());
		return false;
	}

	enet_uint32 data = 0;

	ENetPeer* newPeer = enet_host_connect(host, &addr, details.channelCount, data);
	if (!newPeer)
	{
		LogError("No available peers for initiating an ENet connection.");
		return false;
	}

	return true;
}

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

void HostClient::onPeerConnect(const PeerPtr& newPeer)
{
	peer = newPeer;
	peer->setSession(&session);
	session.setPeer(peer.get());

	auto keyExchanger = Allocate(AllocatorGetNetwork(), PacketClientKeyExchanger);
	peer->addProcessor(keyExchanger);
	keyExchanger->beginKeyExchange(peer.get());
}

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

bool HostServer::createSocket( const HostConnectionDetails& details )
{
	ENetAddress addr;
	addr.host = ENET_HOST_ANY;
	addr.port = details.port;

	host = CreateEnetSocket(&addr);

	return (host != nullptr);
}

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

void HostServer::onPeerConnect(const PeerPtr& peer)
{
	peers.push_back(peer);

	auto keyExchanger = Allocate(AllocatorGetNetwork(), PacketServerKeyExchanger);
	peer->addProcessor(keyExchanger);
}

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

void HostServer::onPeerDisconnect(const PeerPtr& peer)
{
	auto it = std::find(peers.begin(), peers.end(), peer);
	assert( it != peers.end() );

	peers.erase(it);
}

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

NAMESPACE_CORE_END<|endoftext|>


<commit_before>// soundmgr.cxx -- Sound effect management class
//
// Sound manager initially written by David Findlay
// <david_j_findlay@yahoo.com.au> 2001
//
// C++-ified by Curtis Olson, started March 2001.
//
// Copyright (C) 2001  Curtis L. Olson - curt@flightgear.org
//
// 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 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// $Id$

#include <iostream>

#if defined(__APPLE__)
# include <OpenAL/al.h>
# include <OpenAL/alut.h>
# include <OpenAL/alc.h>
#else
# include <AL/al.h>
# include <AL/alut.h>
# include <AL/alc.h>
#endif

#include <simgear/debug/logstream.hxx>
#include <simgear/misc/sg_path.hxx>

#include "soundmgr_openal.hxx"

//
// Sound Manager
//

// constructor
SGSoundMgr::SGSoundMgr() {

    SG_LOG( SG_GENERAL, SG_ALERT, "Initializing OpenAL sound manager" );

    // initialize OpenAL
    alutInit( 0, NULL );
    alGetError();
    if ( alGetError() == AL_NO_ERROR) {
        working = true;
    } else {
        working = false;
	SG_LOG( SG_GENERAL, SG_ALERT, "Audio initialization failed!" );
    }

    listener_pos[0] = 0.0;
    listener_pos[1] = 0.0;
    listener_pos[2] = 0.0;

    listener_vel[0] = 0.0;
    listener_vel[1] = 0.0;
    listener_vel[2] = 0.0;

    listener_ori[0] = 0.0;
    listener_ori[1] = 0.0;
    listener_ori[2] = -1.0;
    listener_ori[3] = 0.0;
    listener_ori[4] = 1.0;
    listener_ori[5] = 0.0;

    alListenerfv( AL_POSITION, listener_pos );
    alListenerfv( AL_VELOCITY, listener_vel );
    alListenerfv( AL_ORIENTATION, listener_ori );
    alGetError();
    if ( alGetError() != AL_NO_ERROR) {
	SG_LOG( SG_GENERAL, SG_ALERT,
                "Oops AL error after audio initialization!" );
    }

    // exaggerate the ear candy?
    alDopplerFactor(1.0);
}

// destructor

SGSoundMgr::~SGSoundMgr() {

    //
    // Remove the samples from the sample manager.
    //
    sample_map_iterator sample_current = samples.begin();
    sample_map_iterator sample_end = samples.end();
    for ( ; sample_current != sample_end; ++sample_current ) {
	SGSoundSample *sample = sample_current->second;
	delete sample;
    }

    alutExit();
}

// initialize the sound manager
void SGSoundMgr::init() {
    //
    // Remove the samples from the sample manager.
    //
    sample_map_iterator sample_current = samples.begin();
    sample_map_iterator sample_end = samples.end();
    for ( ; sample_current != sample_end; ++sample_current ) {
        SGSoundSample *sample = sample_current->second;
        delete sample;
    }
    samples.clear();
}

void SGSoundMgr::bind ()
{
    // no properties
}

void SGSoundMgr::unbind ()
{
    // no properties
}

// run the audio scheduler
void SGSoundMgr::update( double dt ) {
}

void
SGSoundMgr::pause ()
{
    ALCcontext *pCurContext = alcGetCurrentContext();
    alcSuspendContext( pCurContext );
    if ( alGetError() != AL_NO_ERROR) {
	SG_LOG( SG_GENERAL, SG_ALERT,
                "Oops AL error after soundmgr pause()!" );
    }
}

void
SGSoundMgr::resume ()
{
    ALCcontext *pCurContext = alcGetCurrentContext();
    alcProcessContext( pCurContext );
    if ( alGetError() != AL_NO_ERROR) {
	SG_LOG( SG_GENERAL, SG_ALERT,
                "Oops AL error after soundmgr resume()!" );
    }
}

// add a sound effect, return true if successful
bool SGSoundMgr::add( SGSoundSample *sound, const string& refname ) {

    sample_map_iterator sample_it = samples.find( refname );
    if ( sample_it != samples.end() ) {
        // sound already exists
        return false;
    }

    samples[refname] = sound;

    return true;
}

// remove a sound effect, return true if successful
bool SGSoundMgr::remove( const string &refname ) {

    sample_map_iterator sample_it = samples.find( refname );
    if ( sample_it != samples.end() ) {
	// first stop the sound from playing (so we don't bomb the
	// audio scheduler)
	SGSoundSample *sample = sample_it->second;
        delete sample;
        samples.erase( sample_it );

        // cout << "sndmgr: removed -> " << refname << endl;
	return true;
    } else {
        // cout << "sndmgr: failed remove -> " << refname << endl;
        return false;
    }
}

// return true of the specified sound exists in the sound manager system
bool SGSoundMgr::exists( const string &refname ) {
    sample_map_iterator sample_it = samples.find( refname );
    if ( sample_it != samples.end() ) {
	return true;
    } else {
	return false;
    }
}

// return a pointer to the SGSoundSample if the specified sound exists
// in the sound manager system, otherwise return NULL
SGSoundSample *SGSoundMgr::find( const string &refname ) {
    sample_map_iterator sample_it = samples.find( refname );
    if ( sample_it != samples.end() ) {
	return sample_it->second;
    } else {
	return NULL;
    }
}

// tell the scheduler to play the indexed sample in a continuous
// loop
bool SGSoundMgr::play_looped( const string &refname ) {
    SGSoundSample *sample;

    if ( (sample = find( refname )) == NULL ) {
        return false;
    } else {
        sample->play( true );
        return true;
    }
}

// tell the scheduler to play the indexed sample once
bool SGSoundMgr::play_once( const string& refname ) {
    SGSoundSample *sample;

    if ( (sample = find( refname )) == NULL ) {
        return false;
    } else {
        sample->play( false );
        return true;
    }
}

// return true of the specified sound is currently being played
bool SGSoundMgr::is_playing( const string& refname ) {
    SGSoundSample *sample;

    if ( (sample = find( refname )) == NULL ) {
        return false;
    } else {
        return ( sample->is_playing() );
    }
}

// immediate stop playing the sound
bool SGSoundMgr::stop( const string& refname ) {
    SGSoundSample *sample;

    if ( (sample = find( refname )) == NULL ) {
        return false;
    } else {
        sample->stop();
        return true;
    }
}

// set source position of all managed sounds
void SGSoundMgr::set_source_pos_all( ALfloat *pos ) {
    sample_map_iterator sample_current = samples.begin();
    sample_map_iterator sample_end = samples.end();
    for ( ; sample_current != sample_end; ++sample_current ) {
	SGSoundSample *sample = sample_current->second;
        sample->set_source_pos( pos );
    }
}

// set source velocity of all managed sounds
void SGSoundMgr::set_source_vel_all( ALfloat *vel ) {
    sample_map_iterator sample_current = samples.begin();
    sample_map_iterator sample_end = samples.end();
    for ( ; sample_current != sample_end; ++sample_current ) {
	SGSoundSample *sample = sample_current->second;
        sample->set_source_vel( vel );
    }
}
<commit_msg>Tweak the doppler effect.<commit_after>// soundmgr.cxx -- Sound effect management class
//
// Sound manager initially written by David Findlay
// <david_j_findlay@yahoo.com.au> 2001
//
// C++-ified by Curtis Olson, started March 2001.
//
// Copyright (C) 2001  Curtis L. Olson - curt@flightgear.org
//
// 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 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// $Id$

#include <iostream>

#if defined(__APPLE__)
# include <OpenAL/al.h>
# include <OpenAL/alut.h>
# include <OpenAL/alc.h>
#else
# include <AL/al.h>
# include <AL/alut.h>
# include <AL/alc.h>
#endif

#include <simgear/debug/logstream.hxx>
#include <simgear/misc/sg_path.hxx>

#include "soundmgr_openal.hxx"

//
// Sound Manager
//

// constructor
SGSoundMgr::SGSoundMgr() {

    SG_LOG( SG_GENERAL, SG_ALERT, "Initializing OpenAL sound manager" );

    // initialize OpenAL
    alutInit( 0, NULL );
    alGetError();
    if ( alGetError() == AL_NO_ERROR) {
        working = true;
    } else {
        working = false;
	SG_LOG( SG_GENERAL, SG_ALERT, "Audio initialization failed!" );
    }

    listener_pos[0] = 0.0;
    listener_pos[1] = 0.0;
    listener_pos[2] = 0.0;

    listener_vel[0] = 0.0;
    listener_vel[1] = 0.0;
    listener_vel[2] = 0.0;

    listener_ori[0] = 0.0;
    listener_ori[1] = 0.0;
    listener_ori[2] = -1.0;
    listener_ori[3] = 0.0;
    listener_ori[4] = 1.0;
    listener_ori[5] = 0.0;

    alListenerfv( AL_POSITION, listener_pos );
    alListenerfv( AL_VELOCITY, listener_vel );
    alListenerfv( AL_ORIENTATION, listener_ori );
    alGetError();
    if ( alGetError() != AL_NO_ERROR) {
	SG_LOG( SG_GENERAL, SG_ALERT,
                "Oops AL error after audio initialization!" );
    }

    // exaggerate the ear candy?
    alDopplerFactor(1.0);
    alDopplerVelocity(340.0);	// speed of sound in meters per second.
}

// destructor

SGSoundMgr::~SGSoundMgr() {

    //
    // Remove the samples from the sample manager.
    //
    sample_map_iterator sample_current = samples.begin();
    sample_map_iterator sample_end = samples.end();
    for ( ; sample_current != sample_end; ++sample_current ) {
	SGSoundSample *sample = sample_current->second;
	delete sample;
    }

    alutExit();
}

// initialize the sound manager
void SGSoundMgr::init() {
    //
    // Remove the samples from the sample manager.
    //
    sample_map_iterator sample_current = samples.begin();
    sample_map_iterator sample_end = samples.end();
    for ( ; sample_current != sample_end; ++sample_current ) {
        SGSoundSample *sample = sample_current->second;
        delete sample;
    }
    samples.clear();
}

void SGSoundMgr::bind ()
{
    // no properties
}

void SGSoundMgr::unbind ()
{
    // no properties
}

// run the audio scheduler
void SGSoundMgr::update( double dt ) {
}

void
SGSoundMgr::pause ()
{
    ALCcontext *pCurContext = alcGetCurrentContext();
    alcSuspendContext( pCurContext );
    if ( alGetError() != AL_NO_ERROR) {
	SG_LOG( SG_GENERAL, SG_ALERT,
                "Oops AL error after soundmgr pause()!" );
    }
}

void
SGSoundMgr::resume ()
{
    ALCcontext *pCurContext = alcGetCurrentContext();
    alcProcessContext( pCurContext );
    if ( alGetError() != AL_NO_ERROR) {
	SG_LOG( SG_GENERAL, SG_ALERT,
                "Oops AL error after soundmgr resume()!" );
    }
}

// add a sound effect, return true if successful
bool SGSoundMgr::add( SGSoundSample *sound, const string& refname ) {

    sample_map_iterator sample_it = samples.find( refname );
    if ( sample_it != samples.end() ) {
        // sound already exists
        return false;
    }

    samples[refname] = sound;

    return true;
}

// remove a sound effect, return true if successful
bool SGSoundMgr::remove( const string &refname ) {

    sample_map_iterator sample_it = samples.find( refname );
    if ( sample_it != samples.end() ) {
	// first stop the sound from playing (so we don't bomb the
	// audio scheduler)
	SGSoundSample *sample = sample_it->second;
        delete sample;
        samples.erase( sample_it );

        // cout << "sndmgr: removed -> " << refname << endl;
	return true;
    } else {
        // cout << "sndmgr: failed remove -> " << refname << endl;
        return false;
    }
}

// return true of the specified sound exists in the sound manager system
bool SGSoundMgr::exists( const string &refname ) {
    sample_map_iterator sample_it = samples.find( refname );
    if ( sample_it != samples.end() ) {
	return true;
    } else {
	return false;
    }
}

// return a pointer to the SGSoundSample if the specified sound exists
// in the sound manager system, otherwise return NULL
SGSoundSample *SGSoundMgr::find( const string &refname ) {
    sample_map_iterator sample_it = samples.find( refname );
    if ( sample_it != samples.end() ) {
	return sample_it->second;
    } else {
	return NULL;
    }
}

// tell the scheduler to play the indexed sample in a continuous
// loop
bool SGSoundMgr::play_looped( const string &refname ) {
    SGSoundSample *sample;

    if ( (sample = find( refname )) == NULL ) {
        return false;
    } else {
        sample->play( true );
        return true;
    }
}

// tell the scheduler to play the indexed sample once
bool SGSoundMgr::play_once( const string& refname ) {
    SGSoundSample *sample;

    if ( (sample = find( refname )) == NULL ) {
        return false;
    } else {
        sample->play( false );
        return true;
    }
}

// return true of the specified sound is currently being played
bool SGSoundMgr::is_playing( const string& refname ) {
    SGSoundSample *sample;

    if ( (sample = find( refname )) == NULL ) {
        return false;
    } else {
        return ( sample->is_playing() );
    }
}

// immediate stop playing the sound
bool SGSoundMgr::stop( const string& refname ) {
    SGSoundSample *sample;

    if ( (sample = find( refname )) == NULL ) {
        return false;
    } else {
        sample->stop();
        return true;
    }
}

// set source position of all managed sounds
void SGSoundMgr::set_source_pos_all( ALfloat *pos ) {
    sample_map_iterator sample_current = samples.begin();
    sample_map_iterator sample_end = samples.end();
    for ( ; sample_current != sample_end; ++sample_current ) {
	SGSoundSample *sample = sample_current->second;
        sample->set_source_pos( pos );
    }
}

// set source velocity of all managed sounds
void SGSoundMgr::set_source_vel_all( ALfloat *vel ) {
    sample_map_iterator sample_current = samples.begin();
    sample_map_iterator sample_end = samples.end();
    for ( ; sample_current != sample_end; ++sample_current ) {
	SGSoundSample *sample = sample_current->second;
        sample->set_source_vel( vel );
    }
}
<|endoftext|>


<commit_before><commit_msg>update HWP level metadata for nest, common files<commit_after><|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/pm/p9_pm_get_poundv_bucket.C $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
///
/// @file p9_pm_get_poundv_bucket.C
/// @brief Grab PM data from attribute
///

// ----------------------------------------------------------------------
// Includes
// ----------------------------------------------------------------------
#include <p9_pm_get_poundv_bucket.H>
#include <attribute_ids.H>

fapi2::ReturnCode p9_pm_get_poundv_bucket(
    const fapi2::Target<fapi2::TARGET_TYPE_EQ>& i_target,
    fapi2::voltageBucketData_t& o_data)
{
    FAPI_IMP("Entering p9_pm_get_poundv_bucket ....");

    //Create a pointer version of the out param o_data so that
    // we can access bytes individually
    uint8_t* l_tempBuffer = reinterpret_cast<uint8_t*>(malloc(sizeof(o_data)));

    //Set up a char array to hold the bucket data from an attr read
    fapi2::ATTR_POUNDV_BUCKET_DATA_Type l_bucketAttr;

    //Perform an ATTR_GET for POUNDV_BUCKET data on the EQ target
    FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_POUNDV_BUCKET_DATA,
                           i_target,
                           l_bucketAttr));

#ifndef _BIG_ENDIAN
    //The first byte is simply a uint8 that describes the bucket ID
    l_tempBuffer[0] = l_bucketAttr[0];

    //Skipping the first byte (which has already been taken of) start reading
    //the voltage data 2 bytes at a time.
    for(uint8_t offset = 1; offset < sizeof(o_data); offset += 2)
    {
        //Switch from Big Endian to Little Endian
        l_tempBuffer[offset] = l_bucketAttr[offset + 1];
        l_tempBuffer[offset + 1] = l_bucketAttr[offset];
    }

    memcpy(&o_data,
           l_tempBuffer,
           sizeof(o_data));

#else
    memcpy(&o_data,
           l_bucketAttr,
           sizeof(o_data));
#endif

fapi_try_exit:
    free(l_tempBuffer);
    FAPI_IMP("Exiting p9_pm_get_poundv_bucket ....");

    return fapi2::current_err;
}
<commit_msg>PSTATE parameter block:POUNDV parsing function vs native implementation<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/pm/p9_pm_get_poundv_bucket.C $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
///
/// @file p9_pm_get_poundv_bucket.C
/// @brief Grab PM data from attribute
///

// ----------------------------------------------------------------------
// Includes
// ----------------------------------------------------------------------
#include <p9_pm_get_poundv_bucket.H>
#include <attribute_ids.H>

fapi2::ReturnCode p9_pm_get_poundv_bucket(
    const fapi2::Target<fapi2::TARGET_TYPE_EQ>& i_target,
    fapi2::voltageBucketData_t& o_data)
{
    FAPI_IMP("Entering p9_pm_get_poundv_bucket ....");

    //Set up a char array to hold the bucket data from an attr read
    fapi2::ATTR_POUNDV_BUCKET_DATA_Type l_bucketAttr;

    //Perform an ATTR_GET for POUNDV_BUCKET data on the EQ target
    FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_POUNDV_BUCKET_DATA,
                           i_target,
                           l_bucketAttr));

    memcpy(&o_data, l_bucketAttr, sizeof(o_data));

fapi_try_exit:
    FAPI_IMP("Exiting p9_pm_get_poundv_bucket ....");

    return fapi2::current_err;
}
<|endoftext|>