<commit_before>/* ---------------------------------------------------------------------
 * Numenta Platform for Intelligent Computing (NuPIC)
 * Copyright (C) 2013, Numenta, Inc.  Unless you have an agreement
 * with Numenta, Inc., for a separate license for this software code, the
 * following terms and conditions apply:
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero Public License version 3 as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU Affero Public License for more details.
 *
 * You should have received a copy of the GNU Affero Public License
 * along with this program.  If not, see http://www.gnu.org/licenses.
 *
 * http://numenta.org/licenses/
 * ---------------------------------------------------------------------
 */

/** @file
 * Interface for the Link class
 */

#ifndef NTA_LINK_HPP
#define NTA_LINK_HPP

#include <string>

#include <nupic/engine/LinkPolicy.hpp>
#include <nupic/engine/Input.hpp> // needed for splitter map
#include <nupic/ntypes/Dimensions.hpp>
#include <nupic/proto/LinkProto.capnp.h>
#include <nupic/types/Types.hpp>

namespace nupic
{

  class Output;
  class Input;

  /**
   *
   * Represents a link between regions in a Network.
   *
   * @nosubgrouping
   *
   */
  class Link
  {
  public:

    /**
     * @name Initialization
     *
     * @{
     *
     * Links have four-phase initialization.
     *
     * 1. construct with link type, params, names of regions and inputs/outputs
     * 2. wire in to network (setting src and dest Output/Input pointers)
     * 3. set source and destination dimensions
     * 4. initialize -- sets the offset in the destination Input (not known earlier)
     *
     * De-serializing is the same as phase 1.
     *
     * In phase 3, NuPIC will set and/or get source and/or destination
     * dimensions until both are set. Normally we will only set the src dimensions,
     * and the dest dimensions will be induced. It is possible to go the other
     * way, though.
     *
     * The @a linkType and @a linkParams parameters are given to
     * the LinkPolicyFactory to create a link policy
     *
     * @todo Should LinkPolicyFactory be documented?
     *
     */

    /**
     * Initialization Phase 1: setting parameters of the link.
     *
     * @param linkType
     *            The type of the link
     * @param linkParams
     *            The parameters of the link
     * @param srcRegionName
     *            The name of the source Region
     * @param destRegionName
     *            The name of the destination Region
     * @param srcOutputName
     *            The name of the source Output
     * @param destInputName
     *            The name of the destination Input
     *
     * @internal
     *
     * @todo It seems this constructor should be deprecated in favor of the other,
     * which is less redundant. This constructor is being used for unit testing
     * and unit testing links and for deserializing networks.
     *
     * See comments below commonConstructorInit_()
     *
     * @endinternal
     *
     */
    Link(const std::string& linkType, const std::string& linkParams,
         const std::string& srcRegionName, const std::string& destRegionName,
         const std::string& srcOutputName="", const std::string& destInputName="");

    /**
     * Initialization Phase 2: connecting inputs/outputs to
     * the Network.
     *
     * @param src
     *            The source Output of the link
     * @param dest
     *            The destination Input of the link
     */
    void connectToNetwork(Output* src, Input* dest);

    /*
     * Initialization Phase 1 and 2.
     *
     * @param linkType
     *            The type of the link
     * @param linkParams
     *            The parameters of the link
     * @param srcOutput
     *            The source Output of the link
     * @param destInput
     *            The destination Input of the link
     */
    Link(const std::string& linkType, const std::string& linkParams,
         Output* srcOutput, Input* destInput);

    /**
     * Initialization Phase 3: set the Dimensions for the source Output, and
     * induce the Dimensions for the destination Input .
     *
     *
     * @param dims
     *         The Dimensions for the source Output
     */
    void setSrcDimensions(Dimensions& dims);

    /**
     * Initialization Phase 3: Set the Dimensions for the destination Input, and
     * induce the Dimensions for the source Output .
     *
     * @param dims
     *         The Dimensions for the destination Input
     */
    void setDestDimensions(Dimensions& dims);

    /**
     * Initialization Phase 4: sets the offset in the destination Input .
     *
     * @param destinationOffset
     *            The offset in the destination Input, i.e. TODO
     *
     */
    void initialize(size_t destinationOffset);

    /**
     * Destructor
     */
    ~Link();

    /**
     * @}
     *
     * @name Parameter getters of the link
     *
     * @{
     *
     */

    /**
     * Get the Dimensions for the source Output .
     *
     * @returns
     *         The Dimensions for the source Output
     */
    const Dimensions& getSrcDimensions() const;

    /**
     * Get the Dimensions for the destination Input .
     *
     * @returns
     *         The Dimensions for the destination Input
     */
    const Dimensions& getDestDimensions() const;

    /**
     * Get the type of the link.
     *
     * @returns
     *         The type of the link
     */
    const std::string& getLinkType() const;

    /**
     * Get the parameters of the link.
     *
     * @returns
     *         The parameters of the link
     */
    const std::string& getLinkParams() const;

    /**
     * Get the name of the source Region
     *
     * @returns
     *         The name of the source Region
     */
    const std::string& getSrcRegionName() const;

    /**
     * Get the name of the source Output.
     *
     * @returns
     *         The name of the source Output
     */
    const std::string& getSrcOutputName() const;

    /**
     * Get the name of the destination Region.
     *
     * @returns
     *         The name of the destination Region
     *
     */
    const std::string& getDestRegionName() const;

    /**
     * Get the name of the destination Input.
     *
     * @returns
     *         The name of the destination Input
     */
    const std::string& getDestInputName() const;

    /**
     * @}
     *
     * @name Misc
     *
     * @{
     */

    // The methods below only work on connected links (after phase 2)

    /**
     *
     * Get the source Output of the link.
     *
     * @returns
     *         The source Output of the link
     */
    Output& getSrc() const;

    /**
     *
     * Get the destination Input of the link.
     *
     * @returns
     *         The destination Input of the link
     */
    Input& getDest() const;

    /**
     * Copy data from source to destination.
     *
     * Nodes request input data from their input objects. The input objects,
     * in turn, request links to copy data into the inputs.
     *
     * @note This method must be called on a fully initialized link(all 4 phases).
     *
     */
    void
    compute();

    /**
     * Build a splitter map from the link.
     *
     * @param[out] splitter
     *            The built SplitterMap
     *
     * A splitter map is a matrix that maps the full input
     * of a region to the inputs of individual nodes within
     * the region.
     * A splitter map "sm" is declared as:
     *
     *     vector< vector<size_t> > sm;
     *
     *     sm.length() == number of nodes
     *
     * `sm[i]` is a "sparse vector" used to gather the input
     * for node i. `sm[i].size()` is the size (in elements) of
     * the input for node i.
     *
     * `sm[i]` gathers the inputs as follows:
     *
     *     T *regionInput; // input buffer for the whole region
     *     T *nodeInput; // pre-allocated
     *     for (size_t elem = 0; elem < sm[i].size; elem++)
     *        nodeInput[elem] = regionInput[sm[i][elem]];
     *
     * The offset specified by `sm[i][j]` is in units of elements.
     * To get byte offsets, you'd multiply by the size of an input/output
     * element.
     *
     * An input to a region may come from several links.
     * Each link contributes a contiguous block of the region input
     * starting from a certain offset. The splitter map indices are
     * with respect to the full region input, not the partial region
     * input contributed by this link, so the destinationOffset for this
     * link is included in each of the splitter map entries.
     *
     * Finally, the API is designed so that each link associated with
     * an input can contribute its portion to a full splitter map.
     * Thus the splitter map is an input-output parameter. This method
     * appends data to each row of the splitter map, assuming that
     * existing data in the splitter map comes from other links.
     *
     * For region-level inputs, a splitter map has just a single row.
     *
     * ### Splitter map ownership
     *
     * The splitter map is owned by the containing Input. Each Link
     * in the input contributes a portion to the splitter map, through
     * the buildSplitterMap method.
     *
     */
    void
    buildSplitterMap(Input::SplitterMap& splitter);

    /**
     * Convert the Link to a human-readable string.
     *
     * @returns
     *     The human-readable string describing the Link
     */
    const std::string toString() const;

    /**
     * Serialize the link.
     *
     * @param f
     *            The output stream being serialized to
     * @param link
     *            The Link being serialized
     */
    friend std::ostream& operator<<(std::ostream& f, const Link& link);

    void write(LinkProto::Builder& proto) const;
    void read(LinkProto::Reader& proto);

    /**
     *
     * @}
     *
     * @name Not implemented
     *
     * @{
     */

    /**
     * Get the size of the input contributed by this link for a single node.
     *
     * @param nodeIndex
     *            The index of the node
     *
     * @returns
     *         The size of the input contributed by this link for a single node.
     *
     * @todo index=-1 for region-level input?
     *
     * @todo not implemented;  necessary?
     */
    size_t
    getNodeInputSize(size_t nodeIndex);

    /**
     * Tells whether the Input is contiguous.
     *
     * @returns
     *         Whether the Input is contiguous, i.e. TODO
     *
     * If the input for a particular node is a contiguous subset
     * of the src output, then the splitter map is overkill, and
     * all we need to know is the offset/size (per node)
     * Returns true if and only if the input for each node
     * is a contiguous chunk of the input buffer.
     *
     * @todo not implemented;  necessary?
     */
    bool
    isInputContiguous();

    /**
     * Locate the contiguous input for a node.
     *
     * This method is used only if the input is contiguous
     *
     * @param nodeIndex
     *            The index of the node
     *
     * @returns
     *         The Input offset of the node
     *
     * @todo not implemented;  necessary?
     */
    size_t
    getInputOffset(size_t nodeIndex);

    /**
     * @}
     */

  private:
    // common initialization for the two constructors.
    void commonConstructorInit_(const std::string& linkType,
                                const std::string& linkParams,
                                const std::string& srcRegionName,
                                const std::string& destRegionName,
                                const std::string& srcOutputName,
                                const std::string& destInputName);

    // TODO: The strings with src/dest names are redundant with
    // the src_ and dest_ objects. For unit testing links,
    // and for deserializing networks, we need to be able to create
    // a link object without a network. and for deserializing, we
    // need to be able to instantiate a link before we have instantiated
    // all the regions. (Maybe this isn't true? Re-evaluate when
    // more infrastructure is in place).

    std::string srcRegionName_;
    std::string destRegionName_;
    std::string srcOutputName_;
    std::string destInputName_;

    // We store the values given to use. Use these for
    // serialization instead of serializing the LinkPolicy
    // itself.
    std::string linkType_;
    std::string linkParams_;

    LinkPolicy *impl_;

    Output *src_;
    Input *dest_;

    // Each link contributes a contiguous chunk of the destination
    // input. The link needs to know its offset within the destination
    // input. This value is set at initialization time.
    size_t destOffset_;

    // TODO: These are currently unused. Situations where we need them
    // are rare. Would they make more sense as link policy params?
    // Will also need a link getDestinationSize method since
    // the amount of data contributed by this link to the destination input
    // may not equal the size of the source output.
    size_t srcOffset_;
    size_t srcSize_;

    // link must be initialized before it can compute()
    bool initialized_;

  };

} // namespace nupic

#endif // NTA_LINK_HPP
<commit_msg>Update Link to use Serializable<commit_after>/* ---------------------------------------------------------------------
 * Numenta Platform for Intelligent Computing (NuPIC)
 * Copyright (C) 2013, Numenta, Inc.  Unless you have an agreement
 * with Numenta, Inc., for a separate license for this software code, the
 * following terms and conditions apply:
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero Public License version 3 as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU Affero Public License for more details.
 *
 * You should have received a copy of the GNU Affero Public License
 * along with this program.  If not, see http://www.gnu.org/licenses.
 *
 * http://numenta.org/licenses/
 * ---------------------------------------------------------------------
 */

/** @file
 * Interface for the Link class
 */

#ifndef NTA_LINK_HPP
#define NTA_LINK_HPP

#include <string>

#include <nupic/engine/LinkPolicy.hpp>
#include <nupic/engine/Input.hpp> // needed for splitter map
#include <nupic/ntypes/Dimensions.hpp>
#include <nupic/proto/LinkProto.capnp.h>
#include <nupic/types/Serializable.hpp>
#include <nupic/types/Types.hpp>

namespace nupic
{

  class Output;
  class Input;

  /**
   *
   * Represents a link between regions in a Network.
   *
   * @nosubgrouping
   *
   */
  class Link : Serializable<LinkProto>
  {
  public:

    /**
     * @name Initialization
     *
     * @{
     *
     * Links have four-phase initialization.
     *
     * 1. construct with link type, params, names of regions and inputs/outputs
     * 2. wire in to network (setting src and dest Output/Input pointers)
     * 3. set source and destination dimensions
     * 4. initialize -- sets the offset in the destination Input (not known earlier)
     *
     * De-serializing is the same as phase 1.
     *
     * In phase 3, NuPIC will set and/or get source and/or destination
     * dimensions until both are set. Normally we will only set the src dimensions,
     * and the dest dimensions will be induced. It is possible to go the other
     * way, though.
     *
     * The @a linkType and @a linkParams parameters are given to
     * the LinkPolicyFactory to create a link policy
     *
     * @todo Should LinkPolicyFactory be documented?
     *
     */

    /**
     * Initialization Phase 1: setting parameters of the link.
     *
     * @param linkType
     *            The type of the link
     * @param linkParams
     *            The parameters of the link
     * @param srcRegionName
     *            The name of the source Region
     * @param destRegionName
     *            The name of the destination Region
     * @param srcOutputName
     *            The name of the source Output
     * @param destInputName
     *            The name of the destination Input
     *
     * @internal
     *
     * @todo It seems this constructor should be deprecated in favor of the other,
     * which is less redundant. This constructor is being used for unit testing
     * and unit testing links and for deserializing networks.
     *
     * See comments below commonConstructorInit_()
     *
     * @endinternal
     *
     */
    Link(const std::string& linkType, const std::string& linkParams,
         const std::string& srcRegionName, const std::string& destRegionName,
         const std::string& srcOutputName="", const std::string& destInputName="");

    /**
     * Initialization Phase 2: connecting inputs/outputs to
     * the Network.
     *
     * @param src
     *            The source Output of the link
     * @param dest
     *            The destination Input of the link
     */
    void connectToNetwork(Output* src, Input* dest);

    /*
     * Initialization Phase 1 and 2.
     *
     * @param linkType
     *            The type of the link
     * @param linkParams
     *            The parameters of the link
     * @param srcOutput
     *            The source Output of the link
     * @param destInput
     *            The destination Input of the link
     */
    Link(const std::string& linkType, const std::string& linkParams,
         Output* srcOutput, Input* destInput);

    /**
     * Initialization Phase 3: set the Dimensions for the source Output, and
     * induce the Dimensions for the destination Input .
     *
     *
     * @param dims
     *         The Dimensions for the source Output
     */
    void setSrcDimensions(Dimensions& dims);

    /**
     * Initialization Phase 3: Set the Dimensions for the destination Input, and
     * induce the Dimensions for the source Output .
     *
     * @param dims
     *         The Dimensions for the destination Input
     */
    void setDestDimensions(Dimensions& dims);

    /**
     * Initialization Phase 4: sets the offset in the destination Input .
     *
     * @param destinationOffset
     *            The offset in the destination Input, i.e. TODO
     *
     */
    void initialize(size_t destinationOffset);

    /**
     * Destructor
     */
    ~Link();

    /**
     * @}
     *
     * @name Parameter getters of the link
     *
     * @{
     *
     */

    /**
     * Get the Dimensions for the source Output .
     *
     * @returns
     *         The Dimensions for the source Output
     */
    const Dimensions& getSrcDimensions() const;

    /**
     * Get the Dimensions for the destination Input .
     *
     * @returns
     *         The Dimensions for the destination Input
     */
    const Dimensions& getDestDimensions() const;

    /**
     * Get the type of the link.
     *
     * @returns
     *         The type of the link
     */
    const std::string& getLinkType() const;

    /**
     * Get the parameters of the link.
     *
     * @returns
     *         The parameters of the link
     */
    const std::string& getLinkParams() const;

    /**
     * Get the name of the source Region
     *
     * @returns
     *         The name of the source Region
     */
    const std::string& getSrcRegionName() const;

    /**
     * Get the name of the source Output.
     *
     * @returns
     *         The name of the source Output
     */
    const std::string& getSrcOutputName() const;

    /**
     * Get the name of the destination Region.
     *
     * @returns
     *         The name of the destination Region
     *
     */
    const std::string& getDestRegionName() const;

    /**
     * Get the name of the destination Input.
     *
     * @returns
     *         The name of the destination Input
     */
    const std::string& getDestInputName() const;

    /**
     * @}
     *
     * @name Misc
     *
     * @{
     */

    // The methods below only work on connected links (after phase 2)

    /**
     *
     * Get the source Output of the link.
     *
     * @returns
     *         The source Output of the link
     */
    Output& getSrc() const;

    /**
     *
     * Get the destination Input of the link.
     *
     * @returns
     *         The destination Input of the link
     */
    Input& getDest() const;

    /**
     * Copy data from source to destination.
     *
     * Nodes request input data from their input objects. The input objects,
     * in turn, request links to copy data into the inputs.
     *
     * @note This method must be called on a fully initialized link(all 4 phases).
     *
     */
    void
    compute();

    /**
     * Build a splitter map from the link.
     *
     * @param[out] splitter
     *            The built SplitterMap
     *
     * A splitter map is a matrix that maps the full input
     * of a region to the inputs of individual nodes within
     * the region.
     * A splitter map "sm" is declared as:
     *
     *     vector< vector<size_t> > sm;
     *
     *     sm.length() == number of nodes
     *
     * `sm[i]` is a "sparse vector" used to gather the input
     * for node i. `sm[i].size()` is the size (in elements) of
     * the input for node i.
     *
     * `sm[i]` gathers the inputs as follows:
     *
     *     T *regionInput; // input buffer for the whole region
     *     T *nodeInput; // pre-allocated
     *     for (size_t elem = 0; elem < sm[i].size; elem++)
     *        nodeInput[elem] = regionInput[sm[i][elem]];
     *
     * The offset specified by `sm[i][j]` is in units of elements.
     * To get byte offsets, you'd multiply by the size of an input/output
     * element.
     *
     * An input to a region may come from several links.
     * Each link contributes a contiguous block of the region input
     * starting from a certain offset. The splitter map indices are
     * with respect to the full region input, not the partial region
     * input contributed by this link, so the destinationOffset for this
     * link is included in each of the splitter map entries.
     *
     * Finally, the API is designed so that each link associated with
     * an input can contribute its portion to a full splitter map.
     * Thus the splitter map is an input-output parameter. This method
     * appends data to each row of the splitter map, assuming that
     * existing data in the splitter map comes from other links.
     *
     * For region-level inputs, a splitter map has just a single row.
     *
     * ### Splitter map ownership
     *
     * The splitter map is owned by the containing Input. Each Link
     * in the input contributes a portion to the splitter map, through
     * the buildSplitterMap method.
     *
     */
    void
    buildSplitterMap(Input::SplitterMap& splitter);

    /**
     * Convert the Link to a human-readable string.
     *
     * @returns
     *     The human-readable string describing the Link
     */
    const std::string toString() const;

    /**
     * Serialize the link.
     *
     * @param f
     *            The output stream being serialized to
     * @param link
     *            The Link being serialized
     */
    friend std::ostream& operator<<(std::ostream& f, const Link& link);

    using Serializable::write;
    void write(LinkProto::Builder& proto) const;

    using Serializable::read;
    void read(LinkProto::Reader& proto);

    /**
     *
     * @}
     *
     * @name Not implemented
     *
     * @{
     */

    /**
     * Get the size of the input contributed by this link for a single node.
     *
     * @param nodeIndex
     *            The index of the node
     *
     * @returns
     *         The size of the input contributed by this link for a single node.
     *
     * @todo index=-1 for region-level input?
     *
     * @todo not implemented;  necessary?
     */
    size_t
    getNodeInputSize(size_t nodeIndex);

    /**
     * Tells whether the Input is contiguous.
     *
     * @returns
     *         Whether the Input is contiguous, i.e. TODO
     *
     * If the input for a particular node is a contiguous subset
     * of the src output, then the splitter map is overkill, and
     * all we need to know is the offset/size (per node)
     * Returns true if and only if the input for each node
     * is a contiguous chunk of the input buffer.
     *
     * @todo not implemented;  necessary?
     */
    bool
    isInputContiguous();

    /**
     * Locate the contiguous input for a node.
     *
     * This method is used only if the input is contiguous
     *
     * @param nodeIndex
     *            The index of the node
     *
     * @returns
     *         The Input offset of the node
     *
     * @todo not implemented;  necessary?
     */
    size_t
    getInputOffset(size_t nodeIndex);

    /**
     * @}
     */

  private:
    // common initialization for the two constructors.
    void commonConstructorInit_(const std::string& linkType,
                                const std::string& linkParams,
                                const std::string& srcRegionName,
                                const std::string& destRegionName,
                                const std::string& srcOutputName,
                                const std::string& destInputName);

    // TODO: The strings with src/dest names are redundant with
    // the src_ and dest_ objects. For unit testing links,
    // and for deserializing networks, we need to be able to create
    // a link object without a network. and for deserializing, we
    // need to be able to instantiate a link before we have instantiated
    // all the regions. (Maybe this isn't true? Re-evaluate when
    // more infrastructure is in place).

    std::string srcRegionName_;
    std::string destRegionName_;
    std::string srcOutputName_;
    std::string destInputName_;

    // We store the values given to use. Use these for
    // serialization instead of serializing the LinkPolicy
    // itself.
    std::string linkType_;
    std::string linkParams_;

    LinkPolicy *impl_;

    Output *src_;
    Input *dest_;

    // Each link contributes a contiguous chunk of the destination
    // input. The link needs to know its offset within the destination
    // input. This value is set at initialization time.
    size_t destOffset_;

    // TODO: These are currently unused. Situations where we need them
    // are rare. Would they make more sense as link policy params?
    // Will also need a link getDestinationSize method since
    // the amount of data contributed by this link to the destination input
    // may not equal the size of the source output.
    size_t srcOffset_;
    size_t srcSize_;

    // link must be initialized before it can compute()
    bool initialized_;

  };

} // namespace nupic

#endif // NTA_LINK_HPP
<|endoftext|>


<commit_before>//=============================================================================
// ■ main.cpp
//-----------------------------------------------------------------------------
//   VMGS的主程序。
//=============================================================================

#include "VMGS.hpp"

namespace VM76 {
	Shaders* shader_textured = NULL;
	Shaders* gui = NULL;
	Shaders* shader_basic = NULL;
	Res::Texture* tile_texture = NULL;

	TextRenderer* trex = NULL; // 2333 T-Rex

	Cube* block_pointer;
	Cube* clist[16];
	TiledMap* map;

	glm::mat4 gui_2d_projection;

	int hand_id = 1;

	Axis* axe;

	Object* obj = new Object();

	void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) {
		#define PRESS(n) key == n && action == GLFW_PRESS
		if (PRESS(GLFW_KEY_A)) obj->move(glm::vec3(-1.0, 0.0, 0.0));
		if (PRESS(GLFW_KEY_D)) obj->move(glm::vec3(1.0, 0.0, 0.0));
		if (PRESS(GLFW_KEY_W)) obj->move(glm::vec3(0.0, 0.0, -1.0));
		if (PRESS(GLFW_KEY_S)) obj->move(glm::vec3(0.0, 0.0, 1.0));
		if (PRESS(GLFW_KEY_UP)) obj->move(glm::vec3(0.0, 1.0, 0.0));
		if (PRESS(GLFW_KEY_DOWN)) obj->move(glm::vec3(0.0, -1.0, 0.0));

		if (PRESS(GLFW_KEY_0)) hand_id = 0;
		if (PRESS(GLFW_KEY_0)) hand_id = 0;
		if (PRESS(GLFW_KEY_1)) hand_id = 1;
		if (PRESS(GLFW_KEY_2)) hand_id = 2;
		if (PRESS(GLFW_KEY_3)) hand_id = 3;
		if (PRESS(GLFW_KEY_4)) hand_id = 4;
		if (PRESS(GLFW_KEY_5)) hand_id = 5;
		if (PRESS(GLFW_KEY_6)) hand_id = 6;
		if (PRESS(GLFW_KEY_7)) hand_id = 7;
		if (PRESS(GLFW_KEY_8)) hand_id = 8;
		if (PRESS(GLFW_KEY_9)) hand_id = 9;

		if (PRESS(GLFW_KEY_SPACE)) {
			Audio::play_sound("../Media/soft-ping.ogg", false);
			map->tiles[map->calcTileIndex(obj->pos)].tid = hand_id;
			map->bake_tiles();
		}
		#undef PRESS
	}

	void loop() {
		do {
			::main_draw_start();
			update_control();

			glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

			glEnable(GL_BLEND);
			glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

			shader_textured->use();

			// Setup uniforms
			shader_textured->set_float("brightness", VMDE->state.brightness);
			shader_textured->set_texture("colortex0", tile_texture, 0);

			// Textured blocks rendering
			shader_textured->ProjectionView(projection, view);
			map->render();

			// Setup uniforms
			// Non textured rendering
			shader_basic->use();
			shader_basic->set_float("opaque", 0.5);
			shader_textured->ProjectionView(projection, view);
			block_pointer->mat[0] = obj->transform();
			block_pointer->update_instance(1);
			block_pointer->render();

			axe->render();

			// GUI rendering
			gui->use();
			gui->set_texture("atlastex", tile_texture, 0);
			gui->ProjectionView(gui_2d_projection, glm::mat4(1.0));
			glDisable(GL_DEPTH_TEST);
			if (hand_id > 0)
				clist[hand_id - 1]->render();

			char frame_count[32];
			sprintf(frame_count, "%d", VMDE->frame_count);
			trex->instanceRenderText(
				frame_count, gui_2d_projection,
				glm::mat4(1.0),
				glm::translate(glm::mat4(1.0), glm::vec3(0.0,0.8,0.0)),
				0.05, 0.1
			);
			glEnable(GL_DEPTH_TEST);

			::main_draw_end();
		} while (!VMDE->done);
	}

	void start_game() {
		::init_engine(860, 540, "VM / 76");
		init_control();

		tile_texture = new Res::Texture("../Media/terrain.png");

		shader_textured = Shaders::CreateFromFile("../Media/shaders/gbuffers_textured.vsh", "../Media/shaders/gbuffers_textured.fsh");
		shader_basic = Shaders::CreateFromFile("../Media/shaders/gbuffers_basic.vsh", "../Media/shaders/gbuffers_basic.fsh");
		gui = Shaders::CreateFromFile("../Media/shaders/gui.vsh", "../Media/shaders/gui.fsh");
		float aspectRatio = float(VMDE->width) / float(VMDE->height);
		gui_2d_projection = glm::ortho(0.0, 1.0 * aspectRatio, 0.0, 1.0, -1.0, 1.0);

		projection = glm::perspective(1.3f, float(VMDE->width) / float(VMDE->height), 0.1f, 1000.0f);
		view = glm::lookAt(glm::vec3(0.0, 2.6, 0.0), glm::vec3(0.0, 0.0, 0.0), glm::vec3(0.0, 1.0, 0.0));

		// GL settings initialize
		glFrontFace(GL_CCW);
		glEnable(GL_CULL_FACE);

		glEnable(GL_DEPTH_TEST);
		glDepthFunc(GL_LEQUAL);

		glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
		glDepthRange(0.0f, 1.0f);
		glClearDepth(1.0f);
		glDepthMask(GL_TRUE);

		block_pointer = new Cube(1);
		// Set up hand block indicator's matrix
		glm::mat4 block_display = glm::translate(glm::mat4(1.0), glm::vec3(0.02, 0.06, 0.2));
		block_display = glm::scale(block_display, glm::vec3(0.1f));
		block_display = glm::rotate(block_display, Util::PIf / 4.0f, glm::vec3(1.0, 0.0, 0.0));
		block_display = glm::rotate(block_display, Util::PIf / 4.0f, glm::vec3(0.0, 1.0, 0.0));
		for (int i = 0; i < 16; i++) {
			clist[i] = new Cube(i);
			clist[i]->mat[0] = block_display;
			clist[i]->update_instance(1);
		}
		axe = new Axis();
		trex = new TextRenderer();
		map = new TiledMap(16, 16, 16, glm::vec3(0.0));
		block_pointer->obj->data.mat_c = 1;
		glfwSetKeyCallback(window, key_callback);

		loop();
		terminate();
	}

	void terminate() {
		log("starting to terminate");
		terminate_engine();
		VMDE_Dispose(tile_texture);
		VMDE_Dispose(block_pointer);
		for (int i = 0; i < 16; i++) VMDE_Dispose(clist[i]);
		VMDE_Dispose(map);
		log("terminated successfully");
	}
}

int main() {
	log("Hello! This is VM76. Nice to meet you!");
	VM76::start_game();
}
<commit_msg>拿文字渲染做有意义的事<commit_after>//=============================================================================
// ■ main.cpp
//-----------------------------------------------------------------------------
//   VMGS的主程序。
//=============================================================================

#include "VMGS.hpp"

namespace VM76 {
	Shaders* shader_textured = NULL;
	Shaders* gui = NULL;
	Shaders* shader_basic = NULL;
	Res::Texture* tile_texture = NULL;

	TextRenderer* trex = NULL; // 2333 T-Rex

	Cube* block_pointer;
	Cube* clist[16];
	TiledMap* map;

	glm::mat4 gui_2d_projection;

	int hand_id = 1;

	Axis* axe;

	Object* obj = new Object();

	void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) {
		#define PRESS(n) key == n && action == GLFW_PRESS
		if (PRESS(GLFW_KEY_A)) obj->move(glm::vec3(-1.0, 0.0, 0.0));
		if (PRESS(GLFW_KEY_D)) obj->move(glm::vec3(1.0, 0.0, 0.0));
		if (PRESS(GLFW_KEY_W)) obj->move(glm::vec3(0.0, 0.0, -1.0));
		if (PRESS(GLFW_KEY_S)) obj->move(glm::vec3(0.0, 0.0, 1.0));
		if (PRESS(GLFW_KEY_UP)) obj->move(glm::vec3(0.0, 1.0, 0.0));
		if (PRESS(GLFW_KEY_DOWN)) obj->move(glm::vec3(0.0, -1.0, 0.0));

		if (PRESS(GLFW_KEY_0)) hand_id = 0;
		if (PRESS(GLFW_KEY_0)) hand_id = 0;
		if (PRESS(GLFW_KEY_1)) hand_id = 1;
		if (PRESS(GLFW_KEY_2)) hand_id = 2;
		if (PRESS(GLFW_KEY_3)) hand_id = 3;
		if (PRESS(GLFW_KEY_4)) hand_id = 4;
		if (PRESS(GLFW_KEY_5)) hand_id = 5;
		if (PRESS(GLFW_KEY_6)) hand_id = 6;
		if (PRESS(GLFW_KEY_7)) hand_id = 7;
		if (PRESS(GLFW_KEY_8)) hand_id = 8;
		if (PRESS(GLFW_KEY_9)) hand_id = 9;

		if (PRESS(GLFW_KEY_SPACE)) {
			Audio::play_sound("../Media/soft-ping.ogg", false);
			map->tiles[map->calcTileIndex(obj->pos)].tid = hand_id;
			map->bake_tiles();
		}
		#undef PRESS
	}

	void loop() {
		do {
			::main_draw_start();
			update_control();

			glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

			glEnable(GL_BLEND);
			glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

			shader_textured->use();

			// Setup uniforms
			shader_textured->set_float("brightness", VMDE->state.brightness);
			shader_textured->set_texture("colortex0", tile_texture, 0);

			// Textured blocks rendering
			shader_textured->ProjectionView(projection, view);
			map->render();

			// Setup uniforms
			// Non textured rendering
			shader_basic->use();
			shader_basic->set_float("opaque", 0.5);
			shader_textured->ProjectionView(projection, view);
			block_pointer->mat[0] = obj->transform();
			block_pointer->update_instance(1);
			block_pointer->render();

			axe->render();

			// GUI rendering
			gui->use();
			gui->set_texture("atlastex", tile_texture, 0);
			gui->ProjectionView(gui_2d_projection, glm::mat4(1.0));
			glDisable(GL_DEPTH_TEST);
			if (hand_id > 0)
				clist[hand_id - 1]->render();

			char frame_count[64];
			sprintf(frame_count, "FPS: %d Hand ID: %d Pointer ID: %d",
				VMDE->fps,
				hand_id,
				map->tiles[map->calcTileIndex(obj->pos)].tid
			);
			trex->instanceRenderText(
				frame_count, gui_2d_projection,
				glm::mat4(1.0),
				glm::translate(glm::mat4(1.0), glm::vec3(0.01,0.94,0.0)),
				0.025, 0.05
			);
			glEnable(GL_DEPTH_TEST);

			::main_draw_end();
		} while (!VMDE->done);
	}

	void start_game() {
		::init_engine(860, 540, "VM / 76");
		init_control();

		tile_texture = new Res::Texture("../Media/terrain.png");

		shader_textured = Shaders::CreateFromFile("../Media/shaders/gbuffers_textured.vsh", "../Media/shaders/gbuffers_textured.fsh");
		shader_basic = Shaders::CreateFromFile("../Media/shaders/gbuffers_basic.vsh", "../Media/shaders/gbuffers_basic.fsh");
		gui = Shaders::CreateFromFile("../Media/shaders/gui.vsh", "../Media/shaders/gui.fsh");
		float aspectRatio = float(VMDE->width) / float(VMDE->height);
		gui_2d_projection = glm::ortho(0.0, 1.0 * aspectRatio, 0.0, 1.0, -1.0, 1.0);

		projection = glm::perspective(1.3f, float(VMDE->width) / float(VMDE->height), 0.1f, 1000.0f);
		view = glm::lookAt(glm::vec3(0.0, 2.6, 0.0), glm::vec3(0.0, 0.0, 0.0), glm::vec3(0.0, 1.0, 0.0));

		// GL settings initialize
		glFrontFace(GL_CCW);
		glEnable(GL_CULL_FACE);

		glEnable(GL_DEPTH_TEST);
		glDepthFunc(GL_LEQUAL);

		glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
		glDepthRange(0.0f, 1.0f);
		glClearDepth(1.0f);
		glDepthMask(GL_TRUE);

		block_pointer = new Cube(1);
		// Set up hand block indicator's matrix
		glm::mat4 block_display = glm::translate(glm::mat4(1.0), glm::vec3(0.02, 0.06, 0.2));
		block_display = glm::scale(block_display, glm::vec3(0.1f));
		block_display = glm::rotate(block_display, Util::PIf / 4.0f, glm::vec3(1.0, 0.0, 0.0));
		block_display = glm::rotate(block_display, Util::PIf / 4.0f, glm::vec3(0.0, 1.0, 0.0));
		for (int i = 0; i < 16; i++) {
			clist[i] = new Cube(i);
			clist[i]->mat[0] = block_display;
			clist[i]->update_instance(1);
		}
		axe = new Axis();
		trex = new TextRenderer();
		map = new TiledMap(16, 16, 16, glm::vec3(0.0));
		block_pointer->obj->data.mat_c = 1;
		glfwSetKeyCallback(window, key_callback);

		loop();
		terminate();
	}

	void terminate() {
		log("starting to terminate");
		terminate_engine();
		VMDE_Dispose(tile_texture);
		VMDE_Dispose(block_pointer);
		for (int i = 0; i < 16; i++) VMDE_Dispose(clist[i]);
		VMDE_Dispose(map);
		log("terminated successfully");
	}
}

int main() {
	log("Hello! This is VM76. Nice to meet you!");
	VM76::start_game();
}
<|endoftext|>


<commit_before>#include "shader.hpp"
#include "trajectory.hpp"

#define LOGURU_WITH_STREAMS 1
#include "loguru.hpp"

namespace sgl
{

TrajectorySegment::TrajectorySegment(
    ShaderProgram* shdr,
    const sim::SimulationBufferSegment& sim_buf ) :
      shader_program( shdr ),
      draw_type( GL_LINE_STRIP ),
      //draw_type( GL_TRIANGLES ),
      draw_start( 0 )
{
  GLfloat *vertex_buf = (GLfloat*) sim_buf.buffer_ptr( num_points );
  time_stamps = sim_buf.copy_of_time_stamps();
  // events = sim_buf.copy_of_events();  XXXXX DEBUGGING

  glGenVertexArrays( 1, &vao );
  glBindVertexArray( vao );

  glGenBuffers( 1, &vbo );
  glBindBuffer( GL_ARRAY_BUFFER, vbo );

  glBufferData( GL_ARRAY_BUFFER,
                sizeof(GLfloat) * 3 * num_points ,
                vertex_buf,
                GL_DYNAMIC_DRAW );

  glEnableVertexAttribArray( shader_program->get_attrib_loc( "vert" ) );
  glVertexAttribPointer(
    shader_program->get_attrib_loc( "vert" ),
    3,
    GL_FLOAT,
    GL_FALSE,
    0, //3 * sizeof( GLfloat ),
    NULL);

  glBindBuffer(GL_ARRAY_BUFFER, 0); // unbind
  glBindVertexArray( 0 );
}

TrajectorySegment::~TrajectorySegment()
{
  glDeleteBuffers( 1, &vbo );
  // "silently ignores 0's and names that do not correspond to existing buffer objects."
}

void
TrajectorySegment::render()
{
  draw_start = 0;
  draw_count = 3 * num_points;
  // make draw_start, draw_count settable based on where in the sim we want to be

  DLOG_S(INFO) << "Rendering!";

  glBindVertexArray( vao );
  glDrawArrays( draw_type, draw_start, draw_count );
  glBindVertexArray( 0 );
}

bool
Trajectory::copy_simulation_buffer( const sim::SimulationBuffer& sb )
{
  bool copy_happened = false;
  int i = segments.size();
  for( auto& buf_segment : sb )
  {
    if( i > 0 ) { i--; continue; } // Already copied these
    segments.push_back( TrajectorySegment( shader_program, buf_segment ) );
    copy_happened = true;
  }
  return copy_happened;
}

void
Trajectory::render()
{
  for( auto& segment : segments ) segment.render();
  DLOG_S(INFO) << "Rendering!";
}

} // namespace sgl<commit_msg>bugfix: putting back event copying<commit_after>#include "shader.hpp"
#include "trajectory.hpp"

#define LOGURU_WITH_STREAMS 1
#include "loguru.hpp"

namespace sgl
{

TrajectorySegment::TrajectorySegment(
    ShaderProgram* shdr,
    const sim::SimulationBufferSegment& sim_buf ) :
      shader_program( shdr ),
      draw_type( GL_LINE_STRIP ),
      //draw_type( GL_TRIANGLES ),
      draw_start( 0 )
{
  GLfloat *vertex_buf = (GLfloat*) sim_buf.buffer_ptr( num_points );
  time_stamps = sim_buf.copy_of_time_stamps();
  events = sim_buf.copy_of_events();

  glGenVertexArrays( 1, &vao );
  glBindVertexArray( vao );

  glGenBuffers( 1, &vbo );
  glBindBuffer( GL_ARRAY_BUFFER, vbo );

  glBufferData( GL_ARRAY_BUFFER,
                sizeof(GLfloat) * 3 * num_points ,
                vertex_buf,
                GL_DYNAMIC_DRAW );

  glEnableVertexAttribArray( shader_program->get_attrib_loc( "vert" ) );
  glVertexAttribPointer(
    shader_program->get_attrib_loc( "vert" ),
    3,
    GL_FLOAT,
    GL_FALSE,
    0, //3 * sizeof( GLfloat ),
    NULL);

  glBindBuffer(GL_ARRAY_BUFFER, 0); // unbind
  glBindVertexArray( 0 );
}

TrajectorySegment::~TrajectorySegment()
{
  glDeleteBuffers( 1, &vbo );
  // "silently ignores 0's and names that do not correspond to existing buffer objects."
}

void
TrajectorySegment::render()
{
  draw_start = 0;
  draw_count = 3 * num_points;
  // make draw_start, draw_count settable based on where in the sim we want to be

  DLOG_S(INFO) << "Rendering!";

  glBindVertexArray( vao );
  glDrawArrays( draw_type, draw_start, draw_count );
  glBindVertexArray( 0 );
}

bool
Trajectory::copy_simulation_buffer( const sim::SimulationBuffer& sb )
{
  bool copy_happened = false;
  int i = segments.size();
  for( auto& buf_segment : sb )
  {
    if( i > 0 ) { i--; continue; } // Already copied these
    segments.push_back( TrajectorySegment( shader_program, buf_segment ) );
    copy_happened = true;
  }
  return copy_happened;
}

void
Trajectory::render()
{
  for( auto& segment : segments ) segment.render();
  DLOG_S(INFO) << "Rendering!";
}

} // namespace sgl<|endoftext|>


<commit_before>/**************************************************************************************/
/*                                                                                */
/*  Visualization Library                                                             */
/*  http://www.visualizationlibrary.com                                               */
/*                                                                                */
/*  Copyright (c) 2005-2010, Michele Bosi                                             */
/*  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 <vlWin32/Win32Context.hpp>
#include <vlCore/Log.hpp>

using namespace vl;
using namespace vlWin32;

//-----------------------------------------------------------------------------
Win32Context::~Win32Context()
{
  dispatchDestroyEvent();
  destroyAllFBORenderTargets();
}
//-----------------------------------------------------------------------------
void Win32Context::shareOpenGLResources(HGLRC hGLRC)
{
  if (hwnd() && mHDC && mHGLRC)
    wglShareLists(hglrc(), hGLRC);
}
//-----------------------------------------------------------------------------
void Win32Context::makeCurrent()
{
  if (mHDC && mHGLRC)
    wglMakeCurrent(mHDC, mHGLRC);
}
//-----------------------------------------------------------------------------
void Win32Context::update()
{
  if (hwnd())
    PostMessage(hwnd(), WM_PAINT, 0, 0);
}
//-----------------------------------------------------------------------------
void Win32Context::quitApplication()
{
  PostQuitMessage(0);
  eraseAllEventListeners();
}
//-----------------------------------------------------------------------------
void Win32Context::setMouseVisible(bool visible)
{
  mMouseVisible = visible;
  if (visible)
    while(ShowCursor(TRUE ) <  0) {}
  else
    while(ShowCursor(FALSE) >= 0) {}
}
//-----------------------------------------------------------------------------
void Win32Context::setPosition(int x, int y)
{
  if (hwnd())
	  SetWindowPos(hwnd(), 0, x, y, 0, 0, SWP_NOSIZE );
}
//-----------------------------------------------------------------------------
void Win32Context::setSize(int w, int h)
{
  if (hwnd())
  {
    RECT windowRect = { 0, 0, w, h };
    AdjustWindowRectEx(&windowRect, (DWORD)GetWindowLongPtr(hwnd(), GWL_STYLE), 0, (DWORD)GetWindowLongPtr(hwnd(), GWL_EXSTYLE) );
    // computes the actual window based on the client dimensions
    int cx = windowRect.right  - windowRect.left;
    int cy = windowRect.bottom - windowRect.top;
    SetWindowPos(hwnd(), 0, 0, 0, cx, cy, SWP_NOMOVE );
  }
}
//-----------------------------------------------------------------------------
void Win32Context::setWindowSize(int w, int h)
{
  // this are set by WM_SIZE event handler
  // mRenderTarget->setWidth(w);
  // mRenderTarget->setHeight(h);
	SetWindowPos(hwnd(), 0, 0, 0, w, h, SWP_NOMOVE);
}
//-----------------------------------------------------------------------------
vl::ivec2 Win32Context::position() const
{
  RECT r = {0,0,0,0};
  if (hwnd())
	  GetWindowRect(hwnd(), &r);
  return vl::ivec2(r.left,r.top);
}
//-----------------------------------------------------------------------------
vl::ivec2 Win32Context::windowSize() const
{
  RECT r = {0,0,0,0};
  if (hwnd())
	  GetWindowRect(hwnd(), &r);
  return vl::ivec2(r.right - r.left, r.bottom - r.top);
}
//-----------------------------------------------------------------------------
vl::ivec2 Win32Context::size() const
{
  RECT r = {0,0,0,0};
  if (hwnd())
	  GetClientRect(hwnd(), &r);
  return vl::ivec2(r.right - r.left, r.bottom - r.top);
//  return vl::ivec2(width(), height());
}
//-----------------------------------------------------------------------------
void Win32Context::setWindowTitle(const String& title)
{
  if (hwnd())
    SetWindowText(hwnd(), (wchar_t*)title.ptr());
}
//-----------------------------------------------------------------------------
void Win32Context::show()
{
  if (hwnd())
    ShowWindow(hwnd(), SW_SHOW);
}
//-----------------------------------------------------------------------------
void Win32Context::hide()
{
  if (hwnd())
    ShowWindow(hwnd(), SW_HIDE);
}
//-----------------------------------------------------------------------------
void Win32Context::getFocus()
{
  if (hwnd())
    SetFocus(hwnd());
}
//-----------------------------------------------------------------------------
void Win32Context::setMousePosition(int x, int y)
{
  if (hwnd())
  {
    POINT pt = {x, y};
    ClientToScreen( hwnd(), &pt );
    SetCursorPos(pt.x, pt.y);
  }
}
//-----------------------------------------------------------------------------
void Win32Context::swapBuffers()
{
  if(hwnd() && hdc())
    SwapBuffers(hdc());
}
//-----------------------------------------------------------------------------
bool Win32Context::setFullscreen(bool fullscreen_on)
{
  if (!hwnd())
    return false;

  if (fullscreen_on == fullscreen())
    return true;

  if (!fullscreen_on)
  {
    SetWindowLongPtr(hwnd(), GWL_STYLE, mNormFlags/*swl_style*/);

    if (!((mNormFlags & WS_MAXIMIZE) || (mNormFlags & WS_MINIMIZE)))
    {
      setPosition(mNormPosit.x(),mNormPosit.y());
      setSize(mNormSize.x(), mNormSize.y());
    }

    SetWindowPos(hwnd(), 0, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOSIZE | SWP_NOMOVE);

    // restores display settings
    ChangeDisplaySettings(NULL, 0);
  }
  else
  {
    DEVMODE devmode;
    EnumDisplaySettings(NULL,ENUM_CURRENT_SETTINGS,&devmode);

    // devmode.dmPelsWidth  = ... leave current width
    // devmode.dmPelsHeight = ... leave current height
    // change color depth
    devmode.dmBitsPerPel = openglContextInfo().bitsPerPixel();
	  devmode.dmFields		 |= DM_BITSPERPEL;

    mNormFlags = (unsigned int)GetWindowLongPtr(hwnd(), GWL_STYLE);
    mNormPosit = position();
    mNormSize  = size();

    switch( ChangeDisplaySettings(&devmode, CDS_FULLSCREEN) )
    {
      case DISP_CHANGE_SUCCESSFUL:
      {
        RECT windowRect = { 0, 0, devmode.dmPelsWidth, devmode.dmPelsHeight };
        /*mStyle = */SetWindowLongPtr(hwnd(), GWL_STYLE, WS_POPUP | WS_VISIBLE );
        AdjustWindowRectEx(&windowRect, (DWORD)GetWindowLongPtr(hwnd(), GWL_STYLE), 0, (DWORD)GetWindowLongPtr(hwnd(), GWL_EXSTYLE) );
        SetWindowPos(hwnd(), HWND_TOP, windowRect.left, windowRect.top, windowRect.right - windowRect.left, windowRect.bottom - windowRect.top, SWP_FRAMECHANGED );
        break;
      }
      #if(_WIN32_WINNT >= 0x0501)
        case DISP_CHANGE_BADDUALVIEW:
          MessageBox(NULL, L"Full-screen mode switch failed: DISP_CHANGE_BADDUALVIEW", L"Visualization Library Error", MB_OK | MB_ICONEXCLAMATION);
          return false;
      #endif
      case DISP_CHANGE_BADFLAGS:
        MessageBox(NULL, L"Full-screen mode switch failed: DISP_CHANGE_BADFLAGS", L"Visualization Library Error", MB_OK | MB_ICONEXCLAMATION);
        return false;
      case DISP_CHANGE_BADMODE:
        MessageBox(NULL, L"Full-screen mode switch failed: DISP_CHANGE_BADMODE", L"Visualization Library Error", MB_OK | MB_ICONEXCLAMATION);
        return false;
      case DISP_CHANGE_BADPARAM:
        MessageBox(NULL, L"Full-screen mode switch failed: DISP_CHANGE_BADPARAM", L"Visualization Library Error", MB_OK | MB_ICONEXCLAMATION);
        return false;
      case DISP_CHANGE_FAILED:
        MessageBox(NULL, L"Full-screen mode switch failed: DISP_CHANGE_FAILED", L"Visualization Library Error", MB_OK | MB_ICONEXCLAMATION);
        return false;
      case DISP_CHANGE_NOTUPDATED:
        MessageBox(NULL, L"Full-screen mode switch failed: DISP_CHANGE_NOTUPDATED", L"Visualization Library Error", MB_OK | MB_ICONEXCLAMATION);
        return false;
      case DISP_CHANGE_RESTART:
        MessageBox(NULL, L"Full-screen mode switch failed: DISP_CHANGE_RESTART", L"Visualization Library Error", MB_OK | MB_ICONEXCLAMATION);
        return false;
      default:
        return false;
    }
  }

  mFullscreen = fullscreen_on;
  update();
  return true;
}
//-----------------------------------------------------------------------------
bool Win32Context::init(HGLRC share_context, const vl::String& title, const vl::OpenGLContextFormat& fmt, int x, int y, int width, int height)
{
  renderTarget()->setWidth(width);
  renderTarget()->setHeight(height);

  if (!hwnd())
  {
    MessageBox(NULL, L"Cannot create OpenGL context: null HWND.", L"Visualization Library Error", MB_OK);
    destroy();
    return false;
  }

  setWindowTitle(title);

  if (mHDC)
    DeleteDC(mHDC);
  mHDC = ::GetDC(hwnd());
  if (!mHDC)
  {
    MessageBox(NULL, L"Device context acquisition failed.", L"Visualization Library Error", MB_OK);
    destroy();
    return false;
  }

  int pixel_format_index = vlWin32::choosePixelFormat(fmt);
  if (pixel_format_index == -1)
  {
    MessageBox(NULL, L"No suitable pixel fmt found.", L"Visualization Library Error", MB_OK);
    destroy();
    return false;
  }

  if (SetPixelFormat(mHDC, pixel_format_index, NULL) == FALSE)
  {
    MessageBox(NULL, L"Pixel fmt setup failed.", L"Visualization Library Error", MB_OK);
    destroy();
    return false;
  }

  // OpenGL rendering context creation

  if (mHGLRC)
  {
    if ( wglDeleteContext(mHGLRC) == FALSE )
    {
      MessageBox(NULL, L"OpenGL context creation failed.\n"
       L"The handle either doesn't specify a valid context or the context is being used by another thread.", L"Visualization Library Error", MB_OK);
    }
    mHGLRC = NULL;
  }

  if (wglCreateContextAttribsARB && mContextAttribs.size() > 1)
  {
    // must be 0-terminated list
    VL_CHECK(mContextAttribs.back() == 0);
    // Creates an OpenGL 3.x / 4.x context with the specified attributes.
    mHGLRC = wglCreateContextAttribsARB(mHDC, 0, &mContextAttribs[0]);
  }
  else
  {
    // Creates default OpenGL context
    mHGLRC = wglCreateContext(mHDC);
  }

  if (!mHGLRC)
  {
    MessageBox(NULL, L"OpenGL rendering context creation failed.", L"Visualization Library Error", MB_OK);
    destroy();
    return false;
  }
  wglMakeCurrent(mHDC, mHGLRC);
  initGLContext();

  if (fmt.multisample() && !WGLEW_ARB_multisample)
    vl::Log::error("WGL_ARB_multisample not supported.\n");

  dispatchInitEvent();

  setPosition(x, y);
  setSize(width, height);

  if (WGLEW_EXT_swap_control)
    wglSwapIntervalEXT( fmt.vSync() ? 1 : 0 );

  if (share_context)
    shareOpenGLResources(share_context);

  if (fmt.fullscreen())
    setFullscreen(true);

  return true;
}
//-----------------------------------------------------------------------------
void Win32Context::setContextAttribs(const int* attribs)
{
  mContextAttribs.clear();
  for( ; *attribs; ++attribs )
    mContextAttribs.push_back(*attribs);
  mContextAttribs.push_back(0);
}
//-----------------------------------------------------------------------------
<commit_msg>contract based cleanup in Win32Context::init() and better error messages.<commit_after>/**************************************************************************************/
/*                                                                                */
/*  Visualization Library                                                             */
/*  http://www.visualizationlibrary.com                                               */
/*                                                                                */
/*  Copyright (c) 2005-2010, Michele Bosi                                             */
/*  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 <vlWin32/Win32Context.hpp>
#include <vlCore/Log.hpp>

using namespace vl;
using namespace vlWin32;

//-----------------------------------------------------------------------------
Win32Context::~Win32Context()
{
}
//-----------------------------------------------------------------------------
void Win32Context::shareOpenGLResources(HGLRC hGLRC)
{
  if (hwnd() && mHDC && mHGLRC)
    wglShareLists(hglrc(), hGLRC);
}
//-----------------------------------------------------------------------------
void Win32Context::makeCurrent()
{
  if (mHDC && mHGLRC)
    wglMakeCurrent(mHDC, mHGLRC);
}
//-----------------------------------------------------------------------------
void Win32Context::update()
{
  if (hwnd())
    PostMessage(hwnd(), WM_PAINT, 0, 0);
}
//-----------------------------------------------------------------------------
void Win32Context::quitApplication()
{
  PostQuitMessage(0);
  eraseAllEventListeners();
}
//-----------------------------------------------------------------------------
void Win32Context::setMouseVisible(bool visible)
{
  mMouseVisible = visible;
  if (visible)
    while(ShowCursor(TRUE ) <  0) {}
  else
    while(ShowCursor(FALSE) >= 0) {}
}
//-----------------------------------------------------------------------------
void Win32Context::setPosition(int x, int y)
{
  if (hwnd())
	  SetWindowPos(hwnd(), 0, x, y, 0, 0, SWP_NOSIZE );
}
//-----------------------------------------------------------------------------
void Win32Context::setSize(int w, int h)
{
  if (hwnd())
  {
    RECT windowRect = { 0, 0, w, h };
    AdjustWindowRectEx(&windowRect, (DWORD)GetWindowLongPtr(hwnd(), GWL_STYLE), 0, (DWORD)GetWindowLongPtr(hwnd(), GWL_EXSTYLE) );
    // computes the actual window based on the client dimensions
    int cx = windowRect.right  - windowRect.left;
    int cy = windowRect.bottom - windowRect.top;
    SetWindowPos(hwnd(), 0, 0, 0, cx, cy, SWP_NOMOVE );
  }
}
//-----------------------------------------------------------------------------
void Win32Context::setWindowSize(int w, int h)
{
  // this are set by WM_SIZE event handler
  // mRenderTarget->setWidth(w);
  // mRenderTarget->setHeight(h);
	SetWindowPos(hwnd(), 0, 0, 0, w, h, SWP_NOMOVE);
}
//-----------------------------------------------------------------------------
vl::ivec2 Win32Context::position() const
{
  RECT r = {0,0,0,0};
  if (hwnd())
	  GetWindowRect(hwnd(), &r);
  return vl::ivec2(r.left,r.top);
}
//-----------------------------------------------------------------------------
vl::ivec2 Win32Context::windowSize() const
{
  RECT r = {0,0,0,0};
  if (hwnd())
	  GetWindowRect(hwnd(), &r);
  return vl::ivec2(r.right - r.left, r.bottom - r.top);
}
//-----------------------------------------------------------------------------
vl::ivec2 Win32Context::size() const
{
  RECT r = {0,0,0,0};
  if (hwnd())
	  GetClientRect(hwnd(), &r);
  return vl::ivec2(r.right - r.left, r.bottom - r.top);
//  return vl::ivec2(width(), height());
}
//-----------------------------------------------------------------------------
void Win32Context::setWindowTitle(const String& title)
{
  if (hwnd())
    SetWindowText(hwnd(), (wchar_t*)title.ptr());
}
//-----------------------------------------------------------------------------
void Win32Context::show()
{
  if (hwnd())
    ShowWindow(hwnd(), SW_SHOW);
}
//-----------------------------------------------------------------------------
void Win32Context::hide()
{
  if (hwnd())
    ShowWindow(hwnd(), SW_HIDE);
}
//-----------------------------------------------------------------------------
void Win32Context::getFocus()
{
  if (hwnd())
    SetFocus(hwnd());
}
//-----------------------------------------------------------------------------
void Win32Context::setMousePosition(int x, int y)
{
  if (hwnd())
  {
    POINT pt = {x, y};
    ClientToScreen( hwnd(), &pt );
    SetCursorPos(pt.x, pt.y);
  }
}
//-----------------------------------------------------------------------------
void Win32Context::swapBuffers()
{
  if(hwnd() && hdc())
    SwapBuffers(hdc());
}
//-----------------------------------------------------------------------------
bool Win32Context::setFullscreen(bool fullscreen_on)
{
  if (!hwnd())
    return false;

  if (fullscreen_on == fullscreen())
    return true;

  if (!fullscreen_on)
  {
    SetWindowLongPtr(hwnd(), GWL_STYLE, mNormFlags/*swl_style*/);

    if (!((mNormFlags & WS_MAXIMIZE) || (mNormFlags & WS_MINIMIZE)))
    {
      setPosition(mNormPosit.x(),mNormPosit.y());
      setSize(mNormSize.x(), mNormSize.y());
    }

    SetWindowPos(hwnd(), 0, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOSIZE | SWP_NOMOVE);

    // restores display settings
    ChangeDisplaySettings(NULL, 0);
  }
  else
  {
    DEVMODE devmode;
    EnumDisplaySettings(NULL,ENUM_CURRENT_SETTINGS,&devmode);

    // devmode.dmPelsWidth  = ... leave current width
    // devmode.dmPelsHeight = ... leave current height
    // change color depth
    devmode.dmBitsPerPel = openglContextInfo().bitsPerPixel();
	  devmode.dmFields		 |= DM_BITSPERPEL;

    mNormFlags = (unsigned int)GetWindowLongPtr(hwnd(), GWL_STYLE);
    mNormPosit = position();
    mNormSize  = size();

    switch( ChangeDisplaySettings(&devmode, CDS_FULLSCREEN) )
    {
      case DISP_CHANGE_SUCCESSFUL:
      {
        RECT windowRect = { 0, 0, devmode.dmPelsWidth, devmode.dmPelsHeight };
        /*mStyle = */SetWindowLongPtr(hwnd(), GWL_STYLE, WS_POPUP | WS_VISIBLE );
        AdjustWindowRectEx(&windowRect, (DWORD)GetWindowLongPtr(hwnd(), GWL_STYLE), 0, (DWORD)GetWindowLongPtr(hwnd(), GWL_EXSTYLE) );
        SetWindowPos(hwnd(), HWND_TOP, windowRect.left, windowRect.top, windowRect.right - windowRect.left, windowRect.bottom - windowRect.top, SWP_FRAMECHANGED );
        break;
      }
      #if(_WIN32_WINNT >= 0x0501)
        case DISP_CHANGE_BADDUALVIEW:
          MessageBox(NULL, L"Full-screen mode switch failed: DISP_CHANGE_BADDUALVIEW", L"Win32Context::setFullscreen() error!", MB_OK | MB_ICONEXCLAMATION);
          return false;
      #endif
      case DISP_CHANGE_BADFLAGS:
        MessageBox(NULL, L"Full-screen mode switch failed: DISP_CHANGE_BADFLAGS", L"Win32Context::setFullscreen() error!", MB_OK | MB_ICONEXCLAMATION);
        return false;
      case DISP_CHANGE_BADMODE:
        MessageBox(NULL, L"Full-screen mode switch failed: DISP_CHANGE_BADMODE", L"Win32Context::setFullscreen() error!", MB_OK | MB_ICONEXCLAMATION);
        return false;
      case DISP_CHANGE_BADPARAM:
        MessageBox(NULL, L"Full-screen mode switch failed: DISP_CHANGE_BADPARAM", L"Win32Context::setFullscreen() error!", MB_OK | MB_ICONEXCLAMATION);
        return false;
      case DISP_CHANGE_FAILED:
        MessageBox(NULL, L"Full-screen mode switch failed: DISP_CHANGE_FAILED", L"Win32Context::setFullscreen() error!", MB_OK | MB_ICONEXCLAMATION);
        return false;
      case DISP_CHANGE_NOTUPDATED:
        MessageBox(NULL, L"Full-screen mode switch failed: DISP_CHANGE_NOTUPDATED", L"Win32Context::setFullscreen() error!", MB_OK | MB_ICONEXCLAMATION);
        return false;
      case DISP_CHANGE_RESTART:
        MessageBox(NULL, L"Full-screen mode switch failed: DISP_CHANGE_RESTART", L"Win32Context::setFullscreen() error!", MB_OK | MB_ICONEXCLAMATION);
        return false;
      default:
        return false;
    }
  }

  mFullscreen = fullscreen_on;
  update();
  return true;
}
//-----------------------------------------------------------------------------
bool Win32Context::init(HGLRC share_context, const vl::String& title, const vl::OpenGLContextFormat& fmt, int x, int y, int width, int height)
{
  struct Contract
  {
    bool ok;
    Win32Context* ctx;

    Contract(Win32Context* context): ok(true), ctx(context)
    {
      cleanup();
    }

    ~Contract()
    {
      if (!ok)
        cleanup();
    }

    void cleanup()
    {
      // delete HDC
      if (ctx->mHDC)
      {
        DeleteDC(ctx->mHDC);
        ctx->mHDC = NULL;
      }

      // delete HGLRC
      if (ctx->mHGLRC)
      {
        if ( wglDeleteContext(ctx->mHGLRC) == FALSE )
        {
          MessageBox(NULL, L"OpenGL context cleanup failed.\n"
           L"The handle either doesn't specify a valid context or the context is being used by another thread.",
           L"Win32Context::init() error!", MB_OK);
          ok = false;
        }
        ctx->mHGLRC = NULL;
      }
    }
  } contract(this);

  if (!contract.ok)
    return false;

  renderTarget()->setWidth(width);
  renderTarget()->setHeight(height);

  if (!hwnd())
  {
    MessageBox(NULL, L"Cannot create OpenGL context: null HWND.", L"Win32Context::init() error!", MB_OK);
    return contract.ok = false;
  }

  setWindowTitle(title);

  VL_CHECK(mHDC == NULL);
  mHDC = ::GetDC(hwnd());
  if (!mHDC)
  {
    MessageBox(NULL, L"Device context acquisition failed.", L"Win32Context::init() error!", MB_OK);
    return contract.ok = false;
  }

  int pixel_format_index = vlWin32::choosePixelFormat(fmt);
  if (pixel_format_index == -1)
  {
    MessageBox(NULL, L"No suitable pixel fmt found.", L"Win32Context::init() error!", MB_OK);
    return contract.ok = false;
  }

  if (SetPixelFormat(mHDC, pixel_format_index, NULL) == FALSE)
  {
    MessageBox(NULL, L"Pixel fmt setup failed.", L"Win32Context::init() error!", MB_OK);
    return contract.ok = false;
  }

  // OpenGL rendering context creation

  if (wglCreateContextAttribsARB && mContextAttribs.size() > 1)
  {
    // must be 0-terminated list
    VL_CHECK(mContextAttribs.back() == 0);
    // Creates an OpenGL 3.x / 4.x context with the specified attributes.
    mHGLRC = wglCreateContextAttribsARB(mHDC, 0, &mContextAttribs[0]);
  }
  else
  {
    // Creates default OpenGL context
    mHGLRC = wglCreateContext(mHDC);
  }

  if (!mHGLRC)
  {
    MessageBox(NULL, L"OpenGL rendering context creation failed.", L"Win32Context::init() error!", MB_OK);
    return contract.ok = false;
  }

  // init GL context and makes it current
  initGLContext();

  if (fmt.multisample() && !WGLEW_ARB_multisample)
    vl::Log::error("WGL_ARB_multisample not supported.\n");

  dispatchInitEvent();

  setPosition(x, y);

  setSize(width, height);

  if (WGLEW_EXT_swap_control)
    wglSwapIntervalEXT( fmt.vSync() ? 1 : 0 );

  if (share_context)
    shareOpenGLResources(share_context);

  if (fmt.fullscreen())
    setFullscreen(true);

  return contract.ok = true;
}
//-----------------------------------------------------------------------------
void Win32Context::setContextAttribs(const int* attribs)
{
  mContextAttribs.clear();
  for( ; *attribs; ++attribs )
    mContextAttribs.push_back(*attribs);
  mContextAttribs.push_back(0);
}
//-----------------------------------------------------------------------------
<|endoftext|>


<commit_before>#include "WebSocket.hpp"

WebSocket::WebSocket(int server, struct sockaddr_in *server_addr, int client, struct sockaddr_in *client_addr)
{
	m_server = server;
	m_client = client;

	m_server_addr = server_addr;
	m_client_addr = client_addr;

	char request[65535];
	int request_length = 0;

	memset(request, 0, sizeof(request));

	request_length = read(m_client, request, sizeof(request));

	if(0 >= request_length)
	{
		Debug::Warn("Request with no data ignored.");
		return;
	}

	Request *req = new Request(request);

	m_host = req->GetHeader("Host");
	m_origin = req->GetHeader("Origin");
	m_protocol = req->GetHeader("Sec-WebSocket-Protocol");
	m_key = req->GetHeader("Sec-WebSocket-Key");
	m_accept = AcceptKey();

	Debug::Info(sizeof(Frame));

	Debug::Info("Handshake received.");
}

WebSocket::~WebSocket()
{
}

std::string WebSocket::AcceptKey()
{

	return AcceptKey(m_key);
}

std::string WebSocket::AcceptKey(std::string key)
{
	if(key.empty())
		key = m_key;

	std::string result = "";

	if(key.empty())
		return result;

	key += "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";							//RFC6544_MAGIC_KEY

	unsigned char digest[20];												// 160-bit SHA1 digest
	SHA1 sha;

	sha.Input(key.data(), key.size());
	sha.Result((unsigned *) digest);

	// Little to Big Endian
	for(unsigned int i = 0; i < sizeof(digest); i += 4)
	{
		digest[i]		^= digest[i + 3];
		digest[i + 3]	^= digest[i];
		digest[i]		^= digest[i + 3];

		digest[i + 1]	^= digest[i + 2];
		digest[i + 2]	^= digest[i + 1];
		digest[i + 1]	^= digest[i + 2];
	}

	result = base64_encode((const unsigned char *) digest, sizeof(digest));

	return result;
}

void WebSocket::Handshake()
{
	std::string content = "";

	content += "HTTP/1.1 101 Switching Protocols\r\n";
	content += "Upgrade: WebSocket\r\n";
	content += "Connection: Upgrade\r\n";

	if(0 < m_key.length())
		content += "Sec-WebSocket-Accept: " + m_accept + "\r\n";

	if(0 < m_protocol.length())
		content += "Sec-WebSocket-Protocol: " + m_protocol + "\r\n";

	content += "\r\n";

	Response *res = new Response(content.c_str());

	write(m_client, res->ToString().c_str(), res->Length());

	Debug::Info("Handshake accepted.");
}

void WebSocket::Listen()
{
	int in = 0;
	int max = 65535;
	char buffer[max];

	while((in = recv(m_client, &buffer, max , 0)))
	{
		std::string message(buffer);
		Process(message);
	}
}

void WebSocket::Process(std::string message)
{
	std::cout << message << std::endl << std::endl;
}<commit_msg>Check if spaces will fix tab issue on alignments.<commit_after>#include "WebSocket.hpp"

WebSocket::WebSocket(int server, struct sockaddr_in *server_addr, int client, struct sockaddr_in *client_addr)
{
	m_server = server;
	m_client = client;

	m_server_addr = server_addr;
	m_client_addr = client_addr;

	char request[65535];
	int request_length = 0;

	memset(request, 0, sizeof(request));

	request_length = read(m_client, request, sizeof(request));

	if(0 >= request_length)
	{
		Debug::Warn("Request with no data ignored.");
		return;
	}

	Request *req = new Request(request);

	m_host = req->GetHeader("Host");
	m_origin = req->GetHeader("Origin");
	m_protocol = req->GetHeader("Sec-WebSocket-Protocol");
	m_key = req->GetHeader("Sec-WebSocket-Key");
	m_accept = AcceptKey();

	Debug::Info(sizeof(Frame));

	Debug::Info("Handshake received.");
}

WebSocket::~WebSocket()
{
}

std::string WebSocket::AcceptKey()
{

	return AcceptKey(m_key);
}

std::string WebSocket::AcceptKey(std::string key)
{
	if(key.empty())
		key = m_key;

	std::string result = "";

	if(key.empty())
		return result;

	key += "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";                          //RFC6544_MAGIC_KEY

	unsigned char digest[20];                                               // 160-bit SHA1 hash
	SHA1 sha;

	sha.Input(key.data(), key.size());
	sha.Result((unsigned *) digest);

	// Little to Big Endian
	for(unsigned int i = 0; i < sizeof(digest); i += 4)
	{
		digest[i]		^= digest[i + 3];
		digest[i + 3]	^= digest[i];
		digest[i]		^= digest[i + 3];

		digest[i + 1]	^= digest[i + 2];
		digest[i + 2]	^= digest[i + 1];
		digest[i + 1]	^= digest[i + 2];
	}

	result = base64_encode((const unsigned char *) digest, sizeof(digest));

	return result;
}

void WebSocket::Handshake()
{
	std::string content = "";

	content += "HTTP/1.1 101 Switching Protocols\r\n";
	content += "Upgrade: WebSocket\r\n";
	content += "Connection: Upgrade\r\n";

	if(0 < m_key.length())
		content += "Sec-WebSocket-Accept: " + m_accept + "\r\n";

	if(0 < m_protocol.length())
		content += "Sec-WebSocket-Protocol: " + m_protocol + "\r\n";

	content += "\r\n";

	Response *res = new Response(content.c_str());

	write(m_client, res->ToString().c_str(), res->Length());

	Debug::Info("Handshake accepted.");
}

void WebSocket::Listen()
{
	int in = 0;
	int max = 65535;
	char buffer[max];

	while((in = recv(m_client, &buffer, max , 0)))
	{
		std::string message(buffer);
		Process(message);
	}
}

void WebSocket::Process(std::string message)
{
	std::cout << message << std::endl << std::endl;
}<|endoftext|>


<commit_before>/****************************************************************************
 *
 *   (c) 2009-2016 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
 *
 * QGroundControl is licensed according to the terms in the file
 * COPYING.md in the root of the source code directory.
 *
 ****************************************************************************/

#include "APMAutoPilotPlugin.h"
#include "UAS.h"
#include "FirmwarePlugin/APM/APMParameterMetaData.h"  // FIXME: Hack
#include "FirmwarePlugin/APM/APMFirmwarePlugin.h"  // FIXME: Hack
#include "FirmwarePlugin/APM/ArduCopterFirmwarePlugin.h"
#include "VehicleComponent.h"
#include "APMAirframeComponent.h"
#include "APMAirframeComponentAirframes.h"
#include "APMAirframeLoader.h"
#include "APMFlightModesComponent.h"
#include "APMRadioComponent.h"
#include "APMSafetyComponent.h"
#include "APMTuningComponent.h"
#include "APMSensorsComponent.h"
#include "APMPowerComponent.h"
#include "MotorComponent.h"
#include "APMCameraComponent.h"
#include "APMLightsComponent.h"
#include "APMSubFrameComponent.h"
#include "ESP8266Component.h"
#include "MixersComponent.h"

/// This is the AutoPilotPlugin implementatin for the MAV_AUTOPILOT_ARDUPILOT type.
APMAutoPilotPlugin::APMAutoPilotPlugin(Vehicle* vehicle, QObject* parent)
    : AutoPilotPlugin(vehicle, parent)
    , _incorrectParameterVersion(false)
    , _airframeComponent(NULL)
    , _cameraComponent(NULL)
    , _lightsComponent(NULL)
    , _subFrameComponent(NULL)
    , _flightModesComponent(NULL)
    , _powerComponent(NULL)
#if 0
        // Temporarily removed, waiting for new command implementation
    , _motorComponent(NULL)
#endif
    , _radioComponent(NULL)
    , _safetyComponent(NULL)
    , _sensorsComponent(NULL)
    , _tuningComponent(NULL)
    , _airframeFacts(new APMAirframeLoader(this, vehicle->uas(), this))
    , _esp8266Component(NULL)
    , _mixersComponent(NULL)
{
    APMAirframeLoader::loadAirframeFactMetaData();
}

APMAutoPilotPlugin::~APMAutoPilotPlugin()
{

}

const QVariantList& APMAutoPilotPlugin::vehicleComponents(void)
{
    if (_components.count() == 0 && !_incorrectParameterVersion) {
        if (_vehicle->parameterManager()->parametersReady()) {
            _airframeComponent = new APMAirframeComponent(_vehicle, this);
            _airframeComponent->setupTriggerSignals();
            _components.append(QVariant::fromValue((VehicleComponent*)_airframeComponent));

            if ( _vehicle->supportsRadio() ) {
                _radioComponent = new APMRadioComponent(_vehicle, this);
                _radioComponent->setupTriggerSignals();
                _components.append(QVariant::fromValue((VehicleComponent*)_radioComponent));
            }

            _flightModesComponent = new APMFlightModesComponent(_vehicle, this);
            _flightModesComponent->setupTriggerSignals();
            _components.append(QVariant::fromValue((VehicleComponent*)_flightModesComponent));

            _sensorsComponent = new APMSensorsComponent(_vehicle, this);
            _sensorsComponent->setupTriggerSignals();
            _components.append(QVariant::fromValue((VehicleComponent*)_sensorsComponent));

            _powerComponent = new APMPowerComponent(_vehicle, this);
            _powerComponent->setupTriggerSignals();
            _components.append(QVariant::fromValue((VehicleComponent*)_powerComponent));

#if 0
    // Temporarily removed, waiting for new command implementation

            if (_vehicle->multiRotor() || _vehicle->vtol()) {
                _motorComponent = new MotorComponent(_vehicle, this);
                _motorComponent->setupTriggerSignals();
                _components.append(QVariant::fromValue((VehicleComponent*)_motorComponent));
            }
#endif

            _safetyComponent = new APMSafetyComponent(_vehicle, this);
            _safetyComponent->setupTriggerSignals();
            _components.append(QVariant::fromValue((VehicleComponent*)_safetyComponent));

            _tuningComponent = new APMTuningComponent(_vehicle, this);
            _tuningComponent->setupTriggerSignals();
            _components.append(QVariant::fromValue((VehicleComponent*)_tuningComponent));

            _mixersComponent = new MixersComponent(_vehicle, this);
            _mixersComponent->setupTriggerSignals();
            _components.append(QVariant::fromValue((VehicleComponent*)_mixersComponent));

            _cameraComponent = new APMCameraComponent(_vehicle, this);
            _cameraComponent->setupTriggerSignals();
            _components.append(QVariant::fromValue((VehicleComponent*)_cameraComponent));

            if (_vehicle->sub()) {
                _lightsComponent = new APMLightsComponent(_vehicle, this);
                _lightsComponent->setupTriggerSignals();
                _components.append(QVariant::fromValue((VehicleComponent*)_lightsComponent));

                if(_vehicle->firmwareMajorVersion() > 3 || (_vehicle->firmwareMajorVersion() == 3 && _vehicle->firmwareMinorVersion() >= 5)) {
                    _subFrameComponent = new APMSubFrameComponent(_vehicle, this);
                    _subFrameComponent->setupTriggerSignals();
                    _components.append(QVariant::fromValue((VehicleComponent*)_subFrameComponent));
                }
            }

            //-- Is there an ESP8266 Connected?
            if(_vehicle->parameterManager()->parameterExists(MAV_COMP_ID_UDP_BRIDGE, "SW_VER")) {
                _esp8266Component = new ESP8266Component(_vehicle, this);
                _esp8266Component->setupTriggerSignals();
                _components.append(QVariant::fromValue((VehicleComponent*)_esp8266Component));
            }
        } else {
            qWarning() << "Call to vehicleCompenents prior to parametersReady";
        }
    }

    return _components;
}

QString APMAutoPilotPlugin::prerequisiteSetup(VehicleComponent* component) const
{
    bool requiresAirframeCheck = false;

    if (qobject_cast<const APMFlightModesComponent*>(component)) {
        if (_airframeComponent && !_airframeComponent->setupComplete()) {
            return _airframeComponent->name();
        }
        if (_radioComponent && !_radioComponent->setupComplete()) {
            return _radioComponent->name();
        }
        requiresAirframeCheck = true;
    } else if (qobject_cast<const APMRadioComponent*>(component)) {
        requiresAirframeCheck = true;
    } else if (qobject_cast<const APMCameraComponent*>(component)) {
        requiresAirframeCheck = true;
    } else if (qobject_cast<const APMPowerComponent*>(component)) {
        requiresAirframeCheck = true;
    } else if (qobject_cast<const APMSafetyComponent*>(component)) {
        requiresAirframeCheck = true;
    } else if (qobject_cast<const APMTuningComponent*>(component)) {
        requiresAirframeCheck = true;
    } else if (qobject_cast<const APMSensorsComponent*>(component)) {
        requiresAirframeCheck = true;
    }

    if (requiresAirframeCheck) {
        if (_airframeComponent && !_airframeComponent->setupComplete()) {
            return _airframeComponent->name();
        }
    }

    return QString();
}
<commit_msg>Remove flightmodes component for Sub 3.5+<commit_after>/****************************************************************************
 *
 *   (c) 2009-2016 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
 *
 * QGroundControl is licensed according to the terms in the file
 * COPYING.md in the root of the source code directory.
 *
 ****************************************************************************/

#include "APMAutoPilotPlugin.h"
#include "UAS.h"
#include "FirmwarePlugin/APM/APMParameterMetaData.h"  // FIXME: Hack
#include "FirmwarePlugin/APM/APMFirmwarePlugin.h"  // FIXME: Hack
#include "FirmwarePlugin/APM/ArduCopterFirmwarePlugin.h"
#include "VehicleComponent.h"
#include "APMAirframeComponent.h"
#include "APMAirframeComponentAirframes.h"
#include "APMAirframeLoader.h"
#include "APMFlightModesComponent.h"
#include "APMRadioComponent.h"
#include "APMSafetyComponent.h"
#include "APMTuningComponent.h"
#include "APMSensorsComponent.h"
#include "APMPowerComponent.h"
#include "MotorComponent.h"
#include "APMCameraComponent.h"
#include "APMLightsComponent.h"
#include "APMSubFrameComponent.h"
#include "ESP8266Component.h"
#include "MixersComponent.h"

/// This is the AutoPilotPlugin implementatin for the MAV_AUTOPILOT_ARDUPILOT type.
APMAutoPilotPlugin::APMAutoPilotPlugin(Vehicle* vehicle, QObject* parent)
    : AutoPilotPlugin(vehicle, parent)
    , _incorrectParameterVersion(false)
    , _airframeComponent(NULL)
    , _cameraComponent(NULL)
    , _lightsComponent(NULL)
    , _subFrameComponent(NULL)
    , _flightModesComponent(NULL)
    , _powerComponent(NULL)
#if 0
        // Temporarily removed, waiting for new command implementation
    , _motorComponent(NULL)
#endif
    , _radioComponent(NULL)
    , _safetyComponent(NULL)
    , _sensorsComponent(NULL)
    , _tuningComponent(NULL)
    , _airframeFacts(new APMAirframeLoader(this, vehicle->uas(), this))
    , _esp8266Component(NULL)
    , _mixersComponent(NULL)
{
    APMAirframeLoader::loadAirframeFactMetaData();
}

APMAutoPilotPlugin::~APMAutoPilotPlugin()
{

}

const QVariantList& APMAutoPilotPlugin::vehicleComponents(void)
{
    if (_components.count() == 0 && !_incorrectParameterVersion) {
        if (_vehicle->parameterManager()->parametersReady()) {
            _airframeComponent = new APMAirframeComponent(_vehicle, this);
            _airframeComponent->setupTriggerSignals();
            _components.append(QVariant::fromValue((VehicleComponent*)_airframeComponent));

            if ( _vehicle->supportsRadio() ) {
                _radioComponent = new APMRadioComponent(_vehicle, this);
                _radioComponent->setupTriggerSignals();
                _components.append(QVariant::fromValue((VehicleComponent*)_radioComponent));
            }

            // No flight modes component for Sub versions 3.5 and up
            if (!_vehicle->sub() || (_vehicle->firmwareMajorVersion() == 3 && _vehicle->firmwareMinorVersion() <= 4)) {
                _flightModesComponent = new APMFlightModesComponent(_vehicle, this);
                _flightModesComponent->setupTriggerSignals();
                _components.append(QVariant::fromValue((VehicleComponent*)_flightModesComponent));
            }

            _sensorsComponent = new APMSensorsComponent(_vehicle, this);
            _sensorsComponent->setupTriggerSignals();
            _components.append(QVariant::fromValue((VehicleComponent*)_sensorsComponent));

            _powerComponent = new APMPowerComponent(_vehicle, this);
            _powerComponent->setupTriggerSignals();
            _components.append(QVariant::fromValue((VehicleComponent*)_powerComponent));

#if 0
    // Temporarily removed, waiting for new command implementation

            if (_vehicle->multiRotor() || _vehicle->vtol()) {
                _motorComponent = new MotorComponent(_vehicle, this);
                _motorComponent->setupTriggerSignals();
                _components.append(QVariant::fromValue((VehicleComponent*)_motorComponent));
            }
#endif

            _safetyComponent = new APMSafetyComponent(_vehicle, this);
            _safetyComponent->setupTriggerSignals();
            _components.append(QVariant::fromValue((VehicleComponent*)_safetyComponent));

            _tuningComponent = new APMTuningComponent(_vehicle, this);
            _tuningComponent->setupTriggerSignals();
            _components.append(QVariant::fromValue((VehicleComponent*)_tuningComponent));

            _mixersComponent = new MixersComponent(_vehicle, this);
            _mixersComponent->setupTriggerSignals();
            _components.append(QVariant::fromValue((VehicleComponent*)_mixersComponent));

            _cameraComponent = new APMCameraComponent(_vehicle, this);
            _cameraComponent->setupTriggerSignals();
            _components.append(QVariant::fromValue((VehicleComponent*)_cameraComponent));

            if (_vehicle->sub()) {
                _lightsComponent = new APMLightsComponent(_vehicle, this);
                _lightsComponent->setupTriggerSignals();
                _components.append(QVariant::fromValue((VehicleComponent*)_lightsComponent));

                if(_vehicle->firmwareMajorVersion() > 3 || (_vehicle->firmwareMajorVersion() == 3 && _vehicle->firmwareMinorVersion() >= 5)) {
                    _subFrameComponent = new APMSubFrameComponent(_vehicle, this);
                    _subFrameComponent->setupTriggerSignals();
                    _components.append(QVariant::fromValue((VehicleComponent*)_subFrameComponent));
                }
            }

            //-- Is there an ESP8266 Connected?
            if(_vehicle->parameterManager()->parameterExists(MAV_COMP_ID_UDP_BRIDGE, "SW_VER")) {
                _esp8266Component = new ESP8266Component(_vehicle, this);
                _esp8266Component->setupTriggerSignals();
                _components.append(QVariant::fromValue((VehicleComponent*)_esp8266Component));
            }
        } else {
            qWarning() << "Call to vehicleCompenents prior to parametersReady";
        }
    }

    return _components;
}

QString APMAutoPilotPlugin::prerequisiteSetup(VehicleComponent* component) const
{
    bool requiresAirframeCheck = false;

    if (qobject_cast<const APMFlightModesComponent*>(component)) {
        if (_airframeComponent && !_airframeComponent->setupComplete()) {
            return _airframeComponent->name();
        }
        if (_radioComponent && !_radioComponent->setupComplete()) {
            return _radioComponent->name();
        }
        requiresAirframeCheck = true;
    } else if (qobject_cast<const APMRadioComponent*>(component)) {
        requiresAirframeCheck = true;
    } else if (qobject_cast<const APMCameraComponent*>(component)) {
        requiresAirframeCheck = true;
    } else if (qobject_cast<const APMPowerComponent*>(component)) {
        requiresAirframeCheck = true;
    } else if (qobject_cast<const APMSafetyComponent*>(component)) {
        requiresAirframeCheck = true;
    } else if (qobject_cast<const APMTuningComponent*>(component)) {
        requiresAirframeCheck = true;
    } else if (qobject_cast<const APMSensorsComponent*>(component)) {
        requiresAirframeCheck = true;
    }

    if (requiresAirframeCheck) {
        if (_airframeComponent && !_airframeComponent->setupComplete()) {
            return _airframeComponent->name();
        }
    }

    return QString();
}
<|endoftext|>


<commit_before>#include <stdlib.h>
#include <stdio.h>
#include <errno.h>

#include <getopt.h>
#include <unistd.h>

#define OSMIUM_MAIN
#include <osmium.hpp>

#include <geos/geom/MultiPolygon.h>
#include <geos/algorithm/locate/IndexedPointInAreaLocator.h>

#include "softcut.hpp"
#include "hardcut.hpp"

template <class TExtractInfo> bool readConfig(char *conffile, CutInfo<TExtractInfo> &info);

int main(int argc, char *argv[]) {
    bool softcut = false;
    bool debug = false;
    char *filename, *conffile;

    static struct option long_options[] = {
        {"debug",               no_argument, 0, 'd'},
        {"softcut",             no_argument, 0, 's'},
        {"hardcut",             no_argument, 0, 'h'},
        {0, 0, 0, 0}
    };

    while (1) {
        int c = getopt_long(argc, argv, "dsh", long_options, 0);
        if (c == -1)
            break;

        switch (c) {
            case 'd':
                debug = true;
                break;
            case 's':
                softcut = true;
                break;
            case 'h':
                softcut = false;
                break;
        }
    }

    if (optind > argc-2) {
        fprintf(stderr, "Usage: %s [OPTIONS] OSMFILE CONFIGFILE\n", argv[0]);
        return 1;
    }

    filename = argv[optind];
    conffile = argv[optind+1];

    if(softcut & !strcmp(filename, "-")) {
        fprintf(stderr, "Can't read from stdin when in softcut\n");
        return 1;
    }

    Osmium::init(debug);
    Osmium::OSMFile infile(filename);

    if(softcut) {
        SoftcutInfo info;
        if(!readConfig(conffile, info))
        {
            fprintf(stderr, "error reading config\n");
            return 1;
        }

        SoftcutPassOne one(&info);
        one.debug = debug;
        infile.read(one);

        SoftcutPassTwo two(&info);
        two.debug = debug;
        infile.read(two);
    } else {
        HardcutInfo info;
        if(!readConfig(conffile, info))
        {
            fprintf(stderr, "error reading config\n");
            return 1;
        }

        Hardcut cutter(&info);
        cutter.debug = debug;
        infile.read(cutter);
    }

    return 0;
}

template <class TExtractInfo> bool readConfig(char *conffile, CutInfo<TExtractInfo> &info) {
    const int linelen = 4096;

    FILE *fp = fopen(conffile, "r");
    if(!fp) {
        fprintf(stderr, "unable to open config file %s\n", conffile);
        return false;
    }

    char line[linelen];
    while(fgets(line, linelen-1, fp)) {
        line[linelen-1] = '\0';
        if(line[0] == '#' || line[0] == '\r' || line[0] == '\n' || line[0] == '\0')
            continue;

        int n = 0;
        char *tok = strtok(line, "\t ");

        const char *name = NULL;
        double minlon = 0, minlat = 0, maxlon = 0, maxlat = 0;
        char type = '\0';
        char file[linelen];

        while(tok) {
            switch(n) {
                case 0:
                    name = tok;
                    break;

                case 1:
                    if(0 == strcmp("BBOX", tok))
                        type = 'b';
                    else if(0 == strcmp("POLY", tok))
                        type = 'p';
                    else if(0 == strcmp("OSM", tok))
                        type = 'o';
                    else {
                        type = '\0';
                        fprintf(stderr, "output %s of type %s: unkown output type\n", name, tok);
                        return false;
                    }
                    break;

                case 2:
                    switch(type) {
                        case 'b':
                            if(4 == sscanf(tok, "%lf,%lf,%lf,%lf", &minlon, &minlat, &maxlon, &maxlat)) {
                                geos::geom::Geometry *geom = OsmiumExtension::GeometryReader::fromBBox(minlon, minlat, maxlon, maxlat);
                                if(!geom) {
                                    fprintf(stderr, "error creating geometry from bbox for %s\n", name);
                                    break;
                                }
                                info.addExtract(name, geom);
                            }
                            break;
                        case 'p':
                            if(1 == sscanf(tok, "%s", file)) {
                                geos::geom::Geometry *geom = OsmiumExtension::GeometryReader::fromPolyFile(file);
                                if(!geom) {
                                    fprintf(stderr, "error creating geometry from poly-file %s for %s\n", file, name);
                                    break;
                                }
                                info.addExtract(name, geom);
                            }
                            break;
                        case 'o':
                            if(1 == sscanf(tok, "%s", file)) {
                                geos::geom::Geometry *geom = OsmiumExtension::GeometryReader::fromOsmFile(file);
                                if(!geom) {
                                    fprintf(stderr, "error creating geometry from poly-file %s for %s\n", file, name);
                                    break;
                                }
                                info.addExtract(name, geom);
                            }
                            break;
                    }
                    break;
            }

            tok = strtok(NULL, "\t ");
            n++;
        }
    }
    fclose(fp);
    return true;
}

<commit_msg>default to softcut<commit_after>#include <stdlib.h>
#include <stdio.h>
#include <errno.h>

#include <getopt.h>
#include <unistd.h>

#define OSMIUM_MAIN
#include <osmium.hpp>

#include <geos/geom/MultiPolygon.h>
#include <geos/algorithm/locate/IndexedPointInAreaLocator.h>

#include "softcut.hpp"
#include "hardcut.hpp"

template <class TExtractInfo> bool readConfig(char *conffile, CutInfo<TExtractInfo> &info);

int main(int argc, char *argv[]) {
    bool softcut = true;
    bool debug = false;
    char *filename, *conffile;

    static struct option long_options[] = {
        {"debug",               no_argument, 0, 'd'},
        {"softcut",             no_argument, 0, 's'},
        {"hardcut",             no_argument, 0, 'h'},
        {0, 0, 0, 0}
    };

    while (1) {
        int c = getopt_long(argc, argv, "dsh", long_options, 0);
        if (c == -1)
            break;

        switch (c) {
            case 'd':
                debug = true;
                break;
            case 's':
                softcut = true;
                break;
            case 'h':
                softcut = false;
                break;
        }
    }

    if (optind > argc-2) {
        fprintf(stderr, "Usage: %s [OPTIONS] OSMFILE CONFIGFILE\n", argv[0]);
        return 1;
    }

    filename = argv[optind];
    conffile = argv[optind+1];

    if(softcut & !strcmp(filename, "-")) {
        fprintf(stderr, "Can't read from stdin when in softcut\n");
        return 1;
    }

    Osmium::init(debug);
    Osmium::OSMFile infile(filename);

    if(softcut) {
        SoftcutInfo info;
        if(!readConfig(conffile, info))
        {
            fprintf(stderr, "error reading config\n");
            return 1;
        }

        SoftcutPassOne one(&info);
        one.debug = debug;
        infile.read(one);

        SoftcutPassTwo two(&info);
        two.debug = debug;
        infile.read(two);
    } else {
        HardcutInfo info;
        if(!readConfig(conffile, info))
        {
            fprintf(stderr, "error reading config\n");
            return 1;
        }

        Hardcut cutter(&info);
        cutter.debug = debug;
        infile.read(cutter);
    }

    return 0;
}

template <class TExtractInfo> bool readConfig(char *conffile, CutInfo<TExtractInfo> &info) {
    const int linelen = 4096;

    FILE *fp = fopen(conffile, "r");
    if(!fp) {
        fprintf(stderr, "unable to open config file %s\n", conffile);
        return false;
    }

    char line[linelen];
    while(fgets(line, linelen-1, fp)) {
        line[linelen-1] = '\0';
        if(line[0] == '#' || line[0] == '\r' || line[0] == '\n' || line[0] == '\0')
            continue;

        int n = 0;
        char *tok = strtok(line, "\t ");

        const char *name = NULL;
        double minlon = 0, minlat = 0, maxlon = 0, maxlat = 0;
        char type = '\0';
        char file[linelen];

        while(tok) {
            switch(n) {
                case 0:
                    name = tok;
                    break;

                case 1:
                    if(0 == strcmp("BBOX", tok))
                        type = 'b';
                    else if(0 == strcmp("POLY", tok))
                        type = 'p';
                    else if(0 == strcmp("OSM", tok))
                        type = 'o';
                    else {
                        type = '\0';
                        fprintf(stderr, "output %s of type %s: unkown output type\n", name, tok);
                        return false;
                    }
                    break;

                case 2:
                    switch(type) {
                        case 'b':
                            if(4 == sscanf(tok, "%lf,%lf,%lf,%lf", &minlon, &minlat, &maxlon, &maxlat)) {
                                geos::geom::Geometry *geom = OsmiumExtension::GeometryReader::fromBBox(minlon, minlat, maxlon, maxlat);
                                if(!geom) {
                                    fprintf(stderr, "error creating geometry from bbox for %s\n", name);
                                    break;
                                }
                                info.addExtract(name, geom);
                            }
                            break;
                        case 'p':
                            if(1 == sscanf(tok, "%s", file)) {
                                geos::geom::Geometry *geom = OsmiumExtension::GeometryReader::fromPolyFile(file);
                                if(!geom) {
                                    fprintf(stderr, "error creating geometry from poly-file %s for %s\n", file, name);
                                    break;
                                }
                                info.addExtract(name, geom);
                            }
                            break;
                        case 'o':
                            if(1 == sscanf(tok, "%s", file)) {
                                geos::geom::Geometry *geom = OsmiumExtension::GeometryReader::fromOsmFile(file);
                                if(!geom) {
                                    fprintf(stderr, "error creating geometry from poly-file %s for %s\n", file, name);
                                    break;
                                }
                                info.addExtract(name, geom);
                            }
                            break;
                    }
                    break;
            }

            tok = strtok(NULL, "\t ");
            n++;
        }
    }
    fclose(fp);
    return true;
}

<|endoftext|>