<commit_before>///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// 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.
// *       Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// 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
// OWNER 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.
//
///////////////////////////////////////////////////////////////////////////

//-----------------------------------------------------------------------------
//
//	Low-level file input and output for OpenEXR
//	based on C++ standard iostreams.
//
//-----------------------------------------------------------------------------

#include <ImfStdIO.h>
#include <Iex.h>
#include <errno.h>

using namespace std;

namespace Imf {
namespace {

void
clearError ()
{
    errno = 0;
}

bool
checkError (istream &is)
{
    if (!is)
    {
	if (errno)
	    Iex::throwErrnoExc();

#ifdef BROKEN_ISTREAM_HACK
	// HACK - this is a workaround for a bug in Apple's
	// implementation of istream::read.  It's present as of
	// OS X 10.2.3 and the December 2002 developer's tools.
	//
	// When OpenEXR reaches the end of the file, Apple's
	// istream implementation mistakenly sets the stream's
	// failbit.  This hack clears the bits, but note that it
	// may cause problems if there is a legitimate error
	// condition.

	is.clear (std::ios_base::goodbit);
#endif
	return false;
    }

    return true;
}

void
checkError (ostream &os)
{
    if (!os)
    {
	if (errno)
	    Iex::throwErrnoExc();

	throw Iex::ErrnoExc ("File output failed.");
    }
}

} // namespace

StdIFStream::StdIFStream (const char fileName[]):
    IStream (fileName),
#ifndef HAVE_IOS_BASE
    _is (new ifstream (fileName, ios::binary|ios::in)),
#else
    _is (new ifstream (fileName, ios_base::binary)),
#endif
    _deleteStream (true)
{
    if (!*_is)
    {
	delete _is;
	Iex::throwErrnoExc();
    }
}

StdIFStream::StdIFStream (ifstream &is, const char fileName[]):
    IStream (fileName),
    _is (&is),
    _deleteStream (false)
{
    // empty
}

StdIFStream::~StdIFStream ()
{
    if (_deleteStream)
	delete _is;
}

bool
StdIFStream::read (char c[/*n*/], int n)
{
    if (!*_is)
	throw Iex::InputExc ("Unexpected end of file.");

    clearError();
    _is->read (c, n);
    return checkError (*_is);
}

Int64
StdIFStream::tellg ()
{
    return _is->tellg();
}

void
StdIFStream::seekg (Int64 pos)
{
    _is->seekg (pos);
    checkError (*_is);
}

void
StdIFStream::clear ()
{
    _is->clear();
}

StdOFStream::StdOFStream (const char fileName[]):
    OStream (fileName),
#ifndef HAVE_IOS_BASE
    _os (new ofstream (fileName, ios::binary)),
#else
    _os (new ofstream (fileName, ios_base::binary)),
#endif
    _deleteStream (true)
{
    if (!*_os)
    {
	delete _os;
	Iex::throwErrnoExc();
    }
}

StdOFStream::StdOFStream (ofstream &os, const char fileName[]):
    OStream (fileName),
    _os (&os),
    _deleteStream (false)
{
    // empty
}

StdOFStream::~StdOFStream ()
{
    if (_deleteStream)
	delete _os;
}

void
StdOFStream::write (const char c[/*n*/], int n)
{
    clearError();
    _os->write (c, n);
    checkError (*_os);
}

Int64
StdOFStream::tellp ()
{
    return _os->tellp();
}

void
StdOFStream::seekp (Int64 pos)
{
    _os->seekp (pos);
    checkError (*_os);
}

StdOSStream::StdOSStream (): OStream ("(string)")
{
    // empty
}

void
StdOSStream::write (const char c[/*n*/], int n)
{
    clearError();
    _os.write (c, n);
    checkError (_os);
}

Int64
StdOSStream::tellp ()
{
    return _os.tellp();
}

void
StdOSStream::seekp (Int64 pos)
{
    _os.seekp (pos);
    checkError (_os);
}

} // namespace Imf
<commit_msg><commit_after>///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// 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.
// *       Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// 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
// OWNER 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.
//
///////////////////////////////////////////////////////////////////////////

//-----------------------------------------------------------------------------
//
//	Low-level file input and output for OpenEXR
//	based on C++ standard iostreams.
//
//-----------------------------------------------------------------------------

#include <ImfStdIO.h>
#include <Iex.h>
#include <errno.h>

using namespace std;

namespace Imf {
namespace {

void
clearError ()
{
    errno = 0;
}

bool
checkError (istream &is)
{
    if (!is)
    {
	if (errno)
	    Iex::throwErrnoExc();

#ifdef BROKEN_ISTREAM_HACK
	// HACK - this is a workaround for a bug in Apple's
	// implementation of istream::read.  It's present as of
	// OS X 10.2.3 and the December 2002 developer's tools.
	//
	// When OpenEXR reaches the end of the file, Apple's
	// istream implementation mistakenly sets the stream's
	// failbit.  This hack clears the bits, but note that it
	// may cause problems if there is a legitimate error
	// condition.

	is.clear (std::ios_base::goodbit);
#endif
	return false;
    }

    return true;
}

void
checkError (ostream &os)
{
    if (!os)
    {
	if (errno)
	    Iex::throwErrnoExc();

	throw Iex::ErrnoExc ("File output failed.");
    }
}

} // namespace

StdIFStream::StdIFStream (const char fileName[]):
    IStream (fileName),
#ifndef HAVE_IOS_BASE
    _is (new ifstream (fileName, ios::binary|ios::in)),
#else
    _is (new ifstream (fileName, ios_base::binary)),
#endif
    _deleteStream (true)
{
    if (!*_is)
    {
	delete _is;
	Iex::throwErrnoExc();
    }
}

StdIFStream::StdIFStream (ifstream &is, const char fileName[]):
    IStream (fileName),
    _is (&is),
    _deleteStream (false)
{
    // empty
}

StdIFStream::~StdIFStream ()
{
    if (_deleteStream)
	delete _is;
}

bool
StdIFStream::read (char c[/*n*/], int n)
{
    if (!*_is)
	throw Iex::InputExc ("Unexpected end of file.");

    clearError();
    _is->read (c, n);
    return checkError (*_is);
}

Int64
StdIFStream::tellg ()
{
    return std::streamoff (_is->tellg());
}

void
StdIFStream::seekg (Int64 pos)
{
    _is->seekg (pos);
    checkError (*_is);
}

void
StdIFStream::clear ()
{
    _is->clear();
}

StdOFStream::StdOFStream (const char fileName[]):
    OStream (fileName),
#ifndef HAVE_IOS_BASE
    _os (new ofstream (fileName, ios::binary)),
#else
    _os (new ofstream (fileName, ios_base::binary)),
#endif
    _deleteStream (true)
{
    if (!*_os)
    {
	delete _os;
	Iex::throwErrnoExc();
    }
}

StdOFStream::StdOFStream (ofstream &os, const char fileName[]):
    OStream (fileName),
    _os (&os),
    _deleteStream (false)
{
    // empty
}

StdOFStream::~StdOFStream ()
{
    if (_deleteStream)
	delete _os;
}

void
StdOFStream::write (const char c[/*n*/], int n)
{
    clearError();
    _os->write (c, n);
    checkError (*_os);
}

Int64
StdOFStream::tellp ()
{
    return std::streamoff (_os->tellp());
}

void
StdOFStream::seekp (Int64 pos)
{
    _os->seekp (pos);
    checkError (*_os);
}

StdOSStream::StdOSStream (): OStream ("(string)")
{
    // empty
}

void
StdOSStream::write (const char c[/*n*/], int n)
{
    clearError();
    _os.write (c, n);
    checkError (_os);
}

Int64
StdOSStream::tellp ()
{
    return std::streamoff (_os.tellp());
}

void
StdOSStream::seekp (Int64 pos)
{
    _os.seekp (pos);
    checkError (_os);
}

} // namespace Imf
<|endoftext|>


<commit_before>/*
    This file is part of Magnum.

    Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz>

    Permission is hereby granted, free of charge, to any person obtaining a
    copy of this software and associated documentation files (the "Software"),
    to deal in the Software without restriction, including without limitation
    the rights to use, copy, modify, merge, publish, distribute, sublicense,
    and/or sell copies of the Software, and to permit persons to whom the
    Software is furnished to do so, subject to the following conditions:

    The above copyright notice and this permission notice shall be included
    in all copies or substantial portions of the Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
    THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
    DEALINGS IN THE SOFTWARE.
*/

#include <Utility/Arguments.h>
#include <Utility/Debug.h>
#include <corradeCompatibility.h>
#ifdef CORRADE_TARGET_NACL
#include <Utility/NaClStreamBuffer.h>
#endif

#include "AbstractShaderProgram.h"
#include "Buffer.h"
#include "BufferTexture.h"
#include "Context.h"
#include "DebugMessage.h"
#include "Extensions.h"
#include "Framebuffer.h"
#include "Mesh.h"
#include "Renderbuffer.h"
#include "Shader.h"
#ifndef CORRADE_TARGET_NACL
#include "Platform/WindowlessGlxApplication.h"
#else
#include "Platform/WindowlessNaClApplication.h"
#endif

namespace Magnum {

class MagnumInfo: public Platform::WindowlessApplication {
    public:
        explicit MagnumInfo(const Arguments& arguments);

        int exec() override { return 0; }
};

MagnumInfo::MagnumInfo(const Arguments& arguments): Platform::WindowlessApplication(arguments, nullptr) {
    Utility::Arguments args;
    args.addBooleanOption("all-extensions")
        .setHelp("all-extensions", "show extensions also for fully supported versions")
        .addBooleanOption("no-limits")
        .setHelp("no-limits", "don't display limits and implementation-defined values")
        .setHelp("Displays information about Magnum engine and OpenGL capabilities.");

    /**
     * @todo Make this work in NaCl, somehow the arguments aren't passed to
     *      constructor but to Init() or whatnot
     */
    #ifndef CORRADE_TARGET_NACL
    args.parse(arguments.argc, arguments.argv);
    #endif

    /* Create context after parsing arguments, so the help can be displayed
       without creating context */
    createContext();
    Context* c = Context::current();

    /* Pass debug output as messages to JavaScript */
    #ifdef CORRADE_TARGET_NACL
    Utility::NaClMessageStreamBuffer buffer(this);
    std::ostream out(&buffer);
    Debug::setOutput(&out);
    #endif

    Debug() << "";
    Debug() << "  +---------------------------------------------------------+";
    Debug() << "  | Information about Magnum engine and OpenGL capabilities |";
    Debug() << "  +---------------------------------------------------------+";
    Debug() << "";

    Debug() << "Used application: Platform::WindowlessGlxApplication";
    Debug() << "Compilation flags:";
    #ifdef CORRADE_GCC46_COMPATIBILITY
    Debug() << "    CORRADE_GCC46_COMPATIBILITY";
    #endif
    #ifdef CORRADE_GCC47_COMPATIBILITY
    Debug() << "    CORRADE_GCC47_COMPATIBILITY";
    #endif
    #ifdef CORRADE_BUILD_DEPRECATED
    Debug() << "    CORRADE_BUILD_DEPRECATED";
    #endif
    #ifdef CORRADE_BUILD_STATIC
    Debug() << "    CORRADE_BUILD_STATIC";
    #endif
    #ifdef CORRADE_TARGET_NACL
    Debug() << "    CORRADE_TARGET_NACL";
    #endif
    #ifdef CORRADE_TARGET_NACL_NEWLIB
    Debug() << "    CORRADE_TARGET_NACL_NEWLIB";
    #endif
    #ifdef CORRADE_TARGET_NACL_GLIBC
    Debug() << "    CORRADE_TARGET_NACL_GLIBC";
    #endif
    #ifdef CORRADE_TARGET_EMSCRIPTEN
    Debug() << "    CORRADE_TARGET_EMSCRIPTEN";
    #endif
    #ifdef MAGNUM_BUILD_DEPRECATED
    Debug() << "    MAGNUM_BUILD_DEPRECATED";
    #endif
    #ifdef MAGNUM_BUILD_STATIC
    Debug() << "    MAGNUM_BUILD_STATIC";
    #endif
    #ifdef MAGNUM_TARGET_GLES
    Debug() << "    MAGNUM_TARGET_GLES";
    #endif
    #ifdef MAGNUM_TARGET_GLES2
    Debug() << "    MAGNUM_TARGET_GLES2";
    #endif
    #ifdef MAGNUM_TARGET_DESKTOP_GLES
    Debug() << "    MAGNUM_TARGET_DESKTOP_GLES";
    #endif
    Debug() << "";

    Debug() << "Vendor:" << c->vendorString();
    Debug() << "Renderer:" << c->rendererString();
    Debug() << "OpenGL version:" << c->version() << '(' + c->versionString() + ')';

    Debug() << "Supported GLSL versions:";
    const std::vector<std::string> shadingLanguageVersions = c->shadingLanguageVersionStrings();
    for(const auto& version: shadingLanguageVersions)
        Debug() << "   " << version;

    Debug() << "";

    /* Get first future (not supported) version */
    std::vector<Version> versions{
        #ifndef MAGNUM_TARGET_GLES
        Version::GL300,
        Version::GL310,
        Version::GL320,
        Version::GL330,
        Version::GL400,
        Version::GL410,
        Version::GL420,
        Version::GL430,
        Version::GL440,
        #else
        Version::GLES200,
        Version::GLES300,
        #endif
        Version::None
    };
    std::size_t future = 0;

    if(!args.isSet("all-extensions"))
        while(versions[future] != Version::None && c->isVersionSupported(versions[future]))
            ++future;

    /* Display supported OpenGL extensions from unsupported versions */
    for(std::size_t i = future; i != versions.size(); ++i) {
        if(versions[i] != Version::None)
            Debug() << versions[i] << "extension support:";
        else Debug() << "Vendor extension support:";

        for(const auto& extension: Extension::extensions(versions[i])) {
            std::string extensionName = extension.string();
            Debug d;
            d << "   " << extensionName << std::string(60-extensionName.size(), ' ');
            if(c->isExtensionSupported(extension))
                d << "SUPPORTED";
            else if(c->isVersionSupported(extension.requiredVersion()))
                d << "    -";
            else
                d << "   ---";
        }

        Debug() << "";
    }

    if(args.isSet("no-limits")) return;

    /* Limits and implementation-defined values */
    #define _h(val) Debug() << "\n " << Extensions::GL::val::string() + std::string(":");
    #define _l(val) Debug() << "   " << #val << (sizeof(#val) > 64 ? "\n" + std::string(68, ' ') : std::string(64 - sizeof(#val), ' ')) << val;

    Debug() << "Limits and implementation-defined values:";
    _l(AbstractFramebuffer::maxViewportSize())
    _l(AbstractFramebuffer::maxDrawBuffers())
    _l(Framebuffer::maxColorAttachments())
    #ifndef MAGNUM_TARGET_GLES2
    _l(Mesh::maxElementsIndices())
    _l(Mesh::maxElementsVertices())
    #endif
    _l(Renderbuffer::maxSize())
    _l(Renderbuffer::maxSamples())
    _l(Shader::maxVertexOutputComponents())
    _l(Shader::maxFragmentInputComponents())
    _l(Shader::maxTextureImageUnits(Shader::Type::Vertex))
    #ifndef MAGNUM_TARGET_GLES
    _l(Shader::maxTextureImageUnits(Shader::Type::TessellationControl))
    _l(Shader::maxTextureImageUnits(Shader::Type::TessellationEvaluation))
    _l(Shader::maxTextureImageUnits(Shader::Type::Geometry))
    _l(Shader::maxTextureImageUnits(Shader::Type::Compute))
    #endif
    _l(Shader::maxTextureImageUnits(Shader::Type::Fragment))
    _l(Shader::maxCombinedTextureImageUnits())
    _l(Shader::maxUniformComponents(Shader::Type::Vertex))
    #ifndef MAGNUM_TARGET_GLES
    _l(Shader::maxUniformComponents(Shader::Type::TessellationControl))
    _l(Shader::maxUniformComponents(Shader::Type::TessellationEvaluation))
    _l(Shader::maxUniformComponents(Shader::Type::Geometry))
    _l(Shader::maxUniformComponents(Shader::Type::Compute))
    #endif
    _l(Shader::maxUniformComponents(Shader::Type::Fragment))
    #ifndef MAGNUM_TARGET_GLES
    _l(AbstractShaderProgram::maxUniformLocations())
    #endif
    _l(AbstractShaderProgram::maxVertexAttributes())
    #ifndef MAGNUM_TARGET_GLES
    _l(AbstractTexture::maxColorSamples())
    _l(AbstractTexture::maxDepthSamples())
    _l(AbstractTexture::maxIntegerSamples())
    #endif

    #ifndef MAGNUM_TARGET_GLES
    if(c->isExtensionSupported<Extensions::GL::ARB::blend_func_extended>()) {
        _h(ARB::blend_func_extended)

        _l(AbstractFramebuffer::maxDualSourceDrawBuffers())
    }

    if(c->isExtensionSupported<Extensions::GL::ARB::compute_shader>()) {
        _h(ARB::compute_shader)

        _l(AbstractShaderProgram::maxComputeSharedMemorySize())
        _l(AbstractShaderProgram::maxComputeWorkGroupInvocations())
    }

    if(c->isExtensionSupported<Extensions::GL::ARB::geometry_shader4>()) {
        _h(ARB::geometry_shader4)

        _l(Shader::maxGeometryInputComponents())
        _l(Shader::maxGeometryOutputComponents())
        _l(Shader::maxGeometryTotalOutputComponents())
    }

    if(c->isExtensionSupported<Extensions::GL::ARB::shader_atomic_counters>()) {
        _h(ARB::shader_atomic_counters)

        _l(Buffer::maxAtomicCounterBindings())
        _l(Shader::maxAtomicCounterBuffers(Shader::Type::Vertex))
        _l(Shader::maxAtomicCounterBuffers(Shader::Type::TessellationControl))
        _l(Shader::maxAtomicCounterBuffers(Shader::Type::TessellationEvaluation))
        _l(Shader::maxAtomicCounterBuffers(Shader::Type::Geometry))
        _l(Shader::maxAtomicCounterBuffers(Shader::Type::Compute))
        _l(Shader::maxAtomicCounterBuffers(Shader::Type::Fragment))
        _l(Shader::maxCombinedAtomicCounterBuffers())
        _l(Shader::maxAtomicCounters(Shader::Type::Vertex))
        _l(Shader::maxAtomicCounters(Shader::Type::TessellationControl))
        _l(Shader::maxAtomicCounters(Shader::Type::TessellationEvaluation))
        _l(Shader::maxAtomicCounters(Shader::Type::Geometry))
        _l(Shader::maxAtomicCounters(Shader::Type::Compute))
        _l(Shader::maxAtomicCounters(Shader::Type::Fragment))
        _l(Shader::maxCombinedAtomicCounters())
        _l(AbstractShaderProgram::maxAtomicCounterBufferSize())
    }

    if(c->isExtensionSupported<Extensions::GL::ARB::shader_image_load_store>()) {
        _h(ARB::shader_image_load_store)

        _l(Shader::maxImageUniforms(Shader::Type::Vertex))
        _l(Shader::maxImageUniforms(Shader::Type::TessellationControl))
        _l(Shader::maxImageUniforms(Shader::Type::TessellationEvaluation))
        _l(Shader::maxImageUniforms(Shader::Type::Geometry))
        _l(Shader::maxImageUniforms(Shader::Type::Compute))
        _l(Shader::maxImageUniforms(Shader::Type::Fragment))
        _l(Shader::maxCombinedImageUniforms())
        _l(AbstractShaderProgram::maxCombinedShaderOutputResources())
        _l(AbstractShaderProgram::maxImageUnits())
        _l(AbstractShaderProgram::maxImageSamples())
    }

    if(c->isExtensionSupported<Extensions::GL::ARB::shader_storage_buffer_object>()) {
        _h(ARB::shader_storage_buffer_object)

        _l(Shader::maxShaderStorageBlocks(Shader::Type::Vertex))
        _l(Shader::maxShaderStorageBlocks(Shader::Type::TessellationControl))
        _l(Shader::maxShaderStorageBlocks(Shader::Type::TessellationEvaluation))
        _l(Shader::maxShaderStorageBlocks(Shader::Type::Geometry))
        _l(Shader::maxShaderStorageBlocks(Shader::Type::Compute))
        _l(Shader::maxShaderStorageBlocks(Shader::Type::Fragment))
        _l(Shader::maxCombinedShaderStorageBlocks())
        /* AbstractShaderProgram::maxCombinedShaderOutputResources() already in shader_image_load_store */
        _l(AbstractShaderProgram::maxShaderStorageBlockSize())
    }

    if(c->isExtensionSupported<Extensions::GL::ARB::tessellation_shader>()) {
        _h(ARB::tessellation_shader)

        _l(Buffer::shaderStorageOffsetAlignment())
        _l(Buffer::maxShaderStorageBindings())
        _l(Shader::maxTessellationControlInputComponents())
        _l(Shader::maxTessellationControlOutputComponents())
        _l(Shader::maxTessellationControlTotalOutputComponents())
        _l(Shader::maxTessellationEvaluationInputComponents())
        _l(Shader::maxTessellationEvaluationOutputComponents())
    }

    if(c->isExtensionSupported<Extensions::GL::ARB::texture_buffer_range>()) {
        _h(ARB::texture_buffer_range)

        _l(BufferTexture::offsetAlignment())
    }
    #endif

    #ifndef MAGNUM_TARGET_GLES2
    if(c->isExtensionSupported<Extensions::GL::ARB::uniform_buffer_object>()) {
        _h(ARB::uniform_buffer_object)

        _l(Shader::maxUniformBlocks(Shader::Type::Vertex))
        _l(Shader::maxUniformBlocks(Shader::Type::TessellationControl))
        _l(Shader::maxUniformBlocks(Shader::Type::TessellationEvaluation))
        _l(Shader::maxUniformBlocks(Shader::Type::Geometry))
        _l(Shader::maxUniformBlocks(Shader::Type::Compute))
        _l(Shader::maxUniformBlocks(Shader::Type::Fragment))
        _l(Shader::maxCombinedUniformBlocks())
        _l(Shader::maxCombinedUniformComponents(Shader::Type::Vertex))
        _l(Shader::maxCombinedUniformComponents(Shader::Type::TessellationControl))
        _l(Shader::maxCombinedUniformComponents(Shader::Type::TessellationEvaluation))
        _l(Shader::maxCombinedUniformComponents(Shader::Type::Geometry))
        _l(Shader::maxCombinedUniformComponents(Shader::Type::Compute))
        _l(Shader::maxCombinedUniformComponents(Shader::Type::Fragment))
        _l(AbstractShaderProgram::maxUniformBlockSize())
    }

    if(c->isExtensionSupported<Extensions::GL::EXT::gpu_shader4>()) {
        _h(EXT::gpu_shader4)

        _l(Buffer::maxUniformBindings())
        _l(AbstractShaderProgram::minTexelOffset())
        _l(AbstractShaderProgram::maxTexelOffset())
    }
    #endif

    if(c->isExtensionSupported<Extensions::GL::EXT::texture_filter_anisotropic>()) {
        _h(EXT::texture_filter_anisotropic)

        _l(Sampler::maxMaxAnisotropy())
    }

    if(c->isExtensionSupported<Extensions::GL::KHR::debug>()) {
        _h(KHR::debug)

        _l(AbstractObject::maxLabelLength())
        _l(DebugMessage::maxLoggedMessages())
        _l(DebugMessage::maxMessageLength())
    }

    #undef _l
    #undef _h
}

}

MAGNUM_WINDOWLESSAPPLICATION_MAIN(Magnum::MagnumInfo)
<commit_msg>Platform: fixed compilation of magnum-info on ES3.<commit_after>/*
    This file is part of Magnum.

    Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz>

    Permission is hereby granted, free of charge, to any person obtaining a
    copy of this software and associated documentation files (the "Software"),
    to deal in the Software without restriction, including without limitation
    the rights to use, copy, modify, merge, publish, distribute, sublicense,
    and/or sell copies of the Software, and to permit persons to whom the
    Software is furnished to do so, subject to the following conditions:

    The above copyright notice and this permission notice shall be included
    in all copies or substantial portions of the Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
    THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
    DEALINGS IN THE SOFTWARE.
*/

#include <Utility/Arguments.h>
#include <Utility/Debug.h>
#include <corradeCompatibility.h>
#ifdef CORRADE_TARGET_NACL
#include <Utility/NaClStreamBuffer.h>
#endif

#include "AbstractShaderProgram.h"
#include "Buffer.h"
#include "BufferTexture.h"
#include "Context.h"
#include "DebugMessage.h"
#include "Extensions.h"
#include "Framebuffer.h"
#include "Mesh.h"
#include "Renderbuffer.h"
#include "Shader.h"
#ifndef CORRADE_TARGET_NACL
#include "Platform/WindowlessGlxApplication.h"
#else
#include "Platform/WindowlessNaClApplication.h"
#endif

namespace Magnum {

class MagnumInfo: public Platform::WindowlessApplication {
    public:
        explicit MagnumInfo(const Arguments& arguments);

        int exec() override { return 0; }
};

MagnumInfo::MagnumInfo(const Arguments& arguments): Platform::WindowlessApplication(arguments, nullptr) {
    Utility::Arguments args;
    args.addBooleanOption("all-extensions")
        .setHelp("all-extensions", "show extensions also for fully supported versions")
        .addBooleanOption("no-limits")
        .setHelp("no-limits", "don't display limits and implementation-defined values")
        .setHelp("Displays information about Magnum engine and OpenGL capabilities.");

    /**
     * @todo Make this work in NaCl, somehow the arguments aren't passed to
     *      constructor but to Init() or whatnot
     */
    #ifndef CORRADE_TARGET_NACL
    args.parse(arguments.argc, arguments.argv);
    #endif

    /* Create context after parsing arguments, so the help can be displayed
       without creating context */
    createContext();
    Context* c = Context::current();

    /* Pass debug output as messages to JavaScript */
    #ifdef CORRADE_TARGET_NACL
    Utility::NaClMessageStreamBuffer buffer(this);
    std::ostream out(&buffer);
    Debug::setOutput(&out);
    #endif

    Debug() << "";
    Debug() << "  +---------------------------------------------------------+";
    Debug() << "  | Information about Magnum engine and OpenGL capabilities |";
    Debug() << "  +---------------------------------------------------------+";
    Debug() << "";

    Debug() << "Used application: Platform::WindowlessGlxApplication";
    Debug() << "Compilation flags:";
    #ifdef CORRADE_GCC46_COMPATIBILITY
    Debug() << "    CORRADE_GCC46_COMPATIBILITY";
    #endif
    #ifdef CORRADE_GCC47_COMPATIBILITY
    Debug() << "    CORRADE_GCC47_COMPATIBILITY";
    #endif
    #ifdef CORRADE_BUILD_DEPRECATED
    Debug() << "    CORRADE_BUILD_DEPRECATED";
    #endif
    #ifdef CORRADE_BUILD_STATIC
    Debug() << "    CORRADE_BUILD_STATIC";
    #endif
    #ifdef CORRADE_TARGET_NACL
    Debug() << "    CORRADE_TARGET_NACL";
    #endif
    #ifdef CORRADE_TARGET_NACL_NEWLIB
    Debug() << "    CORRADE_TARGET_NACL_NEWLIB";
    #endif
    #ifdef CORRADE_TARGET_NACL_GLIBC
    Debug() << "    CORRADE_TARGET_NACL_GLIBC";
    #endif
    #ifdef CORRADE_TARGET_EMSCRIPTEN
    Debug() << "    CORRADE_TARGET_EMSCRIPTEN";
    #endif
    #ifdef MAGNUM_BUILD_DEPRECATED
    Debug() << "    MAGNUM_BUILD_DEPRECATED";
    #endif
    #ifdef MAGNUM_BUILD_STATIC
    Debug() << "    MAGNUM_BUILD_STATIC";
    #endif
    #ifdef MAGNUM_TARGET_GLES
    Debug() << "    MAGNUM_TARGET_GLES";
    #endif
    #ifdef MAGNUM_TARGET_GLES2
    Debug() << "    MAGNUM_TARGET_GLES2";
    #endif
    #ifdef MAGNUM_TARGET_DESKTOP_GLES
    Debug() << "    MAGNUM_TARGET_DESKTOP_GLES";
    #endif
    Debug() << "";

    Debug() << "Vendor:" << c->vendorString();
    Debug() << "Renderer:" << c->rendererString();
    Debug() << "OpenGL version:" << c->version() << '(' + c->versionString() + ')';

    Debug() << "Supported GLSL versions:";
    const std::vector<std::string> shadingLanguageVersions = c->shadingLanguageVersionStrings();
    for(const auto& version: shadingLanguageVersions)
        Debug() << "   " << version;

    Debug() << "";

    /* Get first future (not supported) version */
    std::vector<Version> versions{
        #ifndef MAGNUM_TARGET_GLES
        Version::GL300,
        Version::GL310,
        Version::GL320,
        Version::GL330,
        Version::GL400,
        Version::GL410,
        Version::GL420,
        Version::GL430,
        Version::GL440,
        #else
        Version::GLES200,
        Version::GLES300,
        #endif
        Version::None
    };
    std::size_t future = 0;

    if(!args.isSet("all-extensions"))
        while(versions[future] != Version::None && c->isVersionSupported(versions[future]))
            ++future;

    /* Display supported OpenGL extensions from unsupported versions */
    for(std::size_t i = future; i != versions.size(); ++i) {
        if(versions[i] != Version::None)
            Debug() << versions[i] << "extension support:";
        else Debug() << "Vendor extension support:";

        for(const auto& extension: Extension::extensions(versions[i])) {
            std::string extensionName = extension.string();
            Debug d;
            d << "   " << extensionName << std::string(60-extensionName.size(), ' ');
            if(c->isExtensionSupported(extension))
                d << "SUPPORTED";
            else if(c->isVersionSupported(extension.requiredVersion()))
                d << "    -";
            else
                d << "   ---";
        }

        Debug() << "";
    }

    if(args.isSet("no-limits")) return;

    /* Limits and implementation-defined values */
    #define _h(val) Debug() << "\n " << Extensions::GL::val::string() + std::string(":");
    #define _l(val) Debug() << "   " << #val << (sizeof(#val) > 64 ? "\n" + std::string(68, ' ') : std::string(64 - sizeof(#val), ' ')) << val;

    Debug() << "Limits and implementation-defined values:";
    _l(AbstractFramebuffer::maxViewportSize())
    _l(AbstractFramebuffer::maxDrawBuffers())
    _l(Framebuffer::maxColorAttachments())
    #ifndef MAGNUM_TARGET_GLES2
    _l(Mesh::maxElementsIndices())
    _l(Mesh::maxElementsVertices())
    #endif
    _l(Renderbuffer::maxSize())
    _l(Renderbuffer::maxSamples())
    _l(Shader::maxVertexOutputComponents())
    _l(Shader::maxFragmentInputComponents())
    _l(Shader::maxTextureImageUnits(Shader::Type::Vertex))
    #ifndef MAGNUM_TARGET_GLES
    _l(Shader::maxTextureImageUnits(Shader::Type::TessellationControl))
    _l(Shader::maxTextureImageUnits(Shader::Type::TessellationEvaluation))
    _l(Shader::maxTextureImageUnits(Shader::Type::Geometry))
    _l(Shader::maxTextureImageUnits(Shader::Type::Compute))
    #endif
    _l(Shader::maxTextureImageUnits(Shader::Type::Fragment))
    _l(Shader::maxCombinedTextureImageUnits())
    _l(Shader::maxUniformComponents(Shader::Type::Vertex))
    #ifndef MAGNUM_TARGET_GLES
    _l(Shader::maxUniformComponents(Shader::Type::TessellationControl))
    _l(Shader::maxUniformComponents(Shader::Type::TessellationEvaluation))
    _l(Shader::maxUniformComponents(Shader::Type::Geometry))
    _l(Shader::maxUniformComponents(Shader::Type::Compute))
    #endif
    _l(Shader::maxUniformComponents(Shader::Type::Fragment))
    #ifndef MAGNUM_TARGET_GLES
    _l(AbstractShaderProgram::maxUniformLocations())
    #endif
    _l(AbstractShaderProgram::maxVertexAttributes())
    #ifndef MAGNUM_TARGET_GLES
    _l(AbstractTexture::maxColorSamples())
    _l(AbstractTexture::maxDepthSamples())
    _l(AbstractTexture::maxIntegerSamples())
    #endif

    #ifndef MAGNUM_TARGET_GLES
    if(c->isExtensionSupported<Extensions::GL::ARB::blend_func_extended>()) {
        _h(ARB::blend_func_extended)

        _l(AbstractFramebuffer::maxDualSourceDrawBuffers())
    }

    if(c->isExtensionSupported<Extensions::GL::ARB::compute_shader>()) {
        _h(ARB::compute_shader)

        _l(AbstractShaderProgram::maxComputeSharedMemorySize())
        _l(AbstractShaderProgram::maxComputeWorkGroupInvocations())
    }

    if(c->isExtensionSupported<Extensions::GL::ARB::geometry_shader4>()) {
        _h(ARB::geometry_shader4)

        _l(Shader::maxGeometryInputComponents())
        _l(Shader::maxGeometryOutputComponents())
        _l(Shader::maxGeometryTotalOutputComponents())
    }

    if(c->isExtensionSupported<Extensions::GL::ARB::shader_atomic_counters>()) {
        _h(ARB::shader_atomic_counters)

        _l(Buffer::maxAtomicCounterBindings())
        _l(Shader::maxAtomicCounterBuffers(Shader::Type::Vertex))
        _l(Shader::maxAtomicCounterBuffers(Shader::Type::TessellationControl))
        _l(Shader::maxAtomicCounterBuffers(Shader::Type::TessellationEvaluation))
        _l(Shader::maxAtomicCounterBuffers(Shader::Type::Geometry))
        _l(Shader::maxAtomicCounterBuffers(Shader::Type::Compute))
        _l(Shader::maxAtomicCounterBuffers(Shader::Type::Fragment))
        _l(Shader::maxCombinedAtomicCounterBuffers())
        _l(Shader::maxAtomicCounters(Shader::Type::Vertex))
        _l(Shader::maxAtomicCounters(Shader::Type::TessellationControl))
        _l(Shader::maxAtomicCounters(Shader::Type::TessellationEvaluation))
        _l(Shader::maxAtomicCounters(Shader::Type::Geometry))
        _l(Shader::maxAtomicCounters(Shader::Type::Compute))
        _l(Shader::maxAtomicCounters(Shader::Type::Fragment))
        _l(Shader::maxCombinedAtomicCounters())
        _l(AbstractShaderProgram::maxAtomicCounterBufferSize())
    }

    if(c->isExtensionSupported<Extensions::GL::ARB::shader_image_load_store>()) {
        _h(ARB::shader_image_load_store)

        _l(Shader::maxImageUniforms(Shader::Type::Vertex))
        _l(Shader::maxImageUniforms(Shader::Type::TessellationControl))
        _l(Shader::maxImageUniforms(Shader::Type::TessellationEvaluation))
        _l(Shader::maxImageUniforms(Shader::Type::Geometry))
        _l(Shader::maxImageUniforms(Shader::Type::Compute))
        _l(Shader::maxImageUniforms(Shader::Type::Fragment))
        _l(Shader::maxCombinedImageUniforms())
        _l(AbstractShaderProgram::maxCombinedShaderOutputResources())
        _l(AbstractShaderProgram::maxImageUnits())
        _l(AbstractShaderProgram::maxImageSamples())
    }

    if(c->isExtensionSupported<Extensions::GL::ARB::shader_storage_buffer_object>()) {
        _h(ARB::shader_storage_buffer_object)

        _l(Shader::maxShaderStorageBlocks(Shader::Type::Vertex))
        _l(Shader::maxShaderStorageBlocks(Shader::Type::TessellationControl))
        _l(Shader::maxShaderStorageBlocks(Shader::Type::TessellationEvaluation))
        _l(Shader::maxShaderStorageBlocks(Shader::Type::Geometry))
        _l(Shader::maxShaderStorageBlocks(Shader::Type::Compute))
        _l(Shader::maxShaderStorageBlocks(Shader::Type::Fragment))
        _l(Shader::maxCombinedShaderStorageBlocks())
        /* AbstractShaderProgram::maxCombinedShaderOutputResources() already in shader_image_load_store */
        _l(AbstractShaderProgram::maxShaderStorageBlockSize())
    }

    if(c->isExtensionSupported<Extensions::GL::ARB::tessellation_shader>()) {
        _h(ARB::tessellation_shader)

        _l(Buffer::shaderStorageOffsetAlignment())
        _l(Buffer::maxShaderStorageBindings())
        _l(Shader::maxTessellationControlInputComponents())
        _l(Shader::maxTessellationControlOutputComponents())
        _l(Shader::maxTessellationControlTotalOutputComponents())
        _l(Shader::maxTessellationEvaluationInputComponents())
        _l(Shader::maxTessellationEvaluationOutputComponents())
    }

    if(c->isExtensionSupported<Extensions::GL::ARB::texture_buffer_range>()) {
        _h(ARB::texture_buffer_range)

        _l(BufferTexture::offsetAlignment())
    }
    #endif

    /** @todo Somehow sort the following into previous list for ES3 */

    #ifndef MAGNUM_TARGET_GLES2
    #ifndef MAGNUM_TARGET_GLES
    if(c->isExtensionSupported<Extensions::GL::ARB::uniform_buffer_object>())
    #endif
    {
        #ifndef MAGNUM_TARGET_GLES
        _h(ARB::uniform_buffer_object)
        #endif

        _l(Shader::maxUniformBlocks(Shader::Type::Vertex))
        #ifndef MAGNUM_TARGET_GLES
        _l(Shader::maxUniformBlocks(Shader::Type::TessellationControl))
        _l(Shader::maxUniformBlocks(Shader::Type::TessellationEvaluation))
        _l(Shader::maxUniformBlocks(Shader::Type::Geometry))
        _l(Shader::maxUniformBlocks(Shader::Type::Compute))
        #endif
        _l(Shader::maxUniformBlocks(Shader::Type::Fragment))
        _l(Shader::maxCombinedUniformBlocks())
        _l(Shader::maxCombinedUniformComponents(Shader::Type::Vertex))
        #ifndef MAGNUM_TARGET_GLES
        _l(Shader::maxCombinedUniformComponents(Shader::Type::TessellationControl))
        _l(Shader::maxCombinedUniformComponents(Shader::Type::TessellationEvaluation))
        _l(Shader::maxCombinedUniformComponents(Shader::Type::Geometry))
        _l(Shader::maxCombinedUniformComponents(Shader::Type::Compute))
        #endif
        _l(Shader::maxCombinedUniformComponents(Shader::Type::Fragment))
        _l(AbstractShaderProgram::maxUniformBlockSize())
    }

    #ifndef MAGNUM_TARGET_GLES
    if(c->isExtensionSupported<Extensions::GL::EXT::gpu_shader4>())
    #endif
    {
        #ifndef MAGNUM_TARGET_GLES
        _h(EXT::gpu_shader4)
        #endif

        _l(Buffer::maxUniformBindings())
        _l(AbstractShaderProgram::minTexelOffset())
        _l(AbstractShaderProgram::maxTexelOffset())
    }
    #endif

    if(c->isExtensionSupported<Extensions::GL::EXT::texture_filter_anisotropic>()) {
        _h(EXT::texture_filter_anisotropic)

        _l(Sampler::maxMaxAnisotropy())
    }

    if(c->isExtensionSupported<Extensions::GL::KHR::debug>()) {
        _h(KHR::debug)

        _l(AbstractObject::maxLabelLength())
        _l(DebugMessage::maxLoggedMessages())
        _l(DebugMessage::maxMessageLength())
    }

    #undef _l
    #undef _h
}

}

MAGNUM_WINDOWLESSAPPLICATION_MAIN(Magnum::MagnumInfo)
<|endoftext|>


<commit_before>// For conditions of distribution and use, see copyright notice in license.txt

#include "StableHeaders.h"
#include "DebugOperatorNew.h"
#include "UiDefines.h"

#include "InworldSceneController.h"
#include "ControlPanelManager.h"

#include "Common/AnchorLayoutManager.h"

#include "Menus/MenuManager.h"

#include "View/UiProxyWidget.h"
#include "View/UiWidgetProperties.h"
#include "View/CommunicationWidget.h"

#include "Inworld/ControlPanel/SettingsWidget.h"
#include "Inworld/ControlPanel/PersonalWidget.h"

#include <QRectF>
#include <QGraphicsItem>
#include <QGraphicsLinearLayout>
#include <QGraphicsWidget>
#include <QGraphicsView>
#include <QGraphicsScene>

#include "MemoryLeakCheck.h"

#include <QDebug>

namespace UiServices
{
    InworldSceneController::InworldSceneController(Foundation::Framework *framework, QGraphicsView *ui_view)
        : QObject(),
          framework_(framework),
          ui_view_(ui_view),
          communication_widget_(0)
    {
        if (!ui_view_)
            return;

        // Store scene pointer
        inworld_scene_ = ui_view_->scene();

        // Init layout manager with scene
        layout_manager_ = new CoreUi::AnchorLayoutManager(this, inworld_scene_);

        // Init UI managers with layout manager
        control_panel_manager_ = new CoreUi::ControlPanelManager(this, layout_manager_);
        menu_manager_ = new CoreUi::MenuManager(this, layout_manager_);

        // Communication core UI
        communication_widget_ = new CoreUi::CommunicationWidget();
        layout_manager_->AddCornerAnchor(communication_widget_, Qt::BottomLeftCorner, Qt::BottomLeftCorner);

        // Connect settings widget
        connect(control_panel_manager_->GetSettingsWidget(), SIGNAL(NewUserInterfaceSettingsApplied(int, int)), SLOT(ApplyNewProxySettings(int, int)));

	//apply new positions to active widgets when the inworld_scene_ is resized
	connect(inworld_scene_, SIGNAL(sceneRectChanged(const QRectF)), this, SLOT(ApplyNewProxyPosition(const QRectF)));
    }

    InworldSceneController::~InworldSceneController()
    {
        SAFE_DELETE(communication_widget_);
    }

    /*************** UI Scene Manager Public Services ***************/

    bool InworldSceneController::AddSettingsWidget(QWidget *settings_widget, const QString &tab_name) const
    {
        control_panel_manager_->GetSettingsWidget()->AddWidget(settings_widget, tab_name);
        return true;
    }

    UiProxyWidget* InworldSceneController::AddWidgetToScene(QWidget *widget)
    {
        return AddWidgetToScene(widget, UiWidgetProperties("Unnamed Widget", ModuleWidget));
    }

    UiProxyWidget* InworldSceneController::AddWidgetToScene(QWidget *widget, const UiServices::UiWidgetProperties &widget_properties)
    {
        UiProxyWidget *proxy_widget = new UiProxyWidget(widget, widget_properties);
        if (AddProxyWidget(proxy_widget))
            return proxy_widget;
        else
            return 0;
    }

    bool InworldSceneController::AddProxyWidget(UiServices::UiProxyWidget *proxy_widget)
    {
        if (!inworld_scene_)
        {
            SAFE_DELETE(proxy_widget);
            return false;
        }

        // Add to scene
        if (proxy_widget->isVisible())
            proxy_widget->hide();
        inworld_scene_->addItem(proxy_widget);

        // Add to internal control list
        if (!all_proxy_widgets_in_scene_.contains(proxy_widget))
            all_proxy_widgets_in_scene_.append(proxy_widget);

        // Add to menu structure if its needed
        UiWidgetProperties properties = proxy_widget->GetWidgetProperties();
        if (properties.IsShownInToolbar())
        {
            QString widget_name = properties.GetWidgetName();
            if (widget_name == "Inventory")
                control_panel_manager_->GetPersonalWidget()->SetInventoryWidget(proxy_widget);
            else if (widget_name == "Avatar Editor")
                control_panel_manager_->GetPersonalWidget()->SetAvatarWidget(proxy_widget);
            else
                menu_manager_->AddMenuItem(CoreUi::MenuManager::Root, proxy_widget, properties);

            connect(proxy_widget, SIGNAL( BringProxyToFrontRequest(UiProxyWidget*) ), this, SLOT( BringProxyToFront(UiProxyWidget*) ));
        }
        return true;
    }

    void InworldSceneController::RemoveProxyWidgetFromScene(UiServices::UiProxyWidget *proxy_widget)
    {
        if (!inworld_scene_)
            return;

        QString widget_name = proxy_widget->GetWidgetProperties().GetWidgetName();
        if (widget_name != "Inventory" && widget_name != "Avatar Editor")
            menu_manager_->RemoveMenuItem(CoreUi::MenuManager::Root, proxy_widget);
        inworld_scene_->removeItem(proxy_widget);
        all_proxy_widgets_in_scene_.removeOne(proxy_widget);
    }

    void InworldSceneController::RemoveProxyWidgetFromScene(QWidget *widget)
    {
        UiProxyWidget *proxy_widget = dynamic_cast<UiProxyWidget*>(widget->graphicsProxyWidget());
        if (proxy_widget)
            RemoveProxyWidgetFromScene(proxy_widget);
    }

    void InworldSceneController::BringProxyToFront(UiProxyWidget *widget) const
    {
        if (!inworld_scene_ || !inworld_scene_->isActive())
            return;
        inworld_scene_->setActiveWindow(widget);
        inworld_scene_->setFocusItem(widget, Qt::ActiveWindowFocusReason);
    }

    void InworldSceneController::BringProxyToFront(QWidget *widget) const
    {
        if (!inworld_scene_)
            return;
        ShowProxyForWidget(widget);
        inworld_scene_->setActiveWindow(widget->graphicsProxyWidget());
        inworld_scene_->setFocusItem(widget->graphicsProxyWidget(), Qt::ActiveWindowFocusReason);
    }

    void InworldSceneController::ShowProxyForWidget(QWidget *widget) const
    {
        if (inworld_scene_)
            widget->graphicsProxyWidget()->show();
    }

    void InworldSceneController::HideProxyForWidget(QWidget *widget) const
    {
        if (inworld_scene_)
            widget->graphicsProxyWidget()->hide();
    }

    QObject *InworldSceneController::GetSettingsObject() const
    {
        return dynamic_cast<QObject *>(control_panel_manager_->GetSettingsWidget());
    }

    void InworldSceneController::SetFocusToChat() const
    {
        if (communication_widget_)
            communication_widget_->SetFocusToChat();
    }

    // Don't touch, please

    void InworldSceneController::SetWorldChatController(QObject *controller) const
    {
        if (communication_widget_)
            communication_widget_->UpdateController(controller);
    }

    void InworldSceneController::SetImWidget(UiProxyWidget *im_proxy) const
    {
        if (communication_widget_)
            communication_widget_->UpdateImWidget(im_proxy);
    }

    // Private

    void InworldSceneController::ApplyNewProxySettings(int new_opacity, int new_animation_speed) const
    {
        foreach (UiProxyWidget *widget, all_proxy_widgets_in_scene_)
        {
            widget->SetUnfocusedOpacity(new_opacity);
            widget->SetShowAnimationSpeed(new_animation_speed);
        }
    }
	//Apply new proxy position
    void InworldSceneController::ApplyNewProxyPosition(const QRectF &new_rect)
	{
		QPointF left_distance;
		QPointF right_distance;
		foreach (UiProxyWidget *widget, all_proxy_widgets_in_scene_)
        	{
			if(widget->isVisible())
			{
				left_distance.setX(widget->x() / last_scene_rect.width() * new_rect.width());
				left_distance.setY(widget->y() / last_scene_rect.height() * new_rect.height());

				right_distance.setX((widget->x() + widget->size().width()) / last_scene_rect.width() * new_rect.width());
				right_distance.setY((widget->y() + widget->size().height()) / last_scene_rect.height() * new_rect.height());
			}

			if(new_rect.contains(right_distance))
			{
				if(widget->size().width() < new_rect.width() && right_distance.x() > new_rect.width() / 2)
				{
					widget->setX(right_distance.x() - widget->size().width());
				}
				else
				{
					widget->setX(left_distance.x());
				}
			}else
			{
				widget->setX(left_distance.x());
			}

			if(new_rect.contains(right_distance))
			{
				if(widget->size().height() < new_rect.height())
				{
					widget->setY(right_distance.y() - widget->size().height());
				}
				else
				{
					widget->setY(left_distance.y());
				}
			}
			else
			{
				widget->setY(left_distance.y());
			}
        	}
		last_scene_rect = new_rect;
	}
}
<commit_msg>Moving widgets when resizing modified. Few more conditions added.<commit_after>// For conditions of distribution and use, see copyright notice in license.txt

#include "StableHeaders.h"
#include "DebugOperatorNew.h"
#include "UiDefines.h"

#include "InworldSceneController.h"
#include "ControlPanelManager.h"

#include "Common/AnchorLayoutManager.h"

#include "Menus/MenuManager.h"

#include "View/UiProxyWidget.h"
#include "View/UiWidgetProperties.h"
#include "View/CommunicationWidget.h"

#include "Inworld/ControlPanel/SettingsWidget.h"
#include "Inworld/ControlPanel/PersonalWidget.h"

#include <QRectF>
#include <QGraphicsItem>
#include <QGraphicsLinearLayout>
#include <QGraphicsWidget>
#include <QGraphicsView>
#include <QGraphicsScene>

#include "MemoryLeakCheck.h"

namespace UiServices
{
    InworldSceneController::InworldSceneController(Foundation::Framework *framework, QGraphicsView *ui_view)
        : QObject(),
          framework_(framework),
          ui_view_(ui_view),
          communication_widget_(0)
    {
        if (!ui_view_)
            return;

        // Store scene pointer
        inworld_scene_ = ui_view_->scene();

        // Init layout manager with scene
        layout_manager_ = new CoreUi::AnchorLayoutManager(this, inworld_scene_);

        // Init UI managers with layout manager
        control_panel_manager_ = new CoreUi::ControlPanelManager(this, layout_manager_);
        menu_manager_ = new CoreUi::MenuManager(this, layout_manager_);

        // Communication core UI
        communication_widget_ = new CoreUi::CommunicationWidget();
        layout_manager_->AddCornerAnchor(communication_widget_, Qt::BottomLeftCorner, Qt::BottomLeftCorner);

        // Connect settings widget
        connect(control_panel_manager_->GetSettingsWidget(), SIGNAL(NewUserInterfaceSettingsApplied(int, int)), SLOT(ApplyNewProxySettings(int, int)));

	//apply new positions to active widgets when the inworld_scene_ is resized
	connect(inworld_scene_, SIGNAL(sceneRectChanged(const QRectF)), this, SLOT(ApplyNewProxyPosition(const QRectF)));
    }

    InworldSceneController::~InworldSceneController()
    {
        SAFE_DELETE(communication_widget_);
    }

    /*************** UI Scene Manager Public Services ***************/

    bool InworldSceneController::AddSettingsWidget(QWidget *settings_widget, const QString &tab_name) const
    {
        control_panel_manager_->GetSettingsWidget()->AddWidget(settings_widget, tab_name);
        return true;
    }

    UiProxyWidget* InworldSceneController::AddWidgetToScene(QWidget *widget)
    {
        return AddWidgetToScene(widget, UiWidgetProperties("Unnamed Widget", ModuleWidget));
    }

    UiProxyWidget* InworldSceneController::AddWidgetToScene(QWidget *widget, const UiServices::UiWidgetProperties &widget_properties)
    {
        UiProxyWidget *proxy_widget = new UiProxyWidget(widget, widget_properties);
        if (AddProxyWidget(proxy_widget))
            return proxy_widget;
        else
            return 0;
    }

    bool InworldSceneController::AddProxyWidget(UiServices::UiProxyWidget *proxy_widget)
    {
        if (!inworld_scene_)
        {
            SAFE_DELETE(proxy_widget);
            return false;
        }

        // Add to scene
        if (proxy_widget->isVisible())
            proxy_widget->hide();
        inworld_scene_->addItem(proxy_widget);

        // Add to internal control list
        if (!all_proxy_widgets_in_scene_.contains(proxy_widget))
            all_proxy_widgets_in_scene_.append(proxy_widget);

        // Add to menu structure if its needed
        UiWidgetProperties properties = proxy_widget->GetWidgetProperties();
        if (properties.IsShownInToolbar())
        {
            QString widget_name = properties.GetWidgetName();
            if (widget_name == "Inventory")
                control_panel_manager_->GetPersonalWidget()->SetInventoryWidget(proxy_widget);
            else if (widget_name == "Avatar Editor")
                control_panel_manager_->GetPersonalWidget()->SetAvatarWidget(proxy_widget);
            else
                menu_manager_->AddMenuItem(CoreUi::MenuManager::Root, proxy_widget, properties);

            connect(proxy_widget, SIGNAL( BringProxyToFrontRequest(UiProxyWidget*) ), this, SLOT( BringProxyToFront(UiProxyWidget*) ));
        }
        return true;
    }

    void InworldSceneController::RemoveProxyWidgetFromScene(UiServices::UiProxyWidget *proxy_widget)
    {
        if (!inworld_scene_)
            return;

        QString widget_name = proxy_widget->GetWidgetProperties().GetWidgetName();
        if (widget_name != "Inventory" && widget_name != "Avatar Editor")
            menu_manager_->RemoveMenuItem(CoreUi::MenuManager::Root, proxy_widget);
        inworld_scene_->removeItem(proxy_widget);
        all_proxy_widgets_in_scene_.removeOne(proxy_widget);
    }

    void InworldSceneController::RemoveProxyWidgetFromScene(QWidget *widget)
    {
        UiProxyWidget *proxy_widget = dynamic_cast<UiProxyWidget*>(widget->graphicsProxyWidget());
        if (proxy_widget)
            RemoveProxyWidgetFromScene(proxy_widget);
    }

    void InworldSceneController::BringProxyToFront(UiProxyWidget *widget) const
    {
        if (!inworld_scene_ || !inworld_scene_->isActive())
            return;
        inworld_scene_->setActiveWindow(widget);
        inworld_scene_->setFocusItem(widget, Qt::ActiveWindowFocusReason);
    }

    void InworldSceneController::BringProxyToFront(QWidget *widget) const
    {
        if (!inworld_scene_)
            return;
        ShowProxyForWidget(widget);
        inworld_scene_->setActiveWindow(widget->graphicsProxyWidget());
        inworld_scene_->setFocusItem(widget->graphicsProxyWidget(), Qt::ActiveWindowFocusReason);
    }

    void InworldSceneController::ShowProxyForWidget(QWidget *widget) const
    {
        if (inworld_scene_)
            widget->graphicsProxyWidget()->show();
    }

    void InworldSceneController::HideProxyForWidget(QWidget *widget) const
    {
        if (inworld_scene_)
            widget->graphicsProxyWidget()->hide();
    }

    QObject *InworldSceneController::GetSettingsObject() const
    {
        return dynamic_cast<QObject *>(control_panel_manager_->GetSettingsWidget());
    }

    void InworldSceneController::SetFocusToChat() const
    {
        if (communication_widget_)
            communication_widget_->SetFocusToChat();
    }

    // Don't touch, please

    void InworldSceneController::SetWorldChatController(QObject *controller) const
    {
        if (communication_widget_)
            communication_widget_->UpdateController(controller);
    }

    void InworldSceneController::SetImWidget(UiProxyWidget *im_proxy) const
    {
        if (communication_widget_)
            communication_widget_->UpdateImWidget(im_proxy);
    }

    // Private

    void InworldSceneController::ApplyNewProxySettings(int new_opacity, int new_animation_speed) const
    {
        foreach (UiProxyWidget *widget, all_proxy_widgets_in_scene_)
        {
            widget->SetUnfocusedOpacity(new_opacity);
            widget->SetShowAnimationSpeed(new_animation_speed);
        }
    }

    //Apply new proxy position
    void InworldSceneController::ApplyNewProxyPosition(const QRectF &new_rect)
	{
		QPointF left_distance;
		QPointF right_distance;
		foreach (UiProxyWidget *widget, all_proxy_widgets_in_scene_)
        	{
			if(widget->isVisible())
			{
				left_distance.setX(widget->x() / last_scene_rect.width() * new_rect.width());
				left_distance.setY(widget->y() / last_scene_rect.height() * new_rect.height());

				right_distance.setX((widget->x() + widget->size().width()) / last_scene_rect.width() * new_rect.width());
				right_distance.setY((widget->y() + widget->size().height()) / last_scene_rect.height() * new_rect.height());
			}

			if(widget->size().width() < new_rect.width())
			{
				if(left_distance.x() > widget->size().width())
				{
					if(new_rect.width() > right_distance.x())
					{
						widget->setX(right_distance.x() - widget->size().width());
					}
					else
					{
						widget->setX(left_distance.x());
					}
				}
				else
				{
					widget->setX(left_distance.x());
				}
			}
			else
			{
				widget->setX(left_distance.x());
			}

			if(widget->size().height() < new_rect.height())
			{
				if(left_distance.y() > widget->size().height())
				{
					if(new_rect.height() > right_distance.y())
					{
						widget->setY(right_distance.y() - widget->size().height());
					}
					else
					{
						widget->setY(left_distance.y());
					}
				}
				else
				{
					widget->setY(left_distance.y());
				}
			}
			else
			{
				widget->setY(left_distance.y());
			}
        	}
		last_scene_rect = new_rect;
	}
}
<|endoftext|>


<commit_before>/*
gpe_scene_background_class.cpp
This file is part of:
GAME PENCIL ENGINE
https://create.pawbyte.com
Copyright (c) 2014-2020 Nathan Hurde, Chase Lee.

Copyright (c) 2014-2020 PawByte LLC.
Copyright (c) 2014-2020 Game Pencil Engine contributors ( Contributors Page )

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the “Software”), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

-Game Pencil Engine <https://create.pawbyte.com>

*/

#include "gpe_scene_background_class.h"

GPE_SceneBackground::GPE_SceneBackground(GPE_GeneralResourceContainer *pFolder)
{
    branchType = BRANCH_TYPE_BACKGROUND;
    iconTexture = guiRCM->texture_add( APP_DIRECTORY_NAME+"resources/gfx/iconpacks/fontawesome/image.png") ;

    textureId = -1;
    texRes = NULL;
    inFront = false;
    tileHori = false;
    tileVert = false;
    stretchBG = false;
    bgXSpeed = 0;
    bgYSpeed =0;
    projectParentFolder = pFolder;

    if( projectParentFolder!=NULL)
    {
        backgroundInEditor = new GPE_DropDown_Resouce_Menu( "Background Texture",projectParentFolder->find_resource_from_name(RESOURCE_TYPE_NAMES[RESOURCE_TYPE_TEXTURE]+"s"),-1,true);
        backgroundInEditor->set_width(192);
    }
    else
    {
        backgroundInEditor = NULL;
    }

    bgHorSpeedField = new GPE_TextInputNumber("","");
    bgHorSpeedField->set_string("0");
    bgHorSpeedField->set_label("H-Speed");
    bgHorSpeedField->scale_width( 0.4 );

    bgVertSpeedField = new GPE_TextInputNumber("","");
    bgVertSpeedField->set_string("0");
    bgVertSpeedField->set_label("V-Speed");
    bgVertSpeedField->scale_width( 0.4 );

    checkTileHori = new GPE_CheckBoxBasic("Tile-Hori","Repeat Tile Horizontally to fill the scene" );
    checkTileVert = new GPE_CheckBoxBasic("Tile-Vert","Repeat Tile Vertically to fill the scene" );
    checkStretch = new GPE_CheckBoxBasic("Stretch BG","Stretch across the entire scene" );

}

GPE_SceneBackground::~GPE_SceneBackground()
{

}

void GPE_SceneBackground::add_typed_elements()
{
    if( PANEL_INSPECTOR!=NULL )
    {
        PANEL_INSPECTOR->add_gui_element( backgroundInEditor, true );
        PANEL_INSPECTOR->add_gui_element( bgHorSpeedField, false );
        PANEL_INSPECTOR->add_gui_element( bgVertSpeedField, true );

        PANEL_INSPECTOR->add_gui_element( checkTileHori, true );
        PANEL_INSPECTOR->add_gui_element( checkTileVert, true );
        PANEL_INSPECTOR->add_gui_element( checkStretch, true );
    }
}

bool GPE_SceneBackground::build_intohtml5_file( std::ofstream * fileTarget, int leftTabAmount,  GPE_GeneralResourceContainer * localResTypeController )
{
    GPE_GeneralResourceContainer * allTexturesFolder = localResTypeController->find_resource_from_name(RESOURCE_TYPE_NAMES[RESOURCE_TYPE_TEXTURE]+"s");
    if( allTexturesFolder == NULL)
    {
        GPE_SceneBasicClass::build_intohtml5_file( fileTarget, leftTabAmount+1, localResTypeController);
        return false;
    }
    std::string nestedTabsStr = generate_tabs( leftTabAmount );
     GPE_GeneralResourceContainer * tempBgResource = allTexturesFolder->find_resource_from_id( textureId);
    if( tempBgResource!=NULL)
    {
        *fileTarget << nestedTabsStr << "newBranch = _scn_temp_layer.scnStartBackgrounds.push( {bgTexId:" <<int_to_string(tempBgResource->exportBuildGlobalId) << ",";

        *fileTarget << "bgXPos: " << int_to_string( xPos) << ",";
        *fileTarget << "bgYPos: " << int_to_string( yPos) << ",";
        *fileTarget << "bgXSpeed: " << int_to_string(bgXSpeed) << ",";
        *fileTarget << "bgYSpeed: " << int_to_string(bgYSpeed) << ",";
        *fileTarget << "bgTileHori: " << int_to_string(tileHori) << ",";
        *fileTarget << "bgTileVert: " << int_to_string(tileVert) << ",";
        *fileTarget << "bgStartStretch: " << int_to_string(stretchBG);
        *fileTarget << "} ); \n";
    }
    else
    {
        *fileTarget << nestedTabsStr << "newBranch = _scn_temp_layer.scnStartBackground = -1; \n";
    }
    GPE_SceneBasicClass::build_intohtml5_file( fileTarget, leftTabAmount+1, localResTypeController);
    return true;
}

void GPE_SceneBackground::calculate_size()
{

}

void GPE_SceneBackground::process_elements()
{
    GPE_SceneBasicClass::process_elements();
    textureId = backgroundInEditor->get_selected_id();
    if(backgroundInEditor->get_selected_id() > 0)
    {
        bgXSpeed = bgHorSpeedField->get_held_number();
        bgYSpeed = bgVertSpeedField->get_held_number();
        tileHori =checkTileHori->is_clicked();
        tileVert =checkTileVert->is_clicked();
        stretchBG =checkStretch->is_clicked();
    }
}

void GPE_SceneBackground::render_branch()
{
    if( spm->cSceneTexList == NULL )
    {
        return;
    }
    GPE_GeneralResourceContainer * texTypeContainer = spm->cSceneTexList->find_resource_from_id(textureId );
    if( texTypeContainer!=NULL)
    {
        spm->tempRect->x = floor( (xPos*spm->zoomValue)- spm->cameraFloorXPos);
        spm->tempRect->y = floor( (yPos*spm->zoomValue)- spm->cameraFloorYPos );
        textureResource * texRes = (textureResource*) texTypeContainer->get_held_resource();

        int bgXItr = 0, bgYItr= 0;
        if( texRes!=NULL && texRes->textureInEditor!=NULL )
        {
            if( texRes->textureInEditor->get_width() >0 && texRes->textureInEditor->get_height() >0 )
            {
                spm->tempRect->x = floor( (xPos* spm->zoomValue)- spm->cameraFloorXPos );
                spm->tempRect->y = floor( (yPos* spm->zoomValue)- spm->cameraFloorYPos );
                if( stretchBG)
                {
                    texRes->textureInEditor->render_tex_resized( 0,0,spm->currentCamera->w,spm->currentCamera->h,NULL, branchColor->get_color(), branchAlpha->get_value()  );
                }
                else if(tileHori  )
                {
                    for( bgXItr = spm->tempRect->x; bgXItr <=( spm->sWidth)*spm->zoomValue; bgXItr+=texRes->textureInEditor->get_width()* spm->zoomValue )
                    {
                        if( tileVert)
                        {
                            for(bgYItr = spm->tempRect->y; bgYItr <= ( spm->sHeight )* spm->zoomValue; bgYItr+=texRes->textureInEditor->get_height()* spm->zoomValue )
                            {
                                texRes->textureInEditor->render_tex_scaled( floor(bgXItr),floor(bgYItr), spm->zoomValue, spm->zoomValue, NULL, branchColor->get_color(), branchAlpha->get_value() );
                            }
                        }
                        else
                        {
                            texRes->textureInEditor->render_tex_scaled( floor( bgXItr ),floor(spm->tempRect->y), spm->zoomValue, spm->zoomValue, NULL, branchColor->get_color(), branchAlpha->get_value() );
                        }
                    }
                }
                else if(tileVert)
                {
                    for(bgYItr = spm->tempRect->y; bgYItr <=( spm->sHeight)*spm->zoomValue; bgYItr+=texRes->textureInEditor->get_height()* spm->zoomValue )
                    {
                        texRes->textureInEditor->render_tex_scaled( floor(spm->tempRect->x),floor( bgYItr ),spm->zoomValue ,spm->zoomValue,NULL, branchColor->get_color(), branchAlpha->get_value()  );
                    }
                }
                else
                {
                    texRes->textureInEditor->render_tex_scaled( floor(spm->tempRect->x),floor(spm->tempRect->y), spm->zoomValue , spm->zoomValue ,NULL, branchColor->get_color(), branchAlpha->get_value()  );
                }
            }
        }
    }
    GPE_SpecialMenu_Branch::render_branch();
}

bool GPE_SceneBackground::save_branch_data(std::ofstream * fileTarget, int nestedFoldersIn  )
{
    if( fileTarget!=NULL && fileTarget->is_open() )
    {
        std::string nestedTabsStr = generate_tabs( nestedFoldersIn );
        *fileTarget << nestedTabsStr+"   GPE_Background=";
        if( backgroundInEditor!=NULL)
        {
            *fileTarget << backgroundInEditor->get_selected_name() << ",";
        }
        else
        {
            *fileTarget << "-1,";
        }
        if( xPosField!=NULL)
        {
            xPosField->make_valid_number(0);
            *fileTarget <<  xPosField->get_held_number() << ",";
        }
        else
        {
            *fileTarget << "-1,";
        }
        if( yPosField!=NULL)
        {
            yPosField->make_valid_number(0);
            *fileTarget << yPosField->get_held_number() << ",";
        }
        else
        {
            *fileTarget << "-1,";
        }
        if( bgHorSpeedField!=NULL)
        {
            bgHorSpeedField->make_valid_number(0);
            *fileTarget << bgHorSpeedField->get_held_number() << ",";
        }
        else
        {
            *fileTarget << "-1,";
        }
        if( bgVertSpeedField!=NULL)
        {
            bgVertSpeedField->make_valid_number(0);
            *fileTarget << bgVertSpeedField->get_held_number() << ",";
        }
        else
        {
            *fileTarget << "-1,";
        }
        if( checkTileHori!=NULL)
        {
            *fileTarget << checkTileHori->is_clicked() << ",";
        }
        else
        {
            *fileTarget << "-1,";
        }
        if( checkTileVert!=NULL)
        {
            *fileTarget << checkTileVert->is_clicked() << ",";
        }
        else
        {
            *fileTarget << "-1,";
        }
        if( checkStretch!=NULL)
        {
            *fileTarget << checkStretch->is_clicked() << ",";
        }
        else
        {
            *fileTarget << "-1,";
        }
        *fileTarget << opName+",";
        *fileTarget << "\n";
        GPE_SceneBasicClass::save_branch_data( fileTarget, nestedFoldersIn+1 );
        return true;
    }
    return false;
}
<commit_msg>Delete gpe_scene_background_class.cpp<commit_after><|endoftext|>


<commit_before>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkRendererSource.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 1993-1996 Ken Martin, Will Schroeder, Bill Lorensen.

This software is copyrighted by Ken Martin, Will Schroeder and Bill Lorensen.
The following terms apply to all files associated with the software unless
explicitly disclaimed in individual files. This copyright specifically does
not apply to the related textbook "The Visualization Toolkit" ISBN
013199837-4 published by Prentice Hall which is covered by its own copyright.

The authors hereby grant permission to use, copy, and distribute this
software and its documentation for any purpose, provided that existing
copyright notices are retained in all copies and that this notice is included
verbatim in any distributions. Additionally, the authors grant permission to
modify this software and its documentation for any purpose, provided that
such modifications are not distributed without the explicit consent of the
authors and that existing copyright notices are retained in all copies. Some
of the algorithms implemented by this software are patented, observe all
applicable patent law.

IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR
DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF,
EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE IS PROVIDED ON AN
"AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE
MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.

=========================================================================*/
#include "vtkRendererSource.h"
#include "vtkRenderWindow.h"
#include "vtkPixmap.h"

vtkRendererSource::vtkRendererSource()
{
  this->Input = NULL;
}

void vtkRendererSource::Execute()
{
  int numOutPts;
  vtkPixmap *outScalars;
  float x1,y1,x2,y2;
  unsigned char *pixels;
  int dims[3];
  vtkStructuredPoints *output=(vtkStructuredPoints *)this->Output;

  vtkDebugMacro(<<"Converting points");

  if (this->Input == NULL )
    {
    vtkErrorMacro(<<"Please specify a renderer as input!");
    return;
    }

  // calc the pixel range for the renderer
  this->Input->SetViewPoint(-1,-1,0);
  this->Input->ViewToDisplay();
  x1 = this->Input->GetDisplayPoint()[0];
  y1 = this->Input->GetDisplayPoint()[1];
  this->Input->SetViewPoint(1,1,0);
  this->Input->ViewToDisplay();
  x2 = this->Input->GetDisplayPoint()[0];
  y2 = this->Input->GetDisplayPoint()[1];

  if (x1 < 0) x1 = 0;
  if (y1 < 0) y1 = 0;
  if (x2 >= (this->Input->GetRenderWindow())->GetSize()[0])
    {
    x2 = (this->Input->GetRenderWindow())->GetSize()[0] - 1;
    }
  if (y2 >= (this->Input->GetRenderWindow())->GetSize()[1])
    {
    y2 = (this->Input->GetRenderWindow())->GetSize()[1] - 1;
    }

  if (this->WholeWindow)
    {
    x1 = 0;
    y1 = 0;
    x2 = (this->Input->GetRenderWindow())->GetSize()[0] - 1;
    y2 = (this->Input->GetRenderWindow())->GetSize()[1] - 1;
    }

  // Get origin, aspect ratio and dimensions from this->Input
  dims[0] = (int)(x2 - x1 + 1); dims[1] = (int)(y2 -y1 + 1); dims[2] = 1;
  output->SetDimensions(dims);
  output->SetAspectRatio(1,1,1);
  output->SetOrigin(0,0,0);

  // Allocate data.  Scalar type is FloatScalars.
  numOutPts = dims[0] * dims[1];
  outScalars = new vtkPixmap;

  pixels = (this->Input->GetRenderWindow())->GetPixelData((int)x1,(int)y1,
							  (int)x2,(int)y2,1);

  // copy scalars over
  memcpy(outScalars->WritePtr(0,numOutPts),pixels,3*numOutPts);

  // Update ourselves
  output->GetPointData()->SetScalars(outScalars);
  outScalars->Delete();

  // free the memory
  delete [] pixels;
}

void vtkRendererSource::PrintSelf(ostream& os, vtkIndent indent)
{
  vtkStructuredPointsSource::PrintSelf(os,indent);

  if ( this->Input )
    {
    os << indent << "Input:\n";
    this->Input->PrintSelf(os,indent.GetNextIndent());
    }
  else
    {
    os << indent << "Input: (none)\n";
    }
}

unsigned long vtkRendererSource::GetMTime()
{
  unsigned long mTime=this->MTime.GetMTime();
  unsigned long transMTime;

  if ( this->Input )
    {
    transMTime = this->Input->GetMTime();
    mTime = ( transMTime > mTime ? transMTime : mTime );
    }

  return mTime;
}
<commit_msg>fixed quirk where viewport not taken<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkRendererSource.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 1993-1996 Ken Martin, Will Schroeder, Bill Lorensen.

This software is copyrighted by Ken Martin, Will Schroeder and Bill Lorensen.
The following terms apply to all files associated with the software unless
explicitly disclaimed in individual files. This copyright specifically does
not apply to the related textbook "The Visualization Toolkit" ISBN
013199837-4 published by Prentice Hall which is covered by its own copyright.

The authors hereby grant permission to use, copy, and distribute this
software and its documentation for any purpose, provided that existing
copyright notices are retained in all copies and that this notice is included
verbatim in any distributions. Additionally, the authors grant permission to
modify this software and its documentation for any purpose, provided that
such modifications are not distributed without the explicit consent of the
authors and that existing copyright notices are retained in all copies. Some
of the algorithms implemented by this software are patented, observe all
applicable patent law.

IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR
DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF,
EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE IS PROVIDED ON AN
"AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE
MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.

=========================================================================*/
#include "vtkRendererSource.h"
#include "vtkRenderWindow.h"
#include "vtkPixmap.h"

vtkRendererSource::vtkRendererSource()
{
  this->Input = NULL;
}

void vtkRendererSource::Execute()
{
  int numOutPts;
  vtkPixmap *outScalars;
  float x1,y1,x2,y2;
  unsigned char *pixels;
  int dims[3];
  vtkStructuredPoints *output=(vtkStructuredPoints *)this->Output;

  vtkDebugMacro(<<"Converting points");

  if (this->Input == NULL )
    {
    vtkErrorMacro(<<"Please specify a renderer as input!");
    return;
    }

  // calc the pixel range for the renderer
  x1 = this->Input->GetViewport()[0]*
    ((this->Input->GetRenderWindow())->GetSize()[0] - 1);
  y1 = this->Input->GetViewport()[1]*
    ((this->Input->GetRenderWindow())->GetSize()[1] - 1);
  x2 = this->Input->GetViewport()[2]*
    ((this->Input->GetRenderWindow())->GetSize()[0] - 1);
  y2 = this->Input->GetViewport()[3]*
    ((this->Input->GetRenderWindow())->GetSize()[1] - 1);

  if (this->WholeWindow)
    {
    x1 = 0;
    y1 = 0;
    x2 = (this->Input->GetRenderWindow())->GetSize()[0] - 1;
    y2 = (this->Input->GetRenderWindow())->GetSize()[1] - 1;
    }

  // Get origin, aspect ratio and dimensions from this->Input
  dims[0] = (int)(x2 - x1 + 1); dims[1] = (int)(y2 -y1 + 1); dims[2] = 1;
  output->SetDimensions(dims);
  output->SetAspectRatio(1,1,1);
  output->SetOrigin(0,0,0);

  // Allocate data.  Scalar type is FloatScalars.
  numOutPts = dims[0] * dims[1];
  outScalars = new vtkPixmap;

  pixels = (this->Input->GetRenderWindow())->GetPixelData((int)x1,(int)y1,
							  (int)x2,(int)y2,1);

  // copy scalars over
  memcpy(outScalars->WritePtr(0,numOutPts),pixels,3*numOutPts);

  // Update ourselves
  output->GetPointData()->SetScalars(outScalars);
  outScalars->Delete();

  // free the memory
  delete [] pixels;
}

void vtkRendererSource::PrintSelf(ostream& os, vtkIndent indent)
{
  vtkStructuredPointsSource::PrintSelf(os,indent);

  if ( this->Input )
    {
    os << indent << "Input:\n";
    this->Input->PrintSelf(os,indent.GetNextIndent());
    }
  else
    {
    os << indent << "Input: (none)\n";
    }
}

unsigned long vtkRendererSource::GetMTime()
{
  unsigned long mTime=this->MTime.GetMTime();
  unsigned long transMTime;

  if ( this->Input )
    {
    transMTime = this->Input->GetMTime();
    mTime = ( transMTime > mTime ? transMTime : mTime );
    }

  return mTime;
}
<|endoftext|>


<commit_before>//..............................................................................
//
//  This file is part of the Jancy toolkit.
//
//  Jancy is distributed under the MIT license.
//  For details see accompanying license.txt file,
//  the public copy of which is also available at:
//  http://tibbo.com/downloads/archive/jancy/license.txt
//
//..............................................................................

#include "pch.h"
#include "jnc_Variant.h"

#ifdef _JNC_DYNAMIC_EXTENSION_LIB
#	include "jnc_ExtensionLib.h"
#elif defined(_JNC_CORE)
#	include "jnc_ct_Module.h"
#	include "jnc_rt_Runtime.h"
#endif

#include "jnc_Runtime.h"

//..............................................................................

JNC_EXTERN_C
bool_t
jnc_Variant_create(
	jnc_Variant* variant,
	const void* p,
	jnc_Type* type
	)
{
	using namespace jnc;

	size_t size = type->getSize();
	if (size <= sizeof(jnc::DataPtr))
	{
		memcpy(variant, p, size);
		variant->m_type = type;
		return true;
	}

	GcHeap* gcHeap = getCurrentThreadGcHeap();
	if (!gcHeap)
		return err::fail(err::Error("not inside Jancy call-site"));

	DataPtr ptr = gcHeap->tryAllocateData(type);
	if (!ptr.m_p)
		return false;

	memcpy(ptr.m_p, p, size);
	variant->m_type = type->getDataPtrType(TypeKind_DataRef, DataPtrTypeKind_Normal, PtrTypeFlag_Const);
	return true;
}

//..............................................................................

#ifdef _JNC_DYNAMIC_EXTENSION_LIB

JNC_EXTERN_C
JNC_EXPORT_O
bool_t
jnc_Variant_cast(
	const jnc_Variant* variant,
	jnc_Type* type,
	void* buffer
	)
{
	return jnc_g_dynamicExtensionLibHost->m_variantFuncTable->m_castFunc(variant, type, buffer);
}

JNC_EXTERN_C
JNC_EXPORT_O
bool_t
jnc_Variant_unaryOperator(
	const jnc_Variant* variant,
	jnc_UnOpKind opKind,
	jnc_Variant* result
	)
{
	return jnc_g_dynamicExtensionLibHost->m_variantFuncTable->m_unaryOperatorFunc(variant, opKind, result);
}

JNC_EXTERN_C
JNC_EXPORT_O
bool_t
jnc_Variant_binaryOperator(
	const jnc_Variant* variant,
	const jnc_Variant* variant2,
	jnc_BinOpKind opKind,
	jnc_Variant* result
	)
{
	return jnc_g_dynamicExtensionLibHost->m_variantFuncTable->m_binaryOperatorFunc(variant, variant2, opKind, result);
}

JNC_EXTERN_C
JNC_EXPORT_O
bool_t
jnc_Variant_relationalOperator(
	const jnc_Variant* variant,
	const jnc_Variant* variant2,
	jnc_BinOpKind opKind,
	bool_t* result
	)
{
	return jnc_g_dynamicExtensionLibHost->m_variantFuncTable->m_relationalOperatorFunc(variant, variant2, opKind, result);
}

JNC_EXTERN_C
JNC_EXPORT_O
bool_t
jnc_Variant_getMember(
	const jnc_Variant* variant,
	const char* name,
	jnc_Variant* result
	)
{
	return jnc_g_dynamicExtensionLibHost->m_variantFuncTable->m_getMemberFunc(variant, name, result);
}

JNC_EXTERN_C
JNC_EXPORT_O
bool_t
jnc_Variant_setMember(
	jnc_Variant* variant,
	const char* name,
	jnc_Variant value
	)
{
	return jnc_g_dynamicExtensionLibHost->m_variantFuncTable->m_setMemberFunc(variant, name, value);
}

JNC_EXTERN_C
JNC_EXPORT_O
bool_t
jnc_Variant_getElement(
	const jnc_Variant* variant,
	size_t index,
	jnc_Variant* result
	)
{
	return jnc_g_dynamicExtensionLibHost->m_variantFuncTable->m_getElementFunc(variant, index, result);
}

JNC_EXTERN_C
JNC_EXPORT_O
bool_t
jnc_Variant_setElement(
	jnc_Variant* variant,
	size_t index,
	jnc_Variant value
	)
{
	return jnc_g_dynamicExtensionLibHost->m_variantFuncTable->m_setElementFunc(variant, index, value);
}

JNC_EXTERN_C
JNC_EXPORT_O
size_t
jnc_Variant_hash(const jnc_Variant* variant)
{
	return jnc_g_dynamicExtensionLibHost->m_variantFuncTable->m_hashFunc(variant);
}

#else // _JNC_DYNAMIC_EXTENSION_LIB

JNC_EXTERN_C
JNC_EXPORT_O
bool_t
jnc_Variant_cast(
	const jnc_Variant* variant,
	jnc_Type* type,
	void* buffer
	)
{
	using namespace jnc;
	ct::Module* module = type->getModule();

	ct::Value opValue(variant, module->m_typeMgr.getPrimitiveType(TypeKind_Variant));
	ct::CastOperator* castOp = module->m_operatorMgr.getStdCastOperator(ct::StdCast_FromVariant);

	memset(buffer, 0, type->getSize());
	return castOp->constCast(opValue, type, buffer);
}

JNC_EXTERN_C
JNC_EXPORT_O
bool_t
jnc_Variant_unaryOperator(
	const jnc_Variant* variant,
	jnc_UnOpKind opKind,
	jnc_Variant* resultVariant
	)
{
	using namespace jnc;
	ct::Value opValue;

	if (variant->m_type)
	{
		opValue.createConst(variant, variant->m_type);
	}
	else
	{
		*resultVariant = *variant;
		return true;
	}

	ct::Module* module = variant->m_type->getModule();

	ct::Value resultValue;
	bool result = module->m_operatorMgr.unaryOperator(
		opKind,
		opValue,
		&resultValue
		) &&
		module->m_operatorMgr.castOperator(&resultValue, TypeKind_Variant);

	if (!result)
		return false;

	*resultVariant = *(Variant*)resultValue.getConstData();
	return true;
}

JNC_EXTERN_C
JNC_EXPORT_O
bool_t
jnc_Variant_binaryOperator(
	const jnc_Variant* variant,
	const jnc_Variant* variant2,
	jnc_BinOpKind opKind,
	jnc_Variant* resultVariant
	)
{
	using namespace jnc;
	ct::Value opValue1;

	if (variant->m_type)
	{
		opValue1.createConst(variant, variant->m_type);
	}
	else if (variant2->m_type)
	{
		opValue1.createConst(NULL, variant2->m_type);
	}
	else
	{
		*resultVariant = *variant;
		return true;
	}

	ct::Value opValue2;

	if (variant2->m_type)
	{
		opValue2.createConst(variant2, variant2->m_type);
	}
	else
	{
		ASSERT(variant->m_type);
		opValue2.createConst(NULL, variant->m_type);
	}

	ct::Module* module = opValue1.getType()->getModule();

	ct::Value resultValue;
	bool result = module->m_operatorMgr.binaryOperator(
		opKind,
		opValue1,
		opValue2,
		&resultValue
		) &&
		module->m_operatorMgr.castOperator(&resultValue, TypeKind_Variant);

	if (!result)
		return false;

	*resultVariant = *(Variant*)resultValue.getConstData();
	return true;
}

JNC_EXTERN_C
JNC_EXPORT_O
bool_t
jnc_Variant_relationalOperator(
	const jnc_Variant* variant,
	const jnc_Variant* variant2,
	jnc_BinOpKind opKind,
	bool_t* resultBool
	)
{
	using namespace jnc;
	ASSERT(opKind >= BinOpKind_Eq && opKind <= BinOpKind_Ge);

	ct::Value opValue1;

	if (variant->m_type)
	{
		opValue1.createConst(variant, variant->m_type);
	}
	else if (variant2->m_type)
	{
		opValue1.createConst(NULL, variant2->m_type);
	}
	else
	{
		*resultBool = opKind == jnc_BinOpKind_Eq;
		return true;
	}

	ct::Value opValue2;

	if (variant2->m_type)
	{
		opValue2.createConst(variant2, variant2->m_type);
	}
	else
	{
		ASSERT(variant->m_type);
		opValue2.createConst(NULL, variant->m_type);
	}

	ct::Module* module = opValue1.getType()->getModule();

	ct::Value resultValue;
	bool result = module->m_operatorMgr.binaryOperator(
		opKind,
		opValue1,
		opValue2,
		&resultValue
		) &&
		module->m_operatorMgr.castOperator(&resultValue, TypeKind_Bool);

	if (!result)
		return false;

	*resultBool = *(bool*)resultValue.getConstData();
	return true;
}

JNC_EXTERN_C
JNC_EXPORT_O
bool_t
jnc_Variant_getMember(
	const jnc_Variant* variant,
	const char* name,
	jnc_Variant* resultVariant
	)
{
	using namespace jnc;

	if (!variant->m_type)
	{
		err::setError("cannot apply member operator to 'null'");
		return true;
	}

	ct::Module* module = variant->m_type->getModule();

	ct::Value opValue(variant, variant->m_type);
	ct::Value memberValue;
	bool result =
		module->m_operatorMgr.memberOperator(opValue, name, &memberValue) &&
		module->m_operatorMgr.castOperator(&memberValue, TypeKind_Variant);

	if (!result)
		return false;

	*resultVariant = *(Variant*)memberValue.getConstData();
	return true;
}

JNC_EXTERN_C
JNC_EXPORT_O
bool_t
jnc_Variant_setMember(
	jnc_Variant* variant,
	const char* name,
	jnc_Variant valueVariant
	)
{
	using namespace jnc;

	if (!variant->m_type)
	{
		err::setError("cannot apply member operator to 'null'");
		return true;
	}

	ct::Module* module = variant->m_type->getModule();

	ct::Value opValue;
	if (variant->m_type->getTypeKindFlags() & TypeKindFlag_Ptr)
	{
		opValue.createConst(variant, variant->m_type);
	}
	else
	{
		ASSERT(variant->m_type->getSize() <= sizeof(DataPtr));
		opValue.createConst(&variant, variant->m_type->getDataPtrType_c(TypeKind_DataRef));
	}

	ct::Value opValue2(&valueVariant, module->m_typeMgr.getPrimitiveType(TypeKind_Variant));
	ct::Value memberValue;

	return
		module->m_operatorMgr.memberOperator(opValue, name, &memberValue) &&
		module->m_operatorMgr.binaryOperator(BinOpKind_Assign, memberValue, opValue2);
}

JNC_EXTERN_C
JNC_EXPORT_O
bool_t
jnc_Variant_getElement(
	const jnc_Variant* variant,
	size_t index,
	jnc_Variant* resultVariant
	)
{
	using namespace jnc;

	if (!variant->m_type)
	{
		err::setError("cannot apply index operator to 'null'");
		return true;
	}

	ct::Module* module = variant->m_type->getModule();

	// turning it into ref is only necessary because of current implementation of OperatorMgr::memberOperator (size_t)

	ct::Value opValue;
	if (variant->m_type->getTypeKindFlags() & TypeKindFlag_Ptr)
	{
		opValue.createConst(variant, variant->m_type);
	}
	else
	{
		ASSERT(variant->m_type->getSize() <= sizeof(DataPtr));
		opValue.createConst(&variant, variant->m_type->getDataPtrType_c(TypeKind_DataRef));
	}

	ct::Value memberValue;
	bool result =
		module->m_operatorMgr.memberOperator(opValue, index, &memberValue) &&
		module->m_operatorMgr.castOperator(&memberValue, TypeKind_Variant);

	if (!result)
		return false;

	*resultVariant = *(Variant*)memberValue.getConstData();
	return true;
}

JNC_EXTERN_C
JNC_EXPORT_O
bool_t
jnc_Variant_setElement(
	jnc_Variant* variant,
	size_t index,
	jnc_Variant valueVariant
	)
{
	using namespace jnc;

	if (!variant->m_type)
	{
		err::setError("cannot apply index operator to 'null'");
		return true;
	}

	ct::Module* module = variant->m_type->getModule();

	ct::Value opValue;
	if (variant->m_type->getTypeKindFlags() & TypeKindFlag_Ptr)
	{
		opValue.createConst(variant, variant->m_type);
	}
	else
	{
		ASSERT(variant->m_type->getSize() <= sizeof(DataPtr));
		opValue.createConst(&variant, variant->m_type->getDataPtrType_c(TypeKind_DataRef));
	}

	ct::Value opValue2(&valueVariant, module->m_typeMgr.getPrimitiveType(TypeKind_Variant));
	ct::Value memberValue;

	return
		module->m_operatorMgr.memberOperator(opValue, index, &memberValue) &&
		module->m_operatorMgr.binaryOperator(BinOpKind_Assign, memberValue, opValue2);
}

JNC_EXTERN_C
JNC_EXPORT_O
size_t
jnc_Variant_hash(const jnc_Variant* variant)
{
	using namespace jnc;
	if (!variant->m_type)
		return 0;

	size_t size = variant->m_type->getSize();

	if (variant->m_type->getTypeKindFlags() & TypeKindFlag_BigEndian)
	{
		uint64_t result = 0;
		axl::sl::swapByteOrder(&result, &variant->m_int64, size);
		return (uintptr_t)result;
	}

	if (size <= sizeof(uintptr_t) || variant->m_type->getTypeKind() == TypeKind_DataPtr)
		return variant->m_uintptr;

	const void* p = size <= sizeof(DataPtr) ? &variant : variant->m_p;
	return sl::djb2(p, size);
}

#endif // _JNC_DYNAMIC_EXTENSION_LIB

//..............................................................................

bool
jnc::Variant::relationalOperator(
	const jnc_Variant* variant2,
	jnc_BinOpKind opKind,
	bool* result
	) const
{
	bool_t intResult;
	if (!jnc_Variant_relationalOperator(this, variant2, opKind, &intResult))
		return false;

	*result = intResult != 0;
	return true;
}

//..............................................................................
<commit_msg>[jnc_api] fix: indirect variant didn't save the newly allocated data ptr<commit_after>//..............................................................................
//
//  This file is part of the Jancy toolkit.
//
//  Jancy is distributed under the MIT license.
//  For details see accompanying license.txt file,
//  the public copy of which is also available at:
//  http://tibbo.com/downloads/archive/jancy/license.txt
//
//..............................................................................

#include "pch.h"
#include "jnc_Variant.h"

#ifdef _JNC_DYNAMIC_EXTENSION_LIB
#	include "jnc_ExtensionLib.h"
#elif defined(_JNC_CORE)
#	include "jnc_ct_Module.h"
#	include "jnc_rt_Runtime.h"
#endif

#include "jnc_Runtime.h"

//..............................................................................

JNC_EXTERN_C
bool_t
jnc_Variant_create(
	jnc_Variant* variant,
	const void* p,
	jnc_Type* type
	)
{
	using namespace jnc;

	size_t size = type->getSize();
	if (size <= sizeof(jnc::DataPtr))
	{
		memcpy(variant, p, size);
		variant->m_type = type;
		return true;
	}

	GcHeap* gcHeap = getCurrentThreadGcHeap();
	if (!gcHeap)
		return err::fail(err::Error("not inside Jancy call-site"));

	DataPtr ptr = gcHeap->tryAllocateData(type);
	if (!ptr.m_p)
		return false;

	memcpy(ptr.m_p, p, size);
	variant->m_type = type->getDataPtrType(TypeKind_DataRef, DataPtrTypeKind_Normal, PtrTypeFlag_Const);
	variant->m_dataPtr = ptr;
	return true;
}

//..............................................................................

#ifdef _JNC_DYNAMIC_EXTENSION_LIB

JNC_EXTERN_C
JNC_EXPORT_O
bool_t
jnc_Variant_cast(
	const jnc_Variant* variant,
	jnc_Type* type,
	void* buffer
	)
{
	return jnc_g_dynamicExtensionLibHost->m_variantFuncTable->m_castFunc(variant, type, buffer);
}

JNC_EXTERN_C
JNC_EXPORT_O
bool_t
jnc_Variant_unaryOperator(
	const jnc_Variant* variant,
	jnc_UnOpKind opKind,
	jnc_Variant* result
	)
{
	return jnc_g_dynamicExtensionLibHost->m_variantFuncTable->m_unaryOperatorFunc(variant, opKind, result);
}

JNC_EXTERN_C
JNC_EXPORT_O
bool_t
jnc_Variant_binaryOperator(
	const jnc_Variant* variant,
	const jnc_Variant* variant2,
	jnc_BinOpKind opKind,
	jnc_Variant* result
	)
{
	return jnc_g_dynamicExtensionLibHost->m_variantFuncTable->m_binaryOperatorFunc(variant, variant2, opKind, result);
}

JNC_EXTERN_C
JNC_EXPORT_O
bool_t
jnc_Variant_relationalOperator(
	const jnc_Variant* variant,
	const jnc_Variant* variant2,
	jnc_BinOpKind opKind,
	bool_t* result
	)
{
	return jnc_g_dynamicExtensionLibHost->m_variantFuncTable->m_relationalOperatorFunc(variant, variant2, opKind, result);
}

JNC_EXTERN_C
JNC_EXPORT_O
bool_t
jnc_Variant_getMember(
	const jnc_Variant* variant,
	const char* name,
	jnc_Variant* result
	)
{
	return jnc_g_dynamicExtensionLibHost->m_variantFuncTable->m_getMemberFunc(variant, name, result);
}

JNC_EXTERN_C
JNC_EXPORT_O
bool_t
jnc_Variant_setMember(
	jnc_Variant* variant,
	const char* name,
	jnc_Variant value
	)
{
	return jnc_g_dynamicExtensionLibHost->m_variantFuncTable->m_setMemberFunc(variant, name, value);
}

JNC_EXTERN_C
JNC_EXPORT_O
bool_t
jnc_Variant_getElement(
	const jnc_Variant* variant,
	size_t index,
	jnc_Variant* result
	)
{
	return jnc_g_dynamicExtensionLibHost->m_variantFuncTable->m_getElementFunc(variant, index, result);
}

JNC_EXTERN_C
JNC_EXPORT_O
bool_t
jnc_Variant_setElement(
	jnc_Variant* variant,
	size_t index,
	jnc_Variant value
	)
{
	return jnc_g_dynamicExtensionLibHost->m_variantFuncTable->m_setElementFunc(variant, index, value);
}

JNC_EXTERN_C
JNC_EXPORT_O
size_t
jnc_Variant_hash(const jnc_Variant* variant)
{
	return jnc_g_dynamicExtensionLibHost->m_variantFuncTable->m_hashFunc(variant);
}

#else // _JNC_DYNAMIC_EXTENSION_LIB

JNC_EXTERN_C
JNC_EXPORT_O
bool_t
jnc_Variant_cast(
	const jnc_Variant* variant,
	jnc_Type* type,
	void* buffer
	)
{
	using namespace jnc;
	ct::Module* module = type->getModule();

	ct::Value opValue(variant, module->m_typeMgr.getPrimitiveType(TypeKind_Variant));
	ct::CastOperator* castOp = module->m_operatorMgr.getStdCastOperator(ct::StdCast_FromVariant);

	memset(buffer, 0, type->getSize());
	return castOp->constCast(opValue, type, buffer);
}

JNC_EXTERN_C
JNC_EXPORT_O
bool_t
jnc_Variant_unaryOperator(
	const jnc_Variant* variant,
	jnc_UnOpKind opKind,
	jnc_Variant* resultVariant
	)
{
	using namespace jnc;
	ct::Value opValue;

	if (variant->m_type)
	{
		opValue.createConst(variant, variant->m_type);
	}
	else
	{
		*resultVariant = *variant;
		return true;
	}

	ct::Module* module = variant->m_type->getModule();

	ct::Value resultValue;
	bool result = module->m_operatorMgr.unaryOperator(
		opKind,
		opValue,
		&resultValue
		) &&
		module->m_operatorMgr.castOperator(&resultValue, TypeKind_Variant);

	if (!result)
		return false;

	*resultVariant = *(Variant*)resultValue.getConstData();
	return true;
}

JNC_EXTERN_C
JNC_EXPORT_O
bool_t
jnc_Variant_binaryOperator(
	const jnc_Variant* variant,
	const jnc_Variant* variant2,
	jnc_BinOpKind opKind,
	jnc_Variant* resultVariant
	)
{
	using namespace jnc;
	ct::Value opValue1;

	if (variant->m_type)
	{
		opValue1.createConst(variant, variant->m_type);
	}
	else if (variant2->m_type)
	{
		opValue1.createConst(NULL, variant2->m_type);
	}
	else
	{
		*resultVariant = *variant;
		return true;
	}

	ct::Value opValue2;

	if (variant2->m_type)
	{
		opValue2.createConst(variant2, variant2->m_type);
	}
	else
	{
		ASSERT(variant->m_type);
		opValue2.createConst(NULL, variant->m_type);
	}

	ct::Module* module = opValue1.getType()->getModule();

	ct::Value resultValue;
	bool result = module->m_operatorMgr.binaryOperator(
		opKind,
		opValue1,
		opValue2,
		&resultValue
		) &&
		module->m_operatorMgr.castOperator(&resultValue, TypeKind_Variant);

	if (!result)
		return false;

	*resultVariant = *(Variant*)resultValue.getConstData();
	return true;
}

JNC_EXTERN_C
JNC_EXPORT_O
bool_t
jnc_Variant_relationalOperator(
	const jnc_Variant* variant,
	const jnc_Variant* variant2,
	jnc_BinOpKind opKind,
	bool_t* resultBool
	)
{
	using namespace jnc;
	ASSERT(opKind >= BinOpKind_Eq && opKind <= BinOpKind_Ge);

	ct::Value opValue1;

	if (variant->m_type)
	{
		opValue1.createConst(variant, variant->m_type);
	}
	else if (variant2->m_type)
	{
		opValue1.createConst(NULL, variant2->m_type);
	}
	else
	{
		*resultBool = opKind == jnc_BinOpKind_Eq;
		return true;
	}

	ct::Value opValue2;

	if (variant2->m_type)
	{
		opValue2.createConst(variant2, variant2->m_type);
	}
	else
	{
		ASSERT(variant->m_type);
		opValue2.createConst(NULL, variant->m_type);
	}

	ct::Module* module = opValue1.getType()->getModule();

	ct::Value resultValue;
	bool result = module->m_operatorMgr.binaryOperator(
		opKind,
		opValue1,
		opValue2,
		&resultValue
		) &&
		module->m_operatorMgr.castOperator(&resultValue, TypeKind_Bool);

	if (!result)
		return false;

	*resultBool = *(bool*)resultValue.getConstData();
	return true;
}

JNC_EXTERN_C
JNC_EXPORT_O
bool_t
jnc_Variant_getMember(
	const jnc_Variant* variant,
	const char* name,
	jnc_Variant* resultVariant
	)
{
	using namespace jnc;

	if (!variant->m_type)
	{
		err::setError("cannot apply member operator to 'null'");
		return true;
	}

	ct::Module* module = variant->m_type->getModule();

	ct::Value opValue(variant, variant->m_type);
	ct::Value memberValue;
	bool result =
		module->m_operatorMgr.memberOperator(opValue, name, &memberValue) &&
		module->m_operatorMgr.castOperator(&memberValue, TypeKind_Variant);

	if (!result)
		return false;

	*resultVariant = *(Variant*)memberValue.getConstData();
	return true;
}

JNC_EXTERN_C
JNC_EXPORT_O
bool_t
jnc_Variant_setMember(
	jnc_Variant* variant,
	const char* name,
	jnc_Variant valueVariant
	)
{
	using namespace jnc;

	if (!variant->m_type)
	{
		err::setError("cannot apply member operator to 'null'");
		return true;
	}

	ct::Module* module = variant->m_type->getModule();

	ct::Value opValue;
	if (variant->m_type->getTypeKindFlags() & TypeKindFlag_Ptr)
	{
		opValue.createConst(variant, variant->m_type);
	}
	else
	{
		ASSERT(variant->m_type->getSize() <= sizeof(DataPtr));
		opValue.createConst(&variant, variant->m_type->getDataPtrType_c(TypeKind_DataRef));
	}

	ct::Value opValue2(&valueVariant, module->m_typeMgr.getPrimitiveType(TypeKind_Variant));
	ct::Value memberValue;

	return
		module->m_operatorMgr.memberOperator(opValue, name, &memberValue) &&
		module->m_operatorMgr.binaryOperator(BinOpKind_Assign, memberValue, opValue2);
}

JNC_EXTERN_C
JNC_EXPORT_O
bool_t
jnc_Variant_getElement(
	const jnc_Variant* variant,
	size_t index,
	jnc_Variant* resultVariant
	)
{
	using namespace jnc;

	if (!variant->m_type)
	{
		err::setError("cannot apply index operator to 'null'");
		return true;
	}

	ct::Module* module = variant->m_type->getModule();

	// turning it into ref is only necessary because of current implementation of OperatorMgr::memberOperator (size_t)

	ct::Value opValue;
	if (variant->m_type->getTypeKindFlags() & TypeKindFlag_Ptr)
	{
		opValue.createConst(variant, variant->m_type);
	}
	else
	{
		ASSERT(variant->m_type->getSize() <= sizeof(DataPtr));
		opValue.createConst(&variant, variant->m_type->getDataPtrType_c(TypeKind_DataRef));
	}

	ct::Value memberValue;
	bool result =
		module->m_operatorMgr.memberOperator(opValue, index, &memberValue) &&
		module->m_operatorMgr.castOperator(&memberValue, TypeKind_Variant);

	if (!result)
		return false;

	*resultVariant = *(Variant*)memberValue.getConstData();
	return true;
}

JNC_EXTERN_C
JNC_EXPORT_O
bool_t
jnc_Variant_setElement(
	jnc_Variant* variant,
	size_t index,
	jnc_Variant valueVariant
	)
{
	using namespace jnc;

	if (!variant->m_type)
	{
		err::setError("cannot apply index operator to 'null'");
		return true;
	}

	ct::Module* module = variant->m_type->getModule();

	ct::Value opValue;
	if (variant->m_type->getTypeKindFlags() & TypeKindFlag_Ptr)
	{
		opValue.createConst(variant, variant->m_type);
	}
	else
	{
		ASSERT(variant->m_type->getSize() <= sizeof(DataPtr));
		opValue.createConst(&variant, variant->m_type->getDataPtrType_c(TypeKind_DataRef));
	}

	ct::Value opValue2(&valueVariant, module->m_typeMgr.getPrimitiveType(TypeKind_Variant));
	ct::Value memberValue;

	return
		module->m_operatorMgr.memberOperator(opValue, index, &memberValue) &&
		module->m_operatorMgr.binaryOperator(BinOpKind_Assign, memberValue, opValue2);
}

JNC_EXTERN_C
JNC_EXPORT_O
size_t
jnc_Variant_hash(const jnc_Variant* variant)
{
	using namespace jnc;
	if (!variant->m_type)
		return 0;

	size_t size = variant->m_type->getSize();

	if (variant->m_type->getTypeKindFlags() & TypeKindFlag_BigEndian)
	{
		uint64_t result = 0;
		axl::sl::swapByteOrder(&result, &variant->m_int64, size);
		return (uintptr_t)result;
	}

	if (size <= sizeof(uintptr_t) || variant->m_type->getTypeKind() == TypeKind_DataPtr)
		return variant->m_uintptr;

	const void* p = size <= sizeof(DataPtr) ? &variant : variant->m_p;
	return sl::djb2(p, size);
}

#endif // _JNC_DYNAMIC_EXTENSION_LIB

//..............................................................................

bool
jnc::Variant::relationalOperator(
	const jnc_Variant* variant2,
	jnc_BinOpKind opKind,
	bool* result
	) const
{
	bool_t intResult;
	if (!jnc_Variant_relationalOperator(this, variant2, opKind, &intResult))
		return false;

	*result = intResult != 0;
	return true;
}

//..............................................................................
<|endoftext|>