<commit_before>// [WriteFile Name=Unique_Value_Renderer, Category=DisplayInformation]
// [Legal]
// Copyright 2016 Esri.

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0

// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// [Legal]

#include "Unique_Value_Renderer.h"

#include "Map.h"
#include "MapQuickView.h"
#include "Basemap.h"
#include "ServiceFeatureTable.h"
#include "FeatureLayer.h"
#include "UniqueValueRenderer.h"
#include "SimpleFillSymbol.h"
#include "SimpleLineSymbol.h"
#include "Viewpoint.h"
#include "Envelope.h"

#include <QUrl>
#include <QStringList>
#include <QVariantList>

using namespace Esri::ArcGISRuntime;

Unique_Value_Renderer::Unique_Value_Renderer(QQuickItem* parent) :
    QQuickItem(parent),
    m_map(nullptr),
    m_mapView(nullptr),
    m_featureLayer(nullptr),
    m_featureTable(nullptr),
    m_defaultSymbol(nullptr),
    m_californiaSymbol(nullptr),
    m_arizonaSymbol(nullptr),
    m_nevadaSymbol(nullptr),
    m_uniqueValueRenderer(nullptr)
{
}

Unique_Value_Renderer::~Unique_Value_Renderer()
{
}

void Unique_Value_Renderer::componentComplete()
{
    QQuickItem::componentComplete();

    // find QML MapView component
    m_mapView = findChild<MapQuickView*>("mapView");

    // create a new basemap instance
    Basemap* basemap = Basemap::topographic(this);
    // create a new map instance
    m_map = new Map(basemap, this);

    // create featureLayer with URL
    m_featureTable = new ServiceFeatureTable(QUrl("http://sampleserver6.arcgisonline.com/arcgis/rest/services/USA/MapServer/2"), this);
    m_featureLayer = new FeatureLayer(m_featureTable, this);
    m_map->operationalLayers()->append(m_featureLayer);

    // create unique renderer
    m_uniqueValueRenderer = new UniqueValueRenderer(this);
    // you can add multiple fields. In this case, only one is used
    m_uniqueValueRenderer->setFieldNames(QStringList("STATE_NAME"));

    // create symbols to be used in the renderer
    m_defaultSymbol = new SimpleFillSymbol(SimpleFillSymbolStyle::Null, QColor("black"), new SimpleLineSymbol(SimpleLineSymbolStyle::Solid, QColor("gray"), 2, this), this);
    m_californiaSymbol = new SimpleFillSymbol(SimpleFillSymbolStyle::Solid, QColor("red"), new SimpleLineSymbol(SimpleLineSymbolStyle::Solid, QColor("red"), 2, this), this);
    m_arizonaSymbol = new SimpleFillSymbol(SimpleFillSymbolStyle::Solid, QColor("green"), new SimpleLineSymbol(SimpleLineSymbolStyle::Solid, QColor("green"), 2, this), this);
    m_nevadaSymbol = new SimpleFillSymbol(SimpleFillSymbolStyle::Solid, QColor("blue"), new SimpleLineSymbol(SimpleLineSymbolStyle::Solid, QColor("blue"), 2, this), this);

    // create unique values and add to the UniqueValueRenderer
    createUniqueValue("California", m_californiaSymbol);
    createUniqueValue("Arizona", m_arizonaSymbol);
    createUniqueValue("Nevada", m_nevadaSymbol);

    // set default symbol
    m_uniqueValueRenderer->setDefaultSymbol(m_defaultSymbol);

    // set the renderer on the feature layer
    m_featureLayer->setRenderer(m_uniqueValueRenderer);

    // set initial viewpoint
    m_map->setInitialViewpoint(Viewpoint(Envelope(-13893029.0, 3573174.0, -12038972.0, 5309823.0, SpatialReference::webMercator())));

    // set map on the map view
    m_mapView->setMap(m_map);
}

void Unique_Value_Renderer::createUniqueValue(QString stateName, SimpleFillSymbol* fillSymbol)
{
    // add state's attribute value for field "STATE_NAME" to QVariantList
    QVariantList stateValue;
    stateValue.append(stateName);

    // set value for a State to be rendered. (label, description, attribute value list, symbol, parent)
    UniqueValue* uniqueValue = new UniqueValue(stateName, "The State of " + stateName, stateValue, fillSymbol, this);
    // append to UniqueValueRenderer
    m_uniqueValueRenderer->uniqueValues()->append(uniqueValue);
}
<commit_msg>Use STATE_ABBR.<commit_after>// [WriteFile Name=Unique_Value_Renderer, Category=DisplayInformation]
// [Legal]
// Copyright 2016 Esri.

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0

// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// [Legal]

#include "Unique_Value_Renderer.h"

#include "Map.h"
#include "MapQuickView.h"
#include "Basemap.h"
#include "ServiceFeatureTable.h"
#include "FeatureLayer.h"
#include "UniqueValueRenderer.h"
#include "SimpleFillSymbol.h"
#include "SimpleLineSymbol.h"
#include "Viewpoint.h"
#include "Envelope.h"

#include <QUrl>
#include <QStringList>
#include <QVariantList>

using namespace Esri::ArcGISRuntime;

Unique_Value_Renderer::Unique_Value_Renderer(QQuickItem* parent) :
    QQuickItem(parent),
    m_map(nullptr),
    m_mapView(nullptr),
    m_featureLayer(nullptr),
    m_featureTable(nullptr),
    m_defaultSymbol(nullptr),
    m_californiaSymbol(nullptr),
    m_arizonaSymbol(nullptr),
    m_nevadaSymbol(nullptr),
    m_uniqueValueRenderer(nullptr)
{
}

Unique_Value_Renderer::~Unique_Value_Renderer()
{
}

void Unique_Value_Renderer::componentComplete()
{
    QQuickItem::componentComplete();

    // find QML MapView component
    m_mapView = findChild<MapQuickView*>("mapView");

    // create a new basemap instance
    Basemap* basemap = Basemap::topographic(this);
    // create a new map instance
    m_map = new Map(basemap, this);

    // create featureLayer with URL
    m_featureTable = new ServiceFeatureTable(QUrl("http://sampleserver6.arcgisonline.com/arcgis/rest/services/USA/MapServer/2"), this);
    m_featureLayer = new FeatureLayer(m_featureTable, this);
    m_map->operationalLayers()->append(m_featureLayer);

    // create unique renderer
    m_uniqueValueRenderer = new UniqueValueRenderer(this);
    // you can add multiple fields. In this case, only one is used
    m_uniqueValueRenderer->setFieldNames(QStringList("STATE_ABBR"));

    // create symbols to be used in the renderer
    m_defaultSymbol = new SimpleFillSymbol(SimpleFillSymbolStyle::Null, QColor("black"), new SimpleLineSymbol(SimpleLineSymbolStyle::Solid, QColor("gray"), 2, this), this);
    m_californiaSymbol = new SimpleFillSymbol(SimpleFillSymbolStyle::Solid, QColor("red"), new SimpleLineSymbol(SimpleLineSymbolStyle::Solid, QColor("red"), 2, this), this);
    m_arizonaSymbol = new SimpleFillSymbol(SimpleFillSymbolStyle::Solid, QColor("green"), new SimpleLineSymbol(SimpleLineSymbolStyle::Solid, QColor("green"), 2, this), this);
    m_nevadaSymbol = new SimpleFillSymbol(SimpleFillSymbolStyle::Solid, QColor("blue"), new SimpleLineSymbol(SimpleLineSymbolStyle::Solid, QColor("blue"), 2, this), this);

    // create unique values and add to the UniqueValueRenderer
    createUniqueValue("CA", m_californiaSymbol);
    createUniqueValue("AZ", m_arizonaSymbol);
    createUniqueValue("NV", m_nevadaSymbol);

    // set default symbol
    m_uniqueValueRenderer->setDefaultSymbol(m_defaultSymbol);

    // set the renderer on the feature layer
    m_featureLayer->setRenderer(m_uniqueValueRenderer);

    // set initial viewpoint
    m_map->setInitialViewpoint(Viewpoint(Envelope(-13893029.0, 3573174.0, -12038972.0, 5309823.0, SpatialReference::webMercator())));

    // set map on the map view
    m_mapView->setMap(m_map);
}

void Unique_Value_Renderer::createUniqueValue(QString stateName, SimpleFillSymbol* fillSymbol)
{
    // add state's attribute value for field "STATE_ABBR" to QVariantList
    QVariantList stateValue;
    stateValue.append(stateName);

    // set value for a State to be rendered. (label, description, attribute value list, symbol, parent)
    UniqueValue* uniqueValue = new UniqueValue(stateName, "The State of " + stateName, stateValue, fillSymbol, this);
    // append to UniqueValueRenderer
    m_uniqueValueRenderer->uniqueValues()->append(uniqueValue);
}
<|endoftext|>


<commit_before>#include <unistd.h>

#include "simdjson/jsonparser.h"

// #define RAPIDJSON_SSE2 // bad
// #define RAPIDJSON_SSE42 // bad
#include "rapidjson/document.h"
#include "rapidjson/reader.h" // you have to check in the submodule
#include "rapidjson/stringbuffer.h"
#include "rapidjson/writer.h"
#include "json11.cpp"
#include "sajson.h"
#include "fastjson.cpp"
#include "fastjson_dom.cpp"
#include "gason.cpp"
extern "C"
{
#include "ultrajsondec.c"
#include "ujdecode.h"
#include "cJSON.h"
#include "cJSON.c"
#include "jsmn.h"
#include "jsmn.c"
}
#include "json/json.h"
#include "jsoncpp.cpp"
using namespace rapidjson;
using namespace std;

// fastjson has a tricky interface
void on_json_error( void *, const fastjson::ErrorContext& ec) {
  //std::cerr<<"ERROR: "<<ec.mesg<<std::endl;
}
bool fastjson_parse(const char *input) {
  fastjson::Token token;
  fastjson::dom::Chunk chunk;
  return fastjson::dom::parse_string(input, &token, &chunk, 0, &on_json_error, NULL);
}
// end of fastjson stuff

using namespace rapidjson;
using namespace std;

int main(int argc, char *argv[]) {
  bool verbose = false;
    int c;
  while ((c = getopt (argc, argv, "v")) != -1)
    switch (c)
      {
      case 'v':
        verbose = true;
        break;
      default:
        abort ();
      }
  if (optind >= argc) {
    cerr << "Usage: " << argv[0] << " <jsonfile>\n";
    cerr << "Or " << argv[0] << " -v <jsonfile>\n";
    exit(1);
  }
  const char * filename = argv[optind];
  std::string_view p;
  try {
    p = get_corpus(filename);
  } catch (const std::exception& e) { // caught by reference to base
    std::cout << "Could not load the file " << filename << std::endl;
    return EXIT_FAILURE;
  }
  if (verbose) {
    std::cout << "Input has ";
    if (p.size() > 1024 * 1024)
      std::cout << p.size() / (1024 * 1024) << " MB ";
    else if (p.size() > 1024)
      std::cout << p.size() / 1024 << " KB ";
    else
      std::cout << p.size() << " B ";
    std::cout << std::endl;
  }
  ParsedJson pj;
  bool allocok = pj.allocateCapacity(p.size(), 1024);
  if (!allocok) {
    std::cerr << "can't allocate memory" << std::endl;
    return EXIT_FAILURE;
  }
  bool ours_correct = json_parse(p, pj);

  rapidjson::Document d;

  char *buffer = (char *)malloc(p.size() + 1);
  memcpy(buffer, p.data(), p.size());
  buffer[p.size()] = '\0';
  bool rapid_correct = (d.Parse((const char *)buffer).HasParseError() == false);
  bool rapid_correct_checkencoding = (d.Parse<kParseValidateEncodingFlag>((const char *)buffer).HasParseError() == false);
  bool sajson_correct = sajson::parse(sajson::dynamic_allocation(), sajson::mutable_string_view(p.size(), buffer)).is_valid();
  std::string json11err;
  bool dropbox_correct = (( json11::Json::parse(buffer,json11err).is_null() ) || ( ! json11err.empty() )) == false;
  bool fastjson_correct =  fastjson_parse(buffer);
  JsonValue value;
  JsonAllocator allocator;
  char *endptr;
  bool gason_correct = (jsonParse(buffer, &endptr, &value, allocator) == JSON_OK);
  void *state;
  bool ultrajson_correct = ((UJDecode(buffer, p.size(), NULL, &state) == NULL) == false);

  auto * tokens = make_unique<jsmntok_t[](p.size());
  bool jsmn_correct = false;
  if(tokens == nullptr) {
    printf("Failed to alloc memory for jsmn\n");
  } else {
    jsmn_parser parser;
    jsmn_init(&parser);
    memcpy(buffer, p.data(), p.size());
    buffer[p.size()] = '\0';
    int r = jsmn_parse(&parser, buffer, p.size(), tokens.get(), p.size());
    tokens = nullptr;
    jsmn_correct = (r > 0);
  }

  memcpy(buffer, p.data(), p.size());
  buffer[p.size()] = '\0';
  cJSON * tree = cJSON_Parse(buffer);
  bool cjson_correct = (tree != NULL);
  if (tree != NULL) {
        cJSON_Delete(tree);
  }

  Json::CharReaderBuilder b;
  Json::CharReader * jsoncppreader = b.newCharReader();
  Json::Value root;
  Json::String errs;
  bool isjsoncppok = jsoncppreader->parse(buffer,buffer+p.size(),&root,&errs);
  delete jsoncppreader;

  printf("our parser                 : %s \n", ours_correct ?   "correct":"invalid");
  printf("rapid                      : %s \n", rapid_correct ?  "correct":"invalid");
  printf("rapid (check encoding)     : %s \n", rapid_correct_checkencoding ?  "correct":"invalid");
  printf("sajson                     : %s \n", sajson_correct ? "correct":"invalid");
  printf("dropbox                    : %s \n", dropbox_correct ? "correct":"invalid");
  printf("fastjson                   : %s \n", fastjson_correct ? "correct":"invalid");
  printf("gason                      : %s \n", gason_correct ? "correct":"invalid");
  printf("ultrajson                  : %s \n", ultrajson_correct ? "correct":"invalid");
  printf("jsmn                       : %s \n", jsmn_correct ? "correct":"invalid");
  printf("cjson                      : %s \n", cjson_correct ? "correct":"invalid");
  printf("jsoncpp                    : %s \n", isjsoncppok ? "correct":"invalid");

  aligned_free((void*)p.data());
  free(buffer);
  return EXIT_SUCCESS;
}
<commit_msg>Fix syntax error introduced by 772919 (#138)<commit_after>#include <unistd.h>

#include "simdjson/jsonparser.h"

// #define RAPIDJSON_SSE2 // bad
// #define RAPIDJSON_SSE42 // bad
#include "rapidjson/document.h"
#include "rapidjson/reader.h" // you have to check in the submodule
#include "rapidjson/stringbuffer.h"
#include "rapidjson/writer.h"
#include "json11.cpp"
#include "sajson.h"
#include "fastjson.cpp"
#include "fastjson_dom.cpp"
#include "gason.cpp"
extern "C"
{
#include "ultrajsondec.c"
#include "ujdecode.h"
#include "cJSON.h"
#include "cJSON.c"
#include "jsmn.h"
#include "jsmn.c"
}
#include "json/json.h"
#include "jsoncpp.cpp"
using namespace rapidjson;
using namespace std;

// fastjson has a tricky interface
void on_json_error( void *, const fastjson::ErrorContext& ec) {
  //std::cerr<<"ERROR: "<<ec.mesg<<std::endl;
}
bool fastjson_parse(const char *input) {
  fastjson::Token token;
  fastjson::dom::Chunk chunk;
  return fastjson::dom::parse_string(input, &token, &chunk, 0, &on_json_error, NULL);
}
// end of fastjson stuff

using namespace rapidjson;
using namespace std;

int main(int argc, char *argv[]) {
  bool verbose = false;
    int c;
  while ((c = getopt (argc, argv, "v")) != -1)
    switch (c)
      {
      case 'v':
        verbose = true;
        break;
      default:
        abort ();
      }
  if (optind >= argc) {
    cerr << "Usage: " << argv[0] << " <jsonfile>\n";
    cerr << "Or " << argv[0] << " -v <jsonfile>\n";
    exit(1);
  }
  const char * filename = argv[optind];
  std::string_view p;
  try {
    p = get_corpus(filename);
  } catch (const std::exception& e) { // caught by reference to base
    std::cout << "Could not load the file " << filename << std::endl;
    return EXIT_FAILURE;
  }
  if (verbose) {
    std::cout << "Input has ";
    if (p.size() > 1024 * 1024)
      std::cout << p.size() / (1024 * 1024) << " MB ";
    else if (p.size() > 1024)
      std::cout << p.size() / 1024 << " KB ";
    else
      std::cout << p.size() << " B ";
    std::cout << std::endl;
  }
  ParsedJson pj;
  bool allocok = pj.allocateCapacity(p.size(), 1024);
  if (!allocok) {
    std::cerr << "can't allocate memory" << std::endl;
    return EXIT_FAILURE;
  }
  bool ours_correct = json_parse(p, pj);

  rapidjson::Document d;

  char *buffer = (char *)malloc(p.size() + 1);
  memcpy(buffer, p.data(), p.size());
  buffer[p.size()] = '\0';
  bool rapid_correct = (d.Parse((const char *)buffer).HasParseError() == false);
  bool rapid_correct_checkencoding = (d.Parse<kParseValidateEncodingFlag>((const char *)buffer).HasParseError() == false);
  bool sajson_correct = sajson::parse(sajson::dynamic_allocation(), sajson::mutable_string_view(p.size(), buffer)).is_valid();
  std::string json11err;
  bool dropbox_correct = (( json11::Json::parse(buffer,json11err).is_null() ) || ( ! json11err.empty() )) == false;
  bool fastjson_correct =  fastjson_parse(buffer);
  JsonValue value;
  JsonAllocator allocator;
  char *endptr;
  bool gason_correct = (jsonParse(buffer, &endptr, &value, allocator) == JSON_OK);
  void *state;
  bool ultrajson_correct = ((UJDecode(buffer, p.size(), NULL, &state) == NULL) == false);

  auto tokens = make_unique<jsmntok_t[]>(p.size());
  bool jsmn_correct = false;
  if(tokens == nullptr) {
    printf("Failed to alloc memory for jsmn\n");
  } else {
    jsmn_parser parser;
    jsmn_init(&parser);
    memcpy(buffer, p.data(), p.size());
    buffer[p.size()] = '\0';
    int r = jsmn_parse(&parser, buffer, p.size(), tokens.get(), p.size());
    tokens = nullptr;
    jsmn_correct = (r > 0);
  }

  memcpy(buffer, p.data(), p.size());
  buffer[p.size()] = '\0';
  cJSON * tree = cJSON_Parse(buffer);
  bool cjson_correct = (tree != NULL);
  if (tree != NULL) {
        cJSON_Delete(tree);
  }

  Json::CharReaderBuilder b;
  Json::CharReader * jsoncppreader = b.newCharReader();
  Json::Value root;
  Json::String errs;
  bool isjsoncppok = jsoncppreader->parse(buffer,buffer+p.size(),&root,&errs);
  delete jsoncppreader;

  printf("our parser                 : %s \n", ours_correct ?   "correct":"invalid");
  printf("rapid                      : %s \n", rapid_correct ?  "correct":"invalid");
  printf("rapid (check encoding)     : %s \n", rapid_correct_checkencoding ?  "correct":"invalid");
  printf("sajson                     : %s \n", sajson_correct ? "correct":"invalid");
  printf("dropbox                    : %s \n", dropbox_correct ? "correct":"invalid");
  printf("fastjson                   : %s \n", fastjson_correct ? "correct":"invalid");
  printf("gason                      : %s \n", gason_correct ? "correct":"invalid");
  printf("ultrajson                  : %s \n", ultrajson_correct ? "correct":"invalid");
  printf("jsmn                       : %s \n", jsmn_correct ? "correct":"invalid");
  printf("cjson                      : %s \n", cjson_correct ? "correct":"invalid");
  printf("jsoncpp                    : %s \n", isjsoncppok ? "correct":"invalid");

  aligned_free((void*)p.data());
  free(buffer);
  return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>/* The Channel class, provides a simple, Ruby thread safe communication
 * mechanism. */

#include "vm.hpp"
#include "vm/object_utils.hpp"
#include "objectmemory.hpp"

#include "builtin/channel.hpp"
#include "builtin/thread.hpp"
#include "builtin/list.hpp"
#include "builtin/fixnum.hpp"
#include "builtin/float.hpp"
#include "builtin/io.hpp"
#include "builtin/contexts.hpp"

#include "message.hpp"
#include "event.hpp"

namespace rubinius {
  Channel* Channel::create(STATE) {
    Channel* chan = (Channel*)state->new_object(G(channel));
    chan->waiting(state, List::create(state));

    return chan;
  }

  Object* Channel::send(STATE, Object* val) {
    if(!waiting_->empty_p()) {
      Thread* thr = as<Thread>(waiting_->shift(state));
      thr->set_top(state, val);
      thr->wakeup(state);
      return Qnil;
    }

    if(value_->nil_p()) {
      List* lst = List::create(state);
      lst->append(state, val);

      value(state, lst);
    }

    return Qnil;
  }

  /** @todo   The list management is iffy. --rue */
  ExecuteStatus Channel::receive_prim(STATE, Executable* exec, Task* task, Message& msg) {
    Thread* current = state->globals.current_thread.get();
    Task* real_task = current->task();

    real_task->active()->clear_stack(msg.stack);

    // @todo  check arity
    if(!value_->nil_p()) {
      Object* val = as<List>(value_)->shift(state);
      task->push(val);
      return cExecuteContinue;
    }

    /* Saves space plus if thread woken forcibly, it gets the Qfalse. */
    real_task->push(Qfalse);

    current->sleep_for(state, this);
    waiting_->append(state, current);

    state->check_events();

    /* This sets the Task to continue from the next
     * opcode when it eventually reactivates. Its
     * stack will then have either the real received
     * value or the default Qfalse if the thread
     * was forced to stop waiting for us.
     */
    return cExecuteRestart;
  }

  Object* Channel::receive(STATE) {
    if(!value_->nil_p()) {
      Object* val = as<List>(value_)->shift(state);
      state->return_value(val);
      return Qnil;
    }

    /* We push nil on the stack to reserve a place to put the result. */
    state->return_value(Qfalse);

    G(current_thread)->sleep_for(state, this);
    waiting_->append(state, G(current_thread));

    state->run_best_thread();

    return Qnil;
  }

  bool Channel::has_readers_p() {
    return !waiting_->empty_p();
  }

  class SendToChannel : public ObjectCallback {
  public:
    TypedRoot<Channel*> chan;

    SendToChannel(STATE, Channel* chan) : ObjectCallback(state), chan(state, chan) { }

    virtual Object* object() {
      return chan.get();
    }

    virtual void call(Object* obj) {
      chan->send(state, obj);
    }
  };

  Object* Channel::send_on_signal(STATE, Channel* chan, Fixnum* signal) {
    SendToChannel* cb = new SendToChannel(state, chan);
    event::Signal* sig = new event::Signal(state, cb, signal->to_native());
    state->signal_events->start(sig);
    return signal;
  }

  Object* Channel::send_on_readable(STATE, Channel* chan, IO* io,
      Object* maybe_buffer, Fixnum* bytes) {

    SendToChannel* cb = new SendToChannel(state, chan);
    event::Read* sig = new event::Read(state, cb, io->to_fd());
    sig->into_buffer(maybe_buffer, bytes->to_native());

    state->events->start(sig);
    return io;
  }

  Object* Channel::send_in_microseconds(STATE, Channel* chan, Integer* useconds, Object* tag) {
    double seconds = useconds->to_native() / 1000000.0;

    return send_in_seconds(state, chan, seconds, tag);
  }

  Object* Channel::send_in_seconds(STATE, Channel* chan, Float* seconds, Object* tag) {
    return send_in_seconds(state, chan, seconds->to_double(state), tag);
  }

  Object* Channel::send_in_seconds(STATE, Channel* chan, double seconds, Object* tag) {
    SendToChannel* cb = new SendToChannel(state, chan);
    event::Timer* sig = new event::Timer(state, cb, seconds, tag);
    state->events->start(sig);
    return Qnil;
  }

  Object* Channel::send_on_stopped(VM* state, Channel* channel, Fixnum* pid, Fixnum* flags)
  {
    event::Child::add(state,
                      new SendToChannel(state, channel),
                      static_cast<pid_t>(pid->to_int()),
                      flags->to_int() );

    /* @todo Figure out the cancellation by id method. */
    return Qnil;
  }

/* ChannelCallback */

  ChannelCallback::ChannelCallback(STATE, Channel* chan) : ObjectCallback(state) {
    channel.set(chan, &GO(roots));
  }

  void ChannelCallback::call(Object* obj) {
    channel->send(state, obj);
  }
}
<commit_msg>Set Channel's value list to Qnil when empty as a hack.<commit_after>/* The Channel class, provides a simple, Ruby thread safe communication
 * mechanism. */

#include "vm.hpp"
#include "vm/object_utils.hpp"
#include "objectmemory.hpp"

#include "builtin/channel.hpp"
#include "builtin/thread.hpp"
#include "builtin/list.hpp"
#include "builtin/fixnum.hpp"
#include "builtin/float.hpp"
#include "builtin/io.hpp"
#include "builtin/contexts.hpp"

#include "message.hpp"
#include "event.hpp"

namespace rubinius {
  Channel* Channel::create(STATE) {
    Channel* chan = (Channel*)state->new_object(G(channel));
    chan->waiting(state, List::create(state));

    return chan;
  }

  Object* Channel::send(STATE, Object* val) {
    if(!waiting_->empty_p()) {
      Thread* thr = as<Thread>(waiting_->shift(state));
      thr->set_top(state, val);
      thr->wakeup(state);
      return Qnil;
    }

    if(value_->nil_p()) {
      List* lst = List::create(state);
      lst->append(state, val);

      value(state, lst);
    }

    return Qnil;
  }

  /**
   * @todo   The list management is iffy. Should probably just
   *          always assume it is a list. --rue
   */
  ExecuteStatus Channel::receive_prim(STATE, Executable* exec, Task* task, Message& msg) {
    Thread* current = state->globals.current_thread.get();
    Task* real_task = current->task();

    real_task->active()->clear_stack(msg.stack);

    // @todo  check arity
    if(!value_->nil_p()) {
      List* list = as<List>(value_);

      real_task->push(list->shift(state));

      if(list->size() == 0) {
        value(state, Qnil);
      }

      return cExecuteContinue;
    }

    /* Saves space plus if thread woken forcibly, it gets the Qfalse. */
    real_task->push(Qfalse);

    current->sleep_for(state, this);
    waiting_->append(state, current);

    state->check_events();

    /* This sets the Task to continue from the next
     * opcode when it eventually reactivates. Its
     * stack will then have either the real received
     * value or the default Qfalse if the thread
     * was forced to stop waiting for us.
     */
    return cExecuteRestart;
  }

  Object* Channel::receive(STATE) {
    if(!value_->nil_p()) {
      Object* val = as<List>(value_)->shift(state);
      state->return_value(val);
      return Qnil;
    }

    /* We push nil on the stack to reserve a place to put the result. */
    state->return_value(Qfalse);

    G(current_thread)->sleep_for(state, this);
    waiting_->append(state, G(current_thread));

    state->run_best_thread();

    return Qnil;
  }

  bool Channel::has_readers_p() {
    return !waiting_->empty_p();
  }

  class SendToChannel : public ObjectCallback {
  public:
    TypedRoot<Channel*> chan;

    SendToChannel(STATE, Channel* chan) : ObjectCallback(state), chan(state, chan) { }

    virtual Object* object() {
      return chan.get();
    }

    virtual void call(Object* obj) {
      chan->send(state, obj);
    }
  };

  Object* Channel::send_on_signal(STATE, Channel* chan, Fixnum* signal) {
    SendToChannel* cb = new SendToChannel(state, chan);
    event::Signal* sig = new event::Signal(state, cb, signal->to_native());
    state->signal_events->start(sig);
    return signal;
  }

  Object* Channel::send_on_readable(STATE, Channel* chan, IO* io,
      Object* maybe_buffer, Fixnum* bytes) {

    SendToChannel* cb = new SendToChannel(state, chan);
    event::Read* sig = new event::Read(state, cb, io->to_fd());
    sig->into_buffer(maybe_buffer, bytes->to_native());

    state->events->start(sig);
    return io;
  }

  Object* Channel::send_in_microseconds(STATE, Channel* chan, Integer* useconds, Object* tag) {
    double seconds = useconds->to_native() / 1000000.0;

    return send_in_seconds(state, chan, seconds, tag);
  }

  Object* Channel::send_in_seconds(STATE, Channel* chan, Float* seconds, Object* tag) {
    return send_in_seconds(state, chan, seconds->to_double(state), tag);
  }

  Object* Channel::send_in_seconds(STATE, Channel* chan, double seconds, Object* tag) {
    SendToChannel* cb = new SendToChannel(state, chan);
    event::Timer* sig = new event::Timer(state, cb, seconds, tag);
    state->events->start(sig);
    return Qnil;
  }

  Object* Channel::send_on_stopped(VM* state, Channel* channel, Fixnum* pid, Fixnum* flags)
  {
    event::Child::add(state,
                      new SendToChannel(state, channel),
                      static_cast<pid_t>(pid->to_int()),
                      flags->to_int() );

    /* @todo Figure out the cancellation by id method. */
    return Qnil;
  }

/* ChannelCallback */

  ChannelCallback::ChannelCallback(STATE, Channel* chan) : ObjectCallback(state) {
    channel.set(chan, &GO(roots));
  }

  void ChannelCallback::call(Object* obj) {
    channel->send(state, obj);
  }
}
<|endoftext|>


<commit_before>/*******************************************************
 * Copyright (c) 2015-2019, ArrayFire
 * All rights reserved.
 *
 * This file is distributed under 3-clause BSD license.
 * The complete license agreement can be obtained at:
 * http://arrayfire.com/licenses/BSD-3-Clause
 ********************************************************/

#include <forge.h>
#define USE_FORGE_CPU_COPY_HELPERS
#include <ComputeCopy.h>
#include <complex>
#include <cmath>
#include <vector>
#include <iostream>

const unsigned DIMX = 640;
const unsigned DIMY = 480;
const float PI = 3.14159265359;
const float MINIMUM = 1.0f;
const float MAXIMUM = 20.f;
const float STEP    = 4.0f;
const int NELEMS    = (MAXIMUM-MINIMUM+1)/STEP;

using namespace std;

void generateColors(std::vector<float>& colors)
{
    static const float AF_BLUE[] = {0.0588f , 0.1137f , 0.2745f , 1.0f};
    static const float AF_ORANGE[] = {0.8588f , 0.6137f , 0.0745f , 1.0f};

    int numElems = NELEMS*NELEMS*NELEMS;
    colors.clear();
    for (int i=0; i<numElems; ++i) {
        if ((i%2) == 0) {
            colors.push_back(AF_ORANGE[0]);
            colors.push_back(AF_ORANGE[1]);
            colors.push_back(AF_ORANGE[2]);
        } else {
            colors.push_back(AF_BLUE[0]);
            colors.push_back(AF_BLUE[1]);
            colors.push_back(AF_BLUE[2]);
        }
    }
}

void moveColors(std::vector<float>& colors)
{
    int end = colors.size()-3;
    float r = colors[end+2];
    float g = colors[end+1];
    float b = colors[end];

    for (int i=0; i<end; i+=3) {
        colors[i] = r;
        colors[i+1] = g;
        colors[i+2] = b;

        r = colors[i+3];
        g = colors[i+4];
        b = colors[i+5];
    }
}

void generatePoints(std::vector<float> &points, std::vector<float> &dirs)
{
    points.clear();

    for (int k=0; k<NELEMS; ++k) {
        float z = MINIMUM + k*STEP;
        for (int j=0; j<NELEMS; ++j) {
            float y = MINIMUM + j*STEP;
            for (int i=0; i<NELEMS; ++i) {
                float x = MINIMUM + i*STEP;
                points.push_back(x);
                points.push_back(y);
                points.push_back(z);
                dirs.push_back(x-10.0f);
                dirs.push_back(y-10.0f);
                dirs.push_back(z-10.0f);
            }
        }
    }
}

int main(void)
{
    /*
     * First Forge call should be a window creation call
     * so that necessary OpenGL context is created for any
     * other forge::* object to be created successfully
     */
    forge::Window wnd(DIMX, DIMY, "3D Vector Field Demo");
    wnd.makeCurrent();

    forge::Chart chart(FG_CHART_3D);
    chart.setAxesLimits(MINIMUM-1.0f, MAXIMUM,
                        MINIMUM-1.0f, MAXIMUM,
                        MINIMUM-1.0f, MAXIMUM);
    chart.setAxesTitles("x-axis", "y-axis", "z-axis");

    int numElems = NELEMS*NELEMS*NELEMS;
    forge::VectorField field = chart.vectorField(numElems, forge::f32);
    field.setColor(0.f, 1.f, 0.f, 1.f);

    std::vector<float> points;
    std::vector<float> colors;
    std::vector<float> dirs;
    generatePoints(points, dirs);
    generateColors(colors);

    GfxHandle* handles[3];
    createGLBuffer(&handles[0], field.vertices(), FORGE_VBO);
    createGLBuffer(&handles[1], field.colors(), FORGE_VBO);
    createGLBuffer(&handles[2], field.directions(), FORGE_VBO);

    copyToGLBuffer(handles[0], (ComputeResourceHandle)points.data(),   field.verticesSize());
    copyToGLBuffer(handles[1], (ComputeResourceHandle)colors.data(),     field.colorsSize());
    copyToGLBuffer(handles[2], (ComputeResourceHandle)dirs.data()  , field.directionsSize());

    do {
        moveColors(colors);
        copyToGLBuffer(handles[1], (ComputeResourceHandle)colors.data(), field.colorsSize());
        wnd.draw(chart);
    } while(!wnd.close());

    releaseGLBuffer(handles[0]);
    releaseGLBuffer(handles[1]);
    releaseGLBuffer(handles[2]);

    return 0;
}
<commit_msg>Remove unused code from stream cpu example<commit_after>/*******************************************************
 * Copyright (c) 2015-2019, ArrayFire
 * All rights reserved.
 *
 * This file is distributed under 3-clause BSD license.
 * The complete license agreement can be obtained at:
 * http://arrayfire.com/licenses/BSD-3-Clause
 ********************************************************/

#include <forge.h>
#define USE_FORGE_CPU_COPY_HELPERS
#include <ComputeCopy.h>
#include <complex>
#include <cmath>
#include <vector>
#include <iostream>

const unsigned DIMX = 640;
const unsigned DIMY = 480;
const float PI = 3.14159265359;
const float MINIMUM = 1.0f;
const float MAXIMUM = 20.f;
const float STEP    = 4.0f;
const int NELEMS    = (MAXIMUM-MINIMUM+1)/STEP;

using namespace std;

void generateColors(std::vector<float>& colors)
{
    static const float AF_BLUE[] = {0.0588f , 0.1137f , 0.2745f , 1.0f};
    static const float AF_ORANGE[] = {0.8588f , 0.6137f , 0.0745f , 1.0f};

    int numElems = NELEMS*NELEMS*NELEMS;
    colors.clear();
    for (int i=0; i<numElems; ++i) {
        if ((i%2) == 0) {
            colors.push_back(AF_ORANGE[0]);
            colors.push_back(AF_ORANGE[1]);
            colors.push_back(AF_ORANGE[2]);
        } else {
            colors.push_back(AF_BLUE[0]);
            colors.push_back(AF_BLUE[1]);
            colors.push_back(AF_BLUE[2]);
        }
    }
}

void generatePoints(std::vector<float> &points, std::vector<float> &dirs)
{
    points.clear();

    for (int k=0; k<NELEMS; ++k) {
        float z = MINIMUM + k*STEP;
        for (int j=0; j<NELEMS; ++j) {
            float y = MINIMUM + j*STEP;
            for (int i=0; i<NELEMS; ++i) {
                float x = MINIMUM + i*STEP;
                points.push_back(x);
                points.push_back(y);
                points.push_back(z);
                dirs.push_back(x-10.0f);
                dirs.push_back(y-10.0f);
                dirs.push_back(z-10.0f);
            }
        }
    }
}

int main(void)
{
    /*
     * First Forge call should be a window creation call
     * so that necessary OpenGL context is created for any
     * other forge::* object to be created successfully
     */
    forge::Window wnd(DIMX, DIMY, "3D Vector Field Demo");
    wnd.makeCurrent();

    forge::Chart chart(FG_CHART_3D);
    chart.setAxesLimits(MINIMUM-1.0f, MAXIMUM,
                        MINIMUM-1.0f, MAXIMUM,
                        MINIMUM-1.0f, MAXIMUM);
    chart.setAxesTitles("x-axis", "y-axis", "z-axis");

    int numElems = NELEMS*NELEMS*NELEMS;
    forge::VectorField field = chart.vectorField(numElems, forge::f32);
    field.setColor(0.f, 1.f, 0.f, 1.f);

    std::vector<float> points;
    std::vector<float> colors;
    std::vector<float> dirs;
    generatePoints(points, dirs);
    generateColors(colors);

    GfxHandle* handles[3];
    createGLBuffer(&handles[0], field.vertices(), FORGE_VBO);
    createGLBuffer(&handles[1], field.colors(), FORGE_VBO);
    createGLBuffer(&handles[2], field.directions(), FORGE_VBO);

    copyToGLBuffer(handles[0], (ComputeResourceHandle)points.data(),   field.verticesSize());
    copyToGLBuffer(handles[1], (ComputeResourceHandle)colors.data(),     field.colorsSize());
    copyToGLBuffer(handles[2], (ComputeResourceHandle)dirs.data()  , field.directionsSize());

    do {
        wnd.draw(chart);
    } while(!wnd.close());

    releaseGLBuffer(handles[0]);
    releaseGLBuffer(handles[1]);
    releaseGLBuffer(handles[2]);

    return 0;
}
<|endoftext|>


<commit_before>/* Gobby - GTK-based collaborative text editor
 * Copyright (C) 2008-2015 Armin Burgmeier <armin@arbur.net>
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include "core/statusbar.hpp"
#include "util/i18n.hpp"

#include <glibmm/main.h>
#include <gtkmm/frame.h>
#include <gtkmm/image.h>

namespace
{
	const gchar*
	message_type_to_icon_name(Gobby::StatusBar::MessageType type)
	{
		switch(type)
		{
		case Gobby::StatusBar::INFO:
			return "dialog-information";
		case Gobby::StatusBar::ERROR:
			return "dialog-error";
		default:
			g_assert_not_reached();
			return NULL;
		}
	}

	void dispose_dialog(Gtk::MessageDialog* dialog)
	{
		delete dialog;
	}
}

class Gobby::StatusBar::Message
{
public:
	Message(Gtk::Widget* widget,
	        const Glib::ustring& simple,
	        const Glib::ustring& detail,
		sigc::connection timeout_conn = sigc::connection()):
		m_widget(widget), m_timeout_conn(timeout_conn),
		m_simple_desc(simple), m_detail_desc(detail)
	{
	}

	~Message()
	{
		m_timeout_conn.disconnect();
	}

	void show_dialog() const
	{
		Gtk::MessageDialog* dialog = new Gtk::MessageDialog(
			m_simple_desc,
			false,
			Gtk::MESSAGE_ERROR,
			Gtk::BUTTONS_NONE,
			false);

		dialog->add_button(_("_Close"), Gtk::RESPONSE_CLOSE);

		dialog->set_secondary_text(m_detail_desc, true);
		dialog->signal_response().connect(
			sigc::hide(
				sigc::bind(
					sigc::ptr_fun(dispose_dialog),
					dialog)));
		dialog->show();
	}

	bool is_error() { return !m_detail_desc.empty(); }

	const Glib::ustring& get_simple_text() const { return m_simple_desc; }
	const Glib::ustring& get_detail_text() const { return m_detail_desc; }

	Gtk::Widget* widget() const { return m_widget; }

protected:
	Gtk::Widget* m_widget;
	sigc::connection m_timeout_conn;
	Glib::ustring m_simple_desc;
	Glib::ustring m_detail_desc;
};

Gobby::StatusBar::StatusBar(const Folder& folder,
                            const Preferences& preferences):
	m_folder(folder), m_preferences(preferences),
	m_visible_messages(0), m_current_view(NULL)
{
	set_column_spacing(2);

	m_lbl_position.set_halign(Gtk::ALIGN_END);
	m_lbl_position.set_hexpand(true);
	m_lbl_position.set_margin_end(6);
	m_lbl_position.show();
	attach(m_lbl_position, 0, 0, 1, 1);

	m_folder.signal_document_removed().connect(
		sigc::mem_fun(*this, &StatusBar::on_document_removed));
	m_folder.signal_document_changed().connect(
		sigc::mem_fun(*this, &StatusBar::on_document_changed));
	m_preferences.appearance.show_statusbar.signal_changed().connect(
		sigc::mem_fun(*this, &StatusBar::on_view_changed));

	// Initial update
	on_document_changed(m_folder.get_current_document());
	on_view_changed();
}

Gobby::StatusBar::~StatusBar()
{
	on_document_changed(NULL);
}

Gobby::StatusBar::MessageHandle
Gobby::StatusBar::add_message(Gobby::StatusBar::MessageType type,
                              const Glib::ustring& message,
                              const Glib::ustring& dialog_message,
                              unsigned int timeout)
{
	if(m_visible_messages >= 12)
	{
		for(MessageHandle iter = m_list.begin();
		    iter != m_list.end();
		    ++iter)
		{
			if(*iter)
			{
				if((*iter)->is_error())
					remove_message(iter);
				else
					// only hide message because whoever
					// installed it is expecting to be
					// able to call remove_message on it
					hide_message(iter);
				break;
			}
		}
	}

	Gtk::Grid* grid = Gtk::manage(new Gtk::Grid());
	grid->set_column_spacing(6);
	grid->set_margin_start(2);
	grid->set_margin_end(2);

	Gtk::Image* image = Gtk::manage(new Gtk::Image);
	image->set_from_icon_name(message_type_to_icon_name(type),
	                          Gtk::ICON_SIZE_MENU);
	grid->attach(*image, 0, 0, 1, 1);
	image->show();

	Gtk::Label* label = Gtk::manage(
		new Gtk::Label(message, Gtk::ALIGN_START));
	label->set_ellipsize(Pango::ELLIPSIZE_END);

	// If we set halign instead, the label will not behave correctly
	// when ellipsized, because then it has always all space around it
	// allocated, and the alignment "jumps" around whin resizing the
	// window due to new characters appearing or disappearing as a result
	// of the ellipsization.
#if GTK_CHECK_VERSION(3, 16, 0)
	gtk_label_set_xalign(label->gobj(), 0.0);
#else
	label->set_alignment(0.0, 0.0);
#endif
	label->show();
	grid->attach(*label, 1, 0, 1, 1);

	Gtk::Frame* frame = Gtk::manage(new Gtk::Frame);

	m_list.push_back(0);
	Gobby::StatusBar::MessageHandle iter(--m_list.end());
	sigc::connection timeout_conn;
	if(timeout)
	{
		timeout_conn = Glib::signal_timeout().connect_seconds(
			sigc::bind(
				sigc::bind_return(
					sigc::mem_fun(
						*this,
						&StatusBar::remove_message),
					false),
				iter),
			timeout);
	}
	*iter = new Message(frame, message, dialog_message, timeout_conn);
	++m_visible_messages;

	if(dialog_message.empty())
	{
		frame->add(*grid);
	}
	else
	{
		Gtk::EventBox *eventbox = Gtk::manage(new Gtk::EventBox);
		frame->add(*eventbox);
		eventbox->add(*grid);
		eventbox->signal_button_press_event().connect(
			sigc::bind_return(sigc::bind(
				sigc::mem_fun(
					*this,
					&StatusBar::on_message_clicked),
				iter), false));

		eventbox->show();
	}

	grid->show();

	// Insert at front
	gtk_grid_attach_next_to(
		gobj(), GTK_WIDGET(frame->gobj()),
		NULL, GTK_POS_LEFT, 1, 1);

	frame->set_halign(Gtk::ALIGN_START);
	frame->set_hexpand(false);
	frame->set_shadow_type(Gtk::SHADOW_NONE);
	frame->show();

	return iter;
}

Gobby::StatusBar::MessageHandle
Gobby::StatusBar::add_info_message(const Glib::ustring& message,
                                   unsigned int timeout)
{
	MessageHandle handle =
		Gobby::StatusBar::add_message(INFO, message, "", timeout);
	// Caller is not allowed to hold on to handles to messages that we are
	// going to delete anyway.
	if(timeout)
		return invalid_handle();
	else
		return handle;
}

void
Gobby::StatusBar::add_error_message(const Glib::ustring& brief_desc,
                                    const Glib::ustring& detailed_desc,
                                    unsigned int timeout)
{
	MessageHandle next;
	for(MessageHandle iter = m_list.begin(); iter != m_list.end(); iter = next)
	{
		next = iter;
		++next;

		if(*iter && (*iter)->is_error())
		{
			if( (*iter)->get_simple_text() == brief_desc)
			{
				remove_message(iter);
			}
		}
	}

	Gobby::StatusBar::add_message(ERROR,
	                              brief_desc,
	                              detailed_desc,
	                              timeout);
}

void Gobby::StatusBar::remove_message(const MessageHandle& handle)
{
	hide_message(handle);
	m_list.erase(handle);
}

void Gobby::StatusBar::hide_message(const MessageHandle& handle)
{
	if(*handle != 0)
	{
		g_assert(m_visible_messages > 0);
		--m_visible_messages;
		remove(*(*handle)->widget());
		delete *handle;
		*handle = 0;
	}
}

Gobby::StatusBar::MessageHandle Gobby::StatusBar::invalid_handle()
{
	return m_list.end();
}

void Gobby::StatusBar::on_message_clicked(GdkEventButton* button,
                                          const MessageHandle& handle)
{
	if(button->button == 1)
		(*handle)->show_dialog();

	remove_message(handle);
}

void Gobby::StatusBar::on_document_removed(SessionView& view)
{
	if(m_current_view == &view)
	{
		GtkTextBuffer* buffer = GTK_TEXT_BUFFER(
			m_current_view->get_text_buffer());

		g_signal_handler_disconnect(buffer, m_mark_set_handler);
		g_signal_handler_disconnect(buffer, m_changed_handler);
		g_signal_handler_disconnect(m_current_view->get_text_view(),
		                            m_toverwrite_handler);

		m_current_view = NULL;
	}
}

void Gobby::StatusBar::on_document_changed(SessionView* view)
{
	if(m_current_view)
	{
		GtkTextBuffer* buffer = GTK_TEXT_BUFFER(
			m_current_view->get_text_buffer());

		g_signal_handler_disconnect(buffer, m_mark_set_handler);
		g_signal_handler_disconnect(buffer, m_changed_handler);
		g_signal_handler_disconnect(m_current_view->get_text_view(),
		                            m_toverwrite_handler);
	}

	m_current_view = dynamic_cast<TextSessionView*>(view);

	if(m_current_view)
	{
		GtkTextBuffer* buffer = GTK_TEXT_BUFFER(
			m_current_view->get_text_buffer());

		m_mark_set_handler = g_signal_connect_after(
			G_OBJECT(buffer), "mark-set",
			G_CALLBACK(on_mark_set_static), this);

		m_changed_handler = g_signal_connect_after(
			G_OBJECT(buffer), "changed",
			G_CALLBACK(on_changed_static), this);

		m_toverwrite_handler = g_signal_connect_after(
			G_OBJECT(m_current_view->get_text_view()),
			"notify::overwrite",
			G_CALLBACK(on_toggled_overwrite_static), this);
	}

	// Initial update
	update_pos_display();
}

void Gobby::StatusBar::on_view_changed()
{
	if(m_preferences.appearance.show_statusbar) show();
	else hide();
}

void Gobby::StatusBar::on_mark_set(GtkTextMark* mark)
{
	GtkTextBuffer* buffer = GTK_TEXT_BUFFER(
		m_current_view->get_text_buffer());

	if(mark == gtk_text_buffer_get_insert(buffer))
		update_pos_display();
}

void Gobby::StatusBar::on_toggled_overwrite()
{
	update_pos_display();
}

void Gobby::StatusBar::on_changed()
{
	update_pos_display();
}

void Gobby::StatusBar::update_pos_display()
{
	if(m_current_view != NULL)
	{
		GtkTextBuffer* buffer = GTK_TEXT_BUFFER(
			m_current_view->get_text_buffer());
		GtkTextIter iter;

		// TODO: Use TextSessionView::get_cursor_position()?
		gtk_text_buffer_get_iter_at_mark(
			buffer, &iter, gtk_text_buffer_get_insert(buffer));

		gint offset = gtk_text_iter_get_line_offset(&iter);

		unsigned int column = 0;
		const unsigned int tab_width = m_preferences.editor.tab_width;
		for(gtk_text_iter_set_line_offset(&iter, 0);
		    gtk_text_iter_get_line_offset(&iter) < offset;
		    gtk_text_iter_forward_char(&iter))
		{
			if(gtk_text_iter_get_char(&iter) == '\t')
				column += (tab_width - column % tab_width);
			else
				++ column;
		}

		// TODO: We might want to have a separate widget for the
		// OVR/INS display.
		m_lbl_position.set_text(
			Glib::ustring::compose(
				_("Ln %1, Col %2\t%3"),
				gtk_text_iter_get_line(&iter) + 1,
				column + 1,
				gtk_text_view_get_overwrite(GTK_TEXT_VIEW(m_current_view->get_text_view())) ? _("OVR") : _("INS")
			)
		);
	}
	else
	{
		m_lbl_position.set_text("");
	}
}
<commit_msg>Make statusbar error dialogs have a transient parent<commit_after>/* Gobby - GTK-based collaborative text editor
 * Copyright (C) 2008-2015 Armin Burgmeier <armin@arbur.net>
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include "core/statusbar.hpp"
#include "util/i18n.hpp"

#include <glibmm/main.h>
#include <gtkmm/frame.h>
#include <gtkmm/image.h>

namespace
{
	const gchar*
	message_type_to_icon_name(Gobby::StatusBar::MessageType type)
	{
		switch(type)
		{
		case Gobby::StatusBar::INFO:
			return "dialog-information";
		case Gobby::StatusBar::ERROR:
			return "dialog-error";
		default:
			g_assert_not_reached();
			return NULL;
		}
	}

	void dispose_dialog(Gtk::MessageDialog* dialog)
	{
		delete dialog;
	}
}

class Gobby::StatusBar::Message
{
public:
	Message(Gtk::Widget* widget,
	        const Glib::ustring& simple,
	        const Glib::ustring& detail,
		sigc::connection timeout_conn = sigc::connection()):
		m_widget(widget), m_timeout_conn(timeout_conn),
		m_simple_desc(simple), m_detail_desc(detail)
	{
	}

	~Message()
	{
		m_timeout_conn.disconnect();
	}

	void show_dialog() const
	{
		Gtk::MessageDialog* dialog = new Gtk::MessageDialog(
			m_simple_desc,
			false,
			Gtk::MESSAGE_ERROR,
			Gtk::BUTTONS_NONE,
			false);

		Gtk::Window* parent = NULL;
		Gtk::Widget* toplevel_widget = m_widget->get_toplevel();
		if(gtk_widget_is_toplevel(toplevel_widget->gobj()))
			parent = dynamic_cast<Gtk::Window*>(toplevel_widget);

		g_assert(parent != NULL);
		dialog->set_transient_for(*parent);

		dialog->add_button(_("_Close"), Gtk::RESPONSE_CLOSE);

		dialog->set_secondary_text(m_detail_desc, true);
		dialog->signal_response().connect(
			sigc::hide(
				sigc::bind(
					sigc::ptr_fun(dispose_dialog),
					dialog)));
		dialog->show();
	}

	bool is_error() { return !m_detail_desc.empty(); }

	const Glib::ustring& get_simple_text() const { return m_simple_desc; }
	const Glib::ustring& get_detail_text() const { return m_detail_desc; }

	Gtk::Widget* widget() const { return m_widget; }

protected:
	Gtk::Widget* m_widget;
	sigc::connection m_timeout_conn;
	Glib::ustring m_simple_desc;
	Glib::ustring m_detail_desc;
};

Gobby::StatusBar::StatusBar(const Folder& folder,
                            const Preferences& preferences):
	m_folder(folder), m_preferences(preferences),
	m_visible_messages(0), m_current_view(NULL)
{
	set_column_spacing(2);

	m_lbl_position.set_halign(Gtk::ALIGN_END);
	m_lbl_position.set_hexpand(true);
	m_lbl_position.set_margin_end(6);
	m_lbl_position.show();
	attach(m_lbl_position, 0, 0, 1, 1);

	m_folder.signal_document_removed().connect(
		sigc::mem_fun(*this, &StatusBar::on_document_removed));
	m_folder.signal_document_changed().connect(
		sigc::mem_fun(*this, &StatusBar::on_document_changed));
	m_preferences.appearance.show_statusbar.signal_changed().connect(
		sigc::mem_fun(*this, &StatusBar::on_view_changed));

	// Initial update
	on_document_changed(m_folder.get_current_document());
	on_view_changed();
}

Gobby::StatusBar::~StatusBar()
{
	on_document_changed(NULL);
}

Gobby::StatusBar::MessageHandle
Gobby::StatusBar::add_message(Gobby::StatusBar::MessageType type,
                              const Glib::ustring& message,
                              const Glib::ustring& dialog_message,
                              unsigned int timeout)
{
	if(m_visible_messages >= 12)
	{
		for(MessageHandle iter = m_list.begin();
		    iter != m_list.end();
		    ++iter)
		{
			if(*iter)
			{
				if((*iter)->is_error())
					remove_message(iter);
				else
					// only hide message because whoever
					// installed it is expecting to be
					// able to call remove_message on it
					hide_message(iter);
				break;
			}
		}
	}

	Gtk::Grid* grid = Gtk::manage(new Gtk::Grid());
	grid->set_column_spacing(6);
	grid->set_margin_start(2);
	grid->set_margin_end(2);

	Gtk::Image* image = Gtk::manage(new Gtk::Image);
	image->set_from_icon_name(message_type_to_icon_name(type),
	                          Gtk::ICON_SIZE_MENU);
	grid->attach(*image, 0, 0, 1, 1);
	image->show();

	Gtk::Label* label = Gtk::manage(
		new Gtk::Label(message, Gtk::ALIGN_START));
	label->set_ellipsize(Pango::ELLIPSIZE_END);

	// If we set halign instead, the label will not behave correctly
	// when ellipsized, because then it has always all space around it
	// allocated, and the alignment "jumps" around whin resizing the
	// window due to new characters appearing or disappearing as a result
	// of the ellipsization.
#if GTK_CHECK_VERSION(3, 16, 0)
	gtk_label_set_xalign(label->gobj(), 0.0);
#else
	label->set_alignment(0.0, 0.0);
#endif
	label->show();
	grid->attach(*label, 1, 0, 1, 1);

	Gtk::Frame* frame = Gtk::manage(new Gtk::Frame);

	m_list.push_back(0);
	Gobby::StatusBar::MessageHandle iter(--m_list.end());
	sigc::connection timeout_conn;
	if(timeout)
	{
		timeout_conn = Glib::signal_timeout().connect_seconds(
			sigc::bind(
				sigc::bind_return(
					sigc::mem_fun(
						*this,
						&StatusBar::remove_message),
					false),
				iter),
			timeout);
	}
	*iter = new Message(frame, message, dialog_message, timeout_conn);
	++m_visible_messages;

	if(dialog_message.empty())
	{
		frame->add(*grid);
	}
	else
	{
		Gtk::EventBox *eventbox = Gtk::manage(new Gtk::EventBox);
		frame->add(*eventbox);
		eventbox->add(*grid);
		eventbox->signal_button_press_event().connect(
			sigc::bind_return(sigc::bind(
				sigc::mem_fun(
					*this,
					&StatusBar::on_message_clicked),
				iter), false));

		eventbox->show();
	}

	grid->show();

	// Insert at front
	gtk_grid_attach_next_to(
		gobj(), GTK_WIDGET(frame->gobj()),
		NULL, GTK_POS_LEFT, 1, 1);

	frame->set_halign(Gtk::ALIGN_START);
	frame->set_hexpand(false);
	frame->set_shadow_type(Gtk::SHADOW_NONE);
	frame->show();

	return iter;
}

Gobby::StatusBar::MessageHandle
Gobby::StatusBar::add_info_message(const Glib::ustring& message,
                                   unsigned int timeout)
{
	MessageHandle handle =
		Gobby::StatusBar::add_message(INFO, message, "", timeout);
	// Caller is not allowed to hold on to handles to messages that we are
	// going to delete anyway.
	if(timeout)
		return invalid_handle();
	else
		return handle;
}

void
Gobby::StatusBar::add_error_message(const Glib::ustring& brief_desc,
                                    const Glib::ustring& detailed_desc,
                                    unsigned int timeout)
{
	MessageHandle next;
	for(MessageHandle iter = m_list.begin(); iter != m_list.end(); iter = next)
	{
		next = iter;
		++next;

		if(*iter && (*iter)->is_error())
		{
			if( (*iter)->get_simple_text() == brief_desc)
			{
				remove_message(iter);
			}
		}
	}

	Gobby::StatusBar::add_message(ERROR,
	                              brief_desc,
	                              detailed_desc,
	                              timeout);
}

void Gobby::StatusBar::remove_message(const MessageHandle& handle)
{
	hide_message(handle);
	m_list.erase(handle);
}

void Gobby::StatusBar::hide_message(const MessageHandle& handle)
{
	if(*handle != 0)
	{
		g_assert(m_visible_messages > 0);
		--m_visible_messages;
		remove(*(*handle)->widget());
		delete *handle;
		*handle = 0;
	}
}

Gobby::StatusBar::MessageHandle Gobby::StatusBar::invalid_handle()
{
	return m_list.end();
}

void Gobby::StatusBar::on_message_clicked(GdkEventButton* button,
                                          const MessageHandle& handle)
{
	if(button->button == 1)
		(*handle)->show_dialog();

	remove_message(handle);
}

void Gobby::StatusBar::on_document_removed(SessionView& view)
{
	if(m_current_view == &view)
	{
		GtkTextBuffer* buffer = GTK_TEXT_BUFFER(
			m_current_view->get_text_buffer());

		g_signal_handler_disconnect(buffer, m_mark_set_handler);
		g_signal_handler_disconnect(buffer, m_changed_handler);
		g_signal_handler_disconnect(m_current_view->get_text_view(),
		                            m_toverwrite_handler);

		m_current_view = NULL;
	}
}

void Gobby::StatusBar::on_document_changed(SessionView* view)
{
	if(m_current_view)
	{
		GtkTextBuffer* buffer = GTK_TEXT_BUFFER(
			m_current_view->get_text_buffer());

		g_signal_handler_disconnect(buffer, m_mark_set_handler);
		g_signal_handler_disconnect(buffer, m_changed_handler);
		g_signal_handler_disconnect(m_current_view->get_text_view(),
		                            m_toverwrite_handler);
	}

	m_current_view = dynamic_cast<TextSessionView*>(view);

	if(m_current_view)
	{
		GtkTextBuffer* buffer = GTK_TEXT_BUFFER(
			m_current_view->get_text_buffer());

		m_mark_set_handler = g_signal_connect_after(
			G_OBJECT(buffer), "mark-set",
			G_CALLBACK(on_mark_set_static), this);

		m_changed_handler = g_signal_connect_after(
			G_OBJECT(buffer), "changed",
			G_CALLBACK(on_changed_static), this);

		m_toverwrite_handler = g_signal_connect_after(
			G_OBJECT(m_current_view->get_text_view()),
			"notify::overwrite",
			G_CALLBACK(on_toggled_overwrite_static), this);
	}

	// Initial update
	update_pos_display();
}

void Gobby::StatusBar::on_view_changed()
{
	if(m_preferences.appearance.show_statusbar) show();
	else hide();
}

void Gobby::StatusBar::on_mark_set(GtkTextMark* mark)
{
	GtkTextBuffer* buffer = GTK_TEXT_BUFFER(
		m_current_view->get_text_buffer());

	if(mark == gtk_text_buffer_get_insert(buffer))
		update_pos_display();
}

void Gobby::StatusBar::on_toggled_overwrite()
{
	update_pos_display();
}

void Gobby::StatusBar::on_changed()
{
	update_pos_display();
}

void Gobby::StatusBar::update_pos_display()
{
	if(m_current_view != NULL)
	{
		GtkTextBuffer* buffer = GTK_TEXT_BUFFER(
			m_current_view->get_text_buffer());
		GtkTextIter iter;

		// TODO: Use TextSessionView::get_cursor_position()?
		gtk_text_buffer_get_iter_at_mark(
			buffer, &iter, gtk_text_buffer_get_insert(buffer));

		gint offset = gtk_text_iter_get_line_offset(&iter);

		unsigned int column = 0;
		const unsigned int tab_width = m_preferences.editor.tab_width;
		for(gtk_text_iter_set_line_offset(&iter, 0);
		    gtk_text_iter_get_line_offset(&iter) < offset;
		    gtk_text_iter_forward_char(&iter))
		{
			if(gtk_text_iter_get_char(&iter) == '\t')
				column += (tab_width - column % tab_width);
			else
				++ column;
		}

		// TODO: We might want to have a separate widget for the
		// OVR/INS display.
		m_lbl_position.set_text(
			Glib::ustring::compose(
				_("Ln %1, Col %2\t%3"),
				gtk_text_iter_get_line(&iter) + 1,
				column + 1,
				gtk_text_view_get_overwrite(GTK_TEXT_VIEW(m_current_view->get_text_view())) ? _("OVR") : _("INS")
			)
		);
	}
	else
	{
		m_lbl_position.set_text("");
	}
}
<|endoftext|>


<commit_before>#include "imageview.h"
#include "experimentcontext.h"
#include "resultspanel.h"
#include "../ori/OriWidgets.h"
#include "appconfig.h"

#include <QBoxLayout>
#include <QLabel>
#include <QVariant>
#include <QDebug>
#include <QDateTime>
#include <QPushButton>

#define WORST_PREDICTED_IMAGE_W 160
#define WORST_PREDICTED_IMAGE_H 120

static QObject* spacing(int px) {
    return reinterpret_cast<QObject*>(px);
}

ResultsPanel::ResultsPanel(ExperimentContext *context, QWidget *parent)
    : QFrame(parent), _updateIntervalMs(AppConfig::fpsUpdateIntervalMs())
{
    setObjectName("resultsPanel");

    _context = context;
    connect(_context, &ExperimentContext::experimentStarted, this, &ResultsPanel::experimentStarted);
    connect(_context, &ExperimentContext::newImageResult, this, &ResultsPanel::newImageResult);
    connect(_context, &ExperimentContext::modeChanged, this, &ResultsPanel::updateOnModeChanged);
    connect(_context, &ExperimentContext::zoomChanged, this, &ResultsPanel::updateOnZoomChanged);

    _infoImagesPerSec = makeInfoLabel();
    _infoPrecision = makeInfoLabel();
    _infoMetricTop1 = makeInfoLabel();
    _infoMetricTop5 = makeInfoLabel();

    _worstPredictedImage = new ImageView(WORST_PREDICTED_IMAGE_W, WORST_PREDICTED_IMAGE_H);

    auto panelCounters = makePanel({ Ori::Gui::makeTitle("IMAGES PER SECOND"), _infoImagesPerSec });
    _panelPrecision = makePanel({ Ori::Gui::makeTitle("AVERAGE PRECISION"), _infoPrecision });
    auto panelMetricTop1 = makePanel({ Ori::Gui::makeTitle("TOP-1"), _infoMetricTop1 });
    auto panelMetricTop5 = makePanel({ Ori::Gui::makeTitle("TOP-5"), _infoMetricTop5 });
    _panelMetrics = new QFrame;
    _panelMetrics->setLayout(Ori::Gui::layoutH(0, 0, { panelMetricTop1, panelMetricTop5 }));
    _panelWorstPrediction = makePanel({
        Ori::Gui::makeTitle("WORST PREDICTION"),
        Ori::Gui::layoutH(0, 0, { 0, _worstPredictedImage, 0}),
    });

    auto buttonZoomIn = new QPushButton;
    buttonZoomIn->setObjectName("buttonZoomIn");
    buttonZoomIn->setToolTip(tr("Zoom in"));
    buttonZoomIn->setIcon(QIcon(":/tools/zoom-in"));
    connect(buttonZoomIn, SIGNAL(clicked(bool)), _context, SLOT(zoomIn()));

    auto buttonZoomOut = new QPushButton;
    buttonZoomOut->setObjectName("buttonZoomOut");
    buttonZoomOut->setToolTip(tr("Zoom out"));
    buttonZoomOut->setIcon(QIcon(":/tools/zoom-out"));
    connect(buttonZoomOut, SIGNAL(clicked(bool)), _context, SLOT(zoomOut()));

    auto buttonZoomActual = new QPushButton;
    buttonZoomActual->setObjectName("buttonZoomActual");
    buttonZoomActual->setToolTip(tr("Actual size"));
    buttonZoomActual->setIcon(QIcon(":/tools/zoom-to-actual-size"));
    connect(buttonZoomActual, SIGNAL(clicked(bool)), _context, SLOT(zoomActual()));

    _infoZoom = new QLabel;
    _infoZoom->setAlignment(Qt::AlignTop | Qt::AlignRight);
    _infoZoom->setProperty("qss-role", "link");

    auto zoomLayout = Ori::Gui::layoutH({buttonZoomIn, spacing(8), buttonZoomOut, 0, buttonZoomActual});
    _panelZoom = makePanel({
        Ori::Gui::layoutH({ Ori::Gui::makeTitle("ZOOM"), 0, _infoZoom }),
        zoomLayout
    });

    setLayout(Ori::Gui::layoutV(0, 0,
        { panelCounters, _panelPrecision, _panelZoom, _panelMetrics, _panelWorstPrediction, 0 }));

    resetInfo();
    updateOnModeChanged(AppConfig::currentMode().value<Mode>());
    updateOnZoomChanged(AppConfig::zoom());
}

QLabel* ResultsPanel::makeInfoLabel(const QString &role) {
    auto label = new QLabel;
    label->setProperty("qss-role", role.isEmpty() ? QString("info-label") : role);
    return label;
}

QFrame* ResultsPanel::makePanel(const std::initializer_list<QObject *> &items, const QString &objectName) {
    auto panel = new QFrame;
    panel->setProperty("qss-role", "results-panel");
    panel->setObjectName(objectName);
    panel->setLayout(Ori::Gui::layoutV(0, 0, items));
    return panel;
}

void ResultsPanel::experimentStarted(bool resume) {
    if (!resume) {
        resetInfo();
    }
}

void ResultsPanel::newImageResult(ImageResult ir) {
    qint64 curTimeMs = QDateTime::currentMSecsSinceEpoch();
    if (curTimeMs - _lastUpdateMs > _updateIntervalMs) {
        _infoImagesPerSec->setText(QString(QStringLiteral("%1")).arg(ir.imagesPerSecond(), 0, 'f', 2));
        _infoPrecision->setText(QString(QStringLiteral("%1")).arg(_context->precision().avg, 0, 'f', 2));
        _infoMetricTop1->setText(QString::number(_context->top1().avg, 'f', 2));
        _infoMetricTop5->setText(QString::number(_context->top5().avg, 'f', 2));

        double accuracyDelta = ir.accuracyDelta();
        if (accuracyDelta > _worstAccuracyDelta) {
            _worstAccuracyDelta = accuracyDelta;
            _worstPredictedImage->loadImage(ir.imageFile);
            _worstPredictedImage->setToolTip(QString(QStringLiteral("%1\nTop1: %2\nCorrect: %3"))
                                             .arg(ir.imageFile)
                                             .arg(ir.predictions[0].str())
                                             .arg(ir.findCorrect()->str()));
        }
        _lastUpdateMs = curTimeMs;
    }
}

void ResultsPanel::resetInfo() {
    _infoImagesPerSec->setText("N/A");
    _infoPrecision->setText("N/A");
    _infoMetricTop1->setText("N/A");
    _infoMetricTop5->setText("N/A");
    _worstAccuracyDelta = 0;
    _worstPredictedImage->clearImage();
    _worstPredictedImage->setToolTip("");
    _lastUpdateMs = 0;
}

void ResultsPanel::updateOnModeChanged(Mode mode) {
    bool v = mode.type == Mode::Type::CLASSIFICATION;
    _panelMetrics->setVisible(v);
    _panelWorstPrediction->setVisible(v);
    _panelPrecision->setVisible(!v);
    _panelZoom->setVisible(!v);
}

void ResultsPanel::updateOnZoomChanged(double z) {
    int p = z * 100;
    _infoZoom->setText(QString("%1%").arg(p));
}
<commit_msg>Chnage zoom controls layout<commit_after>#include "imageview.h"
#include "experimentcontext.h"
#include "resultspanel.h"
#include "../ori/OriWidgets.h"
#include "appconfig.h"

#include <QBoxLayout>
#include <QLabel>
#include <QVariant>
#include <QDebug>
#include <QDateTime>
#include <QPushButton>

#define WORST_PREDICTED_IMAGE_W 160
#define WORST_PREDICTED_IMAGE_H 120

static QObject* spacing(int px) {
    return reinterpret_cast<QObject*>(px);
}

ResultsPanel::ResultsPanel(ExperimentContext *context, QWidget *parent)
    : QFrame(parent), _updateIntervalMs(AppConfig::fpsUpdateIntervalMs())
{
    setObjectName("resultsPanel");

    _context = context;
    connect(_context, &ExperimentContext::experimentStarted, this, &ResultsPanel::experimentStarted);
    connect(_context, &ExperimentContext::newImageResult, this, &ResultsPanel::newImageResult);
    connect(_context, &ExperimentContext::modeChanged, this, &ResultsPanel::updateOnModeChanged);
    connect(_context, &ExperimentContext::zoomChanged, this, &ResultsPanel::updateOnZoomChanged);

    _infoImagesPerSec = makeInfoLabel();
    _infoPrecision = makeInfoLabel();
    _infoMetricTop1 = makeInfoLabel();
    _infoMetricTop5 = makeInfoLabel();

    _worstPredictedImage = new ImageView(WORST_PREDICTED_IMAGE_W, WORST_PREDICTED_IMAGE_H);

    auto panelCounters = makePanel({ Ori::Gui::makeTitle("IMAGES PER SECOND"), _infoImagesPerSec });
    _panelPrecision = makePanel({ Ori::Gui::makeTitle("AVERAGE PRECISION"), _infoPrecision });
    auto panelMetricTop1 = makePanel({ Ori::Gui::makeTitle("TOP-1"), _infoMetricTop1 });
    auto panelMetricTop5 = makePanel({ Ori::Gui::makeTitle("TOP-5"), _infoMetricTop5 });
    _panelMetrics = new QFrame;
    _panelMetrics->setLayout(Ori::Gui::layoutH(0, 0, { panelMetricTop1, panelMetricTop5 }));
    _panelWorstPrediction = makePanel({
        Ori::Gui::makeTitle("WORST PREDICTION"),
        Ori::Gui::layoutH(0, 0, { 0, _worstPredictedImage, 0}),
    });

    auto buttonZoomIn = new QPushButton;
    buttonZoomIn->setObjectName("buttonZoomIn");
    buttonZoomIn->setToolTip(tr("Zoom in"));
    buttonZoomIn->setIcon(QIcon(":/tools/zoom-in"));
    connect(buttonZoomIn, SIGNAL(clicked(bool)), _context, SLOT(zoomIn()));

    auto buttonZoomOut = new QPushButton;
    buttonZoomOut->setObjectName("buttonZoomOut");
    buttonZoomOut->setToolTip(tr("Zoom out"));
    buttonZoomOut->setIcon(QIcon(":/tools/zoom-out"));
    connect(buttonZoomOut, SIGNAL(clicked(bool)), _context, SLOT(zoomOut()));

    auto buttonZoomActual = new QPushButton;
    buttonZoomActual->setObjectName("buttonZoomActual");
    buttonZoomActual->setToolTip(tr("Actual size"));
    buttonZoomActual->setIcon(QIcon(":/tools/zoom-to-actual-size"));
    connect(buttonZoomActual, SIGNAL(clicked(bool)), _context, SLOT(zoomActual()));

    _infoZoom = makeInfoLabel();

    auto zoomLayout = Ori::Gui::layoutH({_infoZoom, 0, buttonZoomActual, spacing(8), buttonZoomOut, spacing(8), buttonZoomIn});
    _panelZoom = makePanel({
        Ori::Gui::makeTitle("ZOOM"),
        zoomLayout
    });

    setLayout(Ori::Gui::layoutV(0, 0,
        { panelCounters, _panelPrecision, _panelZoom, _panelMetrics, _panelWorstPrediction, 0 }));

    resetInfo();
    updateOnModeChanged(AppConfig::currentMode().value<Mode>());
    updateOnZoomChanged(AppConfig::zoom());
}

QLabel* ResultsPanel::makeInfoLabel(const QString &role) {
    auto label = new QLabel;
    label->setProperty("qss-role", role.isEmpty() ? QString("info-label") : role);
    return label;
}

QFrame* ResultsPanel::makePanel(const std::initializer_list<QObject *> &items, const QString &objectName) {
    auto panel = new QFrame;
    panel->setProperty("qss-role", "results-panel");
    panel->setObjectName(objectName);
    panel->setLayout(Ori::Gui::layoutV(0, 0, items));
    return panel;
}

void ResultsPanel::experimentStarted(bool resume) {
    if (!resume) {
        resetInfo();
    }
}

void ResultsPanel::newImageResult(ImageResult ir) {
    qint64 curTimeMs = QDateTime::currentMSecsSinceEpoch();
    if (curTimeMs - _lastUpdateMs > _updateIntervalMs) {
        _infoImagesPerSec->setText(QString(QStringLiteral("%1")).arg(ir.imagesPerSecond(), 0, 'f', 2));
        _infoPrecision->setText(QString(QStringLiteral("%1")).arg(_context->precision().avg, 0, 'f', 2));
        _infoMetricTop1->setText(QString::number(_context->top1().avg, 'f', 2));
        _infoMetricTop5->setText(QString::number(_context->top5().avg, 'f', 2));

        double accuracyDelta = ir.accuracyDelta();
        if (accuracyDelta > _worstAccuracyDelta) {
            _worstAccuracyDelta = accuracyDelta;
            _worstPredictedImage->loadImage(ir.imageFile);
            _worstPredictedImage->setToolTip(QString(QStringLiteral("%1\nTop1: %2\nCorrect: %3"))
                                             .arg(ir.imageFile)
                                             .arg(ir.predictions[0].str())
                                             .arg(ir.findCorrect()->str()));
        }
        _lastUpdateMs = curTimeMs;
    }
}

void ResultsPanel::resetInfo() {
    _infoImagesPerSec->setText("N/A");
    _infoPrecision->setText("N/A");
    _infoMetricTop1->setText("N/A");
    _infoMetricTop5->setText("N/A");
    _worstAccuracyDelta = 0;
    _worstPredictedImage->clearImage();
    _worstPredictedImage->setToolTip("");
    _lastUpdateMs = 0;
}

void ResultsPanel::updateOnModeChanged(Mode mode) {
    bool v = mode.type == Mode::Type::CLASSIFICATION;
    _panelMetrics->setVisible(v);
    _panelWorstPrediction->setVisible(v);
    _panelPrecision->setVisible(!v);
    _panelZoom->setVisible(!v);
}

void ResultsPanel::updateOnZoomChanged(double z) {
    int p = z * 100;
    _infoZoom->setText(QString("%1%").arg(p));
}
<|endoftext|>


<commit_before>#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <iostream>
#include <fstream>
#include <boost/lexical_cast.hpp>
#include "packet.h"

#define USAGE "Usage:\r\nc \r\n[tux machine number] \r\n[probability of packet corruption in int form] \r\n[probability of packet loss in int form] \r\n[probability of packet delay] \r\n[length of delay in ms] \r\n"
#define PORT 10038
#define PAKSIZE 128
#define ACK 0
#define NAK 1
#define BUFSIZE 121
#define FILENAME "Testfile"
#define TIMEOUT 100 //in ms

using namespace std;

bool isvpack(unsigned char * p);
bool init(int argc, char** argv);
bool loadFile();
bool getFile();
bool sendFile();
bool isAck();
void handleAck();
void handleNak(int& x);
bool* gremlin(Packet * pack, int corruptProb, int lossProb, int delayProb);
Packet createPacket(int index);
bool sendPacket();

bool seqNum = true;
struct sockaddr_in a;
struct sockaddr_in ca;
socklen_t calen;
int rlen;
int s;
bool ack;
string fstr;
char * file;
int probCorrupt;
int probLoss;
int probDelay;
int delayT;
Packet p;
int length;
bool dropPck;
bool delayPck;
unsigned char b[BUFSIZE];

int main(int argc, char** argv) {

  if(!init(argc, argv)) return -1;

  calen = sizeof(ca);

  unsigned char packet[PAKSIZE + 1];
  rlen = recvfrom(s, packet, PAKSIZE, 0, (struct sockaddr *)&ca, &calen);

  sendFile();

  return 0;
}

bool init(int argc, char** argv){

  if(argc != 6) {
    cout << USAGE << endl;
    return false;
  }

  char * probCorruptStr = argv[2];
  probCorrupt = boost::lexical_cast<int>(probCorruptStr);
  char * probLossStr = argv[3];
  probLoss = boost::lexical_cast<int>(probLossStr);
  char * probDelayStr = argv[4];
  probDelay = boost::lexical_cast<int>(probDelayStr);
  char* delayTStr = argv[5];
  delayT = boost::lexical_cast<int>(delayTStr);

  static int timeout = TIMEOUT;

  /* Create our socket. */
  if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
    cout << "Socket creation failed. (socket s)" << endl;
    return 0;
  }

  setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout));

  /*
   * Bind our socket to an IP (whatever the computer decides)
   * and a specified port.
   *
   */

  if (!loadFile()) {
    cout << "Loading file failed. (filename FILENAME)" << endl;
    return false;
  }

  memset((char *)&a, 0, sizeof(a));
  a.sin_family = AF_INET;
  a.sin_addr.s_addr = htonl(INADDR_ANY);
  a.sin_port = htons(PORT);

  if (bind(s, (struct sockaddr *)&a, sizeof(a)) < 0) {
    cout << "Socket binding failed. (socket s, address a)" << endl;
    return 0;
  }

  fstr = string(file);
  cout << "File: " << endl << fstr << endl;

  seqNum = true;
  dropPck = false;

  return true;
}

bool isvpack(unsigned char * p) {
  cout << endl << "=== IS VALID PACKET TESTING" << endl;

  char * sns = new char[2];
  memcpy(sns, &p[0], 1);
  sns[1] = '\0';

  char * css = new char[7];
  memcpy(css, &p[1], 6);
  css[6] = '\0';

  char * db = new char[121 + 1];
  memcpy(db, &p[2], 121);
  db[121] = '\0';

  cout << "Seq. num: " << sns << endl;
  cout << "Checksum: " << css << endl;
  cout << "Message: " << db << endl;

  int sn = boost::lexical_cast<int>(sns);
  int cs = boost::lexical_cast<int>(css);

  Packet pk (0, db);
  pk.setSequenceNum(sn);

  // change to validate based on checksum and sequence number

  if(sn == seqNum) return false;
  if(cs != pk.generateCheckSum()) return false;
  return true;
}

bool getFile(){

  /* Loop forever, waiting for messages from a client. */
  cout << "Waiting on port " << PORT << "..." << endl;

  ofstream file("Dumpfile");

  bool isSeqNumSet = false;
  for (;;) {
    unsigned char packet[PAKSIZE + 1];
    unsigned char dataPull[PAKSIZE - 7 + 1];
    rlen = recvfrom(s, packet, PAKSIZE, 0, (struct sockaddr *)&ca, &calen);
    if(!isSeqNumSet) {
      isSeqNumSet = true;
      char * str = new char[1];
      memcpy(str, &packet[0], 1);
      seqNum = boost::lexical_cast<int>(str);
    }
    for(int x = 0; x < PAKSIZE - 7; x++) {
      dataPull[x] = packet[x + 7];
    }
    dataPull[PAKSIZE - 7] = '\0';
    packet[PAKSIZE] = '\0';
    if (rlen > 0) {
      char * css = new char[6];
      memcpy(css, &packet[1], 5);
      css[5] = '\0';
      cout << endl << endl << "=== RECEIPT" << endl;
      cout << "Seq. num: " << packet[0] << endl;
      cout << "Checksum: " << css << endl;
      cout << "Received message: " << dataPull << endl;
      cout << "Sent response: ";
      if(isvpack(packet)) {
        ack = ACK;
        seqNum = (seqNum) ? false : true;
        file << dataPull;
      } else {
        ack = NAK;
      }
      cout << ((ack == ACK) ? "ACK" : "NAK") << endl;
      Packet p ((seqNum) ? false : true, reinterpret_cast<const char *>(dataPull));
      p.setCheckSum(boost::lexical_cast<int>(css));
      p.setAckNack(ack);

      if(sendto(s, p.str(), PAKSIZE, 0, (struct sockaddr *)&ca, calen) < 0) {
        cout << "Acknowledgement failed. (socket s, acknowledgement message ack, client address ca, client address length calen)" << endl;
        return 0;
      }
      delete css;
    }
  }
  file.close();
  return true;
}

bool loadFile() {

  ifstream is (FILENAME, ifstream::binary);

  if(is) {
    is.seekg(0, is.end);
    length = is.tellg();
    is.seekg(0, is.beg);

    file = new char[length];

    cout << "Reading " << length << " characters..." << endl;
    is.read(file, length);

    if(!is) { cout << "File reading failed. (filename " << FILENAME << "). Only " << is.gcount() << " could be read."; return false; }
    is.close();
  }
  return true;
}

bool sendFile() {

  for(int x = 0; x <= (length / BUFSIZE) + 1; x++) {
    p = createPacket(x);
    if(!sendPacket()) continue;

    while(recvfrom(s, b, BUFSIZE + 7, 0, (struct sockaddr *)&ca, &calen) < 0) {
		cout << "Timed out. Resending..." << endl;
		sendPacket();
	}

    if(isAck()) {
      handleAck();
    } else {
      handleNak(x);
    }

    memset(b, 0, BUFSIZE);
  }
  return true;
}

Packet createPacket(int index){
    cout << endl;
    cout << "=== TRANSMISSION START" << endl;
    string mstr = fstr.substr(index * BUFSIZE, BUFSIZE);

	if(mstr.length() < BUFSIZE) {
      mstr[length - (index * BUFSIZE)] = '\0';
    }
    return Packet (seqNum, mstr.c_str());
}

bool sendPacket(){
    int pc = probCorrupt; int pl = probLoss; int pd = probDelay;
	bool* pckStatus = gremlin(&p, pc, pl, pd);

	dropPck = pckStatus[0];
	delayPck = pckStatus[1];

	if (dropPck) return false;
	if (delayPck) sleep(delayT);
    if(sendto(s, p.str(), BUFSIZE + 7, 0, (struct sockaddr *)&ca, sizeof(ca)) < 0) {
		cout << "Package sending failed. (socket s, server address sa, message m)" << endl;
		return false;
    }
    return true;
}

bool isAck() {
    cout << endl << "=== SERVER RESPONSE TEST" << endl;
    cout << "Data: " << b << endl;
    if(b[6] == '0') return true;
    else return false;
}
void handleAck() {

}
void handleNak(int& x) {

      char * sns = new char[2];
      memcpy(sns, &b[0], 1);
      sns[1] = '\0';

      char * css = new char[5];
      memcpy(css, &b[1], 5);

      char * db = new char[BUFSIZE + 1];
      memcpy(db, &b[2], BUFSIZE);
      db[BUFSIZE] = '\0';

      cout << "Sequence number: " << sns << endl;
      cout << "Checksum: " << css << endl;

      Packet pk (0, db);
      pk.setSequenceNum(boost::lexical_cast<int>(sns));
      pk.setCheckSum(boost::lexical_cast<int>(css));

      if(!pk.chksm()) x--;
      else x = (x - 2 > 0) ? x - 2 : 0;
}

bool* gremlin(Packet * pack, int corruptProb, int lossProb, int delayProb){
  bool dropPacket = false;
  bool delayPacket = false;
  bool* packStatus = new bool[2];
  int r = rand() % 100;

  cout << "Corruption probability: " << corruptProb << endl;
  cout << "Random number: " << r << endl;

  if(r <= (lossProb)){
    dropPacket = true;
	packStatus[0] = dropPacket;
    cout << "Dropped!" << endl;
  }
  else if(r <= (delayProb)){
	  delayPacket = true;
	  packStatus[1] = delayPacket;
	  cout << "Delayed!" << endl;
  }
  else if(r <= (corruptProb)){
    cout << "Corrupted!" << endl;
    pack->loadDataBuffer((char*)"GREMLIN LOL");
  }
  else seqNum = (seqNum) ? false : true;
  cout << "Seq. num: " << pack->getSequenceNum() << endl;
  cout << "Checksum: " << pack->getCheckSum() << endl;
  cout << "Message: "  << pack->getDataBuffer() << endl;

  return packStatus;
}<commit_msg>Testing for the fix's fix's fix<commit_after>#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <iostream>
#include <fstream>
#include <boost/lexical_cast.hpp>
#include "packet.h"

#define USAGE "Usage:\r\nc \r\n[tux machine number] \r\n[probability of packet corruption in int form] \r\n[probability of packet loss in int form] \r\n[probability of packet delay] \r\n[length of delay in ms] \r\n"
#define PORT 10038
#define PAKSIZE 128
#define ACK 0
#define NAK 1
#define BUFSIZE 121
#define FILENAME "Testfile"
#define TIMEOUT 100 //in ms

using namespace std;

bool isvpack(unsigned char * p);
bool init(int argc, char** argv);
bool loadFile();
bool getFile();
bool sendFile();
bool isAck();
void handleAck();
void handleNak(int& x);
bool* gremlin(Packet * pack, int corruptProb, int lossProb, int delayProb);
Packet createPacket(int index);
bool sendPacket();

bool seqNum = true;
struct sockaddr_in a;
struct sockaddr_in ca;
socklen_t calen;
int rlen;
int s;
bool ack;
string fstr;
char * file;
int probCorrupt;
int probLoss;
int probDelay;
int delayT;
Packet p;
int length;
bool dropPck;
bool delayPck;
unsigned char b[BUFSIZE];

int main(int argc, char** argv) {

  if(!init(argc, argv)) return -1;

  calen = sizeof(ca);

  unsigned char packet[PAKSIZE + 1];
  rlen = recvfrom(s, packet, PAKSIZE, 0, (struct sockaddr *)&ca, &calen);

  sendFile();

  return 0;
}

bool init(int argc, char** argv){

  if(argc != 6) {
    cout << USAGE << endl;
    return false;
  }

  char * probCorruptStr = argv[2];
  probCorrupt = boost::lexical_cast<int>(probCorruptStr);
  char * probLossStr = argv[3];
  probLoss = boost::lexical_cast<int>(probLossStr);
  char * probDelayStr = argv[4];
  probDelay = boost::lexical_cast<int>(probDelayStr);
  char* delayTStr = argv[5];
  delayT = boost::lexical_cast<int>(delayTStr);

  static int timeout = TIMEOUT;

  /* Create our socket. */
  if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
    cout << "Socket creation failed. (socket s)" << endl;
    return 0;
  }

  setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout));

  /*
   * Bind our socket to an IP (whatever the computer decides)
   * and a specified port.
   *
   */

  if (!loadFile()) {
    cout << "Loading file failed. (filename FILENAME)" << endl;
    return false;
  }

  memset((char *)&a, 0, sizeof(a));
  a.sin_family = AF_INET;
  a.sin_addr.s_addr = htonl(INADDR_ANY);
  a.sin_port = htons(PORT);

  if (bind(s, (struct sockaddr *)&a, sizeof(a)) < 0) {
    cout << "Socket binding failed. (socket s, address a)" << endl;
    return 0;
  }

  fstr = string(file);
  cout << "File: " << endl << fstr << endl;

  seqNum = true;
  dropPck = false;

  return true;
}

bool isvpack(unsigned char * p) {
  cout << endl << "=== IS VALID PACKET TESTING" << endl;

  char * sns = new char[2];
  memcpy(sns, &p[0], 1);
  sns[1] = '\0';

  char * css = new char[7];
  memcpy(css, &p[1], 6);
  css[6] = '\0';

  char * db = new char[121 + 1];
  memcpy(db, &p[2], 121);
  db[121] = '\0';

  cout << "Seq. num: " << sns << endl;
  cout << "Checksum: " << css << endl;
  cout << "Message: " << db << endl;

  int sn = boost::lexical_cast<int>(sns);
  int cs = boost::lexical_cast<int>(css);

  Packet pk (0, db);
  pk.setSequenceNum(sn);

  // change to validate based on checksum and sequence number

  if(sn == seqNum) return false;
  if(cs != pk.generateCheckSum()) return false;
  return true;
}

bool getFile(){

  /* Loop forever, waiting for messages from a client. */
  cout << "Waiting on port " << PORT << "..." << endl;

  ofstream file("Dumpfile");

  bool isSeqNumSet = false;
  for (;;) {
    unsigned char packet[PAKSIZE + 1];
    unsigned char dataPull[PAKSIZE - 7 + 1];
    rlen = recvfrom(s, packet, PAKSIZE, 0, (struct sockaddr *)&ca, &calen);
    if(!isSeqNumSet) {
      isSeqNumSet = true;
      char * str = new char[1];
      memcpy(str, &packet[0], 1);
      seqNum = boost::lexical_cast<int>(str);
    }
    for(int x = 0; x < PAKSIZE - 7; x++) {
      dataPull[x] = packet[x + 7];
    }
    dataPull[PAKSIZE - 7] = '\0';
    packet[PAKSIZE] = '\0';
    if (rlen > 0) {
      char * css = new char[6];
      memcpy(css, &packet[1], 5);
      css[5] = '\0';
      cout << endl << endl << "=== RECEIPT" << endl;
      cout << "Seq. num: " << packet[0] << endl;
      cout << "Checksum: " << css << endl;
      cout << "Received message: " << dataPull << endl;
      cout << "Sent response: ";
      if(isvpack(packet)) {
        ack = ACK;
        seqNum = (seqNum) ? false : true;
        file << dataPull;
      } else {
        ack = NAK;
      }
      cout << ((ack == ACK) ? "ACK" : "NAK") << endl;
      Packet p ((seqNum) ? false : true, reinterpret_cast<const char *>(dataPull));
      p.setCheckSum(boost::lexical_cast<int>(css));
      p.setAckNack(ack);

      if(sendto(s, p.str(), PAKSIZE, 0, (struct sockaddr *)&ca, calen) < 0) {
        cout << "Acknowledgement failed. (socket s, acknowledgement message ack, client address ca, client address length calen)" << endl;
        return 0;
      }
      delete css;
    }
  }
  file.close();
  return true;
}

bool loadFile() {

  ifstream is (FILENAME, ifstream::binary);

  if(is) {
    is.seekg(0, is.end);
    length = is.tellg();
    is.seekg(0, is.beg);

    file = new char[length];

    cout << "Reading " << length << " characters..." << endl;
    is.read(file, length);

    if(!is) { cout << "File reading failed. (filename " << FILENAME << "). Only " << is.gcount() << " could be read."; return false; }
    is.close();
  }
  return true;
}

bool sendFile() {

  for(int x = 0; x <= (length / BUFSIZE) + 1; x++) {
    p = createPacket(x);
    if(!sendPacket()) continue;

    while(recvfrom(s, b, BUFSIZE + 7, 0, (struct sockaddr *)&ca, &calen) < 0) {
		cout << "Timed out. Resending..." << endl;
		sendPacket();
	}

    if(isAck()) {
      handleAck();
    } else {
      handleNak(x);
    }

    memset(b, 0, BUFSIZE);
  }
  return true;
}

Packet createPacket(int index){
    cout << endl;
    cout << "=== TRANSMISSION START" << endl;
    string mstr = fstr.substr(index * BUFSIZE, BUFSIZE);

	if(mstr.length() < BUFSIZE) {
      mstr[length - (index * BUFSIZE)] = '\0';
    }
    return Packet (seqNum, mstr.c_str());
}

bool sendPacket(){
    int pc = probCorrupt; int pl = probLoss; int pd = probDelay;
	bool* pckStatus = gremlin(&p, pc, pl, pd);

	dropPck = pckStatus[0];
	delayPck = pckStatus[1];

	cout << "dropPck: " << dropPck << endl;
	cout << "delayPck: " << delayPck << endl;

	if (dropPck) return false;
	if (delayPck) sleep(delayT);
    if(sendto(s, p.str(), BUFSIZE + 7, 0, (struct sockaddr *)&ca, sizeof(ca)) < 0) {
		cout << "Package sending failed. (socket s, server address sa, message m)" << endl;
		return false;
    }
    return true;
}

bool isAck() {
    cout << endl << "=== SERVER RESPONSE TEST" << endl;
    cout << "Data: " << b << endl;
    if(b[6] == '0') return true;
    else return false;
}
void handleAck() {

}
void handleNak(int& x) {

      char * sns = new char[2];
      memcpy(sns, &b[0], 1);
      sns[1] = '\0';

      char * css = new char[5];
      memcpy(css, &b[1], 5);

      char * db = new char[BUFSIZE + 1];
      memcpy(db, &b[2], BUFSIZE);
      db[BUFSIZE] = '\0';

      cout << "Sequence number: " << sns << endl;
      cout << "Checksum: " << css << endl;

      Packet pk (0, db);
      pk.setSequenceNum(boost::lexical_cast<int>(sns));
      pk.setCheckSum(boost::lexical_cast<int>(css));

      if(!pk.chksm()) x--;
      else x = (x - 2 > 0) ? x - 2 : 0;
}

bool* gremlin(Packet * pack, int corruptProb, int lossProb, int delayProb){
  bool dropPacket = false;
  bool delayPacket = false;
  bool* packStatus = new bool[2];
  int r = rand() % 100;

  cout << "Corruption probability: " << corruptProb << endl;
  cout << "Random number: " << r << endl;

  if(r <= (lossProb)){
    dropPacket = true;
	packStatus[0] = dropPacket;
    cout << "Dropped!" << endl;
  }
  else if(r <= (delayProb)){
	  delayPacket = true;
	  packStatus[1] = delayPacket;
	  cout << "Delayed!" << endl;
  }
  else if(r <= (corruptProb)){
    cout << "Corrupted!" << endl;
    pack->loadDataBuffer((char*)"GREMLIN LOL");
  }
  else seqNum = (seqNum) ? false : true;
  cout << "Seq. num: " << pack->getSequenceNum() << endl;
  cout << "Checksum: " << pack->getCheckSum() << endl;
  cout << "Message: "  << pack->getDataBuffer() << endl;

  return packStatus;
}<|endoftext|>