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

#include "Config.hpp"
#include "ConversionChain.hpp"
#include "Converter.hpp"
#include "DartsDict.hpp"
#include "DictGroup.hpp"
#include "MaxMatchSegmentation.hpp"
#include "TextDict.hpp"

#include "document.h"

#include <unordered_map>

using namespace opencc;

typedef rapidjson::GenericValue<rapidjson::UTF8<char>> JSONValue;

namespace opencc {
class ConfigInternal {
public:
  string configDirectory;
  std::unordered_map<
      string, std::unordered_map<string, std::unordered_map<string, DictPtr>>>
      dictCache;

  const JSONValue& GetProperty(const JSONValue& doc, const char* name) {
    if (!doc.HasMember(name)) {
      throw InvalidFormat("Required property not found: " + string(name));
    }
    return doc[name];
  }

  const JSONValue& GetObjectProperty(const JSONValue& doc, const char* name) {
    const JSONValue& obj = GetProperty(doc, name);
    if (!obj.IsObject()) {
      throw InvalidFormat("Property must be an object: " + string(name));
    }
    return obj;
  }

  const JSONValue& GetArrayProperty(const JSONValue& doc, const char* name) {
    const JSONValue& obj = GetProperty(doc, name);
    if (!obj.IsArray()) {
      throw InvalidFormat("Property must be an array: " + string(name));
    }
    return obj;
  }

  const char* GetStringProperty(const JSONValue& doc, const char* name) {
    const JSONValue& obj = GetProperty(doc, name);
    if (!obj.IsString()) {
      throw InvalidFormat("Property must be a string: " + string(name));
    }
    return obj.GetString();
  }

  template <typename DICT> DictPtr LoadDictWithPaths(const string& fileName) {
    // Working directory
    std::shared_ptr<DICT> dict;
    if (SerializableDict::TryLoadFromFile<DICT>(fileName, &dict)) {
      return dict;
    }
    // Configuration directory
    if ((configDirectory != "") && SerializableDict::TryLoadFromFile<DICT>(
                                       configDirectory + fileName, &dict)) {
      return dict;
    }
    // Package data directory
    if ((PACKAGE_DATA_DIRECTORY != "") &&
        SerializableDict::TryLoadFromFile<DICT>(
            PACKAGE_DATA_DIRECTORY + fileName, &dict)) {
      return dict;
    }
    throw FileNotFound(fileName);
  }

  DictPtr ParseDict(const JSONValue& doc) {
    // Required: type
    string type = GetStringProperty(doc, "type");
    DictPtr dict;
    if (type == "group") {
      list<DictPtr> dicts;
      const JSONValue& docs = GetArrayProperty(doc, "dicts");
      for (rapidjson::SizeType i = 0; i < docs.Size(); i++) {
        if (docs[i].IsObject()) {
          DictPtr dict = ParseDict(docs[i]);
          dicts.push_back(dict);
        } else {
          throw InvalidFormat("Element of the array must be an object");
        }
      }
      return DictGroupPtr(new DictGroup(dicts));
    } else {
      string fileName = GetStringProperty(doc, "file");
      // Read from cache
      DictPtr& cache = dictCache[type][configDirectory][fileName];
      if (cache != nullptr) {
        return cache;
      }
      if (type == "text") {
        dict = LoadDictWithPaths<TextDict>(fileName);
      } else if (type == "ocd") {
        dict = LoadDictWithPaths<DartsDict>(fileName);
      } else {
        throw InvalidFormat("Unknown dictionary type: " + type);
      }
      // Update Cache
      cache = dict;
      return dict;
    }
  }

  SegmentationPtr ParseSegmentation(const JSONValue& doc) {
    SegmentationPtr segmentation;

    // Required: type
    string type = GetStringProperty(doc, "type");
    if (type == "mmseg") {
      // Required: dict
      DictPtr dict = ParseDict(GetObjectProperty(doc, "dict"));
      segmentation = SegmentationPtr(new MaxMatchSegmentation(dict));
    } else {
      throw InvalidFormat("Unknown segmentation type: " + type);
    }
    return segmentation;
  }

  ConversionPtr ParseConversion(const JSONValue& doc) {
    // Required: dict
    DictPtr dict = ParseDict(GetObjectProperty(doc, "dict"));
    ConversionPtr conversion(new Conversion(dict));

    return conversion;
  }

  ConversionChainPtr ParseConversionChain(const JSONValue& docs) {
    list<ConversionPtr> conversions;
    for (rapidjson::SizeType i = 0; i < docs.Size(); i++) {
      const JSONValue& doc = docs[i];
      if (doc.IsObject()) {
        ConversionPtr conversion = ParseConversion(doc);
        conversions.push_back(conversion);
      } else {
      }
    }
    ConversionChainPtr chain(new ConversionChain(conversions));
    return chain;
  }

  string FindConfigFile(string fileName) {
    std::ifstream ifs;

    // Working directory
    ifs.open(fileName.c_str());
    if (ifs.is_open()) {
      return fileName;
    }
    // Package data directory
    if (PACKAGE_DATA_DIRECTORY != "") {
      string prefixedFileName = PACKAGE_DATA_DIRECTORY + fileName;
      ifs.open(prefixedFileName.c_str());
      if (ifs.is_open()) {
        return prefixedFileName;
      }
    }
    throw FileNotFound(fileName);
  }
};
};

Config::Config() : internal(new ConfigInternal()) {}

Config::~Config() { delete (ConfigInternal*)internal; }

ConverterPtr Config::NewFromFile(const string& fileName) {
  ConfigInternal* impl = (ConfigInternal*)internal;
  string prefixedFileName = impl->FindConfigFile(fileName);
  std::ifstream ifs(prefixedFileName);
  string content(std::istreambuf_iterator<char>(ifs),
                 (std::istreambuf_iterator<char>()));

#if defined(_WIN32) || defined(_WIN64)
  UTF8Util::ReplaceAll(prefixedFileName, "\\", "/");
#endif // if defined(_WIN32) || defined(_WIN64)
  size_t slashPos = prefixedFileName.rfind("/");
  string configDirectory = "";
  if (slashPos != string::npos) {
    configDirectory = prefixedFileName.substr(0, slashPos) + "/";
  }
  return NewFromString(content, configDirectory);
}

ConverterPtr Config::NewFromString(const string& json,
                                   const string& configDirectory) {
  rapidjson::Document doc;

  doc.ParseInsitu<0>(const_cast<char*>(json.c_str()));
  if (doc.HasParseError()) {
    throw InvalidFormat("Error parsing JSON"); // doc.GetErrorOffset()
  }
  if (!doc.IsObject()) {
    throw InvalidFormat("Root of configuration must be an object");
  }

  // Optional: name
  string name;
  if (doc.HasMember("name") && doc["name"].IsString()) {
    name = doc["name"].GetString();
  }

  ConfigInternal* impl = (ConfigInternal*)internal;
  impl->configDirectory = configDirectory;

  // Required: segmentation
  SegmentationPtr segmentation =
      impl->ParseSegmentation(impl->GetObjectProperty(doc, "segmentation"));

  // Required: conversion_chain
  ConversionChainPtr chain = impl->ParseConversionChain(
      impl->GetArrayProperty(doc, "conversion_chain"));
  return ConverterPtr(new Converter(name, segmentation, chain));
}
<commit_msg>Allow ext-less config filenames for package data.<commit_after>/*
 * Open Chinese Convert
 *
 * Copyright 2010-2014 BYVoid <byvoid@byvoid.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "Config.hpp"
#include "ConversionChain.hpp"
#include "Converter.hpp"
#include "DartsDict.hpp"
#include "DictGroup.hpp"
#include "MaxMatchSegmentation.hpp"
#include "TextDict.hpp"

#include "document.h"

#include <unordered_map>

using namespace opencc;

typedef rapidjson::GenericValue<rapidjson::UTF8<char>> JSONValue;

namespace opencc {
class ConfigInternal {
public:
  string configDirectory;
  std::unordered_map<
      string, std::unordered_map<string, std::unordered_map<string, DictPtr>>>
      dictCache;

  const JSONValue& GetProperty(const JSONValue& doc, const char* name) {
    if (!doc.HasMember(name)) {
      throw InvalidFormat("Required property not found: " + string(name));
    }
    return doc[name];
  }

  const JSONValue& GetObjectProperty(const JSONValue& doc, const char* name) {
    const JSONValue& obj = GetProperty(doc, name);
    if (!obj.IsObject()) {
      throw InvalidFormat("Property must be an object: " + string(name));
    }
    return obj;
  }

  const JSONValue& GetArrayProperty(const JSONValue& doc, const char* name) {
    const JSONValue& obj = GetProperty(doc, name);
    if (!obj.IsArray()) {
      throw InvalidFormat("Property must be an array: " + string(name));
    }
    return obj;
  }

  const char* GetStringProperty(const JSONValue& doc, const char* name) {
    const JSONValue& obj = GetProperty(doc, name);
    if (!obj.IsString()) {
      throw InvalidFormat("Property must be a string: " + string(name));
    }
    return obj.GetString();
  }

  template <typename DICT> DictPtr LoadDictWithPaths(const string& fileName) {
    // Working directory
    std::shared_ptr<DICT> dict;
    if (SerializableDict::TryLoadFromFile<DICT>(fileName, &dict)) {
      return dict;
    }
    // Configuration directory
    if ((configDirectory != "") && SerializableDict::TryLoadFromFile<DICT>(
                                       configDirectory + fileName, &dict)) {
      return dict;
    }
    // Package data directory
    if ((PACKAGE_DATA_DIRECTORY != "") &&
        SerializableDict::TryLoadFromFile<DICT>(
            PACKAGE_DATA_DIRECTORY + fileName, &dict)) {
      return dict;
    }
    throw FileNotFound(fileName);
  }

  DictPtr ParseDict(const JSONValue& doc) {
    // Required: type
    string type = GetStringProperty(doc, "type");
    DictPtr dict;
    if (type == "group") {
      list<DictPtr> dicts;
      const JSONValue& docs = GetArrayProperty(doc, "dicts");
      for (rapidjson::SizeType i = 0; i < docs.Size(); i++) {
        if (docs[i].IsObject()) {
          DictPtr dict = ParseDict(docs[i]);
          dicts.push_back(dict);
        } else {
          throw InvalidFormat("Element of the array must be an object");
        }
      }
      return DictGroupPtr(new DictGroup(dicts));
    } else {
      string fileName = GetStringProperty(doc, "file");
      // Read from cache
      DictPtr& cache = dictCache[type][configDirectory][fileName];
      if (cache != nullptr) {
        return cache;
      }
      if (type == "text") {
        dict = LoadDictWithPaths<TextDict>(fileName);
      } else if (type == "ocd") {
        dict = LoadDictWithPaths<DartsDict>(fileName);
      } else {
        throw InvalidFormat("Unknown dictionary type: " + type);
      }
      // Update Cache
      cache = dict;
      return dict;
    }
  }

  SegmentationPtr ParseSegmentation(const JSONValue& doc) {
    SegmentationPtr segmentation;

    // Required: type
    string type = GetStringProperty(doc, "type");
    if (type == "mmseg") {
      // Required: dict
      DictPtr dict = ParseDict(GetObjectProperty(doc, "dict"));
      segmentation = SegmentationPtr(new MaxMatchSegmentation(dict));
    } else {
      throw InvalidFormat("Unknown segmentation type: " + type);
    }
    return segmentation;
  }

  ConversionPtr ParseConversion(const JSONValue& doc) {
    // Required: dict
    DictPtr dict = ParseDict(GetObjectProperty(doc, "dict"));
    ConversionPtr conversion(new Conversion(dict));

    return conversion;
  }

  ConversionChainPtr ParseConversionChain(const JSONValue& docs) {
    list<ConversionPtr> conversions;
    for (rapidjson::SizeType i = 0; i < docs.Size(); i++) {
      const JSONValue& doc = docs[i];
      if (doc.IsObject()) {
        ConversionPtr conversion = ParseConversion(doc);
        conversions.push_back(conversion);
      } else {
      }
    }
    ConversionChainPtr chain(new ConversionChain(conversions));
    return chain;
  }

  string FindConfigFile(string fileName) {
    std::ifstream ifs;

    // Working directory
    ifs.open(fileName.c_str());
    if (ifs.is_open()) {
      return fileName;
    }
    // Package data directory
    if (PACKAGE_DATA_DIRECTORY != "") {
      string prefixedFileName = PACKAGE_DATA_DIRECTORY + fileName;
      ifs.open(prefixedFileName.c_str());
      if (ifs.is_open()) {
        return prefixedFileName;
      }
      prefixedFileName += ".json";
      ifs.open(prefixedFileName.c_str());
      if (ifs.is_open()) {
        return prefixedFileName;
      }
    }
    throw FileNotFound(fileName);
  }
};
};

Config::Config() : internal(new ConfigInternal()) {}

Config::~Config() { delete (ConfigInternal*)internal; }

ConverterPtr Config::NewFromFile(const string& fileName) {
  ConfigInternal* impl = (ConfigInternal*)internal;
  string prefixedFileName = impl->FindConfigFile(fileName);
  std::ifstream ifs(prefixedFileName);
  string content(std::istreambuf_iterator<char>(ifs),
                 (std::istreambuf_iterator<char>()));

#if defined(_WIN32) || defined(_WIN64)
  UTF8Util::ReplaceAll(prefixedFileName, "\\", "/");
#endif // if defined(_WIN32) || defined(_WIN64)
  size_t slashPos = prefixedFileName.rfind("/");
  string configDirectory = "";
  if (slashPos != string::npos) {
    configDirectory = prefixedFileName.substr(0, slashPos) + "/";
  }
  return NewFromString(content, configDirectory);
}

ConverterPtr Config::NewFromString(const string& json,
                                   const string& configDirectory) {
  rapidjson::Document doc;

  doc.ParseInsitu<0>(const_cast<char*>(json.c_str()));
  if (doc.HasParseError()) {
    throw InvalidFormat("Error parsing JSON"); // doc.GetErrorOffset()
  }
  if (!doc.IsObject()) {
    throw InvalidFormat("Root of configuration must be an object");
  }

  // Optional: name
  string name;
  if (doc.HasMember("name") && doc["name"].IsString()) {
    name = doc["name"].GetString();
  }

  ConfigInternal* impl = (ConfigInternal*)internal;
  impl->configDirectory = configDirectory;

  // Required: segmentation
  SegmentationPtr segmentation =
      impl->ParseSegmentation(impl->GetObjectProperty(doc, "segmentation"));

  // Required: conversion_chain
  ConversionChainPtr chain = impl->ParseConversionChain(
      impl->GetArrayProperty(doc, "conversion_chain"));
  return ConverterPtr(new Converter(name, segmentation, chain));
}
<|endoftext|>


<commit_before>/****************************************************************/
/* MOOSE - Multiphysics Object Oriented Simulation Environment  */
/*                                                              */
/*          All contents are licensed under LGPL V2.1           */
/*             See LICENSE for full restrictions                */
/****************************************************************/
#include "RecomputeRadialReturnTempDepHardening.h"

#include "PiecewiseLinear.h"

template<>
InputParameters validParams<RecomputeRadialReturnTempDepHardening>()
{
  InputParameters params = validParams<RecomputeRadialReturnIsotropicPlasticity>();

  params.set<Real>("yield_stress") = 1.0;
  params.set<Real>("hardening_constant") = 1.0;

  params.suppressParameter<Real>("yield_stress");
  params.suppressParameter<FunctionName>("yield_stress_function");
  params.suppressParameter<Real>("hardening_constant");
  params.suppressParameter<FunctionName>("hardening_function");

  params.addRequiredParam<std::vector<FunctionName> >("hardening_functions", "List of functions of true stress as function of plastic strain at different temperatures");
  params.addRequiredParam<std::vector<Real> >("temperatures", "List of temperatures corresponding to the functions listed in 'hardening_functions'");

  return params;
}

RecomputeRadialReturnTempDepHardening::RecomputeRadialReturnTempDepHardening(const InputParameters & parameters) :
    RecomputeRadialReturnIsotropicPlasticity(parameters),
    _hardening_functions_names(getParam<std::vector<FunctionName> >("hardening_functions")),
    _hf_temperatures(getParam<std::vector<Real> >("temperatures"))
{
  const unsigned len = _hardening_functions_names.size();
  if (len < 2)
    mooseError("At least two stress-strain curves must be provided in hardening_functions");
  _hardening_functions.resize(len);

  const unsigned len_temps = _hf_temperatures.size();
  if (len != len_temps)
    mooseError("The vector of hardening function temperatures must have the same length as the vector of temperature dependent hardening functions.");

  //Check that the temperatures are strictly increasing
  for (unsigned int i = 1; i < len_temps; ++i)
  {
    if (_hf_temperatures[i] <= _hf_temperatures[i-1])
      mooseError("The temperature dependent hardening functions and corresponding temperatures should be listed in order of increasing temperature.");
  }

  std::vector<Real> yield_stress_vec;
  for (unsigned int i = 0; i < len; ++i)
  {
    PiecewiseLinear * const f = dynamic_cast<PiecewiseLinear*>(&getFunctionByName(_hardening_functions_names[i]));
    if (!f)
      mooseError("Function " << _hardening_functions_names[i] << " not found in " << name());

    _hardening_functions[i] = f;

    Point p;
    yield_stress_vec.push_back(f->value(0.0, p));
  }

  _interp_yield_stress = new LinearInterpolation(_hf_temperatures, yield_stress_vec);

  _scalar_plastic_strain_old = &declarePropertyOld<Real>("scalar_plastic_strain");
}

void
RecomputeRadialReturnTempDepHardening::computeStressInitialize(Real effectiveTrialStress)
{
  _shear_modulus = getIsotropicShearModulus();
  initializeHardeningFunctions();
  computeYieldStress();
  _yield_condition = effectiveTrialStress - _hardening_variable_old[_qp] - _yield_stress;
  _hardening_variable[_qp] = _hardening_variable_old[_qp];
  _plastic_strain[_qp] = _plastic_strain_old[_qp];
}

void
RecomputeRadialReturnTempDepHardening::initializeHardeningFunctions()
{
  Real temp = _temperature[_qp];
  if (temp > _hf_temperatures[0] && temp < _hf_temperatures.back())
  {
    for (unsigned int i = 0; i < _hf_temperatures.size() - 1; ++i)
    {
      if (temp >= _hf_temperatures[i] && temp < _hf_temperatures[i+1])
      {
        _hf_index = i;
        Real temp_lo = _hf_temperatures[i];
        Real temp_hi = _hf_temperatures[i+1];
        _hf_fraction = (temp - temp_lo) / (temp_hi - temp_lo);
      }
    }
  }

  else if (temp <= _hf_temperatures[0])
  {
    _hf_index = 0;
    _hf_fraction = 0.0;
  }

  else if (temp >= _hf_temperatures.back())
  {
    _hf_index = _hf_temperatures.size() - 1;
    _hf_fraction = 1.0;
  }

  if (_hf_fraction < 0.0)
    mooseError("The hardening function fraction cannot be less than zero.");
}

Real
RecomputeRadialReturnTempDepHardening::computeHardeningValue(Real scalar)
{
  const Real strain = (*_scalar_plastic_strain_old)[_qp] + scalar;
  Real temp = _temperature[_qp];
  Real stress = 0.0;
  Point p;

  stress += (1.0 - _hf_fraction) * _hardening_functions[_hf_index]->value(strain, p);
  stress += _hf_fraction * _hardening_functions[_hf_index+1]->value(strain, p);

  return stress - _yield_stress;
}

Real
RecomputeRadialReturnTempDepHardening::computeHardeningDerivative(Real /*scalar*/)
{
  const Real strain_old = (*_scalar_plastic_strain_old)[_qp];
  Real temp = _temperature[_qp];
  Real derivative = 0.0;
  Point p;

  derivative += (1.0 - _hf_fraction) * _hardening_functions[_hf_index]->timeDerivative(strain_old, p);
  derivative += _hf_fraction * _hardening_functions[_hf_index+1]->timeDerivative(strain_old, p);

  return derivative;
}

void
RecomputeRadialReturnTempDepHardening::computeYieldStress()
{
    _yield_stress = _interp_yield_stress->sample(_temperature[_qp]);
    if (_yield_stress <= 0.0)
      mooseError("The yield stress must be greater than zero, but during the simulation your yield stress became less than zero.");
}
<commit_msg>Remove unused variable warning (#1777)<commit_after>/****************************************************************/
/* MOOSE - Multiphysics Object Oriented Simulation Environment  */
/*                                                              */
/*          All contents are licensed under LGPL V2.1           */
/*             See LICENSE for full restrictions                */
/****************************************************************/
#include "RecomputeRadialReturnTempDepHardening.h"

#include "PiecewiseLinear.h"

template<>
InputParameters validParams<RecomputeRadialReturnTempDepHardening>()
{
  InputParameters params = validParams<RecomputeRadialReturnIsotropicPlasticity>();

  params.set<Real>("yield_stress") = 1.0;
  params.set<Real>("hardening_constant") = 1.0;

  params.suppressParameter<Real>("yield_stress");
  params.suppressParameter<FunctionName>("yield_stress_function");
  params.suppressParameter<Real>("hardening_constant");
  params.suppressParameter<FunctionName>("hardening_function");

  params.addRequiredParam<std::vector<FunctionName> >("hardening_functions", "List of functions of true stress as function of plastic strain at different temperatures");
  params.addRequiredParam<std::vector<Real> >("temperatures", "List of temperatures corresponding to the functions listed in 'hardening_functions'");

  return params;
}

RecomputeRadialReturnTempDepHardening::RecomputeRadialReturnTempDepHardening(const InputParameters & parameters) :
    RecomputeRadialReturnIsotropicPlasticity(parameters),
    _hardening_functions_names(getParam<std::vector<FunctionName> >("hardening_functions")),
    _hf_temperatures(getParam<std::vector<Real> >("temperatures"))
{
  const unsigned int len = _hardening_functions_names.size();
  if (len < 2)
    mooseError("At least two stress-strain curves must be provided in hardening_functions");
  _hardening_functions.resize(len);

  const unsigned int len_temps = _hf_temperatures.size();
  if (len != len_temps)
    mooseError("The vector of hardening function temperatures must have the same length as the vector of temperature dependent hardening functions.");

  //Check that the temperatures are strictly increasing
  for (unsigned int i = 1; i < len_temps; ++i)
    if (_hf_temperatures[i] <= _hf_temperatures[i-1])
      mooseError("The temperature dependent hardening functions and corresponding temperatures should be listed in order of increasing temperature.");

  std::vector<Real> yield_stress_vec;
  for (unsigned int i = 0; i < len; ++i)
  {
    PiecewiseLinear * const f = dynamic_cast<PiecewiseLinear*>(&getFunctionByName(_hardening_functions_names[i]));
    if (!f)
      mooseError("Function " << _hardening_functions_names[i] << " not found in " << name());

    _hardening_functions[i] = f;

    yield_stress_vec.push_back(f->value(0.0, Point()));
  }

  _interp_yield_stress = new LinearInterpolation(_hf_temperatures, yield_stress_vec);

  _scalar_plastic_strain_old = &declarePropertyOld<Real>("scalar_plastic_strain");
}

void
RecomputeRadialReturnTempDepHardening::computeStressInitialize(Real effectiveTrialStress)
{
  _shear_modulus = getIsotropicShearModulus();
  initializeHardeningFunctions();
  computeYieldStress();
  _yield_condition = effectiveTrialStress - _hardening_variable_old[_qp] - _yield_stress;
  _hardening_variable[_qp] = _hardening_variable_old[_qp];
  _plastic_strain[_qp] = _plastic_strain_old[_qp];
}

void
RecomputeRadialReturnTempDepHardening::initializeHardeningFunctions()
{
  const Real temp = _temperature[_qp];
  if (temp > _hf_temperatures[0] && temp < _hf_temperatures.back())
  {
    for (unsigned int i = 0; i < _hf_temperatures.size() - 1; ++i)
    {
      if (temp >= _hf_temperatures[i] && temp < _hf_temperatures[i+1])
      {
        _hf_index = i;
        Real temp_lo = _hf_temperatures[i];
        Real temp_hi = _hf_temperatures[i+1];
        _hf_fraction = (temp - temp_lo) / (temp_hi - temp_lo);
      }
    }
  }

  else if (temp <= _hf_temperatures[0])
  {
    _hf_index = 0;
    _hf_fraction = 0.0;
  }

  else if (temp >= _hf_temperatures.back())
  {
    _hf_index = _hf_temperatures.size() - 1;
    _hf_fraction = 1.0;
  }

  if (_hf_fraction < 0.0)
    mooseError("The hardening function fraction cannot be less than zero.");
}

Real
RecomputeRadialReturnTempDepHardening::computeHardeningValue(Real scalar)
{
  const Real strain = (*_scalar_plastic_strain_old)[_qp] + scalar;
  const Point p;
  const Real stress =   (1.0 - _hf_fraction) * _hardening_functions[_hf_index]->value(strain, p)
                      + _hf_fraction * _hardening_functions[_hf_index+1]->value(strain, p);

  return stress - _yield_stress;
}

Real
RecomputeRadialReturnTempDepHardening::computeHardeningDerivative(Real /*scalar*/)
{
  const Real strain_old = (*_scalar_plastic_strain_old)[_qp];
  const Point p;

  return   (1.0 - _hf_fraction) * _hardening_functions[_hf_index]->timeDerivative(strain_old, p)
         + _hf_fraction * _hardening_functions[_hf_index+1]->timeDerivative(strain_old, p);
}

void
RecomputeRadialReturnTempDepHardening::computeYieldStress()
{
  _yield_stress = _interp_yield_stress->sample(_temperature[_qp]);
  if (_yield_stress <= 0.0)
    mooseError("The yield stress must be greater than zero, but during the simulation your yield stress became less than zero.");
}
<|endoftext|>


<commit_before>// Copyright (c) 2012-2015 Dano Pernis
// See LICENSE for details

#include <gtk/gtk.h>
#include <glib.h>
#include <fstream>
#include <iostream>
#include <stdexcept>
#include <cassert>
#include "CPU.h"

namespace hcc {

struct ROM : public IROM {
    unsigned short *data;
    static const unsigned int size = 0x8000;
    ROM() {
        data = new unsigned short[size];
    }
    virtual ~ROM() {
        delete[] data;
    }

    bool load(const char *filename) {
        std::ifstream input(filename);
        std::string line;
        unsigned int counter = 0;
        while (input.good() && counter < size) {
            getline(input, line);
            if (line.size() == 0)
                continue;
            if (line.size() != 16)
                return false;

            unsigned int instruction = 0;
            for (unsigned int i = 0; i<16; ++i) {
                instruction <<= 1;
                switch (line[i]) {
                case '0':
                    break;
                case '1':
                    instruction |= 1;
                    break;
                default:
                    return false;
                }
            }
            data[counter++] = instruction;
        }
        // clear the rest
        while (counter < size) {
            data[counter++] = 0;
        }

        return true;
    }
    virtual unsigned short get(unsigned int address) const {
        if (address < size) {
            return data[address];
        } else {
            std::cerr << "requested memory at " << address << '\n';
            throw std::runtime_error("Memory::get");
        }
    }
};

} // end namespace

gboolean on_draw(GtkWidget*, cairo_t* cr, gpointer data)
{
    GdkPixbuf* pixbuf = reinterpret_cast<GdkPixbuf*>(data);
    gdk_cairo_set_source_pixbuf(cr, pixbuf, 0, 0);
    cairo_paint(cr);
    return FALSE;
}

struct GUIEmulatorRAM : public hcc::IRAM {
    static const unsigned int CHANNELS = 3;
    static const unsigned int SCREEN_WIDTH = 512;
    static const unsigned int SCREEN_HEIGHT = 256;
    static const unsigned int size = 0x6001;

    unsigned short *data;
    GdkPixbuf *pixbuf;
    GtkWidget *screen;

    void putpixel(unsigned short x, unsigned short y, bool black) {
        int color = black ? 0x00 : 0xff;

        int n_channels = gdk_pixbuf_get_n_channels (pixbuf);
        int rowstride = gdk_pixbuf_get_rowstride (pixbuf);
        guchar* pixels = gdk_pixbuf_get_pixels(pixbuf);
        guchar* p = pixels + y * rowstride + x * n_channels;
        p[0] = color;
        p[1] = color;
        p[2] = color;
    }
public:
    GUIEmulatorRAM() {
        data = new unsigned short[size];

        pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, SCREEN_WIDTH, SCREEN_HEIGHT);
        gdk_pixbuf_fill(pixbuf, 0x0000000);

        screen = gtk_drawing_area_new();
        gtk_widget_set_size_request(screen, SCREEN_WIDTH, SCREEN_HEIGHT);
        g_signal_connect(screen, "draw", G_CALLBACK(on_draw), pixbuf);
    }
    virtual ~GUIEmulatorRAM() {
        delete[] data;
    }
    void keyboard(unsigned short value) {
        data[0x6000] = value;
    }
    GtkWidget* getScreenWidget() {
        return screen;
    }
    virtual void set(unsigned int address, unsigned short value) {
        if (address >= size) {
            throw std::runtime_error("RAM::set");
        }

        data[address] = value;

        // check if we are writing to video RAM
        if (0x4000 <= address && address <0x6000) {
            address -= 0x4000;

            unsigned short y = address / 32;
            unsigned short x = 16*(address % 32);
            for (int bit = 0; bit<16; ++bit) {
                putpixel(x + bit, y, value & 1);
                value = value >> 1;
            }
            gdk_threads_enter();
            gtk_widget_queue_draw(screen);
            gdk_threads_leave();
        }
    }
    virtual unsigned short get(unsigned int address) const {
        if (address >= size) {
            throw std::runtime_error("RAM::get");
        }

        return data[address];
    }
};

struct emulator {
    emulator();
    void load_clicked();
    void run_clicked();
    void pause_clicked();
    gboolean keyboard_callback(GdkEventKey* event);
    void run_thread();
    GtkToolItem* create_button(const gchar* stock_id, const gchar* text, GCallback callback);

    hcc::ROM rom;
    GUIEmulatorRAM ram;
    hcc::CPU cpu;

    bool running = false;

    GtkWidget* window;
    GtkWidget* load_dialog;
    GtkWidget* error_dialog;
    GtkToolItem* button_load;
    GtkToolItem* button_run;
    GtkToolItem* button_pause;
};

gboolean c_keyboard_callback(GtkWidget*, GdkEventKey *event, gpointer user_data)
{ return reinterpret_cast<emulator*>(user_data)->keyboard_callback(event); }

void c_load_clicked(GtkButton*, gpointer user_data)
{ reinterpret_cast<emulator*>(user_data)->load_clicked(); }

void c_run_clicked(GtkButton*, gpointer user_data)
{ reinterpret_cast<emulator*>(user_data)->run_clicked(); }

void c_pause_clicked(GtkButton*, gpointer user_data)
{ reinterpret_cast<emulator*>(user_data)->pause_clicked(); }

gpointer c_run_thread(gpointer user_data)
{
    reinterpret_cast<emulator*>(user_data)->run_thread();
    return NULL;
}

// Translate special keys. See Figure 5.6 in TECS book.
unsigned short translate(guint keyval)
{
    switch (keyval) {
    case GDK_KEY_Return:    return 128;
    case GDK_KEY_BackSpace: return 129;
    case GDK_KEY_Left:      return 130;
    case GDK_KEY_Up:        return 131;
    case GDK_KEY_Right:     return 132;
    case GDK_KEY_Down:      return 133;
    case GDK_KEY_Home:      return 134;
    case GDK_KEY_End:       return 135;
    case GDK_KEY_Page_Up:   return 136;
    case GDK_KEY_Page_Down: return 137;
    case GDK_KEY_Insert:    return 138;
    case GDK_KEY_Delete:    return 139;
    case GDK_KEY_Escape:    return 140;
    case GDK_KEY_F1:        return 141;
    case GDK_KEY_F2:        return 142;
    case GDK_KEY_F3:        return 143;
    case GDK_KEY_F4:        return 144;
    case GDK_KEY_F5:        return 145;
    case GDK_KEY_F6:        return 146;
    case GDK_KEY_F7:        return 147;
    case GDK_KEY_F8:        return 148;
    case GDK_KEY_F9:        return 149;
    case GDK_KEY_F10:       return 150;
    case GDK_KEY_F11:       return 151;
    case GDK_KEY_F12:       return 152;
    }
    return keyval;
}

emulator::emulator()
{
    /* toolbar buttons */
    button_load    = create_button("document-open",        "Load...", G_CALLBACK(c_load_clicked));
    button_run     = create_button("media-playback-start", "Run",     G_CALLBACK(c_run_clicked));
    button_pause   = create_button("media-playback-pause", "Pause",   G_CALLBACK(c_pause_clicked));

    GtkToolItem *separator1 = gtk_separator_tool_item_new();

    gtk_widget_set_sensitive(GTK_WIDGET(button_run), FALSE);
    gtk_widget_set_sensitive(GTK_WIDGET(button_pause), FALSE);

    /* toolbar itself */
    GtkWidget *toolbar = gtk_toolbar_new();
    gtk_widget_set_hexpand(toolbar, TRUE);
    gtk_toolbar_set_style(GTK_TOOLBAR(toolbar), GTK_TOOLBAR_ICONS);
    gtk_toolbar_insert(GTK_TOOLBAR(toolbar), button_load,  -1);
    gtk_toolbar_insert(GTK_TOOLBAR(toolbar), separator1,   -1);
    gtk_toolbar_insert(GTK_TOOLBAR(toolbar), button_run,   -1);
    gtk_toolbar_insert(GTK_TOOLBAR(toolbar), button_pause, -1);

    /* keyboard */
    GtkWidget *keyboard = gtk_toggle_button_new_with_label("Grab keyboard focus");
    gtk_widget_add_events(keyboard, GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK);
    g_signal_connect(keyboard, "key-press-event",   G_CALLBACK(c_keyboard_callback), this);
    g_signal_connect(keyboard, "key-release-event", G_CALLBACK(c_keyboard_callback), this);

    /* main layout */
    GtkWidget *grid = gtk_grid_new();
    gtk_grid_attach(GTK_GRID(grid), toolbar, 0, 0, 1, 1);
    gtk_grid_attach(GTK_GRID(grid), ram.getScreenWidget(), 0, 1, 1, 1);
    gtk_grid_attach(GTK_GRID(grid), keyboard, 0, 2, 1, 1);

    /* main window */
    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(window), "HACK emulator");
    gtk_window_set_resizable(GTK_WINDOW(window), FALSE);
    gtk_window_set_focus(GTK_WINDOW(window), NULL);
    g_signal_connect(window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
    gtk_container_add(GTK_CONTAINER(window), grid);
    gtk_widget_show_all(window);
    gtk_widget_set_visible(GTK_WIDGET(button_pause), FALSE);

    load_dialog = gtk_file_chooser_dialog_new(
        "Load ROM", GTK_WINDOW(window), GTK_FILE_CHOOSER_ACTION_OPEN,
        "gtk-cancel", GTK_RESPONSE_CANCEL,
        "gtk-open", GTK_RESPONSE_ACCEPT,
        NULL);

    error_dialog = gtk_message_dialog_new(GTK_WINDOW(window),
        GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE,
        "Error loading program");
}

GtkToolItem* emulator::create_button(const gchar* stock_id, const gchar* text, GCallback callback)
{
    GtkToolItem *button = gtk_tool_button_new(NULL, text);
    gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(button), stock_id);
    gtk_tool_item_set_tooltip_text(button, text);
    g_signal_connect(button, "clicked", callback, this);
    return button;
}

void emulator::load_clicked()
{
    const gint result = gtk_dialog_run(GTK_DIALOG(load_dialog));
    gtk_widget_hide(load_dialog);

    if (result != GTK_RESPONSE_ACCEPT) {
        return;
    }

    char *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(load_dialog));
    const bool loaded = rom.load(filename);
    g_free(filename);

    if (!loaded) {
        gtk_dialog_run(GTK_DIALOG(error_dialog));
        gtk_widget_hide(error_dialog);
        return;
    }

    cpu.reset();
    gtk_widget_set_sensitive(GTK_WIDGET(button_run), TRUE);
}

void emulator::run_clicked()
{
    assert(!running);

    running = true;
    gtk_widget_set_sensitive(GTK_WIDGET(button_run), FALSE);
    gtk_widget_set_visible(GTK_WIDGET(button_run), FALSE);
    gtk_widget_set_sensitive(GTK_WIDGET(button_pause), TRUE);
    gtk_widget_set_visible(GTK_WIDGET(button_pause), TRUE);

    g_thread_create(c_run_thread, this, FALSE, NULL);
}

void emulator::pause_clicked()
{
    assert(running);

    running = false;
    gtk_widget_set_sensitive(GTK_WIDGET(button_pause), FALSE);
    gtk_widget_set_visible(GTK_WIDGET(button_pause), FALSE);
    gtk_widget_set_sensitive(GTK_WIDGET(button_run), TRUE);
    gtk_widget_set_visible(GTK_WIDGET(button_run), TRUE);
}

gboolean emulator::keyboard_callback(GdkEventKey* event)
{
    if (event->type == GDK_KEY_RELEASE) {
        ram.keyboard(0);
    } else {
        ram.keyboard(translate(event->keyval));
    }
    return TRUE;
}

void emulator::run_thread()
{
    int steps = 0;
    while (running) {
        cpu.step(&rom, &ram);
        if (steps>100) {
            g_usleep(10);
            steps = 0;
        }
        ++steps;
    }
}

int main(int argc, char *argv[])
{
    gtk_init(&argc, &argv);
    emulator e;
    gtk_main();
    return 0;
}
<commit_msg>Use std::vector for heap allocated contiguous memory<commit_after>// Copyright (c) 2012-2015 Dano Pernis
// See LICENSE for details

#include <gtk/gtk.h>
#include <glib.h>
#include <fstream>
#include <iostream>
#include <stdexcept>
#include <cassert>
#include <vector>
#include "CPU.h"

struct ROM : public hcc::IROM {
    ROM() : data(0x8000, 0) { }

    bool load(const char *filename)
    {
        std::ifstream input(filename);
        std::string line;
        auto it = begin(data);
        while (input.good() && it != end(data)) {
            getline(input, line);
            if (line.size() == 0) {
                continue;
            }
            if (line.size() != 16) {
                return false;
            }

            unsigned int instruction = 0;
            for (unsigned int i = 0; i<16; ++i) {
                instruction <<= 1;
                switch (line[i]) {
                case '0':
                    break;
                case '1':
                    instruction |= 1;
                    break;
                default:
                    return false;
                }
            }
            *it++ = instruction;
        }

        // clear the rest
        while (it != end(data)) {
            *it++ = 0;
        }

        return true;
    }

    unsigned short get(unsigned int address) const override
    { return data.at(address); }

private:
    std::vector<unsigned short> data;
};

gboolean on_draw(GtkWidget*, cairo_t* cr, gpointer data)
{
    GdkPixbuf* pixbuf = reinterpret_cast<GdkPixbuf*>(data);
    gdk_cairo_set_source_pixbuf(cr, pixbuf, 0, 0);
    cairo_paint(cr);
    return FALSE;
}

struct RAM : public hcc::IRAM {
    static const unsigned int CHANNELS = 3;
    static const unsigned int SCREEN_WIDTH = 512;
    static const unsigned int SCREEN_HEIGHT = 256;

    std::vector<unsigned short> data;
    GdkPixbuf *pixbuf;
    GtkWidget *screen;

    void putpixel(unsigned short x, unsigned short y, bool black) {
        int color = black ? 0x00 : 0xff;

        int n_channels = gdk_pixbuf_get_n_channels (pixbuf);
        int rowstride = gdk_pixbuf_get_rowstride (pixbuf);
        guchar* pixels = gdk_pixbuf_get_pixels(pixbuf);
        guchar* p = pixels + y * rowstride + x * n_channels;
        p[0] = color;
        p[1] = color;
        p[2] = color;
    }
public:
    RAM() : data(0x6001, 0)
    {
        pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, SCREEN_WIDTH, SCREEN_HEIGHT);
        gdk_pixbuf_fill(pixbuf, 0x0000000);

        screen = gtk_drawing_area_new();
        gtk_widget_set_size_request(screen, SCREEN_WIDTH, SCREEN_HEIGHT);
        g_signal_connect(screen, "draw", G_CALLBACK(on_draw), pixbuf);
    }

    void keyboard(unsigned short value) {
        data[0x6000] = value;
    }

    GtkWidget* getScreenWidget() {
        return screen;
    }

    void set(unsigned int address, unsigned short value) override
    {
        data.at(address) = value;

        // check if we are writing to video RAM
        if (0x4000 <= address && address <0x6000) {
            address -= 0x4000;

            unsigned short y = address / 32;
            unsigned short x = 16*(address % 32);
            for (int bit = 0; bit<16; ++bit) {
                putpixel(x + bit, y, value & 1);
                value = value >> 1;
            }
            gdk_threads_enter();
            gtk_widget_queue_draw(screen);
            gdk_threads_leave();
        }
    }

    unsigned short get(unsigned int address) const override
    { return data.at(address); }
};

struct emulator {
    emulator();
    void load_clicked();
    void run_clicked();
    void pause_clicked();
    gboolean keyboard_callback(GdkEventKey* event);
    void run_thread();
    GtkToolItem* create_button(const gchar* stock_id, const gchar* text, GCallback callback);

    ROM rom;
    RAM ram;
    hcc::CPU cpu;

    bool running = false;

    GtkWidget* window;
    GtkWidget* load_dialog;
    GtkWidget* error_dialog;
    GtkToolItem* button_load;
    GtkToolItem* button_run;
    GtkToolItem* button_pause;
};

gboolean c_keyboard_callback(GtkWidget*, GdkEventKey *event, gpointer user_data)
{ return reinterpret_cast<emulator*>(user_data)->keyboard_callback(event); }

void c_load_clicked(GtkButton*, gpointer user_data)
{ reinterpret_cast<emulator*>(user_data)->load_clicked(); }

void c_run_clicked(GtkButton*, gpointer user_data)
{ reinterpret_cast<emulator*>(user_data)->run_clicked(); }

void c_pause_clicked(GtkButton*, gpointer user_data)
{ reinterpret_cast<emulator*>(user_data)->pause_clicked(); }

gpointer c_run_thread(gpointer user_data)
{
    reinterpret_cast<emulator*>(user_data)->run_thread();
    return NULL;
}

// Translate special keys. See Figure 5.6 in TECS book.
unsigned short translate(guint keyval)
{
    switch (keyval) {
    case GDK_KEY_Return:    return 128;
    case GDK_KEY_BackSpace: return 129;
    case GDK_KEY_Left:      return 130;
    case GDK_KEY_Up:        return 131;
    case GDK_KEY_Right:     return 132;
    case GDK_KEY_Down:      return 133;
    case GDK_KEY_Home:      return 134;
    case GDK_KEY_End:       return 135;
    case GDK_KEY_Page_Up:   return 136;
    case GDK_KEY_Page_Down: return 137;
    case GDK_KEY_Insert:    return 138;
    case GDK_KEY_Delete:    return 139;
    case GDK_KEY_Escape:    return 140;
    case GDK_KEY_F1:        return 141;
    case GDK_KEY_F2:        return 142;
    case GDK_KEY_F3:        return 143;
    case GDK_KEY_F4:        return 144;
    case GDK_KEY_F5:        return 145;
    case GDK_KEY_F6:        return 146;
    case GDK_KEY_F7:        return 147;
    case GDK_KEY_F8:        return 148;
    case GDK_KEY_F9:        return 149;
    case GDK_KEY_F10:       return 150;
    case GDK_KEY_F11:       return 151;
    case GDK_KEY_F12:       return 152;
    }
    return keyval;
}

emulator::emulator()
{
    /* toolbar buttons */
    button_load    = create_button("document-open",        "Load...", G_CALLBACK(c_load_clicked));
    button_run     = create_button("media-playback-start", "Run",     G_CALLBACK(c_run_clicked));
    button_pause   = create_button("media-playback-pause", "Pause",   G_CALLBACK(c_pause_clicked));

    GtkToolItem *separator1 = gtk_separator_tool_item_new();

    gtk_widget_set_sensitive(GTK_WIDGET(button_run), FALSE);
    gtk_widget_set_sensitive(GTK_WIDGET(button_pause), FALSE);

    /* toolbar itself */
    GtkWidget *toolbar = gtk_toolbar_new();
    gtk_widget_set_hexpand(toolbar, TRUE);
    gtk_toolbar_set_style(GTK_TOOLBAR(toolbar), GTK_TOOLBAR_ICONS);
    gtk_toolbar_insert(GTK_TOOLBAR(toolbar), button_load,  -1);
    gtk_toolbar_insert(GTK_TOOLBAR(toolbar), separator1,   -1);
    gtk_toolbar_insert(GTK_TOOLBAR(toolbar), button_run,   -1);
    gtk_toolbar_insert(GTK_TOOLBAR(toolbar), button_pause, -1);

    /* keyboard */
    GtkWidget *keyboard = gtk_toggle_button_new_with_label("Grab keyboard focus");
    gtk_widget_add_events(keyboard, GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK);
    g_signal_connect(keyboard, "key-press-event",   G_CALLBACK(c_keyboard_callback), this);
    g_signal_connect(keyboard, "key-release-event", G_CALLBACK(c_keyboard_callback), this);

    /* main layout */
    GtkWidget *grid = gtk_grid_new();
    gtk_grid_attach(GTK_GRID(grid), toolbar, 0, 0, 1, 1);
    gtk_grid_attach(GTK_GRID(grid), ram.getScreenWidget(), 0, 1, 1, 1);
    gtk_grid_attach(GTK_GRID(grid), keyboard, 0, 2, 1, 1);

    /* main window */
    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(window), "HACK emulator");
    gtk_window_set_resizable(GTK_WINDOW(window), FALSE);
    gtk_window_set_focus(GTK_WINDOW(window), NULL);
    g_signal_connect(window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
    gtk_container_add(GTK_CONTAINER(window), grid);
    gtk_widget_show_all(window);
    gtk_widget_set_visible(GTK_WIDGET(button_pause), FALSE);

    load_dialog = gtk_file_chooser_dialog_new(
        "Load ROM", GTK_WINDOW(window), GTK_FILE_CHOOSER_ACTION_OPEN,
        "gtk-cancel", GTK_RESPONSE_CANCEL,
        "gtk-open", GTK_RESPONSE_ACCEPT,
        NULL);

    error_dialog = gtk_message_dialog_new(GTK_WINDOW(window),
        GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE,
        "Error loading program");
}

GtkToolItem* emulator::create_button(const gchar* stock_id, const gchar* text, GCallback callback)
{
    GtkToolItem *button = gtk_tool_button_new(NULL, text);
    gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(button), stock_id);
    gtk_tool_item_set_tooltip_text(button, text);
    g_signal_connect(button, "clicked", callback, this);
    return button;
}

void emulator::load_clicked()
{
    const gint result = gtk_dialog_run(GTK_DIALOG(load_dialog));
    gtk_widget_hide(load_dialog);

    if (result != GTK_RESPONSE_ACCEPT) {
        return;
    }

    char *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(load_dialog));
    const bool loaded = rom.load(filename);
    g_free(filename);

    if (!loaded) {
        gtk_dialog_run(GTK_DIALOG(error_dialog));
        gtk_widget_hide(error_dialog);
        return;
    }

    cpu.reset();
    gtk_widget_set_sensitive(GTK_WIDGET(button_run), TRUE);
}

void emulator::run_clicked()
{
    assert(!running);

    running = true;
    gtk_widget_set_sensitive(GTK_WIDGET(button_run), FALSE);
    gtk_widget_set_visible(GTK_WIDGET(button_run), FALSE);
    gtk_widget_set_sensitive(GTK_WIDGET(button_pause), TRUE);
    gtk_widget_set_visible(GTK_WIDGET(button_pause), TRUE);

    g_thread_create(c_run_thread, this, FALSE, NULL);
}

void emulator::pause_clicked()
{
    assert(running);

    running = false;
    gtk_widget_set_sensitive(GTK_WIDGET(button_pause), FALSE);
    gtk_widget_set_visible(GTK_WIDGET(button_pause), FALSE);
    gtk_widget_set_sensitive(GTK_WIDGET(button_run), TRUE);
    gtk_widget_set_visible(GTK_WIDGET(button_run), TRUE);
}

gboolean emulator::keyboard_callback(GdkEventKey* event)
{
    if (event->type == GDK_KEY_RELEASE) {
        ram.keyboard(0);
    } else {
        ram.keyboard(translate(event->keyval));
    }
    return TRUE;
}

void emulator::run_thread()
{
    int steps = 0;
    while (running) {
        cpu.step(&rom, &ram);
        if (steps>100) {
            g_usleep(10);
            steps = 0;
        }
        ++steps;
    }
}

int main(int argc, char *argv[])
{
    gtk_init(&argc, &argv);
    emulator e;
    gtk_main();
    return 0;
}
<|endoftext|>


<commit_before>/*
This file is part of Bohrium and copyright (c) 2012 the Bohrium
team <http://www.bh107.org>.

Bohrium is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3
of the License, or (at your option) any later version.

Bohrium is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the
GNU Lesser General Public License along with Bohrium.

If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once

#include <type_traits>
#include <ostream>
#include <bh_static_vector.hpp>
#include <bhxx/BhBase.hpp>
#include <bhxx/type_traits_util.hpp>
#include <bhxx/array_operations.hpp>

namespace bhxx {

/** Class which enqueues an BhBase object for deletion
 *  with the Bohrium Runtime, but does not actually delete
 *  it straight away.
 *
 *  \note This is needed to ensure that all BhBase objects
 *  are still around until the list of instructions has
 *  been emptied.
 */
struct RuntimeDeleter {
    void operator()(BhBase *ptr) const;
};

/** Helper function to make shared pointers to BhBase,
 *  which use the RuntimeDeleter as their deleter */
template<typename... Args>
std::shared_ptr<BhBase> make_base_ptr(Args... args) {
    return std::shared_ptr<BhBase>(new BhBase(std::forward<Args>(args)...), RuntimeDeleter{});
}

/** Static allocated shapes and strides that is interchangeable with standard C++ vector as long
 *  as the vector is smaller than `BH_MAXDIM`.
 */
typedef BhStaticVector<uint64_t> Shape;
using Stride = BhIntVec;

/** Return a contiguous stride (row-major) based on `shape` */
extern inline Stride contiguous_stride(const Shape &shape) {
    Stride ret(shape.size());
    int64_t stride = 1;
    for (int64_t i = shape.size() - 1; i >= 0; --i) {
        ret[i] = stride;
        stride *= shape[i];
    }
    return ret;
}

/** Core class that represent the core attributes of a view that isn't typed by its dtype */
class BhArrayUnTypedCore {
protected:
    /// The array offset (from the start of the base in number of elements)
    uint64_t _offset = 0;
    /// The array shape (size of each dimension in number of elements)
    Shape _shape;
    /// The array stride (the absolute stride of each dimension in number of elements)
    Stride _stride;
    /// Pointer to the base of this array
    std::shared_ptr<BhBase> _base;
    /// Metadata to support sliding views
    bh_slide _slides;
public:

    /** Default constructor that leave the instance completely uninitialized */
    BhArrayUnTypedCore() = default;

    /** Constructor to initiate all but the `_slides` attribute */
    BhArrayUnTypedCore(uint64_t offset, Shape shape, Stride stride, std::shared_ptr<BhBase> base) :
            _offset(offset), _shape(std::move(shape)), _stride(std::move(stride)), _base(std::move(base)) {
        if (_shape.size() != _stride.size()) {
            throw std::runtime_error("The shape and stride must have same length");
        }
        if (shape.prod() <= 0) {
            throw std::runtime_error("The total size must be greater than zero");
        }
    }

    /** Return a `bh_view` of the array */
    bh_view getBhView() const {
        bh_view view;
        assert(_base.use_count() > 0);
        view.base = _base.get();
        view.start = static_cast<int64_t>(offset());
        if (shape().empty()) { // Scalar views (i.e. 0-dim views) are represented as 1-dim arrays with size one.
            view.ndim = 1;
            view.shape = BhIntVec({1});
            view.stride = BhIntVec({1});
        } else {
            view.ndim = static_cast<int64_t>(shape().size());
            view.shape = BhIntVec(shape().begin(), shape().end());
            view.stride = BhIntVec(_stride.begin(), _stride.end());;
        }
        view.slides = _slides;
        return view;
    }

    /** Swapping `a` and `b` */
    friend void swap(BhArrayUnTypedCore &a, BhArrayUnTypedCore &b) noexcept {
        using std::swap; // enable ADL
        swap(a._offset, b._offset);
        swap(a._shape, b._shape);
        swap(a._stride, b._stride);
        swap(a._base, b._base);
        swap(a._slides, b._slides);
    }

    /** Return the offset of the array */
    uint64_t offset() const {
        return _offset;
    }

    /** Return the shape of the array */
    const Shape &shape() const {
        return _shape;
    }

    /** Return the stride of the array */
    const Stride &stride() const {
        return _stride;
    }

    /** Return the base of the array */
    const std::shared_ptr<BhBase> &base() const {
        return _base;
    }

    /** Return the base of the array */
    std::shared_ptr<BhBase> base() {
        return _base;
    }

    /** Set the shape and stride of the array (both must have the same lenth) */
    void setShapeAndStride(Shape shape, Stride stride) {
        if (shape.size() != stride.size()) {
            throw std::runtime_error("The shape and stride must have same length");
        }
        _shape = std::move(shape);
        _stride = std::move(stride);
    }

    /** Return the slides object of the array */
    const bh_slide &slides() const {
        return _slides;
    }

    /** Return the slides object of the array */
    bh_slide &slides() {
        return _slides;
    }
};

/** Representation of a multidimensional array that point to a `BhBase` array.
 *
 * @tparam T  The data type of the array and the underlying base array
 */
template<typename T>
class BhArray : public BhArrayUnTypedCore {
public:
    /// The data type of each array element
    typedef T scalar_type;

    /** Default constructor that leave the instance completely uninitialized. */
    BhArray() = default;

    /** Create a new array. `Shape` and `Stride` must have the same length.
     *
     * @param shape   Shape of the new array
     * @param stride  Stride of the new array
     */
    explicit BhArray(Shape shape, Stride stride) : BhArrayUnTypedCore{0, std::move(shape), std::move(stride),
                                                                      make_base_ptr(T(0), shape.prod())} {}

    /** Create a new array (contiguous stride, row-major) */
    explicit BhArray(Shape shape) : BhArray(std::move(shape), contiguous_stride(shape)) {}

    /** Create a array that points to the given base
     *
     *  \note The caller should make sure that the shared pointer
     *        uses the RuntimeDeleter as its deleter, since this is
     *        implicitly assumed throughout, i.e. if one wants to
     *        construct a BhBase object, use the make_base_ptr
     *        helper function.
     */
    explicit BhArray(std::shared_ptr<BhBase> base, Shape shape, Stride stride, uint64_t offset = 0) :
            BhArrayUnTypedCore{offset, std::move(shape), std::move(stride), std::move(base)} {
        assert(shape.size() == stride.size());
        assert(shape.prod() > 0);
    }

    /** Create a view that points to the given base (contiguous stride, row-major)
     *
     *  \note The caller should make sure that the shared pointer
     *        uses the RuntimeDeleter as its deleter, since this is
     *        implicitly assumed throughout, i.e. if one wants to
     *        construct a BhBase object, use the make_base_ptr
     *        helper function.
     */
    explicit BhArray(std::shared_ptr<BhBase> base, Shape shape) : BhArray(std::move(base), std::move(shape),
                                                                          contiguous_stride(shape), 0) {
        assert(static_cast<uint64_t>(base->nelem()) == shape.prod());
    }

    /** Create a copy of `ary` using a Bohrium `identity` operation, which copies the underlying array data.
     *
     *  \note This function implements implicit type conversion for all widening type casts
     */
    template<typename InType,
            typename std::enable_if<type_traits::is_safe_numeric_cast<scalar_type, InType>::value, int>::type = 0>
    BhArray(const BhArray<InType> &ary) : BhArray(ary.shape()) {
        bhxx::identity(*this, ary);
    }

    /** Copy constructor that only copies meta data. The underlying array data is untouched */
    BhArray(const BhArray &) = default;

    /** Move constructor that only moves meta data. The underlying array data is untouched */
    BhArray(BhArray &&) noexcept = default;

    /** Copy the data of `other` into the array using a Bohrium `identity` operation */
    BhArray<T> &operator=(const BhArray<T> &other) {
        bhxx::identity(*this, other);
        return *this;
    }

    /** Copy the data of `other` into the array using a Bohrium `identity` operation
     *
     *  \note A move assignment is the same as a copy assignment.
     */
    BhArray<T> &operator=(BhArray<T> &&other) {
        bhxx::identity(*this, other);
        other.reset();
        return *this;
    }

    /**  Copy the scalar of `scalar_value` into the array using a Bohrium `identity` operation */
    template<typename InType,
            typename std::enable_if<type_traits::is_arithmetic<InType>::value, int>::type = 0>
    BhArray<T> &operator=(const InType &scalar_value) {
        bhxx::identity(*this, scalar_value);
        return *this;
    }

    /** Reset the array to `ary` */
    void reset(BhArray<T> ary) noexcept {
        using std::swap;
        swap(*this, ary);
    }

    /** Reset the array by cleaning all meta data and leave the array uninitialized. */
    void reset() noexcept {
        reset(BhArray());
    }

    /** Return the rank of the BhArray */
    size_t rank() const {
        assert(shape().size() == _stride.size());
        return shape().size();
    }

    /** Return the number of elements */
    uint64_t size() const {
        return shape().prod();
    }

    /** Return whether the view is contiguous and row-major */
    bool isContiguous() const;

    /** Is the data referenced by this view's base array already
     *  allocated, i.e. initialised */
    bool isDataInitialised() const { return _base->getDataPtr() != nullptr; }

    /** Obtain the data pointer of the array, not taking ownership of any kind.
     *
     *  \note This pointer might be a nullptr if the data in
     *        the base data is not initialised.
     *
     *  \note No flush is done automatically. The data might be
     *        out of sync with Bohrium.
     */
    T *data() {
        T *ret = static_cast<T *>(_base->getDataPtr());
        if (ret == nullptr) {
            return nullptr;
        } else {
            return _offset + ret;
        }
    }

    /// The const version of `data()`
    const T *data() const {
        const T *ret = static_cast<T *>(_base->getDataPtr());
        if (ret == nullptr) {
            return nullptr;
        } else {
            return _offset + ret;
        }
    }

    /// Pretty printing the content of the array
    void pprint(std::ostream &os) const;

    /// Returns a new view of the `idx` dimension. Negative index counts from the back
    BhArray<T> operator[](int64_t idx) const;

    /// Return a new transposed view
    BhArray<T> transpose() const;

    /// Return a new reshaped view (the array must be contiguous)
    BhArray<T> reshape(Shape shape) const;
};

template<typename T>
std::ostream &operator<<(std::ostream &os, const BhArray<T> &ary) {
    ary.pprint(os);
    return os;
}

}  // namespace bhxx
<commit_msg>bhxx: reset() now uses the correct swap()<commit_after>/*
This file is part of Bohrium and copyright (c) 2012 the Bohrium
team <http://www.bh107.org>.

Bohrium is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3
of the License, or (at your option) any later version.

Bohrium is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the
GNU Lesser General Public License along with Bohrium.

If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once

#include <type_traits>
#include <ostream>
#include <bh_static_vector.hpp>
#include <bhxx/BhBase.hpp>
#include <bhxx/type_traits_util.hpp>
#include <bhxx/array_operations.hpp>

namespace bhxx {

/** Class which enqueues an BhBase object for deletion
 *  with the Bohrium Runtime, but does not actually delete
 *  it straight away.
 *
 *  \note This is needed to ensure that all BhBase objects
 *  are still around until the list of instructions has
 *  been emptied.
 */
struct RuntimeDeleter {
    void operator()(BhBase *ptr) const;
};

/** Helper function to make shared pointers to BhBase,
 *  which use the RuntimeDeleter as their deleter */
template<typename... Args>
std::shared_ptr<BhBase> make_base_ptr(Args... args) {
    return std::shared_ptr<BhBase>(new BhBase(std::forward<Args>(args)...), RuntimeDeleter{});
}

/** Static allocated shapes and strides that is interchangeable with standard C++ vector as long
 *  as the vector is smaller than `BH_MAXDIM`.
 */
typedef BhStaticVector<uint64_t> Shape;
using Stride = BhIntVec;

/** Return a contiguous stride (row-major) based on `shape` */
extern inline Stride contiguous_stride(const Shape &shape) {
    Stride ret(shape.size());
    int64_t stride = 1;
    for (int64_t i = shape.size() - 1; i >= 0; --i) {
        ret[i] = stride;
        stride *= shape[i];
    }
    return ret;
}

/** Core class that represent the core attributes of a view that isn't typed by its dtype */
class BhArrayUnTypedCore {
protected:
    /// The array offset (from the start of the base in number of elements)
    uint64_t _offset = 0;
    /// The array shape (size of each dimension in number of elements)
    Shape _shape;
    /// The array stride (the absolute stride of each dimension in number of elements)
    Stride _stride;
    /// Pointer to the base of this array
    std::shared_ptr<BhBase> _base;
    /// Metadata to support sliding views
    bh_slide _slides;
public:

    /** Default constructor that leave the instance completely uninitialized */
    BhArrayUnTypedCore() = default;

    /** Constructor to initiate all but the `_slides` attribute */
    BhArrayUnTypedCore(uint64_t offset, Shape shape, Stride stride, std::shared_ptr<BhBase> base) :
            _offset(offset), _shape(std::move(shape)), _stride(std::move(stride)), _base(std::move(base)) {
        if (_shape.size() != _stride.size()) {
            throw std::runtime_error("The shape and stride must have same length");
        }
        if (shape.prod() <= 0) {
            throw std::runtime_error("The total size must be greater than zero");
        }
    }

    /** Return a `bh_view` of the array */
    bh_view getBhView() const {
        bh_view view;
        assert(_base);
        view.base = _base.get();
        view.start = static_cast<int64_t>(offset());
        if (shape().empty()) { // Scalar views (i.e. 0-dim views) are represented as 1-dim arrays with size one.
            view.ndim = 1;
            view.shape = BhIntVec({1});
            view.stride = BhIntVec({1});
        } else {
            view.ndim = static_cast<int64_t>(shape().size());
            view.shape = BhIntVec(shape().begin(), shape().end());
            view.stride = BhIntVec(_stride.begin(), _stride.end());;
        }
        view.slides = _slides;
        return view;
    }

    /** Swapping `a` and `b` */
    friend void swap(BhArrayUnTypedCore &a, BhArrayUnTypedCore &b) noexcept {
        using std::swap; // enable ADL
        swap(a._offset, b._offset);
        swap(a._shape, b._shape);
        swap(a._stride, b._stride);
        swap(a._base, b._base);
        swap(a._slides, b._slides);
    }

    /** Return the offset of the array */
    uint64_t offset() const {
        return _offset;
    }

    /** Return the shape of the array */
    const Shape &shape() const {
        return _shape;
    }

    /** Return the stride of the array */
    const Stride &stride() const {
        return _stride;
    }

    /** Return the base of the array */
    const std::shared_ptr<BhBase> &base() const {
        return _base;
    }

    /** Return the base of the array */
    std::shared_ptr<BhBase> base() {
        return _base;
    }

    /** Set the shape and stride of the array (both must have the same lenth) */
    void setShapeAndStride(Shape shape, Stride stride) {
        if (shape.size() != stride.size()) {
            throw std::runtime_error("The shape and stride must have same length");
        }
        _shape = std::move(shape);
        _stride = std::move(stride);
    }

    /** Return the slides object of the array */
    const bh_slide &slides() const {
        return _slides;
    }

    /** Return the slides object of the array */
    bh_slide &slides() {
        return _slides;
    }
};

/** Representation of a multidimensional array that point to a `BhBase` array.
 *
 * @tparam T  The data type of the array and the underlying base array
 */
template<typename T>
class BhArray : public BhArrayUnTypedCore {
public:
    /// The data type of each array element
    typedef T scalar_type;

    /** Default constructor that leave the instance completely uninitialized. */
    BhArray() = default;

    /** Create a new array. `Shape` and `Stride` must have the same length.
     *
     * @param shape   Shape of the new array
     * @param stride  Stride of the new array
     */
    explicit BhArray(Shape shape, Stride stride) : BhArrayUnTypedCore{0, std::move(shape), std::move(stride),
                                                                      make_base_ptr(T(0), shape.prod())} {}

    /** Create a new array (contiguous stride, row-major) */
    explicit BhArray(Shape shape) : BhArray(std::move(shape), contiguous_stride(shape)) {}

    /** Create a array that points to the given base
     *
     *  \note The caller should make sure that the shared pointer
     *        uses the RuntimeDeleter as its deleter, since this is
     *        implicitly assumed throughout, i.e. if one wants to
     *        construct a BhBase object, use the make_base_ptr
     *        helper function.
     */
    explicit BhArray(std::shared_ptr<BhBase> base, Shape shape, Stride stride, uint64_t offset = 0) :
            BhArrayUnTypedCore{offset, std::move(shape), std::move(stride), std::move(base)} {
        assert(shape.size() == stride.size());
        assert(shape.prod() > 0);
    }

    /** Create a view that points to the given base (contiguous stride, row-major)
     *
     *  \note The caller should make sure that the shared pointer
     *        uses the RuntimeDeleter as its deleter, since this is
     *        implicitly assumed throughout, i.e. if one wants to
     *        construct a BhBase object, use the make_base_ptr
     *        helper function.
     */
    explicit BhArray(std::shared_ptr<BhBase> base, Shape shape) : BhArray(std::move(base), std::move(shape),
                                                                          contiguous_stride(shape), 0) {
        assert(static_cast<uint64_t>(base->nelem()) == shape.prod());
    }

    /** Create a copy of `ary` using a Bohrium `identity` operation, which copies the underlying array data.
     *
     *  \note This function implements implicit type conversion for all widening type casts
     */
    template<typename InType,
            typename std::enable_if<type_traits::is_safe_numeric_cast<scalar_type, InType>::value, int>::type = 0>
    BhArray(const BhArray<InType> &ary) : BhArray(ary.shape()) {
        bhxx::identity(*this, ary);
    }

    /** Copy constructor that only copies meta data. The underlying array data is untouched */
    BhArray(const BhArray &) = default;

    /** Move constructor that only moves meta data. The underlying array data is untouched */
    BhArray(BhArray &&) noexcept = default;

    /** Copy the data of `other` into the array using a Bohrium `identity` operation */
    BhArray<T> &operator=(const BhArray<T> &other) {
        bhxx::identity(*this, other);
        return *this;
    }

    /** Copy the data of `other` into the array using a Bohrium `identity` operation
     *
     *  \note A move assignment is the same as a copy assignment.
     */
    BhArray<T> &operator=(BhArray<T> &&other) {
        bhxx::identity(*this, other);
        other.reset();
        return *this;
    }

    /**  Copy the scalar of `scalar_value` into the array using a Bohrium `identity` operation */
    template<typename InType,
            typename std::enable_if<type_traits::is_arithmetic<InType>::value, int>::type = 0>
    BhArray<T> &operator=(const InType &scalar_value) {
        bhxx::identity(*this, scalar_value);
        return *this;
    }

    /** Reset the array to `ary` */
    void reset(BhArray<T> ary) noexcept {
        swap(*this, ary);
    }

    /** Reset the array by cleaning all meta data and leave the array uninitialized. */
    void reset() noexcept {
        reset(BhArray());
    }

    /** Return the rank of the BhArray */
    size_t rank() const {
        assert(shape().size() == _stride.size());
        return shape().size();
    }

    /** Return the number of elements */
    uint64_t size() const {
        return shape().prod();
    }

    /** Return whether the view is contiguous and row-major */
    bool isContiguous() const;

    /** Is the data referenced by this view's base array already
     *  allocated, i.e. initialised */
    bool isDataInitialised() const { return _base->getDataPtr() != nullptr; }

    /** Obtain the data pointer of the array, not taking ownership of any kind.
     *
     *  \note This pointer might be a nullptr if the data in
     *        the base data is not initialised.
     *
     *  \note No flush is done automatically. The data might be
     *        out of sync with Bohrium.
     */
    T *data() {
        T *ret = static_cast<T *>(_base->getDataPtr());
        if (ret == nullptr) {
            return nullptr;
        } else {
            return _offset + ret;
        }
    }

    /// The const version of `data()`
    const T *data() const {
        const T *ret = static_cast<T *>(_base->getDataPtr());
        if (ret == nullptr) {
            return nullptr;
        } else {
            return _offset + ret;
        }
    }

    /// Pretty printing the content of the array
    void pprint(std::ostream &os) const;

    /// Returns a new view of the `idx` dimension. Negative index counts from the back
    BhArray<T> operator[](int64_t idx) const;

    /// Return a new transposed view
    BhArray<T> transpose() const;

    /// Return a new reshaped view (the array must be contiguous)
    BhArray<T> reshape(Shape shape) const;
};

template<typename T>
std::ostream &operator<<(std::ostream &os, const BhArray<T> &ary) {
    ary.pprint(os);
    return os;
}

}  // namespace bhxx
<|endoftext|>


<commit_before>#include "browser/inspectable_web_contents.h"

#include "browser/inspectable_web_contents_impl.h"

namespace brightray {

InspectableWebContents* InspectableWebContents::Create(const content::WebContents::CreateParams& create_params) {
  return Create(content::WebContents::Create(create_params));
}

InspectableWebContents* InspectableWebContents::Create(content::WebContents* web_contents) {
  return new InspectableWebContentsImpl(web_contents);
}

}
<commit_msg>Fix flashing in WebContents we create<commit_after>#include "browser/inspectable_web_contents.h"

#include "browser/inspectable_web_contents_impl.h"

#include "content/public/browser/web_contents_view.h"

namespace brightray {

InspectableWebContents* InspectableWebContents::Create(const content::WebContents::CreateParams& create_params) {
  auto contents = content::WebContents::Create(create_params);
#if defined(OS_MACOSX)
  // Work around http://crbug.com/279472.
  contents->GetView()->SetAllowOverlappingViews(true);
#endif

  return Create(contents);
}

InspectableWebContents* InspectableWebContents::Create(content::WebContents* web_contents) {
  return new InspectableWebContentsImpl(web_contents);
}

}
<|endoftext|>


<commit_before>#include "ExeBox.h"
#include <Entry.h>
#include <FindDirectory.h>
#include <Directory.h>
#include <storage/Node.h>
#include <OS.h>
#include <File.h>
#include <storage/Path.h>
#include <Locker.h>
#include "ObjectList.h"

#include <Volume.h>
#include <VolumeRoster.h>
#include <Query.h>

static BObjectList<entry_ref> *sPathData = NULL;
BLocker sPathDataLock;
thread_id sThreadID = -1;

void PrintList(const char* s)
{
	sPathDataLock.Lock();
	int len = sPathData->CountItems();

	printf("Count: %i\nsPathData (%s) :\n", len, s);

	for ( int i = 0; i < len ; i += 3 )
	{
		printf("%i: %-13.13s\t", i, sPathData->ItemAt(i)->name);
		if ( i+1 < len )
			printf("%i: %-13.13s\t", i+1, sPathData->ItemAt(i+1)->name);
		if ( i+2 < len )
			printf("%i: %-13.13s\t", i+2, sPathData->ItemAt(i+2)->name);

		printf("\n");
	}
	sPathDataLock.Unlock();
}

ExeBoxFilter::ExeBoxFilter(ExeBox *box)
 :	AutoTextControlFilter(box)
{
}

filter_result
ExeBoxFilter::KeyFilter(const int32 &key, const int32 &mod)
{
	if (key < 32 || ( (mod & B_COMMAND_KEY) && !(mod & B_SHIFT_KEY) &&
					!(mod & B_OPTION_KEY) && !(mod & B_CONTROL_KEY)) )
		return B_DISPATCH_MESSAGE;

	int32 start, end;
	TextControl()->TextView()->GetSelection(&start,&end);
	if (end == (int32)strlen(TextControl()->Text()))
	{
		TextControl()->TextView()->Delete(start,end);

		BString string;
		if( GetCurrentMessage()->FindString("bytes",&string) != B_OK)
			string = "";
		string.Prepend(TextControl()->Text());

		entry_ref *match = NULL, *data;;

		sPathDataLock.Lock();
		for (int32 i = 0; i < sPathData->CountItems(); i++)
		{
			data = sPathData->ItemAt(i);
			BString namestr(data->name);

			if (!data->name)
				continue;

			if (namestr.IFindFirst(string) == 0)
			{
				match = data;
				break;
			}
		}
		sPathDataLock.Unlock();

		if(match)
		{
			BMessage automsg(M_EXE_AUTOCOMPLETE);
			automsg.AddInt32("start",strlen(TextControl()->Text())+1);
			automsg.AddString("string",match->name);

			BMessenger msgr((BHandler*)TextControl()->Window());
			msgr.SendMessage(&automsg);
		}
	}

	return B_DISPATCH_MESSAGE;
}

ExeBox::ExeBox(const BRect &frame, const char *name, const char *label,
			const char *text, BMessage *msg, uint32 resize, uint32 flags)
 :	AutoTextControl(frame,name,label,text,msg,resize,flags)
{
	if (!sPathData)
		InitializeAutocompletion();

	SetFilter(new ExeBoxFilter(this));
	SetCharacterLimit(32);
}

ExeBox::~ExeBox(void)
{
	int32 value;
	sPathDataLock.Lock();
	if (sThreadID >= 0)
	{
		sPathDataLock.Unlock();
		wait_for_thread(sThreadID,&value);
	}
	else
		sPathDataLock.Unlock();
}

entry_ref *
ExeBox::FindMatch(const char *name)
{
	// Handle the autocompletion

	if (!name)
		return NULL;

	entry_ref *match = NULL;

	sPathDataLock.Lock();
	for (int32 i = 0; i < sPathData->CountItems(); i++)
	{
		entry_ref *data = sPathData->ItemAt(i);
		if (!data->name)
			continue;

		BString refstr(data->name);
		if (refstr.IFindFirst(name) == 0)
		{
			match = data;
			break;
		}
	}
	sPathDataLock.Unlock();

	return match;
}

void
ExeBox::InitializeAutocompletion(void)
{
	sPathData = new BObjectList<entry_ref>(20,true);

	// Set up autocomplete
	BEntry entry("/boot/home/config/settings/Run Program");
	BPath path;
	entry_ref ref;

	if (entry.Exists())
	{
		BFile settingsFile("/boot/home/config/settings/Run Program",B_READ_ONLY);
		BMessage settings;
		if (settings.Unflatten(&settingsFile) == B_OK)
		{
			int32 index = 0;
			while (settings.FindRef("refs",index,&ref) == B_OK)
			{
				index++;

				entry_ref *listref = new entry_ref(ref);
				sPathData->AddItem(listref);
			}

			sThreadID = spawn_thread(UpdateThread,
							"updatethread",	B_NORMAL_PRIORITY,	NULL);
			if (sThreadID >= 0)
				resume_thread(sThreadID);
			return;
		}

	}

	BDirectory dir;

	find_directory(B_BEOS_BIN_DIRECTORY,&path);
	dir.SetTo(path.Path());
	dir.Rewind();
	while (dir.GetNextRef(&ref) == B_OK)
	{
		entry.SetTo(&ref,true);
		entry.GetRef(&ref);

		entry_ref *match = NULL;
		for (int32 i = 0; i < sPathData->CountItems(); i++)
		{
			entry_ref *listref = sPathData->ItemAt(i);
			if (*listref == ref)
			{
				match = listref;
				break;
			}
		}
		if (!match)
			sPathData->AddItem(new entry_ref(ref));
	}

	find_directory(B_COMMON_BIN_DIRECTORY,&path);
	dir.SetTo(path.Path());
	dir.Rewind();
	while (dir.GetNextRef(&ref) == B_OK)
	{
		entry.SetTo(&ref, true);
		entry.GetRef(&ref);

		entry_ref *match = NULL;
		for (int32 i = 0; i < sPathData->CountItems(); i++)
		{
			entry_ref *listref = sPathData->ItemAt(i);
			if (*listref == ref)
			{
				match = listref;
				break;
			}
		}
		if (!match)
			sPathData->AddItem(new entry_ref(ref));
	}

	sThreadID = spawn_thread(QueryThread, "querythread", B_NORMAL_PRIORITY, NULL);
	if (sThreadID >= 0)
		resume_thread(sThreadID);

}

static
int
CompareRefs(const entry_ref *ref1, const entry_ref *ref2)
{
	if (!ref1)
		return -1;
	else if (!ref2)
		return 1;

	return strcmp(ref1->name,ref2->name);
}

int32
ExeBox::QueryThread(void *data)
{
	BVolumeRoster 	roster;
	BVolume 		vol;
	BQuery			query;
	entry_ref		ref;

	roster.GetBootVolume(&vol);

	query.SetVolume(&vol);
	query.SetPredicate("((BEOS:APP_SIG==\"application*\")&&"
						"(BEOS:TYPE==\"application/x-vnd.Be-elfexecutable\"))");
	query.Fetch();

	while (query.GetNextRef(&ref) == B_OK)
	{
		if ( ref.directory == B_USER_ADDONS_DIRECTORY
			|| ref.directory == B_BEOS_ADDONS_DIRECTORY
			|| ref.directory == B_COMMON_ADDONS_DIRECTORY)
			continue;

		if (ref.directory == -1)
		{
			fprintf(stderr, "FATAL : Query returned invalid ref!\n");
			return -1;
		}

		sPathDataLock.Lock();
		sPathData->AddItem(new entry_ref(ref));
		sPathDataLock.Unlock();
	}

	BMessage settings;

	sPathDataLock.Lock();
	for (int32 i = 0; i < sPathData->CountItems(); i++)
		settings.AddRef("refs", sPathData->ItemAt(i));
	sPathDataLock.Unlock();

	BFile settingsFile("/boot/home/config/settings/Run Program", B_READ_WRITE |
																B_ERASE_FILE |
																B_CREATE_FILE);
	settings.Flatten(&settingsFile);

	sPathDataLock.Lock();
	sThreadID = -1;
	sPathDataLock.Unlock();
	return 0;
}

int32
ExeBox::UpdateThread(void *data)
{
	// This takes longer, but it's not really time-critical. Most of the time there
	// will only be minor differences between run sessions.

	// In order to save as much time as possible:
	// 1) Get a new ref list via scanning the usual places. This won't take long, thanks
	//	  to the file cache. :)
	// 2) For each item in the official list
	//		- if entry doesn't exist, remove it
	//		- if entry does exist, remove it from the temporary list
	// 3) Add any remaining entries in the temporary list to the official one
	// 4) Update the disk version of the settings file

	BObjectList<entry_ref> queryList(20,true);

	BDirectory 		dir;
	BPath 			path;
	entry_ref 		ref,	*pref;
	BEntry 			entry;
	BVolumeRoster 	roster;
	BVolume 		vol;
	BQuery 			query;

	find_directory(B_BEOS_BIN_DIRECTORY,&path);
	dir.SetTo(path.Path());
	dir.Rewind();

	while (dir.GetNextRef(&ref) == B_OK)
	{
		entry.SetTo(&ref, true);
		entry.GetRef(&ref);
		entry.Unset();
		queryList.AddItem(new entry_ref(ref));
	}

	find_directory(B_COMMON_BIN_DIRECTORY,&path);
	dir.SetTo(path.Path());
	dir.Rewind();

	while (dir.GetNextRef(&ref) == B_OK)
	{
		entry.SetTo(&ref,true);
		entry.GetRef(&ref);
		entry.Unset();
		queryList.AddItem(new entry_ref(ref));
	}

	roster.GetBootVolume(&vol);
	query.SetVolume(&vol);
	query.SetPredicate("((BEOS:APP_SIG==\"application*\")&&"
						"(BEOS:TYPE==\"application/x-vnd.Be-elfexecutable\"))");
	query.Fetch();

	while (query.GetNextRef(&ref) == B_OK)
	{
		entry.SetTo(&ref,true);
		entry.GetPath(&path);
		entry.GetRef(&ref);
		entry.Unset();
		if (strstr(path.Path(),"add-ons") || strstr(path.Path(),"beos/servers") ||
			!ref.name)
			continue;
		queryList.AddItem(new entry_ref(ref));
	}

	// Scan is finished, so start culling
	sPathDataLock.Lock();
	int32 count = sPathData->CountItems();
	sPathDataLock.Unlock();

	for (int32 i = 0; i < count; i++)
	{
		sPathDataLock.Lock();
		pref = sPathData->ItemAt(i);
		entry.SetTo(pref);

		if (! entry.Exists() )
			sPathData->RemoveItemAt( i );
		else
		{
			for (int32 j = 0; j < queryList.CountItems(); j++)
			{
				if (*pref == *queryList.ItemAt(j))
				{
					queryList.RemoveItemAt(j);
					break;
				}
			}
		}
		entry.Unset();
		sPathDataLock.Unlock();
	}

	// Remaining items in queryList are new entries
	sPathDataLock.Lock();
	for (int32 j = 0; j < queryList.CountItems(); j++)
	{
		entry_ref *qref = queryList.RemoveItemAt(j);
		if (qref &&	qref->directory >= 0)
			sPathData->AddItem(qref);
	}
	sPathDataLock.Unlock();

	BMessage settings;

	sPathDataLock.Lock();
 	sPathData->SortItems(CompareRefs);
	sPathDataLock.Unlock();

	sPathDataLock.Lock();
	for (int32 i = 0; i < sPathData->CountItems(); i++)
	{
		entry_ref *listref = sPathData->ItemAt(i);
		settings.AddRef("refs",listref);
	}
	sPathDataLock.Unlock();

	BFile settingsFile("/boot/home/config/settings/Run Program", B_READ_WRITE |
																B_ERASE_FILE |
																B_CREATE_FILE);
	settings.Flatten(&settingsFile);

	sPathDataLock.Lock();
	sThreadID = -1;
	sPathDataLock.Unlock();

	return 0;
}
<commit_msg>applying patch runprogram-1.0rc1.patch<commit_after>#include "ExeBox.h"
#include <Entry.h>
#include <FindDirectory.h>
#include <Directory.h>
#include <storage/Node.h>
#include <OS.h>
#include <File.h>
#include <storage/Path.h>
#include <Locker.h>
#include "ObjectList.h"

#include <Volume.h>
#include <VolumeRoster.h>
#include <Query.h>

static BObjectList<entry_ref> *sPathData = NULL;
BLocker sPathDataLock;
thread_id sThreadID = -1;

void PrintList(const char* s)
{
	sPathDataLock.Lock();
	int len = sPathData->CountItems();

	printf("Count: %i\nsPathData (%s) :\n", len, s);

	for ( int i = 0; i < len ; i += 3 )
	{
		printf("%i: %-13.13s\t", i, sPathData->ItemAt(i)->name);
		if ( i+1 < len )
			printf("%i: %-13.13s\t", i+1, sPathData->ItemAt(i+1)->name);
		if ( i+2 < len )
			printf("%i: %-13.13s\t", i+2, sPathData->ItemAt(i+2)->name);

		printf("\n");
	}
	sPathDataLock.Unlock();
}

ExeBoxFilter::ExeBoxFilter(ExeBox *box)
 :	AutoTextControlFilter(box)
{
}

filter_result
ExeBoxFilter::KeyFilter(const int32 &key, const int32 &mod)
{
	if (key < 32 || ( (mod & B_COMMAND_KEY) && !(mod & B_SHIFT_KEY) &&
					!(mod & B_OPTION_KEY) && !(mod & B_CONTROL_KEY)) )
		return B_DISPATCH_MESSAGE;

	int32 start, end;
	TextControl()->TextView()->GetSelection(&start,&end);
	if (end == (int32)strlen(TextControl()->Text()))
	{
		TextControl()->TextView()->Delete(start,end);

		BString string;
		if( GetCurrentMessage()->FindString("bytes",&string) != B_OK)
			string = "";
		string.Prepend(TextControl()->Text());

		entry_ref *match = NULL, *data;;

		sPathDataLock.Lock();
		for (int32 i = 0; i < sPathData->CountItems(); i++)
		{
			data = sPathData->ItemAt(i);
			BString namestr(data->name);

			if (!data->name)
				continue;

			if (namestr.IFindFirst(string) == 0)
			{
				match = data;
				break;
			}
		}
		sPathDataLock.Unlock();

		if(match)
		{
			BMessage automsg(M_EXE_AUTOCOMPLETE);
			automsg.AddInt32("start",strlen(TextControl()->Text())+1);
			automsg.AddString("string",match->name);

			BMessenger msgr((BHandler*)TextControl()->Window());
			msgr.SendMessage(&automsg);
		}
	}

	return B_DISPATCH_MESSAGE;
}

ExeBox::ExeBox(const BRect &frame, const char *name, const char *label,
			const char *text, BMessage *msg, uint32 resize, uint32 flags)
 :	AutoTextControl(frame,name,label,text,msg,resize,flags)
{
	if (!sPathData)
		InitializeAutocompletion();

	SetFilter(new ExeBoxFilter(this));
	SetCharacterLimit(32);
}

ExeBox::~ExeBox(void)
{
	int32 value;
	sPathDataLock.Lock();
	if (sThreadID >= 0)
	{
		sPathDataLock.Unlock();
		wait_for_thread(sThreadID,&value);
	}
	else
		sPathDataLock.Unlock();
}

entry_ref *
ExeBox::FindMatch(const char *name)
{
	// Handle the autocompletion

	if (!name)
		return NULL;

	entry_ref *match = NULL;

	sPathDataLock.Lock();
	for (int32 i = 0; i < sPathData->CountItems(); i++)
	{
		entry_ref *data = sPathData->ItemAt(i);
		if (!data->name)
			continue;

		BString refstr(data->name);
		if (refstr.IFindFirst(name) == 0)
		{
			match = data;
			break;
		}
	}
	sPathDataLock.Unlock();

	return match;
}

void
ExeBox::InitializeAutocompletion(void)
{
	sPathData = new BObjectList<entry_ref>(20,true);

	// Set up autocomplete
	BEntry entry("/boot/home/config/settings/Run Program");
	BPath path;
	entry_ref ref;

	if (entry.Exists())
	{
		BFile settingsFile("/boot/home/config/settings/Run Program",B_READ_ONLY);
		BMessage settings;
		if (settings.Unflatten(&settingsFile) == B_OK)
		{
			int32 index = 0;
			while (settings.FindRef("refs",index,&ref) == B_OK)
			{
				index++;

				entry_ref *listref = new entry_ref(ref);
				sPathData->AddItem(listref);
			}

			sThreadID = spawn_thread(UpdateThread,
							"updatethread",	B_NORMAL_PRIORITY,	NULL);
			if (sThreadID >= 0)
				resume_thread(sThreadID);
			return;
		}

	}

	BDirectory dir;

	find_directory(B_BEOS_BIN_DIRECTORY,&path);
	dir.SetTo(path.Path());
	dir.Rewind();
	while (dir.GetNextRef(&ref) == B_OK)
	{
		entry.SetTo(&ref,true);
		entry.GetRef(&ref);

		entry_ref *match = NULL;
		for (int32 i = 0; i < sPathData->CountItems(); i++)
		{
			entry_ref *listref = sPathData->ItemAt(i);
			if (*listref == ref)
			{
				match = listref;
				break;
			}
		}
		if (!match)
			sPathData->AddItem(new entry_ref(ref));
	}

	find_directory(B_SYSTEM_BIN_DIRECTORY,&path);
	dir.SetTo(path.Path());
	dir.Rewind();
	while (dir.GetNextRef(&ref) == B_OK)
	{
		entry.SetTo(&ref, true);
		entry.GetRef(&ref);

		entry_ref *match = NULL;
		for (int32 i = 0; i < sPathData->CountItems(); i++)
		{
			entry_ref *listref = sPathData->ItemAt(i);
			if (*listref == ref)
			{
				match = listref;
				break;
			}
		}
		if (!match)
			sPathData->AddItem(new entry_ref(ref));
	}

	sThreadID = spawn_thread(QueryThread, "querythread", B_NORMAL_PRIORITY, NULL);
	if (sThreadID >= 0)
		resume_thread(sThreadID);

}

static
int
CompareRefs(const entry_ref *ref1, const entry_ref *ref2)
{
	if (!ref1)
		return -1;
	else if (!ref2)
		return 1;

	return strcmp(ref1->name,ref2->name);
}

int32
ExeBox::QueryThread(void *data)
{
	BVolumeRoster 	roster;
	BVolume 		vol;
	BQuery			query;
	entry_ref		ref;

	roster.GetBootVolume(&vol);

	query.SetVolume(&vol);
	query.SetPredicate("((BEOS:APP_SIG==\"application*\")&&"
						"(BEOS:TYPE==\"application/x-vnd.Be-elfexecutable\"))");
	query.Fetch();

	while (query.GetNextRef(&ref) == B_OK)
	{
		if ( ref.directory == B_USER_ADDONS_DIRECTORY
			|| ref.directory == B_BEOS_ADDONS_DIRECTORY
			|| ref.directory == B_SYSTEM_ADDONS_DIRECTORY)
			continue;

		if (ref.directory == -1)
		{
			fprintf(stderr, "FATAL : Query returned invalid ref!\n");
			return -1;
		}

		sPathDataLock.Lock();
		sPathData->AddItem(new entry_ref(ref));
		sPathDataLock.Unlock();
	}

	BMessage settings;

	sPathDataLock.Lock();
	for (int32 i = 0; i < sPathData->CountItems(); i++)
		settings.AddRef("refs", sPathData->ItemAt(i));
	sPathDataLock.Unlock();

	BFile settingsFile("/boot/home/config/settings/Run Program", B_READ_WRITE |
																B_ERASE_FILE |
																B_CREATE_FILE);
	settings.Flatten(&settingsFile);

	sPathDataLock.Lock();
	sThreadID = -1;
	sPathDataLock.Unlock();
	return 0;
}

int32
ExeBox::UpdateThread(void *data)
{
	// This takes longer, but it's not really time-critical. Most of the time there
	// will only be minor differences between run sessions.

	// In order to save as much time as possible:
	// 1) Get a new ref list via scanning the usual places. This won't take long, thanks
	//	  to the file cache. :)
	// 2) For each item in the official list
	//		- if entry doesn't exist, remove it
	//		- if entry does exist, remove it from the temporary list
	// 3) Add any remaining entries in the temporary list to the official one
	// 4) Update the disk version of the settings file

	BObjectList<entry_ref> queryList(20,true);

	BDirectory 		dir;
	BPath 			path;
	entry_ref 		ref,	*pref;
	BEntry 			entry;
	BVolumeRoster 	roster;
	BVolume 		vol;
	BQuery 			query;

	find_directory(B_BEOS_BIN_DIRECTORY,&path);
	dir.SetTo(path.Path());
	dir.Rewind();

	while (dir.GetNextRef(&ref) == B_OK)
	{
		entry.SetTo(&ref, true);
		entry.GetRef(&ref);
		entry.Unset();
		queryList.AddItem(new entry_ref(ref));
	}

	find_directory(B_SYSTEM_BIN_DIRECTORY,&path);
	dir.SetTo(path.Path());
	dir.Rewind();

	while (dir.GetNextRef(&ref) == B_OK)
	{
		entry.SetTo(&ref,true);
		entry.GetRef(&ref);
		entry.Unset();
		queryList.AddItem(new entry_ref(ref));
	}

	roster.GetBootVolume(&vol);
	query.SetVolume(&vol);
	query.SetPredicate("((BEOS:APP_SIG==\"application*\")&&"
						"(BEOS:TYPE==\"application/x-vnd.Be-elfexecutable\"))");
	query.Fetch();

	while (query.GetNextRef(&ref) == B_OK)
	{
		entry.SetTo(&ref,true);
		entry.GetPath(&path);
		entry.GetRef(&ref);
		entry.Unset();
		if (strstr(path.Path(),"add-ons") || strstr(path.Path(),"beos/servers") ||
			!ref.name)
			continue;
		queryList.AddItem(new entry_ref(ref));
	}

	// Scan is finished, so start culling
	sPathDataLock.Lock();
	int32 count = sPathData->CountItems();
	sPathDataLock.Unlock();

	for (int32 i = 0; i < count; i++)
	{
		sPathDataLock.Lock();
		pref = sPathData->ItemAt(i);
		entry.SetTo(pref);

		if (! entry.Exists() )
			sPathData->RemoveItemAt( i );
		else
		{
			for (int32 j = 0; j < queryList.CountItems(); j++)
			{
				if (*pref == *queryList.ItemAt(j))
				{
					queryList.RemoveItemAt(j);
					break;
				}
			}
		}
		entry.Unset();
		sPathDataLock.Unlock();
	}

	// Remaining items in queryList are new entries
	sPathDataLock.Lock();
	for (int32 j = 0; j < queryList.CountItems(); j++)
	{
		entry_ref *qref = queryList.RemoveItemAt(j);
		if (qref &&	qref->directory >= 0)
			sPathData->AddItem(qref);
	}
	sPathDataLock.Unlock();

	BMessage settings;

	sPathDataLock.Lock();
 	sPathData->SortItems(CompareRefs);
	sPathDataLock.Unlock();

	sPathDataLock.Lock();
	for (int32 i = 0; i < sPathData->CountItems(); i++)
	{
		entry_ref *listref = sPathData->ItemAt(i);
		settings.AddRef("refs",listref);
	}
	sPathDataLock.Unlock();

	BFile settingsFile("/boot/home/config/settings/Run Program", B_READ_WRITE |
																B_ERASE_FILE |
																B_CREATE_FILE);
	settings.Flatten(&settingsFile);

	sPathDataLock.Lock();
	sThreadID = -1;
	sPathDataLock.Unlock();

	return 0;
}
<|endoftext|>


<commit_before>#include	"FTFace.h"
#include	"FTLibrary.h"
#include	"FTGL.h"

FTFace::FTFace()
:	ftFace(0),
	numCharMaps(0),
	numGlyphs(0)
{}

FTFace::~FTFace()
{
	if( ftFace)
	{
		Close();
		delete ftFace; // is this a prob?
		ftFace = 0;
	}
}

bool	FTFace::Open( const char* filename)
{
	ftFace = new FT_Face;
	err = FT_New_Face( *FTLibrary::Instance().GetLibrary(), filename, 0, ftFace);

	if( err == FT_Err_Unknown_File_Format)
    {
//      ... the font file could be opened and read, but it appears
//      ... that its font format is unsupported
		delete ftFace;
		ftFace = 0;
	    return false;
    }
    else if( err)
    {
//      ... another error code means that the font file could not
//      ... be opened or read, or simply that it is broken...
		delete ftFace;
		ftFace = 0;
	    return false;
    }

    return true;
}

void FTFace::Close()
{
	FT_Done_Face( *ftFace);
}

FTSize& FTFace::Size( const int size, const int res )
{
	charSize.CharSize( ftFace, size, res, res);
	return charSize;
}

bool FTFace::CharMap( CHARMAP encoding )
{
//Insert your own code here.

//End of user code.
	return false;
}

FT_Glyph	FTFace::Glyph( int index )
{
//Insert your own code here.

//End of user code.
}

FT_Vector	FTFace::KernAdvance( int index1, int index2 )
{
//Insert your own code here.

//End of user code.
}
<commit_msg>Tidied up the err stuff<commit_after>#include	"FTFace.h"
#include	"FTLibrary.h"
#include	"FTGL.h"

FTFace::FTFace()
:	ftFace(0),
	numCharMaps(0),
	numGlyphs(0)
{}

FTFace::~FTFace()
{
	if( ftFace)
	{
		Close();
		delete ftFace; // is this a prob?
		ftFace = 0;
	}
}

bool FTFace::Open( const char* filename)
{
	ftFace = new FT_Face;
	err = FT_New_Face( *FTLibrary::Instance().GetLibrary(), filename, 0, ftFace);

	if( err)
    {
		delete ftFace;
		ftFace = 0;
	    return false;
    }
    else
    {
		return true;
	}
}

void FTFace::Close()
{
	FT_Done_Face( *ftFace);
}

FTSize& FTFace::Size( const int size, const int res )
{
	charSize.CharSize( ftFace, size, res, res);
	return charSize;
}

bool FTFace::CharMap( CHARMAP encoding )
{
//Insert your own code here.

//End of user code.
	return false;
}

FT_Glyph FTFace::Glyph( int index )
{
//Insert your own code here.

//End of user code.
}

FT_Vector FTFace::KernAdvance( int index1, int index2 )
{
//Insert your own code here.

//End of user code.
}
<|endoftext|>