<commit_before>/*

Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

*/

#include "Extractor/ExtractorCallbacks.h"
#include "Extractor/ExtractionContainers.h"
#include "Extractor/ScriptingEnvironment.h"
#include "Extractor/PBFParser.h"
#include "Extractor/XMLParser.h"
#include "Util/GitDescription.h"
#include "Util/MachineInfo.h"
#include "Util/OpenMPWrapper.h"
#include "Util/OSRMException.h"
#include "Util/ProgramOptions.h"
#include "Util/SimpleLogger.h"
#include "Util/StringUtil.h"
#include "Util/TimingUtil.h"
#include "Util/UUID.h"
#include "typedefs.h"

#include <cstdlib>

#include <boost/unordered_map.hpp>

#include <iostream>
#include <fstream>
#include <string>

ExtractorCallbacks * extractCallBacks;
UUID uuid;

int main (int argc, char *argv[]) {
    try {
        LogPolicy::GetInstance().Unmute();
        double startup_time = get_timestamp();

        boost::filesystem::path config_file_path, input_path, profile_path;
        int requested_num_threads;

        // declare a group of options that will be allowed only on command line
        boost::program_options::options_description generic_options("Options");
        generic_options.add_options()
            ("version,v", "Show version")
            ("help,h", "Show this help message")
            ("config,c", boost::program_options::value<boost::filesystem::path>(&config_file_path)->default_value("extractor.ini"),
                  "Path to a configuration file.");

        // declare a group of options that will be allowed both on command line and in config file
        boost::program_options::options_description config_options("Configuration");
        config_options.add_options()
            ("profile,p", boost::program_options::value<boost::filesystem::path>(&profile_path)->default_value("profile.lua"),
                "Path to LUA routing profile")
            ("threads,t", boost::program_options::value<int>(&requested_num_threads)->default_value(8),
                "Number of threads to use");

        // hidden options, will be allowed both on command line and in config file, but will not be shown to the user
        boost::program_options::options_description hidden_options("Hidden options");
        hidden_options.add_options()
            ("input,i", boost::program_options::value<boost::filesystem::path>(&input_path),
                "Input file in .osm, .osm.bz2 or .osm.pbf format");

        // positional option
        boost::program_options::positional_options_description positional_options;
        positional_options.add("input", 1);

        // combine above options for parsing
        boost::program_options::options_description cmdline_options;
        cmdline_options.add(generic_options).add(config_options).add(hidden_options);

        boost::program_options::options_description config_file_options;
        config_file_options.add(config_options).add(hidden_options);

        boost::program_options::options_description visible_options(boost::filesystem::basename(argv[0]) + " <input.osm/.osm.bz2/.osm.pbf> [options]");
        visible_options.add(generic_options).add(config_options);

        // parse command line options
        boost::program_options::variables_map option_variables;
        boost::program_options::store(boost::program_options::command_line_parser(argc, argv).
            options(cmdline_options).positional(positional_options).run(), option_variables);

        if(option_variables.count("version")) {
            SimpleLogger().Write() << g_GIT_DESCRIPTION;
            return 0;
        }

        if(option_variables.count("help")) {
            SimpleLogger().Write() << visible_options;
            return 0;
        }

        boost::program_options::notify(option_variables);

        // parse config file
        if(boost::filesystem::is_regular_file(config_file_path)) {
            SimpleLogger().Write() << "Reading options from: " << config_file_path.c_str();
            std::string config_str;
            PrepareConfigFile( config_file_path.c_str(), config_str );
            std::stringstream config_stream( config_str );
            boost::program_options::store(parse_config_file(config_stream, config_file_options), option_variables);
            boost::program_options::notify(option_variables);
        }

        if(!option_variables.count("input")) {
            SimpleLogger().Write() << visible_options;
            return 0;
        }

        if(1 > requested_num_threads) {
            SimpleLogger().Write(logWARNING) << "Number of threads must be 1 or larger";
            return 1;
        }

        if(!boost::filesystem::is_regular_file(input_path)) {
            SimpleLogger().Write(logWARNING) << "Input file " << input_path.c_str() << " not found!";
            return 1;
        }

        if(!boost::filesystem::is_regular_file(profile_path)) {
            SimpleLogger().Write(logWARNING) << "Profile " << profile_path.c_str() << " not found!";
            return 1;
        }

        SimpleLogger().Write() << "Input file: " << input_path.filename().string();
        SimpleLogger().Write() << "Profile: " << profile_path.filename().string();
        SimpleLogger().Write() << "Threads: " << requested_num_threads;

        /*** Setup Scripting Environment ***/
        ScriptingEnvironment scriptingEnvironment(profile_path.c_str());

        omp_set_num_threads( std::min( omp_get_num_procs(), requested_num_threads) );

        bool file_has_pbf_format(false);
        std::string output_file_name(input_path.c_str());
        std::string restrictionsFileName(input_path.c_str());
        std::string::size_type pos = output_file_name.find(".osm.bz2");
        if(pos==std::string::npos) {
            pos = output_file_name.find(".osm.pbf");
            if(pos!=std::string::npos) {
                file_has_pbf_format = true;
            }
        }
        if(pos==std::string::npos) {
            pos = output_file_name.find(".pbf");
            if(pos!=std::string::npos) {
                file_has_pbf_format = true;
            }
        }
        if(pos!=std::string::npos) {
            output_file_name.replace(pos, 8, ".osrm");
            restrictionsFileName.replace(pos, 8, ".osrm.restrictions");
        } else {
            pos=output_file_name.find(".osm");
            if(pos!=std::string::npos) {
                output_file_name.replace(pos, 5, ".osrm");
                restrictionsFileName.replace(pos, 5, ".osrm.restrictions");
            } else {
                output_file_name.append(".osrm");
                restrictionsFileName.append(".osrm.restrictions");
            }
        }

        boost::unordered_map<std::string, NodeID> stringMap;
        ExtractionContainers externalMemory;

        stringMap[""] = 0;
        extractCallBacks = new ExtractorCallbacks(&externalMemory, &stringMap);
        BaseParser* parser;
        if(file_has_pbf_format) {
            parser = new PBFParser(input_path.c_str(), extractCallBacks, scriptingEnvironment);
        } else {
            parser = new XMLParser(input_path.c_str(), extractCallBacks, scriptingEnvironment);
        }

        if(!parser->ReadHeader()) {
            throw OSRMException("Parser not initialized!");
        }
        SimpleLogger().Write() << "Parsing in progress..";
        double parsing_start_time = get_timestamp();
        parser->Parse();
        SimpleLogger().Write() << "Parsing finished after " <<
            (get_timestamp() - parsing_start_time) <<
            " seconds";

        if( externalMemory.all_edges_list.empty() ) {
            SimpleLogger().Write(logWARNING) << "The input data is empty, exiting.";
            return 1;
        }

        externalMemory.PrepareData(output_file_name, restrictionsFileName);

        delete parser;
        delete extractCallBacks;

        SimpleLogger().Write() <<
            "extraction finished after " << get_timestamp() - startup_time <<
            "s";

         SimpleLogger().Write() << "To prepare the data for routing, run: "
            << "./osrm-prepare " << output_file_name << std::endl;

    } catch(boost::program_options::too_many_positional_options_error& e) {
        SimpleLogger().Write(logWARNING) << "Only one input file can be specified";
        return 1;
    } catch(boost::program_options::error& e) {
        SimpleLogger().Write(logWARNING) << e.what();
        return 1;
    } catch(std::exception & e) {
        SimpleLogger().Write(logWARNING) << "Exception occured: " << e.what();
        return 1;
    }
    return 0;
}
<commit_msg>fix inverted logic<commit_after>/*

Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

*/

#include "Extractor/ExtractorCallbacks.h"
#include "Extractor/ExtractionContainers.h"
#include "Extractor/ScriptingEnvironment.h"
#include "Extractor/PBFParser.h"
#include "Extractor/XMLParser.h"
#include "Util/GitDescription.h"
#include "Util/MachineInfo.h"
#include "Util/OpenMPWrapper.h"
#include "Util/OSRMException.h"
#include "Util/ProgramOptions.h"
#include "Util/SimpleLogger.h"
#include "Util/StringUtil.h"
#include "Util/TimingUtil.h"
#include "Util/UUID.h"
#include "typedefs.h"

#include <cstdlib>

#include <boost/unordered_map.hpp>

#include <iostream>
#include <fstream>
#include <string>

ExtractorCallbacks * extractCallBacks;
UUID uuid;

int main (int argc, char *argv[]) {
    try {
        LogPolicy::GetInstance().Unmute();
        double startup_time = get_timestamp();

        boost::filesystem::path config_file_path, input_path, profile_path;
        int requested_num_threads;

        // declare a group of options that will be allowed only on command line
        boost::program_options::options_description generic_options("Options");
        generic_options.add_options()
            ("version,v", "Show version")
            ("help,h", "Show this help message")
            ("config,c", boost::program_options::value<boost::filesystem::path>(&config_file_path)->default_value("extractor.ini"),
                  "Path to a configuration file.");

        // declare a group of options that will be allowed both on command line and in config file
        boost::program_options::options_description config_options("Configuration");
        config_options.add_options()
            ("profile,p", boost::program_options::value<boost::filesystem::path>(&profile_path)->default_value("profile.lua"),
                "Path to LUA routing profile")
            ("threads,t", boost::program_options::value<int>(&requested_num_threads)->default_value(8),
                "Number of threads to use");

        // hidden options, will be allowed both on command line and in config file, but will not be shown to the user
        boost::program_options::options_description hidden_options("Hidden options");
        hidden_options.add_options()
            ("input,i", boost::program_options::value<boost::filesystem::path>(&input_path),
                "Input file in .osm, .osm.bz2 or .osm.pbf format");

        // positional option
        boost::program_options::positional_options_description positional_options;
        positional_options.add("input", 1);

        // combine above options for parsing
        boost::program_options::options_description cmdline_options;
        cmdline_options.add(generic_options).add(config_options).add(hidden_options);

        boost::program_options::options_description config_file_options;
        config_file_options.add(config_options).add(hidden_options);

        boost::program_options::options_description visible_options(boost::filesystem::basename(argv[0]) + " <input.osm/.osm.bz2/.osm.pbf> [options]");
        visible_options.add(generic_options).add(config_options);

        // parse command line options
        boost::program_options::variables_map option_variables;
        boost::program_options::store(boost::program_options::command_line_parser(argc, argv).
            options(cmdline_options).positional(positional_options).run(), option_variables);

        if(option_variables.count("version")) {
            SimpleLogger().Write() << g_GIT_DESCRIPTION;
            return 0;
        }

        if(option_variables.count("help")) {
            SimpleLogger().Write() << visible_options;
            return 0;
        }

        boost::program_options::notify(option_variables);

        // parse config file
        if(boost::filesystem::is_regular_file(config_file_path)) {
            SimpleLogger().Write() << "Reading options from: " << config_file_path.c_str();
            std::string config_str;
            PrepareConfigFile( config_file_path.c_str(), config_str );
            std::stringstream config_stream( config_str );
            boost::program_options::store(parse_config_file(config_stream, config_file_options), option_variables);
            boost::program_options::notify(option_variables);
        }

        if(!option_variables.count("input")) {
            SimpleLogger().Write() << visible_options;
            return 0;
        }

        if(1 > requested_num_threads) {
            SimpleLogger().Write(logWARNING) << "Number of threads must be 1 or larger";
            return 1;
        }

        if(!boost::filesystem::is_regular_file(input_path)) {
            SimpleLogger().Write(logWARNING) << "Input file " << input_path.c_str() << " not found!";
            return 1;
        }

        if(!boost::filesystem::is_regular_file(profile_path)) {
            SimpleLogger().Write(logWARNING) << "Profile " << profile_path.c_str() << " not found!";
            return 1;
        }

        SimpleLogger().Write() << "Input file: " << input_path.filename().string();
        SimpleLogger().Write() << "Profile: " << profile_path.filename().string();
        SimpleLogger().Write() << "Threads: " << requested_num_threads;

        /*** Setup Scripting Environment ***/
        ScriptingEnvironment scriptingEnvironment(profile_path.c_str());

        omp_set_num_threads( std::min( omp_get_num_procs(), requested_num_threads) );

        bool file_has_pbf_format(false);
        std::string output_file_name(input_path.c_str());
        std::string restrictionsFileName(input_path.c_str());
        std::string::size_type pos = output_file_name.find(".osm.bz2");
        if(pos==std::string::npos) {
            pos = output_file_name.find(".osm.pbf");
            if(pos!=std::string::npos) {
                file_has_pbf_format = true;
            }
        }
        if (pos==std::string::npos)
        {
            pos = output_file_name.find(".pbf");
            if (pos!=std::string::npos)
            {
                file_has_pbf_format = true;
            }
        }
        if (pos == std::string::npos)
        {
            pos = output_file_name.find(".osm");
            if (pos == std::string::npos)
            {
                output_file_name.append(".osrm");
                restrictionsFileName.append(".osrm.restrictions");
            }
            else
            {
                output_file_name.replace(pos, 5, ".osrm");
                restrictionsFileName.replace(pos, 5, ".osrm.restrictions");
            }
        }
        else
        {
            output_file_name.replace(pos, 8, ".osrm");
            restrictionsFileName.replace(pos, 8, ".osrm.restrictions");
        }

        boost::unordered_map<std::string, NodeID> stringMap;
        ExtractionContainers externalMemory;

        stringMap[""] = 0;
        extractCallBacks = new ExtractorCallbacks(&externalMemory, &stringMap);
        BaseParser* parser;
        if(file_has_pbf_format) {
            parser = new PBFParser(input_path.c_str(), extractCallBacks, scriptingEnvironment);
        } else {
            parser = new XMLParser(input_path.c_str(), extractCallBacks, scriptingEnvironment);
        }

        if(!parser->ReadHeader()) {
            throw OSRMException("Parser not initialized!");
        }
        SimpleLogger().Write() << "Parsing in progress..";
        double parsing_start_time = get_timestamp();
        parser->Parse();
        SimpleLogger().Write() << "Parsing finished after " <<
            (get_timestamp() - parsing_start_time) <<
            " seconds";

        if( externalMemory.all_edges_list.empty() ) {
            SimpleLogger().Write(logWARNING) << "The input data is empty, exiting.";
            return 1;
        }

        externalMemory.PrepareData(output_file_name, restrictionsFileName);

        delete parser;
        delete extractCallBacks;

        SimpleLogger().Write() <<
            "extraction finished after " << get_timestamp() - startup_time <<
            "s";

         SimpleLogger().Write() << "To prepare the data for routing, run: "
            << "./osrm-prepare " << output_file_name << std::endl;

    } catch(boost::program_options::too_many_positional_options_error& e) {
        SimpleLogger().Write(logWARNING) << "Only one input file can be specified";
        return 1;
    } catch(boost::program_options::error& e) {
        SimpleLogger().Write(logWARNING) << e.what();
        return 1;
    } catch(std::exception & e) {
        SimpleLogger().Write(logWARNING) << "Exception occured: " << e.what();
        return 1;
    }
    return 0;
}
<|endoftext|>


<commit_before>#include "rosplan_planning_system/ProblemGeneration/PDDLProblemGenerator.h"

namespace KCL_rosplan {

	/**
	 * generates a PDDL problem file.
	 * This file is later read by the planner.
	 */
	void PDDLProblemGenerator::generatePDDLProblemFile(std::string &problemPath) {

		std::stringstream ss;

		ss << "/" << knowledge_base << "/domain/name";
		domain_name_service = ss.str();
		ss.str("");

		ss << "/" << knowledge_base << "/domain/types";
		domain_type_service = ss.str();
		ss.str("");

		ss << "/" << knowledge_base << "/domain/predicates";
		domain_predicate_service = ss.str();
		ss.str("");

		ss << "/" << knowledge_base << "/domain/functions";
		domain_function_service = ss.str();
		ss.str("");

		ss << "/" << knowledge_base << "/state/instances";
		state_instance_service = ss.str();
		ss.str("");

		ss << "/" << knowledge_base << "/state/propositions";
		state_proposition_service = ss.str();
		ss.str("");

		ss << "/" << knowledge_base << "/state/functions";
		state_function_service = ss.str();
		ss.str("");

		ss << "/" << knowledge_base << "/state/timed_knowledge";
		state_timed_knowledge_service = ss.str();
		ss.str("");

		ss << "/" << knowledge_base << "/state/goals";
		state_goal_service = ss.str();
		ss.str("");

		ss << "/" << knowledge_base << "/state/metric";
		state_metric_service = ss.str();
		ss.str("");

		std::ofstream pFile;
		pFile.open((problemPath).c_str());

		makeHeader(pFile);
		makeInitialState(pFile);
		makeGoals(pFile);
        makeMetric(pFile);

        // add end of problem file
        pFile << ")" << std::endl;
	}

	/*--------*/
	/* header */
	/*--------*/

	void PDDLProblemGenerator::makeHeader(std::ofstream &pFile) {

		// setup service calls
		ros::NodeHandle nh;

		ros::ServiceClient getNameClient = nh.serviceClient<rosplan_knowledge_msgs::GetDomainNameService>(domain_name_service);
		ros::ServiceClient getTypesClient = nh.serviceClient<rosplan_knowledge_msgs::GetDomainTypeService>(domain_type_service);
		ros::ServiceClient getInstancesClient = nh.serviceClient<rosplan_knowledge_msgs::GetInstanceService>(state_instance_service);

		// get domain name
		rosplan_knowledge_msgs::GetDomainNameService nameSrv;
		if (!getNameClient.call(nameSrv)) {
			ROS_ERROR("KCL: (PDDLProblemGenerator) Failed to call service %s", domain_name_service.c_str());
		}

		pFile << "(define (problem task)" << std::endl;
		pFile << "(:domain " << nameSrv.response.domain_name << ")" << std::endl;

		/* objects */
		pFile << "(:objects" << std::endl;

		// get types
		rosplan_knowledge_msgs::GetDomainTypeService typeSrv;
		if (!getTypesClient.call(typeSrv)) {
			ROS_ERROR("KCL: (PDDLProblemGenerator) Failed to call service %s", domain_type_service.c_str());
		}

		// get instances of each type
		for(size_t t=0; t<typeSrv.response.types.size(); t++) {

			rosplan_knowledge_msgs::GetInstanceService instanceSrv;
			instanceSrv.request.type_name = typeSrv.response.types[t];

			if (!getInstancesClient.call(instanceSrv)) {
				ROS_ERROR("KCL: (PDDLProblemGenerator) Failed to call service %s: %s", state_instance_service.c_str(), instanceSrv.request.type_name.c_str());
			} else {
				if(instanceSrv.response.instances.size() == 0) continue;
				pFile << "    ";
				for(size_t i=0;i<instanceSrv.response.instances.size();i++) {
					pFile << instanceSrv.response.instances[i] << " ";
				}
				pFile << "- " << typeSrv.response.types[t] << std::endl;
			}
		}

		pFile << ")" << std::endl;
	}

	/*---------------*/
	/* initial state */
	/*---------------*/

	void PDDLProblemGenerator::makeInitialState(std::ofstream &pFile) {

		ros::NodeHandle nh;
		ros::ServiceClient getDomainPropsClient = nh.serviceClient<rosplan_knowledge_msgs::GetDomainAttributeService>(domain_predicate_service);
		ros::ServiceClient getDomainFuncsClient = nh.serviceClient<rosplan_knowledge_msgs::GetDomainAttributeService>(domain_function_service);
		ros::ServiceClient getPropsClient = nh.serviceClient<rosplan_knowledge_msgs::GetAttributeService>(state_proposition_service);
		ros::ServiceClient getFuncsClient = nh.serviceClient<rosplan_knowledge_msgs::GetAttributeService>(state_function_service);
		ros::ServiceClient getTILsClient = nh.serviceClient<rosplan_knowledge_msgs::GetAttributeService>(state_timed_knowledge_service);

		// note the time now for TILs
		ros::Time time = ros::Time::now() + ros::Duration(1);

		pFile << "(:init" << std::endl;

		// get propositions
		rosplan_knowledge_msgs::GetDomainAttributeService domainAttrSrv;
		if (!getDomainPropsClient.call(domainAttrSrv)) {
			ROS_ERROR("KCL: (PDDLProblemGenerator) Failed to call service %s", domain_predicate_service.c_str());
		} else {

			std::vector<rosplan_knowledge_msgs::DomainFormula>::iterator ait = domainAttrSrv.response.items.begin();
			for(; ait != domainAttrSrv.response.items.end(); ait++) {

				rosplan_knowledge_msgs::GetAttributeService attrSrv;
				attrSrv.request.predicate_name = ait->name;
				if (!getPropsClient.call(attrSrv)) {
					ROS_ERROR("KCL: (PDDLProblemGenerator) Failed to call service %s: %s", state_proposition_service.c_str(), attrSrv.request.predicate_name.c_str());
				} else {
					if(attrSrv.response.attributes.size() == 0) continue;

					for(size_t i=0;i<attrSrv.response.attributes.size();i++) {

						rosplan_knowledge_msgs::KnowledgeItem attr = attrSrv.response.attributes[i];

						pFile << "    (";

						//Check if the attribute is negated
						if(attr.is_negative) pFile << "not (";

						pFile << attr.attribute_name;
						for(size_t j=0; j<attr.values.size(); j++) {
							pFile << " " << attr.values[j].value;
						}
						pFile << ")";

						if(attr.is_negative) pFile << ")";

						pFile << std::endl;
					}
				}
				pFile << std::endl;

				attrSrv.request.predicate_name = ait->name;
				attrSrv.response.attributes.clear();
				if (!getTILsClient.call(attrSrv)) {
					ROS_ERROR("KCL: (PDDLProblemGenerator) Failed to call service %s: %s", state_timed_knowledge_service.c_str(), attrSrv.request.predicate_name.c_str());
				} else {
					if(attrSrv.response.attributes.size() == 0) continue;

					for(size_t i=0;i<attrSrv.response.attributes.size();i++) {

						rosplan_knowledge_msgs::KnowledgeItem attr = attrSrv.response.attributes[i];

						pFile << "    (at " << (attr.initial_time - time).toSec() << " (";

						//Check if the attribute is negated
						if(attr.is_negative) pFile << "not (";

						pFile << attr.attribute_name;
						for(size_t j=0; j<attr.values.size(); j++) {
							pFile << " " << attr.values[j].value;
						}
						pFile << "))";

						if(attr.is_negative) pFile << ")";

						pFile << std::endl;
					}
				}
				pFile << std::endl;
			}
		}

		// get functions
		if (!getDomainFuncsClient.call(domainAttrSrv)) {
			ROS_ERROR("KCL: (PDDLProblemGenerator) Failed to call service %s", domain_function_service.c_str());
		} else {

			std::vector<rosplan_knowledge_msgs::DomainFormula>::iterator ait = domainAttrSrv.response.items.begin();
			for(; ait != domainAttrSrv.response.items.end(); ait++) {

				rosplan_knowledge_msgs::GetAttributeService attrSrv;
				attrSrv.request.predicate_name = ait->name;
				if (!getFuncsClient.call(attrSrv)) {
					ROS_ERROR("KCL: (PDDLProblemGenerator) Failed to call service %s: %s", state_function_service.c_str(), attrSrv.request.predicate_name.c_str());
				} else {
					if(attrSrv.response.attributes.size() == 0) continue;

					for(size_t i=0;i<attrSrv.response.attributes.size();i++) {

						rosplan_knowledge_msgs::KnowledgeItem attr = attrSrv.response.attributes[i];

						pFile << "    (";

						if(time < attr.initial_time) {
							pFile << "at " << (attr.initial_time - time).toSec() << " (";
						}

						pFile << "= (";

						pFile << attr.attribute_name;
						for(size_t j=0; j<attr.values.size(); j++) {
							pFile << " " << attr.values[j].value;
						}

						pFile << ") " << attr.function_value << ")";

						if(time < attr.initial_time) {
							pFile << ")";
						}

						pFile << std::endl;
					}
				}
				pFile << std::endl;
			}
		}

		pFile << ")" << std::endl;
	}

	/*------*/
	/* goal */
	/*------*/

	void PDDLProblemGenerator::makeGoals(std::ofstream &pFile) {

		ros::NodeHandle nh;
		ros::ServiceClient getCurrentGoalsClient = nh.serviceClient<rosplan_knowledge_msgs::GetAttributeService>(state_goal_service);

		pFile << "(:goal (and" << std::endl;

		// get current goals
		rosplan_knowledge_msgs::GetAttributeService currentGoalSrv;
		if (!getCurrentGoalsClient.call(currentGoalSrv)) {
			ROS_ERROR("KCL: (PDDLProblemGenerator) Failed to call service %s", state_goal_service.c_str());
		} else {

			for(size_t i=0;i<currentGoalSrv.response.attributes.size();i++) {
				rosplan_knowledge_msgs::KnowledgeItem attr = currentGoalSrv.response.attributes[i];
				if(attr.knowledge_type == rosplan_knowledge_msgs::KnowledgeItem::FACT) {
					pFile << "    (" + attr.attribute_name;
					for(size_t j=0; j<attr.values.size(); j++) {
						pFile << " " << attr.values[j].value;
					}
					pFile << ")" << std::endl;
				}
			}
		}
		pFile << "))" << std::endl;
	}

	/*--------*/
	/* metric */
	/*--------*/

	void PDDLProblemGenerator::makeMetric(std::ofstream &pFile) {

		ros::NodeHandle nh;

		// get current metric
		ros::ServiceClient getCurrentMetricClient = nh.serviceClient<rosplan_knowledge_msgs::GetMetricService>(state_metric_service);
		rosplan_knowledge_msgs::GetMetricService currentMetricSrv;
		if (!getCurrentMetricClient.call(currentMetricSrv)) {

			ROS_ERROR("KCL: (PDDLProblemGenerator) Failed to call service %s", state_metric_service.c_str());

		} else {

			rosplan_knowledge_msgs::KnowledgeItem metric = currentMetricSrv.response.metric;
            if (metric.knowledge_type == rosplan_knowledge_msgs::KnowledgeItem::EXPRESSION) {

				pFile << "(:metric " << metric.optimization;
				std::vector<int> operand_count;
				printExpression(pFile, metric.expr);

				pFile << ")" << std::endl;
            }
        }
	}

	void PDDLProblemGenerator::printExpression(std::ofstream &pFile, rosplan_knowledge_msgs::ExprComposite & e) {

		std::vector<rosplan_knowledge_msgs::ExprBase> tokens = e.tokens;
		bool second_operand = false;
		int depth = 0;
		for(int i=0; i<tokens.size(); i++) {
			rosplan_knowledge_msgs::ExprBase token = tokens[i];

			pFile << " ";

			switch(token.expr_type) {
			case rosplan_knowledge_msgs::ExprBase::OPERATOR:

				switch(token.op) {
					case rosplan_knowledge_msgs::ExprBase::ADD: pFile << "(+"; break;
					case rosplan_knowledge_msgs::ExprBase::SUB: pFile << "(-"; break;
					case rosplan_knowledge_msgs::ExprBase::MUL: pFile << "(*"; break;
					case rosplan_knowledge_msgs::ExprBase::DIV: pFile << "(/"; break;
				}
				second_operand = false;
				depth++;
				break;

			case rosplan_knowledge_msgs::ExprBase::CONSTANT:

				pFile << token.constant;
				break;

			case rosplan_knowledge_msgs::ExprBase::FUNCTION:

				pFile << "(" << token.function.name;
				for(size_t j=0; j<token.function.typed_parameters.size(); j++) {
					pFile << " " << token.function.typed_parameters[j].value;
				}
				pFile << ")";
				break;

			case rosplan_knowledge_msgs::ExprBase::SPECIAL:

				switch(token.special_type) {
					case rosplan_knowledge_msgs::ExprBase::HASHT:		pFile << "#t";			break;
					case rosplan_knowledge_msgs::ExprBase::TOTAL_TIME:	pFile << "total-time";	break;
					case rosplan_knowledge_msgs::ExprBase::DURATION:	pFile << "?duration";	break;
				}
				break;
			}

			if(second_operand && token.expr_type!=rosplan_knowledge_msgs::ExprBase::OPERATOR) {
				second_operand = true;
				pFile << ")";
				depth--;
			}

			if(token.expr_type!=rosplan_knowledge_msgs::ExprBase::OPERATOR) {
				second_operand = true;
			}
		}

		while(depth>0) {
			pFile << ")";
			depth--;
		}
	};
} // close namespace
<commit_msg>minor bugfix, added paranthesis in the total-time metric<commit_after>#include "rosplan_planning_system/ProblemGeneration/PDDLProblemGenerator.h"

namespace KCL_rosplan {

	/**
	 * generates a PDDL problem file.
	 * This file is later read by the planner.
	 */
	void PDDLProblemGenerator::generatePDDLProblemFile(std::string &problemPath) {

		std::stringstream ss;

		ss << "/" << knowledge_base << "/domain/name";
		domain_name_service = ss.str();
		ss.str("");

		ss << "/" << knowledge_base << "/domain/types";
		domain_type_service = ss.str();
		ss.str("");

		ss << "/" << knowledge_base << "/domain/predicates";
		domain_predicate_service = ss.str();
		ss.str("");

		ss << "/" << knowledge_base << "/domain/functions";
		domain_function_service = ss.str();
		ss.str("");

		ss << "/" << knowledge_base << "/state/instances";
		state_instance_service = ss.str();
		ss.str("");

		ss << "/" << knowledge_base << "/state/propositions";
		state_proposition_service = ss.str();
		ss.str("");

		ss << "/" << knowledge_base << "/state/functions";
		state_function_service = ss.str();
		ss.str("");

		ss << "/" << knowledge_base << "/state/timed_knowledge";
		state_timed_knowledge_service = ss.str();
		ss.str("");

		ss << "/" << knowledge_base << "/state/goals";
		state_goal_service = ss.str();
		ss.str("");

		ss << "/" << knowledge_base << "/state/metric";
		state_metric_service = ss.str();
		ss.str("");

		std::ofstream pFile;
		pFile.open((problemPath).c_str());

		makeHeader(pFile);
		makeInitialState(pFile);
		makeGoals(pFile);
        makeMetric(pFile);

        // add end of problem file
        pFile << ")" << std::endl;
	}

	/*--------*/
	/* header */
	/*--------*/

	void PDDLProblemGenerator::makeHeader(std::ofstream &pFile) {

		// setup service calls
		ros::NodeHandle nh;

		ros::ServiceClient getNameClient = nh.serviceClient<rosplan_knowledge_msgs::GetDomainNameService>(domain_name_service);
		ros::ServiceClient getTypesClient = nh.serviceClient<rosplan_knowledge_msgs::GetDomainTypeService>(domain_type_service);
		ros::ServiceClient getInstancesClient = nh.serviceClient<rosplan_knowledge_msgs::GetInstanceService>(state_instance_service);

		// get domain name
		rosplan_knowledge_msgs::GetDomainNameService nameSrv;
		if (!getNameClient.call(nameSrv)) {
			ROS_ERROR("KCL: (PDDLProblemGenerator) Failed to call service %s", domain_name_service.c_str());
		}

		pFile << "(define (problem task)" << std::endl;
		pFile << "(:domain " << nameSrv.response.domain_name << ")" << std::endl;

		/* objects */
		pFile << "(:objects" << std::endl;

		// get types
		rosplan_knowledge_msgs::GetDomainTypeService typeSrv;
		if (!getTypesClient.call(typeSrv)) {
			ROS_ERROR("KCL: (PDDLProblemGenerator) Failed to call service %s", domain_type_service.c_str());
		}

		// get instances of each type
		for(size_t t=0; t<typeSrv.response.types.size(); t++) {

			rosplan_knowledge_msgs::GetInstanceService instanceSrv;
			instanceSrv.request.type_name = typeSrv.response.types[t];

			if (!getInstancesClient.call(instanceSrv)) {
				ROS_ERROR("KCL: (PDDLProblemGenerator) Failed to call service %s: %s", state_instance_service.c_str(), instanceSrv.request.type_name.c_str());
			} else {
				if(instanceSrv.response.instances.size() == 0) continue;
				pFile << "    ";
				for(size_t i=0;i<instanceSrv.response.instances.size();i++) {
					pFile << instanceSrv.response.instances[i] << " ";
				}
				pFile << "- " << typeSrv.response.types[t] << std::endl;
			}
		}

		pFile << ")" << std::endl;
	}

	/*---------------*/
	/* initial state */
	/*---------------*/

	void PDDLProblemGenerator::makeInitialState(std::ofstream &pFile) {

		ros::NodeHandle nh;
		ros::ServiceClient getDomainPropsClient = nh.serviceClient<rosplan_knowledge_msgs::GetDomainAttributeService>(domain_predicate_service);
		ros::ServiceClient getDomainFuncsClient = nh.serviceClient<rosplan_knowledge_msgs::GetDomainAttributeService>(domain_function_service);
		ros::ServiceClient getPropsClient = nh.serviceClient<rosplan_knowledge_msgs::GetAttributeService>(state_proposition_service);
		ros::ServiceClient getFuncsClient = nh.serviceClient<rosplan_knowledge_msgs::GetAttributeService>(state_function_service);
		ros::ServiceClient getTILsClient = nh.serviceClient<rosplan_knowledge_msgs::GetAttributeService>(state_timed_knowledge_service);

		// note the time now for TILs
		ros::Time time = ros::Time::now() + ros::Duration(1);

		pFile << "(:init" << std::endl;

		// get propositions
		rosplan_knowledge_msgs::GetDomainAttributeService domainAttrSrv;
		if (!getDomainPropsClient.call(domainAttrSrv)) {
			ROS_ERROR("KCL: (PDDLProblemGenerator) Failed to call service %s", domain_predicate_service.c_str());
		} else {

			std::vector<rosplan_knowledge_msgs::DomainFormula>::iterator ait = domainAttrSrv.response.items.begin();
			for(; ait != domainAttrSrv.response.items.end(); ait++) {

				rosplan_knowledge_msgs::GetAttributeService attrSrv;
				attrSrv.request.predicate_name = ait->name;
				if (!getPropsClient.call(attrSrv)) {
					ROS_ERROR("KCL: (PDDLProblemGenerator) Failed to call service %s: %s", state_proposition_service.c_str(), attrSrv.request.predicate_name.c_str());
				} else {
					if(attrSrv.response.attributes.size() == 0) continue;

					for(size_t i=0;i<attrSrv.response.attributes.size();i++) {

						rosplan_knowledge_msgs::KnowledgeItem attr = attrSrv.response.attributes[i];

						pFile << "    (";

						//Check if the attribute is negated
						if(attr.is_negative) pFile << "not (";

						pFile << attr.attribute_name;
						for(size_t j=0; j<attr.values.size(); j++) {
							pFile << " " << attr.values[j].value;
						}
						pFile << ")";

						if(attr.is_negative) pFile << ")";

						pFile << std::endl;
					}
				}
				pFile << std::endl;

				attrSrv.request.predicate_name = ait->name;
				attrSrv.response.attributes.clear();
				if (!getTILsClient.call(attrSrv)) {
					ROS_ERROR("KCL: (PDDLProblemGenerator) Failed to call service %s: %s", state_timed_knowledge_service.c_str(), attrSrv.request.predicate_name.c_str());
				} else {
					if(attrSrv.response.attributes.size() == 0) continue;

					for(size_t i=0;i<attrSrv.response.attributes.size();i++) {

						rosplan_knowledge_msgs::KnowledgeItem attr = attrSrv.response.attributes[i];

						pFile << "    (at " << (attr.initial_time - time).toSec() << " (";

						//Check if the attribute is negated
						if(attr.is_negative) pFile << "not (";

						pFile << attr.attribute_name;
						for(size_t j=0; j<attr.values.size(); j++) {
							pFile << " " << attr.values[j].value;
						}
						pFile << "))";

						if(attr.is_negative) pFile << ")";

						pFile << std::endl;
					}
				}
				pFile << std::endl;
			}
		}

		// get functions
		if (!getDomainFuncsClient.call(domainAttrSrv)) {
			ROS_ERROR("KCL: (PDDLProblemGenerator) Failed to call service %s", domain_function_service.c_str());
		} else {

			std::vector<rosplan_knowledge_msgs::DomainFormula>::iterator ait = domainAttrSrv.response.items.begin();
			for(; ait != domainAttrSrv.response.items.end(); ait++) {

				rosplan_knowledge_msgs::GetAttributeService attrSrv;
				attrSrv.request.predicate_name = ait->name;
				if (!getFuncsClient.call(attrSrv)) {
					ROS_ERROR("KCL: (PDDLProblemGenerator) Failed to call service %s: %s", state_function_service.c_str(), attrSrv.request.predicate_name.c_str());
				} else {
					if(attrSrv.response.attributes.size() == 0) continue;

					for(size_t i=0;i<attrSrv.response.attributes.size();i++) {

						rosplan_knowledge_msgs::KnowledgeItem attr = attrSrv.response.attributes[i];

						pFile << "    (";

						if(time < attr.initial_time) {
							pFile << "at " << (attr.initial_time - time).toSec() << " (";
						}

						pFile << "= (";

						pFile << attr.attribute_name;
						for(size_t j=0; j<attr.values.size(); j++) {
							pFile << " " << attr.values[j].value;
						}

						pFile << ") " << attr.function_value << ")";

						if(time < attr.initial_time) {
							pFile << ")";
						}

						pFile << std::endl;
					}
				}
				pFile << std::endl;
			}
		}

		pFile << ")" << std::endl;
	}

	/*------*/
	/* goal */
	/*------*/

	void PDDLProblemGenerator::makeGoals(std::ofstream &pFile) {

		ros::NodeHandle nh;
		ros::ServiceClient getCurrentGoalsClient = nh.serviceClient<rosplan_knowledge_msgs::GetAttributeService>(state_goal_service);

		pFile << "(:goal (and" << std::endl;

		// get current goals
		rosplan_knowledge_msgs::GetAttributeService currentGoalSrv;
		if (!getCurrentGoalsClient.call(currentGoalSrv)) {
			ROS_ERROR("KCL: (PDDLProblemGenerator) Failed to call service %s", state_goal_service.c_str());
		} else {

			for(size_t i=0;i<currentGoalSrv.response.attributes.size();i++) {
				rosplan_knowledge_msgs::KnowledgeItem attr = currentGoalSrv.response.attributes[i];
				if(attr.knowledge_type == rosplan_knowledge_msgs::KnowledgeItem::FACT) {
					pFile << "    (" + attr.attribute_name;
					for(size_t j=0; j<attr.values.size(); j++) {
						pFile << " " << attr.values[j].value;
					}
					pFile << ")" << std::endl;
				}
			}
		}
		pFile << "))" << std::endl;
	}

	/*--------*/
	/* metric */
	/*--------*/

	void PDDLProblemGenerator::makeMetric(std::ofstream &pFile) {

		ros::NodeHandle nh;

		// get current metric
		ros::ServiceClient getCurrentMetricClient = nh.serviceClient<rosplan_knowledge_msgs::GetMetricService>(state_metric_service);
		rosplan_knowledge_msgs::GetMetricService currentMetricSrv;
		if (!getCurrentMetricClient.call(currentMetricSrv)) {

			ROS_ERROR("KCL: (PDDLProblemGenerator) Failed to call service %s", state_metric_service.c_str());

		} else {

			rosplan_knowledge_msgs::KnowledgeItem metric = currentMetricSrv.response.metric;
            if (metric.knowledge_type == rosplan_knowledge_msgs::KnowledgeItem::EXPRESSION) {

				pFile << "(:metric " << metric.optimization;
				std::vector<int> operand_count;
				printExpression(pFile, metric.expr);

				pFile << ")" << std::endl;
            }
        }
	}

	void PDDLProblemGenerator::printExpression(std::ofstream &pFile, rosplan_knowledge_msgs::ExprComposite & e) {

		std::vector<rosplan_knowledge_msgs::ExprBase> tokens = e.tokens;
		bool second_operand = false;
		int depth = 0;
		for(int i=0; i<tokens.size(); i++) {
			rosplan_knowledge_msgs::ExprBase token = tokens[i];

			pFile << " ";

			switch(token.expr_type) {
			case rosplan_knowledge_msgs::ExprBase::OPERATOR:

				switch(token.op) {
					case rosplan_knowledge_msgs::ExprBase::ADD: pFile << "(+"; break;
					case rosplan_knowledge_msgs::ExprBase::SUB: pFile << "(-"; break;
					case rosplan_knowledge_msgs::ExprBase::MUL: pFile << "(*"; break;
					case rosplan_knowledge_msgs::ExprBase::DIV: pFile << "(/"; break;
				}
				second_operand = false;
				depth++;
				break;

			case rosplan_knowledge_msgs::ExprBase::CONSTANT:

				pFile << token.constant;
				break;

			case rosplan_knowledge_msgs::ExprBase::FUNCTION:

				pFile << "(" << token.function.name;
				for(size_t j=0; j<token.function.typed_parameters.size(); j++) {
					pFile << " " << token.function.typed_parameters[j].value;
				}
				pFile << ")";
				break;

			case rosplan_knowledge_msgs::ExprBase::SPECIAL:

				switch(token.special_type) {
					case rosplan_knowledge_msgs::ExprBase::HASHT:		pFile << "#t";			break;
					case rosplan_knowledge_msgs::ExprBase::TOTAL_TIME:	pFile << "(total-time)";	break;
					case rosplan_knowledge_msgs::ExprBase::DURATION:	pFile << "?duration";	break;
				}
				break;
			}

			if(second_operand && token.expr_type!=rosplan_knowledge_msgs::ExprBase::OPERATOR) {
				second_operand = true;
				pFile << ")";
				depth--;
			}

			if(token.expr_type!=rosplan_knowledge_msgs::ExprBase::OPERATOR) {
				second_operand = true;
			}
		}

		while(depth>0) {
			pFile << ")";
			depth--;
		}
	};
} // close namespace
<|endoftext|>


<commit_before>// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#include <vespa/fastos/fastos.h>
#include <vespa/log/log.h>
LOG_SETUP(".searchcorespi.index.index_manager_explorer");
#include "index_manager_explorer.h"
#include "index_manager_stats.h"

#include <vespa/vespalib/data/slime/cursor.h>

using vespalib::slime::Cursor;
using vespalib::slime::Inserter;
using search::SearchableStats;

namespace searchcorespi {

IndexManagerExplorer::IndexManagerExplorer(IIndexManager::SP mgr)
    : _mgr(std::move(mgr))
{
}

void
IndexManagerExplorer::get_state(const Inserter &inserter, bool full) const
{
    Cursor &object = inserter.insertObject();
    object.setLong("lastSerialNum", _mgr->getCurrentSerialNum());
    if (full) {
        IndexManagerStats stats(*_mgr);
        Cursor &diskIndexArrayCursor = object.setArray("diskIndexes");
        for (const auto &diskIndex : stats.getDiskIndexes()) {
            Cursor &diskIndexCursor = diskIndexArrayCursor.addObject();
            const SearchableStats &sstats = diskIndex.getSearchableStats();
            diskIndexCursor.setLong("serialNum", diskIndex.getSerialNum());
            diskIndexCursor.setString("indexDir", diskIndex.getIndexdir());
            diskIndexCursor.setLong("sizeOnDisk", sstats.sizeOnDisk());
        }
        Cursor &memoryIndexArrayCursor = object.setArray("memoryIndexes");
        for (const auto &memoryIndex : stats.getMemoryIndexes()) {
            Cursor &memoryIndexCursor = memoryIndexArrayCursor.addObject();
            const SearchableStats &sstats = memoryIndex.getSearchableStats();
            memoryIndexCursor.setLong("serialNum", memoryIndex.getSerialNum());
            memoryIndexCursor.setLong("docsInMemory", sstats.docsInMemory());
            memoryIndexCursor.setLong("memoryUsage", sstats.memoryUsage());
        }
    }
}

} // namespace searchcorespi
<commit_msg>Factor out portions of get_state() to helper functions.<commit_after>// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#include <vespa/fastos/fastos.h>
#include <vespa/log/log.h>
LOG_SETUP(".searchcorespi.index.index_manager_explorer");
#include "index_manager_explorer.h"
#include "index_manager_stats.h"

#include <vespa/vespalib/data/slime/cursor.h>

using vespalib::slime::Cursor;
using vespalib::slime::Inserter;
using search::SearchableStats;
using searchcorespi::index::DiskIndexStats;
using searchcorespi::index::MemoryIndexStats;

namespace searchcorespi {

namespace {

void insertDiskIndex(Cursor &arrayCursor, const DiskIndexStats &diskIndex)
{
    Cursor &diskIndexCursor = arrayCursor.addObject();
    const SearchableStats &sstats = diskIndex.getSearchableStats();
    diskIndexCursor.setLong("serialNum", diskIndex.getSerialNum());
    diskIndexCursor.setString("indexDir", diskIndex.getIndexdir());
    diskIndexCursor.setLong("sizeOnDisk", sstats.sizeOnDisk());
}

void insertMemoryIndex(Cursor &arrayCursor, const MemoryIndexStats &memoryIndex)
{
    Cursor &memoryIndexCursor = arrayCursor.addObject();
    const SearchableStats &sstats = memoryIndex.getSearchableStats();
    memoryIndexCursor.setLong("serialNum", memoryIndex.getSerialNum());
    memoryIndexCursor.setLong("docsInMemory", sstats.docsInMemory());
    memoryIndexCursor.setLong("memoryUsage", sstats.memoryUsage());
}

}

IndexManagerExplorer::IndexManagerExplorer(IIndexManager::SP mgr)
    : _mgr(std::move(mgr))
{
}

void
IndexManagerExplorer::get_state(const Inserter &inserter, bool full) const
{
    Cursor &object = inserter.insertObject();
    object.setLong("lastSerialNum", _mgr->getCurrentSerialNum());
    if (full) {
        IndexManagerStats stats(*_mgr);
        Cursor &diskIndexArrayCursor = object.setArray("diskIndexes");
        for (const auto &diskIndex : stats.getDiskIndexes()) {
            insertDiskIndex(diskIndexArrayCursor, diskIndex);
        }
        Cursor &memoryIndexArrayCursor = object.setArray("memoryIndexes");
        for (const auto &memoryIndex : stats.getMemoryIndexes()) {
            insertMemoryIndex(memoryIndexArrayCursor, memoryIndex);
        }
    }
}

} // namespace searchcorespi
<|endoftext|>


<commit_before>// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#include "docsumfieldwriter.h"
#include "idocsumenvironment.h"
#include "docsumstate.h"
#include <vespa/searchlib/common/documentlocations.h>
#include <vespa/searchlib/common/location.h>
#include <vespa/searchlib/parsequery/stackdumpiterator.h>

#include <vespa/log/log.h>
LOG_SETUP(".searchlib.docsummary.docsumfieldwriter");

namespace search::docsummary {

using search::attribute::IAttributeContext;
using search::attribute::IAttributeVector;
using search::attribute::BasicType;
using search::common::Location;

//--------------------------------------------------------------------------

const vespalib::string IDocsumFieldWriter::_empty("");

bool
IDocsumFieldWriter::setFieldWriterStateIndex(uint32_t)
{
    return false; // Don't need any field writer state by default
}

//--------------------------------------------------------------------------

EmptyDFW::EmptyDFW() = default;

EmptyDFW::~EmptyDFW() = default;

void
EmptyDFW::insertField(uint32_t, GetDocsumsState *, ResType, vespalib::slime::Inserter &target)
{
    // insert explicitly-empty field?
    // target.insertNix();
    (void)target;
}

//--------------------------------------------------------------------------

CopyDFW::CopyDFW()
    : _inputFieldEnumValue(static_cast<uint32_t>(-1))
{
}

CopyDFW::~CopyDFW() = default;

bool
CopyDFW::Init(const ResultConfig & config, const char *inputField)
{
    _inputFieldEnumValue = config.GetFieldNameEnum().Lookup(inputField);

    if (_inputFieldEnumValue >= config.GetFieldNameEnum().GetNumEntries()) {
        LOG(warning, "no docsum format contains field '%s'; copied fields will be empty", inputField);
    }

    for (const auto & field : config) {
        const ResConfigEntry *entry = field.GetEntry(field.GetIndexFromEnumValue(_inputFieldEnumValue));

        if (entry != nullptr &&
            !IsRuntimeCompatible(entry->_type, RES_INT) &&
            !IsRuntimeCompatible(entry->_type, RES_DOUBLE) &&
            !IsRuntimeCompatible(entry->_type, RES_INT64) &&
            !IsRuntimeCompatible(entry->_type, RES_STRING) &&
            !IsRuntimeCompatible(entry->_type, RES_DATA)) {

            LOG(warning, "cannot use docsum field '%s' as input to copy; type conflict with result class %d (%s)",
                inputField, field.GetClassID(), field.GetClassName());
            return false;
        }
    }
    return true;
}

void
CopyDFW::insertField(uint32_t /*docid*/, GeneralResult *gres, GetDocsumsState *, ResType type,
                     vespalib::slime::Inserter &target)
{
    int idx = gres->GetClass()->GetIndexFromEnumValue(_inputFieldEnumValue);
    ResEntry *entry = gres->GetEntry(idx);

    if (entry != nullptr &&
        IsRuntimeCompatible(entry->_type, type))
    {
        switch (type) {
        case RES_INT: {
            uint32_t val32 = entry->_intval;
            target.insertLong(val32);
            break; }

        case RES_SHORT: {
            uint16_t val16 = entry->_intval;
            target.insertLong(val16);
            break; }

        case RES_BYTE: {
            uint8_t val8 = entry->_intval;
            target.insertLong(val8);
            break; }
        case RES_BOOL: {
            target.insertBool(entry->_intval != 0);
            break; }

        case RES_FLOAT: {
            float valfloat = entry->_doubleval;
            target.insertDouble(valfloat);
            break; }

        case RES_DOUBLE: {
            double valdouble = entry->_doubleval;
            target.insertDouble(valdouble);
            break; }

        case RES_INT64: {
            uint64_t valint64 = entry->_int64val;
            target.insertLong(valint64);
            break; }

        case RES_JSONSTRING:
        case RES_FEATUREDATA:
        case RES_LONG_STRING:
        case RES_STRING: {
            uint32_t    len;
            const char *spt;
            // resolve field
            entry->_resolve_field(&spt, &len);
            vespalib::Memory value(spt, len);
            target.insertString(value);
            break; }

        case RES_TENSOR:
        case RES_LONG_DATA:
        case RES_DATA: {
            uint32_t    len;
            const char *dpt;
            // resolve field
            entry->_resolve_field(&dpt, &len);
            vespalib::Memory value(dpt, len);
            target.insertData(value);
            break; }
        }
    }
}

}
<commit_msg>Handle struct field in CopyDFW.<commit_after>// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#include "docsumfieldwriter.h"
#include "idocsumenvironment.h"
#include "docsumstate.h"
#include <vespa/searchlib/common/documentlocations.h>
#include <vespa/searchlib/common/location.h>
#include <vespa/searchlib/parsequery/stackdumpiterator.h>
#include <vespa/vespalib/data/slime/slime.h>

#include <vespa/log/log.h>
LOG_SETUP(".searchlib.docsummary.docsumfieldwriter");

namespace search::docsummary {

using search::attribute::IAttributeContext;
using search::attribute::IAttributeVector;
using search::attribute::BasicType;
using search::common::Location;

//--------------------------------------------------------------------------

const vespalib::string IDocsumFieldWriter::_empty("");

bool
IDocsumFieldWriter::setFieldWriterStateIndex(uint32_t)
{
    return false; // Don't need any field writer state by default
}

//--------------------------------------------------------------------------

EmptyDFW::EmptyDFW() = default;

EmptyDFW::~EmptyDFW() = default;

void
EmptyDFW::insertField(uint32_t, GetDocsumsState *, ResType, vespalib::slime::Inserter &target)
{
    // insert explicitly-empty field?
    // target.insertNix();
    (void)target;
}

//--------------------------------------------------------------------------

CopyDFW::CopyDFW()
    : _inputFieldEnumValue(static_cast<uint32_t>(-1))
{
}

CopyDFW::~CopyDFW() = default;

bool
CopyDFW::Init(const ResultConfig & config, const char *inputField)
{
    _inputFieldEnumValue = config.GetFieldNameEnum().Lookup(inputField);

    if (_inputFieldEnumValue >= config.GetFieldNameEnum().GetNumEntries()) {
        LOG(warning, "no docsum format contains field '%s'; copied fields will be empty", inputField);
    }

    for (const auto & field : config) {
        const ResConfigEntry *entry = field.GetEntry(field.GetIndexFromEnumValue(_inputFieldEnumValue));

        if (entry != nullptr &&
            !IsRuntimeCompatible(entry->_type, RES_INT) &&
            !IsRuntimeCompatible(entry->_type, RES_DOUBLE) &&
            !IsRuntimeCompatible(entry->_type, RES_INT64) &&
            !IsRuntimeCompatible(entry->_type, RES_STRING) &&
            !IsRuntimeCompatible(entry->_type, RES_DATA)) {

            LOG(warning, "cannot use docsum field '%s' as input to copy; type conflict with result class %d (%s)",
                inputField, field.GetClassID(), field.GetClassName());
            return false;
        }
    }
    return true;
}

void
CopyDFW::insertField(uint32_t /*docid*/, GeneralResult *gres, GetDocsumsState *, ResType type,
                     vespalib::slime::Inserter &target)
{
    int idx = gres->GetClass()->GetIndexFromEnumValue(_inputFieldEnumValue);
    ResEntry *entry = gres->GetEntry(idx);

    if (entry != nullptr &&
        IsRuntimeCompatible(entry->_type, type))
    {
        switch (type) {
        case RES_INT: {
            uint32_t val32 = entry->_intval;
            target.insertLong(val32);
            break; }

        case RES_SHORT: {
            uint16_t val16 = entry->_intval;
            target.insertLong(val16);
            break; }

        case RES_BYTE: {
            uint8_t val8 = entry->_intval;
            target.insertLong(val8);
            break; }
        case RES_BOOL: {
            target.insertBool(entry->_intval != 0);
            break; }

        case RES_FLOAT: {
            float valfloat = entry->_doubleval;
            target.insertDouble(valfloat);
            break; }

        case RES_DOUBLE: {
            double valdouble = entry->_doubleval;
            target.insertDouble(valdouble);
            break; }

        case RES_INT64: {
            uint64_t valint64 = entry->_int64val;
            target.insertLong(valint64);
            break; }

        case RES_JSONSTRING: {
            uint32_t    len;
            const char *spt;
            // resolve field
            entry->_resolve_field(&spt, &len);
            if (len != 0) {
                // note: 'JSONSTRING' really means 'structured data'
                vespalib::Slime input_field_as_slime;
                size_t d = vespalib::slime::BinaryFormat::decode(vespalib::Memory(spt, len), input_field_as_slime);
                if (d != len) {
                    LOG(warning, "could not decode %u bytes: %zu bytes decoded", len, d);
                }
                if (d != 0) {
                    inject(input_field_as_slime.get(), target);
                }
            }
            break; }
        case RES_FEATUREDATA:
        case RES_LONG_STRING:
        case RES_STRING: {
            uint32_t    len;
            const char *spt;
            // resolve field
            entry->_resolve_field(&spt, &len);
            vespalib::Memory value(spt, len);
            target.insertString(value);
            break; }

        case RES_TENSOR:
        case RES_LONG_DATA:
        case RES_DATA: {
            uint32_t    len;
            const char *dpt;
            // resolve field
            entry->_resolve_field(&dpt, &len);
            vespalib::Memory value(dpt, len);
            target.insertData(value);
            break; }
        }
    }
}

}
<|endoftext|>


<commit_before>/*!
  \copyright (c) RDO-Team, 2003-2012
  \file      app/rdo_studio_mfc/src/chart/document.cpp
  \author
  \date      20.02.2003
  \brief
  \indent    4T
*/

// ---------------------------------------------------------------------------- PCH
#include "app/rdo_studio_mfc/pch/stdpch.h"
// ----------------------------------------------------------------------- INCLUDES
// ----------------------------------------------------------------------- SYNOPSIS
#include "app/rdo_studio_mfc/src/chart/document.h"
#include "app/rdo_studio_mfc/src/chart/view.h"
#include "app/rdo_studio_mfc/rdo_tracer/rdotracer.h"
#include "app/rdo_studio_mfc/rdo_tracer/rdotracerserie.h"
#include "app/rdo_studio_mfc/rdo_tracer/rdotracervalues.h"
#include "app/rdo_studio_mfc/src/application.h"
#include "app/rdo_studio_mfc/src/main_frm.h"
// --------------------------------------------------------------------------------

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

// --------------------------------------------------------------------------------
// -------------------- RDOStudioChartDocInsertTime
// --------------------------------------------------------------------------------
class RDOStudioChartDocInsertTime
{
	RDOStudioChartDoc* doc;
public:
	RDOStudioChartDocInsertTime( RDOStudioChartDoc* _doc ): doc( _doc ) {};
	void operator ()( RDOTracerValue* val );
};

void RDOStudioChartDocInsertTime::operator ()( RDOTracerValue* val )
{
	if( val ) {
		timesList::iterator it = std::find_if( doc->inserted_it, doc->docTimes.end(), std::bind2nd( std::mem_fun1( &RDOTracerTimeNow::compareTimes ), val->modeltime ) );
		if ( it == doc->docTimes.end() || (*it) != val->modeltime ) {
			doc->inserted_it = doc->docTimes.insert( it, val->modeltime );
			doc->ticksCount += val->modeltime->eventCount;
			double offl = 1.7E+308;
			double offr = 1.7E+308;
			if ( it != doc->docTimes.end() )
				offr = (*it)->time - (*doc->inserted_it)->time;
			if ( doc->inserted_it != doc->docTimes.begin() ) {
				offl = (*doc->inserted_it)->time;
				timesList::iterator prev_it = doc->inserted_it;
				prev_it --;
				offl -= (*prev_it)->time;
			}
			double minoff = min( offl, offr );
			if ( minoff < doc->minTimeOffset )
				doc->minTimeOffset = minoff;
		}
	}
	//studioApp.m_pMainFrame->stepProgress();
}

// --------------------------------------------------------------------------------
// -------------------- RDOStudioChartDoc
// --------------------------------------------------------------------------------
IMPLEMENT_DYNCREATE(RDOStudioChartDoc, CDocument)

BEGIN_MESSAGE_MAP(RDOStudioChartDoc, CDocument)
END_MESSAGE_MAP()

RDOStudioChartDoc::RDOStudioChartDoc( const rbool preview )
	: CDocument(),
	minTimeOffset( 1.7E+308 ),
	ticksCount( 0 ),
	previewMode( preview )
{
	if ( !previewMode )
		tracer->addChart( this );
}

RDOStudioChartDoc::~RDOStudioChartDoc()
{
	tracer->lock();

	mutex.Lock();

	for ( std::vector< RDOStudioDocSerie* >::iterator it = series.begin(); it != series.end(); it++ ) {
		(*it)->serie->removeFromDoc( this );
		delete (*it);
	}
	if ( !previewMode )
		tracer->removeChart( this );

	mutex.Unlock();

	tracer->unlock();
}

int RDOStudioChartDoc::getSerieIndex( RDOStudioDocSerie* serie ) const
{
	int res = -1;
	int index = 0;
	for ( std::vector< RDOStudioDocSerie* >::const_iterator it = series.begin(); it != series.end(); it++ ) {
		if ( serie == (*it) )
			res = index;
		index ++;
	}
	return res;
}

BOOL RDOStudioChartDoc::OnNewDocument()
{
	if ( !CDocument::OnNewDocument() ) return FALSE;
	return TRUE;
}

void RDOStudioChartDoc::Serialize(CArchive& ar)
{
	if ( ar.IsStoring() ) {
	}
	else {
	}
}

void RDOStudioChartDoc::incTimeEventsCount( RDOTracerTimeNow* time )
{
	//mutex.Lock(); Document is locked from RDOTracerBase::addTime

	if ( docTimes.back() == time ) {
		ticksCount ++;
		updateChartViews( UPDATE_TIMETICKS );
	}

	//mutex.Unlock();
}

rbool RDOStudioChartDoc::newValueToSerieAdded( RDOTracerValue* val )
{
	//mutex.Lock(); Document is locked from RDOTracerSerie::addValue

	if ( docTimes.empty() ) {
		docTimes.push_back( val->modeltime );
		ticksCount += val->modeltime->eventCount;
	} else {
		RDOTracerTimeNow* last = docTimes.back();
		if ( last != val->modeltime ) {
			docTimes.push_back( val->modeltime );
			ticksCount += val->modeltime->eventCount;
			double off = val->modeltime->time - last->time;
			if ( off < minTimeOffset )
				minTimeOffset = off;
		}
	}
	updateChartViews( UPDATE_NEWVALUE );

	//mutex.Unlock();

	return true;
}

int RDOStudioChartDoc::getMaxMarkerSize() const
{
	const_cast<CMutex&>(mutex).Lock();

	int res = 0;
	for ( std::vector< RDOStudioDocSerie* >::const_iterator it = series.begin(); it != series.end(); it++ ) {
		if ( (*it)->needDrawMarker && (*it)->marker_size > res ) res = (*it)->marker_size;
	}

	const_cast<CMutex&>(mutex).Unlock();

	return res;
}

void RDOStudioChartDoc::addToViews( const HWND handle )
{
	mutex.Lock();

	views_hwnd.push_back( handle );

	mutex.Unlock();
}

void RDOStudioChartDoc::removeFromViews( const HWND handle )
{
	mutex.Lock();

	std::vector< HWND >::iterator it = std::find( views_hwnd.begin(), views_hwnd.end(), handle );
	if ( it != views_hwnd.end() )
		views_hwnd.erase( it );

	mutex.Unlock();
}

void RDOStudioChartDoc::updateChartViews( const UINT update_type ) const
{
	const_cast<CMutex&>(mutex).Lock();

	for( std::vector< HWND >::const_iterator it = views_hwnd.begin(); it != views_hwnd.end(); it++ ) {
		::SendNotifyMessage( (*it), WM_USER_UPDATE_CHART_VIEW, WPARAM( update_type ), 0 );
	}

	const_cast<CMutex&>(mutex).Unlock();
}

void RDOStudioChartDoc::addSerie( RDOTracerSerie* const serie )
{
	mutex.Lock();

	if ( serie && !serieExists( serie ) ) {
		RDOStudioDocSerie* docserie = new RDOStudioDocSerie( serie );
		docserie->lock();
		docserie->color = selectColor();
		docserie->marker = selectMarker();
		series.push_back( docserie );
		inserted_it = docTimes.begin();

		if ( !docTimes.empty() && !serie->empty() ) {
			timesList::iterator last_doc = docTimes.end();
			last_doc --;
			valuesList::const_iterator first_serie = serie->begin();
			if ( (*first_serie)->modeltime->time >= (*last_doc)->time ) {
				inserted_it = docTimes.end();
				if ( (*first_serie)->modeltime->time == (*last_doc)->time ) {
					inserted_it = last_doc;
				}
			}
		}

		try {
			studioApp.BeginWaitCursor();

			//int count;
			//serie->getValueCount( count );
			//studioApp.m_pMainFrame->beginProgress( 0, count );

			std::for_each( serie->begin(), serie->end(), RDOStudioChartDocInsertTime( this ) );

			//studioApp.m_pMainFrame->endProgress();
			studioApp.EndWaitCursor();
		} catch( ... ) {
			studioApp.EndWaitCursor();
		}

		serie->addToDoc( this );
		if ( series.size() == 1 ) {
			POSITION pos = GetFirstViewPosition();
			while (pos != NULL) {
				CView* pView = GetNextView( pos );
				if ( pView && pView->IsKindOf( RUNTIME_CLASS(RDOStudioChartView) ) )
					static_cast<RDOStudioChartView*>( pView )->yAxis = docserie;
			}
		}
		docserie->unlock();
		updateChartViews( UPDATE_NEWSERIE );
	}

	mutex.Unlock();
}

/*void RDOStudioChartDoc::removeSerie( RDOTracerSerie* const serie )
{
	if ( !serie ) return;
	vector<RDOStudioDocSerie*>::iterator it = find_if( series.begin(), series.end(), bind2nd( mem_fun1(&RDOStudioDocSerie::isTracerSerie), serie ) );
	if ( it != series.end() ) {
		(*it)->serie->removeFromDoc( this );
		//must be recalc of minTimeOffset && tickscount
		delete (*it);
		series.erase( it );
		updateChartViews();
	}
}*/

COLORREF RDOStudioChartDoc::selectColor()
{
	int count = series.size();
	int mul = count / 15;
	int index = count - mul * 16;
	COLORREF res = RGB( 0, 0, 0 );
	switch ( index ) {
		case 0  : res = RGB( 0x00, 0x80, 0x00 ); break;
		case 1  : res = RGB( 0x00, 0x00, 0x80 ); break;
		case 2  : res = RGB( 0x80, 0x80, 0x80 ); break;
		case 3  : res = RGB( 0x80, 0x00, 0x80 ); break;
		case 4  : res = RGB( 0xFF, 0x00, 0x00 ); break;
		case 5  : res = RGB( 0x00, 0xFF, 0x00 ); break;
		case 6  : res = RGB( 0x00, 0x00, 0x00 ); break;
		case 7  : res = RGB( 0x80, 0x80, 0x00 ); break;
		case 8  : res = RGB( 0xC0, 0xC0, 0xC0 ); break;
		case 9  : res = RGB( 0x80, 0x00, 0x00 ); break;
		case 10 : res = RGB( 0x00, 0x80, 0x80 ); break;
		case 11 : res = RGB( 0xFF, 0xFF, 0x00 ); break;
		case 12 : res = RGB( 0x00, 0x00, 0xFF ); break;
		case 13 : res = RGB( 0xFF, 0x00, 0xFF ); break;
		case 14 : res = RGB( 0x00, 0xFF, 0xFF ); break;
	};
	return res;
}

RDOTracerSerieMarker RDOStudioChartDoc::selectMarker()
{
	int count = series.size();
	int mul = count / 4;
	int index = count - mul * 4;
	RDOTracerSerieMarker res = RDOSM_CIRCLE;
	switch ( index ) {
		case 0  : res = RDOSM_CIRCLE; break;
		case 1  : res = RDOSM_SQUARE; break;
		case 2  : res = RDOSM_RHOMB; break;
		case 3  : res = RDOSM_CROSS; break;
	};
	return res;
}

rbool RDOStudioChartDoc::serieExists( const RDOTracerSerie* serie ) const
{
	const_cast<CMutex&>(mutex).Lock();

	rbool res = std::find_if( series.begin(), series.end(), std::bind2nd( std::mem_fun1(&RDOStudioDocSerie::isTracerSerie), serie ) ) != series.end();

	const_cast<CMutex&>(mutex).Unlock();

	return res;
}

void RDOStudioChartDoc::SetTitle( LPCTSTR lpszTitle )
{
	title = lpszTitle;
	CDocument::SetTitle( rdo::format( IDS_CHART_TITLE, title.c_str() ).c_str() );
}

#ifdef _DEBUG
void RDOStudioChartDoc::AssertValid() const
{
	CDocument::AssertValid();
}

void RDOStudioChartDoc::Dump(CDumpContext& dc) const
{
	CDocument::Dump(dc);
}
#endif //_DEBUG<commit_msg> - исправлено падение при построении графика по нетрассируемой переменной<commit_after>/*!
  \copyright (c) RDO-Team, 2003-2012
  \file      app/rdo_studio_mfc/src/chart/document.cpp
  \author
  \date      20.02.2003
  \brief
  \indent    4T
*/

// ---------------------------------------------------------------------------- PCH
#include "app/rdo_studio_mfc/pch/stdpch.h"
// ----------------------------------------------------------------------- INCLUDES
// ----------------------------------------------------------------------- SYNOPSIS
#include "app/rdo_studio_mfc/src/chart/document.h"
#include "app/rdo_studio_mfc/src/chart/view.h"
#include "app/rdo_studio_mfc/rdo_tracer/rdotracer.h"
#include "app/rdo_studio_mfc/rdo_tracer/rdotracerserie.h"
#include "app/rdo_studio_mfc/rdo_tracer/rdotracervalues.h"
#include "app/rdo_studio_mfc/src/application.h"
#include "app/rdo_studio_mfc/src/main_frm.h"
// --------------------------------------------------------------------------------

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

// --------------------------------------------------------------------------------
// -------------------- RDOStudioChartDocInsertTime
// --------------------------------------------------------------------------------
class RDOStudioChartDocInsertTime
{
	RDOStudioChartDoc* doc;
public:
	RDOStudioChartDocInsertTime( RDOStudioChartDoc* _doc ): doc( _doc ) {};
	void operator ()( RDOTracerValue* val );
};

void RDOStudioChartDocInsertTime::operator ()( RDOTracerValue* val )
{
	if( val ) {
		timesList::iterator it = std::find_if( doc->inserted_it, doc->docTimes.end(), std::bind2nd( std::mem_fun1( &RDOTracerTimeNow::compareTimes ), val->modeltime ) );
		if ( it == doc->docTimes.end() || (*it) != val->modeltime ) {
			doc->inserted_it = doc->docTimes.insert( it, val->modeltime );
			doc->ticksCount += val->modeltime->eventCount;
			double offl = 1.7E+308;
			double offr = 1.7E+308;
			if ( it != doc->docTimes.end() )
				offr = (*it)->time - (*doc->inserted_it)->time;
			if ( doc->inserted_it != doc->docTimes.begin() ) {
				offl = (*doc->inserted_it)->time;
				timesList::iterator prev_it = doc->inserted_it;
				prev_it --;
				offl -= (*prev_it)->time;
			}
			double minoff = min( offl, offr );
			if ( minoff < doc->minTimeOffset )
				doc->minTimeOffset = minoff;
		}
	}
	//studioApp.m_pMainFrame->stepProgress();
}

// --------------------------------------------------------------------------------
// -------------------- RDOStudioChartDoc
// --------------------------------------------------------------------------------
IMPLEMENT_DYNCREATE(RDOStudioChartDoc, CDocument)

BEGIN_MESSAGE_MAP(RDOStudioChartDoc, CDocument)
END_MESSAGE_MAP()

RDOStudioChartDoc::RDOStudioChartDoc( const rbool preview )
	: CDocument(),
	minTimeOffset( 1.7E+308 ),
	ticksCount( 0 ),
	previewMode( preview )
{
	if ( !previewMode )
		tracer->addChart( this );
}

RDOStudioChartDoc::~RDOStudioChartDoc()
{
	tracer->lock();

	mutex.Lock();

	for ( std::vector< RDOStudioDocSerie* >::iterator it = series.begin(); it != series.end(); it++ ) {
		(*it)->serie->removeFromDoc( this );
		delete (*it);
	}
	if ( !previewMode )
		tracer->removeChart( this );

	mutex.Unlock();

	tracer->unlock();
}

int RDOStudioChartDoc::getSerieIndex( RDOStudioDocSerie* serie ) const
{
	int res = -1;
	int index = 0;
	for ( std::vector< RDOStudioDocSerie* >::const_iterator it = series.begin(); it != series.end(); it++ ) {
		if ( serie == (*it) )
			res = index;
		index ++;
	}
	return res;
}

BOOL RDOStudioChartDoc::OnNewDocument()
{
	if ( !CDocument::OnNewDocument() ) return FALSE;
	return TRUE;
}

void RDOStudioChartDoc::Serialize(CArchive& ar)
{
	if ( ar.IsStoring() ) {
	}
	else {
	}
}

void RDOStudioChartDoc::incTimeEventsCount( RDOTracerTimeNow* time )
{
	//mutex.Lock(); Document is locked from RDOTracerBase::addTime

	if ( !docTimes.empty() && docTimes.back() == time ) {
		ticksCount ++;
		updateChartViews( UPDATE_TIMETICKS );
	}

	//mutex.Unlock();
}

rbool RDOStudioChartDoc::newValueToSerieAdded( RDOTracerValue* val )
{
	//mutex.Lock(); Document is locked from RDOTracerSerie::addValue

	if ( docTimes.empty() ) {
		docTimes.push_back( val->modeltime );
		ticksCount += val->modeltime->eventCount;
	} else {
		RDOTracerTimeNow* last = docTimes.back();
		if ( last != val->modeltime ) {
			docTimes.push_back( val->modeltime );
			ticksCount += val->modeltime->eventCount;
			double off = val->modeltime->time - last->time;
			if ( off < minTimeOffset )
				minTimeOffset = off;
		}
	}
	updateChartViews( UPDATE_NEWVALUE );

	//mutex.Unlock();

	return true;
}

int RDOStudioChartDoc::getMaxMarkerSize() const
{
	const_cast<CMutex&>(mutex).Lock();

	int res = 0;
	for ( std::vector< RDOStudioDocSerie* >::const_iterator it = series.begin(); it != series.end(); it++ ) {
		if ( (*it)->needDrawMarker && (*it)->marker_size > res ) res = (*it)->marker_size;
	}

	const_cast<CMutex&>(mutex).Unlock();

	return res;
}

void RDOStudioChartDoc::addToViews( const HWND handle )
{
	mutex.Lock();

	views_hwnd.push_back( handle );

	mutex.Unlock();
}

void RDOStudioChartDoc::removeFromViews( const HWND handle )
{
	mutex.Lock();

	std::vector< HWND >::iterator it = std::find( views_hwnd.begin(), views_hwnd.end(), handle );
	if ( it != views_hwnd.end() )
		views_hwnd.erase( it );

	mutex.Unlock();
}

void RDOStudioChartDoc::updateChartViews( const UINT update_type ) const
{
	const_cast<CMutex&>(mutex).Lock();

	for( std::vector< HWND >::const_iterator it = views_hwnd.begin(); it != views_hwnd.end(); it++ ) {
		::SendNotifyMessage( (*it), WM_USER_UPDATE_CHART_VIEW, WPARAM( update_type ), 0 );
	}

	const_cast<CMutex&>(mutex).Unlock();
}

void RDOStudioChartDoc::addSerie( RDOTracerSerie* const serie )
{
	mutex.Lock();

	if ( serie && !serieExists( serie ) ) {
		RDOStudioDocSerie* docserie = new RDOStudioDocSerie( serie );
		docserie->lock();
		docserie->color = selectColor();
		docserie->marker = selectMarker();
		series.push_back( docserie );
		inserted_it = docTimes.begin();

		if ( !docTimes.empty() && !serie->empty() ) {
			timesList::iterator last_doc = docTimes.end();
			last_doc --;
			valuesList::const_iterator first_serie = serie->begin();
			if ( (*first_serie)->modeltime->time >= (*last_doc)->time ) {
				inserted_it = docTimes.end();
				if ( (*first_serie)->modeltime->time == (*last_doc)->time ) {
					inserted_it = last_doc;
				}
			}
		}

		try {
			studioApp.BeginWaitCursor();

			//int count;
			//serie->getValueCount( count );
			//studioApp.m_pMainFrame->beginProgress( 0, count );

			std::for_each( serie->begin(), serie->end(), RDOStudioChartDocInsertTime( this ) );

			//studioApp.m_pMainFrame->endProgress();
			studioApp.EndWaitCursor();
		} catch( ... ) {
			studioApp.EndWaitCursor();
		}

		serie->addToDoc( this );
		if ( series.size() == 1 ) {
			POSITION pos = GetFirstViewPosition();
			while (pos != NULL) {
				CView* pView = GetNextView( pos );
				if ( pView && pView->IsKindOf( RUNTIME_CLASS(RDOStudioChartView) ) )
					static_cast<RDOStudioChartView*>( pView )->yAxis = docserie;
			}
		}
		docserie->unlock();
		updateChartViews( UPDATE_NEWSERIE );
	}

	mutex.Unlock();
}

/*void RDOStudioChartDoc::removeSerie( RDOTracerSerie* const serie )
{
	if ( !serie ) return;
	vector<RDOStudioDocSerie*>::iterator it = find_if( series.begin(), series.end(), bind2nd( mem_fun1(&RDOStudioDocSerie::isTracerSerie), serie ) );
	if ( it != series.end() ) {
		(*it)->serie->removeFromDoc( this );
		//must be recalc of minTimeOffset && tickscount
		delete (*it);
		series.erase( it );
		updateChartViews();
	}
}*/

COLORREF RDOStudioChartDoc::selectColor()
{
	int count = series.size();
	int mul = count / 15;
	int index = count - mul * 16;
	COLORREF res = RGB( 0, 0, 0 );
	switch ( index ) {
		case 0  : res = RGB( 0x00, 0x80, 0x00 ); break;
		case 1  : res = RGB( 0x00, 0x00, 0x80 ); break;
		case 2  : res = RGB( 0x80, 0x80, 0x80 ); break;
		case 3  : res = RGB( 0x80, 0x00, 0x80 ); break;
		case 4  : res = RGB( 0xFF, 0x00, 0x00 ); break;
		case 5  : res = RGB( 0x00, 0xFF, 0x00 ); break;
		case 6  : res = RGB( 0x00, 0x00, 0x00 ); break;
		case 7  : res = RGB( 0x80, 0x80, 0x00 ); break;
		case 8  : res = RGB( 0xC0, 0xC0, 0xC0 ); break;
		case 9  : res = RGB( 0x80, 0x00, 0x00 ); break;
		case 10 : res = RGB( 0x00, 0x80, 0x80 ); break;
		case 11 : res = RGB( 0xFF, 0xFF, 0x00 ); break;
		case 12 : res = RGB( 0x00, 0x00, 0xFF ); break;
		case 13 : res = RGB( 0xFF, 0x00, 0xFF ); break;
		case 14 : res = RGB( 0x00, 0xFF, 0xFF ); break;
	};
	return res;
}

RDOTracerSerieMarker RDOStudioChartDoc::selectMarker()
{
	int count = series.size();
	int mul = count / 4;
	int index = count - mul * 4;
	RDOTracerSerieMarker res = RDOSM_CIRCLE;
	switch ( index ) {
		case 0  : res = RDOSM_CIRCLE; break;
		case 1  : res = RDOSM_SQUARE; break;
		case 2  : res = RDOSM_RHOMB; break;
		case 3  : res = RDOSM_CROSS; break;
	};
	return res;
}

rbool RDOStudioChartDoc::serieExists( const RDOTracerSerie* serie ) const
{
	const_cast<CMutex&>(mutex).Lock();

	rbool res = std::find_if( series.begin(), series.end(), std::bind2nd( std::mem_fun1(&RDOStudioDocSerie::isTracerSerie), serie ) ) != series.end();

	const_cast<CMutex&>(mutex).Unlock();

	return res;
}

void RDOStudioChartDoc::SetTitle( LPCTSTR lpszTitle )
{
	title = lpszTitle;
	CDocument::SetTitle( rdo::format( IDS_CHART_TITLE, title.c_str() ).c_str() );
}

#ifdef _DEBUG
void RDOStudioChartDoc::AssertValid() const
{
	CDocument::AssertValid();
}

void RDOStudioChartDoc::Dump(CDumpContext& dc) const
{
	CDocument::Dump(dc);
}
#endif //_DEBUG<|endoftext|>


<commit_before><commit_msg>avoid use of ref. to possibly deleted object<commit_after><|endoftext|>


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

#ifndef SC_NOTEMARK_HXX
#define SC_NOTEMARK_HXX

#ifndef _MAPMOD_HXX //autogen
#include <vcl/mapmod.hxx>
#endif
#ifndef _TIMER_HXX //autogen
#include <vcl/timer.hxx>
#endif

#ifndef SC_SCGLOB_HXX
#include "global.hxx"
#endif

class SdrModel;
class SdrObject;

class ScNoteMarker
{
private:
    Window*     pWindow;
    Window*     pRightWin;
    Window*     pBottomWin;
    Window*     pDiagWin;
    ScDocument* pDoc;
    ScAddress   aDocPos;
    String      aUserText;
    Timer       aTimer;
    MapMode     aMapMode;
    BOOL        bLeft;
    BOOL        bByKeyboard;

    Rectangle       aRect;
    SdrModel*       pModel;
    SdrObject*      pObject;
    BOOL            bVisible;

    DECL_LINK( TimeHdl, Timer* );

public:
                ScNoteMarker( Window* pWin,
                                Window* pRight, Window* pBottom, Window* pDiagonal,
                                ScDocument* pD, ScAddress aPos,
                                const String& rUser, const MapMode& rMap,
                                BOOL bLeftEdge, BOOL bForce, BOOL bKeyboard );
                ~ScNoteMarker();

    void        Draw();
    void        InvalidateWin();

    ScAddress   GetDocPos() const       { return aDocPos; }
    BOOL        IsByKeyboard() const    { return bByKeyboard; }
};

#endif

<commit_msg>INTEGRATION: CWS rowlimit (1.2.310); FILE MERGED 2003/11/28 19:48:00 er 1.2.310.1: #i1967# move ScAddress, ScRange from global.hxx to address.hxx<commit_after>/*************************************************************************
 *
 *  $RCSfile: notemark.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: obo $ $Date: 2004-06-04 11:36:09 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef SC_NOTEMARK_HXX
#define SC_NOTEMARK_HXX

#ifndef _MAPMOD_HXX //autogen
#include <vcl/mapmod.hxx>
#endif
#ifndef _TIMER_HXX //autogen
#include <vcl/timer.hxx>
#endif

#ifndef SC_SCGLOB_HXX
#include "global.hxx"
#endif

#ifndef SC_ADDRESS_HXX
#include "address.hxx"
#endif

class SdrModel;
class SdrObject;

class ScNoteMarker
{
private:
    Window*     pWindow;
    Window*     pRightWin;
    Window*     pBottomWin;
    Window*     pDiagWin;
    ScDocument* pDoc;
    ScAddress   aDocPos;
    String      aUserText;
    Timer       aTimer;
    MapMode     aMapMode;
    BOOL        bLeft;
    BOOL        bByKeyboard;

    Rectangle       aRect;
    SdrModel*       pModel;
    SdrObject*      pObject;
    BOOL            bVisible;

    DECL_LINK( TimeHdl, Timer* );

public:
                ScNoteMarker( Window* pWin,
                                Window* pRight, Window* pBottom, Window* pDiagonal,
                                ScDocument* pD, ScAddress aPos,
                                const String& rUser, const MapMode& rMap,
                                BOOL bLeftEdge, BOOL bForce, BOOL bKeyboard );
                ~ScNoteMarker();

    void        Draw();
    void        InvalidateWin();

    ScAddress   GetDocPos() const       { return aDocPos; }
    BOOL        IsByKeyboard() const    { return bByKeyboard; }
};

#endif

<|endoftext|>


<commit_before><commit_msg>send mouse events to the OpenGL window<commit_after><|endoftext|>