<commit_before>//
// Copyright (c) 2008-2014 the Urho3D project.
//
// 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 <Atomic/Atomic.h>
#include <Atomic/Engine/Engine.h>
#include <Atomic/IO/FileSystem.h>
#include <Atomic/IO/Log.h>
#include <Atomic/IO/IOEvents.h>
#include <Atomic/Input/InputEvents.h>
#include <Atomic/Core/Main.h>
#include <Atomic/Core/ProcessUtils.h>
#include <Atomic/Resource/ResourceCache.h>
#include <Atomic/Resource/ResourceEvents.h>
#include <Atomic/UI/UI.h>

// Move me
#include <Atomic/Environment/Environment.h>

#include <AtomicJS/Javascript/Javascript.h>

#include <AtomicPlayer/Player.h>

#include "AtomicPlayer.h"

#include <Atomic/DebugNew.h>

#ifdef __APPLE__
#include <unistd.h>
#endif

DEFINE_APPLICATION_MAIN(AtomicPlayer::AtomicPlayerApp)

namespace AtomicPlayer
{

extern void jsapi_init_atomicplayer(JSVM* vm);

AtomicPlayerApp::AtomicPlayerApp(Context* context) :
    Application(context)
{
}

void AtomicPlayerApp::Setup()
{
    FileSystem* filesystem = GetSubsystem<FileSystem>();

    engineParameters_["WindowTitle"] = "AtomicPlayer";

#if (ATOMIC_PLATFORM_ANDROID)
    engineParameters_["FullScreen"] = true;
    engineParameters_["ResourcePaths"] = "CoreData;AtomicResources";
#elif ATOMIC_PLATFORM_WEB
    engineParameters_["FullScreen"] = false;
    engineParameters_["ResourcePaths"] = "AtomicResources";
    // engineParameters_["WindowWidth"] = 1280;
    // engineParameters_["WindowHeight"] = 720;
#elif ATOMIC_PLATFORM_IOS
    engineParameters_["FullScreen"] = false;
    engineParameters_["ResourcePaths"] = "AtomicResources";
#else
    engineParameters_["FullScreen"] = false;
    engineParameters_["WindowWidth"] = 1280;
    engineParameters_["WindowHeight"] = 720;
    engineParameters_["ResourcePaths"] = "AtomicResources";
#endif

#if ATOMIC_PLATFORM_WINDOWS
    engineParameters_["WindowIcon"] = "Images/AtomicLogo32.png";
    engineParameters_["ResourcePrefixPath"] = "AtomicPlayer_Resources";
#elif ATOMIC_PLATFORM_ANDROID
    //engineParameters_["ResourcePrefixPath"] = "assets";
#elif ATOMIC_PLATFORM_OSX
    engineParameters_["ResourcePrefixPath"] = "../Resources";
#endif

    const Vector<String>& arguments = GetArguments();

    for (unsigned i = 0; i < arguments.Size(); ++i)
    {
        if (arguments[i].Length() > 1)
        {
            String argument = arguments[i].ToLower();
            String value = i + 1 < arguments.Size() ? arguments[i + 1] : String::EMPTY;

            if (argument == "--log-std")
            {
                SubscribeToEvent(E_LOGMESSAGE, HANDLER(AtomicPlayerApp, HandleLogMessage));
            }
        }
    }

    // Use the script file name as the base name for the log file
    engineParameters_["LogName"] = filesystem->GetAppPreferencesDir("AtomicPlayer", "Logs") + "AtomicPlayer.log";
}

void AtomicPlayerApp::Start()
{
    Application::Start();

    // Instantiate and register the Javascript subsystem
    Javascript* javascript = new Javascript(context_);
    context_->RegisterSubsystem(javascript);

    vm_ = javascript->InstantiateVM("MainVM");
    vm_->InitJSContext();

    UI* ui = GetSubsystem<UI>();
    ui->Initialize("DefaultUI/language/lng_en.tb.txt");
    ui->LoadDefaultPlayerSkin();

    SubscribeToEvent(E_JSERROR, HANDLER(AtomicPlayerApp, HandleJSError));

    vm_->SetModuleSearchPaths("Modules");

    // Instantiate and register the Player subsystem
    context_->RegisterSubsystem(new AtomicPlayer::Player(context_));
    AtomicPlayer::jsapi_init_atomicplayer(vm_);

    JSVM* vm = JSVM::GetJSVM(0);

    if (!vm->ExecuteMain())
    {
        SendEvent(E_EXITREQUESTED);
    }

    return;
}

void AtomicPlayerApp::Stop()
{
    Application::Stop();
}

void AtomicPlayerApp::HandleScriptReloadStarted(StringHash eventType, VariantMap& eventData)
{
}

void AtomicPlayerApp::HandleScriptReloadFinished(StringHash eventType, VariantMap& eventData)
{
}

void AtomicPlayerApp::HandleScriptReloadFailed(StringHash eventType, VariantMap& eventData)
{
    ErrorExit();
}

void AtomicPlayerApp::HandleLogMessage(StringHash eventType, VariantMap& eventData)
{
    using namespace LogMessage;

    int level = eventData[P_LEVEL].GetInt();
    // The message may be multi-line, so split to rows in that case
    Vector<String> rows = eventData[P_MESSAGE].GetString().Split('\n');

    for (unsigned i = 0; i < rows.Size(); ++i)
    {
        if (level == LOG_ERROR)
        {
            fprintf(stderr, "%s\n", rows[i].CString());
        }
        else
        {
            fprintf(stdout, "%s\n", rows[i].CString());
        }
    }

}

void AtomicPlayerApp::HandleJSError(StringHash eventType, VariantMap& eventData)
{
    using namespace JSError;
    //String errName = eventData[P_ERRORNAME].GetString();
    //String errStack = eventData[P_ERRORSTACK].GetString();
    String errMessage = eventData[P_ERRORMESSAGE].GetString();
    String errFilename = eventData[P_ERRORFILENAME].GetString();
    int errLineNumber = eventData[P_ERRORLINENUMBER].GetInt();

    String errorString = ToString("%s - %s - Line: %i",
                                  errFilename.CString(), errMessage.CString(), errLineNumber);

}

}
<commit_msg>Shutdown JS vm at application stop<commit_after>//
// Copyright (c) 2008-2014 the Urho3D project.
//
// 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 <Atomic/Atomic.h>
#include <Atomic/Engine/Engine.h>
#include <Atomic/IO/FileSystem.h>
#include <Atomic/IO/Log.h>
#include <Atomic/IO/IOEvents.h>
#include <Atomic/Input/InputEvents.h>
#include <Atomic/Core/Main.h>
#include <Atomic/Core/ProcessUtils.h>
#include <Atomic/Resource/ResourceCache.h>
#include <Atomic/Resource/ResourceEvents.h>
#include <Atomic/UI/UI.h>

// Move me
#include <Atomic/Environment/Environment.h>

#include <AtomicJS/Javascript/Javascript.h>

#include <AtomicPlayer/Player.h>

#include "AtomicPlayer.h"

#include <Atomic/DebugNew.h>

#ifdef __APPLE__
#include <unistd.h>
#endif

DEFINE_APPLICATION_MAIN(AtomicPlayer::AtomicPlayerApp)

namespace AtomicPlayer
{

extern void jsapi_init_atomicplayer(JSVM* vm);

AtomicPlayerApp::AtomicPlayerApp(Context* context) :
    Application(context)
{
}

void AtomicPlayerApp::Setup()
{
    FileSystem* filesystem = GetSubsystem<FileSystem>();

    engineParameters_["WindowTitle"] = "AtomicPlayer";

#if (ATOMIC_PLATFORM_ANDROID)
    engineParameters_["FullScreen"] = true;
    engineParameters_["ResourcePaths"] = "CoreData;AtomicResources";
#elif ATOMIC_PLATFORM_WEB
    engineParameters_["FullScreen"] = false;
    engineParameters_["ResourcePaths"] = "AtomicResources";
    // engineParameters_["WindowWidth"] = 1280;
    // engineParameters_["WindowHeight"] = 720;
#elif ATOMIC_PLATFORM_IOS
    engineParameters_["FullScreen"] = false;
    engineParameters_["ResourcePaths"] = "AtomicResources";
#else
    engineParameters_["FullScreen"] = false;
    engineParameters_["WindowWidth"] = 1280;
    engineParameters_["WindowHeight"] = 720;
    engineParameters_["ResourcePaths"] = "AtomicResources";
#endif

#if ATOMIC_PLATFORM_WINDOWS
    engineParameters_["WindowIcon"] = "Images/AtomicLogo32.png";
    engineParameters_["ResourcePrefixPath"] = "AtomicPlayer_Resources";
#elif ATOMIC_PLATFORM_ANDROID
    //engineParameters_["ResourcePrefixPath"] = "assets";
#elif ATOMIC_PLATFORM_OSX
    engineParameters_["ResourcePrefixPath"] = "../Resources";
#endif

    const Vector<String>& arguments = GetArguments();

    for (unsigned i = 0; i < arguments.Size(); ++i)
    {
        if (arguments[i].Length() > 1)
        {
            String argument = arguments[i].ToLower();
            String value = i + 1 < arguments.Size() ? arguments[i + 1] : String::EMPTY;

            if (argument == "--log-std")
            {
                SubscribeToEvent(E_LOGMESSAGE, HANDLER(AtomicPlayerApp, HandleLogMessage));
            }
        }
    }

    // Use the script file name as the base name for the log file
    engineParameters_["LogName"] = filesystem->GetAppPreferencesDir("AtomicPlayer", "Logs") + "AtomicPlayer.log";
}

void AtomicPlayerApp::Start()
{
    Application::Start();

    // Instantiate and register the Javascript subsystem
    Javascript* javascript = new Javascript(context_);
    context_->RegisterSubsystem(javascript);

    vm_ = javascript->InstantiateVM("MainVM");
    vm_->InitJSContext();

    UI* ui = GetSubsystem<UI>();
    ui->Initialize("DefaultUI/language/lng_en.tb.txt");
    ui->LoadDefaultPlayerSkin();

    SubscribeToEvent(E_JSERROR, HANDLER(AtomicPlayerApp, HandleJSError));

    vm_->SetModuleSearchPaths("Modules");

    // Instantiate and register the Player subsystem
    context_->RegisterSubsystem(new AtomicPlayer::Player(context_));
    AtomicPlayer::jsapi_init_atomicplayer(vm_);

    JSVM* vm = JSVM::GetJSVM(0);

    if (!vm->ExecuteMain())
    {
        SendEvent(E_EXITREQUESTED);
    }

    return;
}

void AtomicPlayerApp::Stop()
{

    vm_ = 0;
    context_->RemoveSubsystem<Javascript>();
    // make sure JSVM is really down and no outstanding refs
    // as if not, will hold on engine subsystems, which is bad
    assert(!JSVM::GetJSVM(0));

    Application::Stop();

}

void AtomicPlayerApp::HandleScriptReloadStarted(StringHash eventType, VariantMap& eventData)
{
}

void AtomicPlayerApp::HandleScriptReloadFinished(StringHash eventType, VariantMap& eventData)
{
}

void AtomicPlayerApp::HandleScriptReloadFailed(StringHash eventType, VariantMap& eventData)
{
    ErrorExit();
}

void AtomicPlayerApp::HandleLogMessage(StringHash eventType, VariantMap& eventData)
{
    using namespace LogMessage;

    int level = eventData[P_LEVEL].GetInt();
    // The message may be multi-line, so split to rows in that case
    Vector<String> rows = eventData[P_MESSAGE].GetString().Split('\n');

    for (unsigned i = 0; i < rows.Size(); ++i)
    {
        if (level == LOG_ERROR)
        {
            fprintf(stderr, "%s\n", rows[i].CString());
        }
        else
        {
            fprintf(stdout, "%s\n", rows[i].CString());
        }
    }

}

void AtomicPlayerApp::HandleJSError(StringHash eventType, VariantMap& eventData)
{
    using namespace JSError;
    //String errName = eventData[P_ERRORNAME].GetString();
    //String errStack = eventData[P_ERRORSTACK].GetString();
    String errMessage = eventData[P_ERRORMESSAGE].GetString();
    String errFilename = eventData[P_ERRORFILENAME].GetString();
    int errLineNumber = eventData[P_ERRORLINENUMBER].GetInt();

    String errorString = ToString("%s - %s - Line: %i",
                                  errFilename.CString(), errMessage.CString(), errLineNumber);

}

}
<|endoftext|>


<commit_before>// Copyright 2016 - 2020 Code 4 Game, Org. All Rights Reserved.

#include "glTFForUE4EdPrivatePCH.h"
#include "glTFFactory.h"

#include "glTF/glTFImporterOptions.h"
#include "glTF/glTFImporterOptionsWindowEd.h"
#include "glTF/glTFImporterEd.h"

#include "Engine/StaticMesh.h"
#include "Engine/SkeletalMesh.h"
#include "Misc/FeedbackContext.h"
#include "Misc/Paths.h"

#include "ObjectTools.h"

#define LOCTEXT_NAMESPACE "glTFForUE4EdModule"

UglTFFactory::UglTFFactory()
    : Super()
    , ImportClass(nullptr)
{
    //
}

UglTFFactory::UglTFFactory(const FObjectInitializer& InObjectInitializer)
    : Super(InObjectInitializer)
    , ImportClass(nullptr)
{
    if (Formats.Num() > 0) Formats.Empty();
    Formats.Add(TEXT("gltf;glTF 2.0"));

    bCreateNew = false;
    bText = true;
    bEditorImport = true;
}

bool UglTFFactory::DoesSupportClass(UClass* InClass)
{
    return (InClass == UStaticMesh::StaticClass()
        || InClass == USkeletalMesh::StaticClass());
}

UClass* UglTFFactory::ResolveSupportedClass()
{
    if (ImportClass == nullptr) ImportClass = UStaticMesh::StaticClass();
    return ImportClass;
}

bool UglTFFactory::FactoryCanImport(const FString& InFilePathInOS)
{
    return FPaths::GetExtension(InFilePathInOS).Equals(TEXT("gltf"), ESearchCase::IgnoreCase);
}

UObject* UglTFFactory::FactoryCreateText(UClass* InClass, UObject* InParent, FName InName, EObjectFlags InFlags, UObject* InContext, const TCHAR* InType, const TCHAR*& InBuffer, const TCHAR* InBufferEnd, FFeedbackContext* InWarn)
{
    if (!InBuffer || !InBufferEnd || InBuffer >= InBufferEnd)
    {
        InWarn->Log(ELogVerbosity::Error, FText::Format(NSLOCTEXT("glTFForUE4Ed", "BufferHasErrorInFactoryCreateText", "Buffer has some errors when create the glTF file {0}"), FText::FromName(InName)).ToString());
        return nullptr;
    }

    uint64 BufferSize = InBufferEnd - InBuffer;

    FString glTFJson;
    glTFJson.Append(InBuffer, BufferSize);
    return FactoryCreate(InClass, InParent, InName, InFlags, InContext, InType, InWarn, glTFJson);
}

UObject* UglTFFactory::FactoryCreate(UClass* InClass, UObject* InParent, FName InName, EObjectFlags InFlags, UObject* InContext, const TCHAR* InType, FFeedbackContext* InWarn, const FString& InglTFJson, TSharedPtr<FglTFBuffers> InglTFBuffers /*= nullptr*/)
{
    const FString& FilePathInOS = UFactory::GetCurrentFilename();
    if (!ObjectTools::SanitizeObjectName(FPaths::GetBaseFilename(FilePathInOS)).Equals(InName.ToString()))
    {
        UE_LOG(LogglTFForUE4Ed, Error, TEXT("It is different between current filename(%s) and name(%s)!!"), *FilePathInOS, *InName.ToString());
        return nullptr;
    }

    /// Parse and check the buffer
    std::shared_ptr<libgltf::SGlTF> GlTF;
#if defined(UNICODE)
    std::wstring GlTFString = *InglTFJson;
#else
    std::string GlTFString = *InglTFJson;
#endif
    if (!(GlTF << GlTFString))
    {
        InWarn->Log(ELogVerbosity::Error, FText::Format(NSLOCTEXT("glTFForUE4Ed", "FailedToParseTheglTFFile", "Failed to parse the glTF file {0}"), FText::FromName(InName)).ToString());
        return nullptr;
    }

    /// Open import window, allow to configure some options
    bool bCancel = false;
    TSharedPtr<FglTFImporterOptions> glTFImporterOptions = SglTFImporterOptionsWindowEd::Open(FilePathInOS, InParent->GetPathName(), *GlTF, bCancel);
    if (glTFImporterOptions.IsValid())
    {
        if (glTFImporterOptions->ImportType == EglTFImportType::StaticMesh)
        {
            ImportClass = UStaticMesh::StaticClass();
        }
        else if (glTFImporterOptions->ImportType == EglTFImportType::SkeletalMesh)
        {
            ImportClass = USkeletalMesh::StaticClass();
        }
        else if (glTFImporterOptions->ImportType == EglTFImportType::Actor)
        {
            ImportClass = AActor::StaticClass();
        }
        else if (glTFImporterOptions->ImportType == EglTFImportType::Level)
        {
            ImportClass = ULevel::StaticClass();
        }
        else
        {
            //TODO:
            ImportClass = UStaticMesh::StaticClass();
        }
    }
    if (bCancel)
    {
        UE_LOG(LogglTFForUE4Ed, Display, TEXT("Cancel to import the file - %s"), *FilePathInOS);
        return nullptr;
    }
    if (!glTFImporterOptions.IsValid())
    {
        UE_LOG(LogglTFForUE4Ed, Error, TEXT("Failed to open import window"));
        return nullptr;
    }

    if (!InglTFBuffers.IsValid())
    {
        InglTFBuffers = MakeShareable(new FglTFBuffers);
    }
    const FString FolderPathInOS = FPaths::GetPath(glTFImporterOptions->FilePathInOS);
    InglTFBuffers->Cache(FolderPathInOS, GlTF);

    return FglTFImporterEd::Get(this, ImportClass, InParent, InName, InFlags, InWarn)->Create(glTFImporterOptions, GlTF, *InglTFBuffers);
}

#undef LOCTEXT_NAMESPACE
<commit_msg>[skip ci] convert the `TCHAR` to `WCHAR`<commit_after>// Copyright 2016 - 2020 Code 4 Game, Org. All Rights Reserved.

#include "glTFForUE4EdPrivatePCH.h"
#include "glTFFactory.h"

#include "glTF/glTFImporterOptions.h"
#include "glTF/glTFImporterOptionsWindowEd.h"
#include "glTF/glTFImporterEd.h"

#include "Engine/StaticMesh.h"
#include "Engine/SkeletalMesh.h"
#include "Misc/FeedbackContext.h"
#include "Misc/Paths.h"

#include "ObjectTools.h"

#define LOCTEXT_NAMESPACE "glTFForUE4EdModule"

UglTFFactory::UglTFFactory()
    : Super()
    , ImportClass(nullptr)
{
    //
}

UglTFFactory::UglTFFactory(const FObjectInitializer& InObjectInitializer)
    : Super(InObjectInitializer)
    , ImportClass(nullptr)
{
    if (Formats.Num() > 0) Formats.Empty();
    Formats.Add(TEXT("gltf;glTF 2.0"));

    bCreateNew = false;
    bText = true;
    bEditorImport = true;
}

bool UglTFFactory::DoesSupportClass(UClass* InClass)
{
    return (InClass == UStaticMesh::StaticClass()
        || InClass == USkeletalMesh::StaticClass());
}

UClass* UglTFFactory::ResolveSupportedClass()
{
    if (ImportClass == nullptr) ImportClass = UStaticMesh::StaticClass();
    return ImportClass;
}

bool UglTFFactory::FactoryCanImport(const FString& InFilePathInOS)
{
    return FPaths::GetExtension(InFilePathInOS).Equals(TEXT("gltf"), ESearchCase::IgnoreCase);
}

UObject* UglTFFactory::FactoryCreateText(UClass* InClass, UObject* InParent, FName InName, EObjectFlags InFlags, UObject* InContext, const TCHAR* InType, const TCHAR*& InBuffer, const TCHAR* InBufferEnd, FFeedbackContext* InWarn)
{
    if (!InBuffer || !InBufferEnd || InBuffer >= InBufferEnd)
    {
        InWarn->Log(ELogVerbosity::Error, FText::Format(NSLOCTEXT("glTFForUE4Ed", "BufferHasErrorInFactoryCreateText", "Buffer has some errors when create the glTF file {0}"), FText::FromName(InName)).ToString());
        return nullptr;
    }

    uint64 BufferSize = InBufferEnd - InBuffer;

    FString glTFJson;
    glTFJson.Append(InBuffer, BufferSize);
    return FactoryCreate(InClass, InParent, InName, InFlags, InContext, InType, InWarn, glTFJson);
}

UObject* UglTFFactory::FactoryCreate(UClass* InClass, UObject* InParent, FName InName, EObjectFlags InFlags, UObject* InContext, const TCHAR* InType, FFeedbackContext* InWarn, const FString& InglTFJson, TSharedPtr<FglTFBuffers> InglTFBuffers /*= nullptr*/)
{
    const FString& FilePathInOS = UFactory::GetCurrentFilename();
    if (!ObjectTools::SanitizeObjectName(FPaths::GetBaseFilename(FilePathInOS)).Equals(InName.ToString()))
    {
        UE_LOG(LogglTFForUE4Ed, Error, TEXT("It is different between current filename(%s) and name(%s)!!"), *FilePathInOS, *InName.ToString());
        return nullptr;
    }

    /// Parse and check the buffer
    std::shared_ptr<libgltf::SGlTF> GlTF;
#if defined(UNICODE)
    std::wstring GlTFString = TCHAR_TO_WCHAR(*InglTFJson);
#else
    std::string GlTFString = *InglTFJson;
#endif
    if (!(GlTF << GlTFString))
    {
        InWarn->Log(ELogVerbosity::Error, FText::Format(NSLOCTEXT("glTFForUE4Ed", "FailedToParseTheglTFFile", "Failed to parse the glTF file {0}"), FText::FromName(InName)).ToString());
        return nullptr;
    }

    /// Open import window, allow to configure some options
    bool bCancel = false;
    TSharedPtr<FglTFImporterOptions> glTFImporterOptions = SglTFImporterOptionsWindowEd::Open(FilePathInOS, InParent->GetPathName(), *GlTF, bCancel);
    if (glTFImporterOptions.IsValid())
    {
        if (glTFImporterOptions->ImportType == EglTFImportType::StaticMesh)
        {
            ImportClass = UStaticMesh::StaticClass();
        }
        else if (glTFImporterOptions->ImportType == EglTFImportType::SkeletalMesh)
        {
            ImportClass = USkeletalMesh::StaticClass();
        }
        else if (glTFImporterOptions->ImportType == EglTFImportType::Actor)
        {
            ImportClass = AActor::StaticClass();
        }
        else if (glTFImporterOptions->ImportType == EglTFImportType::Level)
        {
            ImportClass = ULevel::StaticClass();
        }
        else
        {
            //TODO:
            ImportClass = UStaticMesh::StaticClass();
        }
    }
    if (bCancel)
    {
        UE_LOG(LogglTFForUE4Ed, Display, TEXT("Cancel to import the file - %s"), *FilePathInOS);
        return nullptr;
    }
    if (!glTFImporterOptions.IsValid())
    {
        UE_LOG(LogglTFForUE4Ed, Error, TEXT("Failed to open import window"));
        return nullptr;
    }

    if (!InglTFBuffers.IsValid())
    {
        InglTFBuffers = MakeShareable(new FglTFBuffers);
    }
    const FString FolderPathInOS = FPaths::GetPath(glTFImporterOptions->FilePathInOS);
    InglTFBuffers->Cache(FolderPathInOS, GlTF);

    return FglTFImporterEd::Get(this, ImportClass, InParent, InName, InFlags, InWarn)->Create(glTFImporterOptions, GlTF, *InglTFBuffers);
}

#undef LOCTEXT_NAMESPACE
<|endoftext|>


<commit_before>#include <rai/cli/daemon.hpp>

#include <rai/working.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <iostream>
#include <fstream>
#include <thread>

rai_daemon::daemon_config::daemon_config () :
rpc_enable (false),
rpc_address (boost::asio::ip::address_v6::v4_mapped (boost::asio::ip::address_v4::loopback ())),
rpc_enable_control (false)
{
}

void rai_daemon::daemon_config::serialize (std::ostream & output_a)
{
    boost::property_tree::ptree tree;
    tree.put ("rpc_address", rpc_address.to_string ());
    tree.put ("rpc_port", std::to_string (rpc_port));
    tree.put ("rpc_enable", rpc_enable);
    tree.put ("rpc_enable_control", rpc_enable_control);
	boost::property_tree::ptree node_l;
	node.serialize_json (node_l);
	tree.add_child ("node", node_l);
    boost::property_tree::write_json (output_a, tree);
}

rai_daemon::daemon_config::daemon_config (bool & error_a, std::istream & input_a)
{
    error_a = false;
    boost::property_tree::ptree tree;
    try
    {
        boost::property_tree::read_json (input_a, tree);
        auto rpc_address_l (tree.get <std::string> ("rpc_address"));
        auto rpc_port_l (tree.get <std::string> ("rpc_port"));
        rpc_enable = tree.get <bool> ("rpc_enable");
        rpc_enable_control = tree.get <bool> ("rpc_enable_control");
        auto bootstrap_peers_l (tree.get_child ("bootstrap_peers"));
		auto node_l (tree.get_child ("node"));
		error_a = error_a | node.deserialize_json (node_l);
        try
        {
            rpc_port = std::stoul (rpc_port_l);
            error_a = rpc_port > std::numeric_limits <uint16_t>::max ();
        }
        catch (std::logic_error const &)
        {
            error_a = true;
        }
        boost::system::error_code ec;
        rpc_address = boost::asio::ip::address_v6::from_string (rpc_address_l, ec);
        if (ec)
        {
            error_a = true;
        }
    }
    catch (std::runtime_error const &)
    {
        error_a = true;
    }
}

rai_daemon::daemon::daemon ()
{
}

void rai_daemon::daemon::run ()
{
    auto working (rai::working_path ());
	boost::filesystem::create_directories (working);
    auto config_error (false);
    rai_daemon::daemon_config config;
    auto config_path ((working / "config.json").string ());
    std::ifstream config_file;
    config_file.open (config_path);
    if (!config_file.fail ())
    {
        config = rai_daemon::daemon_config (config_error, config_file);
    }
    else
    {
        std::ofstream config_file;
        config_file.open (config_path);
        if (!config_file.fail ())
        {
            config.serialize (config_file);
        }
    }
    if (!config_error)
    {
        auto service (boost::make_shared <boost::asio::io_service> ());
        auto pool (boost::make_shared <boost::network::utils::thread_pool> ());
        rai::processor_service processor;
        rai::node_init init;
        auto node (std::make_shared <rai::node> (init, service, working, processor, config.node));
        if (!init.error ())
        {
            node->start ();
            rai::rpc rpc (service, pool, config.rpc_address, config.rpc_port, *node, config.rpc_enable_control);
            if (config.rpc_enable)
            {
                rpc.start ();
            }
            std::thread network_thread ([&service] ()
                {
                    try
                    {
                        service->run ();
                    }
                    catch (...)
                    {
                        assert (false);
                    }
                });
            std::thread processor_thread ([&processor] ()
                {
                    try
                    {
                        processor.run ();
                    }
                    catch (...)
                    {
                        assert (false);
                    }
                });
            network_thread.join ();
            processor_thread.join ();
        }
        else
        {
            std::cerr << "Error initializing node\n";
        }
    }
    else
    {
        std::cerr << "Error loading configuration\n";
    }
}
<commit_msg>Readding default rpc port.<commit_after>#include <rai/cli/daemon.hpp>

#include <rai/working.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <iostream>
#include <fstream>
#include <thread>

rai_daemon::daemon_config::daemon_config () :
rpc_enable (false),
rpc_address (boost::asio::ip::address_v6::v4_mapped (boost::asio::ip::address_v4::loopback ())),
rpc_port (rai::network::rpc_port),
rpc_enable_control (false)
{
}

void rai_daemon::daemon_config::serialize (std::ostream & output_a)
{
    boost::property_tree::ptree tree;
    tree.put ("rpc_address", rpc_address.to_string ());
    tree.put ("rpc_port", std::to_string (rpc_port));
    tree.put ("rpc_enable", rpc_enable);
    tree.put ("rpc_enable_control", rpc_enable_control);
	boost::property_tree::ptree node_l;
	node.serialize_json (node_l);
	tree.add_child ("node", node_l);
    boost::property_tree::write_json (output_a, tree);
}

rai_daemon::daemon_config::daemon_config (bool & error_a, std::istream & input_a)
{
    error_a = false;
    boost::property_tree::ptree tree;
    try
    {
        boost::property_tree::read_json (input_a, tree);
        auto rpc_address_l (tree.get <std::string> ("rpc_address"));
        auto rpc_port_l (tree.get <std::string> ("rpc_port"));
        rpc_enable = tree.get <bool> ("rpc_enable");
        rpc_enable_control = tree.get <bool> ("rpc_enable_control");
        auto bootstrap_peers_l (tree.get_child ("bootstrap_peers"));
		auto node_l (tree.get_child ("node"));
		error_a = error_a | node.deserialize_json (node_l);
        try
        {
            rpc_port = std::stoul (rpc_port_l);
            error_a = rpc_port > std::numeric_limits <uint16_t>::max ();
        }
        catch (std::logic_error const &)
        {
            error_a = true;
        }
        boost::system::error_code ec;
        rpc_address = boost::asio::ip::address_v6::from_string (rpc_address_l, ec);
        if (ec)
        {
            error_a = true;
        }
    }
    catch (std::runtime_error const &)
    {
        error_a = true;
    }
}

rai_daemon::daemon::daemon ()
{
}

void rai_daemon::daemon::run ()
{
    auto working (rai::working_path ());
	boost::filesystem::create_directories (working);
    auto config_error (false);
    rai_daemon::daemon_config config;
    auto config_path ((working / "config.json").string ());
    std::ifstream config_file;
    config_file.open (config_path);
    if (!config_file.fail ())
    {
        config = rai_daemon::daemon_config (config_error, config_file);
    }
    else
    {
        std::ofstream config_file;
        config_file.open (config_path);
        if (!config_file.fail ())
        {
            config.serialize (config_file);
        }
    }
    if (!config_error)
    {
        auto service (boost::make_shared <boost::asio::io_service> ());
        auto pool (boost::make_shared <boost::network::utils::thread_pool> ());
        rai::processor_service processor;
        rai::node_init init;
        auto node (std::make_shared <rai::node> (init, service, working, processor, config.node));
        if (!init.error ())
        {
            node->start ();
            rai::rpc rpc (service, pool, config.rpc_address, config.rpc_port, *node, config.rpc_enable_control);
            if (config.rpc_enable)
            {
                rpc.start ();
            }
            std::thread network_thread ([&service] ()
                {
                    try
                    {
                        service->run ();
                    }
                    catch (...)
                    {
                        assert (false);
                    }
                });
            std::thread processor_thread ([&processor] ()
                {
                    try
                    {
                        processor.run ();
                    }
                    catch (...)
                    {
                        assert (false);
                    }
                });
            network_thread.join ();
            processor_thread.join ();
        }
        else
        {
            std::cerr << "Error initializing node\n";
        }
    }
    else
    {
        std::cerr << "Error loading configuration\n";
    }
}
<|endoftext|>


<commit_before>//-----------------------------------------------
//
//	This file is part of the Siv3D Engine.
//
//	Copyright (c) 2008-2021 Ryo Suzuki
//	Copyright (c) 2016-2021 OpenSiv3D Project
//
//	Licensed under the MIT License.
//
//-----------------------------------------------

# include <Siv3D/ImageProcessing.hpp>
# include <Siv3D/OpenCV_Bridge.hpp>

namespace s3d
{
	namespace detail
	{
		static Image GenerateMip(const Image& src)
		{
			if (not src)
			{
				return{};
			}

			const Color* pSrc = src.data();
			const int32 srcW = src.width();
			const int32 srcH = src.height();

			const int32 targetWidth = Max(src.width() / 2, 1);
			const int32 targetHeight = Max(src.height() / 2, 1);
			Image result(targetWidth, targetHeight);
			Color* pDst = result.data();

			const float sddx = (srcW - 1.0f) / Max(targetWidth - 1, 1);
			const float sddy = (srcH - 1.0f) / Max(targetHeight - 1, 1);

			for (int32 y = 0; y < targetHeight; ++y)
			{
				float sy = y * sddy;

				const int32 dy = static_cast<int32>(sy);

				sy -= dy;

				const int32 dyO = Min(dy + 1, srcH - 1);

				for (int32 x = 0; x < targetWidth; ++x)
				{
					float sx = x * sddx;

					const int32 dx = static_cast<int32>(sx);

					sx -= dx;

					const int32 dxO = Min(dx + 1, srcW - 1);

					const Color& c0 = pSrc[dy * srcW + dx];
					const Color& c1 = pSrc[dy * srcW + dxO];
					const Color& c2 = pSrc[dyO * srcW + dx];
					const Color& c3 = pSrc[dyO * srcW + dxO];

					const uint8 r = static_cast<uint8>((c0.r * (1 - sx) + c1.r * sx) * (1 - sy) + (c2.r * (1 - sx) + c3.r * sx) * sy);
					const uint8 g = static_cast<uint8>((c0.g * (1 - sx) + c1.g * sx) * (1 - sy) + (c2.g * (1 - sx) + c3.g * sx) * sy);
					const uint8 b = static_cast<uint8>((c0.b * (1 - sx) + c1.b * sx) * (1 - sy) + (c2.b * (1 - sx) + c3.b * sx) * sy);
					const uint8 a = static_cast<uint8>((c0.a * (1 - sx) + c1.a * sx) * (1 - sy) + (c2.a * (1 - sx) + c3.a * sx) * sy);

					(pDst++)->set(r, g, b, a);
				}
			}

			return result;
		}
	}

	namespace ImageProcessing
	{
		Array<Image> GenerateMips(const Image& src)
		{
			const size_t mipCount = (CalculateMipCount(src.width(), src.height()) - 1);

			if (mipCount < 1)
			{
				return{};
			}

			Array<Image> mipImages(mipCount);

			mipImages[0] = detail::GenerateMip(src);

			for (size_t i = 1; i < mipCount; ++i)
			{
				mipImages[i] = detail::GenerateMip(mipImages[i - 1]);
			}

			return mipImages;
		}

		void Sobel(const Image& src, Image& dst, const int32 dx, const int32 dy, int32 apertureSize)
		{
			// 1. パラメータチェック
			{
				if (not src)
				{
					return;
				}

				if (&src == &dst)
				{
					return;
				}

				if (IsEven(apertureSize))
				{
					++apertureSize;
				}
			}

			// 2. 出力画像のサイズ変更
			{
				dst.resize(src.size());
				std::memcpy(dst.data(), src.data(), dst.size_bytes());
			}

			// 3. 処理
			{
				const cv::Mat_<uint8> gray = OpenCV_Bridge::ToGrayScale(src);
				cv::Mat_<uint8> detected_edges;
				cv::Sobel(gray, detected_edges, CV_8U, dx, dy, apertureSize);
				OpenCV_Bridge::FromGrayScale(detected_edges, dst, OverwriteAlpha::No);
			}
		}

		void Laplacian(const Image& src, Image& dst, int32 apertureSize)
		{
			// 1. パラメータチェック
			{
				if (not src)
				{
					return;
				}

				if (&src == &dst)
				{
					return;
				}

				if (IsEven(apertureSize))
				{
					++apertureSize;
				}
			}

			// 2. 出力画像のサイズ変更
			{
				dst.resize(src.size());
				std::memcpy(dst.data(), src.data(), dst.size_bytes());
			}

			// 3. 処理
			{
				const cv::Mat_<uint8> gray = OpenCV_Bridge::ToGrayScale(src);
				cv::Mat_<uint8> detected_edges;
				cv::Laplacian(gray, detected_edges, CV_8U, apertureSize);
				OpenCV_Bridge::FromGrayScale(detected_edges, dst, OverwriteAlpha::No);
			}
		}

		void Canny(const Image& src, Image& dst, const uint8 lowThreshold, const uint8 highThreshold, int32 apertureSize, const bool useL2Gradient)
		{
			// 1. パラメータチェック
			{
				if (not src)
				{
					return;
				}

				if (&src == &dst)
				{
					return;
				}

				if (IsEven(apertureSize))
				{
					++apertureSize;
				}
			}

			// 2. 出力画像のサイズ変更
			{
				dst.resize(src.size());
				std::memcpy(dst.data(), src.data(), dst.size_bytes());
			}

			// 3. 処理
			{
				const cv::Mat_<uint8> gray = OpenCV_Bridge::ToGrayScale(src);
				cv::Mat_<uint8> detected_edges;
				cv::blur(gray, detected_edges, cv::Size(3, 3));
				cv::Canny(detected_edges, detected_edges, lowThreshold, highThreshold, apertureSize, useL2Gradient);
				OpenCV_Bridge::FromGrayScale(detected_edges, dst, OverwriteAlpha::No);
			}
		}

		void EdgePreservingFilter(const Image& src, Image& dst, EdgePreservingFilterType filterType, double sigma_s, double sigma_r)
		{
			// 1. パラメータチェック
			{
				if (not src)
				{
					return dst.clear();
				}
			}

			// 2. 出力画像のサイズ変更
			{
				dst.resize(src.size());
				std::memcpy(dst.data(), src.data(), dst.size_bytes());
			}

			// 3. 処理
			{
				const cv::Mat_<cv::Vec3b> matSrc = OpenCV_Bridge::ToMatVec3bBGR(src);
				cv::Mat_<cv::Vec3b> matDst;
				cv::edgePreservingFilter(matSrc, matDst,
					(filterType == EdgePreservingFilterType::Recursive)
					? cv::RECURS_FILTER : cv::NORMCONV_FILTER,
					static_cast<float>(sigma_s), static_cast<float>(sigma_r));
				OpenCV_Bridge::FromMatVec3b(matDst, dst, OverwriteAlpha::No);
			}
		}

		void DetailEnhance(const Image& src, Image& dst, double sigma_s, double sigma_r)
		{
			// 1. パラメータチェック
			{
				if (not src)
				{
					return dst.clear();
				}
			}

			// 2. 出力画像のサイズ変更
			{
				dst.resize(src.size());
				std::memcpy(dst.data(), src.data(), dst.size_bytes());
			}

			// 3. 処理
			{
				cv::Mat_<cv::Vec3b> matSrc = OpenCV_Bridge::ToMatVec3bBGR(src);
				cv::Mat_<cv::Vec3b> matDst;
				cv::detailEnhance(matSrc, matDst, static_cast<float>(sigma_s), static_cast<float>(sigma_r));
				OpenCV_Bridge::FromMatVec3b(matDst, dst, OverwriteAlpha::No);
			}
		}

		void Stylization(const Image& src, Image& dst, double sigma_s, double sigma_r)
		{
			// 1. パラメータチェック
			{
				if (not src)
				{
					return dst.clear();
				}
			}

			// 2. 出力画像のサイズ変更
			{
				dst.resize(src.size());
				std::memcpy(dst.data(), src.data(), dst.size_bytes());
			}

			// 3. 処理
			{
				cv::Mat_<cv::Vec3b> matSrc = OpenCV_Bridge::ToMatVec3bBGR(src);
				cv::Mat_<cv::Vec3b> matDst;
				cv::stylization(matSrc, matDst, static_cast<float>(sigma_s), static_cast<float>(sigma_r));
				OpenCV_Bridge::FromMatVec3b(matDst, dst, OverwriteAlpha::No);
			}
		}

		ColorF SSIM(const Image& image1, const Image& image2)
		{
			if (image1.size() != image2.size())
			{
				return ColorF{ 1.0 };
			}

			const double C1 = 6.5025, C2 = 58.5225;
			const int32 x = image1.width(), y = image1.height();

			cv::Mat_<cv::Vec3f> I1(y, x), I2(y, x);
			OpenCV_Bridge::ToMatVec3f255(image1, I1);
			OpenCV_Bridge::ToMatVec3f255(image2, I2);

			cv::Mat I2_2 = I2.mul(I2);        // I2^2
			cv::Mat I1_2 = I1.mul(I1);        // I1^2
			cv::Mat I1_I2 = I1.mul(I2);        // I1 * I2

			/*************************** END INITS **********************************/

			cv::Mat mu1, mu2;   // PRELIMINARY COMPUTING
			cv::GaussianBlur(I1, mu1, cv::Size(11, 11), 1.5);
			cv::GaussianBlur(I2, mu2, cv::Size(11, 11), 1.5);

			cv::Mat mu1_2 = mu1.mul(mu1);
			cv::Mat mu2_2 = mu2.mul(mu2);
			cv::Mat mu1_mu2 = mu1.mul(mu2);

			cv::Mat sigma1_2, sigma2_2, sigma12;

			cv::GaussianBlur(I1_2, sigma1_2, cv::Size(11, 11), 1.5);
			sigma1_2 -= mu1_2;

			cv::GaussianBlur(I2_2, sigma2_2, cv::Size(11, 11), 1.5);
			sigma2_2 -= mu2_2;

			cv::GaussianBlur(I1_I2, sigma12, cv::Size(11, 11), 1.5);
			sigma12 -= mu1_mu2;

			///////////////////////////////// FORMULA ////////////////////////////////
			cv::Mat t1, t2, t3;

			t1 = 2 * mu1_mu2 + C1;
			t2 = 2 * sigma12 + C2;
			t3 = t1.mul(t2);              // t3 = ((2*mu1_mu2 + C1).*(2*sigma12 + C2))

			t1 = mu1_2 + mu2_2 + C1;
			t2 = sigma1_2 + sigma2_2 + C2;
			t1 = t1.mul(t2);               // t1 =((mu1_2 + mu2_2 + C1).*(sigma1_2 + sigma2_2 + C2))

			cv::Mat ssim_map;
			cv::divide(t3, t1, ssim_map);      // ssim_map =  t3./t1;

			cv::Scalar mssim = cv::mean(ssim_map); // mssim = average of ssim map
			return{ mssim[2], mssim[1], mssim[0], 1.0 };
		}

		void Inpaint(const Image& image, const Image& maskImage, const Color& maskColor, Image& result, int32 radius)
		{
			// 1. パラメータチェック
			{
				if ((not image) || (not maskImage))
				{
					return;
				}

				if (image.size() != maskImage.size())
				{
					return;
				}

				radius = Max(radius, 0);
			}

			// 2. 処理
			{
				cv::Mat_<cv::Vec3b> matSrc = OpenCV_Bridge::ToMatVec3bBGR(image);

				cv::Mat_<uint8> matMask(image.height(), image.width());
				OpenCV_Bridge::MaskByColor(maskImage, matMask, maskColor);

				cv::Mat_<cv::Vec3b> matDst;
				cv::inpaint(matSrc, matMask, matDst, radius, cv::INPAINT_TELEA);
				OpenCV_Bridge::FromMatVec3b(matDst, result, OverwriteAlpha::Yes);
			}
		}

		void Inpaint(const Image& image, const Grid<uint8>& maskImage, Image& result, int32 radius)
		{
			// 1. パラメータチェック
			{
				if ((not image) || (not maskImage))
				{
					return;
				}

				if (image.size() != maskImage.size())
				{
					return;
				}

				radius = Max(radius, 0);
			}

			// 2. 処理
			{
				cv::Mat_<cv::Vec3b> matSrc = OpenCV_Bridge::ToMatVec3bBGR(image);
				cv::Mat_<uint8> matMask(static_cast<int32>(maskImage.height()), static_cast<int32>(maskImage.width()), const_cast<uint8*>(maskImage.data()), static_cast<int32>(maskImage.width()));
				cv::Mat_<cv::Vec3b> matDst;
				cv::inpaint(matSrc, matMask, matDst, radius, cv::INPAINT_TELEA);
				OpenCV_Bridge::FromMatVec3b(matDst, result, OverwriteAlpha::Yes);
			}
		}
	}
}
<commit_msg>[共通] improve GenerateMip()<commit_after>//-----------------------------------------------
//
//	This file is part of the Siv3D Engine.
//
//	Copyright (c) 2008-2021 Ryo Suzuki
//	Copyright (c) 2016-2021 OpenSiv3D Project
//
//	Licensed under the MIT License.
//
//-----------------------------------------------

# include <Siv3D/ImageProcessing.hpp>
# include <Siv3D/OpenCV_Bridge.hpp>

namespace s3d
{
	namespace detail
	{
		static Image GenerateMip(const Image& src)
		{
			if (not src)
			{
				return{};
			}

			const Color* pSrc = src.data();
			const int32 srcW = src.width();
			const int32 srcH = src.height();

			const int32 targetWidth = Max(src.width() / 2, 1);
			const int32 targetHeight = Max(src.height() / 2, 1);

			if ((targetWidth <= 4) && (targetHeight <= 4))
			{
				return src.scaled(targetWidth, targetHeight, InterpolationAlgorithm::Area);
			}

			Image result(targetWidth, targetHeight);
			Color* pDst = result.data();

			const float sddx = (srcW - 1.0f) / Max(targetWidth - 1, 1);
			const float sddy = (srcH - 1.0f) / Max(targetHeight - 1, 1);

			for (int32 y = 0; y < targetHeight; ++y)
			{
				float sy = y * sddy;

				const int32 dy = static_cast<int32>(sy);

				sy -= dy;

				const int32 dyO = Min(dy + 1, srcH - 1);

				for (int32 x = 0; x < targetWidth; ++x)
				{
					float sx = x * sddx;

					const int32 dx = static_cast<int32>(sx);

					sx -= dx;

					const int32 dxO = Min(dx + 1, srcW - 1);

					const Color& c0 = pSrc[dy * srcW + dx];
					const Color& c1 = pSrc[dy * srcW + dxO];
					const Color& c2 = pSrc[dyO * srcW + dx];
					const Color& c3 = pSrc[dyO * srcW + dxO];

					const uint8 r = static_cast<uint8>((c0.r * (1 - sx) + c1.r * sx) * (1 - sy) + (c2.r * (1 - sx) + c3.r * sx) * sy);
					const uint8 g = static_cast<uint8>((c0.g * (1 - sx) + c1.g * sx) * (1 - sy) + (c2.g * (1 - sx) + c3.g * sx) * sy);
					const uint8 b = static_cast<uint8>((c0.b * (1 - sx) + c1.b * sx) * (1 - sy) + (c2.b * (1 - sx) + c3.b * sx) * sy);
					const uint8 a = static_cast<uint8>((c0.a * (1 - sx) + c1.a * sx) * (1 - sy) + (c2.a * (1 - sx) + c3.a * sx) * sy);

					(pDst++)->set(r, g, b, a);
				}
			}

			return result;
		}
	}

	namespace ImageProcessing
	{
		Array<Image> GenerateMips(const Image& src)
		{
			const size_t mipCount = (CalculateMipCount(src.width(), src.height()) - 1);

			if (mipCount < 1)
			{
				return{};
			}

			Array<Image> mipImages(mipCount);

			mipImages[0] = detail::GenerateMip(src);

			for (size_t i = 1; i < mipCount; ++i)
			{
				mipImages[i] = detail::GenerateMip(mipImages[i - 1]);
			}

			return mipImages;
		}

		void Sobel(const Image& src, Image& dst, const int32 dx, const int32 dy, int32 apertureSize)
		{
			// 1. パラメータチェック
			{
				if (not src)
				{
					return;
				}

				if (&src == &dst)
				{
					return;
				}

				if (IsEven(apertureSize))
				{
					++apertureSize;
				}
			}

			// 2. 出力画像のサイズ変更
			{
				dst.resize(src.size());
				std::memcpy(dst.data(), src.data(), dst.size_bytes());
			}

			// 3. 処理
			{
				const cv::Mat_<uint8> gray = OpenCV_Bridge::ToGrayScale(src);
				cv::Mat_<uint8> detected_edges;
				cv::Sobel(gray, detected_edges, CV_8U, dx, dy, apertureSize);
				OpenCV_Bridge::FromGrayScale(detected_edges, dst, OverwriteAlpha::No);
			}
		}

		void Laplacian(const Image& src, Image& dst, int32 apertureSize)
		{
			// 1. パラメータチェック
			{
				if (not src)
				{
					return;
				}

				if (&src == &dst)
				{
					return;
				}

				if (IsEven(apertureSize))
				{
					++apertureSize;
				}
			}

			// 2. 出力画像のサイズ変更
			{
				dst.resize(src.size());
				std::memcpy(dst.data(), src.data(), dst.size_bytes());
			}

			// 3. 処理
			{
				const cv::Mat_<uint8> gray = OpenCV_Bridge::ToGrayScale(src);
				cv::Mat_<uint8> detected_edges;
				cv::Laplacian(gray, detected_edges, CV_8U, apertureSize);
				OpenCV_Bridge::FromGrayScale(detected_edges, dst, OverwriteAlpha::No);
			}
		}

		void Canny(const Image& src, Image& dst, const uint8 lowThreshold, const uint8 highThreshold, int32 apertureSize, const bool useL2Gradient)
		{
			// 1. パラメータチェック
			{
				if (not src)
				{
					return;
				}

				if (&src == &dst)
				{
					return;
				}

				if (IsEven(apertureSize))
				{
					++apertureSize;
				}
			}

			// 2. 出力画像のサイズ変更
			{
				dst.resize(src.size());
				std::memcpy(dst.data(), src.data(), dst.size_bytes());
			}

			// 3. 処理
			{
				const cv::Mat_<uint8> gray = OpenCV_Bridge::ToGrayScale(src);
				cv::Mat_<uint8> detected_edges;
				cv::blur(gray, detected_edges, cv::Size(3, 3));
				cv::Canny(detected_edges, detected_edges, lowThreshold, highThreshold, apertureSize, useL2Gradient);
				OpenCV_Bridge::FromGrayScale(detected_edges, dst, OverwriteAlpha::No);
			}
		}

		void EdgePreservingFilter(const Image& src, Image& dst, EdgePreservingFilterType filterType, double sigma_s, double sigma_r)
		{
			// 1. パラメータチェック
			{
				if (not src)
				{
					return dst.clear();
				}
			}

			// 2. 出力画像のサイズ変更
			{
				dst.resize(src.size());
				std::memcpy(dst.data(), src.data(), dst.size_bytes());
			}

			// 3. 処理
			{
				const cv::Mat_<cv::Vec3b> matSrc = OpenCV_Bridge::ToMatVec3bBGR(src);
				cv::Mat_<cv::Vec3b> matDst;
				cv::edgePreservingFilter(matSrc, matDst,
					(filterType == EdgePreservingFilterType::Recursive)
					? cv::RECURS_FILTER : cv::NORMCONV_FILTER,
					static_cast<float>(sigma_s), static_cast<float>(sigma_r));
				OpenCV_Bridge::FromMatVec3b(matDst, dst, OverwriteAlpha::No);
			}
		}

		void DetailEnhance(const Image& src, Image& dst, double sigma_s, double sigma_r)
		{
			// 1. パラメータチェック
			{
				if (not src)
				{
					return dst.clear();
				}
			}

			// 2. 出力画像のサイズ変更
			{
				dst.resize(src.size());
				std::memcpy(dst.data(), src.data(), dst.size_bytes());
			}

			// 3. 処理
			{
				cv::Mat_<cv::Vec3b> matSrc = OpenCV_Bridge::ToMatVec3bBGR(src);
				cv::Mat_<cv::Vec3b> matDst;
				cv::detailEnhance(matSrc, matDst, static_cast<float>(sigma_s), static_cast<float>(sigma_r));
				OpenCV_Bridge::FromMatVec3b(matDst, dst, OverwriteAlpha::No);
			}
		}

		void Stylization(const Image& src, Image& dst, double sigma_s, double sigma_r)
		{
			// 1. パラメータチェック
			{
				if (not src)
				{
					return dst.clear();
				}
			}

			// 2. 出力画像のサイズ変更
			{
				dst.resize(src.size());
				std::memcpy(dst.data(), src.data(), dst.size_bytes());
			}

			// 3. 処理
			{
				cv::Mat_<cv::Vec3b> matSrc = OpenCV_Bridge::ToMatVec3bBGR(src);
				cv::Mat_<cv::Vec3b> matDst;
				cv::stylization(matSrc, matDst, static_cast<float>(sigma_s), static_cast<float>(sigma_r));
				OpenCV_Bridge::FromMatVec3b(matDst, dst, OverwriteAlpha::No);
			}
		}

		ColorF SSIM(const Image& image1, const Image& image2)
		{
			if (image1.size() != image2.size())
			{
				return ColorF{ 1.0 };
			}

			const double C1 = 6.5025, C2 = 58.5225;
			const int32 x = image1.width(), y = image1.height();

			cv::Mat_<cv::Vec3f> I1(y, x), I2(y, x);
			OpenCV_Bridge::ToMatVec3f255(image1, I1);
			OpenCV_Bridge::ToMatVec3f255(image2, I2);

			cv::Mat I2_2 = I2.mul(I2);        // I2^2
			cv::Mat I1_2 = I1.mul(I1);        // I1^2
			cv::Mat I1_I2 = I1.mul(I2);        // I1 * I2

			/*************************** END INITS **********************************/

			cv::Mat mu1, mu2;   // PRELIMINARY COMPUTING
			cv::GaussianBlur(I1, mu1, cv::Size(11, 11), 1.5);
			cv::GaussianBlur(I2, mu2, cv::Size(11, 11), 1.5);

			cv::Mat mu1_2 = mu1.mul(mu1);
			cv::Mat mu2_2 = mu2.mul(mu2);
			cv::Mat mu1_mu2 = mu1.mul(mu2);

			cv::Mat sigma1_2, sigma2_2, sigma12;

			cv::GaussianBlur(I1_2, sigma1_2, cv::Size(11, 11), 1.5);
			sigma1_2 -= mu1_2;

			cv::GaussianBlur(I2_2, sigma2_2, cv::Size(11, 11), 1.5);
			sigma2_2 -= mu2_2;

			cv::GaussianBlur(I1_I2, sigma12, cv::Size(11, 11), 1.5);
			sigma12 -= mu1_mu2;

			///////////////////////////////// FORMULA ////////////////////////////////
			cv::Mat t1, t2, t3;

			t1 = 2 * mu1_mu2 + C1;
			t2 = 2 * sigma12 + C2;
			t3 = t1.mul(t2);              // t3 = ((2*mu1_mu2 + C1).*(2*sigma12 + C2))

			t1 = mu1_2 + mu2_2 + C1;
			t2 = sigma1_2 + sigma2_2 + C2;
			t1 = t1.mul(t2);               // t1 =((mu1_2 + mu2_2 + C1).*(sigma1_2 + sigma2_2 + C2))

			cv::Mat ssim_map;
			cv::divide(t3, t1, ssim_map);      // ssim_map =  t3./t1;

			cv::Scalar mssim = cv::mean(ssim_map); // mssim = average of ssim map
			return{ mssim[2], mssim[1], mssim[0], 1.0 };
		}

		void Inpaint(const Image& image, const Image& maskImage, const Color& maskColor, Image& result, int32 radius)
		{
			// 1. パラメータチェック
			{
				if ((not image) || (not maskImage))
				{
					return;
				}

				if (image.size() != maskImage.size())
				{
					return;
				}

				radius = Max(radius, 0);
			}

			// 2. 処理
			{
				cv::Mat_<cv::Vec3b> matSrc = OpenCV_Bridge::ToMatVec3bBGR(image);

				cv::Mat_<uint8> matMask(image.height(), image.width());
				OpenCV_Bridge::MaskByColor(maskImage, matMask, maskColor);

				cv::Mat_<cv::Vec3b> matDst;
				cv::inpaint(matSrc, matMask, matDst, radius, cv::INPAINT_TELEA);
				OpenCV_Bridge::FromMatVec3b(matDst, result, OverwriteAlpha::Yes);
			}
		}

		void Inpaint(const Image& image, const Grid<uint8>& maskImage, Image& result, int32 radius)
		{
			// 1. パラメータチェック
			{
				if ((not image) || (not maskImage))
				{
					return;
				}

				if (image.size() != maskImage.size())
				{
					return;
				}

				radius = Max(radius, 0);
			}

			// 2. 処理
			{
				cv::Mat_<cv::Vec3b> matSrc = OpenCV_Bridge::ToMatVec3bBGR(image);
				cv::Mat_<uint8> matMask(static_cast<int32>(maskImage.height()), static_cast<int32>(maskImage.width()), const_cast<uint8*>(maskImage.data()), static_cast<int32>(maskImage.width()));
				cv::Mat_<cv::Vec3b> matDst;
				cv::inpaint(matSrc, matMask, matDst, radius, cv::INPAINT_TELEA);
				OpenCV_Bridge::FromMatVec3b(matDst, result, OverwriteAlpha::Yes);
			}
		}
	}
}
<|endoftext|>


<commit_before>//-----------------------------------------------
//
//	This file is part of the Siv3D Engine.
//
//	Copyright (c) 2008-2021 Ryo Suzuki
//	Copyright (c) 2016-2021 OpenSiv3D Project
//
//	Licensed under the MIT License.
//
//-----------------------------------------------

# include <Siv3D/SimpleAnimation.hpp>
# include <Siv3D/Math.hpp>

namespace s3d
{
	SimpleAnimation::SimpleAnimation(ISteadyClock* pSteadyClock)
		: m_stopwatch{ StartImmediately::No, pSteadyClock } {}

	SimpleAnimation& SimpleAnimation::set(const StringView name, const KeyFrame& a, const KeyFrame& b, double func(double))
	{
		if ((b.time <= a.time)
			|| (func == nullptr))
		{
			return *this;
		}

		m_animationDurationSec = Max(m_animationDurationSec, b.time.count());

		m_animations[name].push_back({ a, b, func });

		m_animations[name].sort_by([](const Animation& a, const Animation& b) { return (a.a.time < b.a.time); });

		return *this;
	}

	SimpleAnimation& SimpleAnimation::setLoop(const SecondsF& loopEnd)
	{
		m_loopTiming.first = 0.0;
		m_loopTiming.second = loopEnd.count();
		return *this;
	}

	SimpleAnimation& SimpleAnimation::setLoop(const SecondsF& loopBegin, const SecondsF& loopEnd)
	{
		m_loopTiming.first = loopBegin.count();
		m_loopTiming.second = loopEnd.count();
		return *this;
	}

	double SimpleAnimation::operator [](const StringView name) const
	{
		auto it = m_animations.find(name);

		if (it == m_animations.end())
		{
			return 0.0;
		}

		return GetValue(it->second, posSec());
	}

	void SimpleAnimation::start()
	{
		m_stopwatch.start();
	}

	void SimpleAnimation::pause()
	{
		m_stopwatch.pause();
	}

	void SimpleAnimation::resume()
	{
		m_stopwatch.resume();
	}

	void SimpleAnimation::restart()
	{
		m_stopwatch.restart();
	}

	double SimpleAnimation::posSec() const
	{
		const double t = m_stopwatch.sF();

		if (m_loopTiming.second == 0.0)
		{
			return t;
		}

		if (t <= m_loopTiming.second)
		{
			return t;
		}
		else
		{
			const double loopLength = (m_loopTiming.second - m_loopTiming.first);

			const double ext = (t - m_loopTiming.second);

			return (m_loopTiming.first + Math::Fmod(ext, loopLength));
		}
	}

	double SimpleAnimation::lengthSec() const noexcept
	{
		return m_animationDurationSec;
	}

	bool SimpleAnimation::isDone() const
	{
		if (m_loopTiming.second != 0.0)
		{
			return false;
		}

		return (m_stopwatch.sF() <= m_animationDurationSec);
	}

	size_t SimpleAnimation::loopCount() const
	{
		if (m_loopTiming.second == 0.0)
		{
			return 0;
		}

		const double t = m_stopwatch.sF();

		if (t <= m_loopTiming.second)
		{
			return 0;
		}
		else
		{
			const double loopLength = (m_loopTiming.second - m_loopTiming.first);

			const double ext = (t - m_loopTiming.second);

			return static_cast<size_t>(1 + (ext / loopLength));
		}
	}

	double SimpleAnimation::GetValue(const Array<Animation>& animations, const double timeSec)
	{
		if (timeSec < animations.front().a.time.count())
		{
			return animations.front().a.value;
		}

		if (animations.back().b.time.count() <= timeSec)
		{
			return animations.back().b.value;
		}

		for (size_t i = 0; i < animations.size(); ++i)
		{
			const auto& animation = animations[i];
			const double tA = animation.a.time.count();
			const double tB = animation.b.time.count();

			if (timeSec < tA)
			{
				return animations[i - 1].b.value;
			}

			if (InRange(timeSec, tA, tB))
			{
				const double duration = (tB - tA);
				const double f = ((timeSec - tA) / duration);
				return Math::Lerp(animation.a.value, animation.b.value, animation.func(f));
			}
		}

		return animations.back().b.value;
	}
}
<commit_msg>SimpleAnimation::isDone()の戻り値(bool)を修正 (#711)<commit_after>//-----------------------------------------------
//
//	This file is part of the Siv3D Engine.
//
//	Copyright (c) 2008-2021 Ryo Suzuki
//	Copyright (c) 2016-2021 OpenSiv3D Project
//
//	Licensed under the MIT License.
//
//-----------------------------------------------

# include <Siv3D/SimpleAnimation.hpp>
# include <Siv3D/Math.hpp>

namespace s3d
{
	SimpleAnimation::SimpleAnimation(ISteadyClock* pSteadyClock)
		: m_stopwatch{ StartImmediately::No, pSteadyClock } {}

	SimpleAnimation& SimpleAnimation::set(const StringView name, const KeyFrame& a, const KeyFrame& b, double func(double))
	{
		if ((b.time <= a.time)
			|| (func == nullptr))
		{
			return *this;
		}

		m_animationDurationSec = Max(m_animationDurationSec, b.time.count());

		m_animations[name].push_back({ a, b, func });

		m_animations[name].sort_by([](const Animation& a, const Animation& b) { return (a.a.time < b.a.time); });

		return *this;
	}

	SimpleAnimation& SimpleAnimation::setLoop(const SecondsF& loopEnd)
	{
		m_loopTiming.first = 0.0;
		m_loopTiming.second = loopEnd.count();
		return *this;
	}

	SimpleAnimation& SimpleAnimation::setLoop(const SecondsF& loopBegin, const SecondsF& loopEnd)
	{
		m_loopTiming.first = loopBegin.count();
		m_loopTiming.second = loopEnd.count();
		return *this;
	}

	double SimpleAnimation::operator [](const StringView name) const
	{
		auto it = m_animations.find(name);

		if (it == m_animations.end())
		{
			return 0.0;
		}

		return GetValue(it->second, posSec());
	}

	void SimpleAnimation::start()
	{
		m_stopwatch.start();
	}

	void SimpleAnimation::pause()
	{
		m_stopwatch.pause();
	}

	void SimpleAnimation::resume()
	{
		m_stopwatch.resume();
	}

	void SimpleAnimation::restart()
	{
		m_stopwatch.restart();
	}

	double SimpleAnimation::posSec() const
	{
		const double t = m_stopwatch.sF();

		if (m_loopTiming.second == 0.0)
		{
			return t;
		}

		if (t <= m_loopTiming.second)
		{
			return t;
		}
		else
		{
			const double loopLength = (m_loopTiming.second - m_loopTiming.first);

			const double ext = (t - m_loopTiming.second);

			return (m_loopTiming.first + Math::Fmod(ext, loopLength));
		}
	}

	double SimpleAnimation::lengthSec() const noexcept
	{
		return m_animationDurationSec;
	}

	bool SimpleAnimation::isDone() const
	{
		if (m_loopTiming.second != 0.0)
		{
			return false;
		}

		return (m_animationDurationSec <= m_stopwatch.sF());
	}

	size_t SimpleAnimation::loopCount() const
	{
		if (m_loopTiming.second == 0.0)
		{
			return 0;
		}

		const double t = m_stopwatch.sF();

		if (t <= m_loopTiming.second)
		{
			return 0;
		}
		else
		{
			const double loopLength = (m_loopTiming.second - m_loopTiming.first);

			const double ext = (t - m_loopTiming.second);

			return static_cast<size_t>(1 + (ext / loopLength));
		}
	}

	double SimpleAnimation::GetValue(const Array<Animation>& animations, const double timeSec)
	{
		if (timeSec < animations.front().a.time.count())
		{
			return animations.front().a.value;
		}

		if (animations.back().b.time.count() <= timeSec)
		{
			return animations.back().b.value;
		}

		for (size_t i = 0; i < animations.size(); ++i)
		{
			const auto& animation = animations[i];
			const double tA = animation.a.time.count();
			const double tB = animation.b.time.count();

			if (timeSec < tA)
			{
				return animations[i - 1].b.value;
			}

			if (InRange(timeSec, tA, tB))
			{
				const double duration = (tB - tA);
				const double f = ((timeSec - tA) / duration);
				return Math::Lerp(animation.a.value, animation.b.value, animation.func(f));
			}
		}

		return animations.back().b.value;
	}
}
<|endoftext|>


<commit_before>/* tcpstream.cpp
 *
 * cxxtools - general purpose C++-toolbox
 * Copyright (C) 2003 Tommi Maekitalo
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * As a special exception, you may use this file as part of a free
 * software library without restriction. Specifically, if other files
 * instantiate templates or use macros or inline functions from this
 * file, or you compile this file and link it with other files to
 * produce an executable, this file does not by itself cause the
 * resulting executable to be covered by the GNU General Public
 * License. This exception does not however invalidate any other
 * reasons why the executable file might be covered by the GNU Library
 * General Public License.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

#include "cxxtools/tcpstream.h"
#include <sys/poll.h>
#include <sys/socket.h>
#include <unistd.h>
#include <netdb.h>
#include <errno.h>
#include <string.h>
#include "cxxtools/log.h"

log_define("cxxtools.net.tcp")

namespace cxxtools
{

namespace net
{
  ////////////////////////////////////////////////////////////////////////
  // implementation of Server
  //
  Server::Server(const std::string& ipaddr, unsigned short int port,
      int backlog) throw (Exception)
  {
    listen(ipaddr, port, backlog);
  }

  void Server::listen(const std::string& ipaddr, unsigned short int port,
      int backlog) throw (Exception)
  {
    log_debug("listen on " << ipaddr << " port " << port << " backlog " << backlog);

    Addrinfo ai(ipaddr, port);

    int reuseAddr = 1;

    // getaddrinfo() may return more than one addrinfo structure, so work
    // them all out, until we find a pretty useable one
    for (Addrinfo::const_iterator it = ai.begin(); it != ai.end(); ++it)
    {
      try
      {
        Socket::create(it->ai_family, SOCK_STREAM, 0);
      }
      catch (const Exception&)
      {
        continue;
      }

      log_debug("setsockopt SO_REUSEADDR");
      if (::setsockopt(getFd(), SOL_SOCKET, SO_REUSEADDR,
          &reuseAddr, sizeof(reuseAddr)) < 0)
        throw Exception("setsockopt");

      log_debug("bind");
      if (::bind(getFd(), it->ai_addr, it->ai_addrlen) == 0)
      {
        // save our information
        memmove(&servaddr, it->ai_addr, it->ai_addrlen);

        log_debug("listen");
        if (::listen(getFd(), backlog) < 0)
          throw Exception("listen");

        return;
      }
    }

    throw Exception("bind");
  }

  ////////////////////////////////////////////////////////////////////////
  // implementation of Stream
  //
  Stream::Stream()
    { }

  Stream::Stream(const Server& server)
  {
    accept(server);
  }

  Stream::Stream(const std::string& ipaddr, unsigned short int port)
  {
    connect(ipaddr, port);
  }

  void Stream::accept(const Server& server)
  {
    close();

    socklen_t peeraddr_len;
    peeraddr_len = sizeof(peeraddr);
    log_debug("accept " << server.getFd());
    int fd = ::accept(server.getFd(), reinterpret_cast <struct sockaddr *> (&peeraddr), &peeraddr_len);
    if (fd < 0)
      throw Exception("accept");
    setFd(fd);
    log_debug("accepted " << server.getFd() << " => " << getFd());
  }

  void Stream::connect(const std::string& ipaddr, unsigned short int port)
  {
    log_debug("connect to " << ipaddr << " port " << port);

    Addrinfo ai(ipaddr, port);

    log_debug("do connect");
    for (Addrinfo::const_iterator it = ai.begin(); it != ai.end(); ++it)
    {
      try
      {
        Socket::create(it->ai_family, SOCK_STREAM, 0);
      }
      catch (const Exception&)
      {
        continue;
      }

      if (::connect(getFd(), it->ai_addr, it->ai_addrlen) == 0)
      {
        // save our information
        memmove(&peeraddr, it->ai_addr, it->ai_addrlen);
        return;
      }

      if (errno == EINPROGRESS && getTimeout() > 0)
      {
        poll(POLLOUT);

        int sockerr;
        socklen_t optlen = sizeof(sockerr);
        if (::getsockopt(getFd(), SOL_SOCKET, SO_ERROR, &sockerr, &optlen) != 0)
        {
          ::close(getFd());
          throw Exception("getsockopt");
        }

        if (sockerr != 0)
          throw Exception(sockerr, "connect");

        // save our information
        memmove(&peeraddr, it->ai_addr, it->ai_addrlen);
        return;
      }

    }

    throw Exception("connect");
  }

  Stream::size_type Stream::read(char* buffer, Stream::size_type bufsize) const
  {
    ssize_t n;

    if (getTimeout() < 0)
    {
      // blocking read
      do
      {
        log_debug("blocking read");
        n = ::read(getFd(), buffer, bufsize);
        log_debug("blocking read ready, return " << n);
      } while (n < 0 && errno == EINTR);

      if (n < 0 && errno != ECONNRESET)
        throw Exception(errno, "read");
    }
    else
    {
      // non-blocking read

      // try reading without timeout
      do
      {
        log_debug("non blocking read fd=" << getFd());
        n = ::read(getFd(), buffer, bufsize);
        log_debug("non blocking read returns " << n);
      } while (n < 0 && errno == EINTR);

      if (n < 0)
      {
        // no data available

        if (errno == EAGAIN)
        {
          if (getTimeout() == 0)
          {
            log_debug("read timeout (" << getTimeout() << "ms)");
            throw Timeout();
          }

          if (poll(POLLIN) & POLLHUP)
          {
            log_debug("eof in read");
            return 0;
          }

          do
          {
            log_debug("read");
            n = ::read(getFd(), buffer, bufsize);
            log_debug("read returns " << n);
          } while (n < 0 && errno == EINTR);

          if (n < 0)
            throw Exception("read");
        }
        else if (errno != 0 && errno != ECONNRESET)
          throw Exception("read");
      }

    }

    return n < 0 ? 0 : n;
  }

  Stream::size_type Stream::write(const char* buffer,
                                  Stream::size_type bufsize, bool flush) const
  {
    log_debug("Stream::write " << bufsize << " bytes");

    ssize_t n = 0;
    size_type s = bufsize;  // number of bytes left

    while (true)
    {
      do
      {
        n = ::write(getFd(), buffer, s);
        log_debug("::write returns " << n << " errno=" << errno);
      } while (n < 0 && errno == EINTR);

      if (n < 0)
      {
        if (errno == EAGAIN)
          n = 0;
        else
        {
          log_error("error in write; errno=" << errno << " (" << strerror(errno) << ')');
          throw Exception("write");
        }
      }

      buffer += n;
      s -= n;

      if (s > 0 && n > 0 && !flush)
      {
        log_debug("partial write; " << n << " bytes written from " << bufsize << "; return " << (bufsize - s));
        return bufsize - s;
      }

      if (s <= 0)
        break;

      if (getTimeout() <= 0)
      {
        log_debug("write timeout (" << getTimeout() << "ms)");
        throw Timeout();
      }

      if (poll(POLLOUT) & POLLHUP)
      {
        log_debug("eof in write");
        return bufsize - s;
      }
    }

    log_debug("full write - return " << bufsize);
    return bufsize;
  }

  streambuf::streambuf(Stream& stream, unsigned bufsize, int timeout)
    : m_stream(stream),
      m_bufsize(bufsize),
      m_buffer(new char_type[bufsize])
  {
    setTimeout(timeout);
  }

  streambuf::int_type streambuf::overflow(streambuf::int_type c)
  {
    log_debug("streambuf::overflow");

    if (pptr())
    {
      Stream::size_type N = pptr() - m_buffer; // bytes to write
      Stream::size_type n = m_stream.write(m_buffer, N, false);
      if (n <= 0)
        return traits_type::eof();

      if (n < N)
      {
        // there are bytes left - move them to the start of our buffer
        memmove(m_buffer, m_buffer + n, N - n);
        setp(m_buffer + N - n, m_buffer + m_bufsize);
      }
      else
        setp(m_buffer, m_buffer + m_bufsize);
    }
    else
      setp(m_buffer, m_buffer + m_bufsize);

    if (c != traits_type::eof())
    {
      *pptr() = traits_type::to_char_type(c);
      pbump(1);
    }

    return 0;
  }

  streambuf::int_type streambuf::underflow()
  {
    log_debug("streambuf::underflow");

    Stream::size_type n = m_stream.read(m_buffer, m_bufsize);
    if (n <= 0)
      return traits_type::eof();

    setg(m_buffer, m_buffer, m_buffer + n);
    return traits_type::to_int_type(m_buffer[0]);
  }

  int streambuf::sync()
  {
    log_debug("streambuf::sync");

    if (pptr())
    {
      Stream::size_type N = pptr() - m_buffer; // bytes to write
      if (N > 0)
      {
        Stream::size_type n = m_stream.write(m_buffer, N);
        if (n <= 0)
          return -1;
        else
          setp(m_buffer, m_buffer + m_bufsize);
      }
    }
    return 0;
  }

} // namespace net

} // namespace cxxtools
<commit_msg>use separate input and output buffers in tcpstream<commit_after>/* tcpstream.cpp
 *
 * cxxtools - general purpose C++-toolbox
 * Copyright (C) 2003 Tommi Maekitalo
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * As a special exception, you may use this file as part of a free
 * software library without restriction. Specifically, if other files
 * instantiate templates or use macros or inline functions from this
 * file, or you compile this file and link it with other files to
 * produce an executable, this file does not by itself cause the
 * resulting executable to be covered by the GNU General Public
 * License. This exception does not however invalidate any other
 * reasons why the executable file might be covered by the GNU Library
 * General Public License.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

#include "cxxtools/tcpstream.h"
#include <sys/poll.h>
#include <sys/socket.h>
#include <unistd.h>
#include <netdb.h>
#include <errno.h>
#include <string.h>
#include "cxxtools/log.h"

log_define("cxxtools.net.tcp")

namespace cxxtools
{

namespace net
{
  ////////////////////////////////////////////////////////////////////////
  // implementation of Server
  //
  Server::Server(const std::string& ipaddr, unsigned short int port,
      int backlog) throw (Exception)
  {
    listen(ipaddr, port, backlog);
  }

  void Server::listen(const std::string& ipaddr, unsigned short int port,
      int backlog) throw (Exception)
  {
    log_debug("listen on " << ipaddr << " port " << port << " backlog " << backlog);

    Addrinfo ai(ipaddr, port);

    int reuseAddr = 1;

    // getaddrinfo() may return more than one addrinfo structure, so work
    // them all out, until we find a pretty useable one
    for (Addrinfo::const_iterator it = ai.begin(); it != ai.end(); ++it)
    {
      try
      {
        Socket::create(it->ai_family, SOCK_STREAM, 0);
      }
      catch (const Exception&)
      {
        continue;
      }

      log_debug("setsockopt SO_REUSEADDR");
      if (::setsockopt(getFd(), SOL_SOCKET, SO_REUSEADDR,
          &reuseAddr, sizeof(reuseAddr)) < 0)
        throw Exception("setsockopt");

      log_debug("bind");
      if (::bind(getFd(), it->ai_addr, it->ai_addrlen) == 0)
      {
        // save our information
        memmove(&servaddr, it->ai_addr, it->ai_addrlen);

        log_debug("listen");
        if (::listen(getFd(), backlog) < 0)
          throw Exception("listen");

        return;
      }
    }

    throw Exception("bind");
  }

  ////////////////////////////////////////////////////////////////////////
  // implementation of Stream
  //
  Stream::Stream()
    { }

  Stream::Stream(const Server& server)
  {
    accept(server);
  }

  Stream::Stream(const std::string& ipaddr, unsigned short int port)
  {
    connect(ipaddr, port);
  }

  void Stream::accept(const Server& server)
  {
    close();

    socklen_t peeraddr_len;
    peeraddr_len = sizeof(peeraddr);
    log_debug("accept " << server.getFd());
    int fd = ::accept(server.getFd(), reinterpret_cast <struct sockaddr *> (&peeraddr), &peeraddr_len);
    if (fd < 0)
      throw Exception("accept");
    setFd(fd);
    log_debug("accepted " << server.getFd() << " => " << getFd());
  }

  void Stream::connect(const std::string& ipaddr, unsigned short int port)
  {
    log_debug("connect to " << ipaddr << " port " << port);

    Addrinfo ai(ipaddr, port);

    log_debug("do connect");
    for (Addrinfo::const_iterator it = ai.begin(); it != ai.end(); ++it)
    {
      try
      {
        Socket::create(it->ai_family, SOCK_STREAM, 0);
      }
      catch (const Exception&)
      {
        continue;
      }

      if (::connect(getFd(), it->ai_addr, it->ai_addrlen) == 0)
      {
        // save our information
        memmove(&peeraddr, it->ai_addr, it->ai_addrlen);
        return;
      }

      if (errno == EINPROGRESS && getTimeout() > 0)
      {
        poll(POLLOUT);

        int sockerr;
        socklen_t optlen = sizeof(sockerr);
        if (::getsockopt(getFd(), SOL_SOCKET, SO_ERROR, &sockerr, &optlen) != 0)
        {
          ::close(getFd());
          throw Exception("getsockopt");
        }

        if (sockerr != 0)
          throw Exception(sockerr, "connect");

        // save our information
        memmove(&peeraddr, it->ai_addr, it->ai_addrlen);
        return;
      }

    }

    throw Exception("connect");
  }

  Stream::size_type Stream::read(char* buffer, Stream::size_type bufsize) const
  {
    ssize_t n;

    if (getTimeout() < 0)
    {
      // blocking read
      do
      {
        log_debug("blocking read");
        n = ::read(getFd(), buffer, bufsize);
        log_debug("blocking read ready, return " << n);
      } while (n < 0 && errno == EINTR);

      if (n < 0 && errno != ECONNRESET)
        throw Exception(errno, "read");
    }
    else
    {
      // non-blocking read

      // try reading without timeout
      do
      {
        log_debug("non blocking read fd=" << getFd());
        n = ::read(getFd(), buffer, bufsize);
        log_debug("non blocking read returns " << n);
      } while (n < 0 && errno == EINTR);

      if (n < 0)
      {
        // no data available

        if (errno == EAGAIN)
        {
          if (getTimeout() == 0)
          {
            log_debug("read timeout (" << getTimeout() << "ms)");
            throw Timeout();
          }

          if (poll(POLLIN) & POLLHUP)
          {
            log_debug("eof in read");
            return 0;
          }

          do
          {
            log_debug("read");
            n = ::read(getFd(), buffer, bufsize);
            log_debug("read returns " << n);
          } while (n < 0 && errno == EINTR);

          if (n < 0)
            throw Exception("read");
        }
        else if (errno != 0 && errno != ECONNRESET)
          throw Exception("read");
      }

    }

    return n < 0 ? 0 : n;
  }

  Stream::size_type Stream::write(const char* buffer,
                                  Stream::size_type bufsize, bool flush) const
  {
    log_debug("Stream::write " << bufsize << " bytes");

    ssize_t n = 0;
    size_type s = bufsize;  // number of bytes left

    while (true)
    {
      do
      {
        n = ::write(getFd(), buffer, s);
        log_debug("::write returns " << n << " errno=" << errno);
      } while (n < 0 && errno == EINTR);

      if (n < 0)
      {
        if (errno == EAGAIN)
          n = 0;
        else
        {
          log_error("error in write; errno=" << errno << " (" << strerror(errno) << ')');
          throw Exception("write");
        }
      }

      buffer += n;
      s -= n;

      if (s > 0 && n > 0 && !flush)
      {
        log_debug("partial write; " << n << " bytes written from " << bufsize << "; return " << (bufsize - s));
        return bufsize - s;
      }

      if (s <= 0)
        break;

      if (getTimeout() <= 0)
      {
        log_debug("write timeout (" << getTimeout() << "ms)");
        throw Timeout();
      }

      if (poll(POLLOUT) & POLLHUP)
      {
        log_debug("eof in write");
        return bufsize - s;
      }
    }

    log_debug("full write - return " << bufsize);
    return bufsize;
  }

  streambuf::streambuf(Stream& stream, unsigned bufsize, int timeout)
    : m_stream(stream),
      m_bufsize(bufsize),
      m_buffer(new char_type[bufsize * 2])
  {
    setTimeout(timeout);
  }

  streambuf::int_type streambuf::overflow(streambuf::int_type c)
  {
    log_debug("streambuf::overflow");

    if (pptr())
    {
      Stream::size_type N = pptr() - m_buffer; // bytes to write
      Stream::size_type n = m_stream.write(m_buffer, N, false);
      if (n <= 0)
        return traits_type::eof();

      if (n < N)
      {
        // there are bytes left - move them to the start of our buffer
        memmove(m_buffer, m_buffer + n, N - n);
        setp(m_buffer + N - n, m_buffer + m_bufsize);
      }
      else
        setp(m_buffer, m_buffer + m_bufsize);
    }
    else
      setp(m_buffer, m_buffer + m_bufsize);

    if (c != traits_type::eof())
    {
      *pptr() = traits_type::to_char_type(c);
      pbump(1);
    }

    return 0;
  }

  streambuf::int_type streambuf::underflow()
  {
    log_debug("streambuf::underflow");

    Stream::size_type n = m_stream.read(m_buffer + m_bufsize, m_bufsize);
    if (n <= 0)
      return traits_type::eof();

    setg(m_buffer + m_bufsize, m_buffer + m_bufsize, m_buffer + m_bufsize + n);
    return traits_type::to_int_type(m_buffer[m_bufsize]);
  }

  int streambuf::sync()
  {
    log_debug("streambuf::sync");

    if (pptr())
    {
      Stream::size_type N = pptr() - m_buffer; // bytes to write
      if (N > 0)
      {
        Stream::size_type n = m_stream.write(m_buffer, N);
        if (n <= 0)
          return -1;
        else
          setp(m_buffer, m_buffer + m_bufsize);
      }
    }
    return 0;
  }

} // namespace net

} // namespace cxxtools
<|endoftext|>


<commit_before>//==============================================================================
// Main source file
//==============================================================================

#include "common.h"

//==============================================================================

#include <iostream>

//==============================================================================

#include <QCoreApplication>
#include <QDir>
#include <QFileInfo>
#include <QPointer>
#include <QProcess>

//==============================================================================

using namespace OpenCOR;

//==============================================================================

int main(int pArgc, char *pArgv[])
{
    // Create the application

    QCoreApplication *app = new QCoreApplication(pArgc, pArgv);

    // Some general initialisations

    initApplication(app);

    // Try to run OpenCOR as a console application

    int res;

    if (!consoleApplication(app, &res)) {
        // OpenCOR wasn't run as a proper console application, so start its GUI
        // version instead

        static const QString dotExe = ".exe";

        if (app->applicationFilePath().right(dotExe.size()) == dotExe) {
            // This is a safeguard from accidentally running a non-renamed (to
            // '.com') console version of OpenCOR

            error(app, "the console version of "+app->applicationName()+" has the wrong extension ('.exe' instead of '.com').");

            res = -1;
        } else {
            QString guiAppFilePath = app->applicationDirPath()+QDir::separator()+app->applicationName()+dotExe;

            if (!QFileInfo(guiAppFilePath).exists()) {
                // We can't find the GUI version of OpenCOR, so...

                error(app, "the GUI version of "+app->applicationName()+" cannot be found.");

                res = -1;
            } else {
                QProcess().startDetached(guiAppFilePath, app->arguments(), QProcess().workingDirectory());

                res = 0;
            }
        }
    }

    // Release some memory

    delete app;

    // We are done, so...

    return res;
}

//==============================================================================
// End of file
//==============================================================================
<commit_msg>Some minor cleaning up (#57).<commit_after>//==============================================================================
// Main source file
//==============================================================================

#include "common.h"

//==============================================================================

#include <iostream>

//==============================================================================

#include <QCoreApplication>
#include <QDir>
#include <QFileInfo>
#include <QPointer>
#include <QProcess>

//==============================================================================

int main(int pArgc, char *pArgv[])
{
    // Create the application

    QCoreApplication *app = new QCoreApplication(pArgc, pArgv);

    // Some general initialisations

    OpenCOR::initApplication(app);

    // Try to run OpenCOR as a console application

    int res;

    if (!OpenCOR::consoleApplication(app, &res)) {
        // OpenCOR wasn't run as a proper console application, so start its GUI
        // version instead

        static const QString dotExe = ".exe";

        if (app->applicationFilePath().right(dotExe.size()) == dotExe) {
            // This is a safeguard from accidentally running a non-renamed (to
            // '.com') console version of OpenCOR

            OpenCOR::error(app, "the console version of "+app->applicationName()+" has the wrong extension ('.exe' instead of '.com').");

            res = -1;
        } else {
            QString guiAppFilePath = app->applicationDirPath()+QDir::separator()+app->applicationName()+dotExe;

            if (!QFileInfo(guiAppFilePath).exists()) {
                // We can't find the GUI version of OpenCOR, so...

                OpenCOR::error(app, "the GUI version of "+app->applicationName()+" cannot be found.");

                res = -1;
            } else {
                QProcess().startDetached(guiAppFilePath, app->arguments(), QProcess().workingDirectory());

                res = 0;
            }
        }
    }

    // Release some memory

    delete app;

    // We are done, so...

    return res;
}

//==============================================================================
// End of file
//==============================================================================
<|endoftext|>


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

#include "config.h"
#include "core/dom/DOMArrayBufferDeallocationObserver.h"

#include "wtf/StdLibExtras.h"
#include <v8.h>

namespace blink {

DOMArrayBufferDeallocationObserver* DOMArrayBufferDeallocationObserver::instance()
{
    DEFINE_STATIC_LOCAL(DOMArrayBufferDeallocationObserver, deallocationObserver, ());
    return &deallocationObserver;
}

void DOMArrayBufferDeallocationObserver::arrayBufferDeallocated(unsigned sizeInBytes)
{
    v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(-static_cast<int>(sizeInBytes));
}

void DOMArrayBufferDeallocationObserver::blinkAllocatedMemory(unsigned sizeInBytes)
{
    v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(static_cast<int>(sizeInBytes));
}

} // namespace blink
<commit_msg>bindings: Makes DOMArrayBufferDeallocationObserver::instance thread-safe.<commit_after>// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "config.h"
#include "core/dom/DOMArrayBufferDeallocationObserver.h"

#include "wtf/Threading.h"
#include <v8.h>

namespace blink {

DOMArrayBufferDeallocationObserver* DOMArrayBufferDeallocationObserver::instance()
{
    AtomicallyInitializedStatic(
        DOMArrayBufferDeallocationObserver*,
        deallocationObserver = new DOMArrayBufferDeallocationObserver);
    return deallocationObserver;
}

void DOMArrayBufferDeallocationObserver::arrayBufferDeallocated(unsigned sizeInBytes)
{
    v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(-static_cast<int>(sizeInBytes));
}

void DOMArrayBufferDeallocationObserver::blinkAllocatedMemory(unsigned sizeInBytes)
{
    v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(static_cast<int>(sizeInBytes));
}

} // namespace blink
<|endoftext|>


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

Program:   Insight Segmentation & Registration Toolkit
Module:    itkListSampleTest.cxx
Language:  C++
Date:      $Date$
Version:   $Revision$

Copyright (c) Insight Software Consortium. All rights reserved.
See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif
#include "itkArray.h"
#include "itkListSample.h"

int itkListSampleTest(int argc, char *argv[] )
{
  std::cout << "ListSample Test \n \n";
  if( argc< 2 )
    {
    std::cerr << "itkListSampleTest LengthOfMeasurementVector" << std::endl;
    }

  typedef itk::Array< float > MeasurementVectorType ;
  typedef itk::Statistics::ListSample< MeasurementVectorType > SampleType ;

  SampleType::MeasurementVectorSizeType measurementVectorSize = atoi(argv[1]);
  std::cerr << "Measurement vector size: " << measurementVectorSize
            << std::endl;

  unsigned int sampleSize = 25;

  SampleType::Pointer sample = SampleType::New() ;

  sample->SetMeasurementVectorSize( measurementVectorSize );

  MeasurementVectorType mv( measurementVectorSize ) ;
  for ( unsigned int i = 0 ; i < sampleSize ; i++ )
    {
    for (unsigned int j = 0 ; j < measurementVectorSize ; j++ )
      {
      mv[j] = rand() / (RAND_MAX+1.0)  ;
      }
    sample->PushBack(mv) ;
    }

  // tests begin

  //
  // general interface
  //
  std::cerr << "General interface..." << std::endl;
  if ( sampleSize != sample->Size() )
    {
    std::cerr << "Size() failed" << std::endl;
    return EXIT_FAILURE;
    }

  if (sample->GetMeasurementVectorSize() != measurementVectorSize)
    {
    std::cerr << "GetMeasurementVectorSize() failed" << std::endl;
    return EXIT_FAILURE;
    }

  // get and set measurements
  mv = sample->GetMeasurementVector(4) ;
  if ( mv != sample->GetMeasurementVector(4) )
    {
    std::cerr << "GetMeasurementVector failed" << std::endl;
    return EXIT_FAILURE;
    }

  float tmp = mv[0];
  mv[0] += 1.0;
  sample->SetMeasurementVector(4,mv);
  if (mv != sample->GetMeasurementVector(4))
    {
    std::cerr << "SetMeasurementVector failed" << std::endl;
    return EXIT_FAILURE;
    }

  mv[0] = tmp;
  sample->SetMeasurement(4,0,tmp);
  if (mv != sample->GetMeasurementVector(4))
    {
    std::cerr << "SetMeasurement failed" << std::endl;
    return EXIT_FAILURE;
    }

  // frequency
  if (sample->GetTotalFrequency() != sampleSize)
  {
    std::cerr << "GetTotalFrequency failed" << std::endl;
    return EXIT_FAILURE;
  }

  //
  // iterator tests
  //
  std::cerr << "Iterators..." << std::endl;
    {
    // forward iterator
    SampleType::Iterator s_iter = sample->Begin() ;

    // copy constructor
    SampleType::Iterator bs_iter(s_iter);
    if (bs_iter != s_iter)
      {
      std::cerr << "Iterator::Copy Constructor failed" << std::endl;
      return EXIT_FAILURE;
      }

    SampleType::InstanceIdentifier id = 0 ;
    while (s_iter != sample->End())
      {
      if (sample->GetMeasurementVector(id) !=
          s_iter.GetMeasurementVector())
        {
        std::cerr << "Iterator::GetMeasurementVector (forward) failed"
                  << std::endl;
        return EXIT_FAILURE;
        }
      if (id != s_iter.GetInstanceIdentifier())
        {
        std::cerr << "Iterator::GetInstanceIdentifier (forward) failed"
                  << std::endl;
        return EXIT_FAILURE;
        }
      if (s_iter.GetFrequency() != 1)
        {
        std::cerr << "Iterator::GetFrequency (forward) failed" << std::endl;
        return EXIT_FAILURE;
        }
      if (sample->GetFrequency(id) != 1)
        {
        std::cerr << "GetFrequency (forward) failed" << std::endl;
        return EXIT_FAILURE;
        }
      ++id ;
      ++s_iter ;
      }

    if (s_iter != sample->End())
      {
      std::cerr << "Iterator::End (forward) failed" << std::endl;
      return EXIT_FAILURE;
      }

    // backwards iterator
    do
      {
      --s_iter;
      --id;
      if (sample->GetMeasurementVector(id) !=
          s_iter.GetMeasurementVector())
        {
        std::cerr << "Iterator::GetMeasurementVector (backward) failed"
                  << std::endl;
        return EXIT_FAILURE;
        }
      if (id != s_iter.GetInstanceIdentifier())
        {
        std::cerr << "Iterator::GetInstanceIdentifier (backward) failed"
                  << std::endl;
        return EXIT_FAILURE;
        }
      } while (!(s_iter == sample->Begin())); // explicitly test ==

    if (!(s_iter == sample->Begin()))
      {
      std::cerr << "Iterator::Begin (backward) failed" << std::endl;
      return EXIT_FAILURE;
      }
    }

  // ConstIterator test
    std::cerr << "Const Iterators..." << std::endl;
    {
    // forward iterator
    SampleType::ConstIterator s_iter = sample->Begin() ;

    // copy constructor
    SampleType::ConstIterator bs_iter(s_iter);
    if (bs_iter != s_iter)
      {
      std::cerr << "Iterator::Copy Constructor (from const) failed"
                << std::endl;
      return EXIT_FAILURE;
      }

    // copy from non-const iterator
    SampleType::Iterator nonconst_iter = sample->Begin();
    SampleType::ConstIterator s2_iter(nonconst_iter);
    if (s2_iter != s_iter)
      {
      std::cerr << "Iterator::Copy Constructor (from non-const) failed"
                << std::endl;
      return EXIT_FAILURE;
      }
    // assignment from non-const iterator
    s2_iter = nonconst_iter;
    if (s2_iter != s_iter)
      {
      std::cerr << "Iterator::assignment (from non-const) failed" << std::endl;
      return EXIT_FAILURE;
      }

    SampleType::InstanceIdentifier id = 0 ;
    while (s_iter != sample->End())
      {
      if (sample->GetMeasurementVector(id) !=
          s_iter.GetMeasurementVector())
        {
        std::cerr << "Iterator::GetMeasurementVector (forward) failed"
                  << std::endl;
        return EXIT_FAILURE;
        }
      if (id != s_iter.GetInstanceIdentifier())
        {
        std::cerr << "Iterator::GetInstanceIdentifier (forward) failed"
                  << std::endl;
        return EXIT_FAILURE;
        }
      if (s_iter.GetFrequency() != 1)
        {
        std::cerr << "Iterator::GetFrequency (forward) failed" << std::endl;
        return EXIT_FAILURE;
        }
      ++id ;
      ++s_iter ;
      }

    if (s_iter != sample->End())
      {
      std::cerr << "Iterator::End (forward) failed" << std::endl;
      return EXIT_FAILURE;
      }

    // backwards iterator
    do
      {
      --s_iter;
      --id;
      if (sample->GetMeasurementVector(id) !=
          s_iter.GetMeasurementVector())
        {
        std::cerr << "Iterator::GetMeasurementVector (backward) failed"
                  << std::endl;
        return EXIT_FAILURE;
        }
      if (id != s_iter.GetInstanceIdentifier())
        {
        std::cerr << "Iterator::GetInstanceIdentifier (backward) failed"
                  << std::endl;
        return EXIT_FAILURE;
        }
      } while (!(s_iter == sample->Begin())); // explicitly test ==

    if (!(s_iter == sample->Begin()))
      {
      std::cerr << "Iterator::Begin (backward) failed" << std::endl;
      return EXIT_FAILURE;
      }
    }

    std::cerr << "Search..." << std::endl;
    SampleType::SearchResultVectorType searchResult ;
    sample->Search(sample->GetMeasurementVector(sampleSize/2), 0.01,
                   searchResult) ;

    //
    // resizing
    //
    sample->Clear();
    if (sample->Size() != 0)
      {
      std::cerr << "Clear() failed" << std::endl;
      return EXIT_FAILURE;
      }

    sample->Resize(sampleSize);
    if (sample->Size() != sampleSize)
      {
      std::cerr << "Resize() failed" << std::endl;
      return EXIT_FAILURE;
      }
}

<commit_msg>BUG: added back return of EXIT_SUCCESS---it was accidentally removed<commit_after>/*=========================================================================

Program:   Insight Segmentation & Registration Toolkit
Module:    itkListSampleTest.cxx
Language:  C++
Date:      $Date$
Version:   $Revision$

Copyright (c) Insight Software Consortium. All rights reserved.
See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif
#include "itkArray.h"
#include "itkListSample.h"

int itkListSampleTest(int argc, char *argv[] )
{
  std::cout << "ListSample Test \n \n";
  if( argc< 2 )
    {
    std::cerr << "itkListSampleTest LengthOfMeasurementVector" << std::endl;
    }

  typedef itk::Array< float > MeasurementVectorType ;
  typedef itk::Statistics::ListSample< MeasurementVectorType > SampleType ;

  SampleType::MeasurementVectorSizeType measurementVectorSize = atoi(argv[1]);
  std::cerr << "Measurement vector size: " << measurementVectorSize
            << std::endl;

  unsigned int sampleSize = 25;

  SampleType::Pointer sample = SampleType::New() ;

  sample->SetMeasurementVectorSize( measurementVectorSize );

  MeasurementVectorType mv( measurementVectorSize ) ;
  for ( unsigned int i = 0 ; i < sampleSize ; i++ )
    {
    for (unsigned int j = 0 ; j < measurementVectorSize ; j++ )
      {
      mv[j] = rand() / (RAND_MAX+1.0)  ;
      }
    sample->PushBack(mv) ;
    }

  // tests begin

  //
  // general interface
  //
  std::cerr << "General interface..." << std::endl;
  if ( sampleSize != sample->Size() )
    {
    std::cerr << "Size() failed" << std::endl;
    return EXIT_FAILURE;
    }

  if (sample->GetMeasurementVectorSize() != measurementVectorSize)
    {
    std::cerr << "GetMeasurementVectorSize() failed" << std::endl;
    return EXIT_FAILURE;
    }

  // get and set measurements
  mv = sample->GetMeasurementVector(4) ;
  if ( mv != sample->GetMeasurementVector(4) )
    {
    std::cerr << "GetMeasurementVector failed" << std::endl;
    return EXIT_FAILURE;
    }

  float tmp = mv[0];
  mv[0] += 1.0;
  sample->SetMeasurementVector(4,mv);
  if (mv != sample->GetMeasurementVector(4))
    {
    std::cerr << "SetMeasurementVector failed" << std::endl;
    return EXIT_FAILURE;
    }

  mv[0] = tmp;
  sample->SetMeasurement(4,0,tmp);
  if (mv != sample->GetMeasurementVector(4))
    {
    std::cerr << "SetMeasurement failed" << std::endl;
    return EXIT_FAILURE;
    }

  // frequency
  if (sample->GetTotalFrequency() != sampleSize)
  {
    std::cerr << "GetTotalFrequency failed" << std::endl;
    return EXIT_FAILURE;
  }

  //
  // iterator tests
  //
  std::cerr << "Iterators..." << std::endl;
    {
    // forward iterator
    SampleType::Iterator s_iter = sample->Begin() ;

    // copy constructor
    SampleType::Iterator bs_iter(s_iter);
    if (bs_iter != s_iter)
      {
      std::cerr << "Iterator::Copy Constructor failed" << std::endl;
      return EXIT_FAILURE;
      }

    SampleType::InstanceIdentifier id = 0 ;
    while (s_iter != sample->End())
      {
      if (sample->GetMeasurementVector(id) !=
          s_iter.GetMeasurementVector())
        {
        std::cerr << "Iterator::GetMeasurementVector (forward) failed"
                  << std::endl;
        return EXIT_FAILURE;
        }
      if (id != s_iter.GetInstanceIdentifier())
        {
        std::cerr << "Iterator::GetInstanceIdentifier (forward) failed"
                  << std::endl;
        return EXIT_FAILURE;
        }
      if (s_iter.GetFrequency() != 1)
        {
        std::cerr << "Iterator::GetFrequency (forward) failed" << std::endl;
        return EXIT_FAILURE;
        }
      if (sample->GetFrequency(id) != 1)
        {
        std::cerr << "GetFrequency (forward) failed" << std::endl;
        return EXIT_FAILURE;
        }
      ++id ;
      ++s_iter ;
      }

    if (s_iter != sample->End())
      {
      std::cerr << "Iterator::End (forward) failed" << std::endl;
      return EXIT_FAILURE;
      }

    // backwards iterator
    do
      {
      --s_iter;
      --id;
      if (sample->GetMeasurementVector(id) !=
          s_iter.GetMeasurementVector())
        {
        std::cerr << "Iterator::GetMeasurementVector (backward) failed"
                  << std::endl;
        return EXIT_FAILURE;
        }
      if (id != s_iter.GetInstanceIdentifier())
        {
        std::cerr << "Iterator::GetInstanceIdentifier (backward) failed"
                  << std::endl;
        return EXIT_FAILURE;
        }
      } while (!(s_iter == sample->Begin())); // explicitly test ==

    if (!(s_iter == sample->Begin()))
      {
      std::cerr << "Iterator::Begin (backward) failed" << std::endl;
      return EXIT_FAILURE;
      }
    }

  // ConstIterator test
    std::cerr << "Const Iterators..." << std::endl;
    {
    // forward iterator
    SampleType::ConstIterator s_iter = sample->Begin() ;

    // copy constructor
    SampleType::ConstIterator bs_iter(s_iter);
    if (bs_iter != s_iter)
      {
      std::cerr << "Iterator::Copy Constructor (from const) failed"
                << std::endl;
      return EXIT_FAILURE;
      }

    // copy from non-const iterator
    SampleType::Iterator nonconst_iter = sample->Begin();
    SampleType::ConstIterator s2_iter(nonconst_iter);
    if (s2_iter != s_iter)
      {
      std::cerr << "Iterator::Copy Constructor (from non-const) failed"
                << std::endl;
      return EXIT_FAILURE;
      }
    // assignment from non-const iterator
    s2_iter = nonconst_iter;
    if (s2_iter != s_iter)
      {
      std::cerr << "Iterator::assignment (from non-const) failed" << std::endl;
      return EXIT_FAILURE;
      }

    SampleType::InstanceIdentifier id = 0 ;
    while (s_iter != sample->End())
      {
      if (sample->GetMeasurementVector(id) !=
          s_iter.GetMeasurementVector())
        {
        std::cerr << "Iterator::GetMeasurementVector (forward) failed"
                  << std::endl;
        return EXIT_FAILURE;
        }
      if (id != s_iter.GetInstanceIdentifier())
        {
        std::cerr << "Iterator::GetInstanceIdentifier (forward) failed"
                  << std::endl;
        return EXIT_FAILURE;
        }
      if (s_iter.GetFrequency() != 1)
        {
        std::cerr << "Iterator::GetFrequency (forward) failed" << std::endl;
        return EXIT_FAILURE;
        }
      ++id ;
      ++s_iter ;
      }

    if (s_iter != sample->End())
      {
      std::cerr << "Iterator::End (forward) failed" << std::endl;
      return EXIT_FAILURE;
      }

    // backwards iterator
    do
      {
      --s_iter;
      --id;
      if (sample->GetMeasurementVector(id) !=
          s_iter.GetMeasurementVector())
        {
        std::cerr << "Iterator::GetMeasurementVector (backward) failed"
                  << std::endl;
        return EXIT_FAILURE;
        }
      if (id != s_iter.GetInstanceIdentifier())
        {
        std::cerr << "Iterator::GetInstanceIdentifier (backward) failed"
                  << std::endl;
        return EXIT_FAILURE;
        }
      } while (!(s_iter == sample->Begin())); // explicitly test ==

    if (!(s_iter == sample->Begin()))
      {
      std::cerr << "Iterator::Begin (backward) failed" << std::endl;
      return EXIT_FAILURE;
      }
    }

    std::cerr << "Search..." << std::endl;
    SampleType::SearchResultVectorType searchResult ;
    sample->Search(sample->GetMeasurementVector(sampleSize/2), 0.01,
                   searchResult) ;

    //
    // resizing
    //
    sample->Clear();
    if (sample->Size() != 0)
      {
      std::cerr << "Clear() failed" << std::endl;
      return EXIT_FAILURE;
      }

    sample->Resize(sampleSize);
    if (sample->Size() != sampleSize)
      {
      std::cerr << "Resize() failed" << std::endl;
      return EXIT_FAILURE;
      }

    std::cout << "Test passed." << std::endl;
    return EXIT_SUCCESS;
}

<|endoftext|>