<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2006 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/
// stl
#include <iostream>
// boost
#include <boost/optional.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/tokenizer.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>
// mapnik
#include <mapnik/color.hpp>
#include <mapnik/color_factory.hpp>
#include <mapnik/filter_factory.hpp>
#include <mapnik/layer.hpp>
#include <mapnik/datasource_cache.hpp>

#include <mapnik/load_map.hpp>

using boost::lexical_cast;
using boost::bad_lexical_cast;
using boost::tokenizer;

namespace mapnik
{
    void load_map(Map & map, std::string const& filename)
    {
        using boost::property_tree::ptree;
        ptree pt;

        read_xml(filename,pt);

        boost::optional<std::string> bgcolor =
            pt.get_optional<std::string>("Map.<xmlattr>.bgcolor");
        if ( bgcolor)
        {
            Color bg = color_factory::from_string(bgcolor->c_str());
            map.setBackground(bg);
        }

        ptree::const_iterator itr = pt.get_child("Map").begin();
        ptree::const_iterator end = pt.get_child("Map").end();
        for (; itr != end; ++itr)
        {
            ptree::value_type const& v = *itr;

            if (v.first == "Style")
            {
                std::string name = v.second.get<std::string>("<xmlattr>.name");
                feature_type_style style;

                ptree::const_iterator ruleIter = v.second.begin();
                ptree::const_iterator endRule = v.second.end();

                for (; ruleIter!=endRule; ++ruleIter)
                {
                    ptree::value_type const& rule_tag = *ruleIter;
                    if (rule_tag.first == "Rule")
                    {
                        std::string name =
                            rule_tag.second.get<std::string>("<xmlattr>.name","");
                        std::string title =
                            rule_tag.second.get<std::string>("<xmlattr>.title","");
                        rule_type rule(name,title);

                        boost::optional<std::string> filter_expr =
                            rule_tag.second.get_optional<std::string>("Filter");

                        if (filter_expr)
                        {
                            rule.set_filter(create_filter(*filter_expr));
                        }

                        boost::optional<double> min_scale =
                            rule_tag.second.get_optional<double>("MinScaleDenominator");
                        if (min_scale)
                        {
                            rule.set_min_scale(*min_scale);
                        }

                        boost::optional<double> max_scale =
                            rule_tag.second.get_optional<double>("MaxScaleDenominator");
                        if (max_scale)
                        {
                            rule.set_max_scale(*max_scale);
                        }

                        ptree::const_iterator symIter = rule_tag.second.begin();
                        ptree::const_iterator endSym = rule_tag.second.end();

                        for( ;symIter != endSym; ++symIter)
                        {
                            ptree::value_type const& sym = *symIter;

                            if ( sym.first == "PointSymbolizer")
                            {
                                std::cout << sym.first << "\n";
                            }
                            else  if ( sym.first == "LineSymbolizer")
                            {
                                stroke strk;
                                ptree::const_iterator cssIter = sym.second.begin();
                                ptree::const_iterator endCss = sym.second.end();

                                for(; cssIter != endCss; ++cssIter)
                                {
                                    ptree::value_type const& css = * cssIter;
                                    std::string css_name  =
                                        css.second.get<std::string>("<xmlattr>.name");
                                    std::string data = css.second.data();
                                    if (css_name == "stroke")
                                    {
                                        Color c = color_factory::from_string(css.second.data().c_str());
                                        strk.set_color(c);
                                    }
                                    else if (css_name == "stroke-width")
                                    {
                                        try
                                        {
                                            float width = lexical_cast<float>(data);
                                            strk.set_width(width);
                                        }
                                        catch (bad_lexical_cast & ex)
                                        {
                                            std::clog << ex.what() << "\n";
                                        }
                                    }
                                    else if (css_name == "stroke-opacity")
                                    {
                                        try
                                        {
                                            float opacity = lexical_cast<float>(data);
                                            strk.set_opacity(opacity);
                                        }
                                        catch (bad_lexical_cast & ex)
                                        {
                                            std::clog << ex.what() << "\n";
                                        }
                                    }
                                    else if (css_name == "stroke-linejoin")
                                    {
                                         if ("miter" == data)
                                         {
                                             strk.set_line_join(mapnik::MITER_JOIN);
                                         }
                                         else if ("round" == data)
                                         {
                                             strk.set_line_join(mapnik::ROUND_JOIN);
                                         }
                                         else if ("bevel" == data)
                                         {
                                             strk.set_line_join(mapnik::BEVEL_JOIN);
                                         }
                                    }
                                    else if (css_name == "stroke-linecap")
                                    {
                                        if ("round" == data)
                                        {
                                            strk.set_line_cap(mapnik::ROUND_CAP);
                                        }
                                        else if ("butt" == data)
                                        {
                                            strk.set_line_cap(mapnik::BUTT_CAP);
                                        }
                                        else if ("square" == data)
                                        {
                                            strk.set_line_cap(mapnik::SQUARE_CAP);
                                        }
                                    }
                                    else if (css_name == "stroke-dasharray")
                                    {
                                        tokenizer<> tok (data);
                                        std::vector<float> dash_array;
                                        for (tokenizer<>::iterator itr = tok.begin(); itr != tok.end(); ++itr)
                                        {
                                            try
                                            {
                                                float f = boost::lexical_cast<float>(*itr);
                                                dash_array.push_back(f);
                                            }
                                            catch ( boost::bad_lexical_cast & ex)
                                            {
                                                std::clog << ex.what() << "\n";
                                            }
                                        }
                                        if (dash_array.size())
                                        {
                                            size_t size = dash_array.size();
                                            if ( size % 2)
                                            {
                                                for (size_t i=0; i < size ;++i)
                                                {
                                                    dash_array.push_back(dash_array[i]);
                                                }
                                            }
                                            std::vector<float>::const_iterator pos = dash_array.begin();
                                            while (pos != dash_array.end())
                                            {
                                                strk.add_dash(*pos,*(pos + 1));
                                                pos +=2;
                                            }
                                        }
                                    }
                                }
                                rule.append(line_symbolizer(strk));
                            }
                            else if ( sym.first == "PolygonSymbolizer")
                            {
                                polygon_symbolizer poly_sym;

                                ptree::const_iterator cssIter = sym.second.begin();
                                ptree::const_iterator endCss = sym.second.end();

                                for(; cssIter != endCss; ++cssIter)
                                {
                                    ptree::value_type const& css = * cssIter;

                                    std::string css_name  =
                                        css.second.get<std::string>("<xmlattr>.name");
                                    std::string data = css.second.data();
                                    if (css_name == "fill")
                                    {
                                        Color c = color_factory::from_string(css.second.data().c_str());
                                        poly_sym.set_fill(c);
                                    }
                                    else if (css_name == "fill-opacity")
                                    {
                                        try
                                        {
                                            float opacity = lexical_cast<float>(data);
                                            poly_sym.set_opacity(opacity);
                                        }
                                        catch (bad_lexical_cast & ex)
                                        {
                                            std::clog << ex.what() << "\n";
                                        }
                                    }
                                }
                                rule.append(poly_sym);
                            }
                            else if ( sym.first == "TextSymbolizer")
                            {
                                std::cout << sym.first << "\n";
                            }
                            else if ( sym.first == "RasterSymbolizer")
                            {
                                rule.append(raster_symbolizer());
                            }
                        }

                        style.add_rule(rule);
                    }
                }

                map.insert_style(name, style);

            }
            else if (v.first == "Layer")
            {

                std::string name = v.second.get<std::string>("<xmlattr>.name","");
                Layer lyr(name);

                boost::optional<std::string> status =
                    v.second.get<std::string>("<xmlattr>.status");

                if (status && *status == "off")
                {
                    lyr.setActive(false);
                }

                ptree::const_iterator itr2 = v.second.begin();
                ptree::const_iterator end2 = v.second.end();

                for(; itr2 != end2; ++itr2)
                {
                    ptree::value_type const& child = *itr2;

                    if (child.first == "StyleName")
                    {
                        lyr.add_style(child.second.data());
                    }
                    else if (child.first == "Datasource")
                    {
                        parameters params;
                        ptree::const_iterator paramIter = child.second.begin();
                        ptree::const_iterator endParam = child.second.end();
                        for (; paramIter != endParam; ++paramIter)
                        {
                            ptree::value_type const& param_tag=*paramIter;

                            if (param_tag.first == "Parameter")
                            {
                                std::string name = param_tag.second.get<std::string>("<xmlattr>.name");
                                std::string value = param_tag.second.data();
                                std::clog << "name = " << name << " value = " << value << "\n";
                                params[name] = value;
                            }
                        }
                        //now we're ready to create datasource
                        boost::shared_ptr<datasource> ds = datasource_cache::instance()->create(params);
                        lyr.set_datasource(ds);
                    }
                }
                map.addLayer(lyr);
            }
        }
    }
}
<commit_msg>added <ElseFilter/> tag support in map loader.<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2006 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/
// stl
#include <iostream>
// boost
#include <boost/optional.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/tokenizer.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>
// mapnik
#include <mapnik/color.hpp>
#include <mapnik/color_factory.hpp>
#include <mapnik/filter_factory.hpp>
#include <mapnik/layer.hpp>
#include <mapnik/datasource_cache.hpp>

#include <mapnik/load_map.hpp>

using boost::lexical_cast;
using boost::bad_lexical_cast;
using boost::tokenizer;

namespace mapnik
{
    void load_map(Map & map, std::string const& filename)
    {
        using boost::property_tree::ptree;
        ptree pt;

        read_xml(filename,pt);

        boost::optional<std::string> bgcolor =
            pt.get_optional<std::string>("Map.<xmlattr>.bgcolor");
        if ( bgcolor)
        {
            Color bg = color_factory::from_string(bgcolor->c_str());
            map.setBackground(bg);
        }

        ptree::const_iterator itr = pt.get_child("Map").begin();
        ptree::const_iterator end = pt.get_child("Map").end();
        for (; itr != end; ++itr)
        {
            ptree::value_type const& v = *itr;

            if (v.first == "Style")
            {
                std::string name = v.second.get<std::string>("<xmlattr>.name");
                feature_type_style style;

                ptree::const_iterator ruleIter = v.second.begin();
                ptree::const_iterator endRule = v.second.end();

                for (; ruleIter!=endRule; ++ruleIter)
                {
                    ptree::value_type const& rule_tag = *ruleIter;
                    if (rule_tag.first == "Rule")
                    {
                        std::string name =
                            rule_tag.second.get<std::string>("<xmlattr>.name","");
                        std::string title =
                            rule_tag.second.get<std::string>("<xmlattr>.title","");
                        rule_type rule(name,title);

                        boost::optional<std::string> filter_expr =
                            rule_tag.second.get_optional<std::string>("Filter");

                        if (filter_expr)
                        {
                            rule.set_filter(create_filter(*filter_expr));
                        }
                        boost::optional<std::string> else_filter =
                            rule_tag.second.get_optional<std::string>("ElseFilter");
                        if (else_filter)
                        {
                            rule.set_else(true);
                        }

                        boost::optional<double> min_scale =
                            rule_tag.second.get_optional<double>("MinScaleDenominator");
                        if (min_scale)
                        {
                            rule.set_min_scale(*min_scale);
                        }

                        boost::optional<double> max_scale =
                            rule_tag.second.get_optional<double>("MaxScaleDenominator");
                        if (max_scale)
                        {
                            rule.set_max_scale(*max_scale);
                        }

                        ptree::const_iterator symIter = rule_tag.second.begin();
                        ptree::const_iterator endSym = rule_tag.second.end();

                        for( ;symIter != endSym; ++symIter)
                        {
                            ptree::value_type const& sym = *symIter;

                            if ( sym.first == "PointSymbolizer")
                            {
                                std::cout << sym.first << "\n";
                            }
                            else  if ( sym.first == "LineSymbolizer")
                            {
                                stroke strk;
                                ptree::const_iterator cssIter = sym.second.begin();
                                ptree::const_iterator endCss = sym.second.end();

                                for(; cssIter != endCss; ++cssIter)
                                {
                                    ptree::value_type const& css = * cssIter;
                                    std::string css_name  =
                                        css.second.get<std::string>("<xmlattr>.name");
                                    std::string data = css.second.data();
                                    if (css_name == "stroke")
                                    {
                                        Color c = color_factory::from_string(css.second.data().c_str());
                                        strk.set_color(c);
                                    }
                                    else if (css_name == "stroke-width")
                                    {
                                        try
                                        {
                                            float width = lexical_cast<float>(data);
                                            strk.set_width(width);
                                        }
                                        catch (bad_lexical_cast & ex)
                                        {
                                            std::clog << ex.what() << "\n";
                                        }
                                    }
                                    else if (css_name == "stroke-opacity")
                                    {
                                        try
                                        {
                                            float opacity = lexical_cast<float>(data);
                                            strk.set_opacity(opacity);
                                        }
                                        catch (bad_lexical_cast & ex)
                                        {
                                            std::clog << ex.what() << "\n";
                                        }
                                    }
                                    else if (css_name == "stroke-linejoin")
                                    {
                                         if ("miter" == data)
                                         {
                                             strk.set_line_join(mapnik::MITER_JOIN);
                                         }
                                         else if ("round" == data)
                                         {
                                             strk.set_line_join(mapnik::ROUND_JOIN);
                                         }
                                         else if ("bevel" == data)
                                         {
                                             strk.set_line_join(mapnik::BEVEL_JOIN);
                                         }
                                    }
                                    else if (css_name == "stroke-linecap")
                                    {
                                        if ("round" == data)
                                        {
                                            strk.set_line_cap(mapnik::ROUND_CAP);
                                        }
                                        else if ("butt" == data)
                                        {
                                            strk.set_line_cap(mapnik::BUTT_CAP);
                                        }
                                        else if ("square" == data)
                                        {
                                            strk.set_line_cap(mapnik::SQUARE_CAP);
                                        }
                                    }
                                    else if (css_name == "stroke-dasharray")
                                    {
                                        tokenizer<> tok (data);
                                        std::vector<float> dash_array;
                                        for (tokenizer<>::iterator itr = tok.begin(); itr != tok.end(); ++itr)
                                        {
                                            try
                                            {
                                                float f = boost::lexical_cast<float>(*itr);
                                                dash_array.push_back(f);
                                            }
                                            catch ( boost::bad_lexical_cast & ex)
                                            {
                                                std::clog << ex.what() << "\n";
                                            }
                                        }
                                        if (dash_array.size())
                                        {
                                            size_t size = dash_array.size();
                                            if ( size % 2)
                                            {
                                                for (size_t i=0; i < size ;++i)
                                                {
                                                    dash_array.push_back(dash_array[i]);
                                                }
                                            }
                                            std::vector<float>::const_iterator pos = dash_array.begin();
                                            while (pos != dash_array.end())
                                            {
                                                strk.add_dash(*pos,*(pos + 1));
                                                pos +=2;
                                            }
                                        }
                                    }
                                }
                                rule.append(line_symbolizer(strk));
                            }
                            else if ( sym.first == "PolygonSymbolizer")
                            {
                                polygon_symbolizer poly_sym;

                                ptree::const_iterator cssIter = sym.second.begin();
                                ptree::const_iterator endCss = sym.second.end();

                                for(; cssIter != endCss; ++cssIter)
                                {
                                    ptree::value_type const& css = * cssIter;

                                    std::string css_name  =
                                        css.second.get<std::string>("<xmlattr>.name");
                                    std::string data = css.second.data();
                                    if (css_name == "fill")
                                    {
                                        Color c = color_factory::from_string(css.second.data().c_str());
                                        poly_sym.set_fill(c);
                                    }
                                    else if (css_name == "fill-opacity")
                                    {
                                        try
                                        {
                                            float opacity = lexical_cast<float>(data);
                                            poly_sym.set_opacity(opacity);
                                        }
                                        catch (bad_lexical_cast & ex)
                                        {
                                            std::clog << ex.what() << "\n";
                                        }
                                    }
                                }
                                rule.append(poly_sym);
                            }
                            else if ( sym.first == "TextSymbolizer")
                            {
                                std::cout << sym.first << "\n";
                            }
                            else if ( sym.first == "RasterSymbolizer")
                            {
                                rule.append(raster_symbolizer());
                            }
                        }

                        style.add_rule(rule);
                    }
                }

                map.insert_style(name, style);

            }
            else if (v.first == "Layer")
            {

                std::string name = v.second.get<std::string>("<xmlattr>.name","");
                Layer lyr(name);

                boost::optional<std::string> status =
                    v.second.get<std::string>("<xmlattr>.status");

                if (status && *status == "off")
                {
                    lyr.setActive(false);
                }

                ptree::const_iterator itr2 = v.second.begin();
                ptree::const_iterator end2 = v.second.end();

                for(; itr2 != end2; ++itr2)
                {
                    ptree::value_type const& child = *itr2;

                    if (child.first == "StyleName")
                    {
                        lyr.add_style(child.second.data());
                    }
                    else if (child.first == "Datasource")
                    {
                        parameters params;
                        ptree::const_iterator paramIter = child.second.begin();
                        ptree::const_iterator endParam = child.second.end();
                        for (; paramIter != endParam; ++paramIter)
                        {
                            ptree::value_type const& param_tag=*paramIter;

                            if (param_tag.first == "Parameter")
                            {
                                std::string name = param_tag.second.get<std::string>("<xmlattr>.name");
                                std::string value = param_tag.second.data();
                                std::clog << "name = " << name << " value = " << value << "\n";
                                params[name] = value;
                            }
                        }
                        //now we're ready to create datasource
                        boost::shared_ptr<datasource> ds = datasource_cache::instance()->create(params);
                        lyr.set_datasource(ds);
                    }
                }
                map.addLayer(lyr);
            }
        }
    }
}
<|endoftext|>


<commit_before>#include "engine.h"
#include "random.h"
#include "gameEntity.h"
#include "Updatable.h"
#include "collisionable.h"

#ifdef DEBUG
#include <typeinfo>
int DEBUG_PobjCount;
PObject* DEBUG_PobjListStart;
#endif

#ifdef ENABLE_CRASH_LOGGER
#ifdef __WIN32__
//Exception handler for mingw, from https://github.com/jrfonseca/drmingw
#include <exchndl.h>
#endif//__WIN32__
#endif//ENABLE_CRASH_LOGGER

Engine* engine;

Engine::Engine()
{
    engine = this;
#ifdef ENABLE_CRASH_LOGGER
#ifdef __WIN32__
    ExcHndlInit();
#endif//__WIN32__
#endif//ENABLE_CRASH_LOGGER
    initRandom();
    windowManager = nullptr;
    CollisionManager::initialize();
    InputHandler::initialize();
    gameSpeed = 1.0;
    running = true;
    elapsedTime = 0.0;

    soundManager = new SoundManager();
}
Engine::~Engine()
{
    if (windowManager)
        windowManager->close();
    delete soundManager;
    soundManager = nullptr;
}

void Engine::registerObject(string name, P<PObject> obj)
{
    objectMap[name] = obj;
}

P<PObject> Engine::getObject(string name)
{
    if (!objectMap[name])
        return NULL;
    return objectMap[name];
}

void Engine::runMainLoop()
{
    windowManager = dynamic_cast<WindowManager*>(*getObject("windowManager"));
    if (!windowManager)
    {
        sf::Clock frameTimeClock;
        while(running)
        {
            float delta = frameTimeClock.getElapsedTime().asSeconds();
            frameTimeClock.restart();
            if (delta > 0.5)
                delta = 0.5;
            if (delta < 0.001)
                delta = 0.001;
            delta *= gameSpeed;

            entityList.update();
            foreach(Updatable, u, updatableList)
                u->update(delta);
            elapsedTime += delta;
            CollisionManager::handleCollisions(delta);
            ScriptObject::clearDestroyedObjects();
            soundManager->updateTick();

            sf::sleep(sf::seconds(1.0/60.0 - delta));
            //if (elapsedTime > 2.0)
            //    break;
        }
    }else{
        sf::Clock frameTimeClock;
#ifdef DEBUG
        sf::Clock debugOutputClock;
#endif
        while(running && windowManager->window.isOpen())
        {
            InputHandler::preEventsUpdate();
            // Handle events
            sf::Event event;
            while (windowManager->window.pollEvent(event))
            {
                handleEvent(event);
            }
            InputHandler::postEventsUpdate();

#ifdef DEBUG
            if (sf::Keyboard::isKeyPressed(sf::Keyboard::Escape) && windowManager->hasFocus())
                running = false;

            if (debugOutputClock.getElapsedTime().asSeconds() > 1.0)
            {
                printf("Object count: %4d %4d %4d\n", DEBUG_PobjCount, updatableList.size(), entityList.size());
                debugOutputClock.restart();
            }
#endif

            float delta = frameTimeClock.restart().asSeconds();
            if (delta > 0.5)
                delta = 0.5;
            if (delta < 0.001)
                delta = 0.001;
            delta *= gameSpeed;
#ifdef DEBUG
            if (sf::Keyboard::isKeyPressed(sf::Keyboard::Tab))
                delta /= 5.0;
            if (sf::Keyboard::isKeyPressed(sf::Keyboard::Tilde))
                delta *= 5.0;
#endif
            EngineTiming engine_timing;

            sf::Clock engine_timing_clock;
            entityList.update();
            foreach(Updatable, u, updatableList)
                u->update(delta);
            elapsedTime += delta;
            engine_timing.update = engine_timing_clock.restart().asSeconds();
            CollisionManager::handleCollisions(delta);
            engine_timing.collision = engine_timing_clock.restart().asSeconds();
            ScriptObject::clearDestroyedObjects();
            soundManager->updateTick();

            // Clear the window
            windowManager->render();
            engine_timing.render = engine_timing_clock.restart().asSeconds();
            engine_timing.server_update = 0.0f;
            if (game_server)
                engine_timing.server_update = game_server->getUpdateTime();

            last_engine_timing = engine_timing;
        }
        soundManager->stopMusic();
    }
}

void Engine::handleEvent(sf::Event& event)
{
    // Window closed: exit
    if ((event.type == sf::Event::Closed))
        running = false;
    if (event.type == sf::Event::GainedFocus)
        windowManager->windowHasFocus = true;
    if (event.type == sf::Event::LostFocus)
        windowManager->windowHasFocus = false;
#ifdef DEBUG
    if ((event.type == sf::Event::KeyPressed) && (event.key.code == sf::Keyboard::L))
    {
        int n = 0;
        printf("---------------------\n");
        for(PObject* obj = DEBUG_PobjListStart; obj; obj = obj->DEBUG_PobjListNext)
            printf("%c%4d: %4d: %s\n", obj->isDestroyed() ? '>' : ' ', n++, obj->getRefCount(), typeid(*obj).name());
        printf("---------------------\n");
    }
#endif
    InputHandler::handleEvent(event);
    if (event.type == sf::Event::Resized)
        windowManager->setupView();
#ifdef __ANDROID__
    //Focus lost and focus gained events are used when the application window is created and destroyed.
    if (event.type == sf::Event::LostFocus)
        running = false;

    //The MouseEntered and MouseLeft events are received when the activity needs to pause or resume.
    if (event.type == sf::Event::MouseLeft)
    {
        //Pause is when a small popup is on top of the window. So keep running.
        while(windowManager->window.isOpen() && windowManager->window.waitEvent(event))
        {
            if (event.type != sf::Event::MouseLeft)
                handleEvent(event);
            if (event.type == sf::Event::MouseEntered)
                break;
        }
    }
#endif//__ANDROID__
}

void Engine::setGameSpeed(float speed)
{
    gameSpeed = speed;
}

float Engine::getGameSpeed()
{
    return gameSpeed;
}

float Engine::getElapsedTime()
{
    return elapsedTime;
}

Engine::EngineTiming Engine::getEngineTiming()
{
    return last_engine_timing;
}

void Engine::shutdown()
{
    running = false;
}
<commit_msg>Enable floating point exceptions.<commit_after>#include "engine.h"
#include "random.h"
#include "gameEntity.h"
#include "Updatable.h"
#include "collisionable.h"

#ifdef __linux__
#include <fenv.h>
#endif
#ifdef __WIN32__
#include <float.h>
#endif

#ifdef DEBUG
#include <typeinfo>
int DEBUG_PobjCount;
PObject* DEBUG_PobjListStart;
#endif

#ifdef ENABLE_CRASH_LOGGER
#ifdef __WIN32__
//Exception handler for mingw, from https://github.com/jrfonseca/drmingw
#include <exchndl.h>
#endif//__WIN32__
#endif//ENABLE_CRASH_LOGGER

Engine* engine;

Engine::Engine()
{
    engine = this;
#ifdef ENABLE_CRASH_LOGGER
#ifdef __WIN32__
    ExcHndlInit();
#endif//__WIN32__
#endif//ENABLE_CRASH_LOGGER
#ifdef __linux__
    feenableexcept(FE_DIVBYZERO | FE_INVALID);
#endif
#ifdef __WIN32__
    unsigned int current_word = 0;
    _controlfp_s(&current_word, _EM_INVALID | _EM_ZERODIVIDE, _MCW_EM);
#endif
    initRandom();
    windowManager = nullptr;
    CollisionManager::initialize();
    InputHandler::initialize();
    gameSpeed = 1.0;
    running = true;
    elapsedTime = 0.0;

    soundManager = new SoundManager();
}
Engine::~Engine()
{
    if (windowManager)
        windowManager->close();
    delete soundManager;
    soundManager = nullptr;
}

void Engine::registerObject(string name, P<PObject> obj)
{
    objectMap[name] = obj;
}

P<PObject> Engine::getObject(string name)
{
    if (!objectMap[name])
        return NULL;
    return objectMap[name];
}

void Engine::runMainLoop()
{
    windowManager = dynamic_cast<WindowManager*>(*getObject("windowManager"));
    if (!windowManager)
    {
        sf::Clock frameTimeClock;
        while(running)
        {
            float delta = frameTimeClock.getElapsedTime().asSeconds();
            frameTimeClock.restart();
            if (delta > 0.5)
                delta = 0.5;
            if (delta < 0.001)
                delta = 0.001;
            delta *= gameSpeed;

            entityList.update();
            foreach(Updatable, u, updatableList)
                u->update(delta);
            elapsedTime += delta;
            CollisionManager::handleCollisions(delta);
            ScriptObject::clearDestroyedObjects();
            soundManager->updateTick();

            sf::sleep(sf::seconds(1.0/60.0 - delta));
            //if (elapsedTime > 2.0)
            //    break;
        }
    }else{
        sf::Clock frameTimeClock;
#ifdef DEBUG
        sf::Clock debugOutputClock;
#endif
        while(running && windowManager->window.isOpen())
        {
            InputHandler::preEventsUpdate();
            // Handle events
            sf::Event event;
            while (windowManager->window.pollEvent(event))
            {
                handleEvent(event);
            }
            InputHandler::postEventsUpdate();

#ifdef DEBUG
            if (sf::Keyboard::isKeyPressed(sf::Keyboard::Escape) && windowManager->hasFocus())
                running = false;

            if (debugOutputClock.getElapsedTime().asSeconds() > 1.0)
            {
                printf("Object count: %4d %4d %4d\n", DEBUG_PobjCount, updatableList.size(), entityList.size());
                debugOutputClock.restart();
            }
#endif

            float delta = frameTimeClock.restart().asSeconds();
            if (delta > 0.5)
                delta = 0.5;
            if (delta < 0.001)
                delta = 0.001;
            delta *= gameSpeed;
#ifdef DEBUG
            if (sf::Keyboard::isKeyPressed(sf::Keyboard::Tab))
                delta /= 5.0;
            if (sf::Keyboard::isKeyPressed(sf::Keyboard::Tilde))
                delta *= 5.0;
#endif
            EngineTiming engine_timing;

            sf::Clock engine_timing_clock;
            entityList.update();
            foreach(Updatable, u, updatableList)
                u->update(delta);
            elapsedTime += delta;
            engine_timing.update = engine_timing_clock.restart().asSeconds();
            CollisionManager::handleCollisions(delta);
            engine_timing.collision = engine_timing_clock.restart().asSeconds();
            ScriptObject::clearDestroyedObjects();
            soundManager->updateTick();

            // Clear the window
            windowManager->render();
            engine_timing.render = engine_timing_clock.restart().asSeconds();
            engine_timing.server_update = 0.0f;
            if (game_server)
                engine_timing.server_update = game_server->getUpdateTime();

            last_engine_timing = engine_timing;
        }
        soundManager->stopMusic();
    }
}

void Engine::handleEvent(sf::Event& event)
{
    // Window closed: exit
    if ((event.type == sf::Event::Closed))
        running = false;
    if (event.type == sf::Event::GainedFocus)
        windowManager->windowHasFocus = true;
    if (event.type == sf::Event::LostFocus)
        windowManager->windowHasFocus = false;
#ifdef DEBUG
    if ((event.type == sf::Event::KeyPressed) && (event.key.code == sf::Keyboard::L))
    {
        int n = 0;
        printf("---------------------\n");
        for(PObject* obj = DEBUG_PobjListStart; obj; obj = obj->DEBUG_PobjListNext)
            printf("%c%4d: %4d: %s\n", obj->isDestroyed() ? '>' : ' ', n++, obj->getRefCount(), typeid(*obj).name());
        printf("---------------------\n");
    }
#endif
    InputHandler::handleEvent(event);
    if (event.type == sf::Event::Resized)
        windowManager->setupView();
#ifdef __ANDROID__
    //Focus lost and focus gained events are used when the application window is created and destroyed.
    if (event.type == sf::Event::LostFocus)
        running = false;

    //The MouseEntered and MouseLeft events are received when the activity needs to pause or resume.
    if (event.type == sf::Event::MouseLeft)
    {
        //Pause is when a small popup is on top of the window. So keep running.
        while(windowManager->window.isOpen() && windowManager->window.waitEvent(event))
        {
            if (event.type != sf::Event::MouseLeft)
                handleEvent(event);
            if (event.type == sf::Event::MouseEntered)
                break;
        }
    }
#endif//__ANDROID__
}

void Engine::setGameSpeed(float speed)
{
    gameSpeed = speed;
}

float Engine::getGameSpeed()
{
    return gameSpeed;
}

float Engine::getElapsedTime()
{
    return elapsedTime;
}

Engine::EngineTiming Engine::getEngineTiming()
{
    return last_engine_timing;
}

void Engine::shutdown()
{
    running = false;
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2015 Luke San Antonio
 * All rights reserved.
 */
#include <fstream>
#include <sstream>
#include <cstdlib>
#include <vector>
#include <thread>
#include <chrono>

#include "common/log.h"

#include "gfx/gl/driver.h"
#include "gfx/camera.h"
#include "gfx/mesh_chunk.h"
#include "gfx/support/load_wavefront.h"
#include "gfx/support/mesh_conversion.h"
#include "gfx/support/generate_aabb.h"
#include "gfx/support/write_data_to_mesh.h"
#include "gfx/support/texture_load.h"
#include "gfx/support/format.h"
#include "gfx/support/allocate.h"
#include "gfx/support/json.h"

#include "collisionlib/triangle_conversion.h"
#include "collisionlib/triangle.h"

#include "common/json.h"

#include "fps/camera_controller.h"

#include "glad/glad.h"
#include "glfw3.h"

#define GLM_FORCE_RADIANS
#include "glm/glm.hpp"
#include "glm/gtc/matrix_transform.hpp"

#include "uv.h"

#define CATCH_CONFIG_RUNNER
#include "catch/catch.hpp"

#define PI 3.141592653589793238463

int main(int argc, char** argv)
{
  using namespace game;

  set_log_level(Log_Severity::Debug);

  uv_chdir("assets/");

  // Initialize logger.
  Scoped_Log_Init log_init_raii_lock{};

  // Init glfw.
  if(!glfwInit())
    return EXIT_FAILURE;

  auto window = glfwCreateWindow(1000, 1000, "Hello World", NULL, NULL);
  if(!window)
  {
    glfwTerminate();
    return EXIT_FAILURE;
  }

  // Init context + load gl functions.
  glfwMakeContextCurrent(window);
  gladLoadGLLoader((GLADloadproc) glfwGetProcAddress);

  // Log glfw version.
  log_i("Initialized GLFW %", glfwGetVersionString());

  int maj = glfwGetWindowAttrib(window, GLFW_CONTEXT_VERSION_MAJOR);
  int min = glfwGetWindowAttrib(window, GLFW_CONTEXT_VERSION_MINOR);
  int rev = glfwGetWindowAttrib(window, GLFW_CONTEXT_REVISION);

  // Log GL profile.
  log_i("OpenGL core profile %.%.%", maj, min, rev);

  // Hide the mouse and capture it
  glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);

  auto scene = load_json("scene/fps.json");

  auto player_position = vec3_from_js(scene["player_pos"]);

  {
    // Make an OpenGL driver.
    gfx::gl::Driver driver{Vec<int>{1000, 1000}};

    auto shader = driver.make_shader_repr();
    shader->load_vertex_part("shader/basic/v");
    shader->load_fragment_part("shader/basic/f");

    // We need to get rid of dependency on these in the future.
    shader->set_diffuse_name("dif");
    shader->set_projection_name("proj");
    shader->set_view_name("view");
    shader->set_model_name("model");
    shader->set_sampler_name("tex");

    driver.use_shader(*shader);

    shader->set_sampler(0);

    // Get all our textures
    auto brick = driver.make_texture_repr();
    load_png("tex/cracked_soil.png", *brick);
    auto grass = driver.make_texture_repr();
    load_png("tex/grass.png", *grass);

    auto terrain_tex = driver.make_texture_repr();
    load_png("tex/topdown_terrain.png", *terrain_tex);

    // Make an fps camera.
    auto cam = gfx::make_fps_camera();
    cam.fp.pos = player_position;

    auto cam_controller = fps::Camera_Controller{};
    cam_controller.camera(cam);

    cam_controller.set_pitch_limit(PI / 2);

    // TODO put the house on the scene at a fixed location.
    Maybe_Owned<Mesh> terrain = driver.make_mesh_repr();
    auto terrain_data =
      gfx::to_indexed_mesh_data(gfx::load_wavefront("obj/fps_terrain.obj"));

    gfx::allocate_standard_mesh_buffers(terrain_data.vertices.size(),
                                        terrain_data.elements.size(),
                                        *terrain, Usage_Hint::Draw,
                                        Upload_Hint::Static);
    auto ter_chunk = gfx::write_data_to_mesh(terrain_data, std::move(terrain));
    gfx::format_standard_mesh_buffers(*terrain);

    auto triangles = triangles_from_mesh_data(terrain_data);

    auto terrain_model = glm::mat4(1.0f);

    int fps = 0;
    int time = glfwGetTime();

    // Set up some pre-rendering state.
    driver.clear_color_value(Color{0x55, 0x66, 0x77});
    driver.clear_depth_value(1.0);

    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LEQUAL);

    double prev_x, prev_y;
    glfwPollEvents();
    glfwGetCursorPos(window, &prev_x, &prev_y);

    shader->set_diffuse(colors::white);
    driver.bind_texture(*terrain_tex, 0);
    shader->set_model(terrain_model);

    while(!glfwWindowShouldClose(window))
    {
      ++fps;

      glfwPollEvents();

      if(glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
      {
        glfwSetWindowShouldClose(window, true);
      }

      glm::vec4 delta_movement;
      if(glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
      {
        delta_movement.z -= 1.0f;
      }
      if(glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
      {
        delta_movement.x -= 1.0f;
      }
      if(glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
      {
        delta_movement.z += 1.0f;
      }
      if(glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
      {
        delta_movement.x += 1.0f;
      }

      delta_movement *= .005;

      delta_movement = delta_movement *
        glm::rotate(glm::mat4(1.0f), cam.fp.yaw, glm::vec3(0.0f, 1.0f, 0.0f));

      double x, y;
      glfwGetCursorPos(window, &x, &y);
      cam_controller.apply_delta_pitch(y / 250.0 - prev_y / 250.0);
      cam_controller.apply_delta_yaw(x / 250.0 - prev_x / 250.0);
      prev_x = x, prev_y = y;

      cam.fp.pos.x += delta_movement.x;
      cam.fp.pos.z += delta_movement.z;

      // Find the height at cam.fp.pos.
      for(auto const& triangle : triangles)
      {
        if(is_contained(triangle, cam.fp.pos))
        {
          auto bary = to_barycentric_coord(triangle, cam.fp.pos);
          // The order goes u v w, w is the one we found from the others, so
          // it is the first point on the triangle. u is towards 2 and v is
          // towards 1.
          cam.fp.pos.y = triangle.positions[2].y * bary.x +
                         triangle.positions[1].y * bary.y +
                         triangle.positions[0].y * bary.z + 0.5f;
        }
      }

      use_camera(driver, cam);

      // Clear the screen
      driver.clear();

      gfx::render_chunk(ter_chunk);

      glfwSwapBuffers(window);

      if(int(glfwGetTime()) != time)
      {
        time = glfwGetTime();
        log_d("fps: %", fps);
        fps = 0;
      }
    }
  }
  glfwTerminate();
  return 0;
}
<commit_msg>We now have a walking vs running key.<commit_after>/*
 * Copyright (C) 2015 Luke San Antonio
 * All rights reserved.
 */
#include <fstream>
#include <sstream>
#include <cstdlib>
#include <vector>
#include <thread>
#include <chrono>

#include "common/log.h"

#include "gfx/gl/driver.h"
#include "gfx/camera.h"
#include "gfx/mesh_chunk.h"
#include "gfx/support/load_wavefront.h"
#include "gfx/support/mesh_conversion.h"
#include "gfx/support/generate_aabb.h"
#include "gfx/support/write_data_to_mesh.h"
#include "gfx/support/texture_load.h"
#include "gfx/support/format.h"
#include "gfx/support/allocate.h"
#include "gfx/support/json.h"

#include "collisionlib/triangle_conversion.h"
#include "collisionlib/triangle.h"

#include "common/json.h"

#include "fps/camera_controller.h"

#include "glad/glad.h"
#include "glfw3.h"

#define GLM_FORCE_RADIANS
#include "glm/glm.hpp"
#include "glm/gtc/matrix_transform.hpp"

#include "uv.h"

#define CATCH_CONFIG_RUNNER
#include "catch/catch.hpp"

#define PI 3.141592653589793238463

int main(int argc, char** argv)
{
  using namespace game;

  set_log_level(Log_Severity::Debug);

  uv_chdir("assets/");

  // Initialize logger.
  Scoped_Log_Init log_init_raii_lock{};

  // Init glfw.
  if(!glfwInit())
    return EXIT_FAILURE;

  auto window = glfwCreateWindow(1000, 1000, "Hello World", NULL, NULL);
  if(!window)
  {
    glfwTerminate();
    return EXIT_FAILURE;
  }

  // Init context + load gl functions.
  glfwMakeContextCurrent(window);
  gladLoadGLLoader((GLADloadproc) glfwGetProcAddress);

  // Log glfw version.
  log_i("Initialized GLFW %", glfwGetVersionString());

  int maj = glfwGetWindowAttrib(window, GLFW_CONTEXT_VERSION_MAJOR);
  int min = glfwGetWindowAttrib(window, GLFW_CONTEXT_VERSION_MINOR);
  int rev = glfwGetWindowAttrib(window, GLFW_CONTEXT_REVISION);

  // Log GL profile.
  log_i("OpenGL core profile %.%.%", maj, min, rev);

  // Hide the mouse and capture it
  glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);

  auto scene = load_json("scene/fps.json");

  auto player_position = vec3_from_js(scene["player_pos"]);

  {
    // Make an OpenGL driver.
    gfx::gl::Driver driver{Vec<int>{1000, 1000}};

    auto shader = driver.make_shader_repr();
    shader->load_vertex_part("shader/basic/v");
    shader->load_fragment_part("shader/basic/f");

    // We need to get rid of dependency on these in the future.
    shader->set_diffuse_name("dif");
    shader->set_projection_name("proj");
    shader->set_view_name("view");
    shader->set_model_name("model");
    shader->set_sampler_name("tex");

    driver.use_shader(*shader);

    shader->set_sampler(0);

    // Get all our textures
    auto brick = driver.make_texture_repr();
    load_png("tex/cracked_soil.png", *brick);
    auto grass = driver.make_texture_repr();
    load_png("tex/grass.png", *grass);

    auto terrain_tex = driver.make_texture_repr();
    load_png("tex/topdown_terrain.png", *terrain_tex);

    // Make an fps camera.
    auto cam = gfx::make_fps_camera();
    cam.fp.pos = player_position;

    auto cam_controller = fps::Camera_Controller{};
    cam_controller.camera(cam);

    cam_controller.set_pitch_limit(PI / 2);

    // TODO put the house on the scene at a fixed location.
    Maybe_Owned<Mesh> terrain = driver.make_mesh_repr();
    auto terrain_data =
      gfx::to_indexed_mesh_data(gfx::load_wavefront("obj/fps_terrain.obj"));

    gfx::allocate_standard_mesh_buffers(terrain_data.vertices.size(),
                                        terrain_data.elements.size(),
                                        *terrain, Usage_Hint::Draw,
                                        Upload_Hint::Static);
    auto ter_chunk = gfx::write_data_to_mesh(terrain_data, std::move(terrain));
    gfx::format_standard_mesh_buffers(*terrain);

    auto triangles = triangles_from_mesh_data(terrain_data);

    auto terrain_model = glm::mat4(1.0f);

    int fps = 0;
    int time = glfwGetTime();

    // Set up some pre-rendering state.
    driver.clear_color_value(Color{0x55, 0x66, 0x77});
    driver.clear_depth_value(1.0);

    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LEQUAL);

    double prev_x, prev_y;
    glfwPollEvents();
    glfwGetCursorPos(window, &prev_x, &prev_y);

    shader->set_diffuse(colors::white);
    driver.bind_texture(*terrain_tex, 0);
    shader->set_model(terrain_model);

    while(!glfwWindowShouldClose(window))
    {
      ++fps;

      glfwPollEvents();

      if(glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
      {
        glfwSetWindowShouldClose(window, true);
      }

      glm::vec4 delta_movement;
      if(glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
      {
        delta_movement.z -= 1.0f;
      }
      if(glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
      {
        delta_movement.x -= 1.0f;
      }
      if(glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
      {
        delta_movement.z += 1.0f;
      }
      if(glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
      {
        delta_movement.x += 1.0f;
      }

      // Temporary replacement for shift, I just didn't feel like looking it up
      if(glfwGetKey(window, GLFW_KEY_C) == GLFW_PRESS)
      {
        delta_movement *= .0005;
      }
      else
      {
        delta_movement *= .005;
      }

      delta_movement = delta_movement *
        glm::rotate(glm::mat4(1.0f), cam.fp.yaw, glm::vec3(0.0f, 1.0f, 0.0f));

      double x, y;
      glfwGetCursorPos(window, &x, &y);
      cam_controller.apply_delta_pitch(y / 250.0 - prev_y / 250.0);
      cam_controller.apply_delta_yaw(x / 250.0 - prev_x / 250.0);
      prev_x = x, prev_y = y;

      cam.fp.pos.x += delta_movement.x;
      cam.fp.pos.z += delta_movement.z;

      // Find the height at cam.fp.pos.
      for(auto const& triangle : triangles)
      {
        if(is_contained(triangle, cam.fp.pos))
        {
          auto bary = to_barycentric_coord(triangle, cam.fp.pos);
          // The order goes u v w, w is the one we found from the others, so
          // it is the first point on the triangle. u is towards 2 and v is
          // towards 1.
          cam.fp.pos.y = triangle.positions[2].y * bary.x +
                         triangle.positions[1].y * bary.y +
                         triangle.positions[0].y * bary.z + 0.5f;
        }
      }

      use_camera(driver, cam);

      // Clear the screen
      driver.clear();

      gfx::render_chunk(ter_chunk);

      glfwSwapBuffers(window);

      if(int(glfwGetTime()) != time)
      {
        time = glfwGetTime();
        log_d("fps: %", fps);
        fps = 0;
      }
    }
  }
  glfwTerminate();
  return 0;
}
<|endoftext|>


<commit_before>/*
 *  FDOmenu - Menu code generator for icewm
 *  Copyright (C) 2015 Eduard Bloch
 *
 *  Inspired by icewm-menu-gnome2 and Freedesktop.org specifications
 *  Using pure glib/gio code and a built-in menu structure instead
 *  the XML based external definition (as suggested by FD.o specs)
 *
 *  Release under terms of the GNU Library General Public License
 *  (version 2.0)
 *
 *  2015/02/05: Eduard Bloch <edi@gmx.de>
 *  - initial version
 */

#include "config.h"
#include "base.h"
#include "sysdep.h"
#include "intl.h"

const char *g_argv0;

#include <glib.h>
#include <glib/gprintf.h>
#include <glib/gstdio.h>
#include <gio/gdesktopappinfo.h>

typedef GList* pglist;

template<class T>
struct auto_gfree
{
	T *m_p;
	auto_gfree() : m_p(NULL) {};
	auto_gfree(T *xp) : m_p(xp) {};
	~auto_gfree() { g_free(m_p); }
};
struct auto_gunref
{
	GObject *m_p;
	auto_gunref(GObject *xp): m_p(xp) {};
	~auto_gunref() { g_object_unref(m_p); }
};

bool find_in_zArray(const char * const *arrToScan, const char *keyword)
{
	for(const gchar * const * p=arrToScan;*p;++p)
		if(!strcmp(keyword, *p))
			return true;
	return false;
}

// for optional bits that are not consuming much and
// it's OK to leak them, OS will clean up soon enough
//#define FREEASAP
#ifdef FREEASAP
#define opt_g_free(x) g_free(x);
#else
#define opt_g_free(x)
#endif

pglist msettings=0, mscreensavers=0, maccessories=0, mdevelopment=0, meducation=0,
		mgames=0, mgraphics=0, mmultimedia=0, mnetwork=0, moffice=0, msystem=0,
		mother=0, mwine=0, meditors=0;

//#warning needing a dupe filter for filename, maybe use GHashTable for that

void proc_dir(const char *path, unsigned depth=0)
{
	GDir *pdir = g_dir_open (path, 0, NULL);
	if(!pdir)
		return;
	struct tdircloser {
		GDir *m_p;
		tdircloser(GDir *p) : m_p(p) {};
		~tdircloser() { g_dir_close(m_p);}
	} dircloser(pdir);

	const gchar *szFilename(NULL);
	while(NULL != (szFilename = g_dir_read_name (pdir)))
	{
		if(!szFilename)
			continue;
		gchar *szFullName = g_strjoin("/", path, szFilename, NULL);
		auto_gfree<gchar> xxfree(szFullName);
		static GStatBuf buf;
		if(g_stat(szFullName, &buf))
			return;
		if(S_ISDIR(buf.st_mode))
		{
			static ino_t reclog[6];
			for(unsigned i=0; i<depth; ++i)
			{
				if(reclog[i] == buf.st_ino)
					goto dir_visited_before;
			}
			if(depth<ACOUNT(reclog))
			{
				reclog[++depth] = buf.st_ino;
				proc_dir(szFullName, depth);
				--depth;
			}
			dir_visited_before:;
		}

		if(!S_ISREG(buf.st_mode))
			continue;

		GDesktopAppInfo *pInfo = g_desktop_app_info_new_from_filename (szFullName);
		if(!pInfo)
			continue;
		auto_gunref ___pinfo_releaser((GObject*)pInfo);

		if(!g_app_info_should_show((GAppInfo*) pInfo))
			continue;

		const char *cmdraw = g_app_info_get_commandline ((GAppInfo*) pInfo);
		if(!cmdraw || !*cmdraw)
			continue;

		// let's whitespace all special fields that we don't support
		gchar * cmd = g_strdup(cmdraw);
		auto_gfree<gchar> cmdfree(cmd);
		bool bDelChars=false;
		for(gchar *p=cmd; *p; ++p)
		{
			if('%' == *p)
				bDelChars=true;
			if(bDelChars)
				*p = ' ';
			if(bDelChars && !isprint((unsigned)*p))
				bDelChars=false;
		}

		const char *pName=g_app_info_get_name( (GAppInfo*) pInfo);
		if(!pName)
			continue;
		const char *pCats=g_desktop_app_info_get_categories(pInfo);
		if(!pCats)
			pCats="Other";
		if(0 == strncmp(pCats, "X-", 2))
			continue;

		const char *sicon = "-";
		GIcon *pIcon=g_app_info_get_icon( (GAppInfo*) pInfo);
		auto_gfree<char> iconstringrelease;
		if (pIcon)
		{
			char *s = g_icon_to_string(pIcon);
			iconstringrelease.m_p=s;
			sicon=s;
		}

		gchar *menuLine;

		if(g_desktop_app_info_get_boolean (pInfo,
                "Terminal") || strchr(cmdraw, '%'))
		{
			menuLine = g_strdup_printf(
					"prog \"%s\" %s %s \"%s\"\n",
					pName, sicon, g_argv0, szFullName);
		}
		else
			menuLine = g_strdup_printf(
				"prog \"%s\" %s %s\n",
				pName, sicon, cmd);

		// Pigeonholing roughly by guessed menu structure
#define add2menu(x) { x=g_list_append(x, menuLine); }
		gchar **ppCats = g_strsplit(pCats, ";", -1);
		if (find_in_zArray(ppCats, "Screensaver"))
			add2menu(mscreensavers)
		else if (find_in_zArray(ppCats, "Settings"))
			add2menu(msettings)
		else if (find_in_zArray(ppCats, "Accessories"))
			add2menu(maccessories)
		else if (find_in_zArray(ppCats, "Development"))
			add2menu(mdevelopment)
		else if (find_in_zArray(ppCats, "Education"))
			add2menu(meducation)
		else if (find_in_zArray(ppCats, "Game"))
			add2menu(mgames)
		else if (find_in_zArray(ppCats, "Graphics"))
			add2menu(mgraphics)
		else if (find_in_zArray(ppCats, "AudioVideo") || find_in_zArray(ppCats, "Audio")
				|| find_in_zArray(ppCats, "Video"))
		{
			add2menu(mmultimedia)
		}
		else if (find_in_zArray(ppCats, "Network"))
			add2menu(mnetwork)
		else if (find_in_zArray(ppCats, "Office"))
			add2menu(moffice)
		else if (find_in_zArray(ppCats, "System") || find_in_zArray(ppCats, "Emulator"))
			add2menu(msystem)
		else if (strstr(pCats, "Editor"))
					add2menu(meditors)
		else
		{
			const char *pwmclass = g_desktop_app_info_get_startup_wm_class(pInfo);
			if ((pwmclass && strstr(pwmclass, "Wine")) || strstr(cmd, " wine "))
				add2menu(mwine)
			else
				add2menu(mother)
		}
		g_strfreev(ppCats);
	}
}

struct tMenuHead {
		char *title;
		pglist pEntries;
		tMenuHead(char *xt, pglist p) : title(xt), pEntries(p) {};
	};
gint menu_name_compare(gconstpointer a, gconstpointer b)
{
	tMenuHead *pa=(tMenuHead*)a;
	tMenuHead *pb=(tMenuHead*)b;
	return g_utf8_collate(pa->title, pb->title);
}

void print_submenu(gpointer vlp)
{
	tMenuHead *l=static_cast<tMenuHead*>(vlp);
	if(!l->pEntries)
		return;
	l->pEntries=g_list_sort(l->pEntries, (GCompareFunc)g_utf8_collate);
	printf("menu \"%s\" folder {\n", l->title);
	for (pglist m = l->pEntries; m != NULL; m = m->next)
	{
		printf("%s", (const char*) m->data);
		g_free(m->data);
	}
	printf("}\n");
}

void dump_menu()
{
	pglist xmenu = 0;
#define	addmenu(name, store) \
		xmenu = g_list_insert_sorted(xmenu, new tMenuHead(name, store),\
				(GCompareFunc)menu_name_compare);
	addmenu(_("Settings"), msettings);
	addmenu(_("Screensavers"), mscreensavers);
	addmenu(_("Accessories"), maccessories);
	addmenu(_("Development"), mdevelopment);
	addmenu(_("Education"), meducation);
	addmenu(_("Games"), mgames);
	addmenu(_("Graphics"), mgraphics);
	addmenu(_("Multimedia"), mmultimedia);
	addmenu(_("Network"), mnetwork);
	addmenu(_("Office"), moffice);
	addmenu(_("System"), msystem);
	addmenu(_("WINE"), mwine);
	addmenu(_("Editors"), meditors);

	for (pglist l = xmenu; l != NULL; l = l->next)
		print_submenu(l->data);
	puts("separator");
	tMenuHead hmo(_("Other"), mother);
	print_submenu(&hmo);

}

bool launch(const char *dfile)
{
	GDesktopAppInfo *pInfo = g_desktop_app_info_new_from_filename (dfile);
	if(!pInfo)
		return false;
	return g_app_info_launch ((GAppInfo *)pInfo,
                   NULL, NULL, NULL);
}

int main(int argc, char **argv)
{
	g_argv0=argv[0];

	setlocale (LC_ALL, "");

#ifdef ENABLE_NLS
    bindtextdomain(PACKAGE, LOCDIR);
    textdomain(PACKAGE);
#endif

	const char * usershare=getenv("XDG_DATA_HOME"),
			*sysshare=getenv("XDG_DATA_DIRS");

	if(!usershare || !*usershare)
		usershare=g_strjoin(NULL, getenv("HOME"), "/.local/share", NULL);

	if(!sysshare || !*sysshare)
		sysshare="/usr/local/share:/usr/share";

	if(argc>1)
	{
		if(strstr(argv[1], ".desktop") && launch(argv[1]))
			return EXIT_SUCCESS;

		g_fprintf(stderr, "This program doesn't use command line options. It only listens to\n"
			"environment variables defined by XDG Base Directory Specification.\n"
			"XDG_DATA_HOME=%s\n"
				"XDG_DATA_DIRS=%s\n"
			,usershare, sysshare);
		return EXIT_FAILURE;
	}

	proc_dir(usershare);
	gchar **ppDirs = g_strsplit (sysshare, ":", -1);
	for(const gchar * const * p=ppDirs;*p;++p)
	{
		gchar *pmdir=g_strjoin(0, *p, "/applications", NULL);
		proc_dir(pmdir);
		opt_g_free(pmdir);
	}
#ifdef FREEASAP
	g_strfreev(ppDirs);
#endif

	dump_menu();

	return EXIT_SUCCESS;
}
<commit_msg>Bring in more structure, use GTree to sort and remove dupes<commit_after>/*
 *  FDOmenu - Menu code generator for icewm
 *  Copyright (C) 2015 Eduard Bloch
 *
 *  Inspired by icewm-menu-gnome2 and Freedesktop.org specifications
 *  Using pure glib/gio code and a built-in menu structure instead
 *  the XML based external definition (as suggested by FD.o specs)
 *
 *  Release under terms of the GNU Library General Public License
 *  (version 2.0)
 *
 *  2015/02/05: Eduard Bloch <edi@gmx.de>
 *  - initial version
 */

#include "config.h"
#include "base.h"
#include "sysdep.h"
#include "intl.h"

const char *g_argv0;

#include <glib.h>
#include <glib/gprintf.h>
#include <glib/gstdio.h>
#include <gio/gdesktopappinfo.h>

typedef GTree* tMenuContainer;

template<class T>
struct auto_gfree
{
	T *m_p;
	auto_gfree() : m_p(NULL) {};
	auto_gfree(T *xp) : m_p(xp) {};
	~auto_gfree() { g_free(m_p); }
};
struct auto_gunref
{
	GObject *m_p;
	auto_gunref(GObject *xp): m_p(xp) {};
	~auto_gunref() { g_object_unref(m_p); }
};

bool find_in_zArray(const char * const *arrToScan, const char *keyword)
{
	for(const gchar * const * p=arrToScan;*p;++p)
		if(!strcmp(keyword, *p))
			return true;
	return false;
}

// for optional bits that are not consuming much and
// it's OK to leak them, OS will clean up soon enough
//#define FREEASAP
#ifdef FREEASAP
#define opt_g_free(x) g_free(x);
#else
#define opt_g_free(x)
#endif

tMenuContainer msettings=0, mscreensavers=0, maccessories=0, mdevelopment=0, meducation=0,
		mgames=0, mgraphics=0, mmultimedia=0, mnetwork=0, moffice=0, msystem=0,
		mother=0, mwine=0, meditors=0;

struct tListMeta
{
	const char *title;
	tMenuContainer* store;
};
tListMeta menuinfo[] =
{
{ "Settings", &msettings },
{ "Screensavers", &mscreensavers },
{ "Accessories", &maccessories },
{ "Development", &mdevelopment },
{ "Education", &meducation },
{ "Games", &mgames },
{ "Graphics", &mgraphics },
{ "Multimedia", &mmultimedia },
{ "Network", &mnetwork },
{ "Office", &moffice },
{ "System", &msystem },
{ "WINE", &mwine },
{ "Editors", &meditors },
{ "Other", &mother } };

//#warning needing a dupe filter for filename, maybe use GHashTable for that

void proc_dir(const char *path, unsigned depth=0)
{
	GDir *pdir = g_dir_open (path, 0, NULL);
	if(!pdir)
		return;
	struct tdircloser {
		GDir *m_p;
		tdircloser(GDir *p) : m_p(p) {};
		~tdircloser() { g_dir_close(m_p);}
	} dircloser(pdir);

	const gchar *szFilename(NULL);
	while(NULL != (szFilename = g_dir_read_name (pdir)))
	{
		if(!szFilename)
			continue;
		gchar *szFullName = g_strjoin("/", path, szFilename, NULL);
		auto_gfree<gchar> xxfree(szFullName);
		static GStatBuf buf;
		if(g_stat(szFullName, &buf))
			return;
		if(S_ISDIR(buf.st_mode))
		{
			static ino_t reclog[6];
			for(unsigned i=0; i<depth; ++i)
			{
				if(reclog[i] == buf.st_ino)
					goto dir_visited_before;
			}
			if(depth<ACOUNT(reclog))
			{
				reclog[++depth] = buf.st_ino;
				proc_dir(szFullName, depth);
				--depth;
			}
			dir_visited_before:;
		}

		if(!S_ISREG(buf.st_mode))
			continue;

		GDesktopAppInfo *pInfo = g_desktop_app_info_new_from_filename (szFullName);
		if(!pInfo)
			continue;
		auto_gunref ___pinfo_releaser((GObject*)pInfo);

		if(!g_app_info_should_show((GAppInfo*) pInfo))
			continue;

		const char *cmdraw = g_app_info_get_commandline ((GAppInfo*) pInfo);
		if(!cmdraw || !*cmdraw)
			continue;

		// let's whitespace all special fields that we don't support
		gchar * cmd = g_strdup(cmdraw);
		auto_gfree<gchar> cmdfree(cmd);
		bool bDelChars=false;
		for(gchar *p=cmd; *p; ++p)
		{
			if('%' == *p)
				bDelChars=true;
			if(bDelChars)
				*p = ' ';
			if(bDelChars && !isprint((unsigned)*p))
				bDelChars=false;
		}

		const char *pName=g_app_info_get_name( (GAppInfo*) pInfo);
		if(!pName)
			continue;
		const char *pCats=g_desktop_app_info_get_categories(pInfo);
		if(!pCats)
			pCats="Other";
		if(0 == strncmp(pCats, "X-", 2))
			continue;

		const char *sicon = "-";
		GIcon *pIcon=g_app_info_get_icon( (GAppInfo*) pInfo);
		auto_gfree<char> iconstringrelease;
		if (pIcon)
		{
			char *s = g_icon_to_string(pIcon);
			iconstringrelease.m_p=s;
			sicon=s;
		}

		gchar *menuLine;

		if(g_desktop_app_info_get_boolean (pInfo,
                "Terminal") || strchr(cmdraw, '%'))
		{
			menuLine = g_strdup_printf(
					"%s %s \"%s\"",
					sicon, g_argv0, szFullName);
		}
		else
			menuLine = g_strjoin(" ", sicon, cmd, NULL);

		// Pigeonholing roughly by guessed menu structure
#define add2menu(x) { g_tree_replace(x, g_strdup(pName), menuLine); }
		gchar **ppCats = g_strsplit(pCats, ";", -1);
		if (find_in_zArray(ppCats, "Screensaver"))
			add2menu(mscreensavers)
		else if (find_in_zArray(ppCats, "Settings"))
			add2menu(msettings)
		else if (find_in_zArray(ppCats, "Accessories"))
			add2menu(maccessories)
		else if (find_in_zArray(ppCats, "Development"))
			add2menu(mdevelopment)
		else if (find_in_zArray(ppCats, "Education"))
			add2menu(meducation)
		else if (find_in_zArray(ppCats, "Game"))
			add2menu(mgames)
		else if (find_in_zArray(ppCats, "Graphics"))
			add2menu(mgraphics)
		else if (find_in_zArray(ppCats, "AudioVideo") || find_in_zArray(ppCats, "Audio")
				|| find_in_zArray(ppCats, "Video"))
		{
			add2menu(mmultimedia)
		}
		else if (find_in_zArray(ppCats, "Network"))
			add2menu(mnetwork)
		else if (find_in_zArray(ppCats, "Office"))
			add2menu(moffice)
		else if (find_in_zArray(ppCats, "System") || find_in_zArray(ppCats, "Emulator"))
			add2menu(msystem)
		else if (strstr(pCats, "Editor"))
			add2menu(meditors)
		else
		{
			const char *pwmclass = g_desktop_app_info_get_startup_wm_class(pInfo);
			if ((pwmclass && strstr(pwmclass, "Wine")) || strstr(cmd, " wine "))
				add2menu(mwine)
			else
				add2menu(mother)
		}
		g_strfreev(ppCats);
	}
}

static gboolean printKey(const char *key, const char *value, void*)
{
	printf("prog \"%s\" %s\n", key, value);
	return FALSE;
}

void print_submenu(const char *title, tMenuContainer data)
{
	if(!data || !g_tree_nnodes(data))
		return;
	printf("menu \"%s\" folder {\n"
			//"# %u entries\n"
			, title
			//, g_tree_nnodes(data)
			);
	g_tree_foreach(data, (GTraverseFunc) printKey, NULL);
	puts("}");
}

void dump_menu()
{
    for(tListMeta *p=menuinfo; p < menuinfo+ACOUNT(menuinfo)-1; ++p)
    	print_submenu(p->title, * p->store);
	puts("separator");
	print_submenu(menuinfo[ACOUNT(menuinfo)-1].title, * menuinfo[ACOUNT(menuinfo)-1].store);
}

bool launch(const char *dfile, const char **argv, int argc)
{
	GDesktopAppInfo *pInfo = g_desktop_app_info_new_from_filename (dfile);
	if(!pInfo)
		return false;
#if 0 // g_file_get_uri crashes, no idea why, even enforcing file prefix doesn't help
	if(argc>0)
	{
		GList* parms=NULL;
		for(int i=0; i<argc; ++i)
			parms=g_list_append(parms,
					g_strdup_printf("%s%s", strstr(argv[i], "://") ? "" : "file://",
							argv[i]));
		return g_app_info_launch ((GAppInfo *)pInfo,
		                   parms, NULL, NULL);
	}
	else
#else
	(void) argv;
	(void) argc;
#endif
	return g_app_info_launch ((GAppInfo *)pInfo,
                   NULL, NULL, NULL);
}
static int
cmpstringp(const void *p1, const void *p2)
{
    return g_utf8_collate(* (char * const *) p1, * (char * const *) p2);
}

static void init()
{
	setlocale (LC_ALL, "");

#ifdef ENABLE_NLS
    bindtextdomain(PACKAGE, LOCDIR);
    textdomain(PACKAGE);
#endif

    for(tListMeta *p=menuinfo; p < menuinfo+ACOUNT(menuinfo); ++p)
    {
    	p->title = gettext(p->title);
    	*(p->store) = g_tree_new((GCompareFunc) g_utf8_collate);
    }

    qsort(menuinfo, ACOUNT(menuinfo)-1, sizeof(menuinfo[0]), cmpstringp);
}

int main(int argc, const char **argv)
{
	g_argv0=argv[0];

	init();

	const char * usershare=getenv("XDG_DATA_HOME"),
			*sysshare=getenv("XDG_DATA_DIRS");

	if(!usershare || !*usershare)
		usershare=g_strjoin(NULL, getenv("HOME"), "/.local/share", NULL);

	if(!sysshare || !*sysshare)
		sysshare="/usr/local/share:/usr/share";

	if(argc>1)
	{
		if(strstr(argv[1], ".desktop") && launch(argv[1], argv+2, argc-2))
			return EXIT_SUCCESS;

		g_fprintf(stderr, "This program doesn't use command line options. It only listens to\n"
			"environment variables defined by XDG Base Directory Specification.\n"
			"XDG_DATA_HOME=%s\n"
				"XDG_DATA_DIRS=%s\n"
			,usershare, sysshare);
		return EXIT_FAILURE;
	}
	gchar **ppDirs = g_strsplit (sysshare, ":", -1);
#ifdef FREEASAP
	g_strfreev(ppDirs);
#endif
	for (const gchar * const * p = ppDirs; *p; ++p)
	{
		gchar *pmdir = g_strjoin(0, *p, "/applications", NULL);
		proc_dir(pmdir);
		opt_g_free(pmdir);
	}
	// user's stuff might replace the system links
	proc_dir(usershare);

	dump_menu();

	return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before><commit_msg>Reenable BWSI key on login screen<commit_after><|endoftext|>


<commit_before><commit_msg>Fixed compilation error under Visual Studio 2012<commit_after><|endoftext|>


<commit_before><commit_msg>Bugfix: removed duplicate `#include` lines.<commit_after><|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: app.hxx,v $
 *
 *  $Revision: 1.1.1.1 $
 *
 *  last change: $Author: hr $ $Date: 2000-09-18 16:48:27 $
 *
 *  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): _______________________________________
 *
 *
 ************************************************************************/
#define _SD_DLL             // fuer SD_MOD()
#include "sdmod.hxx"

<commit_msg>INTEGRATION: CWS ooo19126 (1.1.1.1.930); FILE MERGED 2005/09/05 13:19:51 rt 1.1.1.1.930.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: app.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 02:53:23 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 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
 *
 ************************************************************************/
#define _SD_DLL             // fuer SD_MOD()
#include "sdmod.hxx"

<|endoftext|>


<commit_before>/*
 * SWE_Plane_TS_ln_erk.cpp
 *
 *  Created on: 29 May 2017
 *      Author: Martin Schreiber <SchreiberX@gmail.com>
 *
 *  Changelog:
 *
 *  	2017-07-13: Updated and validated by P. Peixoto.
 *  	2017-05-29: Based on source swe_plane.cpp
 *					which was also written by Pedro Peixoto
 */

#include "../swe_plane/SWE_Plane_TS_ln_erk.hpp"

/*
 * Main routine for method to be used in case of finite differences
 *
 * - A-Grid with spectral or FD spatial discretizations
 * - C-Grid with energy conserving FD scheme for spatial discretizations
 *
 */
void SWE_Plane_TS_ln_erk::euler_timestep_update(
		const PlaneData &i_h,	///< prognostic variables (perturbed part of height)
		const PlaneData &i_u,	///< prognostic variables
		const PlaneData &i_v,	///< prognostic variables

		PlaneData &o_h_t,	///< time updates
		PlaneData &o_u_t,	///< time updates
		PlaneData &o_v_t,	///< time updates

		double i_simulation_timestamp
)
{
	// A-grid method
	if (!simVars.disc.space_grid_use_c_staggering)
	{
		/*
		 * non-conservative (advective) formulation:
		 *
		 *	h_t = -(u*h)_x - (v*h)_y
		 *	u_t = -g * h_x - u * u_x - v * u_y + f*v
		 *	v_t = -g * h_y - u * v_x - v * v_y - f*u
		 */

		PlaneData total_h = i_h + simVars.sim.h0;

		o_u_t = -simVars.sim.gravitation*op.diff_c_x(total_h) - i_u*op.diff_c_x(i_u) - i_v*op.diff_c_y(i_u);
		o_v_t = -simVars.sim.gravitation*op.diff_c_y(total_h) - i_u*op.diff_c_x(i_v) - i_v*op.diff_c_y(i_v);

		o_u_t += simVars.sim.plane_rotating_f0*i_v;
		o_v_t -= simVars.sim.plane_rotating_f0*i_u;

		// standard update
		/*
		 * P UPDATE
		 */
		if (!use_only_linear_divergence){ //full nonlinear divergence
			// standard update
			//o_h_t = -op.diff_f_x(U) - op.diff_f_y(V);
			o_h_t = -op.diff_c_x(i_u*total_h) - op.diff_c_y(i_v*total_h);
		}
		else // use linear divergence
		{
			//o_h_t = -op.diff_f_x(simVars.sim.h0*i_u) - op.diff_f_y(simVars.sim.h0*i_v);
			o_h_t = -i_u*op.diff_c_x(total_h) - i_v*op.diff_c_y(total_h) + //nonlinear adv
					-op.diff_c_x(i_u*simVars.sim.h0) - op.diff_c_y(i_v*simVars.sim.h0); //linear div
		}

	}
	else // simVars.disc.use_staggering = true
	{
		// STAGGERED GRID

		PlaneData U(i_h.planeDataConfig); // U flux
		PlaneData V(i_h.planeDataConfig); // V flux
		PlaneData H(i_h.planeDataConfig); //Bernoulli potential
		PlaneData total_h = i_h + simVars.sim.h0;

		/*
		 * Sadourny energy conserving scheme
		 *
		 * Note, that this grid does not follow the formulation
		 * in the paper of Robert Sadourny, but looks as follows:
		 *
		 *              ^
		 *              |
		 *       ______v0,1_____
		 *       |             |
		 *       |			   |
		 *       |             |
		 *  u0,0 |->  H/P0,0   |u1,0 ->
		 *(0,0.5)|			   |
		 *       |      ^      |
		 *   q0,0|______|______|
		 * (0,0)      v0,0
		 *           (0.5,0)
		 *
		 * V_t + q N x (P V) + grad( g P + 1/2 V*V) = 0
		 * P_t + div(P V) = 0
		 */
		/*
		 * U and V updates
		 */

		U = op.avg_b_x(total_h)*i_u;
		V = op.avg_b_y(total_h)*i_v;

		H = simVars.sim.gravitation*total_h + 0.5*(op.avg_f_x(i_u*i_u) + op.avg_f_y(i_v*i_v));

		// Potential vorticity
		PlaneData total_h_pv = total_h;
		total_h_pv = op.avg_b_x(op.avg_b_y(total_h));

		if (total_h_pv.reduce_min() < 0.00000001)
		{
			std::cerr << "Test case not adequate for vector invariant formulation. Null or negative water height" << std::endl;
			std::cerr << "Min h_pv   : " << total_h_pv.reduce_min() << std::endl;
			std::cerr << "Min h_total: " << total_h.reduce_min() << std::endl;
			std::cerr << "Min h_pert : " << i_h.reduce_min() << std::endl;
			FatalError("SWE_Plane_TS_ln_erk: Methods unstable or inadequate for vector invariant swe");;
		}

		PlaneData q = (op.diff_b_x(i_v) - op.diff_b_y(i_u) + simVars.sim.plane_rotating_f0) / total_h_pv;

		// u, v tendencies
		// Energy conserving scheme
		o_u_t = op.avg_f_y(q*op.avg_b_x(V)) - op.diff_b_x(H);
		o_v_t = -op.avg_f_x(q*op.avg_b_y(U)) - op.diff_b_y(H);

		/*
		 * P UPDATE
		 */
		if (!use_only_linear_divergence){ //full nonlinear divergence
			// standard update
			o_h_t = -op.diff_f_x(U) - op.diff_f_y(V);
		}
		else // use linear divergence
		{
			o_h_t = -i_u*op.diff_f_x(total_h) - i_v*op.diff_f_y(total_h) + //nonlinear adv
					-op.diff_f_x(i_u*simVars.sim.h0) - op.diff_f_y(i_v*simVars.sim.h0); //linear div
			//o_h_t = -op.diff_f_x(simVars.sim.h0*i_u) - op.diff_f_y(simVars.sim.h0*i_v);
		}
	}
}

void SWE_Plane_TS_ln_erk::run_timestep(
		PlaneData &io_h,	///< prognostic variables
		PlaneData &io_u,	///< prognostic variables
		PlaneData &io_v,	///< prognostic variables

		double i_dt,		///< if this value is not equal to 0, use this time step size instead of computing one
		double i_simulation_timestamp
)
{
	if (i_dt <= 0)
		FatalError("SWE_Plane_TS_ln_erk: Only constant time step size allowed");

	// standard time stepping
	timestepping_rk.run_timestep(
			this,
			&SWE_Plane_TS_ln_erk::euler_timestep_update,	///< pointer to function to compute euler time step updates
			io_h, io_u, io_v,
			i_dt,
			timestepping_order,
			i_simulation_timestamp
		);
}

/*
 * Setup
 */
void SWE_Plane_TS_ln_erk::setup(
		int i_order,	///< order of RK time stepping method
		bool i_use_only_linear_divergence
)
{
	timestepping_order = i_order;
	use_only_linear_divergence = i_use_only_linear_divergence;
}

SWE_Plane_TS_ln_erk::SWE_Plane_TS_ln_erk(
		SimulationVariables &i_simVars,
		PlaneOperators &i_op
)	:
		simVars(i_simVars),
		op(i_op)
{
	setup(simVars.disc.timestepping_order, false);
}

SWE_Plane_TS_ln_erk::~SWE_Plane_TS_ln_erk()
{
}

<commit_msg>removed fatalerror which is caught at a better place<commit_after>/*
 * SWE_Plane_TS_ln_erk.cpp
 *
 *  Created on: 29 May 2017
 *      Author: Martin Schreiber <SchreiberX@gmail.com>
 *
 *  Changelog:
 *
 *  	2017-07-13: Updated and validated by P. Peixoto.
 *  	2017-05-29: Based on source swe_plane.cpp
 *					which was also written by Pedro Peixoto
 */

#include "../swe_plane/SWE_Plane_TS_ln_erk.hpp"

/*
 * Main routine for method to be used in case of finite differences
 *
 * - A-Grid with spectral or FD spatial discretizations
 * - C-Grid with energy conserving FD scheme for spatial discretizations
 *
 */
void SWE_Plane_TS_ln_erk::euler_timestep_update(
		const PlaneData &i_h,	///< prognostic variables (perturbed part of height)
		const PlaneData &i_u,	///< prognostic variables
		const PlaneData &i_v,	///< prognostic variables

		PlaneData &o_h_t,	///< time updates
		PlaneData &o_u_t,	///< time updates
		PlaneData &o_v_t,	///< time updates

		double i_simulation_timestamp
)
{
	// A-grid method
	if (!simVars.disc.space_grid_use_c_staggering)
	{
		/*
		 * non-conservative (advective) formulation:
		 *
		 *	h_t = -(u*h)_x - (v*h)_y
		 *	u_t = -g * h_x - u * u_x - v * u_y + f*v
		 *	v_t = -g * h_y - u * v_x - v * v_y - f*u
		 */

		PlaneData total_h = i_h + simVars.sim.h0;

		o_u_t = -simVars.sim.gravitation*op.diff_c_x(total_h) - i_u*op.diff_c_x(i_u) - i_v*op.diff_c_y(i_u);
		o_v_t = -simVars.sim.gravitation*op.diff_c_y(total_h) - i_u*op.diff_c_x(i_v) - i_v*op.diff_c_y(i_v);

		o_u_t += simVars.sim.plane_rotating_f0*i_v;
		o_v_t -= simVars.sim.plane_rotating_f0*i_u;

		// standard update
		/*
		 * P UPDATE
		 */
		if (!use_only_linear_divergence){ //full nonlinear divergence
			// standard update
			//o_h_t = -op.diff_f_x(U) - op.diff_f_y(V);
			o_h_t = -op.diff_c_x(i_u*total_h) - op.diff_c_y(i_v*total_h);
		}
		else // use linear divergence
		{
			//o_h_t = -op.diff_f_x(simVars.sim.h0*i_u) - op.diff_f_y(simVars.sim.h0*i_v);
			o_h_t = -i_u*op.diff_c_x(total_h) - i_v*op.diff_c_y(total_h) + //nonlinear adv
					-op.diff_c_x(i_u*simVars.sim.h0) - op.diff_c_y(i_v*simVars.sim.h0); //linear div
		}

	}
	else // simVars.disc.use_staggering = true
	{
		// STAGGERED GRID

		PlaneData U(i_h.planeDataConfig); // U flux
		PlaneData V(i_h.planeDataConfig); // V flux
		PlaneData H(i_h.planeDataConfig); //Bernoulli potential
		PlaneData total_h = i_h + simVars.sim.h0;

		/*
		 * Sadourny energy conserving scheme
		 *
		 * Note, that this grid does not follow the formulation
		 * in the paper of Robert Sadourny, but looks as follows:
		 *
		 *              ^
		 *              |
		 *       ______v0,1_____
		 *       |             |
		 *       |			   |
		 *       |             |
		 *  u0,0 |->  H/P0,0   |u1,0 ->
		 *(0,0.5)|			   |
		 *       |      ^      |
		 *   q0,0|______|______|
		 * (0,0)      v0,0
		 *           (0.5,0)
		 *
		 * V_t + q N x (P V) + grad( g P + 1/2 V*V) = 0
		 * P_t + div(P V) = 0
		 */
		/*
		 * U and V updates
		 */

		U = op.avg_b_x(total_h)*i_u;
		V = op.avg_b_y(total_h)*i_v;

		H = simVars.sim.gravitation*total_h + 0.5*(op.avg_f_x(i_u*i_u) + op.avg_f_y(i_v*i_v));

		// Potential vorticity
		PlaneData total_h_pv = total_h;
		total_h_pv = op.avg_b_x(op.avg_b_y(total_h));

#if 0
		if (total_h_pv.reduce_min() < 0.00000001)
		{
			std::cerr << "Test case not adequate for vector invariant formulation. Null or negative water height" << std::endl;
			std::cerr << "Min h_pv   : " << total_h_pv.reduce_min() << std::endl;
			std::cerr << "Min h_total: " << total_h.reduce_min() << std::endl;
			std::cerr << "Min h_pert : " << i_h.reduce_min() << std::endl;
			FatalError("SWE_Plane_TS_ln_erk: Methods unstable or inadequate for vector invariant swe");;
		}
#endif

		PlaneData q = (op.diff_b_x(i_v) - op.diff_b_y(i_u) + simVars.sim.plane_rotating_f0) / total_h_pv;

		// u, v tendencies
		// Energy conserving scheme
		o_u_t = op.avg_f_y(q*op.avg_b_x(V)) - op.diff_b_x(H);
		o_v_t = -op.avg_f_x(q*op.avg_b_y(U)) - op.diff_b_y(H);

		/*
		 * P UPDATE
		 */
		if (!use_only_linear_divergence){ //full nonlinear divergence
			// standard update
			o_h_t = -op.diff_f_x(U) - op.diff_f_y(V);
		}
		else // use linear divergence
		{
			o_h_t = -i_u*op.diff_f_x(total_h) - i_v*op.diff_f_y(total_h) + //nonlinear adv
					-op.diff_f_x(i_u*simVars.sim.h0) - op.diff_f_y(i_v*simVars.sim.h0); //linear div
			//o_h_t = -op.diff_f_x(simVars.sim.h0*i_u) - op.diff_f_y(simVars.sim.h0*i_v);
		}
	}
}

void SWE_Plane_TS_ln_erk::run_timestep(
		PlaneData &io_h,	///< prognostic variables
		PlaneData &io_u,	///< prognostic variables
		PlaneData &io_v,	///< prognostic variables

		double i_dt,		///< if this value is not equal to 0, use this time step size instead of computing one
		double i_simulation_timestamp
)
{
	if (i_dt <= 0)
		FatalError("SWE_Plane_TS_ln_erk: Only constant time step size allowed");

	// standard time stepping
	timestepping_rk.run_timestep(
			this,
			&SWE_Plane_TS_ln_erk::euler_timestep_update,	///< pointer to function to compute euler time step updates
			io_h, io_u, io_v,
			i_dt,
			timestepping_order,
			i_simulation_timestamp
		);
}

/*
 * Setup
 */
void SWE_Plane_TS_ln_erk::setup(
		int i_order,	///< order of RK time stepping method
		bool i_use_only_linear_divergence
)
{
	timestepping_order = i_order;
	use_only_linear_divergence = i_use_only_linear_divergence;
}

SWE_Plane_TS_ln_erk::SWE_Plane_TS_ln_erk(
		SimulationVariables &i_simVars,
		PlaneOperators &i_op
)	:
		simVars(i_simVars),
		op(i_op)
{
	setup(simVars.disc.timestepping_order, false);
}

SWE_Plane_TS_ln_erk::~SWE_Plane_TS_ln_erk()
{
}

<|endoftext|>