<commit_before>//
//  nthRoot.cpp
//  Calculator
//
//  Created by Gavin Scheele on 3/27/14.
//  Copyright (c) 2014 Gavin Scheele. All rights reserved.
//

#include "nthRoot.h"
#include "Integer.h"
#include <array>
using namespace std;
nthRoot::nthRoot(int root, int operand, int coefficient) {
    this->type = "nthRoot";
    this->operand = operand;
    this->root = root;
    this->coefficient = coefficient;
    this->simplify();

    if ((root % 2) == 0 && operand < 0) {
        throw runtime_error("unreal answer");
    }
}

nthRoot::nthRoot(int root, Expression* eoperand, int coefficient) {
    this->type = "nthRoot";
    this->eoperand = eoperand;
    this->root = root;
    this->coefficient = coefficient;

    if ((root % 2) == 0 && eoperand->type == "integer") {
        Integer *a = (Integer *)eoperand;
        if (a->getValue() < 0) {
            throw runtime_error("unreal answer");
        }
    }

    if ((root % 2) == 0 && eoperand->type == "Rational"){
        Rational *b = (Rational*)eoperand;
        if ((b->getNumerator() < 0 || b->getDenominator() < 0)
             && !(b->getNumerator() < 0 && b->getDenominator() < 0)) {
             throw runtime_error("unreal answer");
        }
    }
}

nthRoot::~nthRoot() {

}

 int* nthRoot::primeFactorization(int n, int div, int k) {
    if (n % div == 0) {
        factors[k] = div;
        if (div == n) {
            return factors;
        }
        else {
            primeFactorization((n / div), div, (k + 1));
        }
    }
    else if (div <= n) {
        primeFactorization(n, div++, k);
    }
    return factors;
}

int nthRoot::localExponentiate(int under, int locExponent) {
    for (int i = 1; i < locExponent; i++) {
        under *= under;
    }
//    cout << under << "\n";
    return under;
}
/*int* nthRoot::primeFactorization(int n, int num, int number) {    //non-recursive version
    int k = 0;
    int* factors;
    while (n%2 == 0) {
        factors[k] = 2;
        k++;
        n = n/2;
    }
    for (int i = 3; i <= sqrt(n); i = i + 2) {
//        if (n%i == 0) {
            while (n%i == 0) {
                factors[k] = i;
                k++;
                n = n/i;
            }
//        }
    }
    if (n > 2) {
        factors[k] = n;
    }
    n = 3;
    return factors;
    // added bonus: factors should be sorted already
} */

Expression* nthRoot::simplify(){
    //if coefficient == 0 then return 0?
    //if operand < 0 throw an error
    if ((root % 2) == 0 && operand < 0) {
        throw runtime_error("unreal answer");
    }
//    int *factorsCopy = this->primeFactorization(operand, 2, 0);
      this->primeFactorization(operand, 2, 0);
//    copy(this->primeFactorization(operand, 2, 0)+50, factors);
    int i = 0;
    int factorsSize = sizeof(factors)/sizeof(factors[0]);

    while (i <= factorsSize && factors[i] != 0) {   //all this takes unnecessary factors out of the operand
        int j = i;               //and puts them into the coefficient
        int count = 1;
        while (j <= factorsSize && factors[j + 1] == factors[j] && factors[j] != 0) {
            count++;
            j++;
        }
        if (count >= root) {

            coefficient = coefficient * localExponentiate(factors[i], (count/root));
            operand = (operand / localExponentiate(factors[i], (count - (count % root))));
        }
        i = j + 1;
    }
    if (operand == 1) {
        Integer* newInt = new Integer(coefficient);
        return newInt;
    }
    else {
        Expression* newRoot = new nthRoot(root, operand, coefficient);
        delete this;  //is this necessary?
        return newRoot;
    }

}

Expression* nthRoot::add(Expression* a) {
    nthRoot *b = (nthRoot *)a;
    int asCoefficient = b->getCoefficient();
    int asOperand = b->getOperand();
    int asRoot = b->getRoot();
    if (root == asRoot && operand == asOperand) {
        int newCoefficient = asCoefficient + coefficient;
        nthRoot* newNthRoot = new nthRoot(root, operand, newCoefficient);
        nthRoot* simplifiedVersion = (nthRoot *)newNthRoot->simplify();
        return simplifiedVersion;
    }
    else {
        return this;
    }
}

Expression* nthRoot::subtract(Expression* a) {
    nthRoot *b = (nthRoot *)a;
    int asCoefficient = b->getCoefficient();
    int asOperand = b->getOperand();
    int asRoot = b->getRoot();
    if (root == asRoot && operand == asOperand) {
        int newCoefficient = coefficient - asCoefficient;
        nthRoot* newNthRoot = new nthRoot(root, operand, newCoefficient);
        nthRoot* simplifiedVersion = (nthRoot *)newNthRoot->simplify();
        return simplifiedVersion;
    }
    else {
        return this;
    }
}

Expression* nthRoot::multiply(Expression* a) {
    if (a->type == "integer") {
        Integer *b = (Integer*)a;
        int asValue = b->getValue();
        int newCoefficient = asValue * coefficient;
        nthRoot* newNthRoot = new nthRoot(root, operand, newCoefficient);
        nthRoot* simplifiedVersion = (nthRoot *)newNthRoot->simplify();
        return simplifiedVersion;
    }
    if (a->type == "nthRoot") {
        nthRoot *b = (nthRoot *)a;
        int asCoefficient = b->getCoefficient();
        int asOperand = b->getOperand();
        int asRoot = b->getRoot();
        if (root == asRoot) {
            int newCoefficient = asCoefficient * coefficient;
            int newOperand = operand * asOperand;       //asOperand doesnt exist?
            nthRoot* newNthRoot = new nthRoot(root, newOperand, newCoefficient);
            nthRoot* simplifiedVersion = (nthRoot *)newNthRoot->simplify();
            return simplifiedVersion;
        }
    }
    else {
        return this;
    }
    return this;
}

Expression* nthRoot::divide(Expression* a) {
    nthRoot *b = (nthRoot *)a;
    int asRoot = b->getRoot();
    int asOperand = b->getOperand();
    int asCoefficient = b->getCoefficient();
    if (root == asRoot && fmod( ((double)coefficient / (double)asCoefficient), 1) == 0 && fmod(((double)operand / (double)asOperand), 1) == 0) {
        int newCoefficient = coefficient / asCoefficient;
        int newOperand = operand / asOperand;
        nthRoot* newNthRoot = new nthRoot(root, newOperand, newCoefficient);
        nthRoot* simplifiedVersion = (nthRoot *)newNthRoot->simplify();
        return simplifiedVersion;
    }
   else if (fmod( ((double)coefficient / (double)asCoefficient),1) == 0) {
        int newCoefficient = coefficient / asCoefficient;
        nthRoot* newNthRoot = new nthRoot(root, operand, newCoefficient);
        nthRoot* simplifiedVersion = (nthRoot *)newNthRoot->simplify();
        return simplifiedVersion;
    }
    else {
        return this;
    }
}

int nthRoot::getRoot() {
    return root;
}

int nthRoot::getOperand() {
    return operand;
}

int nthRoot::getCoefficient() {
    return coefficient;
}

void nthRoot::setCoefficient(int n) {
    this->coefficient = n;
}

void nthRoot::setOperand(int n) {
    this->operand = n;
}

void nthRoot::setRoot(int n) {
    this->root = n;
}
ostream& nthRoot::print(std::ostream& output) const {
    if (this->operand == 1) {
        output << this->coefficient;
    }else{
        output << this->coefficient  << "*" << this->root << "rt:" << this->operand;
    }
    return output;
}

string nthRoot::toString() {
    stringstream s;
    if (this->operand == 1) {
        s << this->coefficient;
    }else{
        s << this->coefficient  << "*" << this->root << "rt:" << this->operand;
    }
    return s.str();
}

bool nthRoot::canAdd(Expression* b){     //use "this" as comparison. Solver will call someExpression.canAdd(&someOtherExpression)

    if (this->type == b->type && this->type != "logarithm") {
        if (this->type == "nthRoot") {
        }
        return true;
    }else if((this->type == "integer" && b->type == "rational") || (this->type == "rational" && b->type == "integer")){
        return true;
    }else if(this->type == "multiple" && b->type == "multiple"){
        MultipleExpressions *t = (MultipleExpressions *)this;
        MultipleExpressions *m = (MultipleExpressions *)b;
        if ((t->meType == "as" && m->meType == "as") || (t->meType == "md" && m->meType == "md")) {
            return true;
        }
    }else if(this->type == "multiple" || b->type == "multiple") return true;
    return false;
}
bool nthRoot::canSubtract(Expression* b){
    if (this->type == b->type) {
        return true;
    }else if((this->type == "integer" && b->type == "rational") || (this->type == "rational" && b->type == "integer")){
        return true;
    }else if(this->type == "multiple" && b->type == "multiple"){
        MultipleExpressions *t = (MultipleExpressions *)this;
        MultipleExpressions *m = (MultipleExpressions *)b;
        if ((t->meType == "as" && m->meType == "as") || (t->meType == "md" && m->meType == "md")) {
            return true;
        }
    }else if(this->type == "multiple" || b->type == "multiple") return true;
    return false;
}
bool nthRoot::canMultiply(Expression* b){
    if (this->type == b->type) {
        return true;
    }
    else if(this->type == "integer" && b->type == "rational") return true;
    else if(this->type == "rational" && b->type == "integer") return true;
    else if(this->type == "multiple" && b->type == "multiple"){
        MultipleExpressions *t = (MultipleExpressions *)this;
        MultipleExpressions *m = (MultipleExpressions *)b;
        if ((t->meType == "as" && m->meType == "as") || (t->meType == "md" && m->meType == "md")) {
            return true;
        }
    }else if(this->type == "multiple" || b->type == "multiple") return true;
    return false;

}
bool nthRoot::canDivide(Expression* b){
    if (this->type == b->type) {
        return true;
    }
    else if(this->type == "integer"){
        if( b->type == "rational") return true;
    }
    else if(this->type == "rational" && b->type == "integer") return true;
    else if(this->type == "multiple" && b->type == "multiple"){
        MultipleExpressions *t = (MultipleExpressions *)this;
        MultipleExpressions *m = (MultipleExpressions *)b;
        if ((t->meType == "as" && m->meType == "as") || (t->meType == "md" && m->meType == "md")) {
            return true;
        }
    }else if(this->type == "multiple" || b->type == "multiple") return true;
    return false;
}
<commit_msg>okay, now 2rt:9 works. Slowly getting more difficu<commit_after>//
//  nthRoot.cpp
//  Calculator
//
//  Created by Gavin Scheele on 3/27/14.
//  Copyright (c) 2014 Gavin Scheele. All rights reserved.
//

#include "nthRoot.h"
#include "Integer.h"
#include <array>
using namespace std;
nthRoot::nthRoot(int root, int operand, int coefficient) {
    this->type = "nthRoot";
    this->operand = operand;
    this->root = root;
    this->coefficient = coefficient;
    this->simplify();

    if ((root % 2) == 0 && operand < 0) {
        throw runtime_error("unreal answer");
    }
}

nthRoot::nthRoot(int root, Expression* eoperand, int coefficient) {
    this->type = "nthRoot";
    this->eoperand = eoperand;
    this->root = root;
    this->coefficient = coefficient;

    if ((root % 2) == 0 && eoperand->type == "integer") {
        Integer *a = (Integer *)eoperand;
        if (a->getValue() < 0) {
            throw runtime_error("unreal answer");
        }
    }

    if ((root % 2) == 0 && eoperand->type == "Rational"){
        Rational *b = (Rational*)eoperand;
        if ((b->getNumerator() < 0 || b->getDenominator() < 0)
             && !(b->getNumerator() < 0 && b->getDenominator() < 0)) {
             throw runtime_error("unreal answer");
        }
    }
}

nthRoot::~nthRoot() {

}

 int* nthRoot::primeFactorization(int n, int div, int k) {
    if (n % div == 0) {
        factors[k] = div;
        if (div == n) {
            factors[k+1] = 0; //the zero works as a stopping point later on
            return factors;
        }
        else {
            primeFactorization((n / div), div, (k + 1));
        }
    }
    else if (div <= n) {
        primeFactorization(n, (div + 1), k);
    }
    return factors;
}

int nthRoot::localExponentiate(int under, int locExponent) {
    for (int i = 1; i < locExponent; i++) {
        under *= under;
    }
//    cout << under << "\n";
    return under;
}
/*int* nthRoot::primeFactorization(int n, int num, int number) {    //non-recursive version
    int k = 0;
    int* factors;
    while (n%2 == 0) {
        factors[k] = 2;
        k++;
        n = n/2;
    }
    for (int i = 3; i <= sqrt(n); i = i + 2) {
//        if (n%i == 0) {
            while (n%i == 0) {
                factors[k] = i;
                k++;
                n = n/i;
            }
//        }
    }
    if (n > 2) {
        factors[k] = n;
    }
    n = 3;
    return factors;
    // added bonus: factors should be sorted already
} */

Expression* nthRoot::simplify(){
    //if coefficient == 0 then return 0?
    //if operand < 0 throw an error
    if ((root % 2) == 0 && operand < 0) {
        throw runtime_error("unreal answer");
    }
//    int *factorsCopy = this->primeFactorization(operand, 2, 0);
      this->primeFactorization(operand, 2, 0);
//    copy(this->primeFactorization(operand, 2, 0)+50, factors);
    int i = 0;
    int factorsSize = sizeof(factors)/sizeof(factors[0]);

    while (i <= factorsSize && factors[i] != 0) {   //all this takes unnecessary factors out of the operand
        int j = i;               //and puts them into the coefficient
        int count = 1;
        while (j <= factorsSize && factors[j + 1] == factors[j] && factors[j] != 0) {
            count++;
            j++;
        }
        if (count >= root) {

            coefficient = coefficient * localExponentiate(factors[i], (count/root));
            operand = (operand / localExponentiate(factors[i], (count - (count % root))));
        }
        i = j + 1;
    }
    if (operand == 1) {
        Integer* newInt = new Integer(coefficient);
        return newInt;
    }
    else {
        Expression* newRoot = new nthRoot(root, operand, coefficient);
        delete this;  //is this necessary?
        return newRoot;
    }

}

Expression* nthRoot::add(Expression* a) {
    nthRoot *b = (nthRoot *)a;
    int asCoefficient = b->getCoefficient();
    int asOperand = b->getOperand();
    int asRoot = b->getRoot();
    if (root == asRoot && operand == asOperand) {
        int newCoefficient = asCoefficient + coefficient;
        nthRoot* newNthRoot = new nthRoot(root, operand, newCoefficient);
        nthRoot* simplifiedVersion = (nthRoot *)newNthRoot->simplify();
        return simplifiedVersion;
    }
    else {
        return this;
    }
}

Expression* nthRoot::subtract(Expression* a) {
    nthRoot *b = (nthRoot *)a;
    int asCoefficient = b->getCoefficient();
    int asOperand = b->getOperand();
    int asRoot = b->getRoot();
    if (root == asRoot && operand == asOperand) {
        int newCoefficient = coefficient - asCoefficient;
        nthRoot* newNthRoot = new nthRoot(root, operand, newCoefficient);
        nthRoot* simplifiedVersion = (nthRoot *)newNthRoot->simplify();
        return simplifiedVersion;
    }
    else {
        return this;
    }
}

Expression* nthRoot::multiply(Expression* a) {
    if (a->type == "integer") {
        Integer *b = (Integer*)a;
        int asValue = b->getValue();
        int newCoefficient = asValue * coefficient;
        nthRoot* newNthRoot = new nthRoot(root, operand, newCoefficient);
        nthRoot* simplifiedVersion = (nthRoot *)newNthRoot->simplify();
        return simplifiedVersion;
    }
    if (a->type == "nthRoot") {
        nthRoot *b = (nthRoot *)a;
        int asCoefficient = b->getCoefficient();
        int asOperand = b->getOperand();
        int asRoot = b->getRoot();
        if (root == asRoot) {
            int newCoefficient = asCoefficient * coefficient;
            int newOperand = operand * asOperand;       //asOperand doesnt exist?
            nthRoot* newNthRoot = new nthRoot(root, newOperand, newCoefficient);
            nthRoot* simplifiedVersion = (nthRoot *)newNthRoot->simplify();
            return simplifiedVersion;
        }
    }
    else {
        return this;
    }
    return this;
}

Expression* nthRoot::divide(Expression* a) {
    nthRoot *b = (nthRoot *)a;
    int asRoot = b->getRoot();
    int asOperand = b->getOperand();
    int asCoefficient = b->getCoefficient();
    if (root == asRoot && fmod( ((double)coefficient / (double)asCoefficient), 1) == 0 && fmod(((double)operand / (double)asOperand), 1) == 0) {
        int newCoefficient = coefficient / asCoefficient;
        int newOperand = operand / asOperand;
        nthRoot* newNthRoot = new nthRoot(root, newOperand, newCoefficient);
        nthRoot* simplifiedVersion = (nthRoot *)newNthRoot->simplify();
        return simplifiedVersion;
    }
   else if (fmod( ((double)coefficient / (double)asCoefficient),1) == 0) {
        int newCoefficient = coefficient / asCoefficient;
        nthRoot* newNthRoot = new nthRoot(root, operand, newCoefficient);
        nthRoot* simplifiedVersion = (nthRoot *)newNthRoot->simplify();
        return simplifiedVersion;
    }
    else {
        return this;
    }
}

int nthRoot::getRoot() {
    return root;
}

int nthRoot::getOperand() {
    return operand;
}

int nthRoot::getCoefficient() {
    return coefficient;
}

void nthRoot::setCoefficient(int n) {
    this->coefficient = n;
}

void nthRoot::setOperand(int n) {
    this->operand = n;
}

void nthRoot::setRoot(int n) {
    this->root = n;
}
ostream& nthRoot::print(std::ostream& output) const {
    if (this->operand == 1) {
        output << this->coefficient;
    }else{
        output << this->coefficient  << "*" << this->root << "rt:" << this->operand;
    }
    return output;
}

string nthRoot::toString() {
    stringstream s;
    if (this->operand == 1) {
        s << this->coefficient;
    }else{
        s << this->coefficient  << "*" << this->root << "rt:" << this->operand;
    }
    return s.str();
}

bool nthRoot::canAdd(Expression* b){     //use "this" as comparison. Solver will call someExpression.canAdd(&someOtherExpression)

    if (this->type == b->type && this->type != "logarithm") {
        if (this->type == "nthRoot") {
        }
        return true;
    }else if((this->type == "integer" && b->type == "rational") || (this->type == "rational" && b->type == "integer")){
        return true;
    }else if(this->type == "multiple" && b->type == "multiple"){
        MultipleExpressions *t = (MultipleExpressions *)this;
        MultipleExpressions *m = (MultipleExpressions *)b;
        if ((t->meType == "as" && m->meType == "as") || (t->meType == "md" && m->meType == "md")) {
            return true;
        }
    }else if(this->type == "multiple" || b->type == "multiple") return true;
    return false;
}
bool nthRoot::canSubtract(Expression* b){
    if (this->type == b->type) {
        return true;
    }else if((this->type == "integer" && b->type == "rational") || (this->type == "rational" && b->type == "integer")){
        return true;
    }else if(this->type == "multiple" && b->type == "multiple"){
        MultipleExpressions *t = (MultipleExpressions *)this;
        MultipleExpressions *m = (MultipleExpressions *)b;
        if ((t->meType == "as" && m->meType == "as") || (t->meType == "md" && m->meType == "md")) {
            return true;
        }
    }else if(this->type == "multiple" || b->type == "multiple") return true;
    return false;
}
bool nthRoot::canMultiply(Expression* b){
    if (this->type == b->type) {
        return true;
    }
    else if(this->type == "integer" && b->type == "rational") return true;
    else if(this->type == "rational" && b->type == "integer") return true;
    else if(this->type == "multiple" && b->type == "multiple"){
        MultipleExpressions *t = (MultipleExpressions *)this;
        MultipleExpressions *m = (MultipleExpressions *)b;
        if ((t->meType == "as" && m->meType == "as") || (t->meType == "md" && m->meType == "md")) {
            return true;
        }
    }else if(this->type == "multiple" || b->type == "multiple") return true;
    return false;

}
bool nthRoot::canDivide(Expression* b){
    if (this->type == b->type) {
        return true;
    }
    else if(this->type == "integer"){
        if( b->type == "rational") return true;
    }
    else if(this->type == "rational" && b->type == "integer") return true;
    else if(this->type == "multiple" && b->type == "multiple"){
        MultipleExpressions *t = (MultipleExpressions *)this;
        MultipleExpressions *m = (MultipleExpressions *)b;
        if ((t->meType == "as" && m->meType == "as") || (t->meType == "md" && m->meType == "md")) {
            return true;
        }
    }else if(this->type == "multiple" || b->type == "multiple") return true;
    return false;
}
<|endoftext|>


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

#include "common/init.h"

#include <google/heap-profiler.h>
#include <google/malloc_extension.h>

#include "common/logging.h"
#include "common/status.h"
#include "exprs/expr.h"
#include "util/cpu-info.h"
#include "util/debug-util.h"
#include "util/disk-info.h"
#include "util/logging-support.h"
#include "util/mem-info.h"
#include "util/network-util.h"
#include "util/os-info.h"
#include "util/redactor.h"
#include "util/test-info.h"
#include "runtime/decimal-value.h"
#include "runtime/exec-env.h"
#include "runtime/hdfs-fs-cache.h"
#include "runtime/lib-cache.h"
#include "runtime/mem-tracker.h"
#include "runtime/timestamp-parse-util.h"
#include "rpc/authentication.h"
#include "rpc/thrift-util.h"
#include "util/thread.h"

DECLARE_string(hostname);
DECLARE_string(redaction_rules_file);
// TODO: renamed this to be more generic when we have a good CM release to do so.
DECLARE_int32(logbufsecs);
DECLARE_string(heap_profile_dir);
DECLARE_bool(enable_process_lifetime_heap_profiling);

DEFINE_int32(max_log_files, 10, "Maximum number of log files to retain per severity "
    "level. The most recent log files are retained. If set to 0, all log files are "
    "retained.");

// tcmalloc will hold on to freed memory. We will periodically release the memory back
// to the OS if the extra memory is too high. If the memory used by the application
// is less than this fraction of the total reserved memory, free it back to the OS.
static const float TCMALLOC_RELEASE_FREE_MEMORY_FRACTION = 0.5f;

using namespace boost;
using std::string;

// Maintenance thread that runs periodically. It does a few things:
// 1) flushes glog every logbufsecs sec. glog flushes the log file only if
//    logbufsecs has passed since the previous flush when a new log is written. That means
//    that on a quiet system, logs will be buffered indefinitely.
// 2) checks that tcmalloc has not left too much memory in its pageheap
shared_ptr<impala::Thread> maintenance_thread;
static void MaintenanceThread() {
  while(true) {
    sleep(FLAGS_logbufsecs);

    google::FlushLogFiles(google::GLOG_INFO);

    // Tests don't need to run the maintenance thread. It causes issues when
    // on teardown.
    if (impala::TestInfo::is_test()) continue;

#ifndef ADDRESS_SANITIZER
    // Required to ensure memory gets released back to the OS, even if tcmalloc doesn't do
    // it for us. This is because tcmalloc releases memory based on the
    // TCMALLOC_RELEASE_RATE property, which is not actually a rate but a divisor based
    // on the number of blocks that have been deleted. When tcmalloc does decide to
    // release memory, it removes a single span from the PageHeap. This means there are
    // certain allocation patterns that can lead to OOM due to not enough memory being
    // released by tcmalloc, even when that memory is no longer being used.
    // One example is continually resizing a vector which results in many allocations.
    // Even after the vector goes out of scope, all the memory will not be released
    // unless there are enough other deletions that are occurring in the system.
    // This can eventually lead to OOM/crashes (see IMPALA-818).
    // See: http://google-perftools.googlecode.com/svn/trunk/doc/tcmalloc.html#runtime
    size_t bytes_used = 0;
    size_t bytes_in_pageheap = 0;
    MallocExtension::instance()->GetNumericProperty(
        "generic.current_allocated_bytes", &bytes_used);
    MallocExtension::instance()->GetNumericProperty(
        "generic.heap_size", &bytes_in_pageheap);
    if (bytes_used < bytes_in_pageheap * TCMALLOC_RELEASE_FREE_MEMORY_FRACTION) {
      MallocExtension::instance()->ReleaseFreeMemory();
    }

    // When using tcmalloc, the process limit as measured by our trackers will
    // be out of sync with the process usage. Update the process tracker periodically.
    impala::ExecEnv* env = impala::ExecEnv::GetInstance();
    if (env != NULL && env->process_mem_tracker() != NULL) {
      env->process_mem_tracker()->Release(0);
    }
#endif
    // TODO: we should also update the process mem tracker with the reported JVM
    // mem usage.

    // Check for log rotation in every interval of the maintenance thread
    impala::CheckAndRotateLogFiles(FLAGS_max_log_files);
  }
}

void impala::InitCommonRuntime(int argc, char** argv, bool init_jvm,
    TestInfo::Mode test_mode) {
  CpuInfo::Init();
  DiskInfo::Init();
  MemInfo::Init();
  OsInfo::Init();
  DecimalUtil::InitMaxUnscaledDecimal();
  TestInfo::Init(test_mode);

  // Verify CPU meets the minimum requirements before calling InitGoogleLoggingSafe()
  // which might use SSSE3 instructions (see IMPALA-160).
  CpuInfo::VerifyCpuRequirements();

  // Set the default hostname. The user can override this with the hostname flag.
  GetHostname(&FLAGS_hostname);

  google::SetVersionString(impala::GetBuildVersion());
  google::ParseCommandLineFlags(&argc, &argv, true);
  if (!FLAGS_redaction_rules_file.empty()) {
    const string& error_message = SetRedactionRulesFromFile(FLAGS_redaction_rules_file);
    if (!error_message.empty()) EXIT_WITH_ERROR(error_message);
  }
  impala::InitGoogleLoggingSafe(argv[0]);
  impala::InitThreading();
  impala::TimestampParser::Init();
  EXIT_IF_ERROR(impala::InitAuth(argv[0]));

  // Initialize maintenance_thread after InitGoogleLoggingSafe and InitThreading.
  maintenance_thread.reset(
      new Thread("common", "maintenance-thread", &MaintenanceThread));

  LOG(INFO) << impala::GetVersionString();
  LOG(INFO) << "Using hostname: " << FLAGS_hostname;
  impala::LogCommandLineFlags();

  InitThriftLogging();

  LOG(INFO) << CpuInfo::DebugString();
  LOG(INFO) << DiskInfo::DebugString();
  LOG(INFO) << MemInfo::DebugString();
  LOG(INFO) << OsInfo::DebugString();
  LOG(INFO) << "Process ID: " << getpid();

  // Required for the FE's Catalog
  impala::LibCache::Init();
  impala::HdfsFsCache::Init();

  if (init_jvm) {
    EXIT_IF_ERROR(JniUtil::Init());
    InitJvmLoggingSupport();
  }

  if (argc == -1) {
    // Should not be called. We need BuiltinsInit() so the builtin symbols are
    // not stripped.
    DCHECK(false);
    Expr::InitBuiltinsDummy();
  }

#ifndef ADDRESS_SANITIZER
  // tcmalloc and address sanitizer can not be used together
  if (FLAGS_enable_process_lifetime_heap_profiling) {
    HeapProfilerStart(FLAGS_heap_profile_dir.c_str());
  }
#endif
}
<commit_msg>Redaction: Don't allow row logging when redaction rules are set<commit_after>// Copyright 2012 Cloudera Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "common/init.h"

#include <google/heap-profiler.h>
#include <google/malloc_extension.h>

#include "common/logging.h"
#include "common/status.h"
#include "exprs/expr.h"
#include "util/cpu-info.h"
#include "util/debug-util.h"
#include "util/disk-info.h"
#include "util/logging-support.h"
#include "util/mem-info.h"
#include "util/network-util.h"
#include "util/os-info.h"
#include "util/redactor.h"
#include "util/test-info.h"
#include "runtime/decimal-value.h"
#include "runtime/exec-env.h"
#include "runtime/hdfs-fs-cache.h"
#include "runtime/lib-cache.h"
#include "runtime/mem-tracker.h"
#include "runtime/timestamp-parse-util.h"
#include "rpc/authentication.h"
#include "rpc/thrift-util.h"
#include "util/thread.h"

DECLARE_string(hostname);
DECLARE_string(redaction_rules_file);
// TODO: renamed this to be more generic when we have a good CM release to do so.
DECLARE_int32(logbufsecs);
DECLARE_string(heap_profile_dir);
DECLARE_bool(enable_process_lifetime_heap_profiling);

DEFINE_int32(max_log_files, 10, "Maximum number of log files to retain per severity "
    "level. The most recent log files are retained. If set to 0, all log files are "
    "retained.");

// Defined by glog. This allows users to specify the log level using a glob. For
// example -vmodule=*scanner*=3 would enable full logging for scanners. If redaction
// is enabled, this option won't be allowed because some logging dumps table data
// in ways the authors of redaction rules can't anticipate.
DECLARE_string(vmodule);

// tcmalloc will hold on to freed memory. We will periodically release the memory back
// to the OS if the extra memory is too high. If the memory used by the application
// is less than this fraction of the total reserved memory, free it back to the OS.
static const float TCMALLOC_RELEASE_FREE_MEMORY_FRACTION = 0.5f;

using namespace boost;
using std::string;

// Maintenance thread that runs periodically. It does a few things:
// 1) flushes glog every logbufsecs sec. glog flushes the log file only if
//    logbufsecs has passed since the previous flush when a new log is written. That means
//    that on a quiet system, logs will be buffered indefinitely.
// 2) checks that tcmalloc has not left too much memory in its pageheap
shared_ptr<impala::Thread> maintenance_thread;
static void MaintenanceThread() {
  while(true) {
    sleep(FLAGS_logbufsecs);

    google::FlushLogFiles(google::GLOG_INFO);

    // Tests don't need to run the maintenance thread. It causes issues when
    // on teardown.
    if (impala::TestInfo::is_test()) continue;

#ifndef ADDRESS_SANITIZER
    // Required to ensure memory gets released back to the OS, even if tcmalloc doesn't do
    // it for us. This is because tcmalloc releases memory based on the
    // TCMALLOC_RELEASE_RATE property, which is not actually a rate but a divisor based
    // on the number of blocks that have been deleted. When tcmalloc does decide to
    // release memory, it removes a single span from the PageHeap. This means there are
    // certain allocation patterns that can lead to OOM due to not enough memory being
    // released by tcmalloc, even when that memory is no longer being used.
    // One example is continually resizing a vector which results in many allocations.
    // Even after the vector goes out of scope, all the memory will not be released
    // unless there are enough other deletions that are occurring in the system.
    // This can eventually lead to OOM/crashes (see IMPALA-818).
    // See: http://google-perftools.googlecode.com/svn/trunk/doc/tcmalloc.html#runtime
    size_t bytes_used = 0;
    size_t bytes_in_pageheap = 0;
    MallocExtension::instance()->GetNumericProperty(
        "generic.current_allocated_bytes", &bytes_used);
    MallocExtension::instance()->GetNumericProperty(
        "generic.heap_size", &bytes_in_pageheap);
    if (bytes_used < bytes_in_pageheap * TCMALLOC_RELEASE_FREE_MEMORY_FRACTION) {
      MallocExtension::instance()->ReleaseFreeMemory();
    }

    // When using tcmalloc, the process limit as measured by our trackers will
    // be out of sync with the process usage. Update the process tracker periodically.
    impala::ExecEnv* env = impala::ExecEnv::GetInstance();
    if (env != NULL && env->process_mem_tracker() != NULL) {
      env->process_mem_tracker()->Release(0);
    }
#endif
    // TODO: we should also update the process mem tracker with the reported JVM
    // mem usage.

    // Check for log rotation in every interval of the maintenance thread
    impala::CheckAndRotateLogFiles(FLAGS_max_log_files);
  }
}

void impala::InitCommonRuntime(int argc, char** argv, bool init_jvm,
    TestInfo::Mode test_mode) {
  CpuInfo::Init();
  DiskInfo::Init();
  MemInfo::Init();
  OsInfo::Init();
  DecimalUtil::InitMaxUnscaledDecimal();
  TestInfo::Init(test_mode);

  // Verify CPU meets the minimum requirements before calling InitGoogleLoggingSafe()
  // which might use SSSE3 instructions (see IMPALA-160).
  CpuInfo::VerifyCpuRequirements();

  // Set the default hostname. The user can override this with the hostname flag.
  GetHostname(&FLAGS_hostname);

  google::SetVersionString(impala::GetBuildVersion());
  google::ParseCommandLineFlags(&argc, &argv, true);
  if (!FLAGS_redaction_rules_file.empty()) {
    if (VLOG_ROW_IS_ON || !FLAGS_vmodule.empty()) {
      EXIT_WITH_ERROR("Redaction cannot be used in combination with log level 3 or "
          "higher or the -vmodule option because these log levels may log data in "
          "ways redaction rules may not anticipate.");
    }
    const string& error_message = SetRedactionRulesFromFile(FLAGS_redaction_rules_file);
    if (!error_message.empty()) EXIT_WITH_ERROR(error_message);
  }
  impala::InitGoogleLoggingSafe(argv[0]);
  impala::InitThreading();
  impala::TimestampParser::Init();
  EXIT_IF_ERROR(impala::InitAuth(argv[0]));

  // Initialize maintenance_thread after InitGoogleLoggingSafe and InitThreading.
  maintenance_thread.reset(
      new Thread("common", "maintenance-thread", &MaintenanceThread));

  LOG(INFO) << impala::GetVersionString();
  LOG(INFO) << "Using hostname: " << FLAGS_hostname;
  impala::LogCommandLineFlags();

  InitThriftLogging();

  LOG(INFO) << CpuInfo::DebugString();
  LOG(INFO) << DiskInfo::DebugString();
  LOG(INFO) << MemInfo::DebugString();
  LOG(INFO) << OsInfo::DebugString();
  LOG(INFO) << "Process ID: " << getpid();

  // Required for the FE's Catalog
  impala::LibCache::Init();
  impala::HdfsFsCache::Init();

  if (init_jvm) {
    EXIT_IF_ERROR(JniUtil::Init());
    InitJvmLoggingSupport();
  }

  if (argc == -1) {
    // Should not be called. We need BuiltinsInit() so the builtin symbols are
    // not stripped.
    DCHECK(false);
    Expr::InitBuiltinsDummy();
  }

#ifndef ADDRESS_SANITIZER
  // tcmalloc and address sanitizer can not be used together
  if (FLAGS_enable_process_lifetime_heap_profiling) {
    HeapProfilerStart(FLAGS_heap_profile_dir.c_str());
  }
#endif
}
<|endoftext|>


<commit_before>#include "../test.h"
#include "../../src/forces/label_collision_force.h"
#include "../../src/forces/label_state.h"

namespace Forces
{

TEST(Test_LabelCollisionForce, NoForceIfLabelsDontCollide)
{
  LabelCollisionForce force;

  Eigen::Vector2f size(0.1f, 0.1f);
  LabelState label(1, "Tested label", Eigen::Vector3f(0, 0, 0), size);
  label.labelPosition2D = Eigen::Vector2f(0, 0);

  LabelState other(2, "Other label", Eigen::Vector3f(1, 1, 0), size);
  label.labelPosition2D = Eigen::Vector2f(1, 1);

  LabellerFrameData frameData(1.0f, Eigen::Matrix4f::Identity(),
                              Eigen::Matrix4f::Identity());
  auto labels = std::vector<LabelState>{ label, other };
  auto result = force.calculateForce(label, labels, frameData);

  EXPECT_Vector2f_NEAR(Eigen::Vector2f(0, 0), result, 0.0001f);
}

}  // namespace Forces
<commit_msg>Add another test for LabelCollisionForce.<commit_after>#include "../test.h"
#include "../../src/forces/label_collision_force.h"
#include "../../src/forces/label_state.h"

namespace Forces
{

TEST(Test_LabelCollisionForce, NoForceIfLabelsDontCollide)
{
  LabelCollisionForce force;

  Eigen::Vector2f size(0.1f, 0.1f);
  LabelState label(1, "Tested label", Eigen::Vector3f(0, 0, 0), size);
  label.labelPosition2D = Eigen::Vector2f(0, 0);

  LabelState other(2, "Other label", Eigen::Vector3f(1, 1, 0), size);
  other.labelPosition2D = Eigen::Vector2f(1, 1);

  LabellerFrameData frameData(1.0f, Eigen::Matrix4f::Identity(),
                              Eigen::Matrix4f::Identity());
  auto labels = std::vector<LabelState>{ label, other };
  auto result = force.calculateForce(label, labels, frameData);

  EXPECT_Vector2f_NEAR(Eigen::Vector2f(0, 0), result, 0.0001f);
}

TEST(Test_LabelCollisionForce, ForceIfLabelsCollide)
{
  LabelCollisionForce force;

  Eigen::Vector2f size(1.0f, 1.0f);
  LabelState label(1, "Tested label", Eigen::Vector3f(0, 0, 0), size);
  label.labelPosition2D = Eigen::Vector2f(0, 0);

  LabelState other(2, "Other label", Eigen::Vector3f(1, 1, 0), size);
  other.labelPosition2D = Eigen::Vector2f(1, 1);

  LabellerFrameData frameData(1.0f, Eigen::Matrix4f::Identity(),
                              Eigen::Matrix4f::Identity());
  auto labels = std::vector<LabelState>{ label, other };
  auto result = force.calculateForce(label, labels, frameData);

  EXPECT_Vector2f_NEAR(Eigen::Vector2f(-0.70710678, -0.707010678), result, 0.0001f);
}

}  // namespace Forces
<|endoftext|>


<commit_before>#include "repo-service-helper.h"

#include "filebrowser/data-mgr.h"
#include "filebrowser/progress-dialog.h"
#include "filebrowser/file-browser-requests.h"
#include "filebrowser/tasks.h"
#include "filebrowser/auto-update-mgr.h"

#include "ui/set-repo-password-dialog.h"

#include <QDir>
#include "utils/utils.h"
#include "seafile-applet.h"

void FileDownloadHelper::openFile(const QString& path, bool work_around_mac_auto_udpate)
{
    if (!::openInNativeExtension(path) && !::showInGraphicalShell(path)) {
        QString file_name = QFileInfo(path).fileName();
        QString msg = QObject::tr("%1 couldn't find an application to open file %2").arg(getBrand()).arg(file_name);
        seafApplet->warningBox(msg);
    }
#ifdef Q_WS_MAC
    MacImageFilesWorkAround::instance()->fileOpened(path);
#endif
}

FileDownloadHelper::FileDownloadHelper(const Account &account, const ServerRepo &repo, const QString &path, QWidget *parent)
  : account_(account), repo_(repo), path_(path), file_name_(QFileInfo(path).fileName()), parent_(parent), req_(NULL) {
}

FileDownloadHelper::~FileDownloadHelper()
{
    onCancel();
    if (req_)
        req_->deleteLater();
}

void FileDownloadHelper::start()
{
    if (req_)
        return;
    const QString file_name = QFileInfo(path_).fileName();
    const QString dirent_path = path_.left(path_.size() - file_name.size() - 1);
    req_ = new GetDirentsRequest(account_, repo_.id, dirent_path);
    connect(req_, SIGNAL(success(const QList<SeafDirent> &)),
            this, SLOT(onGetDirentsSuccess(const QList<SeafDirent> &)));
    connect(req_, SIGNAL(failed(const ApiError &)),
            this, SLOT(onGetDirentsFailure(const ApiError &)));
    req_->send();
}

void FileDownloadHelper::onCancel()
{
    if (req_)
        disconnect(req_, 0, this, 0);
}

void FileDownloadHelper::onGetDirentsSuccess(const QList<SeafDirent> &dirents)
{
    bool found_file = false;
    Q_FOREACH(const SeafDirent &dirent, dirents)
    {
        if (dirent.name == file_name_) {
            downloadFile(dirent.id);
            found_file = true;
            break;
        }
    }
    // critally important
    if (!found_file) {
        qDebug("File %s doesn't exist any more", file_name_.toUtf8().data());
    }

}

void FileDownloadHelper::downloadFile(const QString &id)
{
    DataManager data_mgr(account_);

    QString cached_file = data_mgr.getLocalCachedFile(repo_.id, path_, id);
    if (!cached_file.isEmpty()) {
        openFile(cached_file, false);
        return;
    }

    // endless loop for setPasswordDialog
    while(true) {
        FileDownloadTask *task = data_mgr.createDownloadTask(repo_.id, path_);
        FileBrowserProgressDialog dialog(task, parent_);
        if (dialog.exec()) {
            QString full_path =
                data_mgr.getLocalCachedFile(repo_.id, path_, task->fileId());
            if (!full_path.isEmpty())
                openFile(full_path, true);
            break;
        }
        // if the user canceled the task, don't bother it
        if (task->error() == FileNetworkTask::TaskCanceled)
            break;
        // if the repo_sitory is encrypted and password is incorrect
        if (repo_.encrypted && task->httpErrorCode() == 400) {
            SetRepoPasswordDialog password_dialog(repo_, parent_);
            if (password_dialog.exec())
                continue;
            // the user canceled the dialog? skip
            break;
        }
        QString msg =
            QObject::tr("Unable to download item \"%1\"").arg(path_);
        seafApplet->warningBox(msg);
        break;
    }
}

<commit_msg>use getParentPath for repo-service-helper.cpp<commit_after>#include "repo-service-helper.h"

#include "filebrowser/data-mgr.h"
#include "filebrowser/progress-dialog.h"
#include "filebrowser/file-browser-requests.h"
#include "filebrowser/tasks.h"
#include "filebrowser/auto-update-mgr.h"

#include "ui/set-repo-password-dialog.h"

#include <QDir>
#include "utils/utils.h"
#include "utils/file-utils.h"
#include "seafile-applet.h"

void FileDownloadHelper::openFile(const QString& path, bool work_around_mac_auto_udpate)
{
    if (!::openInNativeExtension(path) && !::showInGraphicalShell(path)) {
        QString file_name = QFileInfo(path).fileName();
        QString msg = QObject::tr("%1 couldn't find an application to open file %2").arg(getBrand()).arg(file_name);
        seafApplet->warningBox(msg);
    }
#ifdef Q_WS_MAC
    MacImageFilesWorkAround::instance()->fileOpened(path);
#endif
}

FileDownloadHelper::FileDownloadHelper(const Account &account, const ServerRepo &repo, const QString &path, QWidget *parent)
  : account_(account), repo_(repo), path_(path), file_name_(QFileInfo(path).fileName()), parent_(parent), req_(NULL) {
}

FileDownloadHelper::~FileDownloadHelper()
{
    onCancel();
    if (req_)
        req_->deleteLater();
}

void FileDownloadHelper::start()
{
    if (req_)
        return;
    const QString file_name = QFileInfo(path_).fileName();
    const QString dirent_path = ::getParentPath(path_);
    req_ = new GetDirentsRequest(account_, repo_.id, dirent_path);
    connect(req_, SIGNAL(success(const QList<SeafDirent> &)),
            this, SLOT(onGetDirentsSuccess(const QList<SeafDirent> &)));
    connect(req_, SIGNAL(failed(const ApiError &)),
            this, SLOT(onGetDirentsFailure(const ApiError &)));
    req_->send();
}

void FileDownloadHelper::onCancel()
{
    if (req_)
        disconnect(req_, 0, this, 0);
}

void FileDownloadHelper::onGetDirentsSuccess(const QList<SeafDirent> &dirents)
{
    bool found_file = false;
    Q_FOREACH(const SeafDirent &dirent, dirents)
    {
        if (dirent.name == file_name_) {
            downloadFile(dirent.id);
            found_file = true;
            break;
        }
    }
    // critally important
    if (!found_file) {
        qDebug("File %s doesn't exist any more", file_name_.toUtf8().data());
    }

}

void FileDownloadHelper::downloadFile(const QString &id)
{
    DataManager data_mgr(account_);

    QString cached_file = data_mgr.getLocalCachedFile(repo_.id, path_, id);
    if (!cached_file.isEmpty()) {
        openFile(cached_file, false);
        return;
    }

    // endless loop for setPasswordDialog
    while(true) {
        FileDownloadTask *task = data_mgr.createDownloadTask(repo_.id, path_);
        FileBrowserProgressDialog dialog(task, parent_);
        if (dialog.exec()) {
            QString full_path =
                data_mgr.getLocalCachedFile(repo_.id, path_, task->fileId());
            if (!full_path.isEmpty())
                openFile(full_path, true);
            break;
        }
        // if the user canceled the task, don't bother it
        if (task->error() == FileNetworkTask::TaskCanceled)
            break;
        // if the repo_sitory is encrypted and password is incorrect
        if (repo_.encrypted && task->httpErrorCode() == 400) {
            SetRepoPasswordDialog password_dialog(repo_, parent_);
            if (password_dialog.exec())
                continue;
            // the user canceled the dialog? skip
            break;
        }
        QString msg =
            QObject::tr("Unable to download item \"%1\"").arg(path_);
        seafApplet->warningBox(msg);
        break;
    }
}

<|endoftext|>


<commit_before>#include "SysControl.h"
#include "ControlsApp.h"

//ƽַ̨
#ifdef _WIN32
#pragma execution_character_set("utf-8")
#endif

using namespace MathLib;

class CSysControlLocal : public CSysControl
{

}<commit_msg>Signed-off-by: mrlitong <litongtongxue@gmail.com><commit_after>#include "SysControl.h"
#include "ControlsApp.h"

//ƽַ̨
#ifdef _WIN32
#pragma execution_character_set("utf-8")
#endif

using namespace MathLib;

class CSysControlLocal : public CSysControl
{
public:
	    CSysControlLocal();
    virtual ~CSysControlLocal();
}<|endoftext|>


<commit_before>#include "SysControl.h"
#include "ControlsApp.h"
#include "ControlsXPad360.h"
#include "Engine.h"
#include "App.h"
#include "Engine.h"
#include "App.h"
#include "Input.h"
#include "ObjectGui.h"
#include "WidgetLabel.h"

//解决跨平台字符集兼容问题
#ifdef _WIN32
#pragma execution_character_set("utf-8")
#endif

using namespace MathLib;

class CSysControlLocal : public CSysControl
{
public:
	CSysControlLocal();
	virtual ~CSysControlLocal();

	virtual void Init();	//角色要初始化，着色器要初始化，
	virtual void Update(float ifps);
	virtual void Shutdown();

	virtual int GetState(int state);		//鼠标状态，键盘状态，人物状态，子弹状态等等。
	virtual int ClearState(int state);

	virtual float GetMouseDX();
	virtual float GetMouseDY();

	virtual void SetMouseGrab(int g);		//设置是否显示鼠标
	virtual int GetMouseGrab();			//获取鼠标状态，是显示呢还是不显示的状态。

	virtual void SetControlMode(ControlMode mode);			//控制模式
	virtual ControlMode GetControlMode() const;				//获取控制模式

private:
	void Update_Mouse(float ifps);
	void Update_Keyboard(float ifps);
	void Update_XPad360(float ifps);

	CControlsApp        *m_pControlsApp;		//控制游戏中移动
	CControlsXPad360    *m_pControlsXPad360;
	ControlMode         m_nControlMode;			//控制模式

	int                 m_nOldMouseX;			//上一个鼠标坐标X
	int                 m_nOldMouseY;			//上一个鼠标坐标Y

	CObjectGui          *m_pTest3DUI;
	CWidgetLabel        *m_pTestMessageLabel;

};

CSysControlLocal::CSysControlLocal()
{

}
CSysControlLocal::~CSysControlLocal()
{

}

void CSysControlLocal::Init()
{
	m_pControlsApp = new CControlsApp;
	m_pControlsXPad360 = new CControlsXPad360(0);

	g_Engine.pApp->SetMouseGrab(0);
	g_Engine.pApp->SetMouseShow(0);

	SetControlMode(CONTROL_KEYBORAD_MOUSE);

	m_pTest3DUI = new CObjectGui(2.0f, 1.0f, "data/core/gui/");
	m_pTest3DUI->SetMouseShow(0);
	m_pTest3DUI->SetBackground(1);
	m_pTest3DUI->SetBackgroundColor(vec4(1.0f, 0.0f, 0.0f, 1.0f));

	m_pTest3DUI->SetScreenSize(800, 400);
	m_pTest3DUI->SetControlDistance(1000.0f);
	m_pTest3DUI->CreateMaterial("gui_base");	 //show in game

	m_pTest3DUI->SetWorldTransform(Translate(0.0f, 0.0f, 2.0f) * MakeRotationFromZY(vec3(0.0f, -1.0f, 0.0f), vec3(0.0f, 0.0f, 1.0f)));

	m_pTestMessageLabel = new CWidgetLabel(m_pTest3DUI->GetGui());	//初始化文字标签
	m_pTest3DUI->GetGui()->AddChild(m_pTestMessageLabel, CGui::ALIGN_CENTER);
	m_pTestMessageLabel->SetFontColor(vec4(0.0f, 0.0f, 0.0f, 1.0f));

	m_pTestMessageLabel = new CWidgetLabel(m_pTest3DUI->GetGui());	//初始化文字标签
	m_pTest3DUI->GetGui()->AddChild(m_pTestMessageLabel, CGui::ALIGN_CENTER);
	m_pTestMessageLabel->SetFontColor(vec4(0.0f, 0.0f, 0.0f, 1.0f));

	m_pTestMessageLabel->SetFontSize(80);		//设置字体大小
	m_pTestMessageLabel->SetFontOutline(1);		//设置字体轮廓
	m_pTestMessageLabel->SetText("两个黄鹂鸣翠柳\n一行白鹭上青天\n窗含西岭千秋雪\n门泊东吴万里船");

	void CSysControlLocal::Update(float ifps)
	{
		Update_Mouse(ifps);
		Update_Keyboard(ifps);
		Update_XPad360(ifps);
	}

	m_nOldMouseX = 0;
	m_nOldMouseY = 0;
}
void CSysControlLocal::Shutdown()
{
	g_Engine.pApp->SetMouseGrab(0);
	g_Engine.pApp->SetMouseShow(0);
	delete m_pControlsApp;
	m_pControlsApp = NULL;
	delete m_pControlsXPad360;
	m_pControlsXPad360 = NULL;
	delete m_pTestMessageLabel;
	m_pTestMessageLabel = NULL;
	delete m_pTest3DUI;
	m_pTest3DUI = NULL;

}

int CSysControlLocal::GetState(int state)
{

	return m_pControlsApp->GetState(state);
}

int CSysControlLocal::ClearState(int state)
{
	return m_pControlsApp->ClearState(state);
}

float CSysControlLocal::GetMouseDX()
{
	return m_pControlsApp->GetMouseDX();
}

float CSysControlLocal::GetMouseDY()
{
	return m_pControlsApp->GetMouseDY();
}
void CSysControlLocal::SetMouseGrab(int g)
{
	g_Engine.pApp->SetMouseGrab(g);
	g_Engine.pGui->SetMouseShow(!g);
}
int CSysControlLocal::GetMouseGrab()
{
	return g_Engine.pApp->GetMouseGrab();
}

void CSysControlLocal::SetControlMode(ControlMode mode)
{
	m_nControlMode = mode;
}

CSysControl::ControlMode CSysControlLocal::GetControlMode() const
{
	return m_nControlMode;
}

CSysControl::ControlMode CSysControlLocal::GetControlMode() const
{
	return m_nControlMode;
}
void CSysControlLocal::Update_Mouse(float ifps)
{
	float dx = (g_Engine.pApp->GetMouseX() - m_nOldMouseX) * g_Engine.pControls->GetMouseSensitivity() * 0.1f;//0.1f这个数值越大，鼠标移动越快
	float dy = (g_Engine.pApp->GetMouseY() - m_nOldMouseY) * g_Engine.pControls->GetMouseSensitivity() * 0.1f;//0.1这个数值越小，鼠标移动越慢

	m_pControlsApp->SetMouseDX(dx);
	m_pControlsApp->SetMouseDY(dy);

	if (g_Engine.pApp->GetMouseGrab() && g_Engine.pApp->GetActive())
	{
		g_Engine.pApp->SetMouse(g_Engine.pApp->GetWidth() / 2, g_Engine.pApp->GetHeight() / 2);
	}

	m_nOldMouseX = g_Engine.pApp->GetMouseX();
	m_nOldMouseY = g_Engine.pApp->GetMouseY();
}

void CSysControlLocal::Update_Keyboard(float ifps)		//键盘按键响应wsad
{

	if (g_Engine.pInput->IsKeyDown('w'))
		m_pControlsApp->SetState(CControls::STATE_FORWARD, 1);
	if (g_Engine.pInput->IsKeyDown('s'))
		m_pControlsApp->SetState(CControls::STATE_BACKWARD, 1);
	if (g_Engine.pInput->IsKeyDown('a'))
		m_pControlsApp->SetState(CControls::STATE_MOVE_LEFT, 1);
	if (g_Engine.pInput->IsKeyDown('d'))
		m_pControlsApp->SetState(CControls::STATE_MOVE_RIGHT, 1);

	if (g_Engine.pInput->IsKeyUp('w'))
		m_pControlsApp->SetState(CControls::STATE_FORWARD, 0);
	else if (g_Engine.pInput->IsKeyUp('s'))
		m_pControlsApp->SetState(CControls::STATE_BACKWARD, 0);

	if (g_Engine.pInput->IsKeyUp('a'))
		m_pControlsApp->SetState(CControls::STATE_MOVE_LEFT, 0);
	else if (g_Engine.pInput->IsKeyUp('d'))
		m_pControlsApp->SetState(CControls::STATE_MOVE_RIGHT, 0);
	if (g_Engine.pInput->IsKeyDown(' '))		//空格跳跃
		m_pControlsApp->SetState(CControls::STATE_JUMP, 1);
	else
		m_pControlsApp->SetState(CControls::STATE_JUMP, 0);
}
void CSysControlLocal::Update_XPad360(float ifps)
{
	m_pControlsXPad360->UpdateEvents();
	CUtilStr strMessage;
	strMessage = CUtilStr("测试3D UI\n"),
	strMessage += CUtilStr(m_pControlsXPad360->GetName()) + "\n";

	strMessage += CUtilStr::Format("\n手柄测试\n");
	strMessage += CUtilStr::Format("LeftX:  %5.2f\n", m_pControlsXPad360->GetLeftX());
	strMessage += CUtilStr::Format("LeftY:  %5.2f\n", m_pControlsXPad360->GetLeftY());
	strMessage += CUtilStr::Format("RightX: %5.2f\n", m_pControlsXPad360->GetRightX());
	strMessage += CUtilStr::Format("RightY: %5.2f\n", m_pControlsXPad360->GetRightY());
	strMessage += "\nTriggers:\n";
	strMessage += CUtilStr::Format("Left:   %5.2f\n", m_pControlsXPad360->GetLeftTrigger());
	strMessage += CUtilStr::Format("Right:  %5.2f\n", m_pControlsXPad360->GetRightTrigger());

	strMessage += CUtilStr::Format("\nButtons:\n");
	for (int i = 0; i < CControlsXPad360::NUM_BUTTONS; ++i)
	{
		strMessage += CUtilStr::Format("%d ", m_pControlsXPad360->GetButton(i));
	}
	m_pTestMessageLabel->SetText(strMessage.Get());

	const float fPadThreshold = 0.5f;
	if (m_pControlsXPad360->GetLeftX() > fPadThreshold)
		m_pControlsApp->SetState(CControls::STATE_MOVE_RIGHT, 1);
	else if (m_pControlsXPad360->GetLeftX() < -fPadThreshold)
		m_pControlsApp->SetState(CControls::STATE_MOVE_LEFT, 1);
	else
	{
		m_pControlsApp->SetState(CControls::STATE_MOVE_LEFT, 0);
		m_pControlsApp->SetState(CControls::STATE_MOVE_RIGHT, 0);
	}
	if (m_pControlsXPad360->GetLeftY() > fPadThreshold)
		m_pControlsApp->SetState(CControls::STATE_FORWARD, 1);
	else if (m_pControlsXPad360->GetLeftY() < -fPadThreshold)
		m_pControlsApp->SetState(CControls::STATE_BACKWARD, 1);
	else
	{
		m_pControlsApp->SetState(CControls::STATE_FORWARD, 0);
		m_pControlsApp->SetState(CControls::STATE_BACKWARD, 0);
	}
	if (m_pControlsXPad360->GetButton(CControlsXPad360::BUTTON_SHOULDER_LEFT) || m_pControlsXPad360->GetButton(CControlsXPad360::BUTTON_SHOULDER_RIGHT))
		m_pControlsApp->SetState(CControls::STATE_JUMP, 1);
	else
		m_pControlsApp->SetState(CControls::STATE_JUMP, 0);
	//update jump
	// LT RT

}<commit_msg>Signed-off-by: mrlitong <litongtongxue@gmail.com><commit_after>#include "SysControl.h"
#include "ControlsApp.h"
#include "ControlsXPad360.h"
#include "Engine.h"
#include "App.h"
#include "Engine.h"
#include "App.h"
#include "Input.h"
#include "ObjectGui.h"
#include "WidgetLabel.h"

//解决跨平台字符集兼容问题
#ifdef _WIN32
#pragma execution_character_set("utf-8")
#endif

using namespace MathLib;

class CSysControlLocal : public CSysControl
{
public:
	CSysControlLocal();
	virtual ~CSysControlLocal();

	virtual void Init();	//角色要初始化，着色器要初始化，
	virtual void Update(float ifps);
	virtual void Shutdown();

	virtual int GetState(int state);		//鼠标状态，键盘状态，人物状态，子弹状态等等。
	virtual int ClearState(int state);

	virtual float GetMouseDX();
	virtual float GetMouseDY();

	virtual void SetMouseGrab(int g);		//设置是否显示鼠标
	virtual int GetMouseGrab();			//获取鼠标状态，是显示呢还是不显示的状态。

	virtual void SetControlMode(ControlMode mode);			//控制模式
	virtual ControlMode GetControlMode() const;				//获取控制模式

private:
	void Update_Mouse(float ifps);
	void Update_Keyboard(float ifps);
	void Update_XPad360(float ifps);

	CControlsApp        *m_pControlsApp;		//控制游戏中移动
	CControlsXPad360    *m_pControlsXPad360;
	ControlMode         m_nControlMode;			//控制模式

	int                 m_nOldMouseX;			//上一个鼠标坐标X
	int                 m_nOldMouseY;			//上一个鼠标坐标Y

	CObjectGui          *m_pTest3DUI;
	CWidgetLabel        *m_pTestMessageLabel;

};

CSysControlLocal::CSysControlLocal()
{

}
CSysControlLocal::~CSysControlLocal()
{

}

void CSysControlLocal::Init()
{
	m_pControlsApp = new CControlsApp;
	m_pControlsXPad360 = new CControlsXPad360(0);

	g_Engine.pApp->SetMouseGrab(0);
	g_Engine.pApp->SetMouseShow(0);

	SetControlMode(CONTROL_KEYBORAD_MOUSE);

	m_pTest3DUI = new CObjectGui(2.0f, 1.0f, "data/core/gui/");
	m_pTest3DUI->SetMouseShow(0);
	m_pTest3DUI->SetBackground(1);
	m_pTest3DUI->SetBackgroundColor(vec4(1.0f, 0.0f, 0.0f, 1.0f));

	m_pTest3DUI->SetScreenSize(800, 400);
	m_pTest3DUI->SetControlDistance(1000.0f);
	m_pTest3DUI->CreateMaterial("gui_base");	 //show in game

	m_pTest3DUI->SetWorldTransform(Translate(0.0f, 0.0f, 2.0f) * MakeRotationFromZY(vec3(0.0f, -1.0f, 0.0f), vec3(0.0f, 0.0f, 1.0f)));

	m_pTestMessageLabel = new CWidgetLabel(m_pTest3DUI->GetGui());	//初始化文字标签
	m_pTest3DUI->GetGui()->AddChild(m_pTestMessageLabel, CGui::ALIGN_CENTER);
	m_pTestMessageLabel->SetFontColor(vec4(0.0f, 0.0f, 0.0f, 1.0f));

	m_pTestMessageLabel = new CWidgetLabel(m_pTest3DUI->GetGui());	//初始化文字标签
	m_pTest3DUI->GetGui()->AddChild(m_pTestMessageLabel, CGui::ALIGN_CENTER);
	m_pTestMessageLabel->SetFontColor(vec4(0.0f, 0.0f, 0.0f, 1.0f));

	m_pTestMessageLabel->SetFontSize(80);		//设置字体大小
	m_pTestMessageLabel->SetFontOutline(1);		//设置字体轮廓
	m_pTestMessageLabel->SetText("两个黄鹂鸣翠柳\n一行白鹭上青天\n窗含西岭千秋雪\n门泊东吴万里船");

	void CSysControlLocal::Update(float ifps)
	{
		Update_Mouse(ifps);
		Update_Keyboard(ifps);
		Update_XPad360(ifps);
	}

	m_nOldMouseX = 0;
	m_nOldMouseY = 0;
}
void CSysControlLocal::Shutdown()
{
	g_Engine.pApp->SetMouseGrab(0);
	g_Engine.pApp->SetMouseShow(0);
	delete m_pControlsApp;
	m_pControlsApp = NULL;
	delete m_pControlsXPad360;
	m_pControlsXPad360 = NULL;
	delete m_pTestMessageLabel;
	m_pTestMessageLabel = NULL;
	delete m_pTest3DUI;
	m_pTest3DUI = NULL;

}

int CSysControlLocal::GetState(int state)
{

	return m_pControlsApp->GetState(state);
}

int CSysControlLocal::ClearState(int state)
{
	return m_pControlsApp->ClearState(state);
}

float CSysControlLocal::GetMouseDX()
{
	return m_pControlsApp->GetMouseDX();
}

float CSysControlLocal::GetMouseDY()
{
	return m_pControlsApp->GetMouseDY();
}
void CSysControlLocal::SetMouseGrab(int g)
{
	g_Engine.pApp->SetMouseGrab(g);
	g_Engine.pGui->SetMouseShow(!g);
}
int CSysControlLocal::GetMouseGrab()
{
	return g_Engine.pApp->GetMouseGrab();
}

void CSysControlLocal::SetControlMode(ControlMode mode)
{
	m_nControlMode = mode;
}

CSysControl::ControlMode CSysControlLocal::GetControlMode() const
{
	return m_nControlMode;
}

CSysControl::ControlMode CSysControlLocal::GetControlMode() const
{
	return m_nControlMode;
}
void CSysControlLocal::Update_Mouse(float ifps)
{
	float dx = (g_Engine.pApp->GetMouseX() - m_nOldMouseX) * g_Engine.pControls->GetMouseSensitivity() * 0.1f;//0.1f这个数值越大，鼠标移动越快
	float dy = (g_Engine.pApp->GetMouseY() - m_nOldMouseY) * g_Engine.pControls->GetMouseSensitivity() * 0.1f;//0.1这个数值越小，鼠标移动越慢

	m_pControlsApp->SetMouseDX(dx);
	m_pControlsApp->SetMouseDY(dy);

	if (g_Engine.pApp->GetMouseGrab() && g_Engine.pApp->GetActive())
	{
		g_Engine.pApp->SetMouse(g_Engine.pApp->GetWidth() / 2, g_Engine.pApp->GetHeight() / 2);
	}

	m_nOldMouseX = g_Engine.pApp->GetMouseX();
	m_nOldMouseY = g_Engine.pApp->GetMouseY();
}

void CSysControlLocal::Update_Keyboard(float ifps)		//键盘按键响应wsad
{

	if (g_Engine.pInput->IsKeyDown('w'))
		m_pControlsApp->SetState(CControls::STATE_FORWARD, 1);
	if (g_Engine.pInput->IsKeyDown('s'))
		m_pControlsApp->SetState(CControls::STATE_BACKWARD, 1);
	if (g_Engine.pInput->IsKeyDown('a'))
		m_pControlsApp->SetState(CControls::STATE_MOVE_LEFT, 1);
	if (g_Engine.pInput->IsKeyDown('d'))
		m_pControlsApp->SetState(CControls::STATE_MOVE_RIGHT, 1);

	if (g_Engine.pInput->IsKeyUp('w'))
		m_pControlsApp->SetState(CControls::STATE_FORWARD, 0);
	else if (g_Engine.pInput->IsKeyUp('s'))
		m_pControlsApp->SetState(CControls::STATE_BACKWARD, 0);

	if (g_Engine.pInput->IsKeyUp('a'))
		m_pControlsApp->SetState(CControls::STATE_MOVE_LEFT, 0);
	else if (g_Engine.pInput->IsKeyUp('d'))
		m_pControlsApp->SetState(CControls::STATE_MOVE_RIGHT, 0);
	if (g_Engine.pInput->IsKeyDown(' '))		//空格跳跃
		m_pControlsApp->SetState(CControls::STATE_JUMP, 1);
	else
		m_pControlsApp->SetState(CControls::STATE_JUMP, 0);
}
void CSysControlLocal::Update_XPad360(float ifps)
{
	m_pControlsXPad360->UpdateEvents();
	CUtilStr strMessage;
	strMessage = CUtilStr("测试3D UI\n"),
	strMessage += CUtilStr(m_pControlsXPad360->GetName()) + "\n";

	strMessage += CUtilStr::Format("\n手柄测试\n");
	strMessage += CUtilStr::Format("LeftX:  %5.2f\n", m_pControlsXPad360->GetLeftX());
	strMessage += CUtilStr::Format("LeftY:  %5.2f\n", m_pControlsXPad360->GetLeftY());
	strMessage += CUtilStr::Format("RightX: %5.2f\n", m_pControlsXPad360->GetRightX());
	strMessage += CUtilStr::Format("RightY: %5.2f\n", m_pControlsXPad360->GetRightY());
	strMessage += "\nTriggers:\n";
	strMessage += CUtilStr::Format("Left:   %5.2f\n", m_pControlsXPad360->GetLeftTrigger());
	strMessage += CUtilStr::Format("Right:  %5.2f\n", m_pControlsXPad360->GetRightTrigger());

	strMessage += CUtilStr::Format("\nButtons:\n");
	for (int i = 0; i < CControlsXPad360::NUM_BUTTONS; ++i)
	{
		strMessage += CUtilStr::Format("%d ", m_pControlsXPad360->GetButton(i));
	}
	m_pTestMessageLabel->SetText(strMessage.Get());

	const float fPadThreshold = 0.5f;
	if (m_pControlsXPad360->GetLeftX() > fPadThreshold)
		m_pControlsApp->SetState(CControls::STATE_MOVE_RIGHT, 1);
	else if (m_pControlsXPad360->GetLeftX() < -fPadThreshold)
		m_pControlsApp->SetState(CControls::STATE_MOVE_LEFT, 1);
	else
	{
		m_pControlsApp->SetState(CControls::STATE_MOVE_LEFT, 0);
		m_pControlsApp->SetState(CControls::STATE_MOVE_RIGHT, 0);
	}
	if (m_pControlsXPad360->GetLeftY() > fPadThreshold)
		m_pControlsApp->SetState(CControls::STATE_FORWARD, 1);
	else if (m_pControlsXPad360->GetLeftY() < -fPadThreshold)
		m_pControlsApp->SetState(CControls::STATE_BACKWARD, 1);
	else
	{
		m_pControlsApp->SetState(CControls::STATE_FORWARD, 0);
		m_pControlsApp->SetState(CControls::STATE_BACKWARD, 0);
	}
	if (m_pControlsXPad360->GetButton(CControlsXPad360::BUTTON_SHOULDER_LEFT) || m_pControlsXPad360->GetButton(CControlsXPad360::BUTTON_SHOULDER_RIGHT))
		m_pControlsApp->SetState(CControls::STATE_JUMP, 1);
	else
		m_pControlsApp->SetState(CControls::STATE_JUMP, 0);
	//update jump
	// LT RT
	if (m_pControlsXPad360->GetRightTrigger() > fPadThreshold || m_pControlsXPad360->GetLeftTrigger() > fPadThreshold)
	{

	}
}<|endoftext|>


<commit_before>#include "SysControl.h"
#include "ControlsApp.h"
#include "ControlsXPad360.h"

//ƽַ̨
#ifdef _WIN32
#pragma execution_character_set("utf-8")
#endif

using namespace MathLib;

class CSysControlLocal : public CSysControl
{
public:
	CSysControlLocal();
    virtual ~CSysControlLocal();

	virtual void Init();	//ɫҪʼɫҪʼ
	virtual void Update(float ifps);
	virtual void Shutdown();

	virtual int GetState(int state);		//״̬״̬״̬ӵ״̬ȵȡ
	virtual int ClearState(int state);

	virtual float GetMouseDX();
	virtual float GetMouseDY();

	virtual void SetMouseGrab(int g);		//Ƿʾ
	virtual int GetMouseGrab();			//ȡ״̬ʾػǲʾ״̬

	virtual void SetControlMode(ControlMode mode);			//ģʽ
	virtual ControlMode GetControlMode() const;				//ȡģʽ

private:

}<commit_msg>Signed-off-by: mrlitong <litongtongxue@gmail.com><commit_after>#include "SysControl.h"
#include "ControlsApp.h"
#include "ControlsXPad360.h"

//ƽַ̨
#ifdef _WIN32
#pragma execution_character_set("utf-8")
#endif

using namespace MathLib;

class CSysControlLocal : public CSysControl
{
public:
	CSysControlLocal();
    virtual ~CSysControlLocal();

	virtual void Init();	//ɫҪʼɫҪʼ
	virtual void Update(float ifps);
	virtual void Shutdown();

	virtual int GetState(int state);		//״̬״̬״̬ӵ״̬ȵȡ
	virtual int ClearState(int state);

	virtual float GetMouseDX();
	virtual float GetMouseDY();

	virtual void SetMouseGrab(int g);		//Ƿʾ
	virtual int GetMouseGrab();			//ȡ״̬ʾػǲʾ״̬

	virtual void SetControlMode(ControlMode mode);			//ģʽ
	virtual ControlMode GetControlMode() const;				//ȡģʽ

private:
	void Update_Mouse(float ifps);

}<|endoftext|>