<commit_before>/*******************************************************************************
 * Copyright (c) Nicola Del Gobbo
 * 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
 *
 * THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS
 * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY
 * IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
 * MERCHANTABLITY OR NON-INFRINGEMENT.
 *
 * See the Apache Version 2.0 License for specific language governing
 * permissions and limitations under the License.
 *
 * Contributors - initial API implementation:
 * Nicola Del Gobbo <nicoladelgobbo@gmail.com>
 ******************************************************************************/

#include "kvdb.h"
#include <iostream>
#include <sstream>

using namespace Napi;

/*class GetKeyWorker: public Napi::AsyncWorker {
  public:
    GetKeyWorker(Napi::FunctionReference *callback, vedis *db, std::string cmd )
      :AsyncWorker(callback), db(db), cmd(cmd) {}
    ~GetKeyWorker() {}

    void Execute() {
      int rc;
      rc = vedis_exec(db, cmd.c_str(), -1);
      if(rc != VEDIS_OK) {
        // Handle error
      }
      // Extract the return value of the last executed command (i.e. 'GET test') "
      vedis_value *result;
      vedis_exec_result(db, &result);
      //Cast the vedis object to a string
      value = vedis_value_to_string(result, 0);
    }

    void OnOK() {
      Napi::HandleScope();
      int argc = 2;
      Napi::Value argv[2];
      argv[0] = env.Null();
      argv[1] = Napi::New(env, value);
      callback->Call(argc, argv);
    }

  private:
    vedis *db;
    std::string cmd;
    const char *value;
};*/

class PutKeyWorker: public Napi::AsyncWorker {
  public:
    PutKeyWorker(Napi::FunctionReference *callback) : Napi::AsyncWorker(callback) {}
    ~PutKeyWorker() {}

    void Execute() {
      int rc;
      rc = vedis_exec(db, cmd.c_str(), -1);
      if(rc != VEDIS_OK) {
        // Handle error
      }
    }

    void OnOK() {
      /*Napi::HandleScope();
      int argc = 1;
      Napi::Value argv[1];
      argv[0] = env.Null();
      callback->Call(argc, argv);*/
    }

  private:
    vedis *db;
    std::string cmd;
};

/*void buffer_delete_callback(char* data, void* hint) {
  free(data);
}*/

/*class GetKeyBufferWorker: public Napi::AsyncWorker {
  public:
    GetKeyBufferWorker(Napi::FunctionReference *callback, vedis *db, std::string key)
      :AsyncWorker(callback), db(db), key(key) {}
    ~GetKeyBufferWorker() {}

    void Execute() {
      int rc;

      std::stringstream strlenCmd;
      strlenCmd << "STRLEN " + key;
      rc = vedis_exec(db, (strlenCmd.str()).c_str(), -1);
      if(rc != VEDIS_OK) {
        // Handle error
      }
      // Extract the return value of the last executed command (i.e. 'STRLEN test') "
      vedis_value *strlen_result;
      vedis_exec_result(db, &strlen_result);
      // Cast the vedis object to a string
      this->buffer_length = vedis_value_to_int(strlen_result);

      std::stringstream get_cmd;
      get_cmd << "GET " + key;
      rc = vedis_exec(db, (get_cmd.str()).c_str(), -1);
      if(rc != VEDIS_OK) {
        // Handle error
      }
      // Extract the return value of the last executed command (i.e. 'GET test') "
      vedis_value *get_result;
      vedis_exec_result(db, &get_result);
      // Cast the vedis object to a string
      this->buffer = static_cast<char *>(malloc(this->buffer_length));
      this->buffer = const_cast<char *>(vedis_value_to_string(get_result, 0));

    }

    void OnOK() {
      Napi::HandleScope();
      int argc = 2;
      Napi::Value argv[2];
      argv[0] = env.Null();
      // Error violation memory
      //argv[1] = Napi::Buffer<char>::New(env, this->buffer, this->buffer_length);
      // Not efficient solution
      //argv[1] = Napi::Buffer::Copy(env, this->buffer, this->buffer_length);
      Napi::Object data =
      Napi::Buffer<char>::New(env, this->buffer, this->buffer_length, buffer_delete_callback, this->buffer);
      argv[1] = data;
      callback->Call(argc, argv);
    }
  private:
    vedis *db;
    std::string key;
    char *buffer;
    int buffer_length;
};*/

/*class PutKeyBufferWorker: public Napi::AsyncWorker {
  public:
    PutKeyBufferWorker(Napi::FunctionReference *callback, vedis *db, std::string key, Napi::Object &value)
      :AsyncWorker(callback), db(db), key(key) {
        this->buffer = value.As<Napi::Buffer<char>>().Data();
        this->buffer_length = value.As<Napi::Buffer<char>>().Length();
      }
    ~PutKeyBufferWorker() {}

    void Execute() {
      int rc;
      //rc = vedis_exec(db, cmd.c_str(), -1);
      rc = vedis_kv_store(db, key.c_str(), -1, this->buffer, this->buffer_length);
      if(rc != VEDIS_OK) {
        // Handle error
        std::cout << "Error: " << rc;
      }
    }

    void OnOK() {
      Napi::HandleScope();
      int argc = 1;
      Napi::Value argv[1];
      argv[0] = env.Null();
      callback->Call(argc, argv);
    }

  private:
    vedis *db;
    std::string key;
    char *buffer;
    int buffer_length;
};*/

namespace KVDB {

  Napi::Object Database::Init(Napi::Env env, Napi::Object exports) {
    //Napi::FunctionReference tpl = Napi::Function::New(env, New);
    //tpl->SetClassName(Napi::String::New(env, "Database"));
    Napi::Function tpl = DefineClass(env, "Database", {
      InstanceMethod("getKeySync", &Database::GetKeySync),
      InstanceMethod("putKeySync", &Database::PutKeySync),
      InstanceAccessor("db_name", &Database::DbName, nullptr),
      InstanceMethod("getKey", &Database::GetKey),
      InstanceMethod("putKey", &Database::PutKey)
    });

      //InstanceMethod("getKeyBuffer", &GetKeyBuffer),
      //InstanceMethod("getKeySync", &GetKeySync),
      //InstanceMethod("putKey", &PutKey),
      //InstanceMethod("putKeyBuffer", &PutKeyBuffer),
      //InstanceMethod("putKeySync", &PutKeySync),
    // Only if you have accessor method
    //Local<ObjectTemplate> itpl = tpl->InstanceTemplate();
    //Napi::SetAccessor(itpl, Napi::String::New(env, "db_name"), DbName);
    //constructor().Reset(v8::Isolate::GetCurrent(), Napi::GetFunction(tpl));
    constructor = Napi::Persistent(tpl);
    constructor.SuppressDestruct();
    exports.Set("Database", tpl);
    return exports;
  }

  /*Napi::Value Database::GetKey(const Napi::CallbackInfo& info) {
      // Here we need some control
      Napi::String tmpKey(env, info[0].ToString());
      Napi::FunctionReference *callback = new Napi::FunctionReference(info[1].As<Napi::Function>());
      std::string key(*tmpKey);
      std::stringstream cmd;
      cmd << "GET " + key;
      KVDB::Database* database = ObjectWrap::Unwrap<KVDB::Database>(info.This());
      AsyncQueueWorker(new GetKeyWorker(callback, database->db, cmd.str()));
      return env.Undefined();
  }*/

  /*Napi::Value Database::GetKeyBuffer(const Napi::CallbackInfo& info) {
    // Here we need some control
    Napi::String tmpKey(env, info[0].ToString());
    Napi::FunctionReference *callback = new Napi::FunctionReference(info[1].As<Napi::Function>());
    std::string key(*tmpKey);
    //std::stringstream cmd;
    //cmd << "GET " + key;
    KVDB::Database* database = ObjectWrap::Unwrap<KVDB::Database>(info.This());
    AsyncQueueWorker(new GetKeyBufferWorker(callback, database->db, key));
    return env.Undefined();
  }*/

  Napi::Value Database::GetKeySync(const Napi::CallbackInfo& info) {
    // Here we need some control
    Napi::String tmpKey = info[0].As<Napi::String>();
    std::string  key =  tmpKey.ToString();
    std::stringstream cmd;
    cmd << "GET " + key;
    //KVDB::Database* database = ObjectWrap::Unwrap<KVDB::Database>(info.This());
    int rc;
    rc = vedis_exec(this->db, (cmd.str()).c_str(), -1);
    if(rc != VEDIS_OK) {
      // Handle error
    }
    // Extract the return value of the last executed command (i.e. 'GET test') "
    vedis_value *result;
    vedis_exec_result(this->db, &result);
    const char *value;
    // Cast the vedis object to a string
    value = vedis_value_to_string(result, 0);
    return Napi::String::New(info.Env(), value);
  }

  Napi::Value Database::PutKey(const Napi::CallbackInfo& info) {
    // Here we need some control
    Napi::String tmpKey = info[0].As<Napi::String>();
    std::string key = tmpKey.ToString();
    Napi::String tmpValue = info[1].As<Napi::String>();
    std::string value = tmpValue.ToString();
    std::stringstream cmd;
    cmd << "SET " + key + " '" + value + "'";
    Napi::Function callback = new Napi::Function(info[2].As<Napi::Function>());
    //KVDB::Database* database = ObjectWrap::Unwrap<KVDB::Database>(info.This());
    PutKeyWorker* work = new PutKeyWorker(callback);
    work->Queue();
    return info.Env().Undefined();
 }

  /*Napi::Value Database::PutKeyBuffer(const Napi::CallbackInfo& info) {
     // Here we need some control
     Napi::String tmpKey(env, info[0].ToString());
     std::string key(*tmpKey);
     //Napi::String tmpValue(env, info[1].ToString());
     //std::string value(*tmpValue);
     //std::stringstream cmd;
     //cmd << "SET " + key + " '" + value + "'";
     Napi::Object value = info[1].ToObject();
     Napi::FunctionReference *callback = new Napi::FunctionReference(info[2].As<Napi::Function>());
     KVDB::Database* database = ObjectWrap::Unwrap<KVDB::Database>(info.This());
     AsyncQueueWorker(new PutKeyBufferWorker(callback, database->db, key, value));
     return env.Undefined();
  }*/

  Napi::Value Database::PutKeySync(const Napi::CallbackInfo& info) {
    // Here we need some control
    Napi::String tmpKey = info[0].As<Napi::String>();
    std::string  key =  tmpKey.ToString();
    Napi::String tmpValue = info[1].As<Napi::String>();
    std::string value = tmpValue.ToString();
    std::stringstream cmd;
    cmd << "SET " + key + " '" + value + "'";
    //KVDB::Database* database = ObjectWrap::Unwrap<KVDB::Database>(info.This());
    int rc;
    rc = vedis_exec(this->db, (cmd.str()).c_str(), -1);
    if (rc != VEDIS_OK) {
      // Hanlde  error
    }
    return info.Env().Undefined();
  }

  Napi::Value Database::DbName(const Napi::CallbackInfo& info) {
    //KVDB::Database* database = ObjectWrap::Unwrap<KVDB::Database>(info.This());
    return Napi::String::New(info.Env(), this->db_name);
  }

  /*inline Persistent<v8::Function> & Database::constructor() {
    static Persistent<v8::Function> kvdb_constructor;
    return kvdb_constructor;
  }*/
  Napi::FunctionReference Database::constructor;

  Database::Database(const Napi::CallbackInfo& info) : Napi::ObjectWrap<Database>(info) {
    this->db_name = info[0].As<Napi::String>();
    std::stringstream db_path;
    db_path << root_path << "/" << db_name << db_extension;
    int rc;
    rc = vedis_open(&(this->db), (db_path.str()).c_str());
    //rc = vedis_open(&(this->db), NULL);
    int r;
    uv_fs_t req;
    r = uv_fs_mkdir(NULL, &req, root_path.c_str(), 0777, NULL);
    if (r != 0) {
      // Handle create root folder error
    }
    uv_fs_req_cleanup(&req);
    if (rc != VEDIS_OK) {
      // Hanlde the initialization error
    }
  }

  Database::~Database() {
    // NOOP
  }

}<commit_msg>Napi example async methods complete<commit_after>/*******************************************************************************
 * Copyright (c) Nicola Del Gobbo
 * 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
 *
 * THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS
 * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY
 * IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
 * MERCHANTABLITY OR NON-INFRINGEMENT.
 *
 * See the Apache Version 2.0 License for specific language governing
 * permissions and limitations under the License.
 *
 * Contributors - initial API implementation:
 * Nicola Del Gobbo <nicoladelgobbo@gmail.com>
 ******************************************************************************/

#include "kvdb.h"
#include <iostream>
#include <sstream>

using namespace Napi;

class GetKeyWorker: public Napi::AsyncWorker {
  public:
    GetKeyWorker(Napi::Function& callback, vedis *db, std::string cmd)
      :Napi::AsyncWorker(callback), db(db), cmd(cmd) {}
    ~GetKeyWorker() {}

    void Execute() {
      int rc;
      rc = vedis_exec(db, cmd.c_str(), -1);
      if(rc != VEDIS_OK) {
        // Handle error
      }
      // Extract the return value of the last executed command (i.e. 'GET test') "
      vedis_value *result;
      vedis_exec_result(db, &result);
      //Cast the vedis object to a string
      value = vedis_value_to_string(result, 0);
    }

    void OnOK() {
      Napi::HandleScope scope(Env());
      Callback().Call(Env().Global(), { Env().Null(), Napi::String::New(Env(), value) });
    }

  private:
    vedis *db;
    std::string cmd;
    const char *value;
};

class PutKeyWorker: public Napi::AsyncWorker {
  public:
    PutKeyWorker(Napi::Function& callback, vedis *db, std::string cmd)
      :Napi::AsyncWorker(callback), db(db), cmd(cmd) {}
    ~PutKeyWorker() {}

    void Execute() {
      int rc;
      rc = vedis_exec(db, cmd.c_str(), -1);
      if(rc != VEDIS_OK) {
        // Handle error
      }
    }

    void OnOK() {
      Napi::HandleScope scope(Env());
      Callback().Call(Env().Global(), { Env().Null() });
    }

  private:
    vedis *db;
    std::string cmd;
};

/*void buffer_delete_callback(char* data, void* hint) {
  free(data);
}*/

/*class GetKeyBufferWorker: public Napi::AsyncWorker {
  public:
    GetKeyBufferWorker(Napi::FunctionReference *callback, vedis *db, std::string key)
      :AsyncWorker(callback), db(db), key(key) {}
    ~GetKeyBufferWorker() {}

    void Execute() {
      int rc;

      std::stringstream strlenCmd;
      strlenCmd << "STRLEN " + key;
      rc = vedis_exec(db, (strlenCmd.str()).c_str(), -1);
      if(rc != VEDIS_OK) {
        // Handle error
      }
      // Extract the return value of the last executed command (i.e. 'STRLEN test') "
      vedis_value *strlen_result;
      vedis_exec_result(db, &strlen_result);
      // Cast the vedis object to a string
      this->buffer_length = vedis_value_to_int(strlen_result);

      std::stringstream get_cmd;
      get_cmd << "GET " + key;
      rc = vedis_exec(db, (get_cmd.str()).c_str(), -1);
      if(rc != VEDIS_OK) {
        // Handle error
      }
      // Extract the return value of the last executed command (i.e. 'GET test') "
      vedis_value *get_result;
      vedis_exec_result(db, &get_result);
      // Cast the vedis object to a string
      this->buffer = static_cast<char *>(malloc(this->buffer_length));
      this->buffer = const_cast<char *>(vedis_value_to_string(get_result, 0));

    }

    void OnOK() {
      Napi::HandleScope();
      int argc = 2;
      Napi::Value argv[2];
      argv[0] = env.Null();
      // Error violation memory
      //argv[1] = Napi::Buffer<char>::New(env, this->buffer, this->buffer_length);
      // Not efficient solution
      //argv[1] = Napi::Buffer::Copy(env, this->buffer, this->buffer_length);
      Napi::Object data =
      Napi::Buffer<char>::New(env, this->buffer, this->buffer_length, buffer_delete_callback, this->buffer);
      argv[1] = data;
      callback->Call(argc, argv);
    }
  private:
    vedis *db;
    std::string key;
    char *buffer;
    int buffer_length;
};*/

/*class PutKeyBufferWorker: public Napi::AsyncWorker {
  public:
    PutKeyBufferWorker(Napi::FunctionReference *callback, vedis *db, std::string key, Napi::Object &value)
      :AsyncWorker(callback), db(db), key(key) {
        this->buffer = value.As<Napi::Buffer<char>>().Data();
        this->buffer_length = value.As<Napi::Buffer<char>>().Length();
      }
    ~PutKeyBufferWorker() {}

    void Execute() {
      int rc;
      //rc = vedis_exec(db, cmd.c_str(), -1);
      rc = vedis_kv_store(db, key.c_str(), -1, this->buffer, this->buffer_length);
      if(rc != VEDIS_OK) {
        // Handle error
        std::cout << "Error: " << rc;
      }
    }

    void OnOK() {
      Napi::HandleScope();
      int argc = 1;
      Napi::Value argv[1];
      argv[0] = env.Null();
      callback->Call(argc, argv);
    }

  private:
    vedis *db;
    std::string key;
    char *buffer;
    int buffer_length;
};*/

namespace KVDB {

  Napi::Object Database::Init(Napi::Env env, Napi::Object exports) {
    Napi::Function tpl = DefineClass(env, "Database", {
      InstanceMethod("getKeySync", &Database::GetKeySync),
      InstanceMethod("putKeySync", &Database::PutKeySync),
      InstanceAccessor("db_name", &Database::DbName, nullptr),
      InstanceMethod("getKey", &Database::GetKey),
      InstanceMethod("putKey", &Database::PutKey)
    });

    //InstanceMethod("getKeyBuffer", &GetKeyBuffer),

    //InstanceMethod("putKeyBuffer", &PutKeyBuffer),

    constructor = Napi::Persistent(tpl);
    constructor.SuppressDestruct();
    exports.Set("Database", tpl);
    return exports;
  }

  Napi::Value Database::GetKey(const Napi::CallbackInfo& info) {
      // Here we need some control
      Napi::String tmpKey = info[0].As<Napi::String>();
      std::string key = tmpKey.ToString();
      std::stringstream cmd;
      cmd << "GET " + key;
      Napi::Function callback = info[2].As<Napi::Function>();
      GetKeyWorker* work = new GetKeyWorker(callback, this->db, cmd.str());
      work->Queue();
      return info.Env().Undefined();
  }

  /*Napi::Value Database::GetKeyBuffer(const Napi::CallbackInfo& info) {
    // Here we need some control
    Napi::String tmpKey(env, info[0].ToString());
    Napi::FunctionReference *callback = new Napi::FunctionReference(info[1].As<Napi::Function>());
    std::string key(*tmpKey);
    //std::stringstream cmd;
    //cmd << "GET " + key;
    KVDB::Database* database = ObjectWrap::Unwrap<KVDB::Database>(info.This());
    AsyncQueueWorker(new GetKeyBufferWorker(callback, database->db, key));
    return env.Undefined();
  }*/

  Napi::Value Database::GetKeySync(const Napi::CallbackInfo& info) {
    // Here we need some control
    Napi::String tmpKey = info[0].As<Napi::String>();
    std::string  key =  tmpKey.ToString();
    std::stringstream cmd;
    cmd << "GET " + key;
    //KVDB::Database* database = ObjectWrap::Unwrap<KVDB::Database>(info.This());
    int rc;
    rc = vedis_exec(this->db, (cmd.str()).c_str(), -1);
    if(rc != VEDIS_OK) {
      // Handle error
    }
    // Extract the return value of the last executed command (i.e. 'GET test') "
    vedis_value *result;
    vedis_exec_result(this->db, &result);
    const char *value;
    // Cast the vedis object to a string
    value = vedis_value_to_string(result, 0);
    return Napi::String::New(info.Env(), value);
  }

  Napi::Value Database::PutKey(const Napi::CallbackInfo& info) {
    // Here we need some control
    Napi::String tmpKey = info[0].As<Napi::String>();
    std::string key = tmpKey.ToString();
    Napi::String tmpValue = info[1].As<Napi::String>();
    std::string value = tmpValue.ToString();
    std::stringstream cmd;
    cmd << "SET " + key + " '" + value + "'";
    Napi::Function callback = info[2].As<Napi::Function>();
    PutKeyWorker* work = new PutKeyWorker(callback, this->db, cmd.str());
    work->Queue();
    return info.Env().Undefined();
 }

  /*Napi::Value Database::PutKeyBuffer(const Napi::CallbackInfo& info) {
     // Here we need some control
     Napi::String tmpKey(env, info[0].ToString());
     std::string key(*tmpKey);
     //Napi::String tmpValue(env, info[1].ToString());
     //std::string value(*tmpValue);
     //std::stringstream cmd;
     //cmd << "SET " + key + " '" + value + "'";
     Napi::Object value = info[1].ToObject();
     Napi::FunctionReference *callback = new Napi::FunctionReference(info[2].As<Napi::Function>());
     KVDB::Database* database = ObjectWrap::Unwrap<KVDB::Database>(info.This());
     AsyncQueueWorker(new PutKeyBufferWorker(callback, database->db, key, value));
     return env.Undefined();
  }*/

  Napi::Value Database::PutKeySync(const Napi::CallbackInfo& info) {
    // Here we need some control
    Napi::String tmpKey = info[0].As<Napi::String>();
    std::string  key =  tmpKey.ToString();
    Napi::String tmpValue = info[1].As<Napi::String>();
    std::string value = tmpValue.ToString();
    std::stringstream cmd;
    cmd << "SET " + key + " '" + value + "'";
    int rc;
    rc = vedis_exec(this->db, (cmd.str()).c_str(), -1);
    if (rc != VEDIS_OK) {
      // Hanlde  error
    }
    return info.Env().Undefined();
  }

  Napi::Value Database::DbName(const Napi::CallbackInfo& info) {
    return Napi::String::New(info.Env(), this->db_name);
  }

  Napi::FunctionReference Database::constructor;

  Database::Database(const Napi::CallbackInfo& info) : Napi::ObjectWrap<Database>(info) {
    this->db_name = info[0].As<Napi::String>();
    std::stringstream db_path;
    db_path << root_path << "/" << db_name << db_extension;
    int rc;
    rc = vedis_open(&(this->db), (db_path.str()).c_str());
    //rc = vedis_open(&(this->db), NULL);
    int r;
    uv_fs_t req;
    r = uv_fs_mkdir(NULL, &req, root_path.c_str(), 0777, NULL);
    if (r != 0) {
      // Handle create root folder error
    }
    uv_fs_req_cleanup(&req);
    if (rc != VEDIS_OK) {
      // Hanlde the initialization error
    }
  }

  Database::~Database() {
    // NOOP
  }

}<|endoftext|>


<commit_before>/*
Copyright (c) 2015-2016 Advanced Micro Devices, Inc. All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

/* HIT_START
 * BUILD: %t %s ../../test_common.cpp
 * RUN: %t
 * HIT_END
 */

#include "test_common.h"

enum SyncMode {
    syncNone,
    syncNullStream,
    syncOtherStream,
    syncMarkerThenOtherStream,
    syncMarkerThenOtherNonBlockingStream,
    syncDevice
};

const char* syncModeString(int syncMode) {
    switch (syncMode) {
        case syncNone:
            return "syncNone";
        case syncNullStream:
            return "syncNullStream";
        case syncOtherStream:
            return "syncOtherStream";
        case syncMarkerThenOtherStream:
            return "syncMarkerThenOtherStream";
        case syncMarkerThenOtherNonBlockingStream:
            return "syncMarkerThenOtherNonBlockingStream";
        case syncDevice:
            return "syncDevice";
        default:
            return "unknown";
    };
};

void test(unsigned testMask, int* C_d, int* C_h, int64_t numElements, SyncMode syncMode,
          bool expectMismatch) {
    // This test sends a long-running kernel to the null stream, then tests to see if the
    // specified synchronization technique is effective.
    //
    // Some syncMode are not expected to correctly sync (for example "syncNone").  in these
    // cases the test sets expectMismatch and the check logic below will attempt to ensure that
    // the undesired synchronization did not occur - ie ensure the kernel is still running and did
    // not yet update the stop event.  This can be tricky since if the kernel runs fast enough it
    // may complete before the check.  To prevent this, the addCountReverse has a count parameter
    // which causes it to loop repeatedly, and the results are checked in reverse order.
    //
    // Tests with expectMismatch=true should ensure the kernel finishes correctly. This results
    // are checked and we test to make sure stop event has completed.

    if (!(testMask & p_tests)) {
        return;
    }
    printf("\ntest 0x%02x: syncMode=%s expectMismatch=%d\n", testMask, syncModeString(syncMode),
           expectMismatch);

    size_t sizeBytes = numElements * sizeof(int);

    int count = 100;
    int init0 = 0;
    HIPCHECK(hipMemset(C_d, init0, sizeBytes));
    for (int i = 0; i < numElements; i++) {
        C_h[i] = -1;  // initialize
    }

    hipStream_t otherStream = 0;
    unsigned flags = (syncMode == syncMarkerThenOtherNonBlockingStream) ? hipStreamNonBlocking
                                                                        : hipStreamDefault;
    HIPCHECK(hipStreamCreateWithFlags(&otherStream, flags));
    hipEvent_t stop, otherStreamEvent;
    HIPCHECK(hipEventCreate(&stop));
    HIPCHECK(hipEventCreate(&otherStreamEvent));

    unsigned blocks = HipTest::setNumBlocks(blocksPerCU, threadsPerBlock, numElements);
    // Launch kernel into null stream, should result in C_h == count.
    hipLaunchKernelGGL(HipTest::addCountReverse, dim3(blocks), dim3(threadsPerBlock), 0,
                       0 /*stream*/, static_cast<const int*>(C_d), C_h, numElements, count);
    HIPCHECK(hipEventRecord(stop, 0 /*default*/));

    switch (syncMode) {
        case syncNone:
            break;
        case syncNullStream:
            HIPCHECK(hipStreamSynchronize(0));  // wait on host for null stream:
            break;
        case syncOtherStream:
            // Does this synchronize with the null stream?
            HIPCHECK(hipStreamSynchronize(otherStream));
            break;
        case syncMarkerThenOtherStream:
        case syncMarkerThenOtherNonBlockingStream:

            // this may wait for NULL stream depending hipStreamNonBlocking flag above
            HIPCHECK(hipEventRecord(otherStreamEvent, otherStream));

            HIPCHECK(hipStreamSynchronize(otherStream));
            break;
        case syncDevice:
            HIPCHECK(hipDeviceSynchronize());
            break;
        default:
            assert(0);
    };

    hipError_t done = hipEventQuery(stop);

    if (expectMismatch) {
        assert(done == hipErrorNotReady);
    } else {
        assert(done == hipSuccess);
    }

    int mismatches = 0;
    int expected = init0 + count;
    for (int i = 0; i < numElements; i++) {
        bool compareEqual = (C_h[i] == expected);
        if (!compareEqual) {
            mismatches++;
            if (!expectMismatch) {
                printf("C_h[%d] (%d) != %d\n", i, C_h[i], expected);
                assert(C_h[i] == expected);
            }
        }
    }

    if (expectMismatch) {
        assert(mismatches > 0);
    }

    HIPCHECK(hipStreamDestroy(otherStream));
    HIPCHECK(hipEventDestroy(stop));
    HIPCHECK(hipEventDestroy(otherStreamEvent));

    HIPCHECK(hipDeviceSynchronize());

    printf("test:   OK - %d mismatches (%6.2f%%)\n", mismatches,
           ((double)(mismatches)*100.0) / numElements);
}

void runTests(int64_t numElements) {
    size_t sizeBytes = numElements * sizeof(int);

    printf("\n\ntest: starting sequence with sizeBytes=%zu bytes, %6.2f MB\n", sizeBytes,
           sizeBytes / 1024.0 / 1024.0);

    int *C_h, *C_d;
    HIPCHECK(hipMalloc(&C_d, sizeBytes));
    HIPCHECK(hipHostMalloc(&C_h, sizeBytes));

    {
        test(0x01, C_d, C_h, numElements, syncNone, true /*expectMismatch*/);
        test(0x02, C_d, C_h, numElements, syncNullStream, false /*expectMismatch*/);
        test(0x04, C_d, C_h, numElements, syncOtherStream, false /*expectMismatch*/);
        test(0x08, C_d, C_h, numElements, syncDevice, false /*expectMismatch*/);

        // Sending a marker to to null stream may synchronize the otherStream
        //  - other created with hipStreamNonBlocking=0 : synchronization, should match
        //  - other created with hipStreamNonBlocking=1 : no synchronization, may mismatch
        test(0x10, C_d, C_h, numElements, syncMarkerThenOtherStream, false /*expectMismatch*/);

        // TODO - review why this test seems flaky
        // test (0x20, C_d, C_h, numElements,  syncMarkerThenOtherNonBlockingStream, true
        // /*expectMismatch*/);
    }

    HIPCHECK(hipFree(C_d));
    HIPCHECK(hipHostFree(C_h));
}

int main(int argc, char* argv[]) {
    // Can' destroy the default stream:// TODO - move to another test
    HIPCHECK_API(hipStreamDestroy(0), hipErrorInvalidResourceHandle);

    HipTest::parseStandardArguments(argc, argv, true /*failOnUndefinedArg*/);

    runTests(40000000);

    passed();
}
<commit_msg>Revert changes to runtime/stream/hipStreamSync2<commit_after>/*
Copyright (c) 2015-2016 Advanced Micro Devices, Inc. All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

/* HIT_START
 * BUILD: %t %s ../../test_common.cpp
 * RUN: %t
 * HIT_END
 */

#include "test_common.h"

enum SyncMode {
    syncNone,
    syncNullStream,
    syncOtherStream,
    syncMarkerThenOtherStream,
    syncMarkerThenOtherNonBlockingStream,
    syncDevice
};

const char* syncModeString(int syncMode) {
    switch (syncMode) {
        case syncNone:
            return "syncNone";
        case syncNullStream:
            return "syncNullStream";
        case syncOtherStream:
            return "syncOtherStream";
        case syncMarkerThenOtherStream:
            return "syncMarkerThenOtherStream";
        case syncMarkerThenOtherNonBlockingStream:
            return "syncMarkerThenOtherNonBlockingStream";
        case syncDevice:
            return "syncDevice";
        default:
            return "unknown";
    };
};

void test(unsigned testMask, int* C_d, int* C_h, int64_t numElements, SyncMode syncMode,
          bool expectMismatch) {
    // This test sends a long-running kernel to the null stream, then tests to see if the
    // specified synchronization technique is effective.
    //
    // Some syncMode are not expected to correctly sync (for example "syncNone").  in these
    // cases the test sets expectMismatch and the check logic below will attempt to ensure that
    // the undesired synchronization did not occur - ie ensure the kernel is still running and did
    // not yet update the stop event.  This can be tricky since if the kernel runs fast enough it
    // may complete before the check.  To prevent this, the addCountReverse has a count parameter
    // which causes it to loop repeatedly, and the results are checked in reverse order.
    //
    // Tests with expectMismatch=true should ensure the kernel finishes correctly. This results
    // are checked and we test to make sure stop event has completed.

    if (!(testMask & p_tests)) {
        return;
    }
    printf("\ntest 0x%02x: syncMode=%s expectMismatch=%d\n", testMask, syncModeString(syncMode),
           expectMismatch);

    size_t sizeBytes = numElements * sizeof(int);

    int count = 100;
    int init0 = 0;
    HIPCHECK(hipMemset(C_d, init0, sizeBytes));
    for (int i = 0; i < numElements; i++) {
        C_h[i] = -1;  // initialize
    }

    hipStream_t otherStream = 0;
    unsigned flags = (syncMode == syncMarkerThenOtherNonBlockingStream) ? hipStreamNonBlocking
                                                                        : hipStreamDefault;
    HIPCHECK(hipStreamCreateWithFlags(&otherStream, flags));
    hipEvent_t stop, otherStreamEvent;
    HIPCHECK(hipEventCreate(&stop));
    HIPCHECK(hipEventCreate(&otherStreamEvent));

    unsigned blocks = HipTest::setNumBlocks(blocksPerCU, threadsPerBlock, numElements);
    // Launch kernel into null stream, should result in C_h == count.
    hipLaunchKernelGGL(HipTest::addCountReverse, dim3(blocks), dim3(threadsPerBlock), 0,
                       0 /*stream*/, static_cast<const int*>(C_d), C_h, numElements, count);
    HIPCHECK(hipEventRecord(stop, 0 /*default*/));

    switch (syncMode) {
        case syncNone:
            break;
        case syncNullStream:
            HIPCHECK(hipStreamSynchronize(0));  // wait on host for null stream:
            break;
        case syncOtherStream:
            // Does this synchronize with the null stream?
            HIPCHECK(hipStreamSynchronize(otherStream));
            break;
        case syncMarkerThenOtherStream:
        case syncMarkerThenOtherNonBlockingStream:

            // this may wait for NULL stream depending hipStreamNonBlocking flag above
            HIPCHECK(hipEventRecord(otherStreamEvent, otherStream));

            HIPCHECK(hipStreamSynchronize(otherStream));
            break;
        case syncDevice:
            HIPCHECK(hipDeviceSynchronize());
            break;
        default:
            assert(0);
    };

    hipError_t done = hipEventQuery(stop);

    if (expectMismatch) {
        assert(done == hipErrorNotReady);
    } else {
        assert(done == hipSuccess);
    }

    int mismatches = 0;
    int expected = init0 + count;
    for (int i = 0; i < numElements; i++) {
        bool compareEqual = (C_h[i] == expected);
        if (!compareEqual) {
            mismatches++;
            if (!expectMismatch) {
                printf("C_h[%d] (%d) != %d\n", i, C_h[i], expected);
                assert(C_h[i] == expected);
            }
        }
    }

    if (expectMismatch) {
        assert(mismatches > 0);
    }

    HIPCHECK(hipStreamDestroy(otherStream));
    HIPCHECK(hipEventDestroy(stop));
    HIPCHECK(hipEventDestroy(otherStreamEvent));

    HIPCHECK(hipDeviceSynchronize());

    printf("test:   OK - %d mismatches (%6.2f%%)\n", mismatches,
           ((double)(mismatches)*100.0) / numElements);
}

void runTests(int64_t numElements) {
    size_t sizeBytes = numElements * sizeof(int);

    printf("\n\ntest: starting sequence with sizeBytes=%zu bytes, %6.2f MB\n", sizeBytes,
           sizeBytes / 1024.0 / 1024.0);

    int *C_h, *C_d;
    HIPCHECK(hipMalloc(&C_d, sizeBytes));
    HIPCHECK(hipHostMalloc(&C_h, sizeBytes));

    {
        test(0x01, C_d, C_h, numElements, syncNone, true /*expectMismatch*/);
        test(0x02, C_d, C_h, numElements, syncNullStream, false /*expectMismatch*/);
        test(0x04, C_d, C_h, numElements, syncOtherStream, true /*expectMismatch*/);
        test(0x08, C_d, C_h, numElements, syncDevice, false /*expectMismatch*/);

        // Sending a marker to to null stream may synchronize the otherStream
        //  - other created with hipStreamNonBlocking=0 : synchronization, should match
        //  - other created with hipStreamNonBlocking=1 : no synchronization, may mismatch
        test(0x10, C_d, C_h, numElements, syncMarkerThenOtherStream, false /*expectMismatch*/);

        // TODO - review why this test seems flaky
        // test (0x20, C_d, C_h, numElements,  syncMarkerThenOtherNonBlockingStream, true
        // /*expectMismatch*/);
    }

    HIPCHECK(hipFree(C_d));
    HIPCHECK(hipHostFree(C_h));
}

int main(int argc, char* argv[]) {
    // Can' destroy the default stream:// TODO - move to another test
    HIPCHECK_API(hipStreamDestroy(0), hipErrorInvalidResourceHandle);

    HipTest::parseStandardArguments(argc, argv, true /*failOnUndefinedArg*/);

    runTests(40000000);

    passed();
}
<|endoftext|>


<commit_before>#include "application.hpp"

#include "messageBus\receiver.hpp"

//Include states
#include "modules/states/state.hpp"
#include "modules/states/intro.hpp"
#include "modules/states/menu.hpp"
#include "modules/states/game.hpp"

namespace aw
{

	Application::Application() :
		m_settings(m_messageBus), m_windowHandler(m_messageBus)
	{
		//Init Statemachine
		m_stateMachine.addState("intro", std::unique_ptr<State>(new Intro(m_stateMachine)));
		m_stateMachine.addState("menu", std::unique_ptr<State>(new Menu(m_stateMachine, m_messageBus)));
		m_stateMachine.addState("game", std::unique_ptr<State>(new Game(m_stateMachine, m_messageBus)));

		//Set intro as active State
		m_stateMachine.changeActiveState("menu");

		//Load settings afterwards, because it will send informations to the states
		//Sound, window settings
		m_settings.load();
	}

	int Application::run()
	{
		while (m_windowHandler.getWindow().isOpen())
		{
			//Update the frameTimer
			m_frameTime = m_frameTimer.restart();

			//Check for Events (Will send them to the MessageBus)
			m_windowHandler.checkEventQueue();

			//Update active State
			m_stateMachine.update(m_frameTime);

			//Clear the rendertarget
			m_windowHandler.getWindow().clear();

			//Draw active State
			m_stateMachine.render(m_windowHandler.getWindow());

			//Display frame
			m_windowHandler.getWindow().display();
		}

		m_settings.save();
		return 0;
	}

}<commit_msg>Added std::cin.get() before the main return<commit_after>#include "application.hpp"

#include <iostream>

#include "messageBus\receiver.hpp"

//Include states
#include "modules/states/state.hpp"
#include "modules/states/intro.hpp"
#include "modules/states/menu.hpp"
#include "modules/states/game.hpp"

namespace aw
{

	Application::Application() :
		m_settings(m_messageBus), m_windowHandler(m_messageBus)
	{
		//Init Statemachine
		m_stateMachine.addState("intro", std::unique_ptr<State>(new Intro(m_stateMachine)));
		m_stateMachine.addState("menu", std::unique_ptr<State>(new Menu(m_stateMachine, m_messageBus)));
		m_stateMachine.addState("game", std::unique_ptr<State>(new Game(m_stateMachine, m_messageBus)));

		//Set intro as active State
		m_stateMachine.changeActiveState("menu");

		//Load settings afterwards, because it will send informations to the states
		//Sound, window settings
		m_settings.load();
	}

	int Application::run()
	{
		while (m_windowHandler.getWindow().isOpen())
		{
			//Update the frameTimer
			m_frameTime = m_frameTimer.restart();

			//Check for Events (Will send them to the MessageBus)
			m_windowHandler.checkEventQueue();

			//Update active State
			m_stateMachine.update(m_frameTime);

			//Clear the rendertarget
			m_windowHandler.getWindow().clear();

			//Draw active State
			m_stateMachine.render(m_windowHandler.getWindow());

			//Display frame
			m_windowHandler.getWindow().display();
		}

		m_settings.save();
		std::cin.get();
		return 0;
	}

}<|endoftext|>


<commit_before>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "views/controls/native/native_view_host_gtk.h"

#include <gtk/gtk.h>
#include <algorithm>

#include "base/logging.h"
#include "views/controls/native/native_view_host.h"
#include "views/focus/focus_manager.h"
#include "views/widget/widget_gtk.h"

namespace views {

namespace {
static bool signal_id_initialized_ = false;
static guint focus_in_event_signal_id_;
static guint focus_out_event_signal_id_;

////////////////////////////////////////////////////////////////////////////////
// Utility functions to block focus signals while re-creating
// Fixed widget.

void InitSignalIds() {
  if (!signal_id_initialized_) {
    signal_id_initialized_ = true;
    focus_in_event_signal_id_ =
        g_signal_lookup("focus-in-event", GTK_TYPE_WIDGET);
    focus_out_event_signal_id_ =
        g_signal_lookup("focus-out-event", GTK_TYPE_WIDGET);
  }
}

// Blocks a |signal_id| on the given |widget| if any.
void BlockSignal(GtkWidget* widget, guint signal_id) {
  int handler_id = g_signal_handler_find(G_OBJECT(widget),
                                         G_SIGNAL_MATCH_ID,
                                         signal_id,
                                         0, NULL, NULL, NULL);
  if (handler_id) {
    g_signal_handler_block(G_OBJECT(widget), handler_id);
  }
}

// Unblocks a |signal_id| on the given |widget| if any.
void UnblockSignal(GtkWidget* widget, guint signal_id) {
  int handler_id = g_signal_handler_find(G_OBJECT(widget),
                                         G_SIGNAL_MATCH_ID,
                                         signal_id,
                                         0, NULL, NULL, NULL);
  if (handler_id) {
    g_signal_handler_unblock(G_OBJECT(widget), handler_id);
  }
}

// Blocks focus in/out signals of the widget and its descendent
// children.
// Note: Due to the limiation of Gtk API, this only blocks the 1st
// handler found and won't block the rest if there is more than one handlers.
// See bug http://crbug.com/33236.
void BlockFocusSignals(GtkWidget* widget, gpointer data) {
  if (!widget)
    return;
  InitSignalIds();
  BlockSignal(widget, focus_in_event_signal_id_);
  BlockSignal(widget, focus_out_event_signal_id_);
  if (GTK_IS_CONTAINER(widget))
    gtk_container_foreach(GTK_CONTAINER(widget), BlockFocusSignals, data);
}

// Unlocks focus in/out signals of the widget and its descendent children.
void UnblockFocusSignals(GtkWidget* widget, gpointer data) {
  if (!widget)
    return;
  InitSignalIds();
  UnblockSignal(widget, focus_in_event_signal_id_);
  UnblockSignal(widget, focus_out_event_signal_id_);
  if (GTK_IS_CONTAINER(widget))
    gtk_container_foreach(GTK_CONTAINER(widget), UnblockFocusSignals, data);
}

}  // namespace

////////////////////////////////////////////////////////////////////////////////
// NativeViewHostGtk, public:

NativeViewHostGtk::NativeViewHostGtk(NativeViewHost* host)
    : host_(host),
      installed_clip_(false),
      destroy_signal_id_(0),
      focus_signal_id_(0),
      fixed_(NULL) {
  CreateFixed(false);
}

NativeViewHostGtk::~NativeViewHostGtk() {
  if (fixed_)
    gtk_widget_destroy(fixed_);
}

////////////////////////////////////////////////////////////////////////////////
// NativeViewHostGtk, NativeViewHostWrapper implementation:

void NativeViewHostGtk::NativeViewAttached() {
  DCHECK(host_->native_view());
  if (gtk_widget_get_parent(host_->native_view()))
    gtk_widget_reparent(host_->native_view(), fixed_);
  else
    gtk_container_add(GTK_CONTAINER(fixed_), host_->native_view());

  if (!destroy_signal_id_) {
    destroy_signal_id_ = g_signal_connect(host_->native_view(),
                                          "destroy", G_CALLBACK(CallDestroy),
                                          this);
  }

  if (!focus_signal_id_) {
    focus_signal_id_ = g_signal_connect(host_->native_view(),
                                        "focus-in-event",
                                        G_CALLBACK(CallFocusIn), this);
  }

  // Always layout though.
  host_->Layout();

  // We own the native view as long as it's attached, so that we can safely
  // reparent it in multiple passes.
  gtk_widget_ref(host_->native_view());

  // TODO(port): figure out focus.
}

void NativeViewHostGtk::NativeViewDetaching(bool destroyed) {
  DCHECK(host_->native_view());

  g_signal_handler_disconnect(G_OBJECT(host_->native_view()),
                              destroy_signal_id_);
  destroy_signal_id_ = 0;

  g_signal_handler_disconnect(G_OBJECT(host_->native_view()),
                              focus_signal_id_);
  focus_signal_id_ = 0;

  installed_clip_ = false;

  if (fixed_ && !destroyed) {
    DCHECK_NE(static_cast<gfx::NativeView>(NULL),
              gtk_widget_get_parent(host_->native_view()));
    gtk_container_remove(GTK_CONTAINER(fixed_), host_->native_view());
    DCHECK_EQ(
        0U, g_list_length(gtk_container_get_children(GTK_CONTAINER(fixed_))));
  }

  g_object_unref(G_OBJECT(host_->native_view()));
}

void NativeViewHostGtk::AddedToWidget() {
  if (!fixed_)
    CreateFixed(false);
  if (gtk_widget_get_parent(fixed_))
    GetHostWidget()->ReparentChild(fixed_);
  else
    GetHostWidget()->AddChild(fixed_);

  if (!host_->native_view())
    return;

  if (gtk_widget_get_parent(host_->native_view()))
    gtk_widget_reparent(host_->native_view(), fixed_);
  else
    gtk_container_add(GTK_CONTAINER(fixed_), host_->native_view());

  if (host_->IsVisibleInRootView())
    gtk_widget_show(fixed_);
  else
    gtk_widget_hide(fixed_);
  host_->Layout();
}

void NativeViewHostGtk::RemovedFromWidget() {
  if (!host_->native_view())
    return;

  DestroyFixed();
}

void NativeViewHostGtk::InstallClip(int x, int y, int w, int h) {
  DCHECK(w > 0 && h > 0);
  installed_clip_bounds_.SetRect(x, y, w, h);
  installed_clip_ = true;

  // We only re-create the fixed with a window when a cliprect is installed.
  // Because the presence of a X Window will prevent transparency from working
  // properly, we only want it to be active for the duration of a clip
  // (typically during animations and scrolling.)
  CreateFixed(true);
}

bool NativeViewHostGtk::HasInstalledClip() {
  return installed_clip_;
}

void NativeViewHostGtk::UninstallClip() {
  installed_clip_ = false;
  // We now re-create the fixed without a X Window so transparency works again.
  CreateFixed(false);
}

void NativeViewHostGtk::ShowWidget(int x, int y, int w, int h) {
  // x and y are the desired position of host_ in WidgetGtk coordinates.
  int fixed_x = x;
  int fixed_y = y;
  int fixed_w = w;
  int fixed_h = h;
  int child_x = 0;
  int child_y = 0;
  int child_w = w;
  int child_h = h;
  if (installed_clip_) {
    child_x = -installed_clip_bounds_.x();
    child_y = -installed_clip_bounds_.y();
    fixed_x += -child_x;
    fixed_y += -child_y;
    fixed_w = std::min(installed_clip_bounds_.width(), w);
    fixed_h = std::min(installed_clip_bounds_.height(), h);
  }

  // Size and place the fixed_.
  GetHostWidget()->PositionChild(fixed_, fixed_x, fixed_y, fixed_w, fixed_h);

  // Size and place the hosted NativeView.
  gtk_widget_set_size_request(host_->native_view(), child_w, child_h);
  gtk_fixed_move(GTK_FIXED(fixed_), host_->native_view(), child_x, child_y);

  gtk_widget_show(fixed_);
  gtk_widget_show(host_->native_view());
}

void NativeViewHostGtk::HideWidget() {
  gtk_widget_hide(fixed_);
}

void NativeViewHostGtk::SetFocus() {
  DCHECK(host_->native_view());
  gtk_widget_grab_focus(host_->native_view());
}

////////////////////////////////////////////////////////////////////////////////
// NativeViewHostGtk, private:

void NativeViewHostGtk::CreateFixed(bool needs_window) {
  GtkWidget* focused_widget = GetFocusedDescendant();

  // We move focus around and do not want focus events to be emitted
  // during this process.
  BlockFocusSignals(GetHostWidget()->GetNativeView(), NULL);

  if (focused_widget) {
    // A descendant of our fixed has focus. When we destroy the fixed focus is
    // automatically moved. Temporarily move focus to our host widget, then
    // restore focus after we create the new fixed_. This way focus hasn't
    // really moved.
    gtk_widget_grab_focus(GetHostWidget()->GetNativeView());
  }

  DestroyFixed();

  fixed_ = gtk_fixed_new();
  gtk_fixed_set_has_window(GTK_FIXED(fixed_), needs_window);
  // Defeat refcounting. We need to own the fixed.
  gtk_widget_ref(fixed_);

  WidgetGtk* widget_gtk = GetHostWidget();
  if (widget_gtk)
    widget_gtk->AddChild(fixed_);

  if (host_->native_view())
    gtk_container_add(GTK_CONTAINER(fixed_), host_->native_view());

  if (widget_gtk && host_->native_view() && focused_widget) {
    gtk_widget_grab_focus(focused_widget);
  }
  UnblockFocusSignals(GetHostWidget()->GetNativeView(), NULL);
}

void NativeViewHostGtk::DestroyFixed() {
  if (!fixed_)
    return;

  gtk_widget_hide(fixed_);
  GetHostWidget()->RemoveChild(fixed_);

  if (host_->native_view()) {
    // We can safely remove the widget from its container since we own the
    // widget from the moment it is attached.
    gtk_container_remove(GTK_CONTAINER(fixed_), host_->native_view());
  }
  // fixed_ should not have any children this point.
  DCHECK_EQ(0U,
            g_list_length(gtk_container_get_children(GTK_CONTAINER(fixed_))));
  gtk_widget_destroy(fixed_);
  fixed_ = NULL;
}

WidgetGtk* NativeViewHostGtk::GetHostWidget() const {
  return static_cast<WidgetGtk*>(host_->GetWidget());
}

GtkWidget* NativeViewHostGtk::GetFocusedDescendant() {
  if (!fixed_)
    return NULL;
  WidgetGtk* host = GetHostWidget();
  if (!host)
    return NULL;
  GtkWidget* top_level = gtk_widget_get_toplevel(host->GetNativeView());
  if (!top_level || !GTK_IS_WINDOW(top_level))
    return NULL;
  GtkWidget* focused = gtk_window_get_focus(GTK_WINDOW(top_level));
  if (!focused)
    return NULL;
  return (focused == fixed_ || gtk_widget_is_ancestor(focused, fixed_)) ?
      focused : NULL;
}

// static
void NativeViewHostGtk::CallDestroy(GtkObject* object,
                                    NativeViewHostGtk* host) {
  host->host_->NativeViewDestroyed();
}

// static
void NativeViewHostGtk::CallFocusIn(GtkWidget* widget,
                                    GdkEventFocus* event,
                                    NativeViewHostGtk* host) {
  FocusManager* focus_manager =
      FocusManager::GetFocusManagerForNativeView(widget);
  if (!focus_manager) {
    // TODO(jcampan): http://crbug.com/21378 Reenable this NOTREACHED() when the
    // options page is only based on views.
    // NOTREACHED();
    NOTIMPLEMENTED();
    return;
  }
  focus_manager->SetFocusedView(host->host_->focus_view());
}

////////////////////////////////////////////////////////////////////////////////
// NativeViewHostWrapper, public:

// static
NativeViewHostWrapper* NativeViewHostWrapper::CreateWrapper(
    NativeViewHost* host) {
  return new NativeViewHostGtk(host);
}

}  // namespace views
<commit_msg>Unblock focus signal handlers only when they're blocked.  Unblocking fails when handlers are not blocked. Minor fix. use correct data type for signal handler id.<commit_after>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "views/controls/native/native_view_host_gtk.h"

#include <gtk/gtk.h>
#include <algorithm>

#include "base/logging.h"
#include "views/controls/native/native_view_host.h"
#include "views/focus/focus_manager.h"
#include "views/widget/widget_gtk.h"

namespace views {

namespace {
static bool signal_id_initialized_ = false;
static guint focus_in_event_signal_id_;
static guint focus_out_event_signal_id_;

////////////////////////////////////////////////////////////////////////////////
// Utility functions to block focus signals while re-creating
// Fixed widget.

void InitSignalIds() {
  if (!signal_id_initialized_) {
    signal_id_initialized_ = true;
    focus_in_event_signal_id_ =
        g_signal_lookup("focus-in-event", GTK_TYPE_WIDGET);
    focus_out_event_signal_id_ =
        g_signal_lookup("focus-out-event", GTK_TYPE_WIDGET);
  }
}

// Blocks a |signal_id| on the given |widget| if any.
void BlockSignal(GtkWidget* widget, guint signal_id) {
  gulong handler_id = g_signal_handler_find(G_OBJECT(widget),
                                            G_SIGNAL_MATCH_ID,
                                            signal_id,
                                            0, NULL, NULL, NULL);
  if (handler_id) {
    g_signal_handler_block(G_OBJECT(widget), handler_id);
  }
}

// Unblocks a |signal_id| on the given |widget| if any.
void UnblockSignal(GtkWidget* widget, guint signal_id) {
  gulong handler_id = g_signal_handler_find(G_OBJECT(widget),
                                            G_SIGNAL_MATCH_ID,
                                            signal_id,
                                            0, NULL, NULL, NULL);
  if (handler_id) {
    g_signal_handler_unblock(G_OBJECT(widget), handler_id);
  }
}

// Blocks focus in/out signals of the widget and its descendent
// children.
// Note: Due to the limiation of Gtk API, this only blocks the 1st
// handler found and won't block the rest if there is more than one handlers.
// See bug http://crbug.com/33236.
void BlockFocusSignals(GtkWidget* widget, gpointer data) {
  if (!widget)
    return;
  InitSignalIds();
  BlockSignal(widget, focus_in_event_signal_id_);
  BlockSignal(widget, focus_out_event_signal_id_);
  if (GTK_IS_CONTAINER(widget))
    gtk_container_foreach(GTK_CONTAINER(widget), BlockFocusSignals, data);
}

// Unlocks focus in/out signals of the widget and its descendent children.
void UnblockFocusSignals(GtkWidget* widget, gpointer data) {
  if (!widget)
    return;
  InitSignalIds();
  UnblockSignal(widget, focus_in_event_signal_id_);
  UnblockSignal(widget, focus_out_event_signal_id_);
  if (GTK_IS_CONTAINER(widget))
    gtk_container_foreach(GTK_CONTAINER(widget), UnblockFocusSignals, data);
}

}  // namespace

////////////////////////////////////////////////////////////////////////////////
// NativeViewHostGtk, public:

NativeViewHostGtk::NativeViewHostGtk(NativeViewHost* host)
    : host_(host),
      installed_clip_(false),
      destroy_signal_id_(0),
      focus_signal_id_(0),
      fixed_(NULL) {
  CreateFixed(false);
}

NativeViewHostGtk::~NativeViewHostGtk() {
  if (fixed_)
    gtk_widget_destroy(fixed_);
}

////////////////////////////////////////////////////////////////////////////////
// NativeViewHostGtk, NativeViewHostWrapper implementation:

void NativeViewHostGtk::NativeViewAttached() {
  DCHECK(host_->native_view());
  if (gtk_widget_get_parent(host_->native_view()))
    gtk_widget_reparent(host_->native_view(), fixed_);
  else
    gtk_container_add(GTK_CONTAINER(fixed_), host_->native_view());

  if (!destroy_signal_id_) {
    destroy_signal_id_ = g_signal_connect(host_->native_view(),
                                          "destroy", G_CALLBACK(CallDestroy),
                                          this);
  }

  if (!focus_signal_id_) {
    focus_signal_id_ = g_signal_connect(host_->native_view(),
                                        "focus-in-event",
                                        G_CALLBACK(CallFocusIn), this);
  }

  // Always layout though.
  host_->Layout();

  // We own the native view as long as it's attached, so that we can safely
  // reparent it in multiple passes.
  gtk_widget_ref(host_->native_view());

  // TODO(port): figure out focus.
}

void NativeViewHostGtk::NativeViewDetaching(bool destroyed) {
  DCHECK(host_->native_view());

  g_signal_handler_disconnect(G_OBJECT(host_->native_view()),
                              destroy_signal_id_);
  destroy_signal_id_ = 0;

  g_signal_handler_disconnect(G_OBJECT(host_->native_view()),
                              focus_signal_id_);
  focus_signal_id_ = 0;

  installed_clip_ = false;

  if (fixed_ && !destroyed) {
    DCHECK_NE(static_cast<gfx::NativeView>(NULL),
              gtk_widget_get_parent(host_->native_view()));
    gtk_container_remove(GTK_CONTAINER(fixed_), host_->native_view());
    DCHECK_EQ(
        0U, g_list_length(gtk_container_get_children(GTK_CONTAINER(fixed_))));
  }

  g_object_unref(G_OBJECT(host_->native_view()));
}

void NativeViewHostGtk::AddedToWidget() {
  if (!fixed_)
    CreateFixed(false);
  if (gtk_widget_get_parent(fixed_))
    GetHostWidget()->ReparentChild(fixed_);
  else
    GetHostWidget()->AddChild(fixed_);

  if (!host_->native_view())
    return;

  if (gtk_widget_get_parent(host_->native_view()))
    gtk_widget_reparent(host_->native_view(), fixed_);
  else
    gtk_container_add(GTK_CONTAINER(fixed_), host_->native_view());

  if (host_->IsVisibleInRootView())
    gtk_widget_show(fixed_);
  else
    gtk_widget_hide(fixed_);
  host_->Layout();
}

void NativeViewHostGtk::RemovedFromWidget() {
  if (!host_->native_view())
    return;
  DestroyFixed();
}

void NativeViewHostGtk::InstallClip(int x, int y, int w, int h) {
  DCHECK(w > 0 && h > 0);
  installed_clip_bounds_.SetRect(x, y, w, h);
  installed_clip_ = true;

  // We only re-create the fixed with a window when a cliprect is installed.
  // Because the presence of a X Window will prevent transparency from working
  // properly, we only want it to be active for the duration of a clip
  // (typically during animations and scrolling.)
  CreateFixed(true);
}

bool NativeViewHostGtk::HasInstalledClip() {
  return installed_clip_;
}

void NativeViewHostGtk::UninstallClip() {
  installed_clip_ = false;
  // We now re-create the fixed without a X Window so transparency works again.
  CreateFixed(false);
}

void NativeViewHostGtk::ShowWidget(int x, int y, int w, int h) {
  // x and y are the desired position of host_ in WidgetGtk coordinates.
  int fixed_x = x;
  int fixed_y = y;
  int fixed_w = w;
  int fixed_h = h;
  int child_x = 0;
  int child_y = 0;
  int child_w = w;
  int child_h = h;
  if (installed_clip_) {
    child_x = -installed_clip_bounds_.x();
    child_y = -installed_clip_bounds_.y();
    fixed_x += -child_x;
    fixed_y += -child_y;
    fixed_w = std::min(installed_clip_bounds_.width(), w);
    fixed_h = std::min(installed_clip_bounds_.height(), h);
  }

  // Size and place the fixed_.
  GetHostWidget()->PositionChild(fixed_, fixed_x, fixed_y, fixed_w, fixed_h);

  // Size and place the hosted NativeView.
  gtk_widget_set_size_request(host_->native_view(), child_w, child_h);
  gtk_fixed_move(GTK_FIXED(fixed_), host_->native_view(), child_x, child_y);

  gtk_widget_show(fixed_);
  gtk_widget_show(host_->native_view());
}

void NativeViewHostGtk::HideWidget() {
  gtk_widget_hide(fixed_);
}

void NativeViewHostGtk::SetFocus() {
  DCHECK(host_->native_view());
  gtk_widget_grab_focus(host_->native_view());
}

////////////////////////////////////////////////////////////////////////////////
// NativeViewHostGtk, private:

void NativeViewHostGtk::CreateFixed(bool needs_window) {
  GtkWidget* focused_widget = GetFocusedDescendant();

  bool focus_event_blocked = false;
  // We move focus around and do not want focus events to be emitted
  // during this process.
  if (fixed_) {
    BlockFocusSignals(GetHostWidget()->GetNativeView(), NULL);
    focus_event_blocked = true;
  }

  if (focused_widget) {
    // A descendant of our fixed has focus. When we destroy the fixed focus is
    // automatically moved. Temporarily move focus to our host widget, then
    // restore focus after we create the new fixed_. This way focus hasn't
    // really moved.
    gtk_widget_grab_focus(GetHostWidget()->GetNativeView());
  }

  DestroyFixed();

  fixed_ = gtk_fixed_new();
  gtk_fixed_set_has_window(GTK_FIXED(fixed_), needs_window);
  // Defeat refcounting. We need to own the fixed.
  gtk_widget_ref(fixed_);

  WidgetGtk* widget_gtk = GetHostWidget();
  if (widget_gtk)
    widget_gtk->AddChild(fixed_);

  if (host_->native_view())
    gtk_container_add(GTK_CONTAINER(fixed_), host_->native_view());

  if (widget_gtk && host_->native_view() && focused_widget) {
    gtk_widget_grab_focus(focused_widget);
  }
  if (focus_event_blocked) {
    // Unblocking a signal handler that is not blocked fails.
    // Unblock only when it's unblocked.
    UnblockFocusSignals(GetHostWidget()->GetNativeView(), NULL);
  }
}

void NativeViewHostGtk::DestroyFixed() {
  if (!fixed_)
    return;

  gtk_widget_hide(fixed_);
  GetHostWidget()->RemoveChild(fixed_);

  if (host_->native_view()) {
    // We can safely remove the widget from its container since we own the
    // widget from the moment it is attached.
    gtk_container_remove(GTK_CONTAINER(fixed_), host_->native_view());
  }
  // fixed_ should not have any children this point.
  DCHECK_EQ(0U,
            g_list_length(gtk_container_get_children(GTK_CONTAINER(fixed_))));
  gtk_widget_destroy(fixed_);
  fixed_ = NULL;
}

WidgetGtk* NativeViewHostGtk::GetHostWidget() const {
  return static_cast<WidgetGtk*>(host_->GetWidget());
}

GtkWidget* NativeViewHostGtk::GetFocusedDescendant() {
  if (!fixed_)
    return NULL;
  WidgetGtk* host = GetHostWidget();
  if (!host)
    return NULL;
  GtkWidget* top_level = gtk_widget_get_toplevel(host->GetNativeView());
  if (!top_level || !GTK_IS_WINDOW(top_level))
    return NULL;
  GtkWidget* focused = gtk_window_get_focus(GTK_WINDOW(top_level));
  if (!focused)
    return NULL;
  return (focused == fixed_ || gtk_widget_is_ancestor(focused, fixed_)) ?
      focused : NULL;
}

// static
void NativeViewHostGtk::CallDestroy(GtkObject* object,
                                    NativeViewHostGtk* host) {
  host->host_->NativeViewDestroyed();
}

// static
void NativeViewHostGtk::CallFocusIn(GtkWidget* widget,
                                    GdkEventFocus* event,
                                    NativeViewHostGtk* host) {
  FocusManager* focus_manager =
      FocusManager::GetFocusManagerForNativeView(widget);
  if (!focus_manager) {
    // TODO(jcampan): http://crbug.com/21378 Reenable this NOTREACHED() when the
    // options page is only based on views.
    // NOTREACHED();
    NOTIMPLEMENTED();
    return;
  }
  focus_manager->SetFocusedView(host->host_->focus_view());
}

////////////////////////////////////////////////////////////////////////////////
// NativeViewHostWrapper, public:

// static
NativeViewHostWrapper* NativeViewHostWrapper::CreateWrapper(
    NativeViewHost* host) {
  return new NativeViewHostGtk(host);
}

}  // namespace views
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2013-2015 John Connor (BM-NC49AxAjcqVcF5jNPu85Rb8MJ2d9JqZt)
 *
 * This file is part of vanillacoin.
 *
 * vanillacoin is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License with
 * additional permissions to the one published by the Free Software
 * Foundation, either version 3 of the License, or (at your option)
 * any later version. For more information see LICENSE.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef COIN_LOGGER_HPP
#define COIN_LOGGER_HPP

#if (defined __ANDROID__)
#include <android/log.h>
#endif

#if (defined _WIN32 || defined WIN32) || (defined _WIN64 || defined WIN64)
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#endif // (defined _WIN32 || defined WIN32) || (defined _WIN64 || defined WIN64)

#include <iostream>
#include <memory>
#include <sstream>

#include <mutex>

namespace coin {

    /**
     * Implements a logger.
     */
    class logger
    {
        public:

			typedef enum severity
			{
				severity_none,
				severity_debug,
				severity_error,
				severity_info,
				severity_warning,
                severity_test,
			} severity_t;

            /**
             * Singleton accessor.
             */
			static logger & instance()
			{
			    static logger g_logger;

			    return g_logger;
			}

            /**
             * operator <<
             */
            template <class T>
            logger & operator << (T const & val)
            {
                std::stringstream ss;

                ss << val;

                log(ss);

                ss.str(std::string());

                return logger::instance();
            }

            /**
             * Perform the actual logging.
             * @param val
             */
			void log(std::stringstream & val)
			{
			    static const bool use_file = false;

			    if (use_file)
			    {
                    // ...
			    }

			    static bool use_cout = true;

			    if (use_cout)
			    {
#if (defined _WIN32 || defined WIN32) || (defined _WIN64 || defined WIN64)
#if defined(_UNICODE)
			        DWORD len = MultiByteToWideChar(
			            CP_ACP, 0, val.str().c_str(), -1, NULL, 0
			        );

			        std::unique_ptr<wchar_t> buf(new wchar_t[len]);

			        MultiByteToWideChar(
			            CP_ACP, 0, val.str().c_str(), -1, buf.get(), len
			        );

			        OutputDebugString(buf.get());
			        OutputDebugString(L"\n");

			        std::cerr << val.str() << std::endl;
#else
			        OutputDebugString(val.str().c_str());
			        OutputDebugString(L"\n");

			        std::cerr << val.str() << std::endl;
#endif // _UNICODE
#else // Not Windows.
#if (defined __ANDROID__)
					__android_log_print(
                        ANDROID_LOG_DEBUG, "logger", val.str().c_str()
                    );
#else
			        std::cerr << val.str() << std::endl;
#endif
#endif // defined _WIN32 || defined WIN32) || (defined _WIN64 || defined WIN64
			    }
			}

        private:

			// ...

        protected:

            // ...
    };

    #define log_xx(severity, strm) \
    { \
        std::stringstream __ss; \
        switch (severity) \
        { \
            case coin::logger::severity_debug: \
                __ss << "[DEBUG] - "; \
            break; \
            case coin::logger::severity_error: \
                __ss << "[ERROR] - "; \
            break; \
            case coin::logger::severity_info: \
                __ss << "[INFO] - "; \
            break; \
            case coin::logger::severity_warning: \
                __ss << "[WARNING] - "; \
            break; \
            case coin::logger::severity_test: \
                __ss << "[TEST] - "; \
            break; \
            default: \
                __ss << "[UNKNOWN] - "; \
        } \
		__ss << __FUNCTION__ << ": "; \
        __ss << strm; \
        coin::logger::instance() << __ss.str(); \
        __ss.str(std::string()); \
    } \

#define log_none(strm) /** */
#if (defined NDEBUG)
#define log_debug(strm) log_none(strm)
#else
#define log_debug(strm) log_xx(coin::logger::severity_debug, strm)
#endif
#define log_error(strm) log_xx(coin::logger::severity_error, strm)
#define log_info(strm) log_xx(coin::logger::severity_info, strm)
#define log_warn(strm) log_xx(coin::logger::severity_warning, strm)
#define log_test(strm) log_xx(coin::logger::severity_test, strm)

} // namespace coin

#endif // COIN_LOGGER_HPP

        <commit_msg>support for debug.log file (set use_file = true), line 94<commit_after>/*
 * Copyright (c) 2013-2015 John Connor (BM-NC49AxAjcqVcF5jNPu85Rb8MJ2d9JqZt)
 *
 * This file is part of vanillacoin.
 *
 * vanillacoin is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License with
 * additional permissions to the one published by the Free Software
 * Foundation, either version 3 of the License, or (at your option)
 * any later version. For more information see LICENSE.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef COIN_LOGGER_HPP
#define COIN_LOGGER_HPP

#if (defined __ANDROID__)
#include <android/log.h>
#endif

#if (defined _WIN32 || defined WIN32) || (defined _WIN64 || defined WIN64)
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#endif // (defined _WIN32 || defined WIN32) || (defined _WIN64 || defined WIN64)

#include <iostream>
#include <fstream>
#include <memory>
#include <sstream>

#include <mutex>

#include <coin/filesystem.hpp>

namespace coin {

    /**
     * Implements a logger.
     */
    class logger
    {
        public:

			typedef enum severity
			{
				severity_none,
				severity_debug,
				severity_error,
				severity_info,
				severity_warning,
                severity_test,
			} severity_t;

            /**
             * Singleton accessor.
             */
			static logger & instance()
			{
			    static logger g_logger;

			    return g_logger;
			}

            /**
             * operator <<
             */
            template <class T>
            logger & operator << (T const & val)
            {
                std::stringstream ss;

                ss << val;

                log(ss);

                ss.str(std::string());

                return logger::instance();
            }

            /**
             * Perform the actual logging.
             * @param val
             */
			void log(std::stringstream & val)
			{
			    static const bool use_file = false;

			    if (use_file)
			    {
                    if (ofstream_.is_open() == false)
                    {
                        std::string path =
                            filesystem::data_path() + "debug.log"
                        ;

                        ofstream_.open(
                            path, std::fstream::out | std::fstream::app
                        );
                    }

                    if (ofstream_.is_open() == true)
                    {
                        /**
                         * Limit size.
                         */
                        if (ofstream_.tellp() > 50 * 1000000)
                        {
                            ofstream_.clear();
                        }

                        ofstream_ << val.str() << std::endl;
                    }
			    }

			    static bool use_cout = true;

			    if (use_cout)
			    {
#if (defined _WIN32 || defined WIN32) || (defined _WIN64 || defined WIN64)
#if defined(_UNICODE)
			        DWORD len = MultiByteToWideChar(
			            CP_ACP, 0, val.str().c_str(), -1, NULL, 0
			        );

			        std::unique_ptr<wchar_t> buf(new wchar_t[len]);

			        MultiByteToWideChar(
			            CP_ACP, 0, val.str().c_str(), -1, buf.get(), len
			        );

			        OutputDebugString(buf.get());
			        OutputDebugString(L"\n");

			        std::cerr << val.str() << std::endl;
#else
			        OutputDebugString(val.str().c_str());
			        OutputDebugString(L"\n");

			        std::cerr << val.str() << std::endl;
#endif // _UNICODE
#else // Not Windows.
#if (defined __ANDROID__)
					__android_log_print(
                        ANDROID_LOG_DEBUG, "logger", val.str().c_str()
                    );
#else
			        std::cerr << val.str() << std::endl;
#endif
#endif // defined _WIN32 || defined WIN32) || (defined _WIN64 || defined WIN64
			    }
			}

        private:

			// ...

        protected:

            /**
             * The std::ofstream.
             */
            std::ofstream ofstream_;
    };

    #define log_xx(severity, strm) \
    { \
        std::stringstream __ss; \
        switch (severity) \
        { \
            case coin::logger::severity_debug: \
                __ss << "[DEBUG] - "; \
            break; \
            case coin::logger::severity_error: \
                __ss << "[ERROR] - "; \
            break; \
            case coin::logger::severity_info: \
                __ss << "[INFO] - "; \
            break; \
            case coin::logger::severity_warning: \
                __ss << "[WARNING] - "; \
            break; \
            case coin::logger::severity_test: \
                __ss << "[TEST] - "; \
            break; \
            default: \
                __ss << "[UNKNOWN] - "; \
        } \
		__ss << __FUNCTION__ << ": "; \
        __ss << strm; \
        coin::logger::instance() << __ss.str(); \
        __ss.str(std::string()); \
    } \

#define log_none(strm) /** */
#if (defined NDEBUG)
#define log_debug(strm) log_none(strm)
#else
#define log_debug(strm) log_xx(coin::logger::severity_debug, strm)
#endif
#define log_error(strm) log_xx(coin::logger::severity_error, strm)
#define log_info(strm) log_xx(coin::logger::severity_info, strm)
#define log_warn(strm) log_xx(coin::logger::severity_warning, strm)
#define log_test(strm) log_xx(coin::logger::severity_test, strm)

} // namespace coin

#endif // COIN_LOGGER_HPP

        <|endoftext|>


<commit_before>/**
 * @file		compmanager.cpp
 * @brief		COSSB component manager
 * @author		Byunghun Hwang<bhhwang@nsynapse.com>
 * @date 		2015. 6. 21
 * @details
 */

#include "manager.hpp"
#include "container.hpp"
#include "driver.hpp"
#include <logger.hpp>
#include <base/configreader.hpp>
#include <list>
#include <exception.hpp>

using namespace std;

namespace cossb {
namespace manager {

component_manager::component_manager()
{

}

component_manager::~component_manager()
{
	stop();
	cossb_component_container->destroy();
}

bool component_manager::install(const char* component_name)
{
	string component_path = cossb_config->get_path()["component"];
	if(component_path.empty())
		component_path = "./"+string(component_name);
	else
		component_path+=component_name;

	if(cossb_component_container->add(component_name, new driver::component_driver(component_path.c_str())))
	{
		cossb_log->log(log::loglevel::INFO, fmt::format("Component installed : {}", component_name).c_str());
		cossb_component_container->get_driver(component_name)->setup();
		return true;
	}

	return false;
}

bool component_manager::uninstall(const char* component_name)
{
	if(cossb_component_container->exist(component_name))
	{
		cossb_component_container->get_driver(component_name)->stop();
		cossb_component_container->remove(component_name);
		cossb_log->log(log::loglevel::INFO, fmt::format("Component uninstalled : {}", component_name).c_str());
		return true;
	}
	return false;
}

bool component_manager::run(const char* component_name)
{
	if(cossb_component_container->exist(component_name))
	{
		cossb_component_container->get_driver(component_name)->run();
		return true;
	}
	return false;
}

bool component_manager::run()
{
	for(auto comp:cossb_component_container->_container) {
		this->run(comp.first.c_str());
	}
	return true;
}

bool component_manager::stop(const char* component_name)
{
	if(cossb_component_container->exist(component_name)) {
		cossb_component_container->get_driver(component_name)->stop();
		return true;
	}
	return false;
}

bool component_manager::stop()
{
	for(auto comp:cossb_component_container->_container) {
		this->stop(comp.first.c_str());
	}
	return true;
}

int component_manager::count()
{
	return cossb_component_container->_container.size();
}

driver::component_driver* component_manager::get_driver(const char* component_name)
{
	if(cossb_component_container->exist(component_name)) {
		return cossb_component_container->get_driver(component_name);
	}
	return nullptr;
}

} /* namespace manager */
} /* namespace cossb */
<commit_msg>bug fixed in install function<commit_after>/**
 * @file		compmanager.cpp
 * @brief		COSSB component manager
 * @author		Byunghun Hwang<bhhwang@nsynapse.com>
 * @date 		2015. 6. 21
 * @details
 */

#include "manager.hpp"
#include "container.hpp"
#include "driver.hpp"
#include <logger.hpp>
#include <base/configreader.hpp>
#include <list>
#include <exception.hpp>

using namespace std;

namespace cossb {
namespace manager {

component_manager::component_manager()
{

}

component_manager::~component_manager()
{
	stop();
	cossb_component_container->destroy();
}

bool component_manager::install(const char* component_name)
{
	cout << "component name : " << component_name << endl;

	string component_path = cossb_config->get_path()["component"];
	if(component_path.empty())
		component_path = "./"+string(component_name);
	else
		component_path+=component_name;

	if(cossb_component_container->add(component_name, new driver::component_driver(component_path.c_str())))
	{
		cossb_log->log(log::loglevel::INFO, fmt::format("Component installed : {}", component_name).c_str());
		cossb_component_container->get_driver(component_name)->setup();
		return true;
	}

	return false;
}

bool component_manager::uninstall(const char* component_name)
{
	if(cossb_component_container->exist(component_name))
	{
		cossb_component_container->get_driver(component_name)->stop();
		cossb_component_container->remove(component_name);
		cossb_log->log(log::loglevel::INFO, fmt::format("Component uninstalled : {}", component_name).c_str());
		return true;
	}
	return false;
}

bool component_manager::run(const char* component_name)
{
	if(cossb_component_container->exist(component_name))
	{
		cossb_component_container->get_driver(component_name)->run();
		return true;
	}
	return false;
}

bool component_manager::run()
{
	for(auto comp:cossb_component_container->_container) {
		this->run(comp.first.c_str());
	}
	return true;
}

bool component_manager::stop(const char* component_name)
{
	if(cossb_component_container->exist(component_name)) {
		cossb_component_container->get_driver(component_name)->stop();
		return true;
	}
	return false;
}

bool component_manager::stop()
{
	for(auto comp:cossb_component_container->_container) {
		this->stop(comp.first.c_str());
	}
	return true;
}

int component_manager::count()
{
	return cossb_component_container->_container.size();
}

driver::component_driver* component_manager::get_driver(const char* component_name)
{
	if(cossb_component_container->exist(component_name)) {
		return cossb_component_container->get_driver(component_name);
	}
	return nullptr;
}

} /* namespace manager */
} /* namespace cossb */
<|endoftext|>


<commit_before>//=======================================================================
// Copyright (c) 2014-2016 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

/*!
 * \file
 * \brief Contains some global functions.
*/

#pragma once

#include "etl/temporary.hpp"

#include "etl/impl/decomposition.hpp"

namespace etl {

/*!
 * \brief Indicates if the given expression is a square matrix or not.
 * \param expr The expression to test
 * \return true if the given expression is a square matrix, false otherwise.
 */
template <typename E>
bool is_square(E&& expr) {
    return decay_traits<E>::dimensions() == 2 && etl::dim<0>(expr) == etl::dim<1>(expr);
}

/*!
 * \brief Indicates if the given expression is a rectangular matrix or not.
 * \param expr The expression to test
 * \return true if the given expression is a rectangular matrix, false otherwise.
 */
template <typename E>
bool is_rectangular(E&& expr) {
    return decay_traits<E>::dimensions() == 2 && etl::dim<0>(expr) != etl::dim<1>(expr);
}

/*!
 * \brief Indicates if the given expression contains sub matrices that are square.
 * \param expr The expression to test
 * \return true if the given expression contains sub matrices that are square, false otherwise.
 */
template <typename E>
bool is_sub_square(E&& expr) {
    return decay_traits<E>::dimensions() == 3 && etl::dim<1>(expr) == etl::dim<2>(expr);
}

/*!
 * \brief Indicates if the given expression contains sub matrices that are rectangular.
 * \param expr The expression to test
 * \return true if the given expression contains sub matrices that are rectangular, false otherwise.
 */
template <typename E>
bool is_sub_rectangular(E&& expr) {
    return decay_traits<E>::dimensions() == 3 && etl::dim<1>(expr) != etl::dim<2>(expr);
}

/*!
 * \brief Indicates if the given expression is a symmetric matrix or not.
 * \param expr The expression to test
 * \return true if the given expression is a symmetric matrix, false otherwise.
 */
template <typename E>
bool is_symmetric(E&& expr) {
    if (is_square(expr)) {
        for (std::size_t i = 0; i < etl::dim<0>(expr) - 1; ++i) {
            for (std::size_t j = i + 1; j < etl::dim<0>(expr); ++j) {
                if (expr(i, j) != expr(j, i)) {
                    return false;
                }
            }
        }

        return true;
    }

    return false;
}

/*!
 * \brief Indicates if the given expression is a lower triangular matrix or not.
 * \param expr The expression to test
 * \return true if the given expression is a lower triangular matrix, false otherwise.
 */
template <typename E>
bool is_lower_triangular(E&& expr) {
    if (is_square(expr)) {
        for (std::size_t i = 0; i < etl::dim<0>(expr) - 1; ++i) {
            for (std::size_t j = i + 1; j < etl::dim<0>(expr); ++j) {
                if (expr(i, j) != 0.0) {
                    return false;
                }
            }
        }

        return true;
    }

    return false;
}

/*!
 * \brief Indicates if the given expression is a strictly lower triangular matrix or not.
 * \param expr The expression to test
 * \return true if the given expression is a strictly lower triangular matrix, false otherwise.
 */
template <typename E>
bool is_strictly_lower_triangular(E&& expr) {
    if (is_square(expr)) {
        for (std::size_t i = 0; i < etl::dim<0>(expr); ++i) {
            for (std::size_t j = i; j < etl::dim<0>(expr); ++j) {
                if (expr(i, j) != 0.0) {
                    return false;
                }
            }
        }

        return true;
    }

    return false;
}

/*!
 * \brief Indicates if the given expression is a upper triangular matrix or not.
 * \param expr The expression to test
 * \return true if the given expression is a upper triangular matrix, false otherwise.
 */
template <typename E>
bool is_upper_triangular(E&& expr) {
    if (is_square(expr)) {
        for (std::size_t i = 1; i < etl::dim<0>(expr); ++i) {
            for (std::size_t j = 0; j < i; ++j) {
                if (expr(i, j) != 0.0) {
                    return false;
                }
            }
        }

        return true;
    }

    return false;
}

/*!
 * \brief Indicates if the given expression is a strictly upper triangular matrix or not.
 * \param expr The expression to test
 * \return true if the given expression is a strictly upper triangular matrix, false otherwise.
 */
template <typename E>
bool is_strictly_upper_triangular(E&& expr) {
    if (is_square(expr)) {
        for (std::size_t i = 0; i < etl::dim<0>(expr); ++i) {
            for (std::size_t j = 0; j <= i; ++j) {
                if (expr(i, j) != 0.0) {
                    return false;
                }
            }
        }

        return true;
    }

    return false;
}

/*!
 * \brief Indicates if the given expression is a diagonal matrix or not.
 * \param expr The expression to test
 * \return true if the given expression is a diagonal matrix, false otherwise.
 */
template <typename E>
bool is_diagonal(E&& expr) {
    if (is_square(expr)) {
        for (std::size_t i = 0; i < etl::dim<0>(expr); ++i) {
            for (std::size_t j = 0; j < etl::dim<0>(expr); ++j) {
                if (i != j && expr(i, j) != 0.0) {
                    return false;
                }
            }
        }

        return true;
    }

    return false;
}

/*!
 * \brief Indicates if the given expression is uniform (all elements of the same value)
 * \param expr The expression to test
 * \return true if the given expression is uniform, false otherwise.
 */
template <typename E>
bool is_uniform(E&& expr) {
    if (!etl::size(expr)) {
        return false;
    }

    auto first = *expr.begin();

    for (auto v : expr) {
        if (v != first) {
            return false;
        }
    }

    return true;
}

/*!
 * \brief Returns the trace of the given square matrix.
 *
 * If the given expression does not represent a square matrix, this function will fail
 *
 * \param expr The expression to get the trace from.
 * \return The trace of the given expression
 */
template <typename E>
value_t<E> trace(E&& expr) {
    assert_square(expr);

    auto value = value_t<E>();

    for (std::size_t i = 0; i < etl::dim<0>(expr); ++i) {
        value += expr(i, i);
    }

    return value;
}

template <typename AT, typename LT, typename UT, typename PT>
bool lu(const AT& A, LT& L, UT& U, PT& P) {
    // All matrices must be square
    if (!is_square(A) || !is_square(L) || !is_square(U) || !is_square(P)) {
        return false;
    }

    // All matrices must be of the same dimension
    if (etl::dim(A, 0) != etl::dim(L, 0) || etl::dim(A, 0) != etl::dim(U, 0) || etl::dim(A, 0) != etl::dim(P, 0)) {
        return true;
    }

    detail::lu_impl::apply(A, L, U, P);

    return true;
}

} //end of namespace etl
<commit_msg>Add tests is_complex_matrix and is_real_matrix<commit_after>//=======================================================================
// Copyright (c) 2014-2016 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

/*!
 * \file
 * \brief Contains some global functions.
*/

#pragma once

#include "etl/temporary.hpp"

#include "etl/impl/decomposition.hpp"

namespace etl {

/*!
 * \brief Indicates if the given expression is a square matrix or not.
 * \param expr The expression to test
 * \return true if the given expression is a square matrix, false otherwise.
 */
template <typename E>
bool is_square(E&& expr) {
    return decay_traits<E>::dimensions() == 2 && etl::dim<0>(expr) == etl::dim<1>(expr);
}

/*!
 * \brief Indicates if the given expression is a real matrix or not.
 * \param expr The expression to test
 * \return true if the given expression is a real matrix, false otherwise.
 */
template <typename E>
bool is_real_matrix(E&& expr) {
    cpp_unused(expr);
    return !is_complex<E>::value;
}

/*!
 * \brief Indicates if the given expression is a complex matrix or not.
 * \param expr The expression to test
 * \return true if the given expression is a complex matrix, false otherwise.
 */
template <typename E>
bool is_complex_matrix(E&& expr) {
    cpp_unused(expr);
    return is_complex<E>::value;
}

/*!
 * \brief Indicates if the given expression is a rectangular matrix or not.
 * \param expr The expression to test
 * \return true if the given expression is a rectangular matrix, false otherwise.
 */
template <typename E>
bool is_rectangular(E&& expr) {
    return decay_traits<E>::dimensions() == 2 && etl::dim<0>(expr) != etl::dim<1>(expr);
}

/*!
 * \brief Indicates if the given expression contains sub matrices that are square.
 * \param expr The expression to test
 * \return true if the given expression contains sub matrices that are square, false otherwise.
 */
template <typename E>
bool is_sub_square(E&& expr) {
    return decay_traits<E>::dimensions() == 3 && etl::dim<1>(expr) == etl::dim<2>(expr);
}

/*!
 * \brief Indicates if the given expression contains sub matrices that are rectangular.
 * \param expr The expression to test
 * \return true if the given expression contains sub matrices that are rectangular, false otherwise.
 */
template <typename E>
bool is_sub_rectangular(E&& expr) {
    return decay_traits<E>::dimensions() == 3 && etl::dim<1>(expr) != etl::dim<2>(expr);
}

/*!
 * \brief Indicates if the given expression is a symmetric matrix or not.
 * \param expr The expression to test
 * \return true if the given expression is a symmetric matrix, false otherwise.
 */
template <typename E>
bool is_symmetric(E&& expr) {
    if (is_square(expr)) {
        for (std::size_t i = 0; i < etl::dim<0>(expr) - 1; ++i) {
            for (std::size_t j = i + 1; j < etl::dim<0>(expr); ++j) {
                if (expr(i, j) != expr(j, i)) {
                    return false;
                }
            }
        }

        return true;
    }

    return false;
}

/*!
 * \brief Indicates if the given expression is a lower triangular matrix or not.
 * \param expr The expression to test
 * \return true if the given expression is a lower triangular matrix, false otherwise.
 */
template <typename E>
bool is_lower_triangular(E&& expr) {
    if (is_square(expr)) {
        for (std::size_t i = 0; i < etl::dim<0>(expr) - 1; ++i) {
            for (std::size_t j = i + 1; j < etl::dim<0>(expr); ++j) {
                if (expr(i, j) != 0.0) {
                    return false;
                }
            }
        }

        return true;
    }

    return false;
}

/*!
 * \brief Indicates if the given expression is a strictly lower triangular matrix or not.
 * \param expr The expression to test
 * \return true if the given expression is a strictly lower triangular matrix, false otherwise.
 */
template <typename E>
bool is_strictly_lower_triangular(E&& expr) {
    if (is_square(expr)) {
        for (std::size_t i = 0; i < etl::dim<0>(expr); ++i) {
            for (std::size_t j = i; j < etl::dim<0>(expr); ++j) {
                if (expr(i, j) != 0.0) {
                    return false;
                }
            }
        }

        return true;
    }

    return false;
}

/*!
 * \brief Indicates if the given expression is a upper triangular matrix or not.
 * \param expr The expression to test
 * \return true if the given expression is a upper triangular matrix, false otherwise.
 */
template <typename E>
bool is_upper_triangular(E&& expr) {
    if (is_square(expr)) {
        for (std::size_t i = 1; i < etl::dim<0>(expr); ++i) {
            for (std::size_t j = 0; j < i; ++j) {
                if (expr(i, j) != 0.0) {
                    return false;
                }
            }
        }

        return true;
    }

    return false;
}

/*!
 * \brief Indicates if the given expression is a strictly upper triangular matrix or not.
 * \param expr The expression to test
 * \return true if the given expression is a strictly upper triangular matrix, false otherwise.
 */
template <typename E>
bool is_strictly_upper_triangular(E&& expr) {
    if (is_square(expr)) {
        for (std::size_t i = 0; i < etl::dim<0>(expr); ++i) {
            for (std::size_t j = 0; j <= i; ++j) {
                if (expr(i, j) != 0.0) {
                    return false;
                }
            }
        }

        return true;
    }

    return false;
}

/*!
 * \brief Indicates if the given expression is a diagonal matrix or not.
 * \param expr The expression to test
 * \return true if the given expression is a diagonal matrix, false otherwise.
 */
template <typename E>
bool is_diagonal(E&& expr) {
    if (is_square(expr)) {
        for (std::size_t i = 0; i < etl::dim<0>(expr); ++i) {
            for (std::size_t j = 0; j < etl::dim<0>(expr); ++j) {
                if (i != j && expr(i, j) != 0.0) {
                    return false;
                }
            }
        }

        return true;
    }

    return false;
}

/*!
 * \brief Indicates if the given expression is uniform (all elements of the same value)
 * \param expr The expression to test
 * \return true if the given expression is uniform, false otherwise.
 */
template <typename E>
bool is_uniform(E&& expr) {
    if (!etl::size(expr)) {
        return false;
    }

    auto first = *expr.begin();

    for (auto v : expr) {
        if (v != first) {
            return false;
        }
    }

    return true;
}

/*!
 * \brief Returns the trace of the given square matrix.
 *
 * If the given expression does not represent a square matrix, this function will fail
 *
 * \param expr The expression to get the trace from.
 * \return The trace of the given expression
 */
template <typename E>
value_t<E> trace(E&& expr) {
    assert_square(expr);

    auto value = value_t<E>();

    for (std::size_t i = 0; i < etl::dim<0>(expr); ++i) {
        value += expr(i, i);
    }

    return value;
}

template <typename AT, typename LT, typename UT, typename PT>
bool lu(const AT& A, LT& L, UT& U, PT& P) {
    // All matrices must be square
    if (!is_square(A) || !is_square(L) || !is_square(U) || !is_square(P)) {
        return false;
    }

    // All matrices must be of the same dimension
    if (etl::dim(A, 0) != etl::dim(L, 0) || etl::dim(A, 0) != etl::dim(U, 0) || etl::dim(A, 0) != etl::dim(P, 0)) {
        return true;
    }

    detail::lu_impl::apply(A, L, U, P);

    return true;
}

} //end of namespace etl
<|endoftext|>