<commit_before>#include <cassert>
#include <cstdlib>
#include <fstream>
#include <sstream>
#include <iostream>

#include "Parser.h"
#include "TypeChecker.h"

namespace {
inline bool is_newline(char c) {
    return c == '\n';
}

inline bool is_whitespace(char c) {
    return c == ' ' || c == '\t' || is_newline(c);
}

inline bool is_digit(char c) {
    return c >= 0x30 && c <= 0x39;
}

inline bool is_paren(char c) {
    return c == '(' || c == ')';
}

inline bool is_brace(char c) {
    return c == '{' || c == '}';
}

inline bool is_alphanumeric(char c) {
    return is_digit(c) || (c >= 0x41 && c <= 0x5a) || (c >= 0x61 && c <= 0x7a);
}

}

namespace Bish {

/*
 * The Bish tokenizer. Given a string to tokenize, use the peek() and
 * next() methods to produce a stream of tokens.
 */
class Tokenizer {
public:
    Tokenizer(const std::string &t) : text(t), idx(0), lineno(1) {}

    // Return the token at the head of the stream, but do not skip it.
    Token peek() {
        ResultState st = get_token();
        return st.first;
    }

    // Skip the token currently at the head of the stream.
    void next() {
        ResultState st = get_token();
        idx = st.second;
    }

    // Return the substring beginning at the current index and
    // continuing  until the first occurrence of a token of type
    // 'type'.
    std::string scan_until(Token::Type type) {
        unsigned start = idx;
        Token t = peek();
        while (!t.isa(type) && !eos()) {
            next();
            t = peek();
        }
        unsigned len = idx - start;
        return text.substr(start, len);
    }

    // Return a human-readable representation of the current position
    // in the string.
    std::string position() const {
        std::stringstream s;
        s << "character '" << text[idx] << "', line " << lineno;
        return s.str();
    }

private:
    typedef std::pair<Token, unsigned> ResultState;
    const std::string &text;
    unsigned idx;
    unsigned lineno;

    // Return the current character.
    inline char curchar() const {
        return text[idx];
    }

    // Return true if the tokenizer is at "end of string".
    inline bool eos() const {
        return idx >= text.length();
    }

    // Skip ahead until the next non-whitespace character.
    inline void skip_whitespace() {
        while (!eos() && is_whitespace(curchar())) {
            if (is_newline(curchar())) ++lineno;
            ++idx;
        }
    }

    // Form the next token. The result is a pair (T, n) where T is the
    // token and n is the new index after skipping past T.
    ResultState get_token() {
        skip_whitespace();
        char c = curchar();
        if (eos()) {
            return ResultState(Token::EOS(), idx);
        } else if (c == '(') {
            return ResultState(Token::LParen(), idx + 1);
        } else if (c == ')') {
            return ResultState(Token::RParen(), idx + 1);
        } else if (c == '{') {
            return ResultState(Token::LBrace(), idx + 1);
        } else if (c == '}') {
            return ResultState(Token::RBrace(), idx + 1);
        } else if (c == ';') {
            return ResultState(Token::Semicolon(), idx + 1);
        } else if (c == '=') {
            return ResultState(Token::Equals(), idx + 1);
        } else if (c == '+') {
            return ResultState(Token::Plus(), idx + 1);
        } else if (c == '-') {
            return ResultState(Token::Minus(), idx + 1);
        } else if (c == '*') {
            return ResultState(Token::Star(), idx + 1);
        } else if (c == '/') {
            return ResultState(Token::Slash(), idx + 1);
        } else if (c == '"') {
            return ResultState(Token::Quote(), idx + 1);
        } else if (is_digit(c)) {
            return read_number();
        } else {
            return read_symbol();
        }
    }

    // Read a multi-digit (and possibly fractional) number token.
    ResultState read_number() {
        char c = curchar();
        bool fractional = false;
        std::string snum;
        unsigned newidx = idx;
        while (is_digit(text[newidx])) {
            snum += text[newidx];
            newidx++;
        }
        if (text[newidx] == '.') {
            fractional = true;
            snum += ".";
            newidx++;
            while (is_digit(text[newidx])) {
                snum += text[newidx];
                newidx++;
            }
        }
        if (fractional) {
            return ResultState(Token::Fractional(snum), newidx);
        } else {
            return ResultState(Token::Int(snum), newidx);
        }
    }

    // Read a multi-character string of characters.
    ResultState read_symbol() {
        std::string sym = "";
        unsigned newidx = idx;
        while (is_alphanumeric(text[newidx])) {
            sym += text[newidx];
            newidx++;
        }
        return ResultState(Token::Symbol(sym), newidx);
    }
};

Parser::~Parser() {
    if (tokenizer) delete tokenizer;
}

// Return the entire contents of the file at the given path.
std::string Parser::read_file(const std::string &path) {
    std::ifstream t(path);
    if (!t.is_open()) {
        std::string msg = "Failed to open file at " + path;
        abort(msg);
    }
    std::stringstream buffer;
    buffer << t.rdbuf();
    return buffer.str();
}

// Parse the given file into a Bish AST.
AST *Parser::parse(const std::string &path) {
    std::string contents = read_file(path);
    return parse_string(contents);
}

// Parse the given string into a Bish AST.
AST *Parser::parse_string(const std::string &text) {
    if (tokenizer) delete tokenizer;

    // Insert a dummy block for root scope.
    std::string preprocessed = "{" + text + "}";
    tokenizer = new Tokenizer(preprocessed);

    AST *ast = new AST(block());
    // Type checking
    TypeChecker types;
    ast->accept(&types);
    return ast;
}

// Assert that the given token is of the given type. If true, advance
// the tokenizer. If false, produce an error message.
void Parser::expect(const Token &t, Token::Type ty, const std::string &msg) {
    if (!t.isa(ty)) {
        std::stringstream errstr;
        errstr << "Parsing error: " << msg << " near " << tokenizer->position();
        abort(errstr.str());
    }
    tokenizer->next();
}

// Terminate the parsing process with the given error message.
void Parser::abort(const std::string &msg) {
    std::cerr << msg << "\n";
    exit(1);
}

// Return true if the given token is a unary operator.
bool Parser::is_unop_token(const Token &t) {
    return t.isa(Token::MinusType);
}

// Return true if the given token is a binary operator.
bool Parser::is_binop_token(const Token &t) {
    return t.isa(Token::PlusType) || t.isa(Token::MinusType) ||
        t.isa(Token::StarType) || t.isa(Token::SlashType);
}

// Return the binary Operator corresponding to the given token.
BinOp::Operator Parser::get_binop_operator(const Token &t) {
    switch (t.type()) {
    case Token::PlusType:
        return BinOp::Add;
    case Token::MinusType:
        return BinOp::Sub;
    case Token::StarType:
        return BinOp::Mul;
    case Token::SlashType:
        return BinOp::Div;
    default:
        abort("Invalid operator for binary operation.");
        return BinOp::Add;
    }
}

// Return the unary Operator corresponding to the given token.
UnaryOp::Operator Parser::get_unaryop_operator(const Token &t) {
    switch (t.type()) {
    case Token::MinusType:
        return UnaryOp::Negate;
    default:
        abort("Invalid operator for unary operation.");
        return UnaryOp::Negate;
    }
}

// Return the Bish Type to represent the given AST node.
Type Parser::get_primitive_type(const ASTNode *n) {
    if (const Integer *v = dynamic_cast<const Integer*>(n)) {
        return IntegerTy;
    } else if (const Fractional *v = dynamic_cast<const Fractional*>(n)) {
        return FractionalTy;
    } else if (const String *v = dynamic_cast<const String*>(n)) {
        return StringTy;
    } else if (const Boolean *v = dynamic_cast<const Boolean*>(n)) {
        return BooleanTy;
    } else {
        return UndefinedTy;
    }
}

// Parse a Bish block.
Block *Parser::block() {
    SymbolTable *old = current_symbol_table;
    current_symbol_table = new SymbolTable();
    std::vector<ASTNode *> statements;
    Token t = tokenizer->peek();
    expect(t, Token::LBraceType, "Expected block to begin with '{'");
    bool end = false;
    while (!end) {
        t = tokenizer->peek();
        switch (t.type()) {
        case Token::RBraceType:
            end = true;
            break;
        default:
            statements.push_back(stmt());
            break;
        }
    }
    expect(tokenizer->peek(), Token::RBraceType, "Expected block to end with '}'");
    Block *result = new Block(statements, current_symbol_table);
    current_symbol_table = old;
    return result;
}

// Parse a Bish statement.
ASTNode *Parser::stmt() {
    Variable *v = var();
    expect(tokenizer->peek(), Token::EqualsType, "Expected assignment operator");
    ASTNode *e = expr();
    expect(tokenizer->peek(), Token::SemicolonType, "Expected statement to end with ';'");
    Type t = get_primitive_type(e);
    if (t != UndefinedTy) {
        current_symbol_table->insert(v->name, t);
    }
    return new Assignment(v, e);
}

// Parse a Bish variable.
Variable *Parser::var() {
    std::string name = tokenizer->peek().value();
    expect(tokenizer->peek(), Token::SymbolType, "Expected variable to be a symbol");
    return new Variable(name);
}

// Parse a Bish expression.
ASTNode *Parser::expr() {
    Token t = tokenizer->peek();
    if (t.isa(Token::LParenType)) {
        tokenizer->next();
        ASTNode *e = expr();
        expect(tokenizer->peek(), Token::RParenType, "Unmatched '('");
        return e;
    } else if (is_unop_token(t)) {
        return unop();
    } else {
        ASTNode *a = atom();
        if (is_binop_token(tokenizer->peek())) {
            return binop(a);
        }
        return a;
    }
}

// Parse a Bish binary operator.
BinOp *Parser::binop(ASTNode *a) {
    BinOp *bin = NULL;
    while (is_binop_token(tokenizer->peek())) {
        BinOp::Operator op = get_binop_operator(tokenizer->peek());
        tokenizer->next();
        ASTNode *b = atom();
        bin = new BinOp(op, a, b);
        a = bin;
    }
    return bin;
}

// Parse a Bish unary operator.
UnaryOp *Parser::unop() {
    UnaryOp::Operator op = get_unaryop_operator(tokenizer->peek());
    tokenizer->next();
    ASTNode *a = atom();
    return new UnaryOp(op, a);
}

// Parse a Bish atom.
ASTNode *Parser::atom() {
    Token t = tokenizer->peek();
    tokenizer->next();

    switch(t.type()) {
    case Token::SymbolType:
        return new Variable(t.value());
    case Token::IntType:
        return new Integer(t.value());
    case Token::FractionalType:
        return new Fractional(t.value());
    case Token::QuoteType: {
        std::string str = tokenizer->scan_until(Token::QuoteType);
        expect(tokenizer->peek(), Token::QuoteType, "Unmatched '\"'");
        return new String(str);
    }
    default:
        abort("Invalid token type for atom.");
        return NULL;
    }
}

}
<commit_msg>Allow nested blocks.<commit_after>#include <cassert>
#include <cstdlib>
#include <fstream>
#include <sstream>
#include <iostream>

#include "Parser.h"
#include "TypeChecker.h"

namespace {
inline bool is_newline(char c) {
    return c == '\n';
}

inline bool is_whitespace(char c) {
    return c == ' ' || c == '\t' || is_newline(c);
}

inline bool is_digit(char c) {
    return c >= 0x30 && c <= 0x39;
}

inline bool is_paren(char c) {
    return c == '(' || c == ')';
}

inline bool is_brace(char c) {
    return c == '{' || c == '}';
}

inline bool is_alphanumeric(char c) {
    return is_digit(c) || (c >= 0x41 && c <= 0x5a) || (c >= 0x61 && c <= 0x7a);
}

}

namespace Bish {

/*
 * The Bish tokenizer. Given a string to tokenize, use the peek() and
 * next() methods to produce a stream of tokens.
 */
class Tokenizer {
public:
    Tokenizer(const std::string &t) : text(t), idx(0), lineno(1) {}

    // Return the token at the head of the stream, but do not skip it.
    Token peek() {
        ResultState st = get_token();
        return st.first;
    }

    // Skip the token currently at the head of the stream.
    void next() {
        ResultState st = get_token();
        idx = st.second;
    }

    // Return the substring beginning at the current index and
    // continuing  until the first occurrence of a token of type
    // 'type'.
    std::string scan_until(Token::Type type) {
        unsigned start = idx;
        Token t = peek();
        while (!t.isa(type) && !eos()) {
            next();
            t = peek();
        }
        unsigned len = idx - start;
        return text.substr(start, len);
    }

    // Return a human-readable representation of the current position
    // in the string.
    std::string position() const {
        std::stringstream s;
        s << "character '" << text[idx] << "', line " << lineno;
        return s.str();
    }

private:
    typedef std::pair<Token, unsigned> ResultState;
    const std::string &text;
    unsigned idx;
    unsigned lineno;

    // Return the current character.
    inline char curchar() const {
        return text[idx];
    }

    // Return true if the tokenizer is at "end of string".
    inline bool eos() const {
        return idx >= text.length();
    }

    // Skip ahead until the next non-whitespace character.
    inline void skip_whitespace() {
        while (!eos() && is_whitespace(curchar())) {
            if (is_newline(curchar())) ++lineno;
            ++idx;
        }
    }

    // Form the next token. The result is a pair (T, n) where T is the
    // token and n is the new index after skipping past T.
    ResultState get_token() {
        skip_whitespace();
        char c = curchar();
        if (eos()) {
            return ResultState(Token::EOS(), idx);
        } else if (c == '(') {
            return ResultState(Token::LParen(), idx + 1);
        } else if (c == ')') {
            return ResultState(Token::RParen(), idx + 1);
        } else if (c == '{') {
            return ResultState(Token::LBrace(), idx + 1);
        } else if (c == '}') {
            return ResultState(Token::RBrace(), idx + 1);
        } else if (c == ';') {
            return ResultState(Token::Semicolon(), idx + 1);
        } else if (c == '=') {
            return ResultState(Token::Equals(), idx + 1);
        } else if (c == '+') {
            return ResultState(Token::Plus(), idx + 1);
        } else if (c == '-') {
            return ResultState(Token::Minus(), idx + 1);
        } else if (c == '*') {
            return ResultState(Token::Star(), idx + 1);
        } else if (c == '/') {
            return ResultState(Token::Slash(), idx + 1);
        } else if (c == '"') {
            return ResultState(Token::Quote(), idx + 1);
        } else if (is_digit(c)) {
            return read_number();
        } else {
            return read_symbol();
        }
    }

    // Read a multi-digit (and possibly fractional) number token.
    ResultState read_number() {
        char c = curchar();
        bool fractional = false;
        std::string snum;
        unsigned newidx = idx;
        while (is_digit(text[newidx])) {
            snum += text[newidx];
            newidx++;
        }
        if (text[newidx] == '.') {
            fractional = true;
            snum += ".";
            newidx++;
            while (is_digit(text[newidx])) {
                snum += text[newidx];
                newidx++;
            }
        }
        if (fractional) {
            return ResultState(Token::Fractional(snum), newidx);
        } else {
            return ResultState(Token::Int(snum), newidx);
        }
    }

    // Read a multi-character string of characters.
    ResultState read_symbol() {
        std::string sym = "";
        unsigned newidx = idx;
        while (is_alphanumeric(text[newidx])) {
            sym += text[newidx];
            newidx++;
        }
        return ResultState(Token::Symbol(sym), newidx);
    }
};

Parser::~Parser() {
    if (tokenizer) delete tokenizer;
}

// Return the entire contents of the file at the given path.
std::string Parser::read_file(const std::string &path) {
    std::ifstream t(path);
    if (!t.is_open()) {
        std::string msg = "Failed to open file at " + path;
        abort(msg);
    }
    std::stringstream buffer;
    buffer << t.rdbuf();
    return buffer.str();
}

// Parse the given file into a Bish AST.
AST *Parser::parse(const std::string &path) {
    std::string contents = read_file(path);
    return parse_string(contents);
}

// Parse the given string into a Bish AST.
AST *Parser::parse_string(const std::string &text) {
    if (tokenizer) delete tokenizer;

    // Insert a dummy block for root scope.
    std::string preprocessed = "{" + text + "}";
    tokenizer = new Tokenizer(preprocessed);

    AST *ast = new AST(block());
    expect(tokenizer->peek(), Token::EOSType, "Expected end of string.");
    // Type checking
    TypeChecker types;
    ast->accept(&types);
    return ast;
}

// Assert that the given token is of the given type. If true, advance
// the tokenizer. If false, produce an error message.
void Parser::expect(const Token &t, Token::Type ty, const std::string &msg) {
    if (!t.isa(ty)) {
        std::stringstream errstr;
        errstr << "Parsing error: " << msg << " near " << tokenizer->position();
        abort(errstr.str());
    }
    tokenizer->next();
}

// Terminate the parsing process with the given error message.
void Parser::abort(const std::string &msg) {
    std::cerr << msg << "\n";
    exit(1);
}

// Return true if the given token is a unary operator.
bool Parser::is_unop_token(const Token &t) {
    return t.isa(Token::MinusType);
}

// Return true if the given token is a binary operator.
bool Parser::is_binop_token(const Token &t) {
    return t.isa(Token::PlusType) || t.isa(Token::MinusType) ||
        t.isa(Token::StarType) || t.isa(Token::SlashType);
}

// Return the binary Operator corresponding to the given token.
BinOp::Operator Parser::get_binop_operator(const Token &t) {
    switch (t.type()) {
    case Token::PlusType:
        return BinOp::Add;
    case Token::MinusType:
        return BinOp::Sub;
    case Token::StarType:
        return BinOp::Mul;
    case Token::SlashType:
        return BinOp::Div;
    default:
        abort("Invalid operator for binary operation.");
        return BinOp::Add;
    }
}

// Return the unary Operator corresponding to the given token.
UnaryOp::Operator Parser::get_unaryop_operator(const Token &t) {
    switch (t.type()) {
    case Token::MinusType:
        return UnaryOp::Negate;
    default:
        abort("Invalid operator for unary operation.");
        return UnaryOp::Negate;
    }
}

// Return the Bish Type to represent the given AST node.
Type Parser::get_primitive_type(const ASTNode *n) {
    if (const Integer *v = dynamic_cast<const Integer*>(n)) {
        return IntegerTy;
    } else if (const Fractional *v = dynamic_cast<const Fractional*>(n)) {
        return FractionalTy;
    } else if (const String *v = dynamic_cast<const String*>(n)) {
        return StringTy;
    } else if (const Boolean *v = dynamic_cast<const Boolean*>(n)) {
        return BooleanTy;
    } else {
        return UndefinedTy;
    }
}

// Parse a Bish block.
Block *Parser::block() {
    SymbolTable *old = current_symbol_table;
    current_symbol_table = new SymbolTable();
    std::vector<ASTNode *> statements;
    Token t = tokenizer->peek();
    expect(t, Token::LBraceType, "Expected block to begin with '{'");
    bool end = false;
    while (!end) {
        t = tokenizer->peek();
        switch (t.type()) {
        case Token::LBraceType:
            statements.push_back(block());
            break;
        case Token::RBraceType:
            end = true;
            break;
        default:
            statements.push_back(stmt());
            break;
        }
    }
    expect(tokenizer->peek(), Token::RBraceType, "Expected block to end with '}'");
    Block *result = new Block(statements, current_symbol_table);
    current_symbol_table = old;
    return result;
}

// Parse a Bish statement.
ASTNode *Parser::stmt() {
    Variable *v = var();
    expect(tokenizer->peek(), Token::EqualsType, "Expected assignment operator");
    ASTNode *e = expr();
    expect(tokenizer->peek(), Token::SemicolonType, "Expected statement to end with ';'");
    Type t = get_primitive_type(e);
    if (t != UndefinedTy) {
        current_symbol_table->insert(v->name, t);
    }
    return new Assignment(v, e);
}

// Parse a Bish variable.
Variable *Parser::var() {
    std::string name = tokenizer->peek().value();
    expect(tokenizer->peek(), Token::SymbolType, "Expected variable to be a symbol");
    return new Variable(name);
}

// Parse a Bish expression.
ASTNode *Parser::expr() {
    Token t = tokenizer->peek();
    if (t.isa(Token::LParenType)) {
        tokenizer->next();
        ASTNode *e = expr();
        expect(tokenizer->peek(), Token::RParenType, "Unmatched '('");
        return e;
    } else if (is_unop_token(t)) {
        return unop();
    } else {
        ASTNode *a = atom();
        if (is_binop_token(tokenizer->peek())) {
            return binop(a);
        }
        return a;
    }
}

// Parse a Bish binary operator.
BinOp *Parser::binop(ASTNode *a) {
    BinOp *bin = NULL;
    while (is_binop_token(tokenizer->peek())) {
        BinOp::Operator op = get_binop_operator(tokenizer->peek());
        tokenizer->next();
        ASTNode *b = atom();
        bin = new BinOp(op, a, b);
        a = bin;
    }
    return bin;
}

// Parse a Bish unary operator.
UnaryOp *Parser::unop() {
    UnaryOp::Operator op = get_unaryop_operator(tokenizer->peek());
    tokenizer->next();
    ASTNode *a = atom();
    return new UnaryOp(op, a);
}

// Parse a Bish atom.
ASTNode *Parser::atom() {
    Token t = tokenizer->peek();
    tokenizer->next();

    switch(t.type()) {
    case Token::SymbolType:
        return new Variable(t.value());
    case Token::IntType:
        return new Integer(t.value());
    case Token::FractionalType:
        return new Fractional(t.value());
    case Token::QuoteType: {
        std::string str = tokenizer->scan_until(Token::QuoteType);
        expect(tokenizer->peek(), Token::QuoteType, "Unmatched '\"'");
        return new String(str);
    }
    default:
        abort("Invalid token type for atom.");
        return NULL;
    }
}

}
<|endoftext|>


<commit_before>/*********************************************************************************
 *
 * Inviwo - Interactive Visualization Workshop
 *
 * Copyright (c) 2018-2020 Inviwo Foundation
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *********************************************************************************/

#include <modules/webbrowser/processors/processorcefsynchronizer.h>
#include <modules/webbrowser/webbrowsermodule.h>

#include <inviwo/core/util/stringconversion.h>
#include <inviwo/core/processors/progressbarowner.h>
#include <inviwo/core/util/stringconversion.h>

#include <warn/push>
#include <warn/ignore/all>
#include "include/cef_parser.h"
#include <warn/pop>

namespace inviwo {

ProcessorCefSynchronizer::ProcessorCefSynchronizer(const Processor* webBrowserSource)
    : parent_(webBrowserSource) {}

void ProcessorCefSynchronizer::OnLoadEnd(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame,
                                         int /*httpStatusCode*/) {
    // synchronize all properties
    // Ok to send javascript commands when frame loaded
    for (auto& observer : progressObservers_) {
        observer.second.setFrame(frame);
    }
}

bool ProcessorCefSynchronizer::OnQuery(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame,
                                       int64, const CefString& request, bool,
                                       CefRefPtr<Callback> callback) {

    const std::string& requestStr = request;
    // Assume format "id":"htmlId"
    auto j = json::parse(requestStr);

    try {
        auto command = j.at("command").get<std::string>();
        constexpr std::string_view subscribeProgressCommand = "processor.progress.subscribe";
        constexpr std::string_view unsubscribeProgressCommand = "processor.progress.unsubscribe";
        constexpr std::string_view parentProcessorCommand = "parentwebbrowserprocessor";

        if (command == subscribeProgressCommand) {
            auto p = j.at("path").get<std::string>();
            auto network = parent_->getNetwork();

            if (auto processor = network->getProcessorByIdentifier(p)) {
                if (auto progressOwner = dynamic_cast<ProgressBarOwner*>(processor)) {
                    auto onProgressChange = j.at("onProgressChange").get<std::string>();
                    auto onVisibleChange = j.at("onVisibleChange").get<std::string>();

                    progressObservers_[processor] =
                        ProgressBarObserverCEF(frame, onProgressChange, onVisibleChange);
                    progressOwner->getProgressBar().ProgressBarObservable::addObserver(
                        &progressObservers_[processor]);
                    callback->Success("");
                    return true;
                } else {
                    callback->Failure(0, "Processor " + p + " is not ProgressBarObservable");
                }
            } else {
                callback->Failure(0, "Could not find processor: " + p);
            }
        } else if (command == unsubscribeProgressCommand) {
            auto p = j.at("path").get<std::string>();
            auto network = parent_->getNetwork();
            if (auto processor = network->getProcessorByIdentifier(p)) {
                // Remove observer
                progressObservers_.erase(processor);
                callback->Success("");
                return true;
            } else {
                callback->Failure(0, "Could not find processor: " + p);
            }
        } else if (command == parentProcessorCommand) {
            callback->Success(json{{"path", joinString(parent_->getPath(), ".")}}.dump());
            return true;
        }
    } catch (json::exception& ex) {
        LogError(ex.what());
        callback->Failure(0, ex.what());
    } catch (inviwo::Exception& ex) {
        util::log(ex.getContext(), ex.getMessage(), LogLevel::Error);
        callback->Failure(0, ex.what());
    } catch (std::exception& ex) {
        LogError(ex.what());
        callback->Failure(0, ex.what());
    }

    return false;
}

void ProcessorCefSynchronizer::onProcessorNetworkWillRemoveProcessor(Processor* p) {
    progressObservers_.erase(p);
}

}  // namespace inviwo
<commit_msg>Jenkins: Format fixes<commit_after>/*********************************************************************************
 *
 * Inviwo - Interactive Visualization Workshop
 *
 * Copyright (c) 2018-2020 Inviwo Foundation
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *********************************************************************************/

#include <modules/webbrowser/processors/processorcefsynchronizer.h>
#include <modules/webbrowser/webbrowsermodule.h>

#include <inviwo/core/util/stringconversion.h>
#include <inviwo/core/processors/progressbarowner.h>
#include <inviwo/core/util/stringconversion.h>

#include <warn/push>
#include <warn/ignore/all>
#include "include/cef_parser.h"
#include <warn/pop>

namespace inviwo {

ProcessorCefSynchronizer::ProcessorCefSynchronizer(const Processor* webBrowserSource)
    : parent_(webBrowserSource) {}

void ProcessorCefSynchronizer::OnLoadEnd(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame,
                                         int /*httpStatusCode*/) {
    // synchronize all properties
    // Ok to send javascript commands when frame loaded
    for (auto& observer : progressObservers_) {
        observer.second.setFrame(frame);
    }
}

bool ProcessorCefSynchronizer::OnQuery(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame,
                                       int64, const CefString& request, bool,
                                       CefRefPtr<Callback> callback) {

    const std::string& requestStr = request;
    // Assume format "id":"htmlId"
    auto j = json::parse(requestStr);

    try {
        auto command = j.at("command").get<std::string>();
        constexpr std::string_view subscribeProgressCommand = "processor.progress.subscribe";
        constexpr std::string_view unsubscribeProgressCommand = "processor.progress.unsubscribe";
        constexpr std::string_view parentProcessorCommand = "parentwebbrowserprocessor";

        if (command == subscribeProgressCommand) {
            auto p = j.at("path").get<std::string>();
            auto network = parent_->getNetwork();

            if (auto processor = network->getProcessorByIdentifier(p)) {
                if (auto progressOwner = dynamic_cast<ProgressBarOwner*>(processor)) {
                    auto onProgressChange = j.at("onProgressChange").get<std::string>();
                    auto onVisibleChange = j.at("onVisibleChange").get<std::string>();

                    progressObservers_[processor] =
                        ProgressBarObserverCEF(frame, onProgressChange, onVisibleChange);
                    progressOwner->getProgressBar().ProgressBarObservable::addObserver(
                        &progressObservers_[processor]);
                    callback->Success("");
                    return true;
                } else {
                    callback->Failure(0, "Processor " + p + " is not ProgressBarObservable");
                }
            } else {
                callback->Failure(0, "Could not find processor: " + p);
            }
        } else if (command == unsubscribeProgressCommand) {
            auto p = j.at("path").get<std::string>();
            auto network = parent_->getNetwork();
            if (auto processor = network->getProcessorByIdentifier(p)) {
                // Remove observer
                progressObservers_.erase(processor);
                callback->Success("");
                return true;
            } else {
                callback->Failure(0, "Could not find processor: " + p);
            }
        } else if (command == parentProcessorCommand) {
            callback->Success(json{{"path", joinString(parent_->getPath(), ".")}}.dump());
            return true;
        }
    } catch (json::exception& ex) {
        LogError(ex.what());
        callback->Failure(0, ex.what());
    } catch (inviwo::Exception& ex) {
        util::log(ex.getContext(), ex.getMessage(), LogLevel::Error);
        callback->Failure(0, ex.what());
    } catch (std::exception& ex) {
        LogError(ex.what());
        callback->Failure(0, ex.what());
    }

    return false;
}

void ProcessorCefSynchronizer::onProcessorNetworkWillRemoveProcessor(Processor* p) {
    progressObservers_.erase(p);
}

}  // namespace inviwo
<|endoftext|>


<commit_before>/*
 Copyright (c) 2015, The Cinder Project, All rights reserved.

 This code is intended for use with the Cinder C++ library: http://libcinder.org

 Redistribution and use in source and binary forms, with or without modification, are permitted provided that
 the following conditions are met:

 * Redistributions of source code must retain the above copyright notice, this list of conditions and
	the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
	the following disclaimer in the documentation and/or other materials provided with the distribution.

 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
 TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 POSSIBILITY OF SUCH DAMAGE.
 */

#include "cinder/gl/scoped.h"
#include "cinder/gl/Context.h"
#include "cinder/gl/BufferObj.h"
#include "cinder/gl/Fbo.h"
#include "cinder/CinderAssert.h"

using namespace std;

namespace cinder { namespace gl {

///////////////////////////////////////////////////////////////////////////////////////////
// ScopedVao
ScopedVao::ScopedVao( Vao *vao )
	: mCtx( gl::context() )
{
	mCtx->pushVao( vao );
}

ScopedVao::ScopedVao( VaoRef &vao )
	: mCtx( gl::context() )
{
	mCtx->pushVao( vao );
}

ScopedVao::~ScopedVao()
{
	mCtx->popVao();
}

///////////////////////////////////////////////////////////////////////////////////////////
// ScopedBuffer
ScopedBuffer::ScopedBuffer( const BufferObjRef &bufferObj )
	: mCtx( gl::context() ), mTarget( bufferObj->getTarget() )
{
	mCtx->pushBufferBinding( mTarget, bufferObj->getId() );
}

ScopedBuffer::ScopedBuffer( GLenum target, GLuint id )
		: mCtx( gl::context() ), mTarget( target )
{
	mCtx->pushBufferBinding( target, id );
}

ScopedBuffer::~ScopedBuffer()
{
	mCtx->popBufferBinding( mTarget );
}

///////////////////////////////////////////////////////////////////////////////////////////
// ScopedState
ScopedState::ScopedState( GLenum cap, GLboolean value )
	: mCtx( gl::context() ), mCap( cap )
{
	mCtx->pushBoolState( cap, value );
}

ScopedState::~ScopedState() {
	mCtx->popBoolState( mCap );
}

///////////////////////////////////////////////////////////////////////////////////////////
// ScopedColor
ScopedColor::ScopedColor()
	: mCtx( gl::context() )
{
	mColor = mCtx->getCurrentColor();
}

ScopedColor::ScopedColor( const ColorAf &color )
	: mCtx( gl::context() )
{
	mColor = mCtx->getCurrentColor();
	mCtx->setCurrentColor( color );
}

ScopedColor::ScopedColor( float red, float green, float blue, float alpha )
	: mCtx( gl::context() )
{
	mColor = mCtx->getCurrentColor();
	mCtx->setCurrentColor( ColorA( red, green, blue, alpha ) );
}

ScopedColor::~ScopedColor()
{
	mCtx->setCurrentColor( mColor );
}

///////////////////////////////////////////////////////////////////////////////////////////
// ScopedBlend
ScopedBlend::ScopedBlend( GLboolean enable )
	: mCtx( gl::context() ), mSaveFactors( false )
{
	mCtx->pushBoolState( GL_BLEND, enable );
}

//! Parallels glBlendFunc(), implicitly enables blending
ScopedBlend::ScopedBlend( GLenum sfactor, GLenum dfactor )
	: mCtx( gl::context() ), mSaveFactors( true )
{
	mCtx->pushBoolState( GL_BLEND, GL_TRUE );
	mCtx->pushBlendFuncSeparate( sfactor, dfactor, sfactor, dfactor );
}

//! Parallels glBlendFuncSeparate(), implicitly enables blending
ScopedBlend::ScopedBlend( GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha )
	: mCtx( gl::context() ), mSaveFactors( true )
{
	mCtx->pushBoolState( GL_BLEND, GL_TRUE );
	mCtx->pushBlendFuncSeparate( srcRGB, dstRGB, srcAlpha, dstAlpha );
}

ScopedBlend::~ScopedBlend()
{
	mCtx->popBoolState( GL_BLEND );
	if( mSaveFactors )
		mCtx->popBlendFuncSeparate();
}

///////////////////////////////////////////////////////////////////////////////////////////
// ScopedGlslProg
ScopedGlslProg::ScopedGlslProg( GlslProgRef& prog )
	: mCtx( gl::context() )
{
	mCtx->pushGlslProg( prog.get() );
}

ScopedGlslProg::ScopedGlslProg( const std::shared_ptr<const GlslProg> &prog )
	: mCtx( gl::context() )
{
	mCtx->pushGlslProg( std::const_pointer_cast<GlslProg>( prog ).get() );
}

ScopedGlslProg::ScopedGlslProg( const GlslProg* prog )
	: mCtx( gl::context() )
{
	mCtx->pushGlslProg( const_cast<GlslProg*>( prog ) );
}

ScopedGlslProg::~ScopedGlslProg()
{
	mCtx->popGlslProg();
}

///////////////////////////////////////////////////////////////////////////////////////////
// ScopedFramebuffer
ScopedFramebuffer::ScopedFramebuffer( const FboRef &fbo, GLenum target )
	: mCtx( gl::context() ), mTarget( target )
{
	mCtx->pushFramebuffer( fbo, target );
}

ScopedFramebuffer::ScopedFramebuffer( GLenum target, GLuint framebufferId )
	: mCtx( gl::context() ), mTarget( target )
{
	mCtx->pushFramebuffer( target, framebufferId );
}

ScopedFramebuffer::~ScopedFramebuffer()
{
#if ! defined( CINDER_GL_HAS_FBO_MULTISAMPLING )
	mCtx->popFramebuffer( GL_FRAMEBUFFER );
#else
	if( mTarget == GL_FRAMEBUFFER || mTarget == GL_READ_FRAMEBUFFER )
		mCtx->popFramebuffer( GL_READ_FRAMEBUFFER );
	if( mTarget == GL_FRAMEBUFFER || mTarget == GL_DRAW_FRAMEBUFFER )
		mCtx->popFramebuffer( GL_DRAW_FRAMEBUFFER );
#endif
}

///////////////////////////////////////////////////////////////////////////////////////////
// ScopedActiveTexture
ScopedActiveTexture::ScopedActiveTexture( uint8_t textureUnit )
	: mCtx( gl::context() )
{
	mCtx->pushActiveTexture( textureUnit );
}

ScopedActiveTexture::~ScopedActiveTexture()
{
	mCtx->popActiveTexture();
}

///////////////////////////////////////////////////////////////////////////////////////////
// ScopedTextureBind
ScopedTextureBind::ScopedTextureBind( GLenum target, GLuint textureId )
	: mCtx( gl::context() ), mTarget( target )
{
	mTextureUnit = mCtx->getActiveTexture();
	mCtx->pushTextureBinding( mTarget, textureId, mTextureUnit );
}

ScopedTextureBind::ScopedTextureBind( GLenum target, GLuint textureId, uint8_t textureUnit )
	: mCtx( gl::context() ), mTarget( target ), mTextureUnit( textureUnit )
{
	mCtx->pushTextureBinding( mTarget, textureId, mTextureUnit );
}

ScopedTextureBind::ScopedTextureBind( const TextureBaseRef &texture )
	: mCtx( gl::context() ), mTarget( texture->getTarget() )
{
	mTextureUnit = mCtx->getActiveTexture();
	mCtx->pushTextureBinding( mTarget, texture->getId(), mTextureUnit );
}

ScopedTextureBind::ScopedTextureBind( const TextureBaseRef &texture, uint8_t textureUnit )
	: mCtx( gl::context() ), mTarget( texture->getTarget() ), mTextureUnit( textureUnit )
{
	mCtx->pushTextureBinding( mTarget, texture->getId(), mTextureUnit );
}

// ----------------------------------------------------------------
// These overloads are to alleviate a VS2013 bug where it cannot deduce
// the correct constructor when a TextureBaseRef subclass is passed in
ScopedTextureBind::ScopedTextureBind( const Texture2dRef &texture, uint8_t textureUnit )
	: mCtx( gl::context() ), mTarget( texture->getTarget() ), mTextureUnit( textureUnit )
{
	mCtx->pushTextureBinding( mTarget, texture->getId(), mTextureUnit );
}

#if ! defined( CINDER_GL_ES_2 )

ScopedTextureBind::ScopedTextureBind( const Texture1dRef & texture, uint8_t textureUnit )
	: mCtx( gl::context() ), mTarget( texture->getTarget() ), mTextureUnit( textureUnit )
{
	mCtx->pushTextureBinding( mTarget, texture->getId(), mTextureUnit );
}

ScopedTextureBind::ScopedTextureBind( const Texture3dRef &texture, uint8_t textureUnit )
	: mCtx( gl::context() ), mTarget( texture->getTarget() ), mTextureUnit( textureUnit )
{
	mCtx->pushTextureBinding( mTarget, texture->getId(), mTextureUnit );
}
#endif // ! defined( CINDER_GL_ES_2 )

ScopedTextureBind::ScopedTextureBind( const TextureCubeMapRef &texture, uint8_t textureUnit )
	: mCtx( gl::context() ), mTarget( texture->getTarget() ), mTextureUnit( textureUnit )
{
	mCtx->pushTextureBinding( mTarget, texture->getId(), mTextureUnit );
}
// ----------------------------------------------------------------

ScopedTextureBind::~ScopedTextureBind()
{
	mCtx->popTextureBinding( mTarget, mTextureUnit );
}

///////////////////////////////////////////////////////////////////////////////////////////
// ScopedScissor
ScopedScissor::ScopedScissor( const ivec2 &lowerLeftPosition, const ivec2 &dimension )
	: mCtx( gl::context() )
{
	mCtx->pushBoolState( GL_SCISSOR_TEST, GL_TRUE );
	mCtx->pushScissor( std::pair<ivec2, ivec2>( lowerLeftPosition, dimension ) );
}

ScopedScissor::ScopedScissor( int lowerLeftX, int lowerLeftY, int width, int height )
	: mCtx( gl::context() )
{
	mCtx->pushBoolState( GL_SCISSOR_TEST, GL_TRUE );
	mCtx->pushScissor( std::pair<ivec2, ivec2>( ivec2( lowerLeftX, lowerLeftY ), ivec2( width, height ) ) );
}

ScopedScissor::~ScopedScissor()
{
	mCtx->popBoolState( GL_SCISSOR_TEST );
	mCtx->popScissor();
}

///////////////////////////////////////////////////////////////////////////////////////////
// ScopedFaceCulling
ScopedFaceCulling::ScopedFaceCulling( bool cull )
	: mCtx( gl::context() ), mSaveFace( false )
{
	mCtx->pushBoolState( GL_CULL_FACE, cull );
}

ScopedFaceCulling::ScopedFaceCulling( bool cull, GLenum face )
	: mCtx( gl::context() ), mSaveFace( true )
{
	mCtx->pushBoolState( GL_CULL_FACE, cull );
	mCtx->pushCullFace( face );
}

ScopedFaceCulling::~ScopedFaceCulling()
{
	mCtx->popBoolState( GL_CULL_FACE );
	if( mSaveFace )
		mCtx->popCullFace();
}

#if ! defined( CINDER_GL_ES )

///////////////////////////////////////////////////////////////////////////////////////////
// ScopedLogicOp
ScopedLogicOp::ScopedLogicOp( bool enable )
: mCtx( gl::context() ), mSaveMode( false )
{
	mCtx->pushBoolState( GL_COLOR_LOGIC_OP, enable );
}

ScopedLogicOp::ScopedLogicOp( bool enable, GLenum mode )
: mCtx( gl::context() ), mSaveMode( true )
{
	mCtx->pushBoolState( GL_COLOR_LOGIC_OP, enable );
	mCtx->pushLogicOp( mode );
}

ScopedLogicOp::~ScopedLogicOp()
{
	mCtx->popBoolState( GL_COLOR_LOGIC_OP );
	if( mSaveMode )
		mCtx->popLogicOp();
}

#endif

///////////////////////////////////////////////////////////////////////////////////////////
// ScopedDepth
ScopedDepth::ScopedDepth( bool enableReadAndWrite )
	: mCtx( gl::context() ), mSaveMask( true ), mSaveFunc( false )
{
	mCtx->pushBoolState( GL_DEPTH_TEST, enableReadAndWrite );
	mCtx->pushDepthMask( enableReadAndWrite );
}

ScopedDepth::ScopedDepth( bool enableRead, bool enableWrite )
	: mCtx( gl::context() ), mSaveMask( true ), mSaveFunc( false )
{
	mCtx->pushBoolState( GL_DEPTH_TEST, enableRead );
	mCtx->pushDepthMask( enableWrite );
}

ScopedDepth::ScopedDepth( bool enableRead, bool enableWrite, GLenum depthFunc )
	: mCtx( gl::context() ), mSaveMask( true ), mSaveFunc( true )
{
	mCtx->pushBoolState( GL_DEPTH_TEST, enableRead );
	mCtx->pushDepthMask( enableWrite );
	mCtx->pushDepthFunc( depthFunc );
}

ScopedDepth::~ScopedDepth()
{
	mCtx->popBoolState( GL_DEPTH_TEST );
	if( mSaveMask )
		mCtx->popDepthMask();
	if( mSaveFunc )
		mCtx->popDepthFunc();
}

///////////////////////////////////////////////////////////////////////////////////////////
// ScopedRenderbuffer
ScopedRenderbuffer::ScopedRenderbuffer( const RenderbufferRef &renderBuffer )
	: mCtx( gl::context() )
{
	mCtx->pushRenderbufferBinding( GL_RENDERBUFFER, renderBuffer->getId() );
}

ScopedRenderbuffer::ScopedRenderbuffer( GLenum target, GLuint id )
	: mCtx( gl::context() )
{
	// this is the only legal value currently
	CI_ASSERT( target == GL_RENDERBUFFER );
	mCtx->pushRenderbufferBinding( target, id );
}

ScopedRenderbuffer::~ScopedRenderbuffer()
{
	mCtx->popRenderbufferBinding( GL_RENDERBUFFER );
}

///////////////////////////////////////////////////////////////////////////////////////////
// ScopedViewport
ScopedViewport::ScopedViewport( const ivec2 &lowerLeftPosition, const ivec2 &dimension )
	: mCtx( gl::context() )
{
	mCtx->pushViewport( { lowerLeftPosition, dimension } );
}

ScopedViewport::ScopedViewport( const ivec2 &size )
	: mCtx( gl::context() )
{
	mCtx->pushViewport( { ivec2( 0 ), size } );
}

ScopedViewport::ScopedViewport( int lowerLeftX, int lowerLeftY, int width, int height )
	: mCtx( gl::context() )
{
	mCtx->pushViewport( { ivec2( lowerLeftX, lowerLeftY ), ivec2( width, height ) } );
}

ScopedViewport::~ScopedViewport()
{
	mCtx->popViewport();
}

///////////////////////////////////////////////////////////////////////////////////////////
// ScopedLineWidth
ScopedLineWidth::ScopedLineWidth( float width )
	: mCtx( gl::context() )
{
	mCtx->pushLineWidth( width );
}

ScopedLineWidth::~ScopedLineWidth()
{
	mCtx->popLineWidth();
}

#if ! defined( CINDER_GL_ES )

///////////////////////////////////////////////////////////////////////////////////////////
// ScopedPolygonMode
ScopedPolygonMode::ScopedPolygonMode( GLenum mode )
	: mCtx( gl::context() )
{
	mCtx->pushPolygonMode( GL_FRONT_AND_BACK, mode );
}

ScopedPolygonMode::~ScopedPolygonMode()
{
	mCtx->popPolygonMode( GL_FRONT_AND_BACK );
}

#endif

///////////////////////////////////////////////////////////////////////////////////////////
// ScopedFrontFace
ScopedFrontFace::ScopedFrontFace( GLenum mode )
	: mCtx( gl::context() )
{
	mCtx->pushFrontFace( mode );
}

ScopedFrontFace::~ScopedFrontFace()
{
	mCtx->popFrontFace();
}

} } // namespace cinder::gl
<commit_msg>Minor formatting update against #1096<commit_after>/*
 Copyright (c) 2015, The Cinder Project, All rights reserved.

 This code is intended for use with the Cinder C++ library: http://libcinder.org

 Redistribution and use in source and binary forms, with or without modification, are permitted provided that
 the following conditions are met:

 * Redistributions of source code must retain the above copyright notice, this list of conditions and
	the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
	the following disclaimer in the documentation and/or other materials provided with the distribution.

 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
 TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 POSSIBILITY OF SUCH DAMAGE.
 */

#include "cinder/gl/scoped.h"
#include "cinder/gl/Context.h"
#include "cinder/gl/BufferObj.h"
#include "cinder/gl/Fbo.h"
#include "cinder/CinderAssert.h"

using namespace std;

namespace cinder { namespace gl {

///////////////////////////////////////////////////////////////////////////////////////////
// ScopedVao
ScopedVao::ScopedVao( Vao *vao )
	: mCtx( gl::context() )
{
	mCtx->pushVao( vao );
}

ScopedVao::ScopedVao( VaoRef &vao )
	: mCtx( gl::context() )
{
	mCtx->pushVao( vao );
}

ScopedVao::~ScopedVao()
{
	mCtx->popVao();
}

///////////////////////////////////////////////////////////////////////////////////////////
// ScopedBuffer
ScopedBuffer::ScopedBuffer( const BufferObjRef &bufferObj )
	: mCtx( gl::context() ), mTarget( bufferObj->getTarget() )
{
	mCtx->pushBufferBinding( mTarget, bufferObj->getId() );
}

ScopedBuffer::ScopedBuffer( GLenum target, GLuint id )
		: mCtx( gl::context() ), mTarget( target )
{
	mCtx->pushBufferBinding( target, id );
}

ScopedBuffer::~ScopedBuffer()
{
	mCtx->popBufferBinding( mTarget );
}

///////////////////////////////////////////////////////////////////////////////////////////
// ScopedState
ScopedState::ScopedState( GLenum cap, GLboolean value )
	: mCtx( gl::context() ), mCap( cap )
{
	mCtx->pushBoolState( cap, value );
}

ScopedState::~ScopedState() {
	mCtx->popBoolState( mCap );
}

///////////////////////////////////////////////////////////////////////////////////////////
// ScopedColor
ScopedColor::ScopedColor()
	: mCtx( gl::context() )
{
	mColor = mCtx->getCurrentColor();
}

ScopedColor::ScopedColor( const ColorAf &color )
	: mCtx( gl::context() )
{
	mColor = mCtx->getCurrentColor();
	mCtx->setCurrentColor( color );
}

ScopedColor::ScopedColor( float red, float green, float blue, float alpha )
	: mCtx( gl::context() )
{
	mColor = mCtx->getCurrentColor();
	mCtx->setCurrentColor( ColorA( red, green, blue, alpha ) );
}

ScopedColor::~ScopedColor()
{
	mCtx->setCurrentColor( mColor );
}

///////////////////////////////////////////////////////////////////////////////////////////
// ScopedBlend
ScopedBlend::ScopedBlend( GLboolean enable )
	: mCtx( gl::context() ), mSaveFactors( false )
{
	mCtx->pushBoolState( GL_BLEND, enable );
}

//! Parallels glBlendFunc(), implicitly enables blending
ScopedBlend::ScopedBlend( GLenum sfactor, GLenum dfactor )
	: mCtx( gl::context() ), mSaveFactors( true )
{
	mCtx->pushBoolState( GL_BLEND, GL_TRUE );
	mCtx->pushBlendFuncSeparate( sfactor, dfactor, sfactor, dfactor );
}

//! Parallels glBlendFuncSeparate(), implicitly enables blending
ScopedBlend::ScopedBlend( GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha )
	: mCtx( gl::context() ), mSaveFactors( true )
{
	mCtx->pushBoolState( GL_BLEND, GL_TRUE );
	mCtx->pushBlendFuncSeparate( srcRGB, dstRGB, srcAlpha, dstAlpha );
}

ScopedBlend::~ScopedBlend()
{
	mCtx->popBoolState( GL_BLEND );
	if( mSaveFactors )
		mCtx->popBlendFuncSeparate();
}

///////////////////////////////////////////////////////////////////////////////////////////
// ScopedGlslProg
ScopedGlslProg::ScopedGlslProg( GlslProgRef& prog )
	: mCtx( gl::context() )
{
	mCtx->pushGlslProg( prog.get() );
}

ScopedGlslProg::ScopedGlslProg( const std::shared_ptr<const GlslProg> &prog )
	: mCtx( gl::context() )
{
	mCtx->pushGlslProg( std::const_pointer_cast<GlslProg>( prog ).get() );
}

ScopedGlslProg::ScopedGlslProg( const GlslProg* prog )
	: mCtx( gl::context() )
{
	mCtx->pushGlslProg( const_cast<GlslProg*>( prog ) );
}

ScopedGlslProg::~ScopedGlslProg()
{
	mCtx->popGlslProg();
}

///////////////////////////////////////////////////////////////////////////////////////////
// ScopedFramebuffer
ScopedFramebuffer::ScopedFramebuffer( const FboRef &fbo, GLenum target )
	: mCtx( gl::context() ), mTarget( target )
{
	mCtx->pushFramebuffer( fbo, target );
}

ScopedFramebuffer::ScopedFramebuffer( GLenum target, GLuint framebufferId )
	: mCtx( gl::context() ), mTarget( target )
{
	mCtx->pushFramebuffer( target, framebufferId );
}

ScopedFramebuffer::~ScopedFramebuffer()
{
#if ! defined( CINDER_GL_HAS_FBO_MULTISAMPLING )
	mCtx->popFramebuffer( GL_FRAMEBUFFER );
#else
	if( mTarget == GL_FRAMEBUFFER || mTarget == GL_READ_FRAMEBUFFER )
		mCtx->popFramebuffer( GL_READ_FRAMEBUFFER );
	if( mTarget == GL_FRAMEBUFFER || mTarget == GL_DRAW_FRAMEBUFFER )
		mCtx->popFramebuffer( GL_DRAW_FRAMEBUFFER );
#endif
}

///////////////////////////////////////////////////////////////////////////////////////////
// ScopedActiveTexture
ScopedActiveTexture::ScopedActiveTexture( uint8_t textureUnit )
	: mCtx( gl::context() )
{
	mCtx->pushActiveTexture( textureUnit );
}

ScopedActiveTexture::~ScopedActiveTexture()
{
	mCtx->popActiveTexture();
}

///////////////////////////////////////////////////////////////////////////////////////////
// ScopedTextureBind
ScopedTextureBind::ScopedTextureBind( GLenum target, GLuint textureId )
	: mCtx( gl::context() ), mTarget( target )
{
	mTextureUnit = mCtx->getActiveTexture();
	mCtx->pushTextureBinding( mTarget, textureId, mTextureUnit );
}

ScopedTextureBind::ScopedTextureBind( GLenum target, GLuint textureId, uint8_t textureUnit )
	: mCtx( gl::context() ), mTarget( target ), mTextureUnit( textureUnit )
{
	mCtx->pushTextureBinding( mTarget, textureId, mTextureUnit );
}

ScopedTextureBind::ScopedTextureBind( const TextureBaseRef &texture )
	: mCtx( gl::context() ), mTarget( texture->getTarget() )
{
	mTextureUnit = mCtx->getActiveTexture();
	mCtx->pushTextureBinding( mTarget, texture->getId(), mTextureUnit );
}

ScopedTextureBind::ScopedTextureBind( const TextureBaseRef &texture, uint8_t textureUnit )
	: mCtx( gl::context() ), mTarget( texture->getTarget() ), mTextureUnit( textureUnit )
{
	mCtx->pushTextureBinding( mTarget, texture->getId(), mTextureUnit );
}

// ----------------------------------------------------------------
// These overloads are to alleviate a VS2013 bug where it cannot deduce
// the correct constructor when a TextureBaseRef subclass is passed in
ScopedTextureBind::ScopedTextureBind( const Texture2dRef &texture, uint8_t textureUnit )
	: mCtx( gl::context() ), mTarget( texture->getTarget() ), mTextureUnit( textureUnit )
{
	mCtx->pushTextureBinding( mTarget, texture->getId(), mTextureUnit );
}

#if ! defined( CINDER_GL_ES_2 )

ScopedTextureBind::ScopedTextureBind( const Texture1dRef &texture, uint8_t textureUnit )
	: mCtx( gl::context() ), mTarget( texture->getTarget() ), mTextureUnit( textureUnit )
{
	mCtx->pushTextureBinding( mTarget, texture->getId(), mTextureUnit );
}

ScopedTextureBind::ScopedTextureBind( const Texture3dRef &texture, uint8_t textureUnit )
	: mCtx( gl::context() ), mTarget( texture->getTarget() ), mTextureUnit( textureUnit )
{
	mCtx->pushTextureBinding( mTarget, texture->getId(), mTextureUnit );
}
#endif // ! defined( CINDER_GL_ES_2 )

ScopedTextureBind::ScopedTextureBind( const TextureCubeMapRef &texture, uint8_t textureUnit )
	: mCtx( gl::context() ), mTarget( texture->getTarget() ), mTextureUnit( textureUnit )
{
	mCtx->pushTextureBinding( mTarget, texture->getId(), mTextureUnit );
}
// ----------------------------------------------------------------

ScopedTextureBind::~ScopedTextureBind()
{
	mCtx->popTextureBinding( mTarget, mTextureUnit );
}

///////////////////////////////////////////////////////////////////////////////////////////
// ScopedScissor
ScopedScissor::ScopedScissor( const ivec2 &lowerLeftPosition, const ivec2 &dimension )
	: mCtx( gl::context() )
{
	mCtx->pushBoolState( GL_SCISSOR_TEST, GL_TRUE );
	mCtx->pushScissor( std::pair<ivec2, ivec2>( lowerLeftPosition, dimension ) );
}

ScopedScissor::ScopedScissor( int lowerLeftX, int lowerLeftY, int width, int height )
	: mCtx( gl::context() )
{
	mCtx->pushBoolState( GL_SCISSOR_TEST, GL_TRUE );
	mCtx->pushScissor( std::pair<ivec2, ivec2>( ivec2( lowerLeftX, lowerLeftY ), ivec2( width, height ) ) );
}

ScopedScissor::~ScopedScissor()
{
	mCtx->popBoolState( GL_SCISSOR_TEST );
	mCtx->popScissor();
}

///////////////////////////////////////////////////////////////////////////////////////////
// ScopedFaceCulling
ScopedFaceCulling::ScopedFaceCulling( bool cull )
	: mCtx( gl::context() ), mSaveFace( false )
{
	mCtx->pushBoolState( GL_CULL_FACE, cull );
}

ScopedFaceCulling::ScopedFaceCulling( bool cull, GLenum face )
	: mCtx( gl::context() ), mSaveFace( true )
{
	mCtx->pushBoolState( GL_CULL_FACE, cull );
	mCtx->pushCullFace( face );
}

ScopedFaceCulling::~ScopedFaceCulling()
{
	mCtx->popBoolState( GL_CULL_FACE );
	if( mSaveFace )
		mCtx->popCullFace();
}

#if ! defined( CINDER_GL_ES )

///////////////////////////////////////////////////////////////////////////////////////////
// ScopedLogicOp
ScopedLogicOp::ScopedLogicOp( bool enable )
: mCtx( gl::context() ), mSaveMode( false )
{
	mCtx->pushBoolState( GL_COLOR_LOGIC_OP, enable );
}

ScopedLogicOp::ScopedLogicOp( bool enable, GLenum mode )
: mCtx( gl::context() ), mSaveMode( true )
{
	mCtx->pushBoolState( GL_COLOR_LOGIC_OP, enable );
	mCtx->pushLogicOp( mode );
}

ScopedLogicOp::~ScopedLogicOp()
{
	mCtx->popBoolState( GL_COLOR_LOGIC_OP );
	if( mSaveMode )
		mCtx->popLogicOp();
}

#endif

///////////////////////////////////////////////////////////////////////////////////////////
// ScopedDepth
ScopedDepth::ScopedDepth( bool enableReadAndWrite )
	: mCtx( gl::context() ), mSaveMask( true ), mSaveFunc( false )
{
	mCtx->pushBoolState( GL_DEPTH_TEST, enableReadAndWrite );
	mCtx->pushDepthMask( enableReadAndWrite );
}

ScopedDepth::ScopedDepth( bool enableRead, bool enableWrite )
	: mCtx( gl::context() ), mSaveMask( true ), mSaveFunc( false )
{
	mCtx->pushBoolState( GL_DEPTH_TEST, enableRead );
	mCtx->pushDepthMask( enableWrite );
}

ScopedDepth::ScopedDepth( bool enableRead, bool enableWrite, GLenum depthFunc )
	: mCtx( gl::context() ), mSaveMask( true ), mSaveFunc( true )
{
	mCtx->pushBoolState( GL_DEPTH_TEST, enableRead );
	mCtx->pushDepthMask( enableWrite );
	mCtx->pushDepthFunc( depthFunc );
}

ScopedDepth::~ScopedDepth()
{
	mCtx->popBoolState( GL_DEPTH_TEST );
	if( mSaveMask )
		mCtx->popDepthMask();
	if( mSaveFunc )
		mCtx->popDepthFunc();
}

///////////////////////////////////////////////////////////////////////////////////////////
// ScopedRenderbuffer
ScopedRenderbuffer::ScopedRenderbuffer( const RenderbufferRef &renderBuffer )
	: mCtx( gl::context() )
{
	mCtx->pushRenderbufferBinding( GL_RENDERBUFFER, renderBuffer->getId() );
}

ScopedRenderbuffer::ScopedRenderbuffer( GLenum target, GLuint id )
	: mCtx( gl::context() )
{
	// this is the only legal value currently
	CI_ASSERT( target == GL_RENDERBUFFER );
	mCtx->pushRenderbufferBinding( target, id );
}

ScopedRenderbuffer::~ScopedRenderbuffer()
{
	mCtx->popRenderbufferBinding( GL_RENDERBUFFER );
}

///////////////////////////////////////////////////////////////////////////////////////////
// ScopedViewport
ScopedViewport::ScopedViewport( const ivec2 &lowerLeftPosition, const ivec2 &dimension )
	: mCtx( gl::context() )
{
	mCtx->pushViewport( { lowerLeftPosition, dimension } );
}

ScopedViewport::ScopedViewport( const ivec2 &size )
	: mCtx( gl::context() )
{
	mCtx->pushViewport( { ivec2( 0 ), size } );
}

ScopedViewport::ScopedViewport( int lowerLeftX, int lowerLeftY, int width, int height )
	: mCtx( gl::context() )
{
	mCtx->pushViewport( { ivec2( lowerLeftX, lowerLeftY ), ivec2( width, height ) } );
}

ScopedViewport::~ScopedViewport()
{
	mCtx->popViewport();
}

///////////////////////////////////////////////////////////////////////////////////////////
// ScopedLineWidth
ScopedLineWidth::ScopedLineWidth( float width )
	: mCtx( gl::context() )
{
	mCtx->pushLineWidth( width );
}

ScopedLineWidth::~ScopedLineWidth()
{
	mCtx->popLineWidth();
}

#if ! defined( CINDER_GL_ES )

///////////////////////////////////////////////////////////////////////////////////////////
// ScopedPolygonMode
ScopedPolygonMode::ScopedPolygonMode( GLenum mode )
	: mCtx( gl::context() )
{
	mCtx->pushPolygonMode( GL_FRONT_AND_BACK, mode );
}

ScopedPolygonMode::~ScopedPolygonMode()
{
	mCtx->popPolygonMode( GL_FRONT_AND_BACK );
}

#endif

///////////////////////////////////////////////////////////////////////////////////////////
// ScopedFrontFace
ScopedFrontFace::ScopedFrontFace( GLenum mode )
	: mCtx( gl::context() )
{
	mCtx->pushFrontFace( mode );
}

ScopedFrontFace::~ScopedFrontFace()
{
	mCtx->popFrontFace();
}

} } // namespace cinder::gl
<|endoftext|>


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

  Program:   Visualization Library
  Module:    StreamL.cc
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

This file is part of the Visualization Library. No part of this file
or its contents may be copied, reproduced or altered in any way
without the express written consent of the authors.

Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen 1993, 1994

=========================================================================*/
#include "StreamL.hh"

vlStreamLine::vlStreamLine()
{
  this->DashTime = 0.01;
}

void vlStreamLine::Execute()
{
  vlStreamPoint *sPrev, *sPtr;
  vlFloatPoints *newPts;
  vlFloatVectors *newVectors;
  vlFloatScalars *newScalars=NULL;
  vlCellArray *newLines;
  int i, ptId, j, npts, pts[MAX_CELL_SIZE];
  float tOffset, x[3], v[3], s, r;

  this->vlStreamer::Integrate();
  if ( this->NumberOfStreamers <= 0 ) return;
//
//  Convert streamer into lines. Lines may be dashed.
//
  newPts  = new vlFloatPoints(1000);
  newVectors  = new vlFloatVectors(1000);
  if ( this->Input->GetPointData()->GetScalars() || this->SpeedScalars )
    newScalars = new vlFloatScalars(1000);
  newLines = new vlCellArray();
  newLines->Allocate(newLines->EstimateSize(2*this->NumberOfStreamers,MAX_CELL_SIZE));
//
// Loop over all streamers generating points
//
  for (ptId=0; ptId < this->NumberOfStreamers; ptId++)
    {
    tOffset = 0.0;

    if ( this->Streamers[ptId].GetNumberOfPoints() < 2 ) continue;
    if ( this->Streamers[ptId].GetNumberOfPoints() == 2 )
      {
      sPtr=this->Streamers[ptId].GetStreamPoint(1);
      if ( sPtr->cellId < 0 ) continue;
      }

    for ( sPrev=sPtr=this->Streamers[ptId].GetStreamPoint(0), i=0;
    i < this->Streamers[ptId].GetNumberOfPoints() && sPtr->cellId >= 0;
    i++, sPrev=sPtr, sPtr=this->Streamers[ptId].GetStreamPoint(i) )
      {

      if ( i == 0 ) //create first point
        {
        npts = 0;
        pts[npts++] = newPts->InsertNextPoint(sPtr->x);
        newVectors->InsertVector(pts[npts-1],sPtr->v);
        if ( newScalars ) newScalars->InsertScalar(pts[npts-1],sPtr->s);
        continue;
        }
//
// For each streamer, create points "time increment" apart
//
      if ( (sPtr->t - tOffset) > this->DashTime )
        {
        r = (this->DashTime - (sPrev->t-tOffset)) / (sPtr->t - sPrev->t);
        for (j=0; j<3; j++)
          {
          x[j] = sPrev->x[j] + r * (sPtr->x[j] - sPrev->x[j]);
          v[j] = sPrev->v[j] + r * (sPtr->v[j] - sPrev->v[j]);
          }

        pts[npts++] = newPts->InsertNextPoint(x);
        newVectors->InsertVector(pts[npts-1],v);

        if ( newScalars )
          {
          s = sPrev->s + r * (sPtr->s - sPrev->s);
          newScalars->InsertScalar(pts[npts-1],s);
          }

        tOffset += this->DashTime;

        if ( npts == MAX_CELL_SIZE )
          {
          newLines->InsertNextCell(npts,pts);
          pts[0] = pts[npts-1];
          npts = 1; //prepare for next line
          }
        }
      } //for this streamer
      if ( npts > 1 ) newLines->InsertNextCell(npts,pts);
    } //for all streamers
//
// Update ourselves
//
  vlDebugMacro(<<"Created " << newPts->GetNumberOfPoints() << " points, "
               << newLines->GetNumberOfCells() << " lines");

  this->SetPoints(newPts);
  this->PointData.SetVectors(newVectors);
  if ( newScalars ) this->PointData.SetScalars(newScalars);
  this->SetLines(newLines);

  this->Squeeze();

}

void vlStreamLine::PrintSelf(ostream& os, vlIndent indent)
{
  vlStreamer::PrintSelf(os,indent);

  os << indent << "Dash Time: " << this->DashTime << " <<\n";

}

<commit_msg>ENH: Fixed bug in wild streamers.<commit_after>/*=========================================================================

  Program:   Visualization Library
  Module:    StreamL.cc
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

This file is part of the Visualization Library. No part of this file
or its contents may be copied, reproduced or altered in any way
without the express written consent of the authors.

Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen 1993, 1994

=========================================================================*/
#include "StreamL.hh"

vlStreamLine::vlStreamLine()
{
  this->DashTime = 0.01;
}

void vlStreamLine::Execute()
{
  vlStreamPoint *sPrev, *sPtr;
  vlFloatPoints *newPts;
  vlFloatVectors *newVectors;
  vlFloatScalars *newScalars=NULL;
  vlCellArray *newLines;
  int i, ptId, j, npts, pts[MAX_CELL_SIZE];
  float tOffset, x[3], v[3], s, r;

  this->vlStreamer::Integrate();
  if ( this->NumberOfStreamers <= 0 ) return;
//
//  Convert streamer into lines. Lines may be dashed.
//
  newPts  = new vlFloatPoints(1000);
  newVectors  = new vlFloatVectors(1000);
  if ( this->Input->GetPointData()->GetScalars() || this->SpeedScalars )
    newScalars = new vlFloatScalars(1000);
  newLines = new vlCellArray();
  newLines->Allocate(newLines->EstimateSize(2*this->NumberOfStreamers,MAX_CELL_SIZE));
//
// Loop over all streamers generating points
//
  for (ptId=0; ptId < this->NumberOfStreamers; ptId++)
    {
    tOffset = 0.0;

    if ( this->Streamers[ptId].GetNumberOfPoints() < 2 ) continue;
    if ( this->Streamers[ptId].GetNumberOfPoints() == 2 )
      {
      sPtr=this->Streamers[ptId].GetStreamPoint(1);
      if ( sPtr->cellId < 0 ) continue;
      }

    for ( sPrev=sPtr=this->Streamers[ptId].GetStreamPoint(0), i=0;
    i < this->Streamers[ptId].GetNumberOfPoints() && sPtr->cellId >= 0;
    i++, sPrev=sPtr, sPtr=this->Streamers[ptId].GetStreamPoint(i) )
      {

      if ( i == 0 ) //create first point
        {
        npts = 0;
        pts[npts++] = newPts->InsertNextPoint(sPtr->x);
        newVectors->InsertVector(pts[npts-1],sPtr->v);
        if ( newScalars ) newScalars->InsertScalar(pts[npts-1],sPtr->s);
        continue;
        }
//
// For each streamer, create points approximately "time increment" apart
//
      if ( (sPtr->t - tOffset) > this->DashTime )
        {
        r = (this->DashTime - (sPrev->t-tOffset)) / (sPtr->t - sPrev->t);
        if ( r >= 0.0 )
          {
          for (j=0; j<3; j++)
            {
            x[j] = sPrev->x[j] + r * (sPtr->x[j] - sPrev->x[j]);
            v[j] = sPrev->v[j] + r * (sPtr->v[j] - sPrev->v[j]);
            }
            tOffset += this->DashTime;
          }
        else //more than one "dash time" apart
          {
          for (j=0; j<3; j++)
            {
            x[j] = sPtr->x[j];
            v[j] = sPtr->v[j];
            }
            tOffset = sPtr->t;
          }

        pts[npts++] = newPts->InsertNextPoint(x);
        newVectors->InsertVector(pts[npts-1],v);

        if ( newScalars )
          {
          s = sPrev->s + r * (sPtr->s - sPrev->s);
          newScalars->InsertScalar(pts[npts-1],s);
          }

        if ( npts == MAX_CELL_SIZE )
          {
          newLines->InsertNextCell(npts,pts);
          pts[0] = pts[npts-1];
          npts = 1; //prepare for next line
          }
        }
      } //for this streamer
      if ( npts > 1 ) newLines->InsertNextCell(npts,pts);
    } //for all streamers
//
// Update ourselves
//
  vlDebugMacro(<<"Created " << newPts->GetNumberOfPoints() << " points, "
               << newLines->GetNumberOfCells() << " lines");

  this->SetPoints(newPts);
  this->PointData.SetVectors(newVectors);
  if ( newScalars ) this->PointData.SetScalars(newScalars);
  this->SetLines(newLines);

  this->Squeeze();

}

void vlStreamLine::PrintSelf(ostream& os, vlIndent indent)
{
  vlStreamer::PrintSelf(os,indent);

  os << indent << "Dash Time: " << this->DashTime << " <<\n";

}

<|endoftext|>


<commit_before><commit_msg>mutex fix<commit_after><|endoftext|>


<commit_before>/**
    Copyright (c) 2017 Neon Edge Game
    File Name: Player.cpp
    Header File Name: Player.h
    Class Name: Player
    Objective: manages the behavior of some aspects of the player.
*/

#include "Player.h"
#include "Projectile.h"

/**
    Objective: constructor of the class Player.
    @param ItensManager* itemManager
    @param int x - coordinate of the player.
    @param int y - coordinate of the player.
    @return Player - instance of the class Player.
*/
Player::Player(ItensManager* itemManager, int x, int y):
    Character(x,y),  // Player's positions in the screen.
    inputComponent(nullptr),
    itemManager(itemManager),
    skills( {
            false,
                false,
                true,true,
                true,
                false,
                false
    } ),  // Sets the default enabled skills.
    skillPoints(0),
    energy(5),  // Sets the energy of the player to 5.
    regenCD(500),  // The time of the cool down regeneration in miliseconds.
    isCrouching(false),  // Default state: standing.
    isStading(true) {
    name = "Player";  // Sets the Player's name.
    hitpoints = MAX_HITPOINTS;  // Sets the hitpoints of the player to 10.

}

/**
    Objective: destructor of the class Player.
    @param none.
    @return none.
*/
Player::~Player() {

}

/**
    Objective: checks if is a player.
    @param none.
    @return bool - returns TRUE.
*/
bool Player::IsPlayer() {
    return true;
}

/**
    Objective: gets the energy of player.
    @param none.
    @return int energy - returns the amount of energy of the player.
*/
int Player::GetEnergy() {
    return energy;
}

/**
    Objective: performs the action of crouch.
    @param: none.
    @return: none.
*/
void Player::Crouch() {

    if (isStading) {
        isStading = false;
        soundComponent->SoundCrouching();  // Performs the crouching sound in case that the player is

                                      // standing.
    } else {
        // It does nothing.
    }
    isCrouching = true;
}

/**
    Objective: performs the action of stand.
    @param none.
    @return none.
*/
void Player::Stand() {
    isCrouching = false;
    isStading = true;
}

/**
    Objective: checks if the player is crouching or not.
    @param none.
    @return bool crouching - return true if the player is crouching.
*/
bool Player::IsCrouching() {
    return isCrouching;
}

/**
    Objective: performs an action due to an item used by the player.
    @param string itemName - the name of the item.
    @return none.
*/
void Player::EvalItem(std::string itemName) {
    // Heals the hitpoints of the player by 25% of the total.
    if (itemName == "Healing Potion 25") {
        hitpoints += MAX_HITPOINTS*0.25;
        clamp(hitpoints, 0, MAX_HITPOINTS);
    } else
    // Heals the hitpoints of the player by 50% of the total.
    if (itemName == "Healing Potion 50") {
        hitpoints += MAX_HITPOINTS*0.5;
        clamp(hitpoints, 0, MAX_HITPOINTS);
    } else
    // Adds 2 energy points.
    if (itemName == "Energy Potion 25") {
        energy += 2;
        clamp(energy, 0, 5);
    } else
    // Adds 5 energy points.
    if (itemName == "Energy Potion 50") {
        energy += 5;
        clamp(energy, 0, 5);
    } else
    // Adds 1 point to the skills.
    if (itemName == "Skill Coin") {
        skillPoints++;
    } else {
        // It does nothing.
    }
}

/**
    Objective: manages the reactions of other objects in collision with the player.
    @param GameObject* other - the object that is in collision with the player.
    @return none.
*/
void Player::NotifyObjectCollision(GameObject* other) {
    Character::NotifyObjectCollision(other);
    // The player gets damaged if the object is attacking.
    if (other->IsCharacter() && !other->IsPlayer()) {
        Character* c = (Character*) other;
        if (c->Attacking()) {
            Damage(c->Power());
        } else {
            // It does nothing.
        }
    } else
        // It does nothing.
    if (other->Is("Projectile")) {
        Projectile* p = (Projectile*) other;
        if (!(p->GetOwner() == "Gallahad")) {
            Damage(p->Power());
        } else {
            // It does nothing.
        }
    } else
    // Restores some energy of the player.
    if (other->Is("Energy")) {
        if (isCrouching && !regenCD.IsRunning()) {
            regenCD.Start();
            energy += 1;
            clamp(energy, 0, 5);
        } else {
            // It does nothing.
        }
    } else
    // Restores some hitpoints of the player.
    if (other->Is("Life")) {
        if (isCrouching && !regenCD.IsRunning()) {
            regenCD.Start();
            hitpoints += 1;
            clamp(hitpoints, 0, 10);
        } else {
            // It does nothing.
        }
    } else {
        // It does nothing.
    }
}

/**
    Objective: updates the time of the cool down regeneration.
    @param float dt - the amount of time to cool down the regeneration.
    @return none.
*/
void Player::UpdateTimers(float dt) {
    Character::UpdateTimers(dt);
    regenCD.Update(dt);
}

void Player::Update(TileMap* map, float dt) {
    UpdateTimers(dt);
    inputComponent->Update(this, dt);
    physicsComponent.Update(this, map, dt);
    if (OutOfBounds(map)) {
        SetPosition(Vec2(startingX, startingY));
    } else {
        // It does nothing.
    }
    graphicsComponent->Update(this, dt);
}
<commit_msg>Aplicando Declare variaveis mais tarde 1<commit_after>/**
    Copyright (c) 2017 Neon Edge Game
    File Name: Player.cpp
    Header File Name: Player.h
    Class Name: Player
    Objective: manages the behavior of some aspects of the player.
*/

#include "Player.h"
#include "Projectile.h"

/**
    Objective: constructor of the class Player.
    @param ItensManager* itemManager
    @param int x - coordinate of the player.
    @param int y - coordinate of the player.
    @return Player - instance of the class Player.
*/
Player::Player(ItensManager* itemManager, int x, int y): Character(x,y){
    inputComponent = nullptr;
    this->itemManager = itemManager ;

	// Sets the default enabled skills.
    skills[0] = false;
    skills[1] = false;
    skills[2] = true;
    skills[3] = true;
    skills[4] = true;
    skills[5] = false;
    skills[6] = false;
	skillPoints = 0;
	energy = 5;  // Sets the energy of the player to 5.
	regenCD = 500;  // The time of the cool down regeneration in miliseconds.
	isCrouching = false;  // Default state: standing.
	isStading = true;

    name = "Player";  // Sets the Player's name.
    hitpoints = MAX_HITPOINTS;  // Sets the hitpoints of the player to 10.

}

/**
    Objective: destructor of the class Player.
    @param none.
    @return none.
*/
Player::~Player() {

}

/**
    Objective: checks if is a player.
    @param none.
    @return bool - returns TRUE.
*/
bool Player::IsPlayer() {
    return true;
}

/**
    Objective: gets the energy of player.
    @param none.
    @return int energy - returns the amount of energy of the player.
*/
int Player::GetEnergy() {
    return energy;
}

/**
    Objective: performs the action of crouch.
    @param: none.
    @return: none.
*/
void Player::Crouch() {

    if (isStading) {
        isStading = false;
        soundComponent->SoundCrouching();  // Performs the crouching sound in case that the player is

                                      // standing.
    } else {
        // It does nothing.
    }
    isCrouching = true;
}

/**
    Objective: performs the action of stand.
    @param none.
    @return none.
*/
void Player::Stand() {
    isCrouching = false;
    isStading = true;
}

/**
    Objective: checks if the player is crouching or not.
    @param none.
    @return bool crouching - return true if the player is crouching.
*/
bool Player::IsCrouching() {
    return isCrouching;
}

/**
    Objective: performs an action due to an item used by the player.
    @param string itemName - the name of the item.
    @return none.
*/
void Player::EvalItem(std::string itemName) {
    // Heals the hitpoints of the player by 25% of the total.
    if (itemName == "Healing Potion 25") {
        hitpoints += MAX_HITPOINTS*0.25;
        clamp(hitpoints, 0, MAX_HITPOINTS);
    } else
    // Heals the hitpoints of the player by 50% of the total.
    if (itemName == "Healing Potion 50") {
        hitpoints += MAX_HITPOINTS*0.5;
        clamp(hitpoints, 0, MAX_HITPOINTS);
    } else
    // Adds 2 energy points.
    if (itemName == "Energy Potion 25") {
        energy += 2;
        clamp(energy, 0, 5);
    } else
    // Adds 5 energy points.
    if (itemName == "Energy Potion 50") {
        energy += 5;
        clamp(energy, 0, 5);
    } else
    // Adds 1 point to the skills.
    if (itemName == "Skill Coin") {
        skillPoints++;
    } else {
        // It does nothing.
    }
}

/**
    Objective: manages the reactions of other objects in collision with the player.
    @param GameObject* other - the object that is in collision with the player.
    @return none.
*/
void Player::NotifyObjectCollision(GameObject* other) {
    Character::NotifyObjectCollision(other);
    // The player gets damaged if the object is attacking.
    if (other->IsCharacter() && !other->IsPlayer()) {
        Character* c = (Character*) other;
        if (c->Attacking()) {
            Damage(c->Power());
        } else {
            // It does nothing.
        }
    } else
        // It does nothing.
    if (other->Is("Projectile")) {
        Projectile* p = (Projectile*) other;
        if (!(p->GetOwner() == "Gallahad")) {
            Damage(p->Power());
        } else {
            // It does nothing.
        }
    } else
    // Restores some energy of the player.
    if (other->Is("Energy")) {
        if (isCrouching && !regenCD.IsRunning()) {
            regenCD.Start();
            energy += 1;
            clamp(energy, 0, 5);
        } else {
            // It does nothing.
        }
    } else
    // Restores some hitpoints of the player.
    if (other->Is("Life")) {
        if (isCrouching && !regenCD.IsRunning()) {
            regenCD.Start();
            hitpoints += 1;
            clamp(hitpoints, 0, 10);
        } else {
            // It does nothing.
        }
    } else {
        // It does nothing.
    }
}

/**
    Objective: updates the time of the cool down regeneration.
    @param float dt - the amount of time to cool down the regeneration.
    @return none.
*/
void Player::UpdateTimers(float dt) {
    Character::UpdateTimers(dt);
    regenCD.Update(dt);
}

void Player::Update(TileMap* map, float dt) {
    UpdateTimers(dt);
    inputComponent->Update(this, dt);
    physicsComponent.Update(this, map, dt);
    if (OutOfBounds(map)) {
        SetPosition(Vec2(startingX, startingY));
    } else {
        // It does nothing.
    }
    graphicsComponent->Update(this, dt);
}
<|endoftext|>


<commit_before>//
//  Player.cpp
//  CheckersProject
//
//  Created by Benjamin Emdon on 2016-02-13.
//  Copyright © 2016 Ben Emdon. All rights reserved.
//

#include "../include/Player.h"
#include "../include/CheckersBoard.h"

const int TEAM_SIZE = 12;

Player::Player(bool topSide) {
    initTeam(topSide);
    if (topSide) {
        turn = false;
    }
    else{
        turn = true;
    }
    selectingState = false;
}

void Player::initTeam(bool topSide) {
    if (topSide) {
        //----------------------------BLACK TEAM----------------------------\\
        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 0
        team[0].x = 1;
        team[0].y = 0;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 1
        team[1].x = 3;
        team[1].y = 0;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 2
        team[2].x = 5;
        team[2].y = 0;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 3
        team[3].x = 7;
        team[3].y = 0;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 4
        team[4].x = 0;
        team[4].y = 1;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 5
        team[5].x = 2;
        team[5].y = 1;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 6
        team[6].x = 4;
        team[6].y = 1;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 7
        team[7].x = 6;
        team[7].y = 1;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 8
        team[8].x = 1;
        team[8].y = 2;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 9
        team[9].x = 3;
        team[9].y = 2;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 10
        team[10].x = 5;
        team[10].y = 2;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 11
        team[11].x = 7;
        team[11].y = 2;
    }
    else {
        //-----------------------------RED TEAM----------------------------\\
        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 0
        team[0].x = 0;
        team[0].y = 7;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 1
        team[1].x = 2;
        team[1].y = 7;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 2
        team[2].x = 4;
        team[2].y = 7;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 3
        team[3].x = 6;
        team[3].y = 7;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 4
        team[4].x = 1;
        team[4].y = 6;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 5
        team[5].x = 3;
        team[5].y = 6;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 6
        team[6].x = 5;
        team[6].y = 6;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 7
        team[7].x = 7;
        team[7].y = 6;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 8
        team[8].x = 0;
        team[8].y = 5;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 9
        team[9].x = 2;
        team[9].y = 5;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 10
        team[10].x = 4;
        team[10].y = 5;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 11
        team[11].x = 6;
        team[11].y = 5;
    }

        // Update Virtual board after init //

    for (int teamIndex = 0; teamIndex < TEAM_SIZE; teamIndex++) {
        Board.virtualBoard[team[teamIndex].x][team[teamIndex].y] = topSide + 1;
    }
}

void Player::selectPiece(int *value, int *column, int *row, int index){
    // SELECT PIECE //
    // When a piece hasn't been selected yet, and the button currently selected doesn't have a piece inside //
    switch (Board.virtualBoard[boardButtons[index].getButtonPointX()/80][boardButtons[index].getButtonPointY()/80]) {
        case 0:
            cout<<"Selected button isn't a piece"<<endl;
            break;
        case 1:
            *column = boardButtons[index].getButtonPointX()/80;
            *row = boardButtons[index].getButtonPointY()/80;
            *value = Board.virtualBoard[*column][*row];
            selectingState = true;
            break;
        case 2:
            cout<<"Piece isn't apart of your team"<<endl;
            break;
        default:
            break;
    }
}

void Player::movePiece(int value, int column, int row, int index){
    // MOVE PIECE //
    // When a piece has been selected, and the button currently selected is empty //
    switch (Board.virtualBoard[boardButtons[index].getButtonPointX()/80][boardButtons[index].getButtonPointY()/80]) {
        case 0:
            Board.virtualBoard[column][row] = Board.virtualBoard[boardButtons[index].getButtonPointX()/80][boardButtons[index].getButtonPointY()/80];
            Board.virtualBoard[boardButtons[index].getButtonPointX()/80][boardButtons[index].getButtonPointY()/80] = value;
            for(int b=0;b<TEAM_SIZE;b++){
                if((team[b].x == column) && (team[b].y == row)){
                    team[b].x = (boardButtons[index].getButtonPointX()/80);
                    team[b].y = (boardButtons[index].getButtonPointY()/80);
                    break;
                }
            }
            selectingState = false;
            break;
        case 1:
            cout<<"Can't move onto team member"<<endl;
            break;
        case 2:
            cout<<"Can't move onto other team's member"<<endl;
            break;
        default:
            break;
    }
}
<commit_msg>Added player movement restriction<commit_after>//
//  Player.cpp
//  CheckersProject
//
//  Created by Benjamin Emdon on 2016-02-13.
//  Copyright © 2016 Ben Emdon. All rights reserved.
//

#include "../include/Player.h"
#include "../include/CheckersBoard.h"

const int TEAM_SIZE = 12;

Player::Player(bool topSide) {
    initTeam(topSide);
    if (topSide) {
        turn = false;
    }
    else{
        turn = true;
    }
    selectingState = false;
}

void Player::initTeam(bool topSide) {
    if (topSide) {
        //----------------------------BLACK TEAM----------------------------\\
        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 0
        team[0].x = 1;
        team[0].y = 0;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 1
        team[1].x = 3;
        team[1].y = 0;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 2
        team[2].x = 5;
        team[2].y = 0;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 3
        team[3].x = 7;
        team[3].y = 0;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 4
        team[4].x = 0;
        team[4].y = 1;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 5
        team[5].x = 2;
        team[5].y = 1;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 6
        team[6].x = 4;
        team[6].y = 1;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 7
        team[7].x = 6;
        team[7].y = 1;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 8
        team[8].x = 1;
        team[8].y = 2;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 9
        team[9].x = 3;
        team[9].y = 2;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 10
        team[10].x = 5;
        team[10].y = 2;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 11
        team[11].x = 7;
        team[11].y = 2;
    }
    else {
        //-----------------------------RED TEAM----------------------------\\
        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 0
        team[0].x = 0;
        team[0].y = 7;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 1
        team[1].x = 2;
        team[1].y = 7;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 2
        team[2].x = 4;
        team[2].y = 7;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 3
        team[3].x = 6;
        team[3].y = 7;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 4
        team[4].x = 1;
        team[4].y = 6;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 5
        team[5].x = 3;
        team[5].y = 6;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 6
        team[6].x = 5;
        team[6].y = 6;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 7
        team[7].x = 7;
        team[7].y = 6;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 8
        team[8].x = 0;
        team[8].y = 5;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 9
        team[9].x = 2;
        team[9].y = 5;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 10
        team[10].x = 4;
        team[10].y = 5;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 11
        team[11].x = 6;
        team[11].y = 5;
    }

        // Update Virtual board after init //

    for (int teamIndex = 0; teamIndex < TEAM_SIZE; teamIndex++) {
        Board.virtualBoard[team[teamIndex].x][team[teamIndex].y] = topSide + 1;
    }
}

void Player::selectPiece(int *value, int *column, int *row, int index){
    // SELECT PIECE //
    // When a piece hasn't been selected yet, and the button currently selected doesn't have a piece inside //
    switch (Board.virtualBoard[boardButtons[index].getButtonPointX()/80][boardButtons[index].getButtonPointY()/80]) {
        case 0:
            cout<<"Selected button isn't a piece"<<endl;
            break;
        case 1:
            *column = boardButtons[index].getButtonPointX()/80;
            *row = boardButtons[index].getButtonPointY()/80;
            *value = Board.virtualBoard[*column][*row];
            selectingState = true;
            break;
        case 2:
            cout<<"Piece isn't apart of your team"<<endl;
            break;
        default:
            break;
    }
}

void Player::movePiece(int value, int column, int row, int index){
    // MOVE PIECE //
    // When a piece has been selected, and the button currently selected is empty //
    switch (Board.virtualBoard[boardButtons[index].getButtonPointX()/80][boardButtons[index].getButtonPointY()/80]) {
        case 0:
            if (abs(boardButtons[index].getButtonPointX()/80 - column) == 1 || abs(boardButtons[index].getButtonPointY()/80 - row) == 1) {
                Board.virtualBoard[column][row] = Board.virtualBoard[boardButtons[index].getButtonPointX()/80][boardButtons[index].getButtonPointY()/80];
                Board.virtualBoard[boardButtons[index].getButtonPointX()/80][boardButtons[index].getButtonPointY()/80] = value;
                for(int b=0;b<TEAM_SIZE;b++){
                    if((team[b].x == column) && (team[b].y == row)){
                        team[b].x = (boardButtons[index].getButtonPointX()/80);
                        team[b].y = (boardButtons[index].getButtonPointY()/80);
                        break;
                    }
                }
                selectingState = false;
            }
            else {
                cout<<"Cannot move here, out of range"<<endl;
            }
            break;
        case 1:
            cout<<"Can't move onto team member"<<endl;
            break;
        case 2:
            cout<<"Can't move onto other team's member"<<endl;
            break;
        default:
            break;
    }
}
<|endoftext|>