<commit_before>/* -*-  mode: c++; c-default-style: "google"; indent-tabs-mode: nil -*- */

/* -------------------------------------------------------------------------
ATS

License: see $ATS_DIR/COPYRIGHT
Author: Ethan Coon

Process kernel for energy equation for overland flow.
------------------------------------------------------------------------- */
#include "Teuchos_XMLParameterListHelpers.hpp"

#include "Debugger.hh"
#include "eos_evaluator.hh"
#include "iem_evaluator.hh"
#include "thermal_conductivity_surface_evaluator.hh"
#include "surface_ice_energy_evaluator.hh"
#include "enthalpy_evaluator.hh"
#include "energy_bc_factory.hh"
#include "MatrixMFD_TPFA.hh"
#include "Function.hh"
#include "FunctionFactory.hh"
#include "independent_variable_field_evaluator.hh"
#include "overland_source_from_subsurface_flux_evaluator.hh"

#include "energy_surface_ice.hh"

namespace Amanzi {
namespace Energy {

#define DEBUG_FLAG 1

// -------------------------------------------------------------
// Constructor
// -------------------------------------------------------------
EnergySurfaceIce::EnergySurfaceIce(const Teuchos::RCP<Teuchos::ParameterList>& plist,
        Teuchos::ParameterList& FElist,
        const Teuchos::RCP<TreeVector>& solution) :
    PKDefaultBase(plist, FElist, solution),
    EnergyBase(plist, FElist, solution),
    standalone_mode_(false),
    is_energy_source_term_(false),
    is_mass_source_term_(false),
    is_air_conductivity_(false) {
  plist_->set("primary variable key", "surface_temperature");
  plist_->set("domain name", "surface");
}

void EnergySurfaceIce::setup(const Teuchos::Ptr<State>& S) {
  // set up the meshes
  if (!S->HasMesh("surface")) {
    Teuchos::RCP<const AmanziMesh::Mesh> domain = S->GetMesh();
    ASSERT(domain->space_dimension() == 2);
    standalone_mode_ = true;
    S->AliasMesh("domain", "surface");
  } else {
    standalone_mode_ = false;
  }

  EnergyBase::setup(S);
}

// -------------------------------------------------------------
// Create the physical evaluators for energy, enthalpy, thermal
// conductivity, and any sources.
// -------------------------------------------------------------
void EnergySurfaceIce::SetupPhysicalEvaluators_(const Teuchos::Ptr<State>& S) {
  standalone_mode_ = S->GetMesh() == S->GetMesh("surface");

  // Get data and evaluators needed by the PK
  // -- energy, the conserved quantity
  S->RequireField(energy_key_)->SetMesh(mesh_)->SetGhosted()
    ->AddComponent("cell", AmanziMesh::CELL, 1);
  Teuchos::ParameterList& ee_plist = plist_->sublist("energy evaluator");
  ee_plist.set("energy key", energy_key_);
  Teuchos::RCP<SurfaceIceEnergyEvaluator> ee =
    Teuchos::rcp(new SurfaceIceEnergyEvaluator(ee_plist));
  S->SetFieldEvaluator(energy_key_, ee);

  // -- advection of enthalpy
  S->RequireField(enthalpy_key_)->SetMesh(mesh_)
    ->SetGhosted()->AddComponent("cell", AmanziMesh::CELL, 1);
  Teuchos::ParameterList& enth_plist = plist_->sublist("enthalpy evaluator");
  enth_plist.set("enthalpy key", enthalpy_key_);
  Teuchos::RCP<EnthalpyEvaluator> enth =
    Teuchos::rcp(new EnthalpyEvaluator(enth_plist));
  S->SetFieldEvaluator(enthalpy_key_, enth);

  // -- thermal conductivity
  S->RequireField(conductivity_key_)->SetMesh(mesh_)
    ->SetGhosted()->AddComponent("cell", AmanziMesh::CELL, 1);
  Teuchos::ParameterList& tcm_plist =
    plist_->sublist("thermal conductivity evaluator");
  Teuchos::RCP<EnergyRelations::ThermalConductivitySurfaceEvaluator> tcm =
    Teuchos::rcp(new EnergyRelations::ThermalConductivitySurfaceEvaluator(tcm_plist));
  S->SetFieldEvaluator(conductivity_key_, tcm);

  // -- coupling to subsurface
  coupled_to_subsurface_via_temp_ =
      plist_->get<bool>("coupled to subsurface via temperature", false);
  coupled_to_subsurface_via_flux_ =
      plist_->get<bool>("coupled to subsurface via flux", false);
  ASSERT(! (coupled_to_subsurface_via_flux_ && coupled_to_subsurface_via_temp_));

  if (coupled_to_subsurface_via_temp_ || coupled_to_subsurface_via_flux_ ) {
    // -- ensure mass source from subsurface exists
    S->RequireField("surface_subsurface_flux")
        ->SetMesh(mesh_)->AddComponent("cell", AmanziMesh::CELL, 1);
  }

  if (coupled_to_subsurface_via_temp_) {
    S->RequireFieldEvaluator("surface_subsurface_energy_flux");
    // -- energy source term from subsurface
    S->RequireField("surface_subsurface_energy_flux")
        ->SetMesh(mesh_)->AddComponent("cell", AmanziMesh::CELL, 1);
  }

  // Many quantities are based upon face areas, which are not the cell volume,
  // as the surface mesh has been flattened.
  if (!standalone_mode_) {
    S->RequireFieldEvaluator("surface_3d_cell_volume");
  }
}

// -------------------------------------------------------------
// Initialize the needed models to plug in enthalpy.
// -------------------------------------------------------------
void EnergySurfaceIce::initialize(const Teuchos::Ptr<State>& S) {
  // -- set the cell initial condition if it is taken from the subsurface
  if (!plist_->isSublist("initial condition")) {
    std::stringstream messagestream;
    messagestream << name_ << " has no initial condition parameter list.";
    Errors::Message message(messagestream.str());
    Exceptions::amanzi_throw(message);
  }

  // Call the base class's initialize.
  EnergyBase::initialize(S);

  // Set the cell initial condition if it is taken from the subsurface
  Teuchos::ParameterList& ic_plist = plist_->sublist("initial condition");
  if (ic_plist.get<bool>("initialize surface temperature from subsurface",false)) {
    Teuchos::RCP<CompositeVector> surf_temp_cv = S->GetFieldData(key_, name_);
    Epetra_MultiVector& surf_temp = *surf_temp_cv->ViewComponent("cell",false);
    const Epetra_MultiVector& temp = *S->GetFieldData("temperature")
        ->ViewComponent("face",false);

    unsigned int ncells_surface = mesh_->num_entities(AmanziMesh::CELL,AmanziMesh::OWNED);
    for (unsigned int c=0; c!=ncells_surface; ++c) {
      // -- get the surface cell's equivalent subsurface face and neighboring cell
      AmanziMesh::Entity_ID f =
          mesh_->entity_get_parent(AmanziMesh::CELL, c);
      surf_temp[0][c] = temp[0][f];
    }

    // -- Update faces from cells if needed.
    if (ic_plist.get<bool>("initialize faces from cells", false)) {
      DeriveFaceValuesFromCellValues_(surf_temp_cv.ptr());
    }

    // mark as initialized
    if (ic_plist.get<bool>("initialize surface head from subsurface",false)) {
      S->GetField(key_,name_)->set_initialized();
    }
  }

  // For the boundary conditions, we currently hack in the enthalpy to
  // the boundary faces to correctly advect in a Dirichlet temperature
  // BC.  This requires density and internal energy, which in turn
  // require a model based on p,T.
  // This will be removed once boundary faces are implemented.
  Teuchos::RCP<FieldEvaluator> eos_fe =
      S->GetFieldEvaluator("surface_molar_density_liquid");
  Teuchos::RCP<Relations::EOSEvaluator> eos_eval =
    Teuchos::rcp_dynamic_cast<Relations::EOSEvaluator>(eos_fe);
  ASSERT(eos_eval != Teuchos::null);
  eos_liquid_ = eos_eval->get_EOS();

  Teuchos::RCP<FieldEvaluator> iem_fe =
      S->GetFieldEvaluator("surface_internal_energy_liquid");
  Teuchos::RCP<EnergyRelations::IEMEvaluator> iem_eval =
    Teuchos::rcp_dynamic_cast<EnergyRelations::IEMEvaluator>(iem_fe);
  ASSERT(iem_eval != Teuchos::null);
  iem_liquid_ = iem_eval->get_IEM();
}

// -------------------------------------------------------------
// Plug enthalpy into the boundary faces manually.
// This will be removed once boundary faces exist.
// -------------------------------------------------------------
void EnergySurfaceIce::ApplyDirichletBCsToEnthalpy_(const Teuchos::Ptr<State>& S,
        const Teuchos::Ptr<CompositeVector>& enth) {

  // Since we don't have a surface pressure on faces, this gets a bit uglier.
  // Simply grab the internal cell for now.
  const Epetra_MultiVector& flux = *S->GetFieldData(flux_key_)
      ->ViewComponent("face",false);
  Epetra_MultiVector& enth_f = *enth->ViewComponent("face",false);
  const Epetra_MultiVector& pres_c = *S->GetFieldData("surface_pressure")
      ->ViewComponent("cell",false);
  const Epetra_MultiVector& temp_f = *S->GetFieldData("surface_temperature")
      ->ViewComponent("face",false);

  //  Teuchos::writeParameterListToXmlOStream(*plist_, std::cout);
  Teuchos::ParameterList& enth_plist = plist_->sublist("enthalpy evaluator", true);
  bool include_work = enth_plist.get<bool>("include work term", true);

  AmanziMesh::Entity_ID_List cells;
  unsigned int nfaces = enth_f.MyLength();
  for (unsigned int f=0; f!=nfaces; ++f) {
    mesh_->face_get_cells(f, AmanziMesh::USED, &cells);
    if (cells.size() == 1) {
      double T = bc_markers_[f] == Operators::MATRIX_BC_DIRICHLET ?
          bc_values_[f] : temp_f[0][f];
      double p = pres_c[0][cells[0]];
      double dens = eos_liquid_->MolarDensity(T,p);
      double int_energy = iem_liquid_->InternalEnergy(T);
      double enthalpy = include_work ? int_energy + p/dens : int_energy;

      enth_f[0][f] = enthalpy * fabs(flux[0][f]);
    }
  }

}

// -------------------------------------------------------------
// Deal with the many source terms.
// -------------------------------------------------------------
void EnergySurfaceIce::AddSources_(const Teuchos::Ptr<State>& S,
        const Teuchos::Ptr<CompositeVector>& g) {
  // General source term (covers advection from mass precip and air-surface
  // conduction).
  EnergyBase::AddSources_(S,g);

  Teuchos::OSTab tab = vo_->getOSTab();
  Epetra_MultiVector& g_c = *g->ViewComponent("cell",false);

  // coupling to subsurface
  // -- two parts -- conduction and advection
  // -- advection source
  if (coupled_to_subsurface_via_temp_ || coupled_to_subsurface_via_flux_) {
    S->GetFieldEvaluator("enthalpy")->HasFieldChanged(S.ptr(), name_);
    S->GetFieldEvaluator(enthalpy_key_)->HasFieldChanged(S.ptr(), name_);

    // -- advection source
    const Epetra_MultiVector& source1 =
        *S->GetFieldData("surface_subsurface_flux")->ViewComponent("cell",false);
    const Epetra_MultiVector& enth_surf =
        *S->GetFieldData(enthalpy_key_)->ViewComponent("cell",false);
    const Epetra_MultiVector& enth_subsurf =
        *S->GetFieldData("enthalpy")->ViewComponent("cell",false);

    AmanziMesh::Entity_ID_List cells;

    unsigned int ncells = g_c.MyLength();
    for (unsigned int c=0; c!=ncells; ++c) {
      double flux = source1[0][c];

      // upwind the enthalpy
      if (flux > 0.) { // exfiltration
        // get the subsurface's enthalpy
        AmanziMesh::Entity_ID f = mesh_->entity_get_parent(AmanziMesh::CELL, c);
        S->GetMesh()->face_get_cells(f, AmanziMesh::USED, &cells);
        ASSERT(cells.size() == 1);

        g_c[0][c] -= flux * enth_subsurf[0][cells[0]];
      } else { // infiltration
        g_c[0][c] -= flux * enth_surf[0][c];
      }
    }
    if (vo_->os_OK(Teuchos::VERB_EXTREME)) {
      *vo_->os() << "Adding advection to subsurface" << std::endl;
      db_->WriteVector("res (src)", g, false);
    }
  }

  // -- conduction source
  if (coupled_to_subsurface_via_temp_) {
    const Epetra_MultiVector& e_source1 =
        *S->GetFieldData("surface_subsurface_energy_flux")
        ->ViewComponent("cell",false);

    AmanziMesh::Entity_ID_List cells;

    unsigned int ncells = g_c.MyLength();
    for (unsigned int c=0; c!=ncells; ++c) {
      g_c[0][c] -= e_source1[0][cells[0]];
    }
  }

}

void EnergySurfaceIce::AddSourcesToPrecon_(const Teuchos::Ptr<State>& S, double h) {
  // Deals with nonlinear source terms that are implemented correctly as an evaluator
  EnergyBase::AddSourcesToPrecon_(S,h);

  // Additionally deal with nonlinear source terms that are NOT
  // implemented correctly, as they are part of a PK (surface energy
  // balance!)
  if (is_source_term_ &&
      S->HasFieldEvaluator("surface_conducted_energy_source") &&
      !S->GetFieldEvaluator("surface_conducted_energy_source")->IsDependency(S, key_) &&
      S->HasField("dsurface_conducted_energy_source_dsurface_temperature")) {
    // This checks if 1, there is a source, and, 2, there is a
    // conducted component to that source, and 4, someone, somewhere
    // (i.e. SEB PK) has defined a dsource_dT, but 3, the source
    // evaluator does not think it depends upon T (because it is
    // hacked in by the PK).
    std::vector<double>& Acc_cells = mfd_preconditioner_->Acc_cells();

    const Epetra_MultiVector& dsource_dT =
        *S->GetFieldData("dsurface_conducted_energy_source_dsurface_temperature")->ViewComponent("cell",false);
    const Epetra_MultiVector& cell_vol = *S->GetFieldData(cell_vol_key_)->ViewComponent("cell",false);
    unsigned int ncells = dsource_dT.MyLength();
    for (unsigned int c=0; c!=ncells; ++c) {
      Acc_cells[c] -= dsource_dT[0][c] * cell_vol[0][c];
    }
  }
}

} // namespace
} // namespace
<commit_msg>update to debugging in PC for implicit SEB<commit_after>/* -*-  mode: c++; c-default-style: "google"; indent-tabs-mode: nil -*- */

/* -------------------------------------------------------------------------
ATS

License: see $ATS_DIR/COPYRIGHT
Author: Ethan Coon

Process kernel for energy equation for overland flow.
------------------------------------------------------------------------- */
#include "Teuchos_XMLParameterListHelpers.hpp"

#include "Debugger.hh"
#include "eos_evaluator.hh"
#include "iem_evaluator.hh"
#include "thermal_conductivity_surface_evaluator.hh"
#include "surface_ice_energy_evaluator.hh"
#include "enthalpy_evaluator.hh"
#include "energy_bc_factory.hh"
#include "MatrixMFD_TPFA.hh"
#include "Function.hh"
#include "FunctionFactory.hh"
#include "independent_variable_field_evaluator.hh"
#include "overland_source_from_subsurface_flux_evaluator.hh"

#include "energy_surface_ice.hh"

namespace Amanzi {
namespace Energy {

#define DEBUG_FLAG 1

// -------------------------------------------------------------
// Constructor
// -------------------------------------------------------------
EnergySurfaceIce::EnergySurfaceIce(const Teuchos::RCP<Teuchos::ParameterList>& plist,
        Teuchos::ParameterList& FElist,
        const Teuchos::RCP<TreeVector>& solution) :
    PKDefaultBase(plist, FElist, solution),
    EnergyBase(plist, FElist, solution),
    standalone_mode_(false),
    is_energy_source_term_(false),
    is_mass_source_term_(false),
    is_air_conductivity_(false) {
  plist_->set("primary variable key", "surface_temperature");
  plist_->set("domain name", "surface");
}

void EnergySurfaceIce::setup(const Teuchos::Ptr<State>& S) {
  // set up the meshes
  if (!S->HasMesh("surface")) {
    Teuchos::RCP<const AmanziMesh::Mesh> domain = S->GetMesh();
    ASSERT(domain->space_dimension() == 2);
    standalone_mode_ = true;
    S->AliasMesh("domain", "surface");
  } else {
    standalone_mode_ = false;
  }

  EnergyBase::setup(S);
}

// -------------------------------------------------------------
// Create the physical evaluators for energy, enthalpy, thermal
// conductivity, and any sources.
// -------------------------------------------------------------
void EnergySurfaceIce::SetupPhysicalEvaluators_(const Teuchos::Ptr<State>& S) {
  standalone_mode_ = S->GetMesh() == S->GetMesh("surface");

  // Get data and evaluators needed by the PK
  // -- energy, the conserved quantity
  S->RequireField(energy_key_)->SetMesh(mesh_)->SetGhosted()
    ->AddComponent("cell", AmanziMesh::CELL, 1);
  Teuchos::ParameterList& ee_plist = plist_->sublist("energy evaluator");
  ee_plist.set("energy key", energy_key_);
  Teuchos::RCP<SurfaceIceEnergyEvaluator> ee =
    Teuchos::rcp(new SurfaceIceEnergyEvaluator(ee_plist));
  S->SetFieldEvaluator(energy_key_, ee);

  // -- advection of enthalpy
  S->RequireField(enthalpy_key_)->SetMesh(mesh_)
    ->SetGhosted()->AddComponent("cell", AmanziMesh::CELL, 1);
  Teuchos::ParameterList& enth_plist = plist_->sublist("enthalpy evaluator");
  enth_plist.set("enthalpy key", enthalpy_key_);
  Teuchos::RCP<EnthalpyEvaluator> enth =
    Teuchos::rcp(new EnthalpyEvaluator(enth_plist));
  S->SetFieldEvaluator(enthalpy_key_, enth);

  // -- thermal conductivity
  S->RequireField(conductivity_key_)->SetMesh(mesh_)
    ->SetGhosted()->AddComponent("cell", AmanziMesh::CELL, 1);
  Teuchos::ParameterList& tcm_plist =
    plist_->sublist("thermal conductivity evaluator");
  Teuchos::RCP<EnergyRelations::ThermalConductivitySurfaceEvaluator> tcm =
    Teuchos::rcp(new EnergyRelations::ThermalConductivitySurfaceEvaluator(tcm_plist));
  S->SetFieldEvaluator(conductivity_key_, tcm);

  // -- coupling to subsurface
  coupled_to_subsurface_via_temp_ =
      plist_->get<bool>("coupled to subsurface via temperature", false);
  coupled_to_subsurface_via_flux_ =
      plist_->get<bool>("coupled to subsurface via flux", false);
  ASSERT(! (coupled_to_subsurface_via_flux_ && coupled_to_subsurface_via_temp_));

  if (coupled_to_subsurface_via_temp_ || coupled_to_subsurface_via_flux_ ) {
    // -- ensure mass source from subsurface exists
    S->RequireField("surface_subsurface_flux")
        ->SetMesh(mesh_)->AddComponent("cell", AmanziMesh::CELL, 1);
  }

  if (coupled_to_subsurface_via_temp_) {
    S->RequireFieldEvaluator("surface_subsurface_energy_flux");
    // -- energy source term from subsurface
    S->RequireField("surface_subsurface_energy_flux")
        ->SetMesh(mesh_)->AddComponent("cell", AmanziMesh::CELL, 1);
  }

  // Many quantities are based upon face areas, which are not the cell volume,
  // as the surface mesh has been flattened.
  if (!standalone_mode_) {
    S->RequireFieldEvaluator("surface_3d_cell_volume");
  }
}

// -------------------------------------------------------------
// Initialize the needed models to plug in enthalpy.
// -------------------------------------------------------------
void EnergySurfaceIce::initialize(const Teuchos::Ptr<State>& S) {
  // -- set the cell initial condition if it is taken from the subsurface
  if (!plist_->isSublist("initial condition")) {
    std::stringstream messagestream;
    messagestream << name_ << " has no initial condition parameter list.";
    Errors::Message message(messagestream.str());
    Exceptions::amanzi_throw(message);
  }

  // Call the base class's initialize.
  EnergyBase::initialize(S);

  // Set the cell initial condition if it is taken from the subsurface
  Teuchos::ParameterList& ic_plist = plist_->sublist("initial condition");
  if (ic_plist.get<bool>("initialize surface temperature from subsurface",false)) {
    Teuchos::RCP<CompositeVector> surf_temp_cv = S->GetFieldData(key_, name_);
    Epetra_MultiVector& surf_temp = *surf_temp_cv->ViewComponent("cell",false);
    const Epetra_MultiVector& temp = *S->GetFieldData("temperature")
        ->ViewComponent("face",false);

    unsigned int ncells_surface = mesh_->num_entities(AmanziMesh::CELL,AmanziMesh::OWNED);
    for (unsigned int c=0; c!=ncells_surface; ++c) {
      // -- get the surface cell's equivalent subsurface face and neighboring cell
      AmanziMesh::Entity_ID f =
          mesh_->entity_get_parent(AmanziMesh::CELL, c);
      surf_temp[0][c] = temp[0][f];
    }

    // -- Update faces from cells if needed.
    if (ic_plist.get<bool>("initialize faces from cells", false)) {
      DeriveFaceValuesFromCellValues_(surf_temp_cv.ptr());
    }

    // mark as initialized
    if (ic_plist.get<bool>("initialize surface head from subsurface",false)) {
      S->GetField(key_,name_)->set_initialized();
    }
  }

  // For the boundary conditions, we currently hack in the enthalpy to
  // the boundary faces to correctly advect in a Dirichlet temperature
  // BC.  This requires density and internal energy, which in turn
  // require a model based on p,T.
  // This will be removed once boundary faces are implemented.
  Teuchos::RCP<FieldEvaluator> eos_fe =
      S->GetFieldEvaluator("surface_molar_density_liquid");
  Teuchos::RCP<Relations::EOSEvaluator> eos_eval =
    Teuchos::rcp_dynamic_cast<Relations::EOSEvaluator>(eos_fe);
  ASSERT(eos_eval != Teuchos::null);
  eos_liquid_ = eos_eval->get_EOS();

  Teuchos::RCP<FieldEvaluator> iem_fe =
      S->GetFieldEvaluator("surface_internal_energy_liquid");
  Teuchos::RCP<EnergyRelations::IEMEvaluator> iem_eval =
    Teuchos::rcp_dynamic_cast<EnergyRelations::IEMEvaluator>(iem_fe);
  ASSERT(iem_eval != Teuchos::null);
  iem_liquid_ = iem_eval->get_IEM();
}

// -------------------------------------------------------------
// Plug enthalpy into the boundary faces manually.
// This will be removed once boundary faces exist.
// -------------------------------------------------------------
void EnergySurfaceIce::ApplyDirichletBCsToEnthalpy_(const Teuchos::Ptr<State>& S,
        const Teuchos::Ptr<CompositeVector>& enth) {

  // Since we don't have a surface pressure on faces, this gets a bit uglier.
  // Simply grab the internal cell for now.
  const Epetra_MultiVector& flux = *S->GetFieldData(flux_key_)
      ->ViewComponent("face",false);
  Epetra_MultiVector& enth_f = *enth->ViewComponent("face",false);
  const Epetra_MultiVector& pres_c = *S->GetFieldData("surface_pressure")
      ->ViewComponent("cell",false);
  const Epetra_MultiVector& temp_f = *S->GetFieldData("surface_temperature")
      ->ViewComponent("face",false);

  //  Teuchos::writeParameterListToXmlOStream(*plist_, std::cout);
  Teuchos::ParameterList& enth_plist = plist_->sublist("enthalpy evaluator", true);
  bool include_work = enth_plist.get<bool>("include work term", true);

  AmanziMesh::Entity_ID_List cells;
  unsigned int nfaces = enth_f.MyLength();
  for (unsigned int f=0; f!=nfaces; ++f) {
    mesh_->face_get_cells(f, AmanziMesh::USED, &cells);
    if (cells.size() == 1) {
      double T = bc_markers_[f] == Operators::MATRIX_BC_DIRICHLET ?
          bc_values_[f] : temp_f[0][f];
      double p = pres_c[0][cells[0]];
      double dens = eos_liquid_->MolarDensity(T,p);
      double int_energy = iem_liquid_->InternalEnergy(T);
      double enthalpy = include_work ? int_energy + p/dens : int_energy;

      enth_f[0][f] = enthalpy * fabs(flux[0][f]);
    }
  }

}

// -------------------------------------------------------------
// Deal with the many source terms.
// -------------------------------------------------------------
void EnergySurfaceIce::AddSources_(const Teuchos::Ptr<State>& S,
        const Teuchos::Ptr<CompositeVector>& g) {
  // General source term (covers advection from mass precip and air-surface
  // conduction).
  EnergyBase::AddSources_(S,g);

  Teuchos::OSTab tab = vo_->getOSTab();
  Epetra_MultiVector& g_c = *g->ViewComponent("cell",false);

  // coupling to subsurface
  // -- two parts -- conduction and advection
  // -- advection source
  if (coupled_to_subsurface_via_temp_ || coupled_to_subsurface_via_flux_) {
    S->GetFieldEvaluator("enthalpy")->HasFieldChanged(S.ptr(), name_);
    S->GetFieldEvaluator(enthalpy_key_)->HasFieldChanged(S.ptr(), name_);

    // -- advection source
    const Epetra_MultiVector& source1 =
        *S->GetFieldData("surface_subsurface_flux")->ViewComponent("cell",false);
    const Epetra_MultiVector& enth_surf =
        *S->GetFieldData(enthalpy_key_)->ViewComponent("cell",false);
    const Epetra_MultiVector& enth_subsurf =
        *S->GetFieldData("enthalpy")->ViewComponent("cell",false);

    AmanziMesh::Entity_ID_List cells;

    unsigned int ncells = g_c.MyLength();
    for (unsigned int c=0; c!=ncells; ++c) {
      double flux = source1[0][c];

      // upwind the enthalpy
      if (flux > 0.) { // exfiltration
        // get the subsurface's enthalpy
        AmanziMesh::Entity_ID f = mesh_->entity_get_parent(AmanziMesh::CELL, c);
        S->GetMesh()->face_get_cells(f, AmanziMesh::USED, &cells);
        ASSERT(cells.size() == 1);

        g_c[0][c] -= flux * enth_subsurf[0][cells[0]];
      } else { // infiltration
        g_c[0][c] -= flux * enth_surf[0][c];
      }
    }
    if (vo_->os_OK(Teuchos::VERB_EXTREME)) {
      *vo_->os() << "Adding advection to subsurface" << std::endl;
      db_->WriteVector("res (src)", g, false);
    }
  }

  // -- conduction source
  if (coupled_to_subsurface_via_temp_) {
    const Epetra_MultiVector& e_source1 =
        *S->GetFieldData("surface_subsurface_energy_flux")
        ->ViewComponent("cell",false);

    AmanziMesh::Entity_ID_List cells;

    unsigned int ncells = g_c.MyLength();
    for (unsigned int c=0; c!=ncells; ++c) {
      g_c[0][c] -= e_source1[0][cells[0]];
    }
  }

}

void EnergySurfaceIce::AddSourcesToPrecon_(const Teuchos::Ptr<State>& S, double h) {
  // Deals with nonlinear source terms that are implemented correctly as an evaluator
  EnergyBase::AddSourcesToPrecon_(S,h);

  // Additionally deal with nonlinear source terms that are NOT
  // implemented correctly, as they are part of a PK (surface energy
  // balance!)
  if (is_source_term_ &&
      S->HasFieldEvaluator("surface_conducted_energy_source") &&
      !S->GetFieldEvaluator("surface_conducted_energy_source")->IsDependency(S, key_) &&
      S->HasField("dsurface_conducted_energy_source_dsurface_temperature")) {
    // This checks if 1, there is a source, and, 2, there is a
    // conducted component to that source, and 4, someone, somewhere
    // (i.e. SEB PK) has defined a dsource_dT, but 3, the source
    // evaluator does not think it depends upon T (because it is
    // hacked in by the PK).
    std::vector<double>& Acc_cells = mfd_preconditioner_->Acc_cells();

    const Epetra_MultiVector& dsource_dT =
        *S->GetFieldData("dsurface_conducted_energy_source_dsurface_temperature")->ViewComponent("cell",false);
    const Epetra_MultiVector& cell_vol = *S->GetFieldData(cell_vol_key_)->ViewComponent("cell",false);
    unsigned int ncells = dsource_dT.MyLength();
    for (unsigned int c=0; c!=ncells; ++c) {
      Acc_cells[c] -= dsource_dT[0][c] * cell_vol[0][c];
    }

    if (vo_->os_OK(Teuchos::VERB_EXTREME)) {
      *vo_->os() << "Adding hacked source to PC:" << std::endl;
      db_->WriteVector("de_src_dT", S->GetFieldData("dsurface_conducted_energy_source_dsurface_temperature").ptr(), false);
    }

  }
}

} // namespace
} // namespace
<|endoftext|>


<commit_before>/**
 * The Seeks proxy and plugin framework are part of the SEEKS project.
 * Copyright (C) 2010 Emmanuel Benazera, juban@free.fr
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "img_search_snippet.h"
#include "websearch.h"
#include "query_context.h"
#include "img_query_context.h"
#include "miscutil.h"
#include "mem_utils.h"
#include "encode.h"
#include "urlmatch.h"
#include <assert.h>

#if defined(PROTOBUF) && defined(TC)
#include "query_capture_configuration.h"
#endif

using sp::miscutil;
using sp::encode;
using sp::urlmatch;

namespace seeks_plugins
{

   img_search_snippet::img_search_snippet()
     :search_snippet()
#ifdef FEATURE_OPENCV2
   ,_surf_keypoints(NULL),_surf_descriptors(NULL),_surf_storage(NULL)
#endif
	 , _cached_image(NULL)
       {
	  _doc_type = IMAGE;
       }

   img_search_snippet::img_search_snippet(const short &rank)
     :search_snippet(rank)
#ifdef FEATURE_OPENCV2
   ,_surf_keypoints(NULL),_surf_descriptors(NULL)
#endif
	 , _cached_image(NULL)
       {
	  _doc_type = IMAGE;
#ifdef FEATURE_OPENCV2
	  _surf_storage = cvCreateMemStorage(0);
#endif
       }

   img_search_snippet::~img_search_snippet()
     {
	if (_cached_image)
	  delete _cached_image;

#ifdef FEATURE_OPENCV2
	if (_surf_keypoints)
	  cvClearSeq(_surf_keypoints);
	if (_surf_descriptors)
	  cvClearSeq(_surf_descriptors);
	if (_surf_storage)
	  cvReleaseMemStorage(&_surf_storage);
#endif
     }

   std::string img_search_snippet::to_html_with_highlight(std::vector<std::string> &words,
							  const std::string &base_url_str,
							  const hash_map<const char*,const char*,hash<const char*>,eqstr> *parameters)
     {
	// check for URL redirection for capture & personalization of results.
	bool prs = true;
	const char *pers = miscutil::lookup(parameters,"prs");
	if (!pers)
	  prs = websearch::_wconfig->_personalization;
	else
	  {
	     if (strcasecmp(pers,"on") == 0)
	       prs = true;
	     else if (strcasecmp(pers,"off") == 0)
	       prs = false;
	     else prs = websearch::_wconfig->_personalization;
	  }

	std::string url = _url;

#if defined(PROTOBUF) && defined(TC)
	if (prs && websearch::_qc_plugin && websearch::_qc_plugin_activated
	    && query_capture_configuration::_config
	    && query_capture_configuration::_config->_mode_intercept == "redirect")
	  {
	     char *url_enc = encode::url_encode(url.c_str());
	     url = base_url_str + "/qc_redir?q=" + _qc->_url_enc_query + "&url=" + std::string(url_enc);
	     free(url_enc);
	  }
#endif

	std::string se_icon = "_url_enc_query + "&page=1&expansion=1&action=expand&engines=seeng\"> ";
	std::string html_content = "
";

	html_content += "

";

	const char *title_enc = encode::html_encode(_title.c_str());
	html_content += title_enc;
	free_const(title_enc);

	if (_img_engine.to_ulong()&SE_GOOGLE_IMG)
	  {
	     std::string ggle_se_icon = se_icon;
	     miscutil::replace_in_string(ggle_se_icon,"icon","search_engine_google");
	     miscutil::replace_in_string(ggle_se_icon,"setitle","Google");
	     miscutil::replace_in_string(ggle_se_icon,"seeng","google");
	     html_content += ggle_se_icon;
	  }
	if (_img_engine.to_ulong()&SE_BING_IMG)
	  {
	     std::string bing_se_icon = se_icon;
	     miscutil::replace_in_string(bing_se_icon,"icon","search_engine_bing");
	     miscutil::replace_in_string(bing_se_icon,"setitle","Bing");
	     miscutil::replace_in_string(bing_se_icon,"seeng","bing");
	     html_content += bing_se_icon;
	  }
	if (_img_engine.to_ulong()&SE_FLICKR)
	  {
	     std::string flickr_se_icon = se_icon;
	     miscutil::replace_in_string(flickr_se_icon,"icon","search_engine_flickr");
	     miscutil::replace_in_string(flickr_se_icon,"setitle","Flickr");
	     miscutil::replace_in_string(flickr_se_icon,"seeng","flickr");
	     html_content += flickr_se_icon;
	  }
	if (_img_engine.to_ulong()&SE_WCOMMONS)
	  {
	     std::string wcommons_se_icon = se_icon;
	     miscutil::replace_in_string(wcommons_se_icon,"icon","search_engine_wcommons");
             miscutil::replace_in_string(wcommons_se_icon,"setitle","Wikimedia Commons");
             miscutil::replace_in_string(wcommons_se_icon,"seeng","wcommons");
             html_content += wcommons_se_icon;
	  }
	if (_img_engine.to_ulong()&SE_YAHOO_IMG)
	  {
	     std::string yahoo_se_icon = se_icon;
	     miscutil::replace_in_string(yahoo_se_icon,"icon","search_engine_yahoo");
	     miscutil::replace_in_string(yahoo_se_icon,"setitle","yahoo");
	     miscutil::replace_in_string(yahoo_se_icon,"seeng","yahoo");
	     html_content += yahoo_se_icon;
	  }

	// XXX: personalization icon kind of look ugly with image snippets...
	/* if (_personalized)
	  {
	     html_content += "
";
	  }
	else */
	html_content += "

";
	const char *cite_enc = NULL;
	if (!_cite.empty())
	  {
	     std::string cite_host;
	     std::string cite_path;
	     urlmatch::parse_url_host_and_path(_cite,cite_host,cite_path);
	     cite_enc = encode::html_encode(cite_host.c_str());
	  }
	else
	  {
	     std::string cite_host;
	     std::string cite_path;
	     urlmatch::parse_url_host_and_path(_url,cite_host,cite_path);
	     cite_enc = encode::html_encode(cite_host.c_str());
	  }
	std::string cite_enc_str = std::string(cite_enc);
	if (cite_enc_str.size()>4 && cite_enc_str.substr(0,4)=="www.") //TODO: tolower.
	  cite_enc_str = cite_enc_str.substr(4);
	free_const(cite_enc);
	html_content += "";
	html_content += cite_enc_str;
	html_content += "
";

	if (!_cached.empty())
	  {
	     char *enc_cached = encode::html_encode(_cached.c_str());
	     miscutil::chomp(enc_cached);
	     html_content += "Cached";
	     free_const(enc_cached);
	  }

#ifdef FEATURE_OPENCV2
	if (!_sim_back)
	  {
	     set_similarity_link(parameters);
	     html_content += "<a class=\"search_cache\" href=\"";
	  }
	else
	  {
	     set_back_similarity_link(parameters);
	     html_content += "Similar";
	else html_content += "\">Back";
#endif
	html_content += "

\n";
	return html_content;
     }

   std::string img_search_snippet::to_json(const bool &thumbs,
					   const std::vector<std::string> &query_words)
     {
	std::string json_str;
	json_str += "{";
	json_str += "\"id\":" + miscutil::to_string(_id) + ",";
	json_str += "\"title\":\"" + _title + "\",";
	json_str += "\"url\":\"" + _url + "\",";
	json_str += "\"summary\":\"" + _summary + "\",";
	json_str += "\"seeks_meta\":" + miscutil::to_string(_meta_rank) + ",";
	json_str += "\"seeks_score\":" + miscutil::to_string(_seeks_rank) + ",";
	double rank = _rank / static_cast<double>(_img_engine.count());
	json_str += "\"rank\":" + miscutil::to_string(rank) + ",";
	json_str += "\"cite\":\"";
	if (!_cite.empty())
	  {
	     std::string cite_host;
	     std::string cite_path;
	     urlmatch::parse_url_host_and_path(_cite,cite_host,cite_path);
	     json_str += cite_host + "\",";
	  }
	else
	  {
	     std::string cite_host;
	     std::string cite_path;
	     urlmatch::parse_url_host_and_path(_url,cite_host,cite_path);
	     json_str += cite_host + "\",";
	  }
	if (!_cached.empty())
	  json_str += "\"cached\":\"" + _cached + "\","; // XXX: cached might be malformed without preprocessing.
	json_str += "\"engines\":[";
	std::string json_str_eng = "";
	if (_img_engine.to_ulong()&SE_GOOGLE_IMG)
	  json_str_eng += "\"google\"";
	if (_img_engine.to_ulong()&SE_BING_IMG)
	  {
	     if (!json_str_eng.empty())
	       json_str_eng += ",";
	     json_str_eng += "\"bing\"";
	  }
	if (_img_engine.to_ulong()&SE_FLICKR)
	  {
	     if (!json_str_eng.empty())
	       json_str_eng += ",";
	     json_str_eng += "\"flickr\"";
	  }
	if (_img_engine.to_ulong()&SE_WCOMMONS)
	  {
	     if (!json_str_eng.empty())
	       json_str_eng += ",";
	     json_str_eng += "\"wcommons\"";
	  }
	if (_img_engine.to_ulong()&SE_YAHOO_IMG)
	  {
	     if (!json_str_eng.empty())
	       json_str_eng += ",";
	     json_str_eng += "\"yahoo\"";
	  }
	json_str += json_str_eng + "]";
	json_str += ",\"type\":\"" + get_doc_type_str() + "\"";
	json_str += ",\"personalized\":\"";
	if (_personalized)
	  json_str += "yes";
	else json_str += "no";
	json_str += "\"";
	if (!_date.empty())
	  json_str += ",\"date\":\"" + _date + "\"";
	json_str += "}";
	return json_str;
     }

   bool img_search_snippet::is_se_enabled(const hash_map<const char*,const char*,hash<const char*>,eqstr> *parameters)
     {
	std::bitset<IMG_NSEs> se_enabled;
	img_query_context::fillup_img_engines(parameters,se_enabled);
	std::bitset<IMG_NSEs> band = _img_engine & se_enabled;
	return (band.count() != 0);
     }

   void img_search_snippet::set_similarity_link(const hash_map<const char*,const char*,hash<const char*>,eqstr> *parameters)
     {
	const char *engines = miscutil::lookup(parameters,"engines");
	std::string sfsearch = "on";
	if (!static_cast<img_query_context*>(_qc)->_safesearch)
	  sfsearch = "off";
	_sim_link = "/search_img?q=" + _qc->_url_enc_query
	  + "&page=1&expansion=" + miscutil::to_string(_qc->_page_expansion)
	    + "&action=similarity&safesearch=" + sfsearch
	  + "&id=" + miscutil::to_string(_id) + "&engines=";
	if (engines)
	  _sim_link += std::string(engines);
	_sim_back = false;
     }

   void img_search_snippet::set_back_similarity_link(const hash_map<const char*,const char*,hash<const char*>,eqstr> *parameters)
     {
	const char *engines = miscutil::lookup(parameters,"engines");
	std::string sfsearch = "on";
	if (!static_cast<img_query_context*>(_qc)->_safesearch)
	  sfsearch = "off";
	_sim_link = "/search_img?q=" + _qc->_url_enc_query
	  + "&page=1&expansion=" + miscutil::to_string(_qc->_page_expansion)
	    + "&action=expand&safesearch=" + sfsearch + "&engines=";
	if (engines)
	  _sim_link += std::string(engines);
	_sim_back = true;
     }

   void img_search_snippet::merge_img_snippets(img_search_snippet *s1,
					       const img_search_snippet *s2)
     {
	search_snippet::merge_snippets(s1,s2);

	std::bitset<IMG_NSEs> setest = s1->_img_engine;
	setest &= s2->_img_engine;
	if (setest.count()>0)
	  return;
	s1->_img_engine |= s2->_img_engine;

	if (!s1->_cached_image && s2->_cached_image)
	  s1->_cached_image = new std::string(*s2->_cached_image);

        /// seeks rank.
        s1->_seeks_rank = s1->_img_engine.count();

        // XXX: hack, on English queries, Bing & Yahoo are the same engine,
        // therefore the rank must be tweaked accordingly in this special case.
        if (s1->_qc->_auto_lang == "en"
            && (s1->_img_engine.to_ulong()&SE_YAHOO_IMG)
            && (s1->_img_engine.to_ulong()&SE_BING_IMG))
          s1->_seeks_rank--;
     }

} /* end of namespace. */
<commit_msg>fixed wrong json output in image websearch<commit_after>/**
 * The Seeks proxy and plugin framework are part of the SEEKS project.
 * Copyright (C) 2010 Emmanuel Benazera, juban@free.fr
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "img_search_snippet.h"
#include "websearch.h"
#include "query_context.h"
#include "img_query_context.h"
#include "miscutil.h"
#include "mem_utils.h"
#include "encode.h"
#include "urlmatch.h"
#include <assert.h>

#if defined(PROTOBUF) && defined(TC)
#include "query_capture_configuration.h"
#endif

using sp::miscutil;
using sp::encode;
using sp::urlmatch;

namespace seeks_plugins
{

   img_search_snippet::img_search_snippet()
     :search_snippet()
#ifdef FEATURE_OPENCV2
   ,_surf_keypoints(NULL),_surf_descriptors(NULL),_surf_storage(NULL)
#endif
	 , _cached_image(NULL)
       {
	  _doc_type = IMAGE;
       }

   img_search_snippet::img_search_snippet(const short &rank)
     :search_snippet(rank)
#ifdef FEATURE_OPENCV2
   ,_surf_keypoints(NULL),_surf_descriptors(NULL)
#endif
	 , _cached_image(NULL)
       {
	  _doc_type = IMAGE;
#ifdef FEATURE_OPENCV2
	  _surf_storage = cvCreateMemStorage(0);
#endif
       }

   img_search_snippet::~img_search_snippet()
     {
	if (_cached_image)
	  delete _cached_image;

#ifdef FEATURE_OPENCV2
	if (_surf_keypoints)
	  cvClearSeq(_surf_keypoints);
	if (_surf_descriptors)
	  cvClearSeq(_surf_descriptors);
	if (_surf_storage)
	  cvReleaseMemStorage(&_surf_storage);
#endif
     }

   std::string img_search_snippet::to_html_with_highlight(std::vector<std::string> &words,
							  const std::string &base_url_str,
							  const hash_map<const char*,const char*,hash<const char*>,eqstr> *parameters)
     {
	// check for URL redirection for capture & personalization of results.
	bool prs = true;
	const char *pers = miscutil::lookup(parameters,"prs");
	if (!pers)
	  prs = websearch::_wconfig->_personalization;
	else
	  {
	     if (strcasecmp(pers,"on") == 0)
	       prs = true;
	     else if (strcasecmp(pers,"off") == 0)
	       prs = false;
	     else prs = websearch::_wconfig->_personalization;
	  }

	std::string url = _url;

#if defined(PROTOBUF) && defined(TC)
	if (prs && websearch::_qc_plugin && websearch::_qc_plugin_activated
	    && query_capture_configuration::_config
	    && query_capture_configuration::_config->_mode_intercept == "redirect")
	  {
	     char *url_enc = encode::url_encode(url.c_str());
	     url = base_url_str + "/qc_redir?q=" + _qc->_url_enc_query + "&url=" + std::string(url_enc);
	     free(url_enc);
	  }
#endif

	std::string se_icon = "_url_enc_query + "&page=1&expansion=1&action=expand&engines=seeng\"> ";
	std::string html_content = "
";

	html_content += "

";

	const char *title_enc = encode::html_encode(_title.c_str());
	html_content += title_enc;
	free_const(title_enc);

	if (_img_engine.to_ulong()&SE_GOOGLE_IMG)
	  {
	     std::string ggle_se_icon = se_icon;
	     miscutil::replace_in_string(ggle_se_icon,"icon","search_engine_google");
	     miscutil::replace_in_string(ggle_se_icon,"setitle","Google");
	     miscutil::replace_in_string(ggle_se_icon,"seeng","google");
	     html_content += ggle_se_icon;
	  }
	if (_img_engine.to_ulong()&SE_BING_IMG)
	  {
	     std::string bing_se_icon = se_icon;
	     miscutil::replace_in_string(bing_se_icon,"icon","search_engine_bing");
	     miscutil::replace_in_string(bing_se_icon,"setitle","Bing");
	     miscutil::replace_in_string(bing_se_icon,"seeng","bing");
	     html_content += bing_se_icon;
	  }
	if (_img_engine.to_ulong()&SE_FLICKR)
	  {
	     std::string flickr_se_icon = se_icon;
	     miscutil::replace_in_string(flickr_se_icon,"icon","search_engine_flickr");
	     miscutil::replace_in_string(flickr_se_icon,"setitle","Flickr");
	     miscutil::replace_in_string(flickr_se_icon,"seeng","flickr");
	     html_content += flickr_se_icon;
	  }
	if (_img_engine.to_ulong()&SE_WCOMMONS)
	  {
	     std::string wcommons_se_icon = se_icon;
	     miscutil::replace_in_string(wcommons_se_icon,"icon","search_engine_wcommons");
             miscutil::replace_in_string(wcommons_se_icon,"setitle","Wikimedia Commons");
             miscutil::replace_in_string(wcommons_se_icon,"seeng","wcommons");
             html_content += wcommons_se_icon;
	  }
	if (_img_engine.to_ulong()&SE_YAHOO_IMG)
	  {
	     std::string yahoo_se_icon = se_icon;
	     miscutil::replace_in_string(yahoo_se_icon,"icon","search_engine_yahoo");
	     miscutil::replace_in_string(yahoo_se_icon,"setitle","yahoo");
	     miscutil::replace_in_string(yahoo_se_icon,"seeng","yahoo");
	     html_content += yahoo_se_icon;
	  }

	// XXX: personalization icon kind of look ugly with image snippets...
	/* if (_personalized)
	  {
	     html_content += "
";
	  }
	else */
	html_content += "

";
	const char *cite_enc = NULL;
	if (!_cite.empty())
	  {
	     std::string cite_host;
	     std::string cite_path;
	     urlmatch::parse_url_host_and_path(_cite,cite_host,cite_path);
	     cite_enc = encode::html_encode(cite_host.c_str());
	  }
	else
	  {
	     std::string cite_host;
	     std::string cite_path;
	     urlmatch::parse_url_host_and_path(_url,cite_host,cite_path);
	     cite_enc = encode::html_encode(cite_host.c_str());
	  }
	std::string cite_enc_str = std::string(cite_enc);
	if (cite_enc_str.size()>4 && cite_enc_str.substr(0,4)=="www.") //TODO: tolower.
	  cite_enc_str = cite_enc_str.substr(4);
	free_const(cite_enc);
	html_content += "";
	html_content += cite_enc_str;
	html_content += "
";

	if (!_cached.empty())
	  {
	     char *enc_cached = encode::html_encode(_cached.c_str());
	     miscutil::chomp(enc_cached);
	     html_content += "Cached";
	     free_const(enc_cached);
	  }

#ifdef FEATURE_OPENCV2
	if (!_sim_back)
	  {
	     set_similarity_link(parameters);
	     html_content += "<a class=\"search_cache\" href=\"";
	  }
	else
	  {
	     set_back_similarity_link(parameters);
	     html_content += "Similar";
	else html_content += "\">Back";
#endif
	html_content += "

\n";
	return html_content;
     }

   std::string img_search_snippet::to_json(const bool &thumbs,
					   const std::vector<std::string> &query_words)
     {
	std::string json_str;
	json_str += "{";
	json_str += "\"id\":" + miscutil::to_string(_id) + ",";
	std::string title = _title;
	miscutil::replace_in_string(title,"\"","\\\"");
	json_str += "\"title\":\"" + title + "\",";
	std::string url = _url;
	miscutil::replace_in_string(url,"\"","\\\"");
	json_str += "\"url\":\"" + url + "\",";
	std::string summary = _summary_noenc;
	miscutil::replace_in_string(summary,"\"","\\\"");
	json_str += "\"summary\":\"" + summary + "\",";
	json_str += "\"seeks_meta\":" + miscutil::to_string(_meta_rank) + ",";
	json_str += "\"seeks_score\":" + miscutil::to_string(_seeks_rank) + ",";
	double rank = _rank / static_cast<double>(_img_engine.count());
	json_str += "\"rank\":" + miscutil::to_string(rank) + ",";
	json_str += "\"cite\":\"";
	if (!_cite.empty())
	  {
	     std::string cite_host;
	     std::string cite_path;
	     urlmatch::parse_url_host_and_path(_cite,cite_host,cite_path);
	     json_str += cite_host + "\",";
	  }
	else
	  {
	     std::string cite_host;
	     std::string cite_path;
	     urlmatch::parse_url_host_and_path(_url,cite_host,cite_path);
	     json_str += cite_host + "\",";
	  }
	if (!_cached.empty())
	  {
	     std::string cached = _cached;
	     miscutil::replace_in_string(cached,"\"","\\\"");
	     json_str += "\"cached\":\"" + _cached + "\","; // XXX: cached might be malformed without preprocessing.
	  }
	json_str += "\"engines\":[";
	std::string json_str_eng = "";
	if (_img_engine.to_ulong()&SE_GOOGLE_IMG)
	  json_str_eng += "\"google\"";
	if (_img_engine.to_ulong()&SE_BING_IMG)
	  {
	     if (!json_str_eng.empty())
	       json_str_eng += ",";
	     json_str_eng += "\"bing\"";
	  }
	if (_img_engine.to_ulong()&SE_FLICKR)
	  {
	     if (!json_str_eng.empty())
	       json_str_eng += ",";
	     json_str_eng += "\"flickr\"";
	  }
	if (_img_engine.to_ulong()&SE_WCOMMONS)
	  {
	     if (!json_str_eng.empty())
	       json_str_eng += ",";
	     json_str_eng += "\"wcommons\"";
	  }
	if (_img_engine.to_ulong()&SE_YAHOO_IMG)
	  {
	     if (!json_str_eng.empty())
	       json_str_eng += ",";
	     json_str_eng += "\"yahoo\"";
	  }
	json_str += json_str_eng + "]";
	json_str += ",\"type\":\"" + get_doc_type_str() + "\"";
	json_str += ",\"personalized\":\"";
	if (_personalized)
	  json_str += "yes";
	else json_str += "no";
	json_str += "\"";
	if (!_date.empty())
	  json_str += ",\"date\":\"" + _date + "\"";
	json_str += "}";
	return json_str;
     }

   bool img_search_snippet::is_se_enabled(const hash_map<const char*,const char*,hash<const char*>,eqstr> *parameters)
     {
	std::bitset<IMG_NSEs> se_enabled;
	img_query_context::fillup_img_engines(parameters,se_enabled);
	std::bitset<IMG_NSEs> band = _img_engine & se_enabled;
	return (band.count() != 0);
     }

   void img_search_snippet::set_similarity_link(const hash_map<const char*,const char*,hash<const char*>,eqstr> *parameters)
     {
	const char *engines = miscutil::lookup(parameters,"engines");
	std::string sfsearch = "on";
	if (!static_cast<img_query_context*>(_qc)->_safesearch)
	  sfsearch = "off";
	_sim_link = "/search_img?q=" + _qc->_url_enc_query
	  + "&page=1&expansion=" + miscutil::to_string(_qc->_page_expansion)
	    + "&action=similarity&safesearch=" + sfsearch
	  + "&id=" + miscutil::to_string(_id) + "&engines=";
	if (engines)
	  _sim_link += std::string(engines);
	_sim_back = false;
     }

   void img_search_snippet::set_back_similarity_link(const hash_map<const char*,const char*,hash<const char*>,eqstr> *parameters)
     {
	const char *engines = miscutil::lookup(parameters,"engines");
	std::string sfsearch = "on";
	if (!static_cast<img_query_context*>(_qc)->_safesearch)
	  sfsearch = "off";
	_sim_link = "/search_img?q=" + _qc->_url_enc_query
	  + "&page=1&expansion=" + miscutil::to_string(_qc->_page_expansion)
	    + "&action=expand&safesearch=" + sfsearch + "&engines=";
	if (engines)
	  _sim_link += std::string(engines);
	_sim_back = true;
     }

   void img_search_snippet::merge_img_snippets(img_search_snippet *s1,
					       const img_search_snippet *s2)
     {
	search_snippet::merge_snippets(s1,s2);

	std::bitset<IMG_NSEs> setest = s1->_img_engine;
	setest &= s2->_img_engine;
	if (setest.count()>0)
	  return;
	s1->_img_engine |= s2->_img_engine;

	if (!s1->_cached_image && s2->_cached_image)
	  s1->_cached_image = new std::string(*s2->_cached_image);

        /// seeks rank.
        s1->_seeks_rank = s1->_img_engine.count();

        // XXX: hack, on English queries, Bing & Yahoo are the same engine,
        // therefore the rank must be tweaked accordingly in this special case.
        if (s1->_qc->_auto_lang == "en"
            && (s1->_img_engine.to_ulong()&SE_YAHOO_IMG)
            && (s1->_img_engine.to_ulong()&SE_BING_IMG))
          s1->_seeks_rank--;
     }

} /* end of namespace. */
<|endoftext|>


<commit_before><commit_msg>fix oox build on big endian<commit_after><|endoftext|>


<commit_before>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: pptimport.cxx,v $
 * $Revision: 1.7 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#include "oox/ppt/pptimport.hxx"
#include "oox/drawingml/chart/chartconverter.hxx"
#include "oox/dump/pptxdumper.hxx"
#include "oox/drawingml/table/tablestylelistfragmenthandler.hxx"

using ::rtl::OUString;
using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::xml::sax;
using namespace oox::core;

namespace oox { namespace ppt {

OUString SAL_CALL PowerPointImport_getImplementationName() throw()
{
    return CREATE_OUSTRING( "com.sun.star.comp.Impress.oox.PowerPointImport" );
}

uno::Sequence< OUString > SAL_CALL PowerPointImport_getSupportedServiceNames() throw()
{
    const OUString aServiceName = CREATE_OUSTRING( "com.sun.star.comp.ooxpptx" );
    const Sequence< OUString > aSeq( &aServiceName, 1 );
    return aSeq;
}

uno::Reference< uno::XInterface > SAL_CALL PowerPointImport_createInstance(const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception )
{
    return (cppu::OWeakObject*)new PowerPointImport( rSMgr );
}

PowerPointImport::PowerPointImport( const uno::Reference< lang::XMultiServiceFactory > & rSMgr  )
    : XmlFilterBase( rSMgr )
    , mxChartConv( new ::oox::drawingml::chart::ChartConverter )
{
}

PowerPointImport::~PowerPointImport()
{
}

bool PowerPointImport::importDocument() throw()
{
    /*  to activate the PPTX dumper, define the environment variable
        OOO_PPTXDUMPER and insert the full path to the file
        file:///<path-to-oox-module>/source/dump/pptxdumperconfig.dat. */
    OOX_DUMP_FILE( ::oox::dump::pptx::Dumper );

    OUString aFragmentPath = getFragmentPathFromType( CREATE_OFFICEDOC_RELATIONSTYPE( "officeDocument" ) );
    FragmentHandlerRef xPresentationFragmentHandler( new PresentationFragmentHandler( *this, aFragmentPath ) );
    maTableStyleListPath = xPresentationFragmentHandler->getFragmentPathFromType( CREATE_OFFICEDOC_RELATIONSTYPE( "tableStyles" ) );
    return importFragment( xPresentationFragmentHandler );

}

bool PowerPointImport::exportDocument() throw()
{
    return false;
}

sal_Int32 PowerPointImport::getSchemeClr( sal_Int32 nColorSchemeToken ) const
{
    sal_Int32 nColor = 0;
    if ( mpActualSlidePersist )
    {
        sal_Bool bColorMapped = sal_False;
        oox::drawingml::ClrMapPtr pClrMapPtr( mpActualSlidePersist->getClrMap() );
        if ( pClrMapPtr )
            bColorMapped = pClrMapPtr->getColorMap( nColorSchemeToken );

        if ( !bColorMapped )    // try masterpage mapping
        {
            SlidePersistPtr pMasterPersist = mpActualSlidePersist->getMasterPersist();
            if ( pMasterPersist )
            {
                pClrMapPtr = pMasterPersist->getClrMap();
                if ( pClrMapPtr )
                    bColorMapped = pClrMapPtr->getColorMap( nColorSchemeToken );
            }
        }
        oox::drawingml::ClrSchemePtr pClrSchemePtr( mpActualSlidePersist->getClrScheme() );
        if ( pClrSchemePtr )
            pClrSchemePtr->getColor( nColorSchemeToken, nColor );
        else
        {
            drawingml::ThemePtr pTheme = mpActualSlidePersist->getTheme();
            if( pTheme )
            {
                pTheme->getClrScheme().getColor( nColorSchemeToken, nColor );
            }
            else
            {
                OSL_TRACE("OOX: PowerPointImport::mpThemePtr is NULL");
            }
        }
    }
    return nColor;
}

const oox::vml::DrawingPtr PowerPointImport::getDrawings()
{
    oox::vml::DrawingPtr xRet;
    if ( mpActualSlidePersist )
        xRet = mpActualSlidePersist->getDrawing();
    return xRet;
}

const oox::drawingml::table::TableStyleListPtr PowerPointImport::getTableStyles()
{
    if ( !mpTableStyleList && maTableStyleListPath.getLength() )
    {
        mpTableStyleList = oox::drawingml::table::TableStyleListPtr( new oox::drawingml::table::TableStyleList() );
        importFragment( new oox::drawingml::table::TableStyleListFragmentHandler(
            *this, maTableStyleListPath, *mpTableStyleList ) );
    }
    return mpTableStyleList;;
}

::oox::drawingml::chart::ChartConverter& PowerPointImport::getChartConverter()
{
    return *mxChartConv;
}

OUString PowerPointImport::implGetImplementationName() const
{
    return PowerPointImport_getImplementationName();
}

}}
<commit_msg>INTEGRATION: CWS xmlfilter06 (1.5.6); FILE MERGED 2008/06/30 09:57:41 dr 1.5.6.3: RESYNC: (1.5-1.6); FILE MERGED 2008/06/06 16:27:54 dr 1.5.6.2: chart formatting: builtin line/fill/effect styles, manual line formatting 2008/05/27 10:40:42 dr 1.5.6.1: joined changes from CWS xmlfilter05<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: pptimport.cxx,v $
 * $Revision: 1.8 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#include "oox/ppt/pptimport.hxx"
#include "oox/drawingml/chart/chartconverter.hxx"
#include "oox/dump/pptxdumper.hxx"
#include "oox/drawingml/table/tablestylelistfragmenthandler.hxx"

using ::rtl::OUString;
using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::xml::sax;
using namespace oox::core;

namespace oox { namespace ppt {

OUString SAL_CALL PowerPointImport_getImplementationName() throw()
{
    return CREATE_OUSTRING( "com.sun.star.comp.Impress.oox.PowerPointImport" );
}

uno::Sequence< OUString > SAL_CALL PowerPointImport_getSupportedServiceNames() throw()
{
    const OUString aServiceName = CREATE_OUSTRING( "com.sun.star.comp.ooxpptx" );
    const Sequence< OUString > aSeq( &aServiceName, 1 );
    return aSeq;
}

uno::Reference< uno::XInterface > SAL_CALL PowerPointImport_createInstance(const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception )
{
    return (cppu::OWeakObject*)new PowerPointImport( rSMgr );
}

PowerPointImport::PowerPointImport( const uno::Reference< lang::XMultiServiceFactory > & rSMgr  )
    : XmlFilterBase( rSMgr )
    , mxChartConv( new ::oox::drawingml::chart::ChartConverter )
{
}

PowerPointImport::~PowerPointImport()
{
}

bool PowerPointImport::importDocument() throw()
{
    /*  to activate the PPTX dumper, define the environment variable
        OOO_PPTXDUMPER and insert the full path to the file
        file:///<path-to-oox-module>/source/dump/pptxdumperconfig.dat. */
    OOX_DUMP_FILE( ::oox::dump::pptx::Dumper );

    OUString aFragmentPath = getFragmentPathFromType( CREATE_OFFICEDOC_RELATIONSTYPE( "officeDocument" ) );
    FragmentHandlerRef xPresentationFragmentHandler( new PresentationFragmentHandler( *this, aFragmentPath ) );
    maTableStyleListPath = xPresentationFragmentHandler->getFragmentPathFromType( CREATE_OFFICEDOC_RELATIONSTYPE( "tableStyles" ) );
    return importFragment( xPresentationFragmentHandler );

}

bool PowerPointImport::exportDocument() throw()
{
    return false;
}

const ::oox::drawingml::Theme* PowerPointImport::getCurrentTheme() const
{
    return mpActualSlidePersist ? mpActualSlidePersist->getTheme().get() : 0;
}

sal_Int32 PowerPointImport::getSchemeClr( sal_Int32 nColorSchemeToken ) const
{
    sal_Int32 nColor = 0;
    if ( mpActualSlidePersist )
    {
        sal_Bool bColorMapped = sal_False;
        oox::drawingml::ClrMapPtr pClrMapPtr( mpActualSlidePersist->getClrMap() );
        if ( pClrMapPtr )
            bColorMapped = pClrMapPtr->getColorMap( nColorSchemeToken );

        if ( !bColorMapped )    // try masterpage mapping
        {
            SlidePersistPtr pMasterPersist = mpActualSlidePersist->getMasterPersist();
            if ( pMasterPersist )
            {
                pClrMapPtr = pMasterPersist->getClrMap();
                if ( pClrMapPtr )
                    bColorMapped = pClrMapPtr->getColorMap( nColorSchemeToken );
            }
        }
        oox::drawingml::ClrSchemePtr pClrSchemePtr( mpActualSlidePersist->getClrScheme() );
        if ( pClrSchemePtr )
            pClrSchemePtr->getColor( nColorSchemeToken, nColor );
        else
        {
            ::oox::drawingml::ThemePtr pTheme = mpActualSlidePersist->getTheme();
            if( pTheme )
            {
                pTheme->getClrScheme().getColor( nColorSchemeToken, nColor );
            }
            else
            {
                OSL_TRACE("OOX: PowerPointImport::mpThemePtr is NULL");
            }
        }
    }
    return nColor;
}

const oox::vml::DrawingPtr PowerPointImport::getDrawings()
{
    oox::vml::DrawingPtr xRet;
    if ( mpActualSlidePersist )
        xRet = mpActualSlidePersist->getDrawing();
    return xRet;
}

const oox::drawingml::table::TableStyleListPtr PowerPointImport::getTableStyles()
{
    if ( !mpTableStyleList && maTableStyleListPath.getLength() )
    {
        mpTableStyleList = oox::drawingml::table::TableStyleListPtr( new oox::drawingml::table::TableStyleList() );
        importFragment( new oox::drawingml::table::TableStyleListFragmentHandler(
            *this, maTableStyleListPath, *mpTableStyleList ) );
    }
    return mpTableStyleList;;
}

::oox::drawingml::chart::ChartConverter& PowerPointImport::getChartConverter()
{
    return *mxChartConv;
}

OUString PowerPointImport::implGetImplementationName() const
{
    return PowerPointImport_getImplementationName();
}

}}
<|endoftext|>


<commit_before>/*
 * opencog/server/BaseServer.cc
 *
 * Copyright (C) 2002-2007 Novamente LLC
 * All Rights Reserved
 *
 * Written by Andre Senna <senna@vettalabs.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License v3 as
 * published by the Free Software Foundation and including the exceptions
 * at http://opencog.org/wiki/Licenses
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program; if not, write to:
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include <memory>
#include <opencog/util/oc_assert.h>
#include "BaseServer.h"

using namespace opencog;

AtomSpace* BaseServer::atomSpace = NULL;

static BaseServer* serverInstance = NULL;

BaseServer* BaseServer::createInstance()
{
    OC_ASSERT(0,
        "Accidentally called the base class!\n"
        "To fix this bug, be sure to make the following call in your code:\n"
        "   server(MyServer::MyCreateInstance);\n"
        "So, for example:\n"
        "   server(OAC::createInstance);\n"
        "or maybe this:\n"
        "   server(CogServer::createInstance);\n"
        "depending on which you want.  You only need to do this once,\n"
        "early during the initialization of your program.\n"
    );
    return NULL;
}

BaseServer::BaseServer()
{
    // Set this server as the current server.
    set_current_server(this);
}

BaseServer::~BaseServer()
{
    // We are no longer the current server.
    set_current_server(NULL);
}

AtomSpace& BaseServer::getAtomSpace()
{
    return *atomSpace;
}

BaseServer& opencog::server(BaseServer* (*factoryFunction)())
{
    // Create a new instance using the factory function if we don't
    // already have one.
    if (!serverInstance)
        serverInstance = (*factoryFunction)();

    // Return a reference to our server instance.
    return *serverInstance;
}

void opencog::set_current_server(BaseServer* currentServer)
{
    // Normally used for stack-based server instantiation.

    // Nothing to do if we've already done this.
    if (serverInstance == currentServer)
        return;

    // Should not call this on more than one server at a time.
    if (serverInstance && currentServer != serverInstance) {
        throw (RuntimeException(TRACE_INFO,
                "Can't create more than one server singleton instance!"));
    }

    // Set the current server.
    serverInstance = currentServer;
}
<commit_msg>Fixed intermittent bug in multi-server unit tests<commit_after>/*
 * opencog/server/BaseServer.cc
 *
 * Copyright (C) 2002-2007 Novamente LLC
 * All Rights Reserved
 *
 * Written by Andre Senna <senna@vettalabs.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License v3 as
 * published by the Free Software Foundation and including the exceptions
 * at http://opencog.org/wiki/Licenses
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program; if not, write to:
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include <memory>
#include <opencog/util/oc_assert.h>
#include "BaseServer.h"

using namespace opencog;

AtomSpace* BaseServer::atomSpace = NULL;

static BaseServer* serverInstance = NULL;

BaseServer* BaseServer::createInstance()
{
    OC_ASSERT(0,
        "Accidentally called the base class!\n"
        "To fix this bug, be sure to make the following call in your code:\n"
        "   server(MyServer::MyCreateInstance);\n"
        "So, for example:\n"
        "   server(OAC::createInstance);\n"
        "or maybe this:\n"
        "   server(CogServer::createInstance);\n"
        "depending on which you want.  You only need to do this once,\n"
        "early during the initialization of your program.\n"
    );
    return NULL;
}

BaseServer::BaseServer()
{
    // Set this server as the current server.
    set_current_server(this);
}

BaseServer::~BaseServer()
{
    // We are no longer the current server.
    set_current_server(NULL);
}

AtomSpace& BaseServer::getAtomSpace()
{
    return *atomSpace;
}

BaseServer& opencog::server(BaseServer* (*factoryFunction)())
{
    // Create a new instance using the factory function if we don't
    // already have one.
    if (!serverInstance)
        serverInstance = (*factoryFunction)();

    // Return a reference to our server instance.
    return *serverInstance;
}

void opencog::set_current_server(BaseServer* currentServer)
{
    // Normally used for stack-based server instantiation.

    // Nothing to do if we've already done this.
    if (serverInstance == currentServer)
        return;

    // Should not call this on more than one server at a time.
    if (serverInstance &&
        currentServer != serverInstance &&
        currentServer != NULL ) {
        throw (RuntimeException(TRACE_INFO,
                "Can't create more than one server singleton instance!"));
    }

    // Set the current server.
    serverInstance = currentServer;
}
<|endoftext|>


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

#include "xwalk/extensions/browser/xwalk_extension_web_contents_handler.h"

#include "base/bind.h"
#include "base/threading/thread.h"
#include "xwalk/extensions/browser/xwalk_extension.h"
#include "xwalk/extensions/common/xwalk_extension_messages.h"

DEFINE_WEB_CONTENTS_USER_DATA_KEY(
    xwalk::extensions::XWalkExtensionWebContentsHandler);

namespace tracked_objects {
class Location;
}

namespace xwalk {
namespace extensions {

// This class wraps an XWalkExtension::Context so it runs in its own Extension
// thread. It also provides |post_message| callback for the Context.
class XWalkExtensionRunner {
 public:
  XWalkExtensionRunner(XWalkExtension* extension,
                       IPC::Sender* sender,
                       int32_t render_view_id)
      : extension_(extension),
        sender_(sender),
        render_view_id_(render_view_id) {
    std::string thread_name = "XWalk_ExtensionThread_" + extension_->name();
    thread_.reset(new base::Thread(thread_name.c_str()));
    thread_->Start();
    PostTaskToExtensionThread(
        FROM_HERE, base::Bind(&XWalkExtensionRunner::CreateContext,
                              base::Unretained(this)));
  }

  ~XWalkExtensionRunner() {
    // All Context related code should run in the thread.
    PostTaskToExtensionThread(
        FROM_HERE, base::Bind(&XWalkExtensionRunner::DestroyContext,
                              base::Unretained(this)));

    // Note: this will block until threads message loop process the task above.
    thread_->Stop();
  }

  void HandleMessage(const std::string& msg) {
    PostTaskToExtensionThread(
        FROM_HERE, base::Bind(&XWalkExtension::Context::HandleMessage,
                              base::Unretained(context_.get()),
                              msg));
  }

  void PostMessage(const std::string& msg) {
    sender_->Send(
        new XWalkViewMsg_PostMessage(render_view_id_, extension_->name(), msg));
  }

 private:
  bool PostTaskToExtensionThread(const tracked_objects::Location& from_here,
                                 const base::Closure& task) {
    // FIXME(cmarcelo): Can we cache this message_loop_proxy?
    return thread_->message_loop_proxy()->PostTask(from_here, task);
  }

  void CreateContext() {
    CHECK(CalledOnExtensionThread());

    XWalkExtension::Context* context = extension_->CreateContext(base::Bind(
          &XWalkExtensionRunner::PostMessage, base::Unretained(this)));
    if (!context) {
      VLOG(0) << "Could not create context for extension \"" <<
            extension_->name() << "\". Destroying extension thread.";
      delete this;
      return;
    }

    context_.reset(context);
  }

  void DestroyContext() {
    CHECK(CalledOnExtensionThread());
    context_.reset();
  }

  bool CalledOnExtensionThread() {
    return MessageLoop::current() == thread_->message_loop();
  }

  scoped_ptr<XWalkExtension::Context> context_;
  scoped_ptr<base::Thread> thread_;
  XWalkExtension* extension_;
  IPC::Sender* sender_;
  int32_t render_view_id_;

  DISALLOW_COPY_AND_ASSIGN(XWalkExtensionRunner);
};

XWalkExtensionWebContentsHandler::XWalkExtensionWebContentsHandler(
    content::WebContents* contents)
    : WebContentsObserver(contents) {
}

XWalkExtensionWebContentsHandler::~XWalkExtensionWebContentsHandler() {
  RunnerMap::iterator it = runners_.begin();
  for (; it != runners_.end(); ++it)
    delete it->second;
}

void XWalkExtensionWebContentsHandler::AttachExtension(
    XWalkExtension* extension) {
  runners_[extension->name()] =
      new XWalkExtensionRunner(extension,
                               this,
                               web_contents()->GetRoutingID());
}

bool XWalkExtensionWebContentsHandler::OnMessageReceived(
    const IPC::Message& message) {
  bool handled = true;
  IPC_BEGIN_MESSAGE_MAP(XWalkExtensionWebContentsHandler, message)
    IPC_MESSAGE_HANDLER(XWalkViewHostMsg_PostMessage, OnPostMessage)
    IPC_MESSAGE_UNHANDLED(handled = false)
  IPC_END_MESSAGE_MAP()
  return handled;
}

void XWalkExtensionWebContentsHandler::OnPostMessage(
    const std::string& extension_name, const std::string& msg) {
  RunnerMap::iterator it = runners_.find(extension_name);
  if (it != runners_.end())
    it->second->HandleMessage(msg);
  else
    LOG(WARNING) << "Couldn't handle message for unregistered extension '"
                 << extension_name << "'";
}

}  // namespace extensions
}  // namespace xwalk
<commit_msg>Workaround crash on exit (issue #178).<commit_after>// Copyright (c) 2013 Intel Corporation. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "xwalk/extensions/browser/xwalk_extension_web_contents_handler.h"

#include "base/bind.h"
#include "base/threading/thread.h"
#include "base/threading/thread_restrictions.h"
#include "xwalk/extensions/browser/xwalk_extension.h"
#include "xwalk/extensions/common/xwalk_extension_messages.h"

DEFINE_WEB_CONTENTS_USER_DATA_KEY(
    xwalk::extensions::XWalkExtensionWebContentsHandler);

namespace tracked_objects {
class Location;
}

namespace xwalk {
namespace extensions {

// This class wraps an XWalkExtension::Context so it runs in its own Extension
// thread. It also provides |post_message| callback for the Context.
class XWalkExtensionRunner {
 public:
  XWalkExtensionRunner(XWalkExtension* extension,
                       IPC::Sender* sender,
                       int32_t render_view_id)
      : extension_(extension),
        sender_(sender),
        render_view_id_(render_view_id) {
    std::string thread_name = "XWalk_ExtensionThread_" + extension_->name();
    thread_.reset(new base::Thread(thread_name.c_str()));
    thread_->Start();
    PostTaskToExtensionThread(
        FROM_HERE, base::Bind(&XWalkExtensionRunner::CreateContext,
                              base::Unretained(this)));
  }

  ~XWalkExtensionRunner() {
    // All Context related code should run in the thread.
    PostTaskToExtensionThread(
        FROM_HERE, base::Bind(&XWalkExtensionRunner::DestroyContext,
                              base::Unretained(this)));

    // Waiting on the browser thread is frowned upon since it might cause
    // jank (there's no way to know how much time the extension thread might
    // be blocked for).  However, it's not safe to destroy the extension
    // context from a thread other than the extension thread.  We
    // temporarily turn off this restriction, wait for the extension thread
    // to be properly destroyed, and enable the restriction again.
    // FIXME(leandro): Find a way to properly destroy an extension context
    // without blocking the browser thread.
    bool old_restriction = base::ThreadRestrictions::SetIOAllowed(true);
    thread_->Stop();
    base::ThreadRestrictions::SetIOAllowed(old_restriction);
  }

  void HandleMessage(const std::string& msg) {
    PostTaskToExtensionThread(
        FROM_HERE, base::Bind(&XWalkExtension::Context::HandleMessage,
                              base::Unretained(context_.get()),
                              msg));
  }

  void PostMessage(const std::string& msg) {
    sender_->Send(
        new XWalkViewMsg_PostMessage(render_view_id_, extension_->name(), msg));
  }

 private:
  bool PostTaskToExtensionThread(const tracked_objects::Location& from_here,
                                 const base::Closure& task) {
    // FIXME(cmarcelo): Can we cache this message_loop_proxy?
    return thread_->message_loop_proxy()->PostTask(from_here, task);
  }

  void CreateContext() {
    CHECK(CalledOnExtensionThread());

    XWalkExtension::Context* context = extension_->CreateContext(base::Bind(
          &XWalkExtensionRunner::PostMessage, base::Unretained(this)));
    if (!context) {
      VLOG(0) << "Could not create context for extension \"" <<
            extension_->name() << "\". Destroying extension thread.";
      delete this;
      return;
    }

    context_.reset(context);
  }

  void DestroyContext() {
    CHECK(CalledOnExtensionThread());
    context_.reset();
  }

  bool CalledOnExtensionThread() {
    return MessageLoop::current() == thread_->message_loop();
  }

  scoped_ptr<XWalkExtension::Context> context_;
  scoped_ptr<base::Thread> thread_;
  XWalkExtension* extension_;
  IPC::Sender* sender_;
  int32_t render_view_id_;

  DISALLOW_COPY_AND_ASSIGN(XWalkExtensionRunner);
};

XWalkExtensionWebContentsHandler::XWalkExtensionWebContentsHandler(
    content::WebContents* contents)
    : WebContentsObserver(contents) {
}

XWalkExtensionWebContentsHandler::~XWalkExtensionWebContentsHandler() {
  RunnerMap::iterator it = runners_.begin();
  for (; it != runners_.end(); ++it)
    delete it->second;
}

void XWalkExtensionWebContentsHandler::AttachExtension(
    XWalkExtension* extension) {
  runners_[extension->name()] =
      new XWalkExtensionRunner(extension,
                               this,
                               web_contents()->GetRoutingID());
}

bool XWalkExtensionWebContentsHandler::OnMessageReceived(
    const IPC::Message& message) {
  bool handled = true;
  IPC_BEGIN_MESSAGE_MAP(XWalkExtensionWebContentsHandler, message)
    IPC_MESSAGE_HANDLER(XWalkViewHostMsg_PostMessage, OnPostMessage)
    IPC_MESSAGE_UNHANDLED(handled = false)
  IPC_END_MESSAGE_MAP()
  return handled;
}

void XWalkExtensionWebContentsHandler::OnPostMessage(
    const std::string& extension_name, const std::string& msg) {
  RunnerMap::iterator it = runners_.find(extension_name);
  if (it != runners_.end())
    it->second->HandleMessage(msg);
  else
    LOG(WARNING) << "Couldn't handle message for unregistered extension '"
                 << extension_name << "'";
}

}  // namespace extensions
}  // namespace xwalk
<|endoftext|>


<commit_before>/*
 * KDots
 * Copyright (c) 2011-2012 Minh Ngo <nlminhtl@gmail.com>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#include "prioritymap.hpp"
#include <QDebug>

namespace KDots
{
	namespace simpleai
	{
		const std::list<MapData> PRIORITY_MAP {
			{
				{//1
					{NM, SE, NM},
					{FI, CU, FI},
					{NM, SE, NM}
				},
				{1, 1},
				1
			},
			{
				{//2
					{SE, PF, NM},
					{FI, CU, PF},
					{NM, SE, NM}
				},
				{1, 1},
				0.9
			},
			{
				{//3
					{NM, SE, PF},
					{FI, FI, CU},
					{NM, SE, PF}
				},
				{2, 1},
				0.9
			},
			{
				{//4
					{SE, NM, PF},
					{NM, CU, NM},
					{PF, NM, SE}
				},
				{1, 1},
				0.05
			},
			{
				{//5
					{NM, FI, NM, NM},
					{EM, EM, SE, NM},
					{NM, CU, EM, FI},
					{NM, NM, EM, NM}
				},
				{1, 2},
				0.8
			},
			{
				{//6
					{NM, FI, NM},
					{FI, SE, EM},
					{PF, CU, PF},
					{NM, SE, NM}
				},
				{1, 2},
				0.7
			},
			{
				{//7
					{NM, FI, NM},
					{FI, SE, EM},
					{NM, CU, NM}
				},
				{1, 2},
				0.2
			},
			{
				{//8
					{NM, EM, NM, NM},
					{FI, SE, CU, NM},
					{NM, FI, SE, EM},
					{NM, NM, FI, NM}
				},
				{2, 1},
				1
			},
			{
				{//9
					{NM, FI, NM},
					{PF, SE, CU},
					{NM, FI, NM}
				},
				{2, 1},
				0.2
			},
			{
				{//10
					{NM, SE, NM},
					{PF, CU, PF},
					{NM, SE, NM}
				},
				{1, 1},
				0.05
			},
			{
				{//11
					{PF, PF, CU},
					{EM, EM, EM},
					{PF, SE, PF},
					{NM, SE, NM}
				},
				{2, 0},
				0.01
			},
			{
				{//12
					{NM, PF, NM},
					{FI, EM, CU},
					{PF, SE, EM},
					{NM, SE, NM}
				},
				{2, 1},
				0.05
			},
			{
				{//13
					{NM, FI, NM},
					{FI, CU, FI}
				},
				{1, 1},
				-0.5
			},
			{
				{//14
					{NM, SE, NM},
					{NM, EM, NM},
					{PF, CU, PF},
					{NM, SE, NM}
				},
				{1, 2},
				0.05
			},
			{
				{//15
					{NM, SE, NM},
					{NM, EM, NM},
					{PF, CU, PF},
					{NM, EM, NM},
					{NM, SE, NM}
				},
				{1, 2},
				0.05
			},
			{
				{//16
					{NM, SE, NM},
					{NM, EM, NM},
					{PF, CU, PF},
					{NM, EM, NM},
					{NM, EM, NM},
					{NM, SE, NM}
				},
				{1, 2},
				0.05
			},
			{
				{//17
					{NM, SE, NM},
					{NM, EM, NM},
					{NM, EM, NM},
					{PF, CU, PF},
					{NM, EM, NM},
					{NM, EM, NM},
					{NM, SE, NM}
				},
				{1, 3},
				0.05
			},
			{
				{//18
					{NM, NM, SE},
					{PF, CU, PF},
					{NM, SE, NM}
				},
				{1, 1},
				0.05
			},
			{
				{//19
					{NM, SE, NM},
					{PF, CU, PF},
					{PS, EM, NM},
					{SE, NM, NM}
				},
				{1, 1},
				0.05
			},
			{
				{//20
					{NM, SE, NM},
					{NM, EM, NM},
					{PF, CU, PF},
					{PS, EM, NM},
					{SE, NM, NM}
				},
				{1, 2},
				0.05
			},
			{
				{//21
					{NM, SE},
					{NM, EM},
					{PF, EM},
					{PF, CU},
					{SE, NM}
				},
				{1, 3},
				0.05
			},
			{
				{//22
					{NM, SE, NM},
					{PF, FI, CU},
					{NM, SE, NM}
				},
				{2, 1},
				0.1
			},
			{
				{//23
					{NM, SE, NM},
					{PF, FI, CU},
					{NM, EM, EM},
					{NM, SE, NM}
				},
				{2, 1},
				0.1
			},
			{
				{//24
					{NM, SE, NM},
					{NM, EM, EM},
					{PF, FI, CU},
					{NM, EM, EM},
					{NM, SE, NM}
				},
				{2, 2},
				0.1
			},
			{
				{//25
					{NM, SE},
					{PF, EM},
					{PF, CU},
					{SE, NM}
				},
				{1, 2},
				0.05
			},
			{
				{//26
					{SE, CU},
					{SE, SE}
				},
				{1, 0},
				-0.5
			},
			{
				{//27
					{NM, NM, EM, EM, NM},
					{NM, CU, EM, EM, SE},
					{EM, EM, FI, NM, NM},
					{NM, SE, NM, NM, NM}
				},
				{1, 1},
				0.8
			},
			{
				{//28
					{NM, NM, EM, EM, NM},
					{NM, CU, EM, EM, SE},
					{EM, EM, PF, FI, NM},
					{NM, SE, NM, NM, NM}
				},
				{1, 1},
				0.8
			},
			{
				{//29
					{FI, SE},
					{CU, FI},
					{SE, NM}
				},
				{0, 1},
				0.9
			},
			{
				{//30
					{NM, SE, NM},
					{NM, EM, EM},
					{NM, EM, EM},
					{PF, FI, CU},
					{NM, SE, NM}
				},
				{2, 3},
				0.1
			},
			{
				{//31
					{NM, SE, NM},
					{NM, EM, EM},
					{NM, EM, EM},
					{PF, FI, CU},
					{NM, EM, EM},
					{NM, SE, NM}
				},
				{2, 3},
				0.1
			},
			{
				{//32
					{NM, SE},
					{NM, EM},
					{FI, CU},
					{SE, NM}
				},
				{1, 2},
				0.1
			},
			{
				{//33
					{SE, FI, NM},
					{FI, CU, NM},
					{NM, NM, SE}
				},
				{1, 1},
				0.1
			}/*,
			{
				{//34
					{SE, EM},
					{EM, CU}
				},
				{1, 1},
				0.01
			}*/
		};

		bool MapData::operator== (const MapData& other) const
		{
			if (m_current != other.m_current)
				return false;

			if (m_priority != other.m_priority)
				return false;

			if (other.m_map.size () != m_map.size ()
					|| !other.m_map.size ()
					|| !m_map.size ())
				return false;

			for (MapType::const_iterator other_itr = other.m_map.begin (),
					itr = m_map.begin (), other_e = other.m_map.end ();
					other_itr != other_e ; ++other_itr, ++itr)
			{
				if (!std::equal (other_itr->begin (), other_itr->end (), itr->begin ()))
					return false;
			}

			return true;
		}

		bool MapData::operator!= (const MapData& other) const
		{
			return !(other == *this);
		}

		///

		MapData PriorityMap::inverse (const MapData& data)
		{
			const MapType& map = data.m_map;
			MapData newData;
			MapType& newMap = newData.m_map;

			newMap.resize (map.size ());

			MapType::const_iterator map_i = map.begin ();
			for (MapType::iterator new_i = newMap.begin (),
					new_e = newMap.end ();
					new_i != new_e; ++new_i, ++map_i)
			{
				new_i->resize (map_i->size ());
				std::reverse_copy (map_i->begin (), map_i->end (), new_i->begin ());
			}

			newData.m_priority = data.m_priority;
			newData.m_current = {static_cast<int> (map.front ().size () - 1 - data.m_current.x ()),
					data.m_current.y ()};

			return newData;
		}

		MapData PriorityMap::rotate (const MapData& data)
		{
			const MapType& map = data.m_map;
			MapData newData;
			MapType& newMap = newData.m_map;

			newMap.resize (map.front ().size ());
			std::for_each (newMap.begin (), newMap.end (), [&map] (MapLine& line) {
				line.resize (map.size ());
			});

			for (int i = 0, max_i = newMap.size (), j, max_j = map.size (); i != max_i; ++i) //y
			{
				for (j = 0; j != max_j; ++j) //x
					newMap[i][j] = map[max_j - 1 - j][i];
			}

			newData.m_priority = data.m_priority;
			newData.m_current = {static_cast<int> (map.size () - 1 - data.m_current.y ()),
					data.m_current.x ()};

			return newData;
		}

		PriorityMap::PriorityMap ()
			: m_priorityMap (PRIORITY_MAP)
		{
			for (const MapData& data : PRIORITY_MAP)
			{
				const MapData& invertedData = inverse (data);
				m_priorityMap.push_back (invertedData);

				MapData newData = data;
				for (int i = 0; i < 3; ++i)
				{
					newData = rotate (newData);
					m_priorityMap.push_back (newData);
					const MapData& invertedMap = inverse (newData);
					m_priorityMap.push_back (invertedMap);
				}
			}
		}

		PriorityMap& PriorityMap::instance ()
		{
			static PriorityMap obj;
			return obj;
		}

		const std::list<MapData>& PriorityMap::priorityMap ()
		{
			return m_priorityMap;
		}
	}
}<commit_msg>Fixing AI algorithm<commit_after>/*
 * KDots
 * Copyright (c) 2011-2012 Minh Ngo <nlminhtl@gmail.com>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#include "prioritymap.hpp"
#include <QDebug>

namespace KDots
{
	namespace simpleai
	{
		const std::list<MapData> PRIORITY_MAP {
			{
				{//1
					{NM, SE, NM},
					{FI, CU, FI},
					{NM, SE, NM}
				},
				{1, 1},
				1
			},
			{
				{//2
					{SE, PF, NM},
					{FI, CU, PF},
					{NM, SE, NM}
				},
				{1, 1},
				0.9
			},
			{
				{//3
					{NM, SE, PF},
					{FI, FI, CU},
					{NM, SE, PF}
				},
				{2, 1},
				0.9
			},
			{
				{//4
					{SE, NM, PF},
					{NM, CU, NM},
					{PF, NM, SE}
				},
				{1, 1},
				0.05
			},
			{
				{//5
					{NM, FI, NM, NM},
					{EM, EM, SE, NM},
					{NM, CU, EM, FI},
					{NM, NM, EM, NM}
				},
				{1, 2},
				0.8
			},
			{
				{//6
					{NM, FI, NM},
					{FI, SE, EM},
					{PF, CU, PF},
					{NM, SE, NM}
				},
				{1, 2},
				0.7
			},
			{
				{//7
					{NM, FI, NM},
					{FI, SE, EM},
					{NM, CU, NM}
				},
				{1, 2},
				0.2
			},
			{
				{//8
					{NM, EM, NM, NM},
					{FI, SE, CU, NM},
					{NM, FI, SE, EM},
					{NM, NM, FI, NM}
				},
				{2, 1},
				1
			},
			{
				{//9
					{NM, FI, NM},
					{PF, SE, CU},
					{NM, FI, NM}
				},
				{2, 1},
				0.2
			},
			{
				{//10
					{NM, SE, NM},
					{PF, CU, PF},
					{NM, SE, NM}
				},
				{1, 1},
				0.05
			},
			{
				{//11
					{PF, PF, CU},
					{EM, EM, EM},
					{PF, SE, PF},
					{NM, SE, NM}
				},
				{2, 0},
				0.01
			},
			{
				{//12
					{NM, PF, NM},
					{FI, EM, CU},
					{PF, SE, EM},
					{NM, SE, NM}
				},
				{2, 1},
				0.05
			},
			{
				{//13
					{NM, FI, NM},
					{FI, CU, FI}
				},
				{1, 1},
				-0.5
			},
			{
				{//14
					{NM, SE, NM},
					{NM, EM, NM},
					{PF, CU, PF},
					{NM, SE, NM}
				},
				{1, 2},
				0.05
			},
			{
				{//15
					{NM, SE, NM},
					{NM, EM, NM},
					{PF, CU, PF},
					{NM, EM, NM},
					{NM, SE, NM}
				},
				{1, 2},
				0.05
			},
			{
				{//16
					{NM, SE, NM},
					{NM, EM, NM},
					{PF, CU, PF},
					{NM, EM, NM},
					{NM, EM, NM},
					{NM, SE, NM}
				},
				{1, 2},
				0.05
			},
			{
				{//17
					{NM, SE, NM},
					{NM, EM, NM},
					{NM, EM, NM},
					{PF, CU, PF},
					{NM, EM, NM},
					{NM, EM, NM},
					{NM, SE, NM}
				},
				{1, 3},
				0.05
			},
			{
				{//18
					{NM, NM, SE},
					{PF, CU, PF},
					{NM, SE, NM}
				},
				{1, 1},
				0.05
			},
			{
				{//19
					{NM, SE, NM},
					{PF, CU, PF},
					{PS, EM, NM},
					{SE, NM, NM}
				},
				{1, 1},
				0.05
			},
			{
				{//20
					{NM, SE, NM},
					{NM, EM, NM},
					{PF, CU, PF},
					{PS, EM, NM},
					{SE, NM, NM}
				},
				{1, 2},
				0.05
			},
			{
				{//21
					{NM, SE},
					{NM, EM},
					{PF, EM},
					{PF, CU},
					{SE, NM}
				},
				{1, 3},
				0.05
			},
			{
				{//22
					{NM, SE, NM},
					{PF, FI, CU},
					{NM, SE, NM}
				},
				{2, 1},
				0.1
			},
			{
				{//23
					{NM, SE, NM},
					{PF, FI, CU},
					{NM, EM, EM},
					{NM, SE, NM}
				},
				{2, 1},
				0.1
			},
			{
				{//24
					{NM, SE, NM},
					{NM, EM, EM},
					{PF, FI, CU},
					{NM, EM, EM},
					{NM, SE, NM}
				},
				{2, 2},
				0.1
			},
			{
				{//25
					{NM, SE},
					{PF, EM},
					{PF, CU},
					{SE, NM}
				},
				{1, 2},
				0.05
			},
			{
				{//26
					{SE, CU},
					{SE, SE}
				},
				{1, 0},
				-0.5
			},
			{
				{//27
					{NM, NM, EM, EM, NM},
					{NM, CU, EM, EM, SE},
					{EM, EM, FI, NM, NM},
					{NM, SE, NM, NM, NM}
				},
				{1, 1},
				0.8
			},
			{
				{//28
					{NM, NM, EM, EM, NM},
					{NM, CU, EM, EM, SE},
					{EM, EM, PF, FI, NM},
					{NM, SE, NM, NM, NM}
				},
				{1, 1},
				0.8
			},
			{
				{//29
					{FI, SE},
					{CU, FI},
					{SE, NM}
				},
				{0, 1},
				0.9
			},
			{
				{//30
					{NM, SE, NM},
					{NM, EM, EM},
					{NM, EM, EM},
					{PF, FI, CU},
					{NM, SE, NM}
				},
				{2, 3},
				0.1
			},
			{
				{//31
					{NM, SE, NM},
					{NM, EM, EM},
					{NM, EM, EM},
					{PF, FI, CU},
					{NM, EM, EM},
					{NM, SE, NM}
				},
				{2, 3},
				0.1
			},
			{
				{//32
					{NM, SE},
					{NM, EM},
					{FI, CU},
					{SE, NM}
				},
				{1, 2},
				0.1
			},
			{
				{//33
					{SE, FI, NM},
					{FI, CU, NM},
					{NM, NM, SE}
				},
				{1, 1},
				0.1
			},
			{
				{//34
					{SE, EM},
					{EM, CU}
				},
				{1, 1},
				0.01
			},
			{
				{//35
					{EM, EM, EM},
					{EM, EM, EM},
					{EM, EM, CU}
				},
				{2, 2},
				-0.05
			},
			{
				{//36
					{EM, SE, SE},
					{CU, FI, SE},
					{EM, SE, NM}
				},
				{0, 1},
				0.5
			},
			{
				{
					{NM, FI, NM},
					{CU, SE, FI},
					{SE, FI, SE}
				},
				{0, 1},
				0.9
			}
		};

		bool MapData::operator== (const MapData& other) const
		{
			if (m_current != other.m_current)
				return false;

			if (m_priority != other.m_priority)
				return false;

			if (other.m_map.size () != m_map.size ()
					|| !other.m_map.size ()
					|| !m_map.size ())
				return false;

			for (MapType::const_iterator other_itr = other.m_map.begin (),
					itr = m_map.begin (), other_e = other.m_map.end ();
					other_itr != other_e ; ++other_itr, ++itr)
			{
				if (!std::equal (other_itr->begin (), other_itr->end (), itr->begin ()))
					return false;
			}

			return true;
		}

		bool MapData::operator!= (const MapData& other) const
		{
			return !(other == *this);
		}

		///

		MapData PriorityMap::inverse (const MapData& data)
		{
			const MapType& map = data.m_map;
			MapData newData;
			MapType& newMap = newData.m_map;

			newMap.resize (map.size ());

			MapType::const_iterator map_i = map.begin ();
			for (MapType::iterator new_i = newMap.begin (),
					new_e = newMap.end ();
					new_i != new_e; ++new_i, ++map_i)
			{
				new_i->resize (map_i->size ());
				std::reverse_copy (map_i->begin (), map_i->end (), new_i->begin ());
			}

			newData.m_priority = data.m_priority;
			newData.m_current = {static_cast<int> (map.front ().size () - 1 - data.m_current.x ()),
					data.m_current.y ()};

			return newData;
		}

		MapData PriorityMap::rotate (const MapData& data)
		{
			const MapType& map = data.m_map;
			MapData newData;
			MapType& newMap = newData.m_map;

			newMap.resize (map.front ().size ());
			std::for_each (newMap.begin (), newMap.end (), [&map] (MapLine& line) {
				line.resize (map.size ());
			});

			for (int i = 0, max_i = newMap.size (), j, max_j = map.size (); i != max_i; ++i) //y
			{
				for (j = 0; j != max_j; ++j) //x
					newMap[i][j] = map[max_j - 1 - j][i];
			}

			newData.m_priority = data.m_priority;
			newData.m_current = {static_cast<int> (map.size () - 1 - data.m_current.y ()),
					data.m_current.x ()};

			return newData;
		}

		PriorityMap::PriorityMap ()
			: m_priorityMap (PRIORITY_MAP)
		{
			for (const MapData& data : PRIORITY_MAP)
			{
				const MapData& invertedData = inverse (data);
				m_priorityMap.push_back (invertedData);

				MapData newData = data;
				for (int i = 0; i < 3; ++i)
				{
					newData = rotate (newData);
					m_priorityMap.push_back (newData);
					const MapData& invertedMap = inverse (newData);
					m_priorityMap.push_back (invertedMap);
				}
			}
		}

		PriorityMap& PriorityMap::instance ()
		{
			static PriorityMap obj;
			return obj;
		}

		const std::list<MapData>& PriorityMap::priorityMap ()
		{
			return m_priorityMap;
		}
	}
}<|endoftext|>


<commit_before>

/// Wifi not associated to access point: continuous short blinks.
#define WIFI_BLINK_NOTASSOCIATED  0b1010
/// Waiting for IP address: double short blink, pause, double short blink, ...
#define WIFI_BLINK_ASSOC_NOIP  0b101000
/// Connecting to hub: long blinks
#define WIFI_BLINK_CONNECTING  0b1100

extern "C" {
/// Name of wifi accesspoint to connect to.
extern char WIFI_SSID[];
/// Password of wifi connection. If empty, use no encryption.
extern char WIFI_PASS[];
/// Hostname at which the OpenLCB hub is at.
extern char WIFI_HUB_HOSTNAME[];
/// Port number of the OpenLCB hub.
extern int WIFI_HUB_PORT;
}
<commit_msg>Adds a blinker for when the wifi connection has failed.<commit_after>

/// Wifi not associated to access point: continuous short blinks.
#define WIFI_BLINK_NOTASSOCIATED  0b1010
/// Waiting for IP address: double short blink, pause, double short blink, ...
#define WIFI_BLINK_ASSOC_NOIP  0b101000
/// Connecting to hub: long blinks
#define WIFI_BLINK_CONNECTING  0b1100
/// Connecting to hub: long blinks
#define WIFI_BLINK_FAILED  0b10101100

extern "C" {
/// Name of wifi accesspoint to connect to.
extern char WIFI_SSID[];
/// Password of wifi connection. If empty, use no encryption.
extern char WIFI_PASS[];
/// Hostname at which the OpenLCB hub is at.
extern char WIFI_HUB_HOSTNAME[];
/// Port number of the OpenLCB hub.
extern int WIFI_HUB_PORT;
}
<|endoftext|>