<commit_before>/** Copyright (C) 2013 David Braam - Released under terms of the AGPLv3 License */
#include <cmath> // std::ceil

#include "skin.h"
#include "utils/math.h"
#include "utils/polygonUtils.h"

#define MIN_AREA_SIZE (0.4 * 0.4)

namespace cura
{

void generateSkins(int layerNr, SliceMeshStorage& mesh, int downSkinCount, int upSkinCount, int wall_line_count, int innermost_wall_line_width, int insetCount, bool no_small_gaps_heuristic)
{
    generateSkinAreas(layerNr, mesh, innermost_wall_line_width, downSkinCount, upSkinCount, wall_line_count, no_small_gaps_heuristic);

    SliceLayer* layer = &mesh.layers[layerNr];
    for(unsigned int partNr=0; partNr<layer->parts.size(); partNr++)
    {
        SliceLayerPart* part = &layer->parts[partNr];
        generateSkinInsets(part, innermost_wall_line_width, insetCount);
    }
}

void generateSkinAreas(int layer_nr, SliceMeshStorage& mesh, const int innermost_wall_line_width, int downSkinCount, int upSkinCount, int wall_line_count, bool no_small_gaps_heuristic)
{
    SliceLayer& layer = mesh.layers[layer_nr];

    if (downSkinCount == 0 && upSkinCount == 0)
    {
        return;
    }

    for(unsigned int partNr = 0; partNr < layer.parts.size(); partNr++)
    {
        SliceLayerPart& part = layer.parts[partNr];

        if (int(part.insets.size()) < wall_line_count)
        {
            continue; // the last wall is not present, the part should only get inter perimeter gaps, but no skin.
        }

        Polygons upskin = part.insets.back().offset(-innermost_wall_line_width / 2);
        Polygons downskin = (downSkinCount == 0) ? Polygons() : upskin;
        if (upSkinCount == 0) upskin = Polygons();

        auto getInsidePolygons = [&part, wall_line_count](SliceLayer& layer2)
            {
                Polygons result;
                for(SliceLayerPart& part2 : layer2.parts)
                {
                    if (part.boundaryBox.hit(part2.boundaryBox))
                    {
                        unsigned int wall_idx = std::max(0, std::min(wall_line_count, (int) part2.insets.size()) - 1);
                        result.add(part2.insets[wall_idx]);
                    }
                }
                return result;
            };

        if (no_small_gaps_heuristic)
        {
            if (static_cast<int>(layer_nr - downSkinCount) >= 0)
            {
                downskin = downskin.difference(getInsidePolygons(mesh.layers[layer_nr - downSkinCount])); // skin overlaps with the walls
            }

            if (static_cast<int>(layer_nr + upSkinCount) < static_cast<int>(mesh.layers.size()))
            {
                upskin = upskin.difference(getInsidePolygons(mesh.layers[layer_nr + upSkinCount])); // skin overlaps with the walls
            }
        }
        else
        {
            if (layer_nr >= downSkinCount && downSkinCount > 0)
            {
                Polygons not_air = getInsidePolygons(mesh.layers[layer_nr - 1]);
                for (int downskin_layer_nr = layer_nr - downSkinCount; downskin_layer_nr < layer_nr - 1; downskin_layer_nr++)
                {
                    not_air = not_air.intersection(getInsidePolygons(mesh.layers[downskin_layer_nr]));
                }
                downskin = downskin.difference(not_air); // skin overlaps with the walls
            }

            if (layer_nr < static_cast<int>(mesh.layers.size()) - 1 - upSkinCount && upSkinCount > 0)
            {
                Polygons not_air = getInsidePolygons(mesh.layers[layer_nr + 1]);
                for (int upskin_layer_nr = layer_nr + 2; upskin_layer_nr < layer_nr + upSkinCount + 1; upskin_layer_nr++)
                {
                    not_air = not_air.intersection(getInsidePolygons(mesh.layers[upskin_layer_nr]));
                }
                upskin = upskin.difference(not_air); // skin overlaps with the walls
            }
        }

        Polygons skin = upskin.unionPolygons(downskin);

        skin.removeSmallAreas(MIN_AREA_SIZE);

        for (PolygonsPart& skin_area_part : skin.splitIntoParts())
        {
            part.skin_parts.emplace_back();
            part.skin_parts.back().outline = skin_area_part;
        }
    }
}

void generateSkinInsets(SliceLayerPart* part, const int wall_line_width, int insetCount)
{
    if (insetCount == 0)
    {
        return;
    }

    for (SkinPart& skin_part : part->skin_parts)
    {
        for(int i=0; i<insetCount; i++)
        {
            skin_part.insets.push_back(Polygons());
            if (i == 0)
            {
                skin_part.insets[0] = skin_part.outline.offset(-wall_line_width / 2);
            }
            else
            {
                skin_part.insets[i] = skin_part.insets[i - 1].offset(-wall_line_width);
            }

            // optimize polygons: remove unnecessary verts
            skin_part.insets[i].simplify();
            if (skin_part.insets[i].size() < 1)
            {
                skin_part.insets.pop_back();
                break;
            }
        }
    }
}

void generateInfill(int layerNr, SliceMeshStorage& mesh, const int innermost_wall_line_width, int infill_skin_overlap, int wall_line_count)
{
    SliceLayer& layer = mesh.layers[layerNr];

    for(SliceLayerPart& part : layer.parts)
    {
        if (int(part.insets.size()) < wall_line_count)
        {
            continue; // the last wall is not present, the part should only get inter preimeter gaps, but no infill.
        }
        Polygons infill = part.insets.back().offset(-innermost_wall_line_width / 2 - infill_skin_overlap);

        for(SliceLayerPart& part2 : layer.parts)
        {
            if (part.boundaryBox.hit(part2.boundaryBox))
            {
                for(SkinPart& skin_part : part2.skin_parts)
                {
                    infill = infill.difference(skin_part.outline);
                }
            }
        }
        infill.removeSmallAreas(MIN_AREA_SIZE);

        part.infill_area = infill.offset(infill_skin_overlap);
    }
}

void SkinInfillAreaComputation::generateGradualInfill(SliceMeshStorage& mesh, unsigned int gradual_infill_step_height, unsigned int max_infill_steps)
{
    // no early-out for this function; it needs to initialize the [infill_area_per_combine_per_density]
    float layer_skip_count = 8; // skip every so many layers as to ignore small gaps in the model making computation more easy
    if (!mesh.getSettingBoolean("skin_no_small_gaps_heuristic"))
    {
        layer_skip_count = 1;
    }
    unsigned int gradual_infill_step_layer_count = round_divide(gradual_infill_step_height, mesh.getSettingInMicrons("layer_height")); // The difference in layer count between consecutive density infill areas

    // make gradual_infill_step_height divisable by layer_skip_count
    float n_skip_steps_per_gradual_step = std::max(1.0f, std::ceil(gradual_infill_step_layer_count / layer_skip_count)); // only decrease layer_skip_count to make it a divisor of gradual_infill_step_layer_count
    layer_skip_count = gradual_infill_step_layer_count / n_skip_steps_per_gradual_step;

    size_t min_layer = mesh.getSettingAsCount("bottom_layers");
    size_t max_layer = mesh.layers.size() - 1 - mesh.getSettingAsCount("top_layers");

    for (size_t layer_idx = 0; layer_idx < mesh.layers.size(); layer_idx++)
    { // loop also over layers which don't contain infill cause of bottom_ and top_layer to initialize their infill_area_per_combine_per_density
        SliceLayer& layer = mesh.layers[layer_idx];

        for (SliceLayerPart& part : layer.parts)
        {
            assert(part.infill_area_per_combine_per_density.size() == 0 && "infill_area_per_combine_per_density is supposed to be uninitialized");

            const Polygons& infill_area = part.getOwnInfillArea();

            if (infill_area.size() == 0 || layer_idx < min_layer || layer_idx > max_layer)
            { // initialize infill_area_per_combine_per_density empty
                part.infill_area_per_combine_per_density.emplace_back(); // create a new infill_area_per_combine
                part.infill_area_per_combine_per_density.back().emplace_back(); // put empty infill area in the newly constructed infill_area_per_combine
                // note: no need to copy part.infill_area, cause it's the empty vector anyway
                continue;
            }
            Polygons less_dense_infill = infill_area; // one step less dense with each infill_step
            for (unsigned int infill_step = 0; infill_step < max_infill_steps; infill_step++)
            {
                size_t min_layer = layer_idx + infill_step * gradual_infill_step_layer_count + layer_skip_count;
                size_t max_layer = layer_idx + (infill_step + 1) * gradual_infill_step_layer_count;

                for (float upper_layer_idx = min_layer; static_cast<unsigned int>(upper_layer_idx) <= max_layer; upper_layer_idx += layer_skip_count)
                {
                    if (static_cast<unsigned int>(upper_layer_idx) >= mesh.layers.size())
                    {
                        less_dense_infill.clear();
                        break;
                    }
                    SliceLayer& upper_layer = mesh.layers[static_cast<unsigned int>(upper_layer_idx)];
                    Polygons relevent_upper_polygons;
                    for (SliceLayerPart& upper_layer_part : upper_layer.parts)
                    {
                        if (!upper_layer_part.boundaryBox.hit(part.boundaryBox))
                        {
                            continue;
                        }
                        relevent_upper_polygons.add(upper_layer_part.getOwnInfillArea());
                    }
                    less_dense_infill = less_dense_infill.intersection(relevent_upper_polygons);
                }
                if (less_dense_infill.size() == 0)
                {
                    break;
                }
                // add new infill_area_per_combine for the current density
                part.infill_area_per_combine_per_density.emplace_back();
                std::vector<Polygons>& infill_area_per_combine_current_density = part.infill_area_per_combine_per_density.back();
                const Polygons more_dense_infill = infill_area.difference(less_dense_infill);
                infill_area_per_combine_current_density.push_back(more_dense_infill);

                if (less_dense_infill.size() == 0)
                {
                    break;
                }
            }
            part.infill_area_per_combine_per_density.emplace_back();
            std::vector<Polygons>& infill_area_per_combine_current_density = part.infill_area_per_combine_per_density.back();
            infill_area_per_combine_current_density.push_back(infill_area);
            part.infill_area_own = nullptr; // clear infill_area_own, it's not needed any more.
            assert(part.infill_area_per_combine_per_density.size() != 0 && "infill_area_per_combine_per_density is now initialized");
        }
    }
}

void combineInfillLayers(SliceMeshStorage& mesh, unsigned int amount)
{
    if (mesh.layers.empty() || mesh.layers.size() - 1 < static_cast<size_t>(mesh.getSettingAsCount("top_layers")) || mesh.getSettingAsCount("infill_line_distance") <= 0) //No infill is even generated.
    {
        return;
    }
    if(amount <= 1) //If we must combine 1 layer, nothing needs to be combined. Combining 0 layers is invalid.
    {
        return;
    }
    /* We need to round down the layer index we start at to the nearest
    divisible index. Otherwise we get some parts that have infill at divisible
    layers and some at non-divisible layers. Those layers would then miss each
    other. */
    size_t min_layer = mesh.getSettingAsCount("bottom_layers") + amount - 1;
    min_layer -= min_layer % amount; //Round upwards to the nearest layer divisible by infill_sparse_combine.
    size_t max_layer = mesh.layers.size() - 1 - mesh.getSettingAsCount("top_layers");
    max_layer -= max_layer % amount; //Round downwards to the nearest layer divisible by infill_sparse_combine.
    for(size_t layer_idx = min_layer;layer_idx <= max_layer;layer_idx += amount) //Skip every few layers, but extrude more.
    {
        SliceLayer* layer = &mesh.layers[layer_idx];
        for(unsigned int combine_count_here = 1; combine_count_here < amount; combine_count_here++)
        {
            if(layer_idx < combine_count_here)
            {
                break;
            }

            size_t lower_layer_idx = layer_idx - combine_count_here;
            if (lower_layer_idx < min_layer)
            {
                break;
            }
            SliceLayer* lower_layer = &mesh.layers[lower_layer_idx];
            for (SliceLayerPart& part : layer->parts)
            {
                for (unsigned int density_idx = 0; density_idx < part.infill_area_per_combine_per_density.size(); density_idx++)
                { // go over each density of gradual infill (these density areas overlap!)
                    std::vector<Polygons>& infill_area_per_combine = part.infill_area_per_combine_per_density[density_idx];
                    Polygons result;
                    for (SliceLayerPart& lower_layer_part : lower_layer->parts)
                    {
                        if (part.boundaryBox.hit(lower_layer_part.boundaryBox))
                        {

                            Polygons intersection = infill_area_per_combine[combine_count_here - 1].intersection(lower_layer_part.infill_area).offset(-200).offset(200);
                            result.add(intersection); // add area to be thickened
                            infill_area_per_combine[combine_count_here - 1] = infill_area_per_combine[combine_count_here - 1].difference(intersection); // remove thickened area from less thick layer here
                            if (density_idx < lower_layer_part.infill_area_per_combine_per_density.size())
                            { // only remove from *same density* areas on layer below
                                // If there are no same density areas, then it's ok to print them anyway
                                // Don't remove other density areas
                                unsigned int lower_density_idx = density_idx;
                                std::vector<Polygons>& lower_infill_area_per_combine = lower_layer_part.infill_area_per_combine_per_density[lower_density_idx];
                                lower_infill_area_per_combine[0] = lower_infill_area_per_combine[0].difference(intersection); // remove thickened area from lower (thickened) layer
                            }
                        }
                    }

                    infill_area_per_combine.push_back(result);
                }
            }
        }
    }
}

}//namespace cura
<commit_msg>fix: concentric infill doesn't oscilate because of alternate extra wall (CURA-2772)<commit_after>/** Copyright (C) 2013 David Braam - Released under terms of the AGPLv3 License */
#include <cmath> // std::ceil

#include "skin.h"
#include "utils/math.h"
#include "utils/polygonUtils.h"

#define MIN_AREA_SIZE (0.4 * 0.4)

namespace cura
{

void generateSkins(int layerNr, SliceMeshStorage& mesh, int downSkinCount, int upSkinCount, int wall_line_count, int innermost_wall_line_width, int insetCount, bool no_small_gaps_heuristic)
{
    generateSkinAreas(layerNr, mesh, innermost_wall_line_width, downSkinCount, upSkinCount, wall_line_count, no_small_gaps_heuristic);

    SliceLayer* layer = &mesh.layers[layerNr];
    for(unsigned int partNr=0; partNr<layer->parts.size(); partNr++)
    {
        SliceLayerPart* part = &layer->parts[partNr];
        generateSkinInsets(part, innermost_wall_line_width, insetCount);
    }
}

void generateSkinAreas(int layer_nr, SliceMeshStorage& mesh, const int innermost_wall_line_width, int downSkinCount, int upSkinCount, int wall_line_count, bool no_small_gaps_heuristic)
{
    SliceLayer& layer = mesh.layers[layer_nr];

    if (downSkinCount == 0 && upSkinCount == 0)
    {
        return;
    }

    for(unsigned int partNr = 0; partNr < layer.parts.size(); partNr++)
    {
        SliceLayerPart& part = layer.parts[partNr];

        if (int(part.insets.size()) < wall_line_count)
        {
            continue; // the last wall is not present, the part should only get inter perimeter gaps, but no skin.
        }

        Polygons upskin = part.insets.back().offset(-innermost_wall_line_width / 2);
        Polygons downskin = (downSkinCount == 0) ? Polygons() : upskin;
        if (upSkinCount == 0) upskin = Polygons();

        auto getInsidePolygons = [&part, wall_line_count](SliceLayer& layer2)
            {
                Polygons result;
                for(SliceLayerPart& part2 : layer2.parts)
                {
                    if (part.boundaryBox.hit(part2.boundaryBox))
                    {
                        unsigned int wall_idx = std::max(0, std::min(wall_line_count, (int) part2.insets.size()) - 1);
                        result.add(part2.insets[wall_idx]);
                    }
                }
                return result;
            };

        if (no_small_gaps_heuristic)
        {
            if (static_cast<int>(layer_nr - downSkinCount) >= 0)
            {
                downskin = downskin.difference(getInsidePolygons(mesh.layers[layer_nr - downSkinCount])); // skin overlaps with the walls
            }

            if (static_cast<int>(layer_nr + upSkinCount) < static_cast<int>(mesh.layers.size()))
            {
                upskin = upskin.difference(getInsidePolygons(mesh.layers[layer_nr + upSkinCount])); // skin overlaps with the walls
            }
        }
        else
        {
            if (layer_nr >= downSkinCount && downSkinCount > 0)
            {
                Polygons not_air = getInsidePolygons(mesh.layers[layer_nr - 1]);
                for (int downskin_layer_nr = layer_nr - downSkinCount; downskin_layer_nr < layer_nr - 1; downskin_layer_nr++)
                {
                    not_air = not_air.intersection(getInsidePolygons(mesh.layers[downskin_layer_nr]));
                }
                downskin = downskin.difference(not_air); // skin overlaps with the walls
            }

            if (layer_nr < static_cast<int>(mesh.layers.size()) - 1 - upSkinCount && upSkinCount > 0)
            {
                Polygons not_air = getInsidePolygons(mesh.layers[layer_nr + 1]);
                for (int upskin_layer_nr = layer_nr + 2; upskin_layer_nr < layer_nr + upSkinCount + 1; upskin_layer_nr++)
                {
                    not_air = not_air.intersection(getInsidePolygons(mesh.layers[upskin_layer_nr]));
                }
                upskin = upskin.difference(not_air); // skin overlaps with the walls
            }
        }

        Polygons skin = upskin.unionPolygons(downskin);

        skin.removeSmallAreas(MIN_AREA_SIZE);

        for (PolygonsPart& skin_area_part : skin.splitIntoParts())
        {
            part.skin_parts.emplace_back();
            part.skin_parts.back().outline = skin_area_part;
        }
    }
}

void generateSkinInsets(SliceLayerPart* part, const int wall_line_width, int insetCount)
{
    if (insetCount == 0)
    {
        return;
    }

    for (SkinPart& skin_part : part->skin_parts)
    {
        for(int i=0; i<insetCount; i++)
        {
            skin_part.insets.push_back(Polygons());
            if (i == 0)
            {
                skin_part.insets[0] = skin_part.outline.offset(-wall_line_width / 2);
            }
            else
            {
                skin_part.insets[i] = skin_part.insets[i - 1].offset(-wall_line_width);
            }

            // optimize polygons: remove unnecessary verts
            skin_part.insets[i].simplify();
            if (skin_part.insets[i].size() < 1)
            {
                skin_part.insets.pop_back();
                break;
            }
        }
    }
}

void generateInfill(int layerNr, SliceMeshStorage& mesh, const int innermost_wall_line_width, int infill_skin_overlap, int wall_line_count)
{
    SliceLayer& layer = mesh.layers[layerNr];

    int extra_offset = 0;
    EFillMethod fill_pattern = mesh.getSettingAsFillMethod("infill_pattern");
    if ((fill_pattern == EFillMethod::CONCENTRIC || fill_pattern == EFillMethod::CONCENTRIC_3D)
        && layerNr % 2 == 0
        && mesh.getSettingInMicrons("infill_line_distance") > mesh.getSettingInMicrons("infill_line_width") * 2)
    {
        extra_offset = -innermost_wall_line_width;
    }

    for(SliceLayerPart& part : layer.parts)
    {
        if (int(part.insets.size()) < wall_line_count)
        {
            continue; // the last wall is not present, the part should only get inter preimeter gaps, but no infill.
        }
        Polygons infill = part.insets.back().offset(extra_offset - innermost_wall_line_width / 2 - infill_skin_overlap);

        for(SliceLayerPart& part2 : layer.parts)
        {
            if (part.boundaryBox.hit(part2.boundaryBox))
            {
                for(SkinPart& skin_part : part2.skin_parts)
                {
                    infill = infill.difference(skin_part.outline);
                }
            }
        }
        infill.removeSmallAreas(MIN_AREA_SIZE);

        part.infill_area = infill.offset(infill_skin_overlap);
    }
}

void SkinInfillAreaComputation::generateGradualInfill(SliceMeshStorage& mesh, unsigned int gradual_infill_step_height, unsigned int max_infill_steps)
{
    // no early-out for this function; it needs to initialize the [infill_area_per_combine_per_density]
    float layer_skip_count = 8; // skip every so many layers as to ignore small gaps in the model making computation more easy
    if (!mesh.getSettingBoolean("skin_no_small_gaps_heuristic"))
    {
        layer_skip_count = 1;
    }
    unsigned int gradual_infill_step_layer_count = round_divide(gradual_infill_step_height, mesh.getSettingInMicrons("layer_height")); // The difference in layer count between consecutive density infill areas

    // make gradual_infill_step_height divisable by layer_skip_count
    float n_skip_steps_per_gradual_step = std::max(1.0f, std::ceil(gradual_infill_step_layer_count / layer_skip_count)); // only decrease layer_skip_count to make it a divisor of gradual_infill_step_layer_count
    layer_skip_count = gradual_infill_step_layer_count / n_skip_steps_per_gradual_step;

    size_t min_layer = mesh.getSettingAsCount("bottom_layers");
    size_t max_layer = mesh.layers.size() - 1 - mesh.getSettingAsCount("top_layers");

    for (size_t layer_idx = 0; layer_idx < mesh.layers.size(); layer_idx++)
    { // loop also over layers which don't contain infill cause of bottom_ and top_layer to initialize their infill_area_per_combine_per_density
        SliceLayer& layer = mesh.layers[layer_idx];

        for (SliceLayerPart& part : layer.parts)
        {
            assert(part.infill_area_per_combine_per_density.size() == 0 && "infill_area_per_combine_per_density is supposed to be uninitialized");

            const Polygons& infill_area = part.getOwnInfillArea();

            if (infill_area.size() == 0 || layer_idx < min_layer || layer_idx > max_layer)
            { // initialize infill_area_per_combine_per_density empty
                part.infill_area_per_combine_per_density.emplace_back(); // create a new infill_area_per_combine
                part.infill_area_per_combine_per_density.back().emplace_back(); // put empty infill area in the newly constructed infill_area_per_combine
                // note: no need to copy part.infill_area, cause it's the empty vector anyway
                continue;
            }
            Polygons less_dense_infill = infill_area; // one step less dense with each infill_step
            for (unsigned int infill_step = 0; infill_step < max_infill_steps; infill_step++)
            {
                size_t min_layer = layer_idx + infill_step * gradual_infill_step_layer_count + layer_skip_count;
                size_t max_layer = layer_idx + (infill_step + 1) * gradual_infill_step_layer_count;

                for (float upper_layer_idx = min_layer; static_cast<unsigned int>(upper_layer_idx) <= max_layer; upper_layer_idx += layer_skip_count)
                {
                    if (static_cast<unsigned int>(upper_layer_idx) >= mesh.layers.size())
                    {
                        less_dense_infill.clear();
                        break;
                    }
                    SliceLayer& upper_layer = mesh.layers[static_cast<unsigned int>(upper_layer_idx)];
                    Polygons relevent_upper_polygons;
                    for (SliceLayerPart& upper_layer_part : upper_layer.parts)
                    {
                        if (!upper_layer_part.boundaryBox.hit(part.boundaryBox))
                        {
                            continue;
                        }
                        relevent_upper_polygons.add(upper_layer_part.getOwnInfillArea());
                    }
                    less_dense_infill = less_dense_infill.intersection(relevent_upper_polygons);
                }
                if (less_dense_infill.size() == 0)
                {
                    break;
                }
                // add new infill_area_per_combine for the current density
                part.infill_area_per_combine_per_density.emplace_back();
                std::vector<Polygons>& infill_area_per_combine_current_density = part.infill_area_per_combine_per_density.back();
                const Polygons more_dense_infill = infill_area.difference(less_dense_infill);
                infill_area_per_combine_current_density.push_back(more_dense_infill);

                if (less_dense_infill.size() == 0)
                {
                    break;
                }
            }
            part.infill_area_per_combine_per_density.emplace_back();
            std::vector<Polygons>& infill_area_per_combine_current_density = part.infill_area_per_combine_per_density.back();
            infill_area_per_combine_current_density.push_back(infill_area);
            part.infill_area_own = nullptr; // clear infill_area_own, it's not needed any more.
            assert(part.infill_area_per_combine_per_density.size() != 0 && "infill_area_per_combine_per_density is now initialized");
        }
    }
}

void combineInfillLayers(SliceMeshStorage& mesh, unsigned int amount)
{
    if (mesh.layers.empty() || mesh.layers.size() - 1 < static_cast<size_t>(mesh.getSettingAsCount("top_layers")) || mesh.getSettingAsCount("infill_line_distance") <= 0) //No infill is even generated.
    {
        return;
    }
    if(amount <= 1) //If we must combine 1 layer, nothing needs to be combined. Combining 0 layers is invalid.
    {
        return;
    }
    /* We need to round down the layer index we start at to the nearest
    divisible index. Otherwise we get some parts that have infill at divisible
    layers and some at non-divisible layers. Those layers would then miss each
    other. */
    size_t min_layer = mesh.getSettingAsCount("bottom_layers") + amount - 1;
    min_layer -= min_layer % amount; //Round upwards to the nearest layer divisible by infill_sparse_combine.
    size_t max_layer = mesh.layers.size() - 1 - mesh.getSettingAsCount("top_layers");
    max_layer -= max_layer % amount; //Round downwards to the nearest layer divisible by infill_sparse_combine.
    for(size_t layer_idx = min_layer;layer_idx <= max_layer;layer_idx += amount) //Skip every few layers, but extrude more.
    {
        SliceLayer* layer = &mesh.layers[layer_idx];
        for(unsigned int combine_count_here = 1; combine_count_here < amount; combine_count_here++)
        {
            if(layer_idx < combine_count_here)
            {
                break;
            }

            size_t lower_layer_idx = layer_idx - combine_count_here;
            if (lower_layer_idx < min_layer)
            {
                break;
            }
            SliceLayer* lower_layer = &mesh.layers[lower_layer_idx];
            for (SliceLayerPart& part : layer->parts)
            {
                for (unsigned int density_idx = 0; density_idx < part.infill_area_per_combine_per_density.size(); density_idx++)
                { // go over each density of gradual infill (these density areas overlap!)
                    std::vector<Polygons>& infill_area_per_combine = part.infill_area_per_combine_per_density[density_idx];
                    Polygons result;
                    for (SliceLayerPart& lower_layer_part : lower_layer->parts)
                    {
                        if (part.boundaryBox.hit(lower_layer_part.boundaryBox))
                        {

                            Polygons intersection = infill_area_per_combine[combine_count_here - 1].intersection(lower_layer_part.infill_area).offset(-200).offset(200);
                            result.add(intersection); // add area to be thickened
                            infill_area_per_combine[combine_count_here - 1] = infill_area_per_combine[combine_count_here - 1].difference(intersection); // remove thickened area from less thick layer here
                            if (density_idx < lower_layer_part.infill_area_per_combine_per_density.size())
                            { // only remove from *same density* areas on layer below
                                // If there are no same density areas, then it's ok to print them anyway
                                // Don't remove other density areas
                                unsigned int lower_density_idx = density_idx;
                                std::vector<Polygons>& lower_infill_area_per_combine = lower_layer_part.infill_area_per_combine_per_density[lower_density_idx];
                                lower_infill_area_per_combine[0] = lower_infill_area_per_combine[0].difference(intersection); // remove thickened area from lower (thickened) layer
                            }
                        }
                    }

                    infill_area_per_combine.push_back(result);
                }
            }
        }
    }
}

}//namespace cura
<|endoftext|>


<commit_before>#include <sys/types.h>
#include <sys/socket.h>
#include <string>
#include <sstream>
#include <tr1/cstdint>
#include <cstddef>
#include <cstdlib>
#include <cstdio>
#include <unistd.h>
#include <arpa/inet.h>
#include <netinet/tcp.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include "socket.h"

using std::string;

/*
 * Find out the hostname and port number of the remote end of a connection.
 */
static inline
bool load_info(int sock, string& name, uint16_t& port)
{
	sockaddr_in addr;

	// Load info about other end (the peer)
	socklen_t len = sizeof(addr);
	if (getpeername(sock, reinterpret_cast<sockaddr*>(&addr), &len) == -1) {
		return false;
	}

	// Get hold of the hostname
	char nname[INET_ADDRSTRLEN];
	if (getnameinfo(reinterpret_cast<sockaddr*>(&addr), (socklen_t) sizeof(addr), nname, sizeof(nname), NULL, 0, NI_NUMERICHOST) != 0) {
		return false;
	}

	name = string(nname);

	// Get the port number
	port = ntohs(addr.sin_port);

	return true;
}

/*
 * Allocate and fill a struct addrinfo.
 */
bool Sock::load_addrinfo(addrinfo*& info, const char* host, uint16_t port)
{
	addrinfo hints;

	memset(&hints, 0, sizeof(hints));
	hints.ai_family = AF_INET;
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_flags = host == NULL ? AI_PASSIVE : 0;

	std::ostringstream converter;
	converter << port; // convert uint16_t to string

	return getaddrinfo(host, converter.str().c_str(), &hints, &info) == 0;
}

/*
 * Try to bind a socket descriptor to a local port.
 */
static inline
bool bind_port(int sock, uint16_t port)
{
	sockaddr_in addr;

	memset(&addr, 0, sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_addr.s_addr = INADDR_ANY;
	addr.sin_port = htons(port);

	// Set the port to quickly reusable, so subsequent connections can quickly
	// reuse the port
	int flag = 1;
	setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag));

	return bind(sock, reinterpret_cast<sockaddr*>(&addr), sizeof(addr));
}

static void close_sock(int* s)
{
	if (*s != -1) {
		::close(*s);
	}

	delete s;
}

/*
 * Give control of a socket descriptor to an instance of socket.
 */
Sock::Sock(int descriptor) :
	sock( new int(descriptor), &close_sock ),
	fd(descriptor)
{
	// Set socket to non-blocking
	int status = fcntl(*sock, F_GETFL, 0);
	fcntl(*sock, F_SETFL, status | O_NONBLOCK);
}

/*
 * Check if the socket descriptor is still valid.
 */
bool Sock::alive()
{
	if (*sock == -1 || (fcntl(*sock, F_GETFL) == -1 && errno == EBADF)) {
		fprintf(stderr, "not alive\n");
		*sock = -1;
		return false;
	}

	return true;
}

/*
 * Create a TCP connection to a remote host.
 */
Sock* Sock::create(const char* host, uint16_t remote_port, uint16_t local_port)
{
	addrinfo *ptr, *info = NULL;

	// Find info about remote host
	if (!load_addrinfo(info, host, remote_port)) {
		if (info != NULL) {
			freeaddrinfo(info);
		}

		return NULL;
	}

	int sock = -1;
	for (ptr = info; ptr != NULL; ptr = ptr->ai_next) {

		// Try to create a socket descriptor
		if ((sock = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol)) == -1) {
			continue;
		}

		// Turn off Nagle's algorithm
		int flag = 1;
		setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(flag));

		// If a local port is given, try to bind to that port
		if (local_port > 0) {
			bind_port(sock, local_port);
		}

		// Try to connect to remote host
		if (connect(sock, ptr->ai_addr, ptr->ai_addrlen) != -1) {
			break;
		}

		// Failed, close the socket and try again
		close(sock);
	}

	if (info) {
		freeaddrinfo(info);
	}

	// No suitable connection could be made
	if (ptr == NULL) {
		return NULL;
	}

	return new Sock(sock);
}

/*
 * Create a TCP connection to a remote host using a random outgoing port.
 */
Sock* Sock::create(const char* hostname, uint16_t port)
{
	return create(hostname, port, 0);
}

/*
 * Read data from the connection.
 */
ssize_t Sock::read(char* buf, size_t len)
{
	if (*sock != -1) {
		ssize_t bytes = recv(*sock, buf, len, MSG_DONTWAIT);

		if (bytes == -1 && (errno == EWOULDBLOCK || errno == EAGAIN)) {
			return 0;
		} else if (bytes == 0) {
			// Remote end closed the connection
			close(*sock);
			*sock = -1;
			return -1;
		} else if (bytes == -1) {
			// TODO: Create a list of return values for various errnos
			close(*sock);
			*sock = -1;
			return -2;
		}

		return bytes;
	}

	return -1;
}

/*
 * Write data to a connection
 */
ssize_t Sock::write(const char* buf, size_t len)
{
	if (*sock != -1) {
		ssize_t bytes = send(*sock, buf, len, MSG_DONTWAIT);

		if (bytes == -1 && (errno == EWOULDBLOCK || errno == EAGAIN)) {
			return 0;
		} else if (bytes == -1) {
			close(*sock);
			*sock = -1;

			// TODO: Add a list of return values for various errnos
			switch (errno) {
				case ECONNRESET:
					return -2;
			}

			return -1;
		}

		return bytes;
	}

	return -1;
}

/*
 * Get remote port.
 */
uint16_t Sock::port()
{
	string name;
	uint16_t port = 0;

	if (*sock != -1) {
		load_info(*sock, name, port);
	}

	return port;
}

/*
 * Get remote hostname.
 */
string Sock::host()
{
	string name;
	uint16_t port;

	if (*sock != -1) {
		load_info(*sock, name, port);
	}

	return name;
}

/*
 * Get the socket descriptor.
 */
int Sock::get_raw()
{
	return *sock;
}
<commit_msg>removed debug output<commit_after>#include <sys/types.h>
#include <sys/socket.h>
#include <string>
#include <sstream>
#include <tr1/cstdint>
#include <cstddef>
#include <cstdlib>
#include <cstdio>
#include <unistd.h>
#include <arpa/inet.h>
#include <netinet/tcp.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include "socket.h"

using std::string;

/*
 * Find out the hostname and port number of the remote end of a connection.
 */
static inline
bool load_info(int sock, string& name, uint16_t& port)
{
	sockaddr_in addr;

	// Load info about other end (the peer)
	socklen_t len = sizeof(addr);
	if (getpeername(sock, reinterpret_cast<sockaddr*>(&addr), &len) == -1) {
		return false;
	}

	// Get hold of the hostname
	char nname[INET_ADDRSTRLEN];
	if (getnameinfo(reinterpret_cast<sockaddr*>(&addr), (socklen_t) sizeof(addr), nname, sizeof(nname), NULL, 0, NI_NUMERICHOST) != 0) {
		return false;
	}

	name = string(nname);

	// Get the port number
	port = ntohs(addr.sin_port);

	return true;
}

/*
 * Allocate and fill a struct addrinfo.
 */
bool Sock::load_addrinfo(addrinfo*& info, const char* host, uint16_t port)
{
	addrinfo hints;

	memset(&hints, 0, sizeof(hints));
	hints.ai_family = AF_INET;
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_flags = host == NULL ? AI_PASSIVE : 0;

	std::ostringstream converter;
	converter << port; // convert uint16_t to string

	return getaddrinfo(host, converter.str().c_str(), &hints, &info) == 0;
}

/*
 * Try to bind a socket descriptor to a local port.
 */
static inline
bool bind_port(int sock, uint16_t port)
{
	sockaddr_in addr;

	memset(&addr, 0, sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_addr.s_addr = INADDR_ANY;
	addr.sin_port = htons(port);

	// Set the port to quickly reusable, so subsequent connections can quickly
	// reuse the port
	int flag = 1;
	setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag));

	return bind(sock, reinterpret_cast<sockaddr*>(&addr), sizeof(addr));
}

static void close_sock(int* s)
{
	if (*s != -1) {
		::close(*s);
	}

	delete s;
}

/*
 * Give control of a socket descriptor to an instance of socket.
 */
Sock::Sock(int descriptor) :
	sock( new int(descriptor), &close_sock ),
	fd(descriptor)
{
	// Set socket to non-blocking
	int status = fcntl(*sock, F_GETFL, 0);
	fcntl(*sock, F_SETFL, status | O_NONBLOCK);
}

/*
 * Check if the socket descriptor is still valid.
 */
bool Sock::alive()
{
	if (*sock == -1 || (fcntl(*sock, F_GETFL) == -1 && errno == EBADF)) {
		*sock = -1;
		return false;
	}

	return true;
}

/*
 * Create a TCP connection to a remote host.
 */
Sock* Sock::create(const char* host, uint16_t remote_port, uint16_t local_port)
{
	addrinfo *ptr, *info = NULL;

	// Find info about remote host
	if (!load_addrinfo(info, host, remote_port)) {
		if (info != NULL) {
			freeaddrinfo(info);
		}

		return NULL;
	}

	int sock = -1;
	for (ptr = info; ptr != NULL; ptr = ptr->ai_next) {

		// Try to create a socket descriptor
		if ((sock = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol)) == -1) {
			continue;
		}

		// Turn off Nagle's algorithm
		int flag = 1;
		setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(flag));

		// If a local port is given, try to bind to that port
		if (local_port > 0) {
			bind_port(sock, local_port);
		}

		// Try to connect to remote host
		if (connect(sock, ptr->ai_addr, ptr->ai_addrlen) != -1) {
			break;
		}

		// Failed, close the socket and try again
		close(sock);
	}

	if (info) {
		freeaddrinfo(info);
	}

	// No suitable connection could be made
	if (ptr == NULL) {
		return NULL;
	}

	return new Sock(sock);
}

/*
 * Create a TCP connection to a remote host using a random outgoing port.
 */
Sock* Sock::create(const char* hostname, uint16_t port)
{
	return create(hostname, port, 0);
}

/*
 * Read data from the connection.
 */
ssize_t Sock::read(char* buf, size_t len)
{
	if (*sock != -1) {
		ssize_t bytes = recv(*sock, buf, len, MSG_DONTWAIT);

		if (bytes == -1 && (errno == EWOULDBLOCK || errno == EAGAIN)) {
			return 0;
		} else if (bytes == 0) {
			// Remote end closed the connection
			close(*sock);
			*sock = -1;
			return -1;
		} else if (bytes == -1) {
			// TODO: Create a list of return values for various errnos
			close(*sock);
			*sock = -1;
			return -2;
		}

		return bytes;
	}

	return -1;
}

/*
 * Write data to a connection
 */
ssize_t Sock::write(const char* buf, size_t len)
{
	if (*sock != -1) {
		ssize_t bytes = send(*sock, buf, len, MSG_DONTWAIT);

		if (bytes == -1 && (errno == EWOULDBLOCK || errno == EAGAIN)) {
			return 0;
		} else if (bytes == -1) {
			close(*sock);
			*sock = -1;

			// TODO: Add a list of return values for various errnos
			switch (errno) {
				case ECONNRESET:
					return -2;
			}

			return -1;
		}

		return bytes;
	}

	return -1;
}

/*
 * Get remote port.
 */
uint16_t Sock::port()
{
	string name;
	uint16_t port = 0;

	if (*sock != -1) {
		load_info(*sock, name, port);
	}

	return port;
}

/*
 * Get remote hostname.
 */
string Sock::host()
{
	string name;
	uint16_t port;

	if (*sock != -1) {
		load_info(*sock, name, port);
	}

	return name;
}

/*
 * Get the socket descriptor.
 */
int Sock::get_raw()
{
	return *sock;
}
<|endoftext|>


<commit_before>#include "spaceship.h"
#include "camera.h"
#include "gun.h"

#include <iostream>

#define PI 3.14159265

Spaceship::Spaceship(sf::RenderWindow &w):
    window(w),
    direction{1, 0},
    coordinate{0,0},
    velocity{0, 0},
    maxSpeed(200.f),
    speed(0.f),
    acceleration(600),
    isThrusterOn(false)
{
    texture.loadFromFile("../spritesheet/player_ship.png");
    body = sf::Sprite(texture, {0,0,160,70});
    body.setScale(0.4f, 0.4f);
    body.setOrigin(80.f, 38.f);

    gun = Gun(texture, 5, 500.f);

    thrusterAnimation.setSpriteSheet(texture);
    thrusterAnimation.addFrame({0,70,160,70});
    thrusterAnimation.addFrame({160,70,160,70});

    thruster = AnimatedSprite(sf::seconds(0.09), true, false);
    thruster.setAnimation(thrusterAnimation);

    thruster.setScale(0.2f, 0.2f);
    thruster.setPosition(body.getPosition());
    thruster.setOrigin(80.f, 36.f);
}

void Spaceship::update(sf::Time elapsedTime) {
    if(sf::Keyboard::isKeyPressed(sf::Keyboard::X)) {
        gun.fire(elapsedTime, getGunPos(), getDirection());
    }
    if(sf::Keyboard::isKeyPressed(sf::Keyboard::Left)) {
        steerLeft();
    }
    if(sf::Keyboard::isKeyPressed(sf::Keyboard::Right)) {
        steerRight();
    }
    if(sf::Keyboard::isKeyPressed(sf::Keyboard::Up)) {
        accelerate(elapsedTime);
    }
    else {
        deccelerate(elapsedTime);
    }

    coordinate += velocity;
    velocity = direction * speed * elapsedTime.asSeconds();

    thruster.update(elapsedTime);
    gun.update(elapsedTime);
}

void Spaceship::draw(Camera &camera){

    body.setPosition(coordinate - camera.getCoordinate());

    thruster.setPosition(getEnginePos());
    thruster.setRotation(body.getRotation());

    window.draw(body);
    gun.draw(&window, &camera);

    if(isThrusterOn)
        window.draw(thruster);
}

void Spaceship::accelerate(sf::Time elapsedTime) {
    enableThrusters();
    if(speed < maxSpeed) {
        speed += acceleration * elapsedTime.asSeconds();
    }
}
void Spaceship::deccelerate(sf::Time elapsedTime) {
    disableThrusters();
    if(speed > 0.01f)
        speed *= 0.9f;
    else
        speed = 0.f;
}

void Spaceship::steerLeft() {
    body.rotate(-5);
    direction.x = cos(body.getRotation() * PI / 180);
    direction.y = sin(body.getRotation() * PI / 180);
    changeView();
}

void Spaceship::steerRight() {
    body.rotate(5);
    direction.x = cos(body.getRotation() * PI / 180);
    direction.y = sin(body.getRotation() * PI / 180);
    changeView();
}

void Spaceship::enableThrusters() {
    isThrusterOn = true;
    thruster.play(thrusterAnimation);
}

void Spaceship::disableThrusters() {
    isThrusterOn = false;
    thruster.stop();
}

void Spaceship::changeView() {
    float angle = body.getRotation();  // NOTE: angle increases clockwise

    if(angle < 45 || angle > 315) {
        body.setTextureRect({0,0,160,70});
        body.setOrigin(80.f, 38.f);
    }
    else if(angle > 135 && angle < 225) {
        body.setTextureRect({320,0,160,70});
        body.setOrigin(80.f, 32.f);
    }
    else {
        body.setTextureRect({160,0,160,70});
        body.setOrigin(80.f, 35.f);
    }
}

sf::Vector2f Spaceship::getEnginePos() {
    if(body.getTextureRect() == sf::IntRect{160,0,160,70}) {
        return body.getPosition() - ( getDirection() * 44.f );
    }
    else {
        sf::Transform translation;
        translation.rotate(90);
        sf::Vector2f newPoint = translation.transformPoint(getDirection()) * 2.f;
        return body.getPosition() - (newPoint + ( getDirection() * 44.f ));
    }
}

sf::Vector2f Spaceship::getGunPos() {
    float shipLength = (body.getTextureRect() == sf::IntRect{160, 0, 160, 70}) ? 26.f : 32.f;

    return getCoordinate() + (getDirection() * shipLength);
}

sf::Vector2f Spaceship::getCoordinate() { return coordinate; }
sf::Vector2f Spaceship::getDirection() { return direction; }
sf::Vector2f Spaceship::getVelocity() { return velocity; }
<commit_msg>adjust player speed<commit_after>#include "spaceship.h"
#include "camera.h"
#include "gun.h"

#include <iostream>

#define PI 3.14159265

Spaceship::Spaceship(sf::RenderWindow &w):
    window(w),
    direction{1, 0},
    coordinate{0,0},
    velocity{0, 0},
    maxSpeed(300.f),
    speed(0.f),
    acceleration(600),
    isThrusterOn(false)
{
    texture.loadFromFile("../spritesheet/player_ship.png");
    body = sf::Sprite(texture, {0,0,160,70});
    body.setScale(0.4f, 0.4f);
    body.setOrigin(80.f, 38.f);

    gun = Gun(texture, 5, 500.f);

    thrusterAnimation.setSpriteSheet(texture);
    thrusterAnimation.addFrame({0,70,160,70});
    thrusterAnimation.addFrame({160,70,160,70});

    thruster = AnimatedSprite(sf::seconds(0.09), true, false);
    thruster.setAnimation(thrusterAnimation);

    thruster.setScale(0.2f, 0.2f);
    thruster.setPosition(body.getPosition());
    thruster.setOrigin(80.f, 36.f);
}

void Spaceship::update(sf::Time elapsedTime) {
    if(sf::Keyboard::isKeyPressed(sf::Keyboard::X)) {
        gun.fire(elapsedTime, getGunPos(), getDirection());
    }
    if(sf::Keyboard::isKeyPressed(sf::Keyboard::Left)) {
        steerLeft();
    }
    if(sf::Keyboard::isKeyPressed(sf::Keyboard::Right)) {
        steerRight();
    }
    if(sf::Keyboard::isKeyPressed(sf::Keyboard::Up)) {
        accelerate(elapsedTime);
    }
    else {
        deccelerate(elapsedTime);
    }

    coordinate += velocity;
    velocity = direction * speed * elapsedTime.asSeconds();

    thruster.update(elapsedTime);
    gun.update(elapsedTime);
}

void Spaceship::draw(Camera &camera){

    body.setPosition(coordinate - camera.getCoordinate());

    thruster.setPosition(getEnginePos());
    thruster.setRotation(body.getRotation());

    window.draw(body);
    gun.draw(&window, &camera);

    if(isThrusterOn)
        window.draw(thruster);
}

void Spaceship::accelerate(sf::Time elapsedTime) {
    enableThrusters();
    if(speed < maxSpeed) {
        speed += acceleration * elapsedTime.asSeconds();
    }
}
void Spaceship::deccelerate(sf::Time elapsedTime) {
    disableThrusters();
    if(speed > 0.01f)
        speed *= 0.9f;
    else
        speed = 0.f;
}

void Spaceship::steerLeft() {
    body.rotate(-5);
    direction.x = cos(body.getRotation() * PI / 180);
    direction.y = sin(body.getRotation() * PI / 180);
    changeView();
}

void Spaceship::steerRight() {
    body.rotate(5);
    direction.x = cos(body.getRotation() * PI / 180);
    direction.y = sin(body.getRotation() * PI / 180);
    changeView();
}

void Spaceship::enableThrusters() {
    isThrusterOn = true;
    thruster.play(thrusterAnimation);
}

void Spaceship::disableThrusters() {
    isThrusterOn = false;
    thruster.stop();
}

void Spaceship::changeView() {
    float angle = body.getRotation();  // NOTE: angle increases clockwise

    if(angle < 45 || angle > 315) {
        body.setTextureRect({0,0,160,70});
        body.setOrigin(80.f, 38.f);
    }
    else if(angle > 135 && angle < 225) {
        body.setTextureRect({320,0,160,70});
        body.setOrigin(80.f, 32.f);
    }
    else {
        body.setTextureRect({160,0,160,70});
        body.setOrigin(80.f, 35.f);
    }
}

sf::Vector2f Spaceship::getEnginePos() {
    if(body.getTextureRect() == sf::IntRect{160,0,160,70}) {
        return body.getPosition() - ( getDirection() * 44.f );
    }
    else {
        sf::Transform translation;
        translation.rotate(90);
        sf::Vector2f newPoint = translation.transformPoint(getDirection()) * 2.f;
        return body.getPosition() - (newPoint + ( getDirection() * 44.f ));
    }
}

sf::Vector2f Spaceship::getGunPos() {
    float shipLength = (body.getTextureRect() == sf::IntRect{160, 0, 160, 70}) ? 26.f : 32.f;

    return getCoordinate() + (getDirection() * shipLength);
}

sf::Vector2f Spaceship::getCoordinate() { return coordinate; }
sf::Vector2f Spaceship::getDirection() { return direction; }
sf::Vector2f Spaceship::getVelocity() { return velocity; }
<|endoftext|>


<commit_before>#include "data-general.hpp"
#include "data-course.hpp"
#include "data-student.hpp"
using namespace std;

vector<Course> all_courses;
Student user;

void loadCourses() {
	ifstream infile("data/2012-13-s2-csv.csv");
	string str; // read in the header line
	getline(infile, str);
	while (infile.peek() != -1){
		Course incourse(infile);
		all_courses.push_back(incourse);
		// cout << incourse << endl;
	}
	// for (vector<Course>::iterator c = all_courses.begin(); c != all_courses.end(); ++c)
	// 	if (c->getProfessor()[1] == ' ')
	// 		if (c->getProfessor()[2] == '0' || c->getProfessor()[2] == '1')
	// 			c->displayMany();
}

void welcome() {
	string name, yearS = "", yearE = "", majors;
	cout << "Welcome!" << endl;
	cout << "What is your name? ";
	getline(cin, name);
	cout << "What year do you graduate? ";
	getline(cin, yearE);
	cout << "What are your majors (ex. CSCI, ASIAN) ";
	getline(cin, majors);
	user = Student(name, yearS, yearE, majors);
}

void getCourses() {
	string courses;
	cout << "What are some courses that you have taken? (ex. CSCI125, STAT 110)" << endl;
	getline(cin, courses);
	user.addCourses(courses);
}

int main(int argc, const char *argv[]) {
	loadCourses();

	// Method 1: Dynamic.
	// welcome();
	// getCourses();

	// Method 2: Hard-coded file path.
	// Student user("data/user.txt");

	// Method 3: File path as an argument.
	Student user(argv[1]);

	user.display();

	cout << "Question: Has the user taken CSCI 251? ";
	cout << user.hasTakenCourse("CSCI251") << endl;

	return 0;
}

// TODO: Add concentrations to Student
<commit_msg>It's easier to test with the hardcoded path.<commit_after>#include "data-general.hpp"
#include "data-course.hpp"
#include "data-student.hpp"
using namespace std;

vector<Course> all_courses;
Student user;

void loadCourses() {
	ifstream infile("data/2012-13-s2-csv.csv");
	string str; // read in the header line
	getline(infile, str);
	while (infile.peek() != -1){
		Course incourse(infile);
		all_courses.push_back(incourse);
		// cout << incourse << endl;
	}
	// for (vector<Course>::iterator c = all_courses.begin(); c != all_courses.end(); ++c)
	// 	if (c->getProfessor()[1] == ' ')
	// 		if (c->getProfessor()[2] == '0' || c->getProfessor()[2] == '1')
	// 			c->displayMany();
}

void welcome() {
	string name, yearS = "", yearE = "", majors;
	cout << "Welcome!" << endl;
	cout << "What is your name? ";
	getline(cin, name);
	cout << "What year do you graduate? ";
	getline(cin, yearE);
	cout << "What are your majors (ex. CSCI, ASIAN) ";
	getline(cin, majors);
	user = Student(name, yearS, yearE, majors);
}

void getCourses() {
	string courses;
	cout << "What are some courses that you have taken? (ex. CSCI125, STAT 110)" << endl;
	getline(cin, courses);
	user.addCourses(courses);
}

int main(int argc, const char *argv[]) {
	loadCourses();

	// Method 1: Dynamic.
	// welcome();
	// getCourses();

	// Method 2: Hard-coded file path.
	Student user("data/user.txt");

	// Method 3: File path as an argument.
	// Student user(argv[1]);

	user.display();

	cout << "Question: Has the user taken CSCI 251? ";
	cout << user.hasTakenCourse("CSCI251") << endl;

	return 0;
}

// TODO: Add concentrations to Student
<|endoftext|>


<commit_before>#include <windows.h>
#include <gl/gL.h>
#include "../../game/GLGame.h"
#include "../../game/GLUtils.h"
#include "resources.h"

class AppController {
public:
    AppController();
    ~AppController();
    bool init(HINSTANCE hInstance);
    void run();
private:
    HINSTANCE hInstance;
    HWND win;
    HACCEL accelerators;
    GLGame game;

    HGLRC hRC;
    HDC hDC;

    static LRESULT CALLBACK AppController::WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
    void onRender();
    void onResize(UINT width, UINT height);
    void onMenu(WORD cmd);
    void onKey(WPARAM key, bool down);
    void onMouseDown(UINT x, UINT y);
};

AppController::AppController()
{
}

AppController::~AppController()
{
}

bool AppController::init(HINSTANCE hInstance)
{
    // Register the window class
    WNDCLASSEX winClass;
    ZeroMemory(&winClass, sizeof(WNDCLASSEX));
    winClass.cbSize = sizeof(winClass);
    winClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
    winClass.lpfnWndProc = AppController::WndProc;
    winClass.cbWndExtra = sizeof(LONG_PTR);
    winClass.hInstance = hInstance;
    winClass.hCursor = LoadCursor(NULL, IDI_APPLICATION);
    winClass.lpszClassName = L"MainWindow";
    winClass.lpszMenuName = MAKEINTRESOURCEW(IDR_MAINMENU);
    if (RegisterClassExW(&winClass) == 0) {
        return false;
    }

    // Load the accelerators from the resource file so menu keyboard shortcuts work.
    accelerators = LoadAcceleratorsW(hInstance, MAKEINTRESOURCEW(ID_MENU_ACCELERATORS));
    if (accelerators == NULL) {
        return false;
    }

    // Create the window centered
    int w = 640, h = 460;
    int x = (GetSystemMetrics(SM_CXSCREEN) - w) / 2;
    int y = (GetSystemMetrics(SM_CYSCREEN) - h) / 2;
    win = CreateWindowW(winClass.lpszClassName, L"Glypha III", WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX, x, y, w, h, NULL, NULL, hInstance, this);
    if (win == NULL) {
        return false;
    }

    // Setup OpenGL
    hDC = GetDC(win);
    if (hDC == NULL) {
        return false;
    }
    static PIXELFORMATDESCRIPTOR pfd = {
        sizeof(PIXELFORMATDESCRIPTOR), 1, PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
        PFD_TYPE_RGBA, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, PFD_MAIN_PLANE, 0, 0, 0, 0
    };
    int pixelFormat = ChoosePixelFormat(hDC, &pfd);
    if (pixelFormat == 0 || SetPixelFormat(hDC, pixelFormat, &pfd) == FALSE) {
        return false;
    }
    hRC = wglCreateContext(hDC);
    if (hRC == NULL || wglMakeCurrent(hDC, hRC) == FALSE) {
        return false;
    }

    // Readjust the window so the client size matches our desired size
    RECT rcClient, rcWindow;
    POINT ptDiff;
    (void)GetClientRect(win, &rcClient);
    (void)GetWindowRect(win, &rcWindow);
    ptDiff.x = (rcWindow.right - rcWindow.left) - rcClient.right;
    ptDiff.y = (rcWindow.bottom - rcWindow.top) - rcClient.bottom;
    (void)MoveWindow(win, rcWindow.left, rcWindow.top, w + ptDiff.x, h + ptDiff.y, TRUE);

    // Show the window
    (void)ShowWindow(win, SW_SHOWNORMAL);
    (void)UpdateWindow(win);

    return true;
}

void AppController::run()
{
    MSG msg;
    GLUtils utils;
    const double fps = game.updateFrequency();
    double curr;
    double last = utils.now();
    for (;;) {
        while (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE)) {
            // Check for keystrokes for the menus
            if (!TranslateAcceleratorW(win, accelerators, &msg)) {
                (void)TranslateMessage(&msg);
                (void)DispatchMessageW(&msg);
            }
        }
        if (msg.message == WM_QUIT) {
            break;
        }

        // force FPS. probably should be done in GLGame eventually
        curr = utils.now();
        if ((curr - last) > fps) {
            (void)InvalidateRect(win, NULL, FALSE);
            last = curr;
        }
    }
}

void AppController::onKey(WPARAM key, bool down)
{
    GLGameKey gameKey;
    switch (key) {
    case VK_SPACE: gameKey = kGLGameKeySpacebar; break;
    case VK_DOWN: gameKey = kGLGameKeyDownArrow; break;
    case VK_LEFT: gameKey = kGLGameKeyLeftArrow; break;
    case VK_RIGHT: gameKey = kGLGameKeyRightArrow; break;
    case 'A': gameKey = kGLGameKeyA; break;
    case 'S': gameKey = kGLGameKeyS; break;
    case VK_OEM_1: gameKey = kGLGameKeyColon; break;
    case VK_OEM_7: gameKey = kGLGameKeyQuote; break;
    default:
	    return;
    }
    if (down) {
	    game.handleKeyDownEvent(gameKey);
    } else {
	    game.handleKeyUpEvent(gameKey);
    }
}

void AppController::onMouseDown(UINT x, UINT y)
{
    game.handleMouseDownEvent(GLPoint(x, y));
}

LRESULT CALLBACK AppController::WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    LRESULT result = 0;

    if (message == WM_CREATE) {
        LPCREATESTRUCT pcs = (LPCREATESTRUCT)lParam;
        AppController *appController = (AppController *)pcs->lpCreateParams;
        (void)SetWindowLongPtrW(hwnd, GWLP_USERDATA, PtrToUlong(appController));
        result = 1;
    } else {
        AppController *appController = reinterpret_cast<AppController *>(static_cast<LONG_PTR>(GetWindowLongPtrW(hwnd, GWLP_USERDATA)));
        bool wasHandled = false;

        if (appController != NULL) {
            switch (message) {
            case WM_SIZE:
                appController->onResize(LOWORD(lParam), HIWORD(lParam));
                result = 0;
                wasHandled = true;
                break;

            case WM_DISPLAYCHANGE:
                (void)InvalidateRect(hwnd, NULL, FALSE);
                result = 0;
                wasHandled = true;
                break;

            case WM_PAINT:
                appController->onRender();
                (void)ValidateRect(hwnd, NULL);
                result = 0;
                wasHandled = true;
                break;

            case WM_DESTROY:
                PostQuitMessage(0);
                result = 1;
                wasHandled = true;
                break;

            case WM_COMMAND:
                appController->onMenu(LOWORD(wParam));
                result = 1;
                wasHandled = true;
                break;

            case WM_KEYDOWN:
            case WM_KEYUP:
	            appController->onKey(wParam, message == WM_KEYDOWN);
	            result = 0;
	            wasHandled = true;
	            break;

            case WM_LBUTTONDOWN:
                appController->onMouseDown(lParam & 0xFFFF, lParam >> 16);
                break;
            }
        }

        if (wasHandled == false) {
            result = DefWindowProc(hwnd, message, wParam, lParam);
        }
    }

    return result;
}

void AppController::onRender()
{
    game.draw();
    (void)SwapBuffers(hDC);
}

void AppController::onResize(UINT width, UINT height)
{
    game.renderer()->resize(width, height);
}

void AppController::onMenu(WORD cmd)
{
    switch(cmd) {
    case ID_MENU_NEW_GAME:
        game.newGame();
        break;
    case ID_MENU_EXIT:
        PostMessage(win, WM_CLOSE, 0, 0);
        break;
    }
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    AppController appController;
    if (appController.init(hInstance) == false) {
        (void)MessageBoxW(NULL, L"Failed to initialize.", NULL, MB_OK | MB_ICONERROR);
        return 0;
    }
    appController.run();
    return 0;
}
<commit_msg>Fixed x64 Windows compiler error.<commit_after>#include <windows.h>
#include <gl/gL.h>
#include "../../game/GLGame.h"
#include "../../game/GLUtils.h"
#include "resources.h"

class AppController {
public:
    AppController();
    ~AppController();
    bool init(HINSTANCE hInstance);
    void run();
private:
    HINSTANCE hInstance;
    HWND win;
    HACCEL accelerators;
    GLGame game;

    HGLRC hRC;
    HDC hDC;

    static LRESULT CALLBACK AppController::WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
    void onRender();
    void onResize(UINT width, UINT height);
    void onMenu(WORD cmd);
    void onKey(WPARAM key, bool down);
    void onMouseDown(UINT x, UINT y);
};

AppController::AppController()
{
}

AppController::~AppController()
{
}

bool AppController::init(HINSTANCE hInstance)
{
    // Register the window class
    WNDCLASSEX winClass;
    ZeroMemory(&winClass, sizeof(WNDCLASSEX));
    winClass.cbSize = sizeof(winClass);
    winClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
    winClass.lpfnWndProc = AppController::WndProc;
    winClass.cbWndExtra = sizeof(LONG_PTR);
    winClass.hInstance = hInstance;
    winClass.hCursor = LoadCursor(NULL, IDI_APPLICATION);
    winClass.lpszClassName = L"MainWindow";
    winClass.lpszMenuName = MAKEINTRESOURCEW(IDR_MAINMENU);
    if (RegisterClassExW(&winClass) == 0) {
        return false;
    }

    // Load the accelerators from the resource file so menu keyboard shortcuts work.
    accelerators = LoadAcceleratorsW(hInstance, MAKEINTRESOURCEW(ID_MENU_ACCELERATORS));
    if (accelerators == NULL) {
        return false;
    }

    // Create the window centered
    int w = 640, h = 460;
    int x = (GetSystemMetrics(SM_CXSCREEN) - w) / 2;
    int y = (GetSystemMetrics(SM_CYSCREEN) - h) / 2;
    win = CreateWindowW(winClass.lpszClassName, L"Glypha III", WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX, x, y, w, h, NULL, NULL, hInstance, this);
    if (win == NULL) {
        return false;
    }

    // Setup OpenGL
    hDC = GetDC(win);
    if (hDC == NULL) {
        return false;
    }
    static PIXELFORMATDESCRIPTOR pfd = {
        sizeof(PIXELFORMATDESCRIPTOR), 1, PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
        PFD_TYPE_RGBA, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, PFD_MAIN_PLANE, 0, 0, 0, 0
    };
    int pixelFormat = ChoosePixelFormat(hDC, &pfd);
    if (pixelFormat == 0 || SetPixelFormat(hDC, pixelFormat, &pfd) == FALSE) {
        return false;
    }
    hRC = wglCreateContext(hDC);
    if (hRC == NULL || wglMakeCurrent(hDC, hRC) == FALSE) {
        return false;
    }

    // Readjust the window so the client size matches our desired size
    RECT rcClient, rcWindow;
    POINT ptDiff;
    (void)GetClientRect(win, &rcClient);
    (void)GetWindowRect(win, &rcWindow);
    ptDiff.x = (rcWindow.right - rcWindow.left) - rcClient.right;
    ptDiff.y = (rcWindow.bottom - rcWindow.top) - rcClient.bottom;
    (void)MoveWindow(win, rcWindow.left, rcWindow.top, w + ptDiff.x, h + ptDiff.y, TRUE);

    // Show the window
    (void)ShowWindow(win, SW_SHOWNORMAL);
    (void)UpdateWindow(win);

    return true;
}

void AppController::run()
{
    MSG msg;
    GLUtils utils;
    const double fps = game.updateFrequency();
    double curr;
    double last = utils.now();
    for (;;) {
        while (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE)) {
            // Check for keystrokes for the menus
            if (!TranslateAcceleratorW(win, accelerators, &msg)) {
                (void)TranslateMessage(&msg);
                (void)DispatchMessageW(&msg);
            }
        }
        if (msg.message == WM_QUIT) {
            break;
        }

        // force FPS. probably should be done in GLGame eventually
        curr = utils.now();
        if ((curr - last) > fps) {
            (void)InvalidateRect(win, NULL, FALSE);
            last = curr;
        }
    }
}

void AppController::onKey(WPARAM key, bool down)
{
    GLGameKey gameKey;
    switch (key) {
    case VK_SPACE: gameKey = kGLGameKeySpacebar; break;
    case VK_DOWN: gameKey = kGLGameKeyDownArrow; break;
    case VK_LEFT: gameKey = kGLGameKeyLeftArrow; break;
    case VK_RIGHT: gameKey = kGLGameKeyRightArrow; break;
    case 'A': gameKey = kGLGameKeyA; break;
    case 'S': gameKey = kGLGameKeyS; break;
    case VK_OEM_1: gameKey = kGLGameKeyColon; break;
    case VK_OEM_7: gameKey = kGLGameKeyQuote; break;
    default:
	    return;
    }
    if (down) {
	    game.handleKeyDownEvent(gameKey);
    } else {
	    game.handleKeyUpEvent(gameKey);
    }
}

void AppController::onMouseDown(UINT x, UINT y)
{
    game.handleMouseDownEvent(GLPoint(x, y));
}

LRESULT CALLBACK AppController::WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    LRESULT result = 0;

    if (message == WM_CREATE) {
        LPCREATESTRUCT pcs = (LPCREATESTRUCT)lParam;
        AppController *appController = (AppController *)pcs->lpCreateParams;
        (void)SetWindowLongPtrW(hwnd, GWLP_USERDATA, PtrToUlong(appController));
        result = 1;
    } else {
        AppController *appController = reinterpret_cast<AppController *>(static_cast<LONG_PTR>(GetWindowLongPtrW(hwnd, GWLP_USERDATA)));
        bool wasHandled = false;

        if (appController != NULL) {
            switch (message) {
            case WM_SIZE:
                appController->onResize(LOWORD(lParam), HIWORD(lParam));
                result = 0;
                wasHandled = true;
                break;

            case WM_DISPLAYCHANGE:
                (void)InvalidateRect(hwnd, NULL, FALSE);
                result = 0;
                wasHandled = true;
                break;

            case WM_PAINT:
                appController->onRender();
                (void)ValidateRect(hwnd, NULL);
                result = 0;
                wasHandled = true;
                break;

            case WM_DESTROY:
                PostQuitMessage(0);
                result = 1;
                wasHandled = true;
                break;

            case WM_COMMAND:
                appController->onMenu(LOWORD(wParam));
                result = 1;
                wasHandled = true;
                break;

            case WM_KEYDOWN:
            case WM_KEYUP:
	            appController->onKey(wParam, message == WM_KEYDOWN);
	            result = 0;
	            wasHandled = true;
	            break;

            case WM_LBUTTONDOWN:
                appController->onMouseDown(lParam & 0xFFFF, (lParam >> 16) & 0xFFFF);
                break;
            }
        }

        if (wasHandled == false) {
            result = DefWindowProc(hwnd, message, wParam, lParam);
        }
    }

    return result;
}

void AppController::onRender()
{
    game.draw();
    (void)SwapBuffers(hDC);
}

void AppController::onResize(UINT width, UINT height)
{
    game.renderer()->resize(width, height);
}

void AppController::onMenu(WORD cmd)
{
    switch(cmd) {
    case ID_MENU_NEW_GAME:
        game.newGame();
        break;
    case ID_MENU_EXIT:
        PostMessage(win, WM_CLOSE, 0, 0);
        break;
    }
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    AppController appController;
    if (appController.init(hInstance) == false) {
        (void)MessageBoxW(NULL, L"Failed to initialize.", NULL, MB_OK | MB_ICONERROR);
        return 0;
    }
    appController.run();
    return 0;
}
<|endoftext|>


<commit_before>#include <gmi_mesh.h>
#include <apf.h>
#include <apfMesh2.h>
#include <apfMDS.h>
#include <PCU.h>
#include <parma.h>
#include <cassert>

namespace {
  const char* modelFile = 0;
  const char* meshFile = 0;

  void freeMesh(apf::Mesh* m)
  {
    m->destroyNative();
    apf::destroyMesh(m);
  }

  void getConfig(int argc, char** argv)
  {
    assert(argc==4);
    modelFile = argv[1];
    meshFile = argv[2];
  }

  double getFun3dW(int type) {
    assert( type >= apf::Mesh::VERTEX && type <= apf::Mesh::PYRAMID );
    const double vtxw = 1.0;
    const double edgew = 1.0;
    const double triw = 1.0;
    const double quadw = 1.0;
    const double tetw = 1.0;
    const double pyrw = 6.8;
    const double przw = 7.5;
    const double hexw = 13.8;
    const double weights[8] =
      {vtxw, edgew, triw, quadw, tetw, hexw, przw, pyrw};
    return weights[type];
  }

  apf::MeshTag* applyFun3dWeight(apf::Mesh* m) {
    apf::MeshTag* wtag = m->createDoubleTag("ghostWeight",1);
    apf::MeshEntity* e;
    for(int d=0; d <= m->getDimension(); d++) {
      apf::MeshIterator* itr = m->begin(d);
      while( (e = m->iterate(itr)) ) {
        double w = getFun3dW(m->getType(e));
        m->setDoubleTag(e, wtag, &w);
      }
      m->end(itr);
    }
    return wtag;
  }

  void runParma(apf::Mesh* m, apf::MeshTag* weights) {
    const int layers = 1;
    const double stepFactor = 0.5;
    const int verbosity = 2;
    apf::Balancer* ghost =
      Parma_MakeGhostDiffuser(m, layers, stepFactor, verbosity);
    ghost->balance(weights, 1.05);
    delete ghost;
  }
}

int main(int argc, char** argv)
{
  MPI_Init(&argc,&argv);
  PCU_Comm_Init();
  PCU_Debug_Open();
  gmi_register_mesh();
  getConfig(argc,argv);
  apf::Mesh2* m = apf::loadMdsMesh(modelFile,meshFile);
  apf::MeshTag* weights = applyFun3dWeight(m);
  runParma(m,weights);
  m->destroyTag(weights);
  apf::writeVtkFiles(argv[3],m);
  freeMesh(m);
  PCU_Comm_Free();
  MPI_Finalize();
}
<commit_msg>disable debug output and write the vtx ptn<commit_after>#include <gmi_mesh.h>
#include <apf.h>
#include <apfMesh2.h>
#include <apfMDS.h>
#include <PCU.h>
#include <parma.h>
#include <cassert>

namespace {
  const char* modelFile = 0;
  const char* meshFile = 0;

  void freeMesh(apf::Mesh* m)
  {
    m->destroyNative();
    apf::destroyMesh(m);
  }

  void getConfig(int argc, char** argv)
  {
    assert(argc==4);
    modelFile = argv[1];
    meshFile = argv[2];
  }

  double getFun3dW(int type) {
    assert( type >= apf::Mesh::VERTEX && type <= apf::Mesh::PYRAMID );
    const double vtxw = 1.0;
    const double edgew = 1.0;
    const double triw = 1.0;
    const double quadw = 1.0;
    const double tetw = 1.0;
    const double pyrw = 6.8;
    const double przw = 7.5;
    const double hexw = 13.8;
    const double weights[8] =
      {vtxw, edgew, triw, quadw, tetw, hexw, przw, pyrw};
    return weights[type];
  }

  apf::MeshTag* applyFun3dWeight(apf::Mesh* m) {
    apf::MeshTag* wtag = m->createDoubleTag("ghostWeight",1);
    apf::MeshEntity* e;
    for(int d=0; d <= m->getDimension(); d++) {
      apf::MeshIterator* itr = m->begin(d);
      while( (e = m->iterate(itr)) ) {
        double w = getFun3dW(m->getType(e));
        m->setDoubleTag(e, wtag, &w);
      }
      m->end(itr);
    }
    return wtag;
  }

  void runParma(apf::Mesh* m, apf::MeshTag* weights) {
    const int layers = 1;
    const double stepFactor = 0.5;
    const int verbosity = 2;
    apf::Balancer* ghost =
      Parma_MakeGhostDiffuser(m, layers, stepFactor, verbosity);
    ghost->balance(weights, 1.05);
    delete ghost;
  }
}

int main(int argc, char** argv)
{
  MPI_Init(&argc,&argv);
  PCU_Comm_Init();
  gmi_register_mesh();
  getConfig(argc,argv);
  apf::Mesh2* m = apf::loadMdsMesh(modelFile,meshFile);
  apf::MeshTag* weights = applyFun3dWeight(m);
  runParma(m,weights);
  m->destroyTag(weights);
  apf::writeVtkFiles(argv[3],m);
  Parma_WriteVtxPtn(m,argv[3]);
  freeMesh(m);
  PCU_Comm_Free();
  MPI_Finalize();
}
<|endoftext|>


<commit_before>// Copyright (c) 2011-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "sync.h"

#include "util.h"

#include <boost/foreach.hpp>

#ifdef DEBUG_LOCKCONTENTION
void PrintLockContention(const char* pszName, const char* pszFile, int nLine)
{
    LogPrintf("LOCKCONTENTION: %s\n", pszName);
    LogPrintf("Locker: %s:%d\n", pszFile, nLine);
}
#endif /* DEBUG_LOCKCONTENTION */

#ifdef DEBUG_LOCKORDER
//
// Early deadlock detection.
// Problem being solved:
//    Thread 1 locks  A, then B, then C
//    Thread 2 locks  D, then C, then A
//     --> may result in deadlock between the two threads, depending on when they run.
// Solution implemented here:
// Keep track of pairs of locks: (A before B), (A before C), etc.
// Complain if any thread tries to lock in a different order.
//

struct CLockLocation
{
    CLockLocation(const char* pszName, const char* pszFile, int nLine)
    {
        mutexName = pszName;
        sourceFile = pszFile;
        sourceLine = nLine;
    }

    std::string ToString() const
    {
        return mutexName+"  "+sourceFile+":"+itostr(sourceLine);
    }

    std::string MutexName() const { return mutexName; }

private:
    std::string mutexName;
    std::string sourceFile;
    int sourceLine;
};

typedef std::vector< std::pair<void*, CLockLocation> > LockStack;

static boost::mutex dd_mutex;
static std::map<std::pair<void*, void*>, LockStack> lockorders;
static boost::thread_specific_ptr<LockStack> lockstack;

static void potential_deadlock_detected(const std::pair<void*, void*>& mismatch, const LockStack& s1, const LockStack& s2)
{
    LogPrintf("POTENTIAL DEADLOCK DETECTED\n");
    LogPrintf("Previous lock order was:\n");
    BOOST_FOREACH(const PAIRTYPE(void*, CLockLocation)& i, s2)
    {
        if (i.first == mismatch.first) LogPrintf(" (1)");
        if (i.first == mismatch.second) LogPrintf(" (2)");
        LogPrintf(" %s\n", i.second.ToString().c_str());
    }
    LogPrintf("Current lock order is:\n");
    BOOST_FOREACH(const PAIRTYPE(void*, CLockLocation)& i, s1)
    {
        if (i.first == mismatch.first) LogPrintf(" (1)");
        if (i.first == mismatch.second) LogPrintf(" (2)");
        LogPrintf(" %s\n", i.second.ToString().c_str());
    }
}

static void push_lock(void* c, const CLockLocation& locklocation, bool fTry)
{
    if (lockstack.get() == NULL)
        lockstack.reset(new LockStack);

    if (fDebug) LogPrintf("Locking: %s\n", locklocation.ToString().c_str());
    dd_mutex.lock();

    (*lockstack).push_back(std::make_pair(c, locklocation));

    if (!fTry) {
        BOOST_FOREACH(const PAIRTYPE(void*, CLockLocation)& i, (*lockstack)) {
            if (i.first == c) break;

            std::pair<void*, void*> p1 = std::make_pair(i.first, c);
            if (lockorders.count(p1))
                continue;
            lockorders[p1] = (*lockstack);

            std::pair<void*, void*> p2 = std::make_pair(c, i.first);
            if (lockorders.count(p2))
            {
                potential_deadlock_detected(p1, lockorders[p2], lockorders[p1]);
                break;
            }
        }
    }
    dd_mutex.unlock();
}

static void pop_lock()
{
    if (fDebug)
    {
        const CLockLocation& locklocation = (*lockstack).rbegin()->second;
        LogPrintf("Unlocked: %s\n", locklocation.ToString().c_str());
    }
    dd_mutex.lock();
    (*lockstack).pop_back();
    dd_mutex.unlock();
}

void EnterCritical(const char* pszName, const char* pszFile, int nLine, void* cs, bool fTry)
{
    push_lock(cs, CLockLocation(pszName, pszFile, nLine), fTry);
}

void LeaveCritical()
{
    pop_lock();
}

std::string LocksHeld()
{
    std::string result;
    BOOST_FOREACH(const PAIRTYPE(void*, CLockLocation)&i, *lockstack)
        result += i.second.ToString() + std::string("\n");
    return result;
}

void AssertLockHeldInternal(const char *pszName, const char* pszFile, int nLine, void *cs)
{
    BOOST_FOREACH(const PAIRTYPE(void*, CLockLocation)&i, *lockstack)
        if (i.first == cs) return;
    fprintf(stderr, "Assertion failed: lock %s not held in %s:%i; locks held:\n%s",
            pszName, pszFile, nLine, LocksHeld().c_str());
    abort();
}

#endif /* DEBUG_LOCKORDER */
<commit_msg>state.h in sync.cpp<commit_after>// Copyright (c) 2011-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "sync.h"

#include "util.h"
#include "state.h"

#include <boost/foreach.hpp>

#ifdef DEBUG_LOCKCONTENTION
void PrintLockContention(const char* pszName, const char* pszFile, int nLine)
{
    LogPrintf("LOCKCONTENTION: %s\n", pszName);
    LogPrintf("Locker: %s:%d\n", pszFile, nLine);
}
#endif /* DEBUG_LOCKCONTENTION */

#ifdef DEBUG_LOCKORDER
//
// Early deadlock detection.
// Problem being solved:
//    Thread 1 locks  A, then B, then C
//    Thread 2 locks  D, then C, then A
//     --> may result in deadlock between the two threads, depending on when they run.
// Solution implemented here:
// Keep track of pairs of locks: (A before B), (A before C), etc.
// Complain if any thread tries to lock in a different order.
//

struct CLockLocation
{
    CLockLocation(const char* pszName, const char* pszFile, int nLine)
    {
        mutexName = pszName;
        sourceFile = pszFile;
        sourceLine = nLine;
    }

    std::string ToString() const
    {
        return mutexName+"  "+sourceFile+":"+itostr(sourceLine);
    }

    std::string MutexName() const { return mutexName; }

private:
    std::string mutexName;
    std::string sourceFile;
    int sourceLine;
};

typedef std::vector< std::pair<void*, CLockLocation> > LockStack;

static boost::mutex dd_mutex;
static std::map<std::pair<void*, void*>, LockStack> lockorders;
static boost::thread_specific_ptr<LockStack> lockstack;

static void potential_deadlock_detected(const std::pair<void*, void*>& mismatch, const LockStack& s1, const LockStack& s2)
{
    LogPrintf("POTENTIAL DEADLOCK DETECTED\n");
    LogPrintf("Previous lock order was:\n");
    BOOST_FOREACH(const PAIRTYPE(void*, CLockLocation)& i, s2)
    {
        if (i.first == mismatch.first) LogPrintf(" (1)");
        if (i.first == mismatch.second) LogPrintf(" (2)");
        LogPrintf(" %s\n", i.second.ToString().c_str());
    }
    LogPrintf("Current lock order is:\n");
    BOOST_FOREACH(const PAIRTYPE(void*, CLockLocation)& i, s1)
    {
        if (i.first == mismatch.first) LogPrintf(" (1)");
        if (i.first == mismatch.second) LogPrintf(" (2)");
        LogPrintf(" %s\n", i.second.ToString().c_str());
    }
}

static void push_lock(void* c, const CLockLocation& locklocation, bool fTry)
{
    if (lockstack.get() == NULL)
        lockstack.reset(new LockStack);

    if (fDebug) LogPrintf("Locking: %s\n", locklocation.ToString().c_str());
    dd_mutex.lock();

    (*lockstack).push_back(std::make_pair(c, locklocation));

    if (!fTry) {
        BOOST_FOREACH(const PAIRTYPE(void*, CLockLocation)& i, (*lockstack)) {
            if (i.first == c) break;

            std::pair<void*, void*> p1 = std::make_pair(i.first, c);
            if (lockorders.count(p1))
                continue;
            lockorders[p1] = (*lockstack);

            std::pair<void*, void*> p2 = std::make_pair(c, i.first);
            if (lockorders.count(p2))
            {
                potential_deadlock_detected(p1, lockorders[p2], lockorders[p1]);
                break;
            }
        }
    }
    dd_mutex.unlock();
}

static void pop_lock()
{
    if (fDebug)
    {
        const CLockLocation& locklocation = (*lockstack).rbegin()->second;
        LogPrintf("Unlocked: %s\n", locklocation.ToString().c_str());
    }
    dd_mutex.lock();
    (*lockstack).pop_back();
    dd_mutex.unlock();
}

void EnterCritical(const char* pszName, const char* pszFile, int nLine, void* cs, bool fTry)
{
    push_lock(cs, CLockLocation(pszName, pszFile, nLine), fTry);
}

void LeaveCritical()
{
    pop_lock();
}

std::string LocksHeld()
{
    std::string result;
    BOOST_FOREACH(const PAIRTYPE(void*, CLockLocation)&i, *lockstack)
        result += i.second.ToString() + std::string("\n");
    return result;
}

void AssertLockHeldInternal(const char *pszName, const char* pszFile, int nLine, void *cs)
{
    BOOST_FOREACH(const PAIRTYPE(void*, CLockLocation)&i, *lockstack)
        if (i.first == cs) return;
    fprintf(stderr, "Assertion failed: lock %s not held in %s:%i; locks held:\n%s",
            pszName, pszFile, nLine, LocksHeld().c_str());
    abort();
}

#endif /* DEBUG_LOCKORDER */
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: ComboBox.hxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: obo $ $Date: 2003-10-21 08:55:46 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library 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 for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _FORMS_COMBOBOX_HXX_
#define _FORMS_COMBOBOX_HXX_

#ifndef _FORMS_FORMCOMPONENT_HXX_
#include "FormComponent.hxx"
#endif
#ifndef _CPPUHELPER_INTERFACECONTAINER_HXX_
#include <cppuhelper/interfacecontainer.hxx>
#endif
#ifndef _DATE_HXX
#include <tools/date.hxx>
#endif
#ifndef _SV_TIMER_HXX
#include <vcl/timer.hxx>
#endif

#ifndef _COM_SUN_STAR_UTIL_XREFRESHABLE_HPP_
#include <com/sun/star/util/XRefreshable.hpp>
#endif
#ifndef _COM_SUN_STAR_UTIL_XNUMBERFORMATTER_HPP_
#include <com/sun/star/util/XNumberFormatter.hpp>
#endif
#ifndef _COM_SUN_STAR_SDB_XSQLERRORBROADCASTER_HPP_
#include <com/sun/star/sdb/XSQLErrorBroadcaster.hpp>
#endif
#ifndef _COM_SUN_STAR_FORM_LISTSOURCETYPE_HPP_
#include <com/sun/star/form/ListSourceType.hpp>
#endif
#ifndef _COM_SUN_STAR_AWT_XITEMLISTENER_HPP_
#include <com/sun/star/awt/XItemListener.hpp>
#endif
#ifndef _COM_SUN_STAR_AWT_XFOCUSLISTENER_HPP_
#include <com/sun/star/awt/XFocusListener.hpp>
#endif
#ifndef FORMS_ERRORBROADCASTER_HXX
#include "errorbroadcaster.hxx"
#endif
#ifndef FORMS_ENTRYLISTHELPER_HXX
#include "entrylisthelper.hxx"
#endif

//.........................................................................
namespace frm
{

//==================================================================
// OComboBoxModel
//==================================================================
class OComboBoxModel
            :public OBoundControlModel
            ,public OEntryListHelper
            ,public OErrorBroadcaster
            ,public ::comphelper::OAggregationArrayUsageHelper< OComboBoxModel >
{
    ::com::sun::star::uno::Any              m_aBoundColumn;         // obsolet
    ::rtl::OUString                         m_aListSource;          //
    ::rtl::OUString                         m_aDefaultText;         // DefaultText
    ::rtl::OUString                         m_aSaveValue;

    StringSequence                          m_aDesignModeStringItems;
        // upon loading, in some cases we reset fill our string item list ourself. We don't want
        // to lose the user's items then, so we remember them here.

    ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatter> m_xFormatter;

    ::com::sun::star::form::ListSourceType  m_eListSourceType;      // type der list source
    ::com::sun::star::util::Date            m_aNullDate;
    sal_Int32                               m_nFormatKey;
    sal_Int16                               m_nFieldType;
    sal_Int16                               m_nKeyType;
    sal_Bool                                m_bEmptyIsNull;         // LeerString wird als NULL interpretiert

protected:
    virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type>   _getTypes();

public:
    DECLARE_DEFAULT_LEAF_XTOR( OComboBoxModel );

    virtual void SAL_CALL disposing();

    // OPropertySetHelper
    virtual void SAL_CALL getFastPropertyValue(::com::sun::star::uno::Any& rValue, sal_Int32 nHandle) const;
    virtual void SAL_CALL setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const ::com::sun::star::uno::Any& rValue )
                throw (::com::sun::star::uno::Exception);
    virtual sal_Bool SAL_CALL convertFastPropertyValue(
                ::com::sun::star::uno::Any& _rConvertedValue, ::com::sun::star::uno::Any& _rOldValue, sal_Int32 _nHandle, const ::com::sun::star::uno::Any& _rValue )
                throw (::com::sun::star::lang::IllegalArgumentException);

    // XLoadListener
    virtual void SAL_CALL reloaded( const ::com::sun::star::lang::EventObject& aEvent ) throw(::com::sun::star::uno::RuntimeException);

    // XServiceInfo
    IMPLEMENTATION_NAME(OComboBoxModel);
    virtual StringSequence SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException);

    // UNO
    DECLARE_UNO3_AGG_DEFAULTS(OComboBoxModel, OBoundControlModel);
    virtual ::com::sun::star::uno::Any SAL_CALL queryAggregation( const ::com::sun::star::uno::Type& _rType ) throw (::com::sun::star::uno::RuntimeException);

    // XPropertySet
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo> SAL_CALL getPropertySetInfo() throw(::com::sun::star::uno::RuntimeException);
    virtual cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper();

    // XPersistObject
    virtual ::rtl::OUString SAL_CALL    getServiceName() throw(::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL
        write(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectOutputStream>& _rxOutStream) throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL
        read(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectInputStream>& _rxInStream) throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);

    // OAggregationArrayUsageHelper
    virtual void fillProperties(
        ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& /* [out] */ _rProps,
        ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& /* [out] */ _rAggregateProps
        ) const;
    IMPLEMENT_INFO_SERVICE()

    // XEventListener
    virtual void SAL_CALL disposing(const ::com::sun::star::lang::EventObject& Source) throw (::com::sun::star::uno::RuntimeException);

protected:
    // OBoundControlModel overridables
    virtual ::com::sun::star::uno::Any
                            translateDbColumnToControlValue( );
    virtual sal_Bool        commitControlValueToDbColumn( bool _bPostReset );

    virtual void            onConnectedDbColumn( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _rxForm );
    virtual void            onDisconnectedDbColumn();

    virtual ::com::sun::star::uno::Any
                            getDefaultForReset() const;

    virtual sal_Bool        approveValueBinding( const ::com::sun::star::uno::Reference< ::drafts::com::sun::star::form::XValueBinding >& _rxBinding );

    // OEntryListHelper overriables
    virtual void    stringItemListChanged( );
    virtual void    connectedExternalListSource( );
    virtual void    disconnectedExternalListSource( );

protected:
    void loadData();

    DECLARE_XCLONEABLE();
};

//==================================================================
// OComboBoxControl
//==================================================================

class OComboBoxControl : public OBoundControl
{
public:
    OComboBoxControl(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& _rxFactory);

    // XServiceInfo
    IMPLEMENTATION_NAME(OComboBoxControl);
    virtual StringSequence SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException);
};

//.........................................................................
}
//.........................................................................

#endif // _FORMS_COMBOBOX_HXX_

<commit_msg>INTEGRATION: CWS frmvalidation (1.7.36); FILE MERGED 2004/03/11 16:46:12 fs 1.7.36.1: mass checkin - #i25106# core for validating form controls via external XValidator instances - moved the services/interfaces related to binding form controls to external   value suppliers into css.form.binding (out of drafts.css.form/component)<commit_after>/*************************************************************************
 *
 *  $RCSfile: ComboBox.hxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: rt $ $Date: 2004-04-02 10:50:00 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library 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 for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _FORMS_COMBOBOX_HXX_
#define _FORMS_COMBOBOX_HXX_

#ifndef _FORMS_FORMCOMPONENT_HXX_
#include "FormComponent.hxx"
#endif
#ifndef _CPPUHELPER_INTERFACECONTAINER_HXX_
#include <cppuhelper/interfacecontainer.hxx>
#endif
#ifndef _DATE_HXX
#include <tools/date.hxx>
#endif
#ifndef _SV_TIMER_HXX
#include <vcl/timer.hxx>
#endif

#ifndef _COM_SUN_STAR_UTIL_XREFRESHABLE_HPP_
#include <com/sun/star/util/XRefreshable.hpp>
#endif
#ifndef _COM_SUN_STAR_UTIL_XNUMBERFORMATTER_HPP_
#include <com/sun/star/util/XNumberFormatter.hpp>
#endif
#ifndef _COM_SUN_STAR_SDB_XSQLERRORBROADCASTER_HPP_
#include <com/sun/star/sdb/XSQLErrorBroadcaster.hpp>
#endif
#ifndef _COM_SUN_STAR_FORM_LISTSOURCETYPE_HPP_
#include <com/sun/star/form/ListSourceType.hpp>
#endif
#ifndef _COM_SUN_STAR_AWT_XITEMLISTENER_HPP_
#include <com/sun/star/awt/XItemListener.hpp>
#endif
#ifndef _COM_SUN_STAR_AWT_XFOCUSLISTENER_HPP_
#include <com/sun/star/awt/XFocusListener.hpp>
#endif
#ifndef FORMS_ERRORBROADCASTER_HXX
#include "errorbroadcaster.hxx"
#endif
#ifndef FORMS_ENTRYLISTHELPER_HXX
#include "entrylisthelper.hxx"
#endif

//.........................................................................
namespace frm
{

//==================================================================
// OComboBoxModel
//==================================================================
class OComboBoxModel
            :public OBoundControlModel
            ,public OEntryListHelper
            ,public OErrorBroadcaster
            ,public ::comphelper::OAggregationArrayUsageHelper< OComboBoxModel >
{
    ::com::sun::star::uno::Any              m_aBoundColumn;         // obsolet
    ::rtl::OUString                         m_aListSource;          //
    ::rtl::OUString                         m_aDefaultText;         // DefaultText
    ::rtl::OUString                         m_aSaveValue;

    StringSequence                          m_aDesignModeStringItems;
        // upon loading, in some cases we reset fill our string item list ourself. We don't want
        // to lose the user's items then, so we remember them here.

    ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatter> m_xFormatter;

    ::com::sun::star::form::ListSourceType  m_eListSourceType;      // type der list source
    ::com::sun::star::util::Date            m_aNullDate;
    sal_Int32                               m_nFormatKey;
    sal_Int16                               m_nFieldType;
    sal_Int16                               m_nKeyType;
    sal_Bool                                m_bEmptyIsNull;         // LeerString wird als NULL interpretiert

protected:
    virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type>   _getTypes();

public:
    DECLARE_DEFAULT_LEAF_XTOR( OComboBoxModel );

    virtual void SAL_CALL disposing();

    // OPropertySetHelper
    virtual void SAL_CALL getFastPropertyValue(::com::sun::star::uno::Any& rValue, sal_Int32 nHandle) const;
    virtual void SAL_CALL setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const ::com::sun::star::uno::Any& rValue )
                throw (::com::sun::star::uno::Exception);
    virtual sal_Bool SAL_CALL convertFastPropertyValue(
                ::com::sun::star::uno::Any& _rConvertedValue, ::com::sun::star::uno::Any& _rOldValue, sal_Int32 _nHandle, const ::com::sun::star::uno::Any& _rValue )
                throw (::com::sun::star::lang::IllegalArgumentException);

    // XLoadListener
    virtual void SAL_CALL reloaded( const ::com::sun::star::lang::EventObject& aEvent ) throw(::com::sun::star::uno::RuntimeException);

    // XServiceInfo
    IMPLEMENTATION_NAME(OComboBoxModel);
    virtual StringSequence SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException);

    // UNO
    DECLARE_UNO3_AGG_DEFAULTS(OComboBoxModel, OBoundControlModel);
    virtual ::com::sun::star::uno::Any SAL_CALL queryAggregation( const ::com::sun::star::uno::Type& _rType ) throw (::com::sun::star::uno::RuntimeException);

    // XPropertySet
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo> SAL_CALL getPropertySetInfo() throw(::com::sun::star::uno::RuntimeException);
    virtual cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper();

    // XPersistObject
    virtual ::rtl::OUString SAL_CALL    getServiceName() throw(::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL
        write(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectOutputStream>& _rxOutStream) throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL
        read(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectInputStream>& _rxInStream) throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);

    // OAggregationArrayUsageHelper
    virtual void fillProperties(
        ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& /* [out] */ _rProps,
        ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& /* [out] */ _rAggregateProps
        ) const;
    IMPLEMENT_INFO_SERVICE()

    // XEventListener
    virtual void SAL_CALL disposing(const ::com::sun::star::lang::EventObject& Source) throw (::com::sun::star::uno::RuntimeException);

protected:
    // OBoundControlModel overridables
    virtual ::com::sun::star::uno::Any
                            translateDbColumnToControlValue( );
    virtual sal_Bool        commitControlValueToDbColumn( bool _bPostReset );

    virtual void            onConnectedDbColumn( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _rxForm );
    virtual void            onDisconnectedDbColumn();

    virtual ::com::sun::star::uno::Any
                            getDefaultForReset() const;

    virtual sal_Bool        approveValueBinding( const ::com::sun::star::uno::Reference< ::com::sun::star::form::binding::XValueBinding >& _rxBinding );

    // OEntryListHelper overriables
    virtual void    stringItemListChanged( );
    virtual void    connectedExternalListSource( );
    virtual void    disconnectedExternalListSource( );

protected:
    void loadData();

    DECLARE_XCLONEABLE();
};

//==================================================================
// OComboBoxControl
//==================================================================

class OComboBoxControl : public OBoundControl
{
public:
    OComboBoxControl(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& _rxFactory);

    // XServiceInfo
    IMPLEMENTATION_NAME(OComboBoxControl);
    virtual StringSequence SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException);
};

//.........................................................................
}
//.........................................................................

#endif // _FORMS_COMBOBOX_HXX_

<|endoftext|>