<commit_before>/*****************************************************************************************
 *                                                                                *
 * OpenSpace                                                                             *
 *                                                                                *
 * Copyright (c) 2014-2021                                                               *
 *                                                                                *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this  *
 * software and associated documentation files (the "Software"), to deal in the Software *
 * without restriction, including without limitation the rights to use, copy, modify,    *
 * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to    *
 * permit persons to whom the Software is furnished to do so, subject to the following   *
 * conditions:                                                                           *
 *                                                                                *
 * The above copyright notice and this permission notice shall be included in all copies *
 * or substantial portions of the Software.                                              *
 *                                                                                *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,   *
 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A         *
 * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT    *
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF  *
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE  *
 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                                         *
 ****************************************************************************************/

#include <openspace/util/coordinateconversion.h>

#include <ghoul/fmt.h>
#include <ghoul/logging/logmanager.h>
#include <ghoul/lua/ghoul_lua.h>

namespace {
    constexpr const char* _loggerCat = "Coordinateconversion";

    bool isStringNumber(const std::string& str) {
        for (size_t i = 0; i < str.size(); ++i) {
            if (!isdigit(str[i])) {
                if (i == 0 && str.size() > 1) {
                    if (str[i] == '-' || str[i] == '+') {
                        continue;
                    }
                    else {
                        return false;
                    }
                }
                else {
                    return false;
                }
            }
        }
        return true;
    }

    void parseString(const std::string& str, double& hours_or_degrees, double& minutes,
                     double& seconds)
    {
        // Find hms or dms indicies
        size_t h_or_d_index;
        if (str.find('h') != std::string::npos) {
            h_or_d_index = str.find('h');
        }
        else {
            h_or_d_index = str.find('d');
        }
        size_t m_index = str.find('m');
        size_t s_index = str.find('s');
        if (h_or_d_index == std::string::npos || m_index == std::string::npos ||
            s_index == std::string::npos)
        {
            throw(ghoul::lua::LuaRuntimeException(fmt::format(
                "Ra or Dec '{}' format is incorrect. Correct format is: Ra 'XXhYYmZZs' "
                "or 'XhYmZs', and Dec 'XXdYYmZZs', '-XXdYYmZZs', 'XdYmZs' or '-XdYmZs'",
                str)
            ));
        }

        // Construct the number strings
        std::string s_hours_or_degrees = str.substr(0, h_or_d_index);
        std::string s_minutes = str.substr(h_or_d_index + 1, m_index - h_or_d_index - 1);
        std::string s_seconds = str.substr(m_index + 1, s_index - m_index - 1);
        if (!isStringNumber(s_hours_or_degrees) || !isStringNumber(s_minutes) ||
            !isStringNumber(s_seconds))
        {
            throw(ghoul::lua::LuaRuntimeException(fmt::format(
                "Ra or Dec '{}' format is incorrect. Correct format is: Ra 'XXhYYmZZs' "
                "or 'XhYmZs', and Dec 'XXdYYmZZs', '-XXdYYmZZs', 'XdYmZs' or '-XdYmZs'",
                str)
            ));
        }

        // Convert the strings to numbers
        hours_or_degrees = std::stod(s_hours_or_degrees);
        minutes = std::stod(s_minutes);
        seconds = std::stod(s_seconds);
    }

    void parseRa(const std::string& ra, double& hours, double& minutes, double& seconds) {
        if (ra.find('d') != std::string::npos) {
            throw(ghoul::lua::LuaRuntimeException(fmt::format(
                "Ra '{}' format is incorrect. Correct format is: Ra 'XXhYYmZZs' or "
                "'XhYmZs'", ra)
            ));
        }
        parseString(ra, hours, minutes, seconds);
    }

    void parseDec(const std::string& dec, double& degrees, double& minutes,
                  double& seconds)
    {
        if (dec.find('h') != std::string::npos) {
            throw(ghoul::lua::LuaRuntimeException(fmt::format(
                "Dec '{}' format is incorrect. Correct format is: "
                "Dec 'XXdYYmZZs', '-XXdYYmZZs', 'XdYmZs' or '-XdYmZs'", dec)
            ));
        }
        parseString(dec, degrees, minutes, seconds);
    }

    bool isRaDecValid(double ra_h, double ra_m, double ra_s, double dec_d,
                      double dec_m, double dec_s)
    {
        // Ra
        if (ra_h < 0.0 || ra_h >= 24.0) {
            LWARNING(fmt::format("Right ascension hours '{}' is outside the allowed "
                "range of 0 to 24 hours (exclusive)", ra_h)
            );
            return false;
        }
        if (ra_m < 0.0 || ra_m >= 60.0) {
            LWARNING(fmt::format("Right ascension minutes '{}' is outside the allowed "
                "range of 0 to 60 minutes (exclusive)", ra_m)
            );
            return false;
        }
        if (ra_s < 0.0 || ra_s >= 60.0) {
            LWARNING(fmt::format("Right ascension seconds '{}' is outside the allowed "
                "range of 0 to 60 seconds (exclusive)", ra_s)
            );
            return false;
        }

        // Dec
        if (dec_d < -90.0 || dec_d > 90.0) {
            LWARNING(fmt::format("Declination degrees '{}' is outside the allowed range "
                "of -90 to 90 degrees (inclusive)", dec_d)
            );
            return false;
        }
        else if ((dec_d == -90.0 || dec_d == 90.0) && (dec_m != 0 || dec_s != 0)) {
            LWARNING("Total declination is outside the allowed range of -90 to 90 "
                "degrees (inclusive)"
            );
            return false;
        }
        if (dec_m < 0.0 || dec_m >= 60.0) {
            LWARNING(fmt::format("Declination minutes '{}' is outside the allowed range "
                "of 0 to 60 minutes (exclusive)", dec_m)
            );
            return false;
        }
        if (dec_s < 0.0 || dec_s >= 60.0) {
            LWARNING(fmt::format("Declination seconds '{}' is outside the allowed range "
                "of 0 to 60 seconds (exclusive)", dec_s)
            );
            return false;
        }

        return true;
    }
} // namespace

namespace openspace {

// Convert Equatorial coordinates ICRS right ascension and declination (a, d)
// into Galactic coordinates (l, b)
glm::dvec3 icrsToGalacticCartesian(double ra, double dec, double distance) {
    // Reference:
    // https://www.atnf.csiro.au/people/Tobias.Westmeier/tools_coords.php

    // (Ra, Dec) -> (a, d)
    double a = glm::radians(ra);
    double d = glm::radians(dec);

    // J2000 Galactic reference frame
    constexpr double a0 = glm::radians(192.8595); // Equatorial coordinates of the Galactic north pole
    constexpr double d0 = glm::radians(27.1284);
    constexpr double l0 = glm::radians(122.9320); // Galactic longitude of the equatorial north pole

    // Convert to galactic reference frame
    double l = l0 - atan2(
        cos(d) * sin(a - a0),
        sin(d) * cos(d0) - cos(d) * sin(d0) * cos(a - a0)
    );
    double b = asin(sin(d) * sin(d0) + cos(d) * cos(d0) * cos(a - a0));

    // Convert to cartesian
    glm::dvec3 rGalactic = glm::dvec3(
        cos(b) * cos(l),
        cos(b) * sin(l),
        sin(b)
    );

    return distance * rGalactic;
}

// Ra format "XXhYYmZZs" or "XhYmZs"
// Dec format "XXdYYmZZs", "-XXdYYmZZs", "XdYmZs" or "-XdYmZs"
glm::dvec2 icrsToDecimalDegrees(const std::string& ra, const std::string& dec) {
    // Reference:
    // https://math.stackexchange.com/questions/15323/how-do-i-calculate-the-cartesian-coordinates-of-stars
    if (ra.size() > 9 || ra.size() < 6 || dec.size() > 10 || dec.size() < 6) {
        throw(ghoul::lua::LuaRuntimeException(fmt::format(
            "Ra '{}' or Dec '{}' format is incorrect. Correct format is: Ra 'XXhYYmZZs' "
            "or 'XhYmZs', and Dec 'XXdYYmZZs', '-XXdYYmZZs', 'XdYmZs' or '-XdYmZs'",
            ra, dec)
        ));
    }

    // Parse right ascension
    double ra_hours, ra_minutes, ra_seconds;
    parseRa(ra, ra_hours, ra_minutes, ra_seconds);

    // Parse declination
    double dec_degrees, dec_minutes, dec_seconds;
    parseDec(dec, dec_degrees, dec_minutes, dec_seconds);

    if (!isRaDecValid(ra_hours, ra_minutes, ra_seconds, dec_degrees, dec_minutes,
        dec_seconds))
    {
        LWARNING(fmt::format("Ra '{}' or Dec '{}' is outside the allowed range, "
            "result may be incorrect", ra, dec)
        );
    }

    // Convert from hours, minutes, seconds to decimal degrees
    double sign = signbit(dec_degrees) ? -1.0 : 1.0;
    double ra_deg = (ra_hours * 15.0) +
        (ra_minutes * 15.0 / 60.0) +
        (ra_seconds * 15.0 / 3600.0);

    double dec_deg = (abs(dec_degrees) +
        (dec_minutes / 60.0) +
        (dec_seconds / 3600.0)) * sign;

    return glm::dvec2(ra_deg, dec_deg);
}

// Convert Galactic coordinates (x, y, z) or (l, b) into
// Equatorial coordinates ICRS right ascension and declination (a, d) plus distance
glm::dvec3 galacticCartesianToIcrs(double x, double y, double z) {
    // References:
    // https://www.atnf.csiro.au/people/Tobias.Westmeier/tools_coords.php,
    // https://en.wikipedia.org/wiki/Celestial_coordinate_system

    // Normalize
    double distance = sqrt(x * x + y * y + z * z);
    double n_x = x / distance;
    double n_y = y / distance;
    double n_z = z / distance;

    // Convert from cartesian
    // (x, y, z) -> (l, b)
    double l = atan2(n_y, n_x);
    double b = asin(n_z);

    // J2000 Galactic reference frame
    constexpr double a0 = glm::radians(192.8595); // Equatorial coordinates of the Galactic north pole
    constexpr double d0 = glm::radians(27.1284);
    constexpr double l0 = glm::radians(122.9320); // Galactic longitude of the equatorial north pole

    // Convert to equatorial reference frame
    double a = atan2(
        cos(b) * sin(l0 - l),
        sin(b) * cos(d0) - cos(b) * sin(d0) * cos(l0 - l)
    ) + a0;
    double d = asin(sin(b) * sin(d0) + cos(b) * cos(d0) * cos(l0 - l));

    glm::dvec3 rEquatorial = glm::dvec3(a, d, distance);

    return rEquatorial;
}

// Return a pair with two formatted strings from the decimal degrees ra and dec
std::pair<std::string, std::string> decimalDegreesToIcrs(double ra, double dec) {
    // References:
    // https://www.rapidtables.com/convert/number/degrees-to-degrees-minutes-seconds.html,
    // https://math.stackexchange.com/questions/15323/how-do-i-calculate-the-cartesian-coordinates-of-stars

    // Radians to degrees
    double ra_deg = glm::degrees(ra);
    double dec_deg = glm::degrees(dec);

    // Check input
    if (ra_deg < 0 || ra_deg > 360 || dec_deg < -90 || dec_deg > 90) {
        LWARNING(fmt::format("Given Ra '{}' or Dec '{}' is outside the allowed range, "
            "result may be incorrect", ra, dec)
        );
    }

    // Calculate Ra
    int ra_hours = std::trunc(ra_deg) / 15.0;
    double ra_minutes_full = (ra_deg - ra_hours * 15.0) * 60.0 / 15.0;
    int ra_minutes = std::trunc(ra_minutes_full);
    double ra_seconds = (ra_minutes_full - ra_minutes) * 60.0;

    // Calculate Dec
    int dec_degrees = std::trunc(dec_deg);
    double dec_minutes_full = (abs(dec_deg) - abs(dec_degrees)) * 60.0;
    int dec_minutes = std::trunc(dec_minutes_full);
    double dec_seconds = (dec_minutes_full - dec_minutes) * 60.0;

    // Construct strings
    std::pair<std::string, std::string> result;
    result.first = std::to_string(ra_hours) + 'h' +
        std::to_string(ra_minutes) + 'm' +
        std::to_string(ra_seconds) + 's';

    result.second = std::to_string(dec_degrees) + 'd' +
        std::to_string(dec_minutes) + 'm' +
        std::to_string(dec_seconds) + 's';

    // Check results
    if (!isRaDecValid(ra_hours, ra_minutes, ra_seconds, dec_degrees, dec_minutes,
        dec_seconds))
    {
        LWARNING(fmt::format("Resulting Ra '{}' or Dec '{}' is outside the allowed range, "
            "result may be incorrect", result.first, result.second)
        );
    }
    return result;
}

} // namespace openspace
<commit_msg>Improve Ra Dec string conversions<commit_after>/*****************************************************************************************
 *                                                                                *
 * OpenSpace                                                                             *
 *                                                                                *
 * Copyright (c) 2014-2021                                                               *
 *                                                                                *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this  *
 * software and associated documentation files (the "Software"), to deal in the Software *
 * without restriction, including without limitation the rights to use, copy, modify,    *
 * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to    *
 * permit persons to whom the Software is furnished to do so, subject to the following   *
 * conditions:                                                                           *
 *                                                                                *
 * The above copyright notice and this permission notice shall be included in all copies *
 * or substantial portions of the Software.                                              *
 *                                                                                *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,   *
 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A         *
 * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT    *
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF  *
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE  *
 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                                         *
 ****************************************************************************************/

#include <openspace/util/coordinateconversion.h>

#include <ghoul/fmt.h>
#include <ghoul/logging/logmanager.h>
#include <ghoul/lua/ghoul_lua.h>

namespace {
    constexpr const char* _loggerCat = "Coordinateconversion";

    void parseString(const std::string& str, int& hours_or_degrees, int& minutes,
                     double& seconds)
    {
        // Find hms or dms indicies
        size_t h_or_d_index;
        if (str.find('h') != std::string::npos) {
            h_or_d_index = str.find('h');
        }
        else {
            h_or_d_index = str.find('d');
        }
        size_t m_index = str.find('m');
        size_t s_index = str.find('s');
        if (h_or_d_index == std::string::npos || m_index == std::string::npos ||
            s_index == std::string::npos)
        {
            throw(ghoul::lua::LuaRuntimeException(fmt::format(
                "Ra or Dec '{}' format is incorrect. Correct format is: Ra 'XhYmZs', "
                "and Dec 'XdYmZs'", str))
            );
        }

        // Construct the number strings
        std::string s_hours_or_degrees = str.substr(0, h_or_d_index);
        std::string s_minutes = str.substr(h_or_d_index + 1, m_index - h_or_d_index - 1);
        std::string s_seconds = str.substr(m_index + 1, s_index - m_index - 1);

        // Convert the strings to numbers
        try {
            // Hours or degrees must be an integer
            double temp = std::stod(s_hours_or_degrees);
            std::cout << "double h: " << temp << std::endl;
            if (std::floor(temp) != temp) {
                throw(ghoul::lua::LuaRuntimeException(fmt::format(
                    "Ra or Dec '{}' format is incorrect. Correct format is: Ra 'XhYmZs', "
                    "and Dec 'XdYmZs', where X must be an integer", str))
                );
            }
            hours_or_degrees = std::stoi(s_hours_or_degrees);

            // Minutes must be an integer
            temp = std::stod(s_minutes);
            std::cout << "double m: " << temp << std::endl;
            if (std::floor(temp) != temp) {
                throw(ghoul::lua::LuaRuntimeException(fmt::format(
                    "Ra or Dec '{}' format is incorrect. Correct format is: Ra 'XhYmZs', "
                    "and Dec 'XdYmZs', where Y must be an integer", str))
                    );
            }
            minutes = std::stoi(s_minutes);

            // Seconds is a double
            seconds = std::stod(s_seconds);
        } catch (const std::invalid_argument& ia) {
            throw(ghoul::lua::LuaRuntimeException(fmt::format(
                "Ra or Dec '{}' format is incorrect. Correct format is: Ra 'XhYmZs', "
                "and Dec 'XdYmZs'", str))
            );
        }
    }

    void parseRa(const std::string& ra, int& hours, int& minutes, double& seconds) {
        if (ra.find('d') != std::string::npos) {
            throw(ghoul::lua::LuaRuntimeException(fmt::format(
                "Ra '{}' format is incorrect. Correct format is: 'XhYmZs'", ra))
            );
        }
        parseString(ra, hours, minutes, seconds);
    }

    void parseDec(const std::string& dec, int& degrees, int& minutes,
                  double& seconds)
    {
        if (dec.find('h') != std::string::npos) {
            throw(ghoul::lua::LuaRuntimeException(fmt::format(
                "Dec '{}' format is incorrect. Correct format is: "
                "Dec 'XXdYYmZZs', '-XXdYYmZZs', 'XdYmZs' or '-XdYmZs'", dec))
            );
        }
        parseString(dec, degrees, minutes, seconds);
    }

    bool isRaDecValid(int ra_h, int ra_m, double ra_s, int dec_d,
                      int dec_m, double dec_s)
    {
        // Ra
        if (ra_h < 0.0 || ra_h >= 24.0) {
            LWARNING(fmt::format("Right ascension hours '{}' is outside the allowed "
                "range of 0 to 24 hours (exclusive)", ra_h)
            );
            return false;
        }
        if (ra_m < 0.0 || ra_m >= 60.0) {
            LWARNING(fmt::format("Right ascension minutes '{}' is outside the allowed "
                "range of 0 to 60 minutes (exclusive)", ra_m)
            );
            return false;
        }
        if (ra_s < 0.0 || ra_s >= 60.0) {
            LWARNING(fmt::format("Right ascension seconds '{}' is outside the allowed "
                "range of 0 to 60 seconds (exclusive)", ra_s)
            );
            return false;
        }

        // Dec
        if (dec_d < -90.0 || dec_d > 90.0) {
            LWARNING(fmt::format("Declination degrees '{}' is outside the allowed range "
                "of -90 to 90 degrees (inclusive)", dec_d)
            );
            return false;
        }
        else if ((dec_d == -90.0 || dec_d == 90.0) && (dec_m != 0 || dec_s != 0)) {
            LWARNING("Total declination is outside the allowed range of -90 to 90 "
                "degrees (inclusive)"
            );
            return false;
        }
        if (dec_m < 0.0 || dec_m >= 60.0) {
            LWARNING(fmt::format("Declination minutes '{}' is outside the allowed range "
                "of 0 to 60 minutes (exclusive)", dec_m)
            );
            return false;
        }
        if (dec_s < 0.0 || dec_s >= 60.0) {
            LWARNING(fmt::format("Declination seconds '{}' is outside the allowed range "
                "of 0 to 60 seconds (exclusive)", dec_s)
            );
            return false;
        }

        return true;
    }
} // namespace

namespace openspace {

// Convert Equatorial coordinates ICRS right ascension and declination (a, d)
// into Galactic coordinates (l, b)
glm::dvec3 icrsToGalacticCartesian(double ra, double dec, double distance) {
    // Reference:
    // https://www.atnf.csiro.au/people/Tobias.Westmeier/tools_coords.php

    // (Ra, Dec) -> (a, d)
    double a = glm::radians(ra);
    double d = glm::radians(dec);

    // J2000 Galactic reference frame
    constexpr double a0 = glm::radians(192.8595); // Equatorial coordinates of the Galactic north pole
    constexpr double d0 = glm::radians(27.1284);
    constexpr double l0 = glm::radians(122.9320); // Galactic longitude of the equatorial north pole

    // Convert to galactic reference frame
    double l = l0 - atan2(
        cos(d) * sin(a - a0),
        sin(d) * cos(d0) - cos(d) * sin(d0) * cos(a - a0)
    );
    double b = asin(sin(d) * sin(d0) + cos(d) * cos(d0) * cos(a - a0));

    // Convert to cartesian
    glm::dvec3 rGalactic = glm::dvec3(
        cos(b) * cos(l),
        cos(b) * sin(l),
        sin(b)
    );

    return distance * rGalactic;
}

// Ra format "XXhYYmZZs" or "XhYmZs"
// Dec format "XXdYYmZZs", "-XXdYYmZZs", "XdYmZs" or "-XdYmZs"
glm::dvec2 icrsToDecimalDegrees(const std::string& ra, const std::string& dec) {
    // Reference:
    // https://math.stackexchange.com/questions/15323/how-do-i-calculate-the-cartesian-coordinates-of-stars
    if (ra.size() < 6 || dec.size() < 6) {
        throw(ghoul::lua::LuaRuntimeException(fmt::format(
            "Ra '{}' or Dec '{}' format is incorrect. Correct format is: Ra 'XhYmZs', "
            "and Dec 'XdYmZs'", ra, dec)
        ));
    }

    // Parse right ascension
    int ra_hours, ra_minutes;
    double ra_seconds;
    parseRa(ra, ra_hours, ra_minutes, ra_seconds);

    // Parse declination
    int dec_degrees, dec_minutes;
    double dec_seconds;
    parseDec(dec, dec_degrees, dec_minutes, dec_seconds);

    if (!isRaDecValid(ra_hours, ra_minutes, ra_seconds, dec_degrees, dec_minutes,
        dec_seconds))
    {
        LWARNING(fmt::format("Ra '{}' or Dec '{}' is outside the allowed range, "
            "result may be incorrect", ra, dec)
        );
    }

    // Convert from hours, minutes, seconds to decimal degrees
    double sign = signbit(static_cast<float>(dec_degrees)) ? -1.0 : 1.0;
    double ra_deg = (ra_hours * 15.0) +
        (ra_minutes * 15.0 / 60.0) +
        (ra_seconds * 15.0 / 3600.0);

    double dec_deg = (abs(dec_degrees) +
        (dec_minutes / 60.0) +
        (dec_seconds / 3600.0)) * sign;

    return glm::dvec2(ra_deg, dec_deg);
}

// Convert Galactic coordinates (x, y, z) or (l, b) into
// Equatorial coordinates ICRS right ascension and declination (a, d) plus distance
glm::dvec3 galacticCartesianToIcrs(double x, double y, double z) {
    // References:
    // https://www.atnf.csiro.au/people/Tobias.Westmeier/tools_coords.php,
    // https://en.wikipedia.org/wiki/Celestial_coordinate_system

    // Normalize
    double distance = sqrt(x * x + y * y + z * z);
    double n_x = x / distance;
    double n_y = y / distance;
    double n_z = z / distance;

    // Convert from cartesian
    // (x, y, z) -> (l, b)
    double l = atan2(n_y, n_x);
    double b = asin(n_z);

    // J2000 Galactic reference frame
    constexpr double a0 = glm::radians(192.8595); // Equatorial coordinates of the Galactic north pole
    constexpr double d0 = glm::radians(27.1284);
    constexpr double l0 = glm::radians(122.9320); // Galactic longitude of the equatorial north pole

    // Convert to equatorial reference frame
    double a = atan2(
        cos(b) * sin(l0 - l),
        sin(b) * cos(d0) - cos(b) * sin(d0) * cos(l0 - l)
    ) + a0;
    double d = asin(sin(b) * sin(d0) + cos(b) * cos(d0) * cos(l0 - l));

    glm::dvec3 rEquatorial = glm::dvec3(a, d, distance);

    return rEquatorial;
}

// Return a pair with two formatted strings from the decimal degrees ra and dec
std::pair<std::string, std::string> decimalDegreesToIcrs(double ra, double dec) {
    // References:
    // https://www.rapidtables.com/convert/number/degrees-to-degrees-minutes-seconds.html,
    // https://math.stackexchange.com/questions/15323/how-do-i-calculate-the-cartesian-coordinates-of-stars

    // Radians to degrees
    double ra_deg = glm::degrees(ra);
    double dec_deg = glm::degrees(dec);

    // Check input
    if (ra_deg < 0 || ra_deg > 360 || dec_deg < -90 || dec_deg > 90) {
        LWARNING(fmt::format("Given Ra '{}' or Dec '{}' is outside the allowed range, "
            "result may be incorrect", ra, dec)
        );
    }

    // Calculate Ra
    int ra_hours = std::trunc(ra_deg) / 15.0;
    double ra_minutes_full = (ra_deg - ra_hours * 15.0) * 60.0 / 15.0;
    int ra_minutes = std::trunc(ra_minutes_full);
    double ra_seconds = (ra_minutes_full - ra_minutes) * 60.0;

    // Calculate Dec
    int dec_degrees = std::trunc(dec_deg);
    double dec_minutes_full = (abs(dec_deg) - abs(dec_degrees)) * 60.0;
    int dec_minutes = std::trunc(dec_minutes_full);
    double dec_seconds = (dec_minutes_full - dec_minutes) * 60.0;

    // Construct strings
    std::pair<std::string, std::string> result;
    result.first = std::to_string(ra_hours) + 'h' +
        std::to_string(ra_minutes) + 'm' +
        std::to_string(ra_seconds) + 's';

    result.second = std::to_string(dec_degrees) + 'd' +
        std::to_string(dec_minutes) + 'm' +
        std::to_string(dec_seconds) + 's';

    // Check results
    if (!isRaDecValid(ra_hours, ra_minutes, ra_seconds, dec_degrees, dec_minutes,
        dec_seconds))
    {
        LWARNING(fmt::format("Resulting Ra '{}' or Dec '{}' is outside the allowed range, "
            "result may be incorrect", result.first, result.second)
        );
    }
    return result;
}

} // namespace openspace
<|endoftext|>


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

// Ensure that Python.h is included before any other header in Python debuglet.
#include "common.h"

#include "leaky_bucket.h"

#include "third_party/absl/time/clock.h"
#include "third_party/absl/time/time.h"

#ifndef NACL_BUILD
#include <sys/time.h>
#include <time.h>
#else   // NACL_BUILD
#include "third_party/apphosting/nacl/chromium/base/time.h"
#endif  // NACL_BUILD

#include <algorithm>
#include <limits>

namespace devtools {
namespace cdbg {

static int64 NowInNanoseconds() {
#ifndef NACL_BUILD
  timespec time;
  clock_gettime(CLOCK_MONOTONIC, &time);
  return 1000000000LL * time.tv_sec + time.tv_nsec;
#else   // NACL_BUILD
  return (base::Time::Now() - base::Time::UnixEpoch()).InMicroseconds() * 1000;
#endif  // NACL_BUILD
}

LeakyBucket::LeakyBucket(int64 capacity, int64 fill_rate)
    : capacity_(capacity),
      fractional_tokens_(0.0),
      fill_rate_(fill_rate),
      fill_time_ns_(NowInNanoseconds()) {
  tokens_ = capacity;
}

bool LeakyBucket::RequestTokensSlow(int64 requested_tokens) {
  // Getting the time outside the lock is significantly faster (reduces
  // contention, etc.).
  const int64 current_time_ns = NowInNanoseconds();

  std::lock_guard<std::mutex> lock(mu_);

  const int64 cur_tokens = AtomicLoadTokens();
  if (cur_tokens >= 0) {
    return true;
  }

  const int64 available_tokens =
      RefillBucket(requested_tokens + cur_tokens, current_time_ns);
  if (available_tokens >= 0) {
    return true;
  }

  // Since we were unable to satisfy the request, we need to restore the
  // requested tokens.
  AtomicIncrementTokens(requested_tokens);

  return false;
}

int64 LeakyBucket::RefillBucket(
    int64 available_tokens,
    int64 current_time_ns) {
  if (current_time_ns <= fill_time_ns_) {
    // We check to see if the bucket has been refilled after we checked the
    // current time but before we grabbed mu_. If it has there's nothing to do.
    return AtomicLoadTokens();
  }

  const int64 elapsed_ns = current_time_ns - fill_time_ns_;
  fill_time_ns_ = current_time_ns;

  // Calculate the number of tokens we can add. Note elapsed is in ns while
  // fill_rate_ is in tokens per second, hence the scaling factor.
  // We can get a negative amount of tokens by calling TakeTokens. Make sure we
  // don't add more than the capacity of leaky bucket.
  fractional_tokens_ +=
      std::min(elapsed_ns * (fill_rate_ / 1e9), static_cast<double>(capacity_));
  const int64 ideal_tokens_to_add = fractional_tokens_;

  const int64 max_tokens_to_add = capacity_ - available_tokens;
  int64 real_tokens_to_add;
  if (max_tokens_to_add < ideal_tokens_to_add) {
    fractional_tokens_ = 0.0;
    real_tokens_to_add = max_tokens_to_add;
  } else {
    real_tokens_to_add = ideal_tokens_to_add;
    fractional_tokens_ -= real_tokens_to_add;
  }

  return AtomicIncrementTokens(real_tokens_to_add);
}

void LeakyBucket::TakeTokens(int64 tokens) {
  const int64 remaining = AtomicIncrementTokens(-tokens);

  if (remaining < 0) {
    // (Try to) refill the bucket. If we don't do this, we could just
    // keep decreasing forever without refilling. We need to be
    // refilling at least as frequently as every capacity_ /
    // fill_rate_ seconds. Otherwise, we waste tokens.
    const int64 current_time_ns = NowInNanoseconds();

    std::lock_guard<std::mutex> lock(mu_);
    RefillBucket(remaining, current_time_ns);
  }
}

}  // namespace cdbg
}  // namespace devtools
<commit_msg>Rolling back build breaking change<commit_after>/**
 * Copyright 2015 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// Ensure that Python.h is included before any other header in Python debuglet.
#include "common.h"

#include "leaky_bucket.h"

#ifndef NACL_BUILD
#include <sys/time.h>
#include <time.h>
#else   // NACL_BUILD
#include "third_party/apphosting/nacl/chromium/base/time.h"
#endif  // NACL_BUILD

#include <algorithm>
#include <limits>

namespace devtools {
namespace cdbg {

static int64 NowInNanoseconds() {
#ifndef NACL_BUILD
  timespec time;
  clock_gettime(CLOCK_MONOTONIC, &time);
  return 1000000000LL * time.tv_sec + time.tv_nsec;
#else   // NACL_BUILD
  return (base::Time::Now() - base::Time::UnixEpoch()).InMicroseconds() * 1000;
#endif  // NACL_BUILD
}

LeakyBucket::LeakyBucket(int64 capacity, int64 fill_rate)
    : capacity_(capacity),
      fractional_tokens_(0.0),
      fill_rate_(fill_rate),
      fill_time_ns_(NowInNanoseconds()) {
  tokens_ = capacity;
}

bool LeakyBucket::RequestTokensSlow(int64 requested_tokens) {
  // Getting the time outside the lock is significantly faster (reduces
  // contention, etc.).
  const int64 current_time_ns = NowInNanoseconds();

  std::lock_guard<std::mutex> lock(mu_);

  const int64 cur_tokens = AtomicLoadTokens();
  if (cur_tokens >= 0) {
    return true;
  }

  const int64 available_tokens =
      RefillBucket(requested_tokens + cur_tokens, current_time_ns);
  if (available_tokens >= 0) {
    return true;
  }

  // Since we were unable to satisfy the request, we need to restore the
  // requested tokens.
  AtomicIncrementTokens(requested_tokens);

  return false;
}

int64 LeakyBucket::RefillBucket(
    int64 available_tokens,
    int64 current_time_ns) {
  if (current_time_ns <= fill_time_ns_) {
    // We check to see if the bucket has been refilled after we checked the
    // current time but before we grabbed mu_. If it has there's nothing to do.
    return AtomicLoadTokens();
  }

  const int64 elapsed_ns = current_time_ns - fill_time_ns_;
  fill_time_ns_ = current_time_ns;

  // Calculate the number of tokens we can add. Note elapsed is in ns while
  // fill_rate_ is in tokens per second, hence the scaling factor.
  // We can get a negative amount of tokens by calling TakeTokens. Make sure we
  // don't add more than the capacity of leaky bucket.
  fractional_tokens_ +=
      std::min(elapsed_ns * (fill_rate_ / 1e9), static_cast<double>(capacity_));
  const int64 ideal_tokens_to_add = fractional_tokens_;

  const int64 max_tokens_to_add = capacity_ - available_tokens;
  int64 real_tokens_to_add;
  if (max_tokens_to_add < ideal_tokens_to_add) {
    fractional_tokens_ = 0.0;
    real_tokens_to_add = max_tokens_to_add;
  } else {
    real_tokens_to_add = ideal_tokens_to_add;
    fractional_tokens_ -= real_tokens_to_add;
  }

  return AtomicIncrementTokens(real_tokens_to_add);
}

void LeakyBucket::TakeTokens(int64 tokens) {
  const int64 remaining = AtomicIncrementTokens(-tokens);

  if (remaining < 0) {
    // (Try to) refill the bucket. If we don't do this, we could just
    // keep decreasing forever without refilling. We need to be
    // refilling at least as frequently as every capacity_ /
    // fill_rate_ seconds. Otherwise, we waste tokens.
    const int64 current_time_ns = NowInNanoseconds();

    std::lock_guard<std::mutex> lock(mu_);
    RefillBucket(remaining, current_time_ns);
  }
}

}  // namespace cdbg
}  // namespace devtools
<|endoftext|>


<commit_before>#include "CSharp.h"

extern "C"
{

////////////////////////////////////////////////////// VariantMap //////////////////////////////////////////////////////
URHO3D_EXPORT_API unsigned Urho3D_HashMap_StringHash_Variant_GetKey(Urho3D::VariantMap::Iterator it)
{
    return it->first_.Value();
}

URHO3D_EXPORT_API void* Urho3D_HashMap_StringHash_Variant_GetValue(Urho3D::VariantMap::Iterator it)
{
    return (void*) script->AddRef<Variant>(it->second_);
}

URHO3D_EXPORT_API void Urho3D_HashMap_StringHash_Variant_Add(Urho3D::VariantMap* map, unsigned key,
    Urho3D::Variant* value)
{
    map->Insert(Urho3D::Pair<StringHash, Variant>(StringHash(key), *value));
}

URHO3D_EXPORT_API bool Urho3D_HashMap_StringHash_Variant_Remove(Urho3D::VariantMap* map, unsigned key)
{
    map->Erase(StringHash(key));
}

URHO3D_EXPORT_API bool Urho3D_HashMap_StringHash_Variant_First(Urho3D::VariantMap* map,
    Urho3D::VariantMap::Iterator& it)
{
    if (it == map->End())
        return false;
    it = map->Begin();
    return true;
}

URHO3D_EXPORT_API bool Urho3D_HashMap_StringHash_Variant_Next(Urho3D::VariantMap* map, Urho3D::VariantMap::Iterator& it)
{
    it++;
    return it != map->End();
}

URHO3D_EXPORT_API bool Urho3D_HashMap_StringHash_Variant_Contains(Urho3D::VariantMap* map, unsigned key)
{
    return map->Contains(StringHash(key));
}

URHO3D_EXPORT_API Variant* Urho3D_HashMap_StringHash_Variant_TryGet(Urho3D::VariantMap* map, unsigned key)
{
    Variant result;
    if (map->TryGetValue(StringHash(key), result))
        return script->AddRef<Variant>(std::move(result));
    return nullptr;
}

URHO3D_EXPORT_API void Urho3D_HashMap_StringHash_Variant_destructor(Urho3D::VariantMap* map)
{
    script->ReleaseRef<Urho3D::VariantMap>(map);
}

}
<commit_msg>Fix crash when accessing empty VariantMap.<commit_after>#include "CSharp.h"

extern "C"
{

////////////////////////////////////////////////////// VariantMap //////////////////////////////////////////////////////
URHO3D_EXPORT_API unsigned Urho3D_HashMap_StringHash_Variant_GetKey(Urho3D::VariantMap::Iterator it)
{
    return it->first_.Value();
}

URHO3D_EXPORT_API void* Urho3D_HashMap_StringHash_Variant_GetValue(Urho3D::VariantMap::Iterator it)
{
    return (void*) script->AddRef<Variant>(it->second_);
}

URHO3D_EXPORT_API void Urho3D_HashMap_StringHash_Variant_Add(Urho3D::VariantMap* map, unsigned key,
    Urho3D::Variant* value)
{
    map->Insert(Urho3D::Pair<StringHash, Variant>(StringHash(key), *value));
}

URHO3D_EXPORT_API bool Urho3D_HashMap_StringHash_Variant_Remove(Urho3D::VariantMap* map, unsigned key)
{
    map->Erase(StringHash(key));
}

URHO3D_EXPORT_API bool Urho3D_HashMap_StringHash_Variant_First(Urho3D::VariantMap* map,
    Urho3D::VariantMap::Iterator& it)
{
    it = map->Begin();
    return it != map->End();
}

URHO3D_EXPORT_API bool Urho3D_HashMap_StringHash_Variant_Next(Urho3D::VariantMap* map, Urho3D::VariantMap::Iterator& it)
{
    it++;
    return it != map->End();
}

URHO3D_EXPORT_API bool Urho3D_HashMap_StringHash_Variant_Contains(Urho3D::VariantMap* map, unsigned key)
{
    return map->Contains(StringHash(key));
}

URHO3D_EXPORT_API Variant* Urho3D_HashMap_StringHash_Variant_TryGet(Urho3D::VariantMap* map, unsigned key)
{
    Variant result;
    if (map->TryGetValue(StringHash(key), result))
        return script->AddRef<Variant>(std::move(result));
    return nullptr;
}

URHO3D_EXPORT_API void Urho3D_HashMap_StringHash_Variant_destructor(Urho3D::VariantMap* map)
{
    script->ReleaseRef<Urho3D::VariantMap>(map);
}

}
<|endoftext|>


<commit_before>// Copyright 2014 Project Vogue. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <algorithm>
#include <string>

#include "elang/compiler/compilation_session.h"

#include "elang/base/atomic_string_factory.h"
#include "elang/compiler/ast/namespace.h"
#include "elang/compiler/ast/node_factory.h"
#include "elang/compiler/compilation_unit.h"
#include "elang/compiler/predefined_names.h"
#include "elang/compiler/public/compiler_error_code.h"
#include "elang/compiler/public/compiler_error_data.h"
#include "elang/compiler/string_source_code.h"
#include "elang/compiler/token_factory.h"
#include "elang/compiler/token_type.h"

namespace elang {
namespace compiler {

namespace {

ast::Namespace* CreateGlobalNamespace(CompilationSession* session,
                                      SourceCode* source_code) {
  auto const keyword = session->NewToken(
      SourceCodeRange(source_code, 0, 0),
      TokenData(TokenType::Namespace, session->NewAtomicString(L"namespace")));

  auto const ns_global = session->ast_factory()->NewNamespace(
      nullptr, keyword, session->NewToken(keyword->location(),
                                          session->NewAtomicString(L"global")));
  ns_global->AddNamespaceBody(
      session->ast_factory()->NewNamespaceBody(nullptr, ns_global));
  return ns_global;
}

ast::Namespace* CreateNamespace(CompilationSession* session,
                                ast::Namespace* enclosing_namespace,
                                base::StringPiece16 name) {
  auto const ns = session->ast_factory()->NewNamespace(
      enclosing_namespace->bodies().front(), enclosing_namespace->keyword(),
      session->NewToken(enclosing_namespace->keyword()->location(),
                        session->NewAtomicString(name)));
  ns->AddNamespaceBody(session->ast_factory()->NewNamespaceBody(
      enclosing_namespace->bodies().front(), ns));
  return ns;
}

}  // namespace

//////////////////////////////////////////////////////////////////////
//
// CompilationSession
//
CompilationSession::CompilationSession()
    : ast_factory_(new ast::NodeFactory(zone())),
      atomic_string_factory_(new AtomicStringFactory()),
      predefined_names_(new PredefinedNames(this)),
      source_code_(new StringSourceCode(L"-", L"")),
      token_factory_(new TokenFactory(zone())),
      global_namespace_(CreateGlobalNamespace(this, source_code_.get())),
      system_namespace_(CreateNamespace(this, global_namespace(), L"System")) {
}

CompilationSession::~CompilationSession() {
}

AtomicString* CompilationSession::name_for(PredefinedName name) const {
  return predefined_names_->name_for(name);
}

void CompilationSession::AddError(ErrorCode error_code, Token* token) {
  AddError(token->location(), error_code, std::vector<Token*>{token});
}

void CompilationSession::AddError(ErrorCode error_code,
                                  Token* token1,
                                  Token* token2) {
  AddError(token1->location(), error_code, std::vector<Token*>{token1, token2});
}

void CompilationSession::AddError(const SourceCodeRange& location,
                                  ErrorCode error_code) {
  AddError(location, error_code, std::vector<Token*>());
}

void CompilationSession::AddError(const SourceCodeRange& location,
                                  ErrorCode error_code,
                                  const std::vector<Token*>& tokens) {
  std::vector<ErrorData*>* list =
      error_code > ErrorCode::WarningCodeZero ? &warnings_ : &errors_;
  list->push_back(new (zone()) ErrorData(zone(), location, error_code, tokens));
  std::sort(list->begin(), list->end(),
            [](const ErrorData* a, const ErrorData* b) {
    return a->location().start_offset() < b->location().start_offset();
  });
}

AtomicString* CompilationSession::NewAtomicString(base::StringPiece16 string) {
  return atomic_string_factory_->NewAtomicString(string);
}

CompilationUnit* CompilationSession::NewCompilationUnit(
    SourceCode* source_code) {
  auto unit = std::make_unique<CompilationUnit>(this, source_code);
  compilation_units_.push_back(std::move(unit));
  return compilation_units_.back().get();
}

base::StringPiece16* CompilationSession::NewString(base::StringPiece16 string) {
  auto const buffer = atomic_string_factory_->NewString(string);
  return new (Allocate(sizeof(base::StringPiece16)))
      base::StringPiece16(buffer.data(), buffer.size());
}

Token* CompilationSession::NewUniqueNameToken(const SourceCodeRange& location,
                                              const base::char16* format) {
  auto const name = atomic_string_factory_->NewUniqueAtomicString(format);
  return token_factory_->NewToken(location,
                                  TokenData(TokenType::TempName, name));
}

Token* CompilationSession::NewToken(const SourceCodeRange& location,
                                    const TokenData& data) {
  return token_factory_->NewToken(location, data);
}

Token* CompilationSession::NewToken(const SourceCodeRange& location,
                                    AtomicString* name) {
  return token_factory_->NewToken(location, TokenData(name));
}

}  // namespace compiler
}  // namespace elang
<commit_msg>elang/compiler: Add "System" namespace via |ast::NamespaceBody::AddMember()| rather than |ast::Namespace|.<commit_after>// Copyright 2014 Project Vogue. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <algorithm>
#include <string>

#include "elang/compiler/compilation_session.h"

#include "elang/base/atomic_string_factory.h"
#include "elang/compiler/ast/namespace.h"
#include "elang/compiler/ast/namespace_body.h"
#include "elang/compiler/ast/node_factory.h"
#include "elang/compiler/compilation_unit.h"
#include "elang/compiler/predefined_names.h"
#include "elang/compiler/public/compiler_error_code.h"
#include "elang/compiler/public/compiler_error_data.h"
#include "elang/compiler/string_source_code.h"
#include "elang/compiler/token_factory.h"
#include "elang/compiler/token_type.h"

namespace elang {
namespace compiler {

namespace {

ast::Namespace* CreateGlobalNamespace(CompilationSession* session,
                                      SourceCode* source_code) {
  auto const keyword = session->NewToken(
      SourceCodeRange(source_code, 0, 0),
      TokenData(TokenType::Namespace, session->NewAtomicString(L"namespace")));

  auto const ns_global = session->ast_factory()->NewNamespace(
      nullptr, keyword, session->NewToken(keyword->location(),
                                          session->NewAtomicString(L"global")));
  ns_global->AddNamespaceBody(
      session->ast_factory()->NewNamespaceBody(nullptr, ns_global));
  return ns_global;
}

ast::Namespace* CreateNamespace(CompilationSession* session,
                                ast::Namespace* enclosing_namespace,
                                base::StringPiece16 name) {
  auto const enclosing_body = enclosing_namespace->bodies().front();
  auto const ns = session->ast_factory()->NewNamespace(
      enclosing_body, enclosing_namespace->keyword(),
      session->NewToken(enclosing_namespace->keyword()->location(),
                        session->NewAtomicString(name)));
  enclosing_body->AddMember(ns);
  ns->AddNamespaceBody(
      session->ast_factory()->NewNamespaceBody(enclosing_body, ns));
  return ns;
}

}  // namespace

//////////////////////////////////////////////////////////////////////
//
// CompilationSession
//
CompilationSession::CompilationSession()
    : ast_factory_(new ast::NodeFactory(zone())),
      atomic_string_factory_(new AtomicStringFactory()),
      predefined_names_(new PredefinedNames(this)),
      source_code_(new StringSourceCode(L"-", L"")),
      token_factory_(new TokenFactory(zone())),
      global_namespace_(CreateGlobalNamespace(this, source_code_.get())),
      system_namespace_(CreateNamespace(this, global_namespace(), L"System")) {
}

CompilationSession::~CompilationSession() {
}

AtomicString* CompilationSession::name_for(PredefinedName name) const {
  return predefined_names_->name_for(name);
}

void CompilationSession::AddError(ErrorCode error_code, Token* token) {
  AddError(token->location(), error_code, std::vector<Token*>{token});
}

void CompilationSession::AddError(ErrorCode error_code,
                                  Token* token1,
                                  Token* token2) {
  AddError(token1->location(), error_code, std::vector<Token*>{token1, token2});
}

void CompilationSession::AddError(const SourceCodeRange& location,
                                  ErrorCode error_code) {
  AddError(location, error_code, std::vector<Token*>());
}

void CompilationSession::AddError(const SourceCodeRange& location,
                                  ErrorCode error_code,
                                  const std::vector<Token*>& tokens) {
  std::vector<ErrorData*>* list =
      error_code > ErrorCode::WarningCodeZero ? &warnings_ : &errors_;
  list->push_back(new (zone()) ErrorData(zone(), location, error_code, tokens));
  std::sort(list->begin(), list->end(),
            [](const ErrorData* a, const ErrorData* b) {
    return a->location().start_offset() < b->location().start_offset();
  });
}

AtomicString* CompilationSession::NewAtomicString(base::StringPiece16 string) {
  return atomic_string_factory_->NewAtomicString(string);
}

CompilationUnit* CompilationSession::NewCompilationUnit(
    SourceCode* source_code) {
  auto unit = std::make_unique<CompilationUnit>(this, source_code);
  compilation_units_.push_back(std::move(unit));
  return compilation_units_.back().get();
}

base::StringPiece16* CompilationSession::NewString(base::StringPiece16 string) {
  auto const buffer = atomic_string_factory_->NewString(string);
  return new (Allocate(sizeof(base::StringPiece16)))
      base::StringPiece16(buffer.data(), buffer.size());
}

Token* CompilationSession::NewUniqueNameToken(const SourceCodeRange& location,
                                              const base::char16* format) {
  auto const name = atomic_string_factory_->NewUniqueAtomicString(format);
  return token_factory_->NewToken(location,
                                  TokenData(TokenType::TempName, name));
}

Token* CompilationSession::NewToken(const SourceCodeRange& location,
                                    const TokenData& data) {
  return token_factory_->NewToken(location, data);
}

Token* CompilationSession::NewToken(const SourceCodeRange& location,
                                    AtomicString* name) {
  return token_factory_->NewToken(location, TokenData(name));
}

}  // namespace compiler
}  // namespace elang
<|endoftext|>


<commit_before>#include "stdsneezy.h"
#include "obj_tool.h"

const unsigned int GRAFFITI_MAX = 50;
const int GRAFFITI_OBJ = 33315;

// this proc is meant for tools only, designed with chalk in mind
int graffitiMaker(TBeing *ch, cmdTypeT cmd, const char *arg, TObj *o, TObj *)
{
  if (cmd != CMD_WRITE)
    return FALSE;

  sstring buf;
//  buf = sstring(arg).word(0);
  buf = sstring(arg);

  if (!o || !ch)
    return FALSE;

  TTool *tool = dynamic_cast<TTool *>(o);

  if (!tool)
    return FALSE;

  TBeing *cho = dynamic_cast<TBeing *>(o->equippedBy);

  if (!cho) {
    return FALSE;
  }

//  buf = buf.upper();

//  if (!buf.isWord() || buf.length() > GRAFFITI_MAX) {
  if (buf.length() > GRAFFITI_MAX) {
    ch->sendTo("You can't write that - try something shorter.\n\r");
    return TRUE;
  }

  TObj * gfti = read_object(GRAFFITI_OBJ, VIRTUAL);

  if (!gfti) {
    ch->sendTo("Problem making graffiti object, bug a coder.\n\r");
    vlogf(LOG_BUG, fmt("Couldn't load object (%d) in graffitiMaker.")
        % GRAFFITI_OBJ);
    return TRUE;
  }

  sstring newName = fmt("%s message [graffiti]") % buf;
  sstring newShort = fmt("the message '<W>%s<z>'") % buf;
  sstring newLong = fmt("Some vandal has left a message: '<W>%s<z>'.") % buf;
  gfti->swapToStrung();
  gfti->name = mud_str_dup(newName);
  gfti->shortDescr = mud_str_dup(newShort);
  gfti->setDescr(mud_str_dup(newLong));

  act("$n scrawls some graffiti with $s $p.", TRUE, ch, o, NULL, TO_ROOM);
  act("You make your mark.", TRUE, ch, o, NULL, TO_CHAR);
  tool->addToToolUses(-1);
  *ch->roomp += *gfti;
  return TRUE;
}
<commit_msg>- stripping color codes now - makes more sense that one bag of chalk has just one color - might be cool to add different color bags of chalk later<commit_after>#include "stdsneezy.h"
#include "obj_tool.h"

const unsigned int GRAFFITI_MAX = 50;
const int GRAFFITI_OBJ = 33315;

// this proc is meant for tools only, designed with chalk in mind
int graffitiMaker(TBeing *ch, cmdTypeT cmd, const char *arg, TObj *o, TObj *)
{
  if (cmd != CMD_WRITE)
    return FALSE;

  sstring buf;
//  buf = sstring(arg).word(0);
  buf = sstring(stripColorCodes(arg));

  if (!o || !ch)
    return FALSE;

  TTool *tool = dynamic_cast<TTool *>(o);

  if (!tool)
    return FALSE;

  TBeing *cho = dynamic_cast<TBeing *>(o->equippedBy);

  if (!cho) {
    return FALSE;
  }

//  buf = buf.upper();

//  if (!buf.isWord() || buf.length() > GRAFFITI_MAX) {
  if (buf.length() > GRAFFITI_MAX) {
    ch->sendTo("You can't write that - try something shorter.\n\r");
    return TRUE;
  }

  TObj * gfti = read_object(GRAFFITI_OBJ, VIRTUAL);

  if (!gfti) {
    ch->sendTo("Problem making graffiti object, bug a coder.\n\r");
    vlogf(LOG_BUG, fmt("Couldn't load object (%d) in graffitiMaker.")
        % GRAFFITI_OBJ);
    return TRUE;
  }

  sstring newName = fmt("%s message [graffiti]") % buf;
  sstring newShort = fmt("the message '<W>%s<z>'") % buf;
  sstring newLong = fmt("Some vandal has left a message: '<W>%s<z>'.") % buf;
  gfti->swapToStrung();
  gfti->name = mud_str_dup(newName);
  gfti->shortDescr = mud_str_dup(newShort);
  gfti->setDescr(mud_str_dup(newLong));

  act("$n scrawls some graffiti with $s $p.", TRUE, ch, o, NULL, TO_ROOM);
  act("You make your mark.", TRUE, ch, o, NULL, TO_CHAR);
  tool->addToToolUses(-1);
  *ch->roomp += *gfti;
  return TRUE;
}
<|endoftext|>


<commit_before>// material_tests.cpp
#include "material_tests.h"

#include <cmath>

#include <gtest/gtest.h>

#include "cyc_limits.h"
#include "env.h"
#include "error.h"

namespace cyclus {

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(MaterialTest, Constructors) {
  EXPECT_EQ(default_mat_->units(), "kg");
  EXPECT_EQ(default_mat_->type(), cyclus::Material::kType);
  EXPECT_GE(default_mat_->obj_id(), 0);
  EXPECT_EQ(default_mat_->type(), Material::kType);
  EXPECT_GE(default_mat_->id(), 0);
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(MaterialTest, Clone) {
  Resource::Ptr clone_mat;
  ASSERT_NO_THROW(clone_mat = test_mat_->Clone());

  EXPECT_EQ(test_mat_->type(), clone_mat->type());
  EXPECT_EQ(test_mat_->units(), clone_mat->units());
  EXPECT_DOUBLE_EQ(test_mat_->quantity(), clone_mat->quantity());
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(MaterialTest, ExtractRes) {
  EXPECT_DOUBLE_EQ(test_size_, test_mat_->quantity());
  double other_size = test_size_ / 3;
  Resource::Ptr other;
  ASSERT_NO_THROW(other = test_mat_->ExtractRes(other_size));
  EXPECT_DOUBLE_EQ(test_size_ - other_size, test_mat_->quantity());
  EXPECT_DOUBLE_EQ(other_size, other->quantity());
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(MaterialTest, SimpleAbsorb) {
  double val = 1.5 * units::kg;
  Material::Ptr m1 = Material::CreateUntracked(val, test_comp_);
  Material::Ptr m2 = Material::CreateUntracked(val, test_comp_);
  ASSERT_EQ(m1->comp(), m2->comp());
  ASSERT_EQ(m1->quantity(), m2->quantity());

  m2->Absorb(m1);

  /// ASSERT_EQ(m1->comp(), m2->comp());
  /// EXPECT_EQ(m1->quantity(), 0);
  /// EXPECT_EQ(m2->quantity(), 2 * val);
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(MaterialTest, AbsorbLikeMaterial) {
  Material::Ptr mat1;
  Material::Ptr mat2;
  Material::Ptr mat10;
  mat1 = Material::CreateUntracked(1 * test_size_, test_comp_);
  mat2 = Material::CreateUntracked(2 * test_size_, test_comp_);
  mat10 = Material::CreateUntracked(10 * test_size_, test_comp_);

  // see that two materials with the same composition do the right thing
  double orig = test_mat_->quantity();
  int factor = 2;
  ASSERT_NO_THROW(test_mat_->Absorb(mat1));
  ASSERT_EQ(test_mat_->comp(), mat1->comp());
  EXPECT_DOUBLE_EQ(test_mat_->quantity(), factor * orig);

  factor += 2;
  ASSERT_NO_THROW(test_mat_->Absorb(mat2));
  ASSERT_EQ(test_mat_->comp(), mat2->comp());
  EXPECT_DOUBLE_EQ(test_mat_->quantity(), factor * orig);

  factor += 10;
  ASSERT_NO_THROW(test_mat_->Absorb(mat10));
  ASSERT_EQ(test_mat_->comp(), mat10->comp());
  EXPECT_DOUBLE_EQ(test_mat_->quantity(), factor * orig);
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(MaterialTest, AbsorbUnLikeMaterial) {
  Env::SetNucDataPath();
  // make a number of materials masses 1, 2, and 10
  Material::Ptr same_as_orig_test_mat = Material::CreateUntracked(0,
                                                test_comp_);

  CompMap v;
  v[pb208_] = 1.0 * units::g;
  v[am241_] = 1.0 * units::g;
  v[th228_] = 1.0 * units::g;
  Composition::Ptr diff_test_comp = Composition::CreateFromMass(
                                              v);
  Material::Ptr diff_test_mat = Material::CreateUntracked(
                                        test_size_ / 2,
                                        diff_test_comp);

  double orig = test_mat_->quantity();
  double origdiff = diff_test_mat->quantity();

  // see that materials with different compositions do the right thing
  ASSERT_NO_THROW(test_mat_->Absorb(diff_test_mat));
  EXPECT_NE(test_mat_->comp(), diff_test_mat->comp());
  EXPECT_NE(test_mat_->comp(), same_as_orig_test_mat->comp());
  EXPECT_DOUBLE_EQ(orig + origdiff, test_mat_->quantity());
  EXPECT_TRUE(std::abs(same_as_orig_test_mat->quantity() -
                       test_mat_->quantity()) > eps_rsrc());

  // see that an empty material appropriately absorbs a not empty material.
  ASSERT_NO_THROW(default_mat_->Absorb(test_mat_);
  EXPECT_DOUBLE_EQ(orig + origdiff, default_mat_->quantity());
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(MaterialTest, AbsorbZeroMaterial) {
  Material::Ptr same_as_test_mat = Material::CreateUntracked(0, test_comp_);
  EXPECT_NO_THROW(test_mat_->Absorb(same_as_test_mat));
  EXPECT_FLOAT_EQ(test_size_, test_mat_->quantity());
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(MaterialTest, AbsorbIntoZeroMaterial) {
  Material::Ptr same_as_test_mat = Material::CreateUntracked(0, test_comp_);
  EXPECT_NO_THROW(same_as_test_mat->Absorb(test_mat_));
  EXPECT_FLOAT_EQ(test_size_, same_as_test_mat->quantity());
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(MaterialTest, ExtractMass) {
  double amt = test_size_ / 3;
  double diff = test_size_ - amt;
  Material::Ptr extracted;
  EXPECT_DOUBLE_EQ(test_mat_->quantity(), test_size_);  // we expect this amt
  EXPECT_NO_THROW(extracted = test_mat_->ExtractQty(amt));  // extract an amt
  EXPECT_DOUBLE_EQ(extracted->quantity(), amt);  // check correctness
  EXPECT_DOUBLE_EQ(test_mat_->quantity(), diff);  // check correctness
  EXPECT_EQ(test_mat_->comp(), extracted->comp());
  EXPECT_THROW(two_test_mat_->ExtractQty(2 * two_test_mat_->quantity()),
               Error);
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(MaterialTest, ExtractComplete) {
  Material::Ptr m1;
  EXPECT_NO_THROW(m1 = test_mat_->ExtractComp(test_size_, test_comp_));
  EXPECT_EQ(m1->comp(), test_comp_);
  EXPECT_DOUBLE_EQ(0, test_mat_->quantity());
  EXPECT_DOUBLE_EQ(test_size_, m1->quantity());
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(MaterialTest, ExtractOverQty) {
  EXPECT_THROW(diff_mat_->ExtractComp(2 * test_size_, test_comp_),
               ValueError);
  EXPECT_THROW(test_mat_->ExtractComp(2 * test_size_, test_comp_),
               ValueError);
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(MaterialTest, ExtractOverComp) {
  Material::Ptr m;

  CompMap inexact = diff_comp_->mass();
  inexact[am241_] *= 2;
  Composition::Ptr inexact_comp = Composition::CreateFromMass(inexact);

  EXPECT_THROW(diff_mat_->ExtractComp(test_size_, inexact_comp),
               ValueError);
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(MaterialTest, ExtractHalf) {
  Material::Ptr m1 = two_test_mat_->ExtractComp(test_size_, test_comp_);
  EXPECT_DOUBLE_EQ(test_size_, m1->quantity());
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(MaterialTest, AbsorbThenExtract) {
  Composition::Ptr comp_to_rem = Composition::Ptr(test_comp_);
  double kg_to_rem = 0.25 * test_size_;

  // if you start with an empty material
  EXPECT_DOUBLE_EQ(0, default_mat_->quantity());
  // then you absorb another material, they should be identical
  EXPECT_NO_THROW(default_mat_->Absorb(test_mat_));
  EXPECT_EQ(default_mat_->comp(), test_mat_->comp());
  EXPECT_DOUBLE_EQ(test_size_, default_mat_->quantity());
  // and it should be okay to extract a fraction of the original composiiton
  EXPECT_NO_THROW(default_mat_->ExtractComp(kg_to_rem, comp_to_rem));
  EXPECT_DOUBLE_EQ(test_size_ - kg_to_rem, default_mat_->quantity());
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(MaterialTest, ExtractInGrams) {
  Composition::Ptr comp_to_rem = Composition::Ptr(test_comp_);
  double kg_to_rem = 0.25 * test_size_;
  double g_to_rem = 1000 * kg_to_rem;

  // if you start with an empty material
  EXPECT_DOUBLE_EQ(0, default_mat_->quantity());
  // then you absorb another material, they should be identical
  EXPECT_NO_THROW(default_mat_->Absorb(test_mat_));
  EXPECT_EQ(default_mat_->comp(), test_mat_->comp());
  EXPECT_DOUBLE_EQ(test_size_, default_mat_->quantity());
  // and it should be okay to extract part of the original composiiton IN GRAMS
  EXPECT_NO_THROW(default_mat_->ExtractComp(g_to_rem * units::g, comp_to_rem));
  EXPECT_DOUBLE_EQ(test_size_ - kg_to_rem, default_mat_->quantity());
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(MaterialTest, DecayShortcut) {
  Env::SetNucDataPath();
  CompMap mp;
  mp[922350000] = 1;
  Composition::Ptr c = Composition::CreateFromAtom(mp);
  Material::Ptr m = Material::CreateUntracked(1.0, c);

  double u235_decay_const = 8.087e-11;  // per month
  double eps = 1e-3;
  double threshold = -1 * std::log(1-eps) / u235_decay_const;
  m->Decay(threshold * 0.9);
  EXPECT_EQ(c, m->comp());
}

} // namespace cyclus
<commit_msg>missing )<commit_after>// material_tests.cpp
#include "material_tests.h"

#include <cmath>

#include <gtest/gtest.h>

#include "cyc_limits.h"
#include "env.h"
#include "error.h"

namespace cyclus {

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(MaterialTest, Constructors) {
  EXPECT_EQ(default_mat_->units(), "kg");
  EXPECT_EQ(default_mat_->type(), cyclus::Material::kType);
  EXPECT_GE(default_mat_->obj_id(), 0);
  EXPECT_EQ(default_mat_->type(), Material::kType);
  EXPECT_GE(default_mat_->id(), 0);
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(MaterialTest, Clone) {
  Resource::Ptr clone_mat;
  ASSERT_NO_THROW(clone_mat = test_mat_->Clone());

  EXPECT_EQ(test_mat_->type(), clone_mat->type());
  EXPECT_EQ(test_mat_->units(), clone_mat->units());
  EXPECT_DOUBLE_EQ(test_mat_->quantity(), clone_mat->quantity());
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(MaterialTest, ExtractRes) {
  EXPECT_DOUBLE_EQ(test_size_, test_mat_->quantity());
  double other_size = test_size_ / 3;
  Resource::Ptr other;
  ASSERT_NO_THROW(other = test_mat_->ExtractRes(other_size));
  EXPECT_DOUBLE_EQ(test_size_ - other_size, test_mat_->quantity());
  EXPECT_DOUBLE_EQ(other_size, other->quantity());
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(MaterialTest, SimpleAbsorb) {
  double val = 1.5 * units::kg;
  Material::Ptr m1 = Material::CreateUntracked(val, test_comp_);
  Material::Ptr m2 = Material::CreateUntracked(val, test_comp_);
  ASSERT_EQ(m1->comp(), m2->comp());
  ASSERT_EQ(m1->quantity(), m2->quantity());

  m2->Absorb(m1);

  /// ASSERT_EQ(m1->comp(), m2->comp());
  /// EXPECT_EQ(m1->quantity(), 0);
  /// EXPECT_EQ(m2->quantity(), 2 * val);
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(MaterialTest, AbsorbLikeMaterial) {
  Material::Ptr mat1;
  Material::Ptr mat2;
  Material::Ptr mat10;
  mat1 = Material::CreateUntracked(1 * test_size_, test_comp_);
  mat2 = Material::CreateUntracked(2 * test_size_, test_comp_);
  mat10 = Material::CreateUntracked(10 * test_size_, test_comp_);

  // see that two materials with the same composition do the right thing
  double orig = test_mat_->quantity();
  int factor = 2;
  ASSERT_NO_THROW(test_mat_->Absorb(mat1));
  ASSERT_EQ(test_mat_->comp(), mat1->comp());
  EXPECT_DOUBLE_EQ(test_mat_->quantity(), factor * orig);

  factor += 2;
  ASSERT_NO_THROW(test_mat_->Absorb(mat2));
  ASSERT_EQ(test_mat_->comp(), mat2->comp());
  EXPECT_DOUBLE_EQ(test_mat_->quantity(), factor * orig);

  factor += 10;
  ASSERT_NO_THROW(test_mat_->Absorb(mat10));
  ASSERT_EQ(test_mat_->comp(), mat10->comp());
  EXPECT_DOUBLE_EQ(test_mat_->quantity(), factor * orig);
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(MaterialTest, AbsorbUnLikeMaterial) {
  Env::SetNucDataPath();
  // make a number of materials masses 1, 2, and 10
  Material::Ptr same_as_orig_test_mat = Material::CreateUntracked(0,
                                                test_comp_);

  CompMap v;
  v[pb208_] = 1.0 * units::g;
  v[am241_] = 1.0 * units::g;
  v[th228_] = 1.0 * units::g;
  Composition::Ptr diff_test_comp = Composition::CreateFromMass(
                                              v);
  Material::Ptr diff_test_mat = Material::CreateUntracked(
                                        test_size_ / 2,
                                        diff_test_comp);

  double orig = test_mat_->quantity();
  double origdiff = diff_test_mat->quantity();

  // see that materials with different compositions do the right thing
  ASSERT_NO_THROW(test_mat_->Absorb(diff_test_mat));
  EXPECT_NE(test_mat_->comp(), diff_test_mat->comp());
  EXPECT_NE(test_mat_->comp(), same_as_orig_test_mat->comp());
  EXPECT_DOUBLE_EQ(orig + origdiff, test_mat_->quantity());
  EXPECT_TRUE(std::abs(same_as_orig_test_mat->quantity() -
                       test_mat_->quantity()) > eps_rsrc());

  // see that an empty material appropriately absorbs a not empty material.
  ASSERT_NO_THROW(default_mat_->Absorb(test_mat_));
  EXPECT_DOUBLE_EQ(orig + origdiff, default_mat_->quantity());
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(MaterialTest, AbsorbZeroMaterial) {
  Material::Ptr same_as_test_mat = Material::CreateUntracked(0, test_comp_);
  EXPECT_NO_THROW(test_mat_->Absorb(same_as_test_mat));
  EXPECT_FLOAT_EQ(test_size_, test_mat_->quantity());
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(MaterialTest, AbsorbIntoZeroMaterial) {
  Material::Ptr same_as_test_mat = Material::CreateUntracked(0, test_comp_);
  EXPECT_NO_THROW(same_as_test_mat->Absorb(test_mat_));
  EXPECT_FLOAT_EQ(test_size_, same_as_test_mat->quantity());
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(MaterialTest, ExtractMass) {
  double amt = test_size_ / 3;
  double diff = test_size_ - amt;
  Material::Ptr extracted;
  EXPECT_DOUBLE_EQ(test_mat_->quantity(), test_size_);  // we expect this amt
  EXPECT_NO_THROW(extracted = test_mat_->ExtractQty(amt));  // extract an amt
  EXPECT_DOUBLE_EQ(extracted->quantity(), amt);  // check correctness
  EXPECT_DOUBLE_EQ(test_mat_->quantity(), diff);  // check correctness
  EXPECT_EQ(test_mat_->comp(), extracted->comp());
  EXPECT_THROW(two_test_mat_->ExtractQty(2 * two_test_mat_->quantity()),
               Error);
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(MaterialTest, ExtractComplete) {
  Material::Ptr m1;
  EXPECT_NO_THROW(m1 = test_mat_->ExtractComp(test_size_, test_comp_));
  EXPECT_EQ(m1->comp(), test_comp_);
  EXPECT_DOUBLE_EQ(0, test_mat_->quantity());
  EXPECT_DOUBLE_EQ(test_size_, m1->quantity());
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(MaterialTest, ExtractOverQty) {
  EXPECT_THROW(diff_mat_->ExtractComp(2 * test_size_, test_comp_),
               ValueError);
  EXPECT_THROW(test_mat_->ExtractComp(2 * test_size_, test_comp_),
               ValueError);
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(MaterialTest, ExtractOverComp) {
  Material::Ptr m;

  CompMap inexact = diff_comp_->mass();
  inexact[am241_] *= 2;
  Composition::Ptr inexact_comp = Composition::CreateFromMass(inexact);

  EXPECT_THROW(diff_mat_->ExtractComp(test_size_, inexact_comp),
               ValueError);
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(MaterialTest, ExtractHalf) {
  Material::Ptr m1 = two_test_mat_->ExtractComp(test_size_, test_comp_);
  EXPECT_DOUBLE_EQ(test_size_, m1->quantity());
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(MaterialTest, AbsorbThenExtract) {
  Composition::Ptr comp_to_rem = Composition::Ptr(test_comp_);
  double kg_to_rem = 0.25 * test_size_;

  // if you start with an empty material
  EXPECT_DOUBLE_EQ(0, default_mat_->quantity());
  // then you absorb another material, they should be identical
  EXPECT_NO_THROW(default_mat_->Absorb(test_mat_));
  EXPECT_EQ(default_mat_->comp(), test_mat_->comp());
  EXPECT_DOUBLE_EQ(test_size_, default_mat_->quantity());
  // and it should be okay to extract a fraction of the original composiiton
  EXPECT_NO_THROW(default_mat_->ExtractComp(kg_to_rem, comp_to_rem));
  EXPECT_DOUBLE_EQ(test_size_ - kg_to_rem, default_mat_->quantity());
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(MaterialTest, ExtractInGrams) {
  Composition::Ptr comp_to_rem = Composition::Ptr(test_comp_);
  double kg_to_rem = 0.25 * test_size_;
  double g_to_rem = 1000 * kg_to_rem;

  // if you start with an empty material
  EXPECT_DOUBLE_EQ(0, default_mat_->quantity());
  // then you absorb another material, they should be identical
  EXPECT_NO_THROW(default_mat_->Absorb(test_mat_));
  EXPECT_EQ(default_mat_->comp(), test_mat_->comp());
  EXPECT_DOUBLE_EQ(test_size_, default_mat_->quantity());
  // and it should be okay to extract part of the original composiiton IN GRAMS
  EXPECT_NO_THROW(default_mat_->ExtractComp(g_to_rem * units::g, comp_to_rem));
  EXPECT_DOUBLE_EQ(test_size_ - kg_to_rem, default_mat_->quantity());
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(MaterialTest, DecayShortcut) {
  Env::SetNucDataPath();
  CompMap mp;
  mp[922350000] = 1;
  Composition::Ptr c = Composition::CreateFromAtom(mp);
  Material::Ptr m = Material::CreateUntracked(1.0, c);

  double u235_decay_const = 8.087e-11;  // per month
  double eps = 1e-3;
  double threshold = -1 * std::log(1-eps) / u235_decay_const;
  m->Decay(threshold * 0.9);
  EXPECT_EQ(c, m->comp());
}

} // namespace cyclus
<|endoftext|>


<commit_before>//-----------------------------------------------------------
//
//    Copyright (C) 2015 by the deal2lkit authors
//
//    This file is part of the deal2lkit library.
//
//    The deal2lkit library is free software; you can use it, 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.
//    The full text of the license can be found in the file LICENSE at
//    the top level of the deal2lkit distribution.
//
//-----------------------------------------------------------

#include "../tests.h"
#include <deal2lkit/utilities.h>
#include <deal2lkit/parsed_grid_generator.h>

#include <deal.II/grid/grid_out.h>
#include <deal.II/base/utilities.h>

using namespace deal2lkit;

template<int dim, int spacedim>
void test(ParsedGridGenerator<dim, spacedim> &pgg)
{
  Triangulation<dim, spacedim> *tria = pgg.serial();
  GridOut go;
  go.write_msh(*tria, deallog.get_file_stream());
}

int main ()
{
  initlog();
  ParsedGridGenerator<2,2> a("Rectangle");
  ParsedGridGenerator<2,2> b("Rectangle with points");

  ParameterHandler prm;

  Point<2> p1, p2;
  std::string string1, string2, string3;

  p1[0] = -1.;
  p1[1] = -2.;
  p2[0] = 1.;
  p2[1] = 2.;

  string1 = print(p1);
  string2 = print(p2);
  ParameterAcceptor::declare_all_parameters(prm);

  prm.read_input_from_string(""
                             "subsection Rectangle\n"
                             "  set Grid to generate = rectangle \n"
                             "  set Optional Point<spacedim> 1 = 0, 0 \n"
                             "  set Optional Point<spacedim> 2 = -1., -2. \n"
                             "end\n");

  string3 = ""
            "subsection Rectangle with points\n"
            "  set Grid to generate = hyperrectangle \n"
            "  set Optional Point<spacedim> 1 = "+ string1 +"\n"
            "  set Optional Point<spacedim> 2 = "+ string2 +"\n"
            "end\n";
  prm.read_input_from_string(string3.c_str());

  ParameterAcceptor::parse_all_parameters(prm);

  test(a);
  test(b);
}
<commit_msg>fix test parsed_grid_generator_04<commit_after>//-----------------------------------------------------------
//
//    Copyright (C) 2015 by the deal2lkit authors
//
//    This file is part of the deal2lkit library.
//
//    The deal2lkit library is free software; you can use it, 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.
//    The full text of the license can be found in the file LICENSE at
//    the top level of the deal2lkit distribution.
//
//-----------------------------------------------------------

#include "../tests.h"
#include <deal2lkit/utilities.h>
#include <deal2lkit/parsed_grid_generator.h>

#include <deal.II/grid/grid_out.h>
#include <deal.II/base/utilities.h>

using namespace deal2lkit;

template<int dim, int spacedim>
void test(ParsedGridGenerator<dim, spacedim> &pgg)
{
  Triangulation<dim, spacedim> *tria = pgg.serial();
  GridOut go;
  go.write_msh(*tria, deallog.get_file_stream());
}

int main ()
{
  initlog();
  ParsedGridGenerator<2,2> a("Rectangle");
  ParsedGridGenerator<2,2> b("Rectangle with points");

  ParameterHandler prm;

  Point<2> p1, p2;
  std::string string1, string2, string3;

  p1[0] = -1.;
  p1[1] = -2.;
  p2[0] = 1.;
  p2[1] = 2.;

  string1 = print(p1);
  string2 = print(p2);
  ParameterAcceptor::declare_all_parameters(prm);

  prm.read_input_from_string(""
                             "subsection Rectangle\n"
                             "  set Grid to generate = rectangle \n"
                             "  set Optional Point<spacedim> 1 = 0, 0 \n"
                             "  set Optional Point<spacedim> 2 = -1., -2. \n"
                             "end\n");

  string3 = ""
            "subsection Rectangle with points\n"
            "  set Grid to generate = rectangle \n"
            "  set Optional Point<spacedim> 1 = "+ string1 +"\n"
            "  set Optional Point<spacedim> 2 = "+ string2 +"\n"
            "end\n";
  prm.read_input_from_string(string3.c_str());

  ParameterAcceptor::parse_all_parameters(prm);

  test(a);
  test(b);
}
<|endoftext|>


<commit_before>#include "nodeType.h"
#include "diagram.h"
#include "xmlCompiler.h"
#include "outFile.h"
#include "pointPort.h"
#include "linePort.h"
#include "editor.h"
#include "nameNormalizer.h"
#include "label.h"

#include <QDebug>

NodeType::NodeType(Diagram *diagram) : GraphicType(diagram)
{}

NodeType::~NodeType()
{
	foreach (Port *port, mPorts)
	{
		delete port;
	}
}

bool NodeType::initAssociations()
{
	return true;
}

void NodeType::addKernelParent()
{
	if ((mName != "Kernel Element") && (mName != "Named Element"))
	{
		mParents.append("Named Element");
	}
}

bool NodeType::initGraphics()
{
	if (!initSdf())
	{
		return false;
	}
	if (!initPorts())
	{
		return false;
	}
	return true;
}

bool NodeType::initSdf()
{
	QDomElement sdfElement = mElement.firstChildElement("picture");
	if (sdfElement.isNull())
	{
		mVisible = (mName == "NamedElement");
	}
	else
	{
		mWidth = sdfElement.attribute("sizex").toInt();
		mHeight = sdfElement.attribute("sizey").toInt();
		QString name = NameNormalizer::normalize(mName);
		QString resourceName = name + "Class.sdf";
		mDiagram->editor()->xmlCompiler()->addResource("\t<file>" + resourceName + "</file>\n");
		OutFile out("generated/shapes/" + resourceName);
		sdfElement.save(out(), 1);
		mVisible = true;
	}
	return true;
}

bool NodeType::initPorts()
{
	QDomElement portsElement = mElement.firstChildElement("ports");
	if (portsElement.isNull())
	{
		return true;
	}
	QString const name = NameNormalizer::normalize(mName);
	mDiagram->editor()->xmlCompiler()->addResource("\t<file>" + name + "Ports.sdf" + "</file>\n");
	OutFile out("generated/shapes/" + name + "Ports.sdf");
	out() << "<picture ";
	out() << "sizex=\"" << portsElement.attribute("sizex").toInt() << "\" ";
	out() << "sizey=\"" << portsElement.attribute("sizey").toInt() << "\" ";
	out() << ">\n";

	if (!initPointPorts(portsElement, out))
	{
		qDebug() << "Error: can't parse point ports";
		return false;
	}
	if (!initLinePorts(portsElement, out))
	{
		qDebug() << "Error: can't parse line ports";
		return false;
	}
	return true;
}

bool NodeType::initPointPorts(QDomElement const &portsElement, OutFile &out)
{
	for (QDomElement portElement = portsElement.firstChildElement("pointPort"); !portElement.isNull();
		portElement = portElement.nextSiblingElement("pointPort"))
	{
		out() << "\t<point stroke-width=\"11\" stroke-style=\"solid\" stroke=\"#c3dcc4\" ";
		out() << "x1=\""<<portElement.attribute("x") << "\" y1=\""<<portElement.attribute("y") << "\" ";
		out() << "/>\n";
		out() << "\t<point stroke-width=\"3\" stroke-style=\"solid\" stroke=\"#465945\" ";
		out() << "x1=\"" << portElement.attribute("x") << "\" y1=\"" << portElement.attribute("y") << "\" ";
		out() << "/>\n";

		Port *pointPort = new PointPort();
		if (!pointPort->init(portElement, mWidth, mHeight))
		{
			delete pointPort;
			return false;
		}
		mPorts.append(pointPort);
	}
	return true;
}

bool NodeType::initLinePorts(QDomElement const &portsElement, OutFile &out)
{
	for (QDomElement portElement = portsElement.firstChildElement("linePort"); !portElement.isNull();
		portElement = portElement.nextSiblingElement("linePort"))
	{
		QDomElement portStartElement = portElement.firstChildElement("start");
		QDomElement portEndElement = portElement.firstChildElement("end");

		out() << "\t<line x1=\"" << portStartElement.attribute("startx") << "\" y1=\"" << portStartElement.attribute("starty") << "\" ";
		out() << "x2=\"" << portEndElement.attribute("endx") << "\" y2=\"" << portEndElement.attribute("endy") << "\" ";
		out() << "stroke-width=\"7\" stroke-style=\"solid\" stroke=\"#c3dcc4\" ";
		out() << "/>\n";

		out() << "\t<line x1=\"" << portStartElement.attribute("startx") << "\" y1=\""<<portStartElement.attribute("starty") << "\" ";
		out() << "x2=\""<<portEndElement.attribute("endx") << "\" y2=\"" << portEndElement.attribute("endy") << "\" ";
		out() << "stroke-width=\"1\" stroke-style=\"solid\" stroke=\"#465945\" ";
		out() << "/>\n";

		Port *linePort = new LinePort();
		if (!linePort->init(portElement, mWidth, mHeight))
		{
			delete linePort;
			return false;
		}
		mPorts.append(linePort);
	}
	return true;
}

void NodeType::generateCode(OutFile &out)
{
	QString const className = NameNormalizer::normalize(mName);

	out() << "\tclass " << className << " : public NodeElement {\n"
		<< "\tpublic:\n"
		<< "\t\t" << className << "() {\n";

	bool hasSdf = false;
	bool hasPorts = false;

	QFile sdffile("generated/shapes/" + className + "Class.sdf");
	if (sdffile.exists()) {
		out() << "\t\t\tmRenderer.load(QString(\":/" << className << "Class.sdf\"));\n";
		hasSdf = true;
	}

	sdffile.setFileName("generated/shapes/" + className + "Ports.sdf");
	if (sdffile.exists()) {
		out() << "\t\t\tmPortRenderer.load(QString(\":/" << className << "Ports.sdf\"));\n";
		hasPorts = true;
	}

	out() << "\t\t\tmContents.setWidth(" << mWidth << ");\n"
		<< "\t\t\tmContents.setHeight(" << mHeight << ");\n"
		<< "\t\t\tmTitle.setFlags(0);\n"
		<< "\t\t\tmTitle.setTextInteractionFlags(Qt::NoTextInteraction);\n"
		<< "\t\t\tmTitle.setParentItem(this);\n";

	// True horror:
	if ((className == "Class_method") || (className == "Class_field")) {
		out() << "\tmDocVis.setParentItem(this);\n"
			<< "\tmDocType.setParentItem(this);\n";
	}

	foreach (Port *port, mPorts)
	{
		port->generateCode(out);
	}

	out() << "\t\t}\n\n"
		<< "\t\t~" << className << "() {}\n\n"
		<< "\t\tvoid paint(QPainter *painter, QStyleOptionGraphicsItem const *style, QWidget *widget)\n\t\t{\n";

	if (hasSdf)
		out() << "\t\t\tmRenderer.render(painter, mContents);\n";

	if (hasPorts)
		out() << "\t\t\tNodeElement::paint(painter, style, widget, &mPortRenderer);\n";
	else
		out() << "\t\t\tNodeElement::paint(painter, style, widget, NULL);\n";

	out() << "\t\t}\n\n"
		<< "\t\tvoid updateData()\n\t\t{\n"
		<< "\t\t\tNodeElement::updateData();\n";

	foreach (Label *label, mLabels)
	{
		label->generateCode(out);
	}
	if (mLabels.size() > 0)  //
	{
		out() << ";\n";
		out() << "\t\t\tmTitle.setHtml(text);\n";
	}

	out() << "\t\t\tupdate();\n" << "\t\t}\n\n";

	out() << "\tprivate:\n";
	if (hasSdf)
		out() << "\t\tSdfRenderer mRenderer;\n";
	if (hasPorts)
		out() << "\t\tSdfRenderer mPortRenderer;\n";
	out() << "\t};";
	out() << "\n\n";
}<commit_msg>порты поправлены<commit_after>#include "nodeType.h"
#include "diagram.h"
#include "xmlCompiler.h"
#include "outFile.h"
#include "pointPort.h"
#include "linePort.h"
#include "editor.h"
#include "nameNormalizer.h"
#include "label.h"

#include <QDebug>

NodeType::NodeType(Diagram *diagram) : GraphicType(diagram)
{}

NodeType::~NodeType()
{
	foreach (Port *port, mPorts)
	{
		delete port;
	}
}

bool NodeType::initAssociations()
{
	return true;
}

void NodeType::addKernelParent()
{
	if ((mName != "Kernel Element") && (mName != "Named Element"))
	{
		mParents.append("Named Element");
	}
}

bool NodeType::initGraphics()
{
	if (!initSdf())
	{
		return false;
	}
	if (!initPorts())
	{
		return false;
	}
	return true;
}

bool NodeType::initSdf()
{
	QDomElement sdfElement = mElement.firstChildElement("picture");
	if (sdfElement.isNull())
	{
		mVisible = (mName == "NamedElement");
	}
	else
	{
		mWidth = sdfElement.attribute("sizex").toInt();
		mHeight = sdfElement.attribute("sizey").toInt();
		QString name = NameNormalizer::normalize(mName);
		QString resourceName = name + "Class.sdf";
		mDiagram->editor()->xmlCompiler()->addResource("\t<file>" + resourceName + "</file>\n");
		OutFile out("generated/shapes/" + resourceName);
		sdfElement.save(out(), 1);
		mVisible = true;
	}
	return true;
}

bool NodeType::initPorts()
{
	QDomElement portsElement = mElement.firstChildElement("ports");
	if (portsElement.isNull())
	{
		return true;
	}
	QString const name = NameNormalizer::normalize(mName);
	mDiagram->editor()->xmlCompiler()->addResource("\t<file>" + name + "Ports.sdf" + "</file>\n");
	OutFile out("generated/shapes/" + name + "Ports.sdf");
	out() << "<picture ";
	out() << "sizex=\"" << mWidth << "\" ";
	out() << "sizey=\"" << mHeight << "\" ";
	out() << ">\n";

	if (!initPointPorts(portsElement, out))
	{
		qDebug() << "Error: can't parse point ports";
		return false;
	}
	if (!initLinePorts(portsElement, out))
	{
		qDebug() << "Error: can't parse line ports";
		return false;
	}
	out() << "</picture>\n";
	return true;
}

bool NodeType::initPointPorts(QDomElement const &portsElement, OutFile &out)
{
	for (QDomElement portElement = portsElement.firstChildElement("pointPort"); !portElement.isNull();
		portElement = portElement.nextSiblingElement("pointPort"))
	{
		out() << "\t<point stroke-width=\"11\" stroke-style=\"solid\" stroke=\"#c3dcc4\" ";
		out() << "x1=\""<<portElement.attribute("x") << "\" y1=\""<<portElement.attribute("y") << "\" ";
		out() << "/>\n";
		out() << "\t<point stroke-width=\"3\" stroke-style=\"solid\" stroke=\"#465945\" ";
		out() << "x1=\"" << portElement.attribute("x") << "\" y1=\"" << portElement.attribute("y") << "\" ";
		out() << "/>\n";

		Port *pointPort = new PointPort();
		if (!pointPort->init(portElement, mWidth, mHeight))
		{
			delete pointPort;
			return false;
		}
		mPorts.append(pointPort);
	}
	return true;
}

bool NodeType::initLinePorts(QDomElement const &portsElement, OutFile &out)
{
	for (QDomElement portElement = portsElement.firstChildElement("linePort"); !portElement.isNull();
		portElement = portElement.nextSiblingElement("linePort"))
	{
		QDomElement portStartElement = portElement.firstChildElement("start");
		QDomElement portEndElement = portElement.firstChildElement("end");

		out() << "\t<line x1=\"" << portStartElement.attribute("startx") << "\" y1=\"" << portStartElement.attribute("starty") << "\" ";
		out() << "x2=\"" << portEndElement.attribute("endx") << "\" y2=\"" << portEndElement.attribute("endy") << "\" ";
		out() << "stroke-width=\"7\" stroke-style=\"solid\" stroke=\"#c3dcc4\" ";
		out() << "/>\n";

		out() << "\t<line x1=\"" << portStartElement.attribute("startx") << "\" y1=\""<<portStartElement.attribute("starty") << "\" ";
		out() << "x2=\""<<portEndElement.attribute("endx") << "\" y2=\"" << portEndElement.attribute("endy") << "\" ";
		out() << "stroke-width=\"1\" stroke-style=\"solid\" stroke=\"#465945\" ";
		out() << "/>\n";

		Port *linePort = new LinePort();
		if (!linePort->init(portElement, mWidth, mHeight))
		{
			delete linePort;
			return false;
		}
		mPorts.append(linePort);
	}
	return true;
}

void NodeType::generateCode(OutFile &out)
{
	QString const className = NameNormalizer::normalize(mName);

	out() << "\tclass " << className << " : public NodeElement {\n"
		<< "\tpublic:\n"
		<< "\t\t" << className << "() {\n";

	bool hasSdf = false;
	bool hasPorts = false;

	QFile sdffile("generated/shapes/" + className + "Class.sdf");
	if (sdffile.exists()) {
		out() << "\t\t\tmRenderer.load(QString(\":/" << className << "Class.sdf\"));\n";
		hasSdf = true;
	}

	sdffile.setFileName("generated/shapes/" + className + "Ports.sdf");
	if (sdffile.exists()) {
		out() << "\t\t\tmPortRenderer.load(QString(\":/" << className << "Ports.sdf\"));\n";
		hasPorts = true;
	}

	out() << "\t\t\tmContents.setWidth(" << mWidth << ");\n"
		<< "\t\t\tmContents.setHeight(" << mHeight << ");\n"
		<< "\t\t\tmTitle.setFlags(0);\n"
		<< "\t\t\tmTitle.setTextInteractionFlags(Qt::NoTextInteraction);\n"
		<< "\t\t\tmTitle.setParentItem(this);\n";

	// True horror:
	if ((className == "Class_method") || (className == "Class_field")) {
		out() << "\tmDocVis.setParentItem(this);\n"
			<< "\tmDocType.setParentItem(this);\n";
	}

	foreach (Port *port, mPorts)
	{
		port->generateCode(out);
	}

	out() << "\t\t}\n\n"
		<< "\t\t~" << className << "() {}\n\n"
		<< "\t\tvoid paint(QPainter *painter, QStyleOptionGraphicsItem const *style, QWidget *widget)\n\t\t{\n";

	if (hasSdf)
		out() << "\t\t\tmRenderer.render(painter, mContents);\n";

	if (hasPorts)
		out() << "\t\t\tNodeElement::paint(painter, style, widget, &mPortRenderer);\n";
	else
		out() << "\t\t\tNodeElement::paint(painter, style, widget, NULL);\n";

	out() << "\t\t}\n\n"
		<< "\t\tvoid updateData()\n\t\t{\n"
		<< "\t\t\tNodeElement::updateData();\n";

	foreach (Label *label, mLabels)
	{
		label->generateCode(out);
	}
	if (mLabels.size() > 0)  //
	{
		out() << ";\n";
		out() << "\t\t\tmTitle.setHtml(text);\n";
	}

	out() << "\t\t\tupdate();\n" << "\t\t}\n\n";

	out() << "\tprivate:\n";
	if (hasSdf)
		out() << "\t\tSdfRenderer mRenderer;\n";
	if (hasPorts)
		out() << "\t\tSdfRenderer mPortRenderer;\n";
	out() << "\t};";
	out() << "\n\n";
}<|endoftext|>


<commit_before>/*
 Kopete Oscar Protocol
 icqsearchdialog.cpp - search for people

 Copyright (c) 2005 Matt Rogers <mattr@kde.org>

 Kopete (c) 2002-2005 by the Kopete developers <kopete-devel@kde.org>

 *************************************************************************
 *                                                                       *
 * 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 of the License, or (at your option) any later version.      *
 *                                                                       *
 *************************************************************************
*/

#include "icqsearchdialog.h"

#include <qlineedit.h>
#include <qcheckbox.h>
#include <qcombobox.h>
#include <qlayout.h>
#include <kdebug.h>
#include <kiconloader.h>
#include <klistview.h>
#include <klocale.h>
#include <kpushbutton.h>
#include "icqaccount.h"
#include "icqprotocol.h"
#include "icqsearchbase.h"
#include "oscartypes.h"

ICQSearchDialog::ICQSearchDialog( ICQAccount* account, QWidget* parent, const char* name )
: KDialogBase( parent, name, true, i18n( "ICQ User Search" ), 0, NoDefault )
{
	m_account = account;
	m_searchUI = new ICQSearchBase( this, name );
	setMainWidget( m_searchUI );
	connect( m_searchUI->searchButton, SIGNAL( clicked() ), this, SLOT( startSearch() ) );
	connect( m_searchUI->searchResults, SIGNAL( selectionChanged() ), this, SLOT( resultSelectionChanged() ) );
	connect( m_searchUI->addButton, SIGNAL( clicked() ), this, SLOT( addContact() ) );
	connect( m_searchUI->clearButton, SIGNAL( clicked() ), this, SLOT( clearResults() ) );
	connect( m_searchUI->stopButton, SIGNAL( clicked() ), this, SLOT( stopSearch() ) );

	ICQProtocol *p = ICQProtocol::protocol();
	p->fillComboFromTable( m_searchUI->gender, p->genders() );
	p->fillComboFromTable( m_searchUI->country, p->countries() );
	p->fillComboFromTable( m_searchUI->language, p->languages() );
}

ICQSearchDialog::~ICQSearchDialog()
{
}

void ICQSearchDialog::startSearch()
{
	m_searchUI->stopButton->setEnabled( true );
	connect( m_account->engine(), SIGNAL( gotSearchResults( const ICQSearchResult& ) ),
	         this, SLOT( newResult( const ICQSearchResult& ) ) );
	connect( m_account->engine(), SIGNAL( endOfSearch( int ) ),
	         this, SLOT( searchFinished( int ) ) );

	if ( !m_searchUI->uin->text().isEmpty() )
	{
		//doing a uin search
		m_account->engine()->uinSearch( m_searchUI->uin->text() );
	}
	else
	{
		//create a ICQWPSearchInfo struct and send it
		ICQProtocol* p = ICQProtocol::protocol();
		ICQWPSearchInfo info;
		info.firstName = m_searchUI->firstName->text();
		info.lastName = m_searchUI->lastName->text();
		info.nickName = m_searchUI->nickName->text();
		info.email = m_searchUI->email->text();
		info.city = m_searchUI->city->text(); // City
		info.gender = m_searchUI->gender->currentItem(); // Gender
		info.language = p->getCodeForCombo(m_searchUI->language, p->languages()); // Lang
		info.country =p->getCodeForCombo(m_searchUI->country, p->countries()); // country code
		info.onlineOnly = m_searchUI->onlyOnline->isChecked();
		kdWarning(OSCAR_ICQ_DEBUG) << k_funcinfo << "Whitepage searching not implemented yet" << endl;
	}
}

void ICQSearchDialog::stopSearch()
{
	disconnect( m_account->engine(), SIGNAL( gotSearchResults( const ICQSearchResult& ) ),
	         this, SLOT( newResult( const ICQSearchResult& ) ) );
	disconnect( m_account->engine(), SIGNAL( endOfSearch( int ) ),
	         this, SLOT( searchFinished( int ) ) );
	m_searchUI->stopButton->setEnabled( false );
}

void ICQSearchDialog::addContact()
{
	//push the uin to the add contact wizard.
}

void ICQSearchDialog::clearResults()
{
	stopSearch();
	m_searchUI->searchResults->clear();
	m_searchUI->addButton->setEnabled( false );
}

void ICQSearchDialog::resultSelectionChanged()
{
	if ( !m_searchUI->searchResults->selectedItem() )
		m_searchUI->addButton->setEnabled( false );
	else
		m_searchUI->addButton->setEnabled( true );
}

void ICQSearchDialog::newResult( const ICQSearchResult& info )
{
	if ( info.uin == '1' )
	{
		//TODO update progress
		return;
	}

	QListViewItem *item = new QListViewItem(m_searchUI->searchResults, QString::number( info.uin ),
	                                        info.nickName, info.firstName, info.lastName, info.email);

	if ( !item )
		return;

	info.online ? item->setPixmap( 0, SmallIcon( "icq_online" ) ) : item->setPixmap( 0, SmallIcon( "icq_offline" ) );

}

void ICQSearchDialog::searchFinished( int numLeft )
{
	kdWarning(OSCAR_ICQ_DEBUG) << k_funcinfo << "There are " << numLeft << "contact left out of this search" << endl;
}

//kate: indent-mode csands; space-indent off; replace-tabs off; tab-width 4;
<commit_msg>Includemoc, cvsignore<commit_after>/*
 Kopete Oscar Protocol
 icqsearchdialog.cpp - search for people

 Copyright (c) 2005 Matt Rogers <mattr@kde.org>

 Kopete (c) 2002-2005 by the Kopete developers <kopete-devel@kde.org>

 *************************************************************************
 *                                                                       *
 * 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 of the License, or (at your option) any later version.      *
 *                                                                       *
 *************************************************************************
*/

#include "icqsearchdialog.h"

#include <qlineedit.h>
#include <qcheckbox.h>
#include <qcombobox.h>
#include <qlayout.h>
#include <kdebug.h>
#include <kiconloader.h>
#include <klistview.h>
#include <klocale.h>
#include <kpushbutton.h>
#include "icqaccount.h"
#include "icqprotocol.h"
#include "icqsearchbase.h"
#include "oscartypes.h"

ICQSearchDialog::ICQSearchDialog( ICQAccount* account, QWidget* parent, const char* name )
: KDialogBase( parent, name, true, i18n( "ICQ User Search" ), 0, NoDefault )
{
	m_account = account;
	m_searchUI = new ICQSearchBase( this, name );
	setMainWidget( m_searchUI );
	connect( m_searchUI->searchButton, SIGNAL( clicked() ), this, SLOT( startSearch() ) );
	connect( m_searchUI->searchResults, SIGNAL( selectionChanged() ), this, SLOT( resultSelectionChanged() ) );
	connect( m_searchUI->addButton, SIGNAL( clicked() ), this, SLOT( addContact() ) );
	connect( m_searchUI->clearButton, SIGNAL( clicked() ), this, SLOT( clearResults() ) );
	connect( m_searchUI->stopButton, SIGNAL( clicked() ), this, SLOT( stopSearch() ) );

	ICQProtocol *p = ICQProtocol::protocol();
	p->fillComboFromTable( m_searchUI->gender, p->genders() );
	p->fillComboFromTable( m_searchUI->country, p->countries() );
	p->fillComboFromTable( m_searchUI->language, p->languages() );
}

ICQSearchDialog::~ICQSearchDialog()
{
}

void ICQSearchDialog::startSearch()
{
	m_searchUI->stopButton->setEnabled( true );
	connect( m_account->engine(), SIGNAL( gotSearchResults( const ICQSearchResult& ) ),
	         this, SLOT( newResult( const ICQSearchResult& ) ) );
	connect( m_account->engine(), SIGNAL( endOfSearch( int ) ),
	         this, SLOT( searchFinished( int ) ) );

	if ( !m_searchUI->uin->text().isEmpty() )
	{
		//doing a uin search
		m_account->engine()->uinSearch( m_searchUI->uin->text() );
	}
	else
	{
		//create a ICQWPSearchInfo struct and send it
		ICQProtocol* p = ICQProtocol::protocol();
		ICQWPSearchInfo info;
		info.firstName = m_searchUI->firstName->text();
		info.lastName = m_searchUI->lastName->text();
		info.nickName = m_searchUI->nickName->text();
		info.email = m_searchUI->email->text();
		info.city = m_searchUI->city->text(); // City
		info.gender = m_searchUI->gender->currentItem(); // Gender
		info.language = p->getCodeForCombo(m_searchUI->language, p->languages()); // Lang
		info.country =p->getCodeForCombo(m_searchUI->country, p->countries()); // country code
		info.onlineOnly = m_searchUI->onlyOnline->isChecked();
		kdWarning(OSCAR_ICQ_DEBUG) << k_funcinfo << "Whitepage searching not implemented yet" << endl;
	}
}

void ICQSearchDialog::stopSearch()
{
	disconnect( m_account->engine(), SIGNAL( gotSearchResults( const ICQSearchResult& ) ),
	         this, SLOT( newResult( const ICQSearchResult& ) ) );
	disconnect( m_account->engine(), SIGNAL( endOfSearch( int ) ),
	         this, SLOT( searchFinished( int ) ) );
	m_searchUI->stopButton->setEnabled( false );
}

void ICQSearchDialog::addContact()
{
	//push the uin to the add contact wizard.
}

void ICQSearchDialog::clearResults()
{
	stopSearch();
	m_searchUI->searchResults->clear();
	m_searchUI->addButton->setEnabled( false );
}

void ICQSearchDialog::resultSelectionChanged()
{
	if ( !m_searchUI->searchResults->selectedItem() )
		m_searchUI->addButton->setEnabled( false );
	else
		m_searchUI->addButton->setEnabled( true );
}

void ICQSearchDialog::newResult( const ICQSearchResult& info )
{
	if ( info.uin == '1' )
	{
		//TODO update progress
		return;
	}

	QListViewItem *item = new QListViewItem(m_searchUI->searchResults, QString::number( info.uin ),
	                                        info.nickName, info.firstName, info.lastName, info.email);

	if ( !item )
		return;

	info.online ? item->setPixmap( 0, SmallIcon( "icq_online" ) ) : item->setPixmap( 0, SmallIcon( "icq_offline" ) );

}

void ICQSearchDialog::searchFinished( int numLeft )
{
	kdWarning(OSCAR_ICQ_DEBUG) << k_funcinfo << "There are " << numLeft << "contact left out of this search" << endl;
}

//kate: indent-mode csands; space-indent off; replace-tabs off; tab-width 4;

#include "icqsearchdialog.moc"
<|endoftext|>