<commit_before>/*
 * Copyright (c) 2003-2005 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Nathan Binkert
 */

#include "base/flags.hh"
#include "base/stats/types.hh"

namespace Stats {

typedef uint16_t FlagsType;
typedef ::Flags<FlagsType> Flags;

/** Nothing extra to print. */
const FlagsType none =          0x0000;
/** This Stat is Initialized */
const FlagsType init =          0x0001;
/** Print this stat. */
const FlagsType print =         0x0002;
/** Print the total. */
const FlagsType total =         0x0010;
/** Print the percent of the total that this entry represents. */
const FlagsType pdf =           0x0020;
/** Print the cumulative percentage of total upto this entry. */
const FlagsType cdf =           0x0040;
/** Print the distribution. */
const FlagsType dist =          0x0080;
/** Don't print if this is zero. */
const FlagsType nozero =        0x0100;
/** Don't print if this is NAN */
const FlagsType nonan =         0x0200;
/** Used for SS compatability. */
const FlagsType __substat =     0x8000;

/** Mask of flags that can't be set directly */
const FlagsType __reserved =    init | print | __substat;

struct StorageParams
{
    virtual ~StorageParams();
};

struct Visit;

class Info
{
  public:
    /** The name of the stat. */
    std::string name;
    /** The description of the stat. */
    std::string desc;
    /** The formatting flags. */
    Flags flags;
    /** The display precision. */
    int precision;
    /** A pointer to a prerequisite Stat. */
    const Info *prereq;
    /**
     * A unique stat ID for each stat in the simulator.
     * Can be used externally for lookups as well as for debugging.
     */
    static int id_count;
    int id;

  public:
    const StorageParams *storageParams;

  public:
    Info();
    virtual ~Info();

    /** Set the name of this statistic */
    void setName(const std::string &name);

    /**
     * Check that this stat has been set up properly and is ready for
     * use
     * @return true for success
     */
    virtual bool check() const = 0;
    bool baseCheck() const;

    /**
     * Enable the stat for use
     */
    virtual void enable();

    /**
     * Prepare the stat for dumping.
     */
    virtual void prepare() = 0;

    /**
     * Reset the stat to the default state.
     */
    virtual void reset() = 0;

    /**
     * @return true if this stat has a value and satisfies its
     * requirement as a prereq
     */
    virtual bool zero() const = 0;

    /**
     * Visitor entry for outputing statistics data
     */
    virtual void visit(Visit &visitor) = 0;

    /**
     * Checks if the first stat's name is alphabetically less than the second.
     * This function breaks names up at periods and considers each subname
     * separately.
     * @param stat1 The first stat.
     * @param stat2 The second stat.
     * @return stat1's name is alphabetically before stat2's
     */
    static bool less(Info *stat1, Info *stat2);
};

class ScalarInfo : public Info
{
  public:
    virtual Counter value() const = 0;
    virtual Result result() const = 0;
    virtual Result total() const = 0;
};

class VectorInfo : public Info
{
  public:
    /** Names and descriptions of subfields. */
    std::vector<std::string> subnames;
    std::vector<std::string> subdescs;

  public:
    void enable();

  public:
    virtual size_type size() const = 0;
    virtual const VCounter &value() const = 0;
    virtual const VResult &result() const = 0;
    virtual Result total() const = 0;
};

struct DistData
{
    Counter min_val;
    Counter max_val;
    Counter underflow;
    Counter overflow;
    VCounter cvec;
    Counter sum;
    Counter squares;
    Counter samples;
};

struct DistParams : public StorageParams
{
    const bool fancy;

    /** The minimum value to track. */
    Counter min;
    /** The maximum value to track. */
    Counter max;
    /** The number of entries in each bucket. */
    Counter bucket_size;
    /** The number of buckets. Equal to (max-min)/bucket_size. */
    size_type buckets;

    explicit DistParams(bool f) : fancy(f) {}
};

class DistInfo : public Info
{
  public:
    /** Local storage for the entry values, used for printing. */
    DistData data;
};

class VectorDistInfo : public Info
{
  public:
    std::vector<DistData> data;

    /** Names and descriptions of subfields. */
    std::vector<std::string> subnames;
    std::vector<std::string> subdescs;
    void enable();

  protected:
    /** Local storage for the entry values, used for printing. */
    mutable VResult rvec;

  public:
    virtual size_type size() const = 0;
};

class Vector2dInfo : public Info
{
  public:
    /** Names and descriptions of subfields. */
    std::vector<std::string> subnames;
    std::vector<std::string> subdescs;
    std::vector<std::string> y_subnames;

    size_type x;
    size_type y;

    /** Local storage for the entry values, used for printing. */
    mutable VCounter cvec;

    void enable();
};

class FormulaInfo : public VectorInfo
{
  public:
    virtual std::string str() const = 0;
};

/* namespace Stats */ }
<commit_msg>scons: add include guards to info.hh<commit_after>/*
 * Copyright (c) 2003-2005 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Nathan Binkert
 */

#ifndef __BASE_STATS_INFO_HH__
#define __BASE_STATS_INFO_HH__

#include "base/flags.hh"
#include "base/stats/types.hh"

namespace Stats {

typedef uint16_t FlagsType;
typedef ::Flags<FlagsType> Flags;

/** Nothing extra to print. */
const FlagsType none =          0x0000;
/** This Stat is Initialized */
const FlagsType init =          0x0001;
/** Print this stat. */
const FlagsType print =         0x0002;
/** Print the total. */
const FlagsType total =         0x0010;
/** Print the percent of the total that this entry represents. */
const FlagsType pdf =           0x0020;
/** Print the cumulative percentage of total upto this entry. */
const FlagsType cdf =           0x0040;
/** Print the distribution. */
const FlagsType dist =          0x0080;
/** Don't print if this is zero. */
const FlagsType nozero =        0x0100;
/** Don't print if this is NAN */
const FlagsType nonan =         0x0200;
/** Used for SS compatability. */
const FlagsType __substat =     0x8000;

/** Mask of flags that can't be set directly */
const FlagsType __reserved =    init | print | __substat;

struct StorageParams
{
    virtual ~StorageParams();
};

struct Visit;

class Info
{
  public:
    /** The name of the stat. */
    std::string name;
    /** The description of the stat. */
    std::string desc;
    /** The formatting flags. */
    Flags flags;
    /** The display precision. */
    int precision;
    /** A pointer to a prerequisite Stat. */
    const Info *prereq;
    /**
     * A unique stat ID for each stat in the simulator.
     * Can be used externally for lookups as well as for debugging.
     */
    static int id_count;
    int id;

  public:
    const StorageParams *storageParams;

  public:
    Info();
    virtual ~Info();

    /** Set the name of this statistic */
    void setName(const std::string &name);

    /**
     * Check that this stat has been set up properly and is ready for
     * use
     * @return true for success
     */
    virtual bool check() const = 0;
    bool baseCheck() const;

    /**
     * Enable the stat for use
     */
    virtual void enable();

    /**
     * Prepare the stat for dumping.
     */
    virtual void prepare() = 0;

    /**
     * Reset the stat to the default state.
     */
    virtual void reset() = 0;

    /**
     * @return true if this stat has a value and satisfies its
     * requirement as a prereq
     */
    virtual bool zero() const = 0;

    /**
     * Visitor entry for outputing statistics data
     */
    virtual void visit(Visit &visitor) = 0;

    /**
     * Checks if the first stat's name is alphabetically less than the second.
     * This function breaks names up at periods and considers each subname
     * separately.
     * @param stat1 The first stat.
     * @param stat2 The second stat.
     * @return stat1's name is alphabetically before stat2's
     */
    static bool less(Info *stat1, Info *stat2);
};

class ScalarInfo : public Info
{
  public:
    virtual Counter value() const = 0;
    virtual Result result() const = 0;
    virtual Result total() const = 0;
};

class VectorInfo : public Info
{
  public:
    /** Names and descriptions of subfields. */
    std::vector<std::string> subnames;
    std::vector<std::string> subdescs;

  public:
    void enable();

  public:
    virtual size_type size() const = 0;
    virtual const VCounter &value() const = 0;
    virtual const VResult &result() const = 0;
    virtual Result total() const = 0;
};

struct DistData
{
    Counter min_val;
    Counter max_val;
    Counter underflow;
    Counter overflow;
    VCounter cvec;
    Counter sum;
    Counter squares;
    Counter samples;
};

struct DistParams : public StorageParams
{
    const bool fancy;

    /** The minimum value to track. */
    Counter min;
    /** The maximum value to track. */
    Counter max;
    /** The number of entries in each bucket. */
    Counter bucket_size;
    /** The number of buckets. Equal to (max-min)/bucket_size. */
    size_type buckets;

    explicit DistParams(bool f) : fancy(f) {}
};

class DistInfo : public Info
{
  public:
    /** Local storage for the entry values, used for printing. */
    DistData data;
};

class VectorDistInfo : public Info
{
  public:
    std::vector<DistData> data;

    /** Names and descriptions of subfields. */
    std::vector<std::string> subnames;
    std::vector<std::string> subdescs;
    void enable();

  protected:
    /** Local storage for the entry values, used for printing. */
    mutable VResult rvec;

  public:
    virtual size_type size() const = 0;
};

class Vector2dInfo : public Info
{
  public:
    /** Names and descriptions of subfields. */
    std::vector<std::string> subnames;
    std::vector<std::string> subdescs;
    std::vector<std::string> y_subnames;

    size_type x;
    size_type y;

    /** Local storage for the entry values, used for printing. */
    mutable VCounter cvec;

    void enable();
};

class FormulaInfo : public VectorInfo
{
  public:
    virtual std::string str() const = 0;
};

/* namespace Stats */ }

#endif // __BASE_STATS_INFO_HH__
<|endoftext|>


<commit_before><commit_msg>Fix crash when destroying the browser window while a context menu is displayed.<commit_after><|endoftext|>


<commit_before>/*
 *  This file is part of Poedit (http://poedit.net)
 *
 *  Copyright (C) 2015-2016 Vaclav Slavik
 *
 *  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 "hidpi.h"

#include <wx/bitmap.h>
#include <wx/dcscreen.h>
#include <wx/image.h>

#ifdef NEEDS_MANUAL_HIDPI

double g_pxScalingFactor = 1.0;

void InitHiDPIHandling()
{
    wxSize dpi = wxScreenDC().GetPPI();
    g_pxScalingFactor = dpi.y / 96.0;
}

namespace
{
void LoadPNGImage(wxImage& img, const wxString& filename)
{
    img.LoadFile(filename, wxBITMAP_TYPE_PNG);
    // wxImage doesn't load alpha from PNG if it could be expressed as a mask.
    // Too bad this breaks a) scaling and b) wxToolbar's disabled bitmaps.
    // Beat some sense into it:
    if (img.IsOk() && img.HasMask())
    {
        img.InitAlpha();
    }
}

} // anonymous namespace

#endif // NEEDS_MANUAL_HIDPI

wxBitmap LoadScaledBitmap(const wxString& name)
{
    const wxString filename(name + ".png");
    if (!wxFileExists(filename))
        return wxNullBitmap;

#ifdef NEEDS_MANUAL_HIDPI
    if (HiDPIScalingFactor() > 1.0)
    {
        wxImage img;
        double imgScale = HiDPIScalingFactor();
        const wxString filename_2x(name + "@2x.png");
        if (wxFileExists(filename_2x))
        {
            LoadPNGImage(img, filename_2x);
            if (HiDPIScalingFactor() == 2.0)
                return wxBitmap(img);
            else
                imgScale /= 2.0;
        }
        else
        {
            LoadPNGImage(img, filename);
        }

        img.Rescale(img.GetWidth() * imgScale, img.GetHeight() * imgScale,
                    imgScale == 2.0 ? wxIMAGE_QUALITY_NEAREST : wxIMAGE_QUALITY_BICUBIC);
        return wxBitmap(img);
    }
    // else: load normally
#endif

    return wxBitmap(wxImage(filename, wxBITMAP_TYPE_PNG));
}
<commit_msg>Small visual fixes for HiDPI on Windows<commit_after>/*
 *  This file is part of Poedit (http://poedit.net)
 *
 *  Copyright (C) 2015-2016 Vaclav Slavik
 *
 *  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 "hidpi.h"

#include <wx/bitmap.h>
#include <wx/dcscreen.h>
#include <wx/image.h>

#ifdef NEEDS_MANUAL_HIDPI

double g_pxScalingFactor = 1.0;

void InitHiDPIHandling()
{
    wxSize dpi = wxScreenDC().GetPPI();
    g_pxScalingFactor = dpi.y / 96.0;
}

namespace
{
void LoadPNGImage(wxImage& img, const wxString& filename)
{
    img.LoadFile(filename, wxBITMAP_TYPE_PNG);
    // wxImage doesn't load alpha from PNG if it could be expressed as a mask.
    // Too bad this breaks a) scaling and b) wxToolbar's disabled bitmaps.
    // Beat some sense into it:
    if (img.IsOk() && img.HasMask())
    {
        img.InitAlpha();
    }
}

} // anonymous namespace

#endif // NEEDS_MANUAL_HIDPI

wxBitmap LoadScaledBitmap(const wxString& name)
{
    const wxString filename(name + ".png");
    if (!wxFileExists(filename))
        return wxNullBitmap;

#ifdef NEEDS_MANUAL_HIDPI
    if (HiDPIScalingFactor() > 1.0)
    {
        wxImage img;
        double imgScale = HiDPIScalingFactor();
        const wxString filename_2x(name + "@2x.png");
        if (wxFileExists(filename_2x))
        {
            LoadPNGImage(img, filename_2x);
            if (HiDPIScalingFactor() == 2.0)
                return wxBitmap(img);
            else
                imgScale /= 2.0;
        }
        else
        {
            LoadPNGImage(img, filename);
        }

        wxImageResizeQuality quality;
        if (imgScale == 2.0)
            quality = wxIMAGE_QUALITY_NEAREST;
        else if (imgScale == 1.5)
            quality = wxIMAGE_QUALITY_BILINEAR;
        else
            quality = wxIMAGE_QUALITY_BICUBIC;
        img.Rescale(img.GetWidth() * imgScale, img.GetHeight() * imgScale, quality);
        return wxBitmap(img);
    }
    // else: load normally
#endif

    return wxBitmap(wxImage(filename, wxBITMAP_TYPE_PNG));
}
<|endoftext|>


<commit_before>//
// Copyright (c) 2017-2019 the rbfx 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.
//
#if _WIN32
#   undef GetObject
#endif
#include <Urho3D/Core/ProcessUtils.h>
#include <Urho3D/Core/StringUtils.h>
#include <Urho3D/Engine/EngineDefs.h>
#include <Urho3D/Engine/EngineEvents.h>
#include <Urho3D/Graphics/Renderer.h>
#include <Urho3D/IO/FileSystem.h>
#include <Urho3D/IO/Log.h>
#include <Urho3D/Resource/ResourceCache.h>
#include <Urho3D/Resource/JSONArchive.h>
#include <Urho3D/Scene/SceneManager.h>
#if URHO3D_CSHARP
#   include <Urho3D/Script/Script.h>
#endif
#if URHO3D_SYSTEMUI
#   include <Urho3D/SystemUI/SystemUI.h>
#endif
#include "Player.h"

namespace Urho3D
{

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

void Player::Setup()
{
#if DESKTOP
    FileSystem* fs = GetFileSystem();
    engineParameters_[EP_RESOURCE_PREFIX_PATHS] = fs->GetProgramDir() + ";" + fs->GetCurrentDir();
#endif
    engineParameters_[EP_RESOURCE_PATHS] = "Cache;Resources";

    JSONFile settings(context_);
#if DESKTOP
    // Try file in current directory for release builds.
    // If not found try to load settings of default flavor from cache dir.
    StringVector tryPrefixes{"", "Cache/"};
#elif ANDROID
    // Always load file from root of the apk bundle.
    StringVector tryPrefixes{APK};
#else
    // iOS should load file from root of it's appbundle. FIXME: WebGL untested.
    StringVector tryPrefixes{""};
#endif
    for (const ea::string& prefix : tryPrefixes)
    {
        ea::string settingsFilePath = Format("{}{}", prefix, "Settings.json");
        if (!GetFileSystem()->Exists(settingsFilePath))
            continue;
        if (settings.LoadFile(settingsFilePath))
        {
            JSONInputArchive archive(&settings);
            if (settings_.Serialize(archive))
            {
                for (const auto& pair : settings_.engineParameters_)
                    engineParameters_[pair.first] = pair.second;
            }
        }
    }
}

void Player::Start()
{
#if URHO3D_SYSTEMUI
    ui::GetIO().IniFilename = nullptr;              // Disable of imgui.ini creation,
#endif

    GetCache()->AddResourceRouter(new BakedResourceRouter(context_));

    context_->RegisterSubsystem(new SceneManager(context_));

#if URHO3D_STATIC
    SendEvent(E_REGISTERSTATICPLUGINS);
#else
    if (!LoadPlugins(settings_.plugins_))
        ErrorExit("Loading of required plugins failed.");
#endif
#if URHO3D_CSHARP && URHO3D_PLUGINS
    RegisterPlugin(Script::GetRuntimeApi()->CompileResourceScriptPlugin());
#endif

    for (LoadedModule& plugin : plugins_)
    {
        plugin.application_->SendEvent(E_PLUGINSTART);
        plugin.application_->Start();
    }

    // Load main scene.
    {
        auto* manager = GetSubsystem<SceneManager>();
        Scene* scene = manager->CreateScene();

        if (scene->LoadFile(settings_.defaultScene_))
            manager->SetActiveScene(scene);
        else
            ErrorExit("Invalid scene file.");
    }
}

void Player::Stop()
{
    for (LoadedModule& plugin : plugins_)
    {
        plugin.application_->SendEvent(E_PLUGINSTOP);
        plugin.application_->Stop();
    }

    if (auto* manager = GetSubsystem<SceneManager>())
        manager->UnloadAll();

    for (LoadedModule& plugin : plugins_)
    {
        plugin.application_->SendEvent(E_PLUGINUNLOAD);
        plugin.application_->Unload();
    }

#if URHO3D_CSHARP
    for (LoadedModule& plugin : plugins_)
        Script::GetRuntimeApi()->DereferenceAndDispose(plugin.application_.Detach());
#endif

}

bool Player::LoadPlugins(const StringVector& plugins)
{
    // Load plugins.
#if URHO3D_PLUGINS
    for (const ea::string& pluginName : plugins)
    {
        ea::string pluginFileName;
        bool loaded = false;
#if !_WIN32
        // Native plugins on unixes
#if __linux__
        pluginFileName = "lib" + pluginName + ".so";
#elif APPLE
        pluginFileName = "lib" + pluginName + ".dylib";
#endif

#if MOBILE
        // On mobile libraries are loaded already so it is ok to not check for existence, TODO: iOS
        loaded = LoadAssembly(pluginFileName, PLUGIN_NATIVE);
#else
        // On desktop we can access file system as usual
        if (GetFileSystem()->Exists(pluginFileName))
            loaded = LoadAssembly(pluginFileName);
        else
        {
            pluginFileName = GetFileSystem()->GetProgramDir() + pluginFileName;
            if (GetFileSystem()->Exists(pluginFileName))
                loaded = LoadAssembly(pluginFileName);
        }
#endif  // MOBILE
#endif  // !_WIN32

#if _WIN32 || URHO3D_CSHARP
        // Native plugins on windows or managed plugins on all platforms
        if (!loaded)
        {
            pluginFileName = pluginName + ".dll";
#if ANDROID
            pluginFileName = ea::string(APK) + "assets/.net/" + pluginFileName;
#endif
            if (GetFileSystem()->Exists(pluginFileName))
                loaded = LoadAssembly(pluginFileName);
#if DESKTOP
            else
            {
                pluginFileName = GetFileSystem()->GetProgramDir() + pluginFileName;
                if (GetFileSystem()->Exists(pluginFileName))
                    loaded = LoadAssembly(pluginFileName);
            }
#endif  // DESKTOP
        }
#endif  // URHO3D_PLUGINS

        if (!loaded)
        {
            URHO3D_LOGERRORF("Loading of '%s' assembly failed.", pluginName.c_str());
            return false;
        }
    }
#endif  // URHO3D_PLUGINS
    return true;
}
#if URHO3D_PLUGINS
bool Player::LoadAssembly(const ea::string& path)
{
    LoadedModule moduleInfo;

    moduleInfo.module_ = new PluginModule(context_);
    if (moduleInfo.module_->Load(path))
    {
        moduleInfo.application_ = moduleInfo.module_->InstantiatePlugin();
        if (moduleInfo.application_.NotNull())
        {
            plugins_.emplace_back(moduleInfo);
            moduleInfo.application_->SendEvent(E_PLUGINLOAD);
            moduleInfo.application_->Load();
            return true;
        }
    }
    return false;
}

bool Player::RegisterPlugin(PluginApplication* plugin)
{
    if (plugin == nullptr)
    {
        URHO3D_LOGERROR("PluginApplication may not be null.");
        return false;
    }
    LoadedModule moduleInfo;
    moduleInfo.application_ = plugin;
    plugins_.emplace_back(moduleInfo);
    plugin->SendEvent(E_PLUGINLOAD);
    plugin->Load();
    return true;
}
#endif
BakedResourceRouter::BakedResourceRouter(Context* context)
    : ResourceRouter(context)
{
    SharedPtr<JSONFile> file(GetCache()->GetResource<JSONFile>("CacheInfo.json"));
    if (file)
    {
        const auto& info = file->GetRoot().GetObject();
        for (const auto & it : info)
        {
            const JSONArray& files = it.second["files"].GetArray();
            if (files.size() == 1)
                routes_[it.first] = files[0].GetString();
        }
    }
}

void BakedResourceRouter::Route(ea::string& name, ResourceRequest requestType)
{
    auto it = routes_.find(name);
    if (it != routes_.end())
        name = it->second;
}

}
<commit_msg>Player: Fix build error on mobiles due to changed APIs.<commit_after>//
// Copyright (c) 2017-2019 the rbfx 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.
//
#if _WIN32
#   undef GetObject
#endif
#include <Urho3D/Core/ProcessUtils.h>
#include <Urho3D/Core/StringUtils.h>
#include <Urho3D/Engine/EngineDefs.h>
#include <Urho3D/Engine/EngineEvents.h>
#include <Urho3D/Graphics/Renderer.h>
#include <Urho3D/IO/FileSystem.h>
#include <Urho3D/IO/Log.h>
#include <Urho3D/Resource/ResourceCache.h>
#include <Urho3D/Resource/JSONArchive.h>
#include <Urho3D/Scene/SceneManager.h>
#if URHO3D_CSHARP
#   include <Urho3D/Script/Script.h>
#endif
#if URHO3D_SYSTEMUI
#   include <Urho3D/SystemUI/SystemUI.h>
#endif
#include "Player.h"

namespace Urho3D
{

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

void Player::Setup()
{
#if DESKTOP
    FileSystem* fs = GetFileSystem();
    engineParameters_[EP_RESOURCE_PREFIX_PATHS] = fs->GetProgramDir() + ";" + fs->GetCurrentDir();
#endif
    engineParameters_[EP_RESOURCE_PATHS] = "Cache;Resources";

    JSONFile settings(context_);
#if DESKTOP
    // Try file in current directory for release builds.
    // If not found try to load settings of default flavor from cache dir.
    StringVector tryPrefixes{"", "Cache/"};
#elif ANDROID
    // Always load file from root of the apk bundle.
    StringVector tryPrefixes{APK};
#else
    // iOS should load file from root of it's appbundle. FIXME: WebGL untested.
    StringVector tryPrefixes{""};
#endif
    for (const ea::string& prefix : tryPrefixes)
    {
        ea::string settingsFilePath = Format("{}{}", prefix, "Settings.json");
        if (!GetFileSystem()->Exists(settingsFilePath))
            continue;
        if (settings.LoadFile(settingsFilePath))
        {
            JSONInputArchive archive(&settings);
            if (settings_.Serialize(archive))
            {
                for (const auto& pair : settings_.engineParameters_)
                    engineParameters_[pair.first] = pair.second;
            }
        }
    }
}

void Player::Start()
{
#if URHO3D_SYSTEMUI
    ui::GetIO().IniFilename = nullptr;              // Disable of imgui.ini creation,
#endif

    GetCache()->AddResourceRouter(new BakedResourceRouter(context_));

    context_->RegisterSubsystem(new SceneManager(context_));

#if URHO3D_STATIC
    SendEvent(E_REGISTERSTATICPLUGINS);
#else
    if (!LoadPlugins(settings_.plugins_))
        ErrorExit("Loading of required plugins failed.");
#endif
#if URHO3D_CSHARP && URHO3D_PLUGINS
    RegisterPlugin(Script::GetRuntimeApi()->CompileResourceScriptPlugin());
#endif

    for (LoadedModule& plugin : plugins_)
    {
        plugin.application_->SendEvent(E_PLUGINSTART);
        plugin.application_->Start();
    }

    // Load main scene.
    {
        auto* manager = GetSubsystem<SceneManager>();
        Scene* scene = manager->CreateScene();

        if (scene->LoadFile(settings_.defaultScene_))
            manager->SetActiveScene(scene);
        else
            ErrorExit("Invalid scene file.");
    }
}

void Player::Stop()
{
    for (LoadedModule& plugin : plugins_)
    {
        plugin.application_->SendEvent(E_PLUGINSTOP);
        plugin.application_->Stop();
    }

    if (auto* manager = GetSubsystem<SceneManager>())
        manager->UnloadAll();

    for (LoadedModule& plugin : plugins_)
    {
        plugin.application_->SendEvent(E_PLUGINUNLOAD);
        plugin.application_->Unload();
    }

#if URHO3D_CSHARP
    for (LoadedModule& plugin : plugins_)
        Script::GetRuntimeApi()->DereferenceAndDispose(plugin.application_.Detach());
#endif

}

bool Player::LoadPlugins(const StringVector& plugins)
{
    // Load plugins.
#if URHO3D_PLUGINS
    for (const ea::string& pluginName : plugins)
    {
        ea::string pluginFileName;
        bool loaded = false;
#if !_WIN32
        // Native plugins on unixes
#if __linux__
        pluginFileName = "lib" + pluginName + ".so";
#elif APPLE
        pluginFileName = "lib" + pluginName + ".dylib";
#endif

#if MOBILE
        // On mobile libraries are loaded already so it is ok to not check for existence, TODO: iOS
        loaded = LoadAssembly(pluginFileName);
#else
        // On desktop we can access file system as usual
        if (GetFileSystem()->Exists(pluginFileName))
            loaded = LoadAssembly(pluginFileName);
        else
        {
            pluginFileName = GetFileSystem()->GetProgramDir() + pluginFileName;
            if (GetFileSystem()->Exists(pluginFileName))
                loaded = LoadAssembly(pluginFileName);
        }
#endif  // MOBILE
#endif  // !_WIN32

#if _WIN32 || URHO3D_CSHARP
        // Native plugins on windows or managed plugins on all platforms
        if (!loaded)
        {
            pluginFileName = pluginName + ".dll";
#if ANDROID
            pluginFileName = ea::string(APK) + "assets/.net/" + pluginFileName;
#endif
            if (GetFileSystem()->Exists(pluginFileName))
                loaded = LoadAssembly(pluginFileName);
#if DESKTOP
            else
            {
                pluginFileName = GetFileSystem()->GetProgramDir() + pluginFileName;
                if (GetFileSystem()->Exists(pluginFileName))
                    loaded = LoadAssembly(pluginFileName);
            }
#endif  // DESKTOP
        }
#endif  // URHO3D_PLUGINS

        if (!loaded)
        {
            URHO3D_LOGERRORF("Loading of '%s' assembly failed.", pluginName.c_str());
            return false;
        }
    }
#endif  // URHO3D_PLUGINS
    return true;
}
#if URHO3D_PLUGINS
bool Player::LoadAssembly(const ea::string& path)
{
    LoadedModule moduleInfo;

    moduleInfo.module_ = new PluginModule(context_);
    if (moduleInfo.module_->Load(path))
    {
        moduleInfo.application_ = moduleInfo.module_->InstantiatePlugin();
        if (moduleInfo.application_.NotNull())
        {
            plugins_.emplace_back(moduleInfo);
            moduleInfo.application_->SendEvent(E_PLUGINLOAD);
            moduleInfo.application_->Load();
            return true;
        }
    }
    return false;
}

bool Player::RegisterPlugin(PluginApplication* plugin)
{
    if (plugin == nullptr)
    {
        URHO3D_LOGERROR("PluginApplication may not be null.");
        return false;
    }
    LoadedModule moduleInfo;
    moduleInfo.application_ = plugin;
    plugins_.emplace_back(moduleInfo);
    plugin->SendEvent(E_PLUGINLOAD);
    plugin->Load();
    return true;
}
#endif
BakedResourceRouter::BakedResourceRouter(Context* context)
    : ResourceRouter(context)
{
    SharedPtr<JSONFile> file(GetCache()->GetResource<JSONFile>("CacheInfo.json"));
    if (file)
    {
        const auto& info = file->GetRoot().GetObject();
        for (const auto & it : info)
        {
            const JSONArray& files = it.second["files"].GetArray();
            if (files.size() == 1)
                routes_[it.first] = files[0].GetString();
        }
    }
}

void BakedResourceRouter::Route(ea::string& name, ResourceRequest requestType)
{
    auto it = routes_.find(name);
    if (it != routes_.end())
        name = it->second;
}

}
<|endoftext|>


<commit_before>#include <algorithm>
#include <cassert>
#include <climits>
#include <cstdlib>
#include <sys/time.h>
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <sstream>

using namespace std;

const int NX=1024, NY=NX;
int T_FINAL;

const int X_MASK = NX-1, Y_MASK=NY-1;

const int NT=16;
const int NTO=NX/NT;
const int NF=NX/4;

double dens_initial[NX][NX];
double dens_final[NX][NX];

double dens_final_pitch[NX][NX];

double yuka[NTO][NTO][1][NT+2][NT+2];

const int N_KABE=NF+NT/2+2;
double yuka_tmp[1][NT+2][NT+2];
double kabe_y[NTO][NTO][N_KABE][2][NT+2];
double kabe_x[NTO][NTO][N_KABE][NT+2][2];

static double second(){
  struct timeval tv;
  gettimeofday(&tv, NULL);
  return double(tv.tv_sec) + 1.e-6*double(tv.tv_usec);
}

void initialize() {
  for (int y=0; y<NY; ++y) {
    for (int x=0; x<NX; ++x) {
      dens_initial[y][x]=(rand()/double(INT_MAX)*2 > 1 ? 1 : 0);
      dens_final[y][x]=424242;
    }
  }
}
void dump(const char* fn) {
  ofstream ofs(fn);
  for (int y=0; y<NY; ++y) {
    for(int x=0;x<NX;++x) {
      ofs << x << " " << y << " " << dens_final[y][x] << endl;
    }
    ofs << endl;
  }
}

inline double stencil_function(double o, double a, double b, double c, double d) {
  return 0.5*o+0.125*(a+b+c+d);
}

double ref_buf[NX][NX];
double ref_buf2[NX][NX];

void compute_reference() {
  for (int y=0;y<NY;++y) {
    for (int x=0;x<NX;++x) {
      ref_buf[y][x]=dens_initial[y][x];
    }
  }

  for (int t=1; t <=T_FINAL; ++t) {
    for (int y=0;y<NY;++y) {
      for (int x=0;x<NX;++x) {
        ref_buf2[y][x]=stencil_function
          (ref_buf[y][x],
           ref_buf[(y-1)&Y_MASK][x],
           ref_buf[(y+1)&Y_MASK][x],
           ref_buf[y][(x-1)&X_MASK],
           ref_buf[y][(x+1)&X_MASK]
           );
      }
    }
    swap(ref_buf, ref_buf2);
  }
  for (int y=0;y<NY;++y) {
    for (int x=0;x<NX;++x) {
      dens_final[y][x] = ref_buf[y][x];
    }
  }
}

double work[N_KABE][NT+2][NT+2];

template <bool near_initial, bool near_final>
void pitch_kernel
(int t_orig, int y_orig, int x_orig,
 double yuka_in[1][NT+2][NT+2], double kabe_y_in[N_KABE][2][NT+2], double kabe_x_in[N_KABE][NT+2][2],
 double yuka_out[1][NT+2][NT+2], double kabe_y_out[N_KABE][2][NT+2], double kabe_x_out[N_KABE][NT+2][2])
{
  for(int t=0; t<NF+NT/4+2;++t) {
    for(int y=0; y<NT+2; ++y) {
      work[t][y][0] = kabe_x_in[t+NT/4][y][0];
      work[t][y][1] = kabe_x_in[t+NT/4][y][1];
    }
    for(int x=0; x<NT+2; ++x) {
      work[t][0][x] = kabe_y_in[t+NT/4][0][x];
      work[t][1][x] = kabe_y_in[t+NT/4][1][x];
    }
  }

  // iter 1
  for(int t=1; t<=NT;++t) {
    for(int y=2; y<NT+2; ++y) {
      for(int x=2; x<NT+2; ++x) {
        int t_k=t, y_k = y-t, x_k = x-t;
        int t_dash = (2*t_k-x_k-y_k)>>2;
        const bool in_region = t_dash >=0 && t_dash < NF+1;

        if (in_region) {
          double ret=work[t][y][x];
          if (t_k + t_orig == 0 && near_initial) {
            ret = dens_initial[(y_k+y_orig) & Y_MASK][(x_k+x_orig) & X_MASK];
          } else if (t_dash == 0) {
            ret = yuka_in[0][y][x];
          } else if (t+t_orig>0 && y>=2 && x>=2) {
            asm volatile("#kernel");
            ret = stencil_function(work[t-1][y-1][x-1],work[t-1][y-2][x-1],work[t-1][y][x-1],work[t-1][y-1][x-2],work[t-1][y-1][x]);
          }

          work[t][y][x] = ret;

          if (t_k + t_orig == T_FINAL && near_final) {
            dens_final[(y_k+y_orig) & Y_MASK][(x_k+x_orig) & X_MASK] = ret;
          }
        }
      }
    }
  }

  // iter 2
  for(int t=NT+1; t<=NF+1;++t) {
    for(int y=2; y<NT+2; ++y) {
      for(int x=2; x<NT+2; ++x) {
        int t_k=t, y_k = y-t, x_k = x-t;

        double ret=work[t][y][x];
        if (t_k + t_orig == 0 && near_initial) {
          ret = dens_initial[(y_k+y_orig) & Y_MASK][(x_k+x_orig) & X_MASK];
        } else if (t+t_orig>0 && y>=2 && x>=2) {
          asm volatile("#kernel");
          ret = stencil_function(work[t-1][y-1][x-1],work[t-1][y-2][x-1],work[t-1][y][x-1],work[t-1][y-1][x-2],work[t-1][y-1][x]);
        }
        work[t][y][x] = ret;
        if (t_k + t_orig == T_FINAL && near_final) {
            dens_final[(y_k+y_orig) & Y_MASK][(x_k+x_orig) & X_MASK] = ret;
        }
      }
    }
  }

  // iter 3
  for(int t=NF+2; t<NF+NT/2+2;++t) {
    for(int y=2; y<NT+2; ++y) {
      for(int x=2; x<NT+2; ++x) {
        int t_k=t, y_k = y-t, x_k = x-t;
        int t_dash = (2*t_k-x_k-y_k)>>2;
        const bool in_region = t_dash >=0 && t_dash < NF+1;

        if (in_region) {
          double ret=work[t][y][x];
          if (t_k + t_orig == 0 && near_initial) {
            ret = dens_initial[(y_k+y_orig) & Y_MASK][(x_k+x_orig) & X_MASK];
          } else if (t+t_orig>0 && y>=2 && x>=2) {
            asm volatile("#kernel");
            ret = stencil_function(work[t-1][y-1][x-1],work[t-1][y-2][x-1],work[t-1][y][x-1],work[t-1][y-1][x-2],work[t-1][y-1][x]);
          }

          work[t][y][x] = ret;

          if (t_dash == NF && t >=NF+2) {
            yuka_out[0][y][x] = ret;
          }
          if (t_k + t_orig == T_FINAL && near_final) {
            dens_final[(y_k+y_orig) & Y_MASK][(x_k+x_orig) & X_MASK] = ret;
          }
        }
      }
    }
  }

  for(int t=0; t<NF+NT/2+2;++t) {
    for(int x=0; x<NT+2; ++x) {
      kabe_y_out[t][0][x] = work[t][NT+0][x];
      kabe_y_out[t][1][x] = work[t][NT+1][x];
    }
    for(int y=0; y<NT+2; ++y) {
      kabe_x_out[t][y][0] = work[t][y][NT+0];
      kabe_x_out[t][y][1] = work[t][y][NT+1];
    }
  }

}

void compute_pitch(){
  for(int t_orig=-NX; t_orig <= T_FINAL; t_orig+=NF) {
    int y_orig = -t_orig;
    int x_orig = -t_orig;
    for (int yo=0;yo<NTO;++yo) {
      for (int xo=0;xo<NTO;++xo) {
        int dy = yo*NT, dx = xo*NT;
        bool near_initial = t_orig < 0;
        bool near_final   = t_orig >= T_FINAL-NX;
        if(near_initial && near_final) {
          pitch_kernel<true, true>
            (t_orig+(dx+dy)/4,
             y_orig+(3*dy-dx)/4,
             x_orig+(3*dx-dy)/4,
             yuka[yo][xo],kabe_y[yo][xo],kabe_x[yo][xo],
             yuka_tmp,kabe_y[(yo+1)%NTO][xo],kabe_x[yo][(xo+1)%NTO]);
        }else if(near_initial) {
          pitch_kernel<true, false>
            (t_orig+(dx+dy)/4,
             y_orig+(3*dy-dx)/4,
             x_orig+(3*dx-dy)/4,
             yuka[yo][xo],kabe_y[yo][xo],kabe_x[yo][xo],
             yuka_tmp,kabe_y[(yo+1)%NTO][xo],kabe_x[yo][(xo+1)%NTO]);
        }else  if(near_final) {
          pitch_kernel<false, true >
            (t_orig+(dx+dy)/4,
             y_orig+(3*dy-dx)/4,
             x_orig+(3*dx-dy)/4,
             yuka[yo][xo],kabe_y[yo][xo],kabe_x[yo][xo],
             yuka_tmp,kabe_y[(yo+1)%NTO][xo],kabe_x[yo][(xo+1)%NTO]);
        }else {
          pitch_kernel<false, false>
            (t_orig+(dx+dy)/4,
             y_orig+(3*dy-dx)/4,
             x_orig+(3*dx-dy)/4,
             yuka[yo][xo],kabe_y[yo][xo],kabe_x[yo][xo],
             yuka_tmp,kabe_y[(yo+1)%NTO][xo],kabe_x[yo][(xo+1)%NTO]);
        }
        swap(yuka[yo][xo], yuka_tmp);
      }
    }
  }
}

int main ()
{
  double n_flop[2], wct_pitch[2], wct_ref[2];

  for(int part=0; part<2; ++part) {
    T_FINAL = NX*(3+part);
    initialize();
    n_flop[part]=6.0*NX*NX*double(T_FINAL);
    double t1 = second();
    compute_pitch();
    double t2 = second();
    cout << "PiTCH: " << n_flop[part] << " flop " << (t2-t1) << " second" << endl;
    wct_pitch[part] = t2-t1;

    swap(dens_final, dens_final_pitch);

    double t3 = second();
    compute_reference();
    double t4 = second();
    cout << "Ref: " << n_flop[part] << " flop " << (t4-t3) << " second" << endl;
    wct_ref[part] = t4-t3;
    for (int y=0;y<NY;++y) {
      for (int x=0;x<NX;++x){
        assert(dens_final[y][x]==dens_final_pitch[y][x]);
      }
    }
  }

  cerr << "PiTCH: " << (n_flop[1]-n_flop[0])/(wct_pitch[1]-wct_pitch[0]) << " flop/s " << endl;
  cerr << "Ref: " << (n_flop[1]-n_flop[0])/(wct_ref[1]-wct_ref[0]) << " flop/s " << endl;
}
<commit_msg>more accurate boundary.<commit_after>#include <algorithm>
#include <cassert>
#include <climits>
#include <cstdlib>
#include <sys/time.h>
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <sstream>

using namespace std;

const int NX=1024, NY=NX;
int T_FINAL;

const int X_MASK = NX-1, Y_MASK=NY-1;

const int NT=16;
const int NTO=NX/NT;
const int NF=NX/4;

double dens_initial[NX][NX];
double dens_final[NX][NX];

double dens_final_pitch[NX][NX];

double yuka[NTO][NTO][1][NT+2][NT+2];

const int N_KABE=NF+NT/2+2;
double yuka_tmp[1][NT+2][NT+2];
double kabe_y[NTO][NTO][N_KABE][2][NT+2];
double kabe_x[NTO][NTO][N_KABE][NT+2][2];

static double second(){
  struct timeval tv;
  gettimeofday(&tv, NULL);
  return double(tv.tv_sec) + 1.e-6*double(tv.tv_usec);
}

void initialize() {
  for (int y=0; y<NY; ++y) {
    for (int x=0; x<NX; ++x) {
      dens_initial[y][x]=(rand()/double(INT_MAX)*2 > 1 ? 1 : 0);
      dens_final[y][x]=424242;
    }
  }
}
void dump(const char* fn) {
  ofstream ofs(fn);
  for (int y=0; y<NY; ++y) {
    for(int x=0;x<NX;++x) {
      ofs << x << " " << y << " " << dens_final[y][x] << endl;
    }
    ofs << endl;
  }
}

inline double stencil_function(double o, double a, double b, double c, double d) {
  return 0.5*o+0.125*(a+b+c+d);
}

double ref_buf[NX][NX];
double ref_buf2[NX][NX];

void compute_reference() {
  for (int y=0;y<NY;++y) {
    for (int x=0;x<NX;++x) {
      ref_buf[y][x]=dens_initial[y][x];
    }
  }

  for (int t=1; t <=T_FINAL; ++t) {
    for (int y=0;y<NY;++y) {
      for (int x=0;x<NX;++x) {
        ref_buf2[y][x]=stencil_function
          (ref_buf[y][x],
           ref_buf[(y-1)&Y_MASK][x],
           ref_buf[(y+1)&Y_MASK][x],
           ref_buf[y][(x-1)&X_MASK],
           ref_buf[y][(x+1)&X_MASK]
           );
      }
    }
    swap(ref_buf, ref_buf2);
  }
  for (int y=0;y<NY;++y) {
    for (int x=0;x<NX;++x) {
      dens_final[y][x] = ref_buf[y][x];
    }
  }
}

double work[N_KABE][NT+2][NT+2];

template <bool near_initial, bool near_final>
void pitch_kernel
(int t_orig, int y_orig, int x_orig,
 double yuka_in[1][NT+2][NT+2], double kabe_y_in[N_KABE][2][NT+2], double kabe_x_in[N_KABE][NT+2][2],
 double yuka_out[1][NT+2][NT+2], double kabe_y_out[N_KABE][2][NT+2], double kabe_x_out[N_KABE][NT+2][2])
{
  for(int t=0; t<NF+NT/4+2;++t) {
    for(int y=0; y<NT+2; ++y) {
      work[t][y][0] = kabe_x_in[t+NT/4][y][0];
      work[t][y][1] = kabe_x_in[t+NT/4][y][1];
    }
    for(int x=0; x<NT+2; ++x) {
      work[t][0][x] = kabe_y_in[t+NT/4][0][x];
      work[t][1][x] = kabe_y_in[t+NT/4][1][x];
    }
  }

  // iter 1
  const int t_boundary_1 = NT/2+2;
  const int t_boundary_2 = NF+2;
  for(int t=1; t<t_boundary_1;++t) {
    for(int y=2; y<NT+2; ++y) {
      for(int x=2; x<NT+2; ++x) {
        int t_k=t, y_k = y-t, x_k = x-t;
        int t_dash = (2*t_k-x_k-y_k)>>2;
        const bool in_region = t_dash >=0 && t_dash < NF+1;

        if (in_region) {
          double ret=work[t][y][x];
          if (t_k + t_orig == 0 && near_initial) {
            ret = dens_initial[(y_k+y_orig) & Y_MASK][(x_k+x_orig) & X_MASK];
          } else if (t_dash == 0) {
            ret = yuka_in[0][y][x];
          } else if (t+t_orig>0 && y>=2 && x>=2) {
            asm volatile("#kernel");
            ret = stencil_function(work[t-1][y-1][x-1],work[t-1][y-2][x-1],work[t-1][y][x-1],work[t-1][y-1][x-2],work[t-1][y-1][x]);
          }

          work[t][y][x] = ret;

          if (t_k + t_orig == T_FINAL && near_final) {
            dens_final[(y_k+y_orig) & Y_MASK][(x_k+x_orig) & X_MASK] = ret;
          }
        }
      }
    }
  }

  // iter 2
  for(int t=t_boundary_1; t<t_boundary_2;++t) {
    for(int y=2; y<NT+2; ++y) {
      for(int x=2; x<NT+2; ++x) {
        int t_k=t, y_k = y-t, x_k = x-t;

        double ret=work[t][y][x];
        if (t_k + t_orig == 0 && near_initial) {
          ret = dens_initial[(y_k+y_orig) & Y_MASK][(x_k+x_orig) & X_MASK];
        } else if (t+t_orig>0 && y>=2 && x>=2) {
          asm volatile("#kernel");
          ret = stencil_function(work[t-1][y-1][x-1],work[t-1][y-2][x-1],work[t-1][y][x-1],work[t-1][y-1][x-2],work[t-1][y-1][x]);
        }
        work[t][y][x] = ret;
        if (t_k + t_orig == T_FINAL && near_final) {
            dens_final[(y_k+y_orig) & Y_MASK][(x_k+x_orig) & X_MASK] = ret;
        }
      }
    }
  }

  // iter 3
  for(int t=t_boundary_2; t<NF+NT/2+2;++t) {
    for(int y=2; y<NT+2; ++y) {
      for(int x=2; x<NT+2; ++x) {
        int t_k=t, y_k = y-t, x_k = x-t;
        int t_dash = (2*t_k-x_k-y_k)>>2;
        const bool in_region = t_dash >=0 && t_dash < NF+1;

        if (in_region) {
          double ret=work[t][y][x];
          if (t_k + t_orig == 0 && near_initial) {
            ret = dens_initial[(y_k+y_orig) & Y_MASK][(x_k+x_orig) & X_MASK];
          } else if (t+t_orig>0 && y>=2 && x>=2) {
            asm volatile("#kernel");
            ret = stencil_function(work[t-1][y-1][x-1],work[t-1][y-2][x-1],work[t-1][y][x-1],work[t-1][y-1][x-2],work[t-1][y-1][x]);
          }

          work[t][y][x] = ret;

          if (t_dash == NF && t >=NF+2) {
            yuka_out[0][y][x] = ret;
          }
          if (t_k + t_orig == T_FINAL && near_final) {
            dens_final[(y_k+y_orig) & Y_MASK][(x_k+x_orig) & X_MASK] = ret;
          }
        }
      }
    }
  }

  for(int t=0; t<NF+NT/2+2;++t) {
    for(int x=0; x<NT+2; ++x) {
      kabe_y_out[t][0][x] = work[t][NT+0][x];
      kabe_y_out[t][1][x] = work[t][NT+1][x];
    }
    for(int y=0; y<NT+2; ++y) {
      kabe_x_out[t][y][0] = work[t][y][NT+0];
      kabe_x_out[t][y][1] = work[t][y][NT+1];
    }
  }

}

void compute_pitch(){
  for(int t_orig=-NX; t_orig <= T_FINAL; t_orig+=NF) {
    int y_orig = -t_orig;
    int x_orig = -t_orig;
    for (int yo=0;yo<NTO;++yo) {
      for (int xo=0;xo<NTO;++xo) {
        int dy = yo*NT, dx = xo*NT;
        bool near_initial = t_orig < 0;
        bool near_final   = t_orig >= T_FINAL-NX;
        if(near_initial && near_final) {
          pitch_kernel<true, true>
            (t_orig+(dx+dy)/4,
             y_orig+(3*dy-dx)/4,
             x_orig+(3*dx-dy)/4,
             yuka[yo][xo],kabe_y[yo][xo],kabe_x[yo][xo],
             yuka_tmp,kabe_y[(yo+1)%NTO][xo],kabe_x[yo][(xo+1)%NTO]);
        }else if(near_initial) {
          pitch_kernel<true, false>
            (t_orig+(dx+dy)/4,
             y_orig+(3*dy-dx)/4,
             x_orig+(3*dx-dy)/4,
             yuka[yo][xo],kabe_y[yo][xo],kabe_x[yo][xo],
             yuka_tmp,kabe_y[(yo+1)%NTO][xo],kabe_x[yo][(xo+1)%NTO]);
        }else  if(near_final) {
          pitch_kernel<false, true >
            (t_orig+(dx+dy)/4,
             y_orig+(3*dy-dx)/4,
             x_orig+(3*dx-dy)/4,
             yuka[yo][xo],kabe_y[yo][xo],kabe_x[yo][xo],
             yuka_tmp,kabe_y[(yo+1)%NTO][xo],kabe_x[yo][(xo+1)%NTO]);
        }else {
          pitch_kernel<false, false>
            (t_orig+(dx+dy)/4,
             y_orig+(3*dy-dx)/4,
             x_orig+(3*dx-dy)/4,
             yuka[yo][xo],kabe_y[yo][xo],kabe_x[yo][xo],
             yuka_tmp,kabe_y[(yo+1)%NTO][xo],kabe_x[yo][(xo+1)%NTO]);
        }
        swap(yuka[yo][xo], yuka_tmp);
      }
    }
  }
}

int main ()
{
  double n_flop[2], wct_pitch[2], wct_ref[2];

  for(int part=0; part<2; ++part) {
    T_FINAL = NX*(3+part);
    initialize();
    n_flop[part]=6.0*NX*NX*double(T_FINAL);
    double t1 = second();
    compute_pitch();
    double t2 = second();
    cout << "PiTCH: " << n_flop[part] << " flop " << (t2-t1) << " second" << endl;
    wct_pitch[part] = t2-t1;

    swap(dens_final, dens_final_pitch);

    double t3 = second();
    compute_reference();
    double t4 = second();
    cout << "Ref: " << n_flop[part] << " flop " << (t4-t3) << " second" << endl;
    wct_ref[part] = t4-t3;
    for (int y=0;y<NY;++y) {
      for (int x=0;x<NX;++x){
        assert(dens_final[y][x]==dens_final_pitch[y][x]);
      }
    }
  }

  cerr << "PiTCH: " << (n_flop[1]-n_flop[0])/(wct_pitch[1]-wct_pitch[0]) << " flop/s " << endl;
  cerr << "Ref: " << (n_flop[1]-n_flop[0])/(wct_ref[1]-wct_ref[0]) << " flop/s " << endl;
}
<|endoftext|>


<commit_before>/**
* @file NaothModule.cpp
*
* @author Oliver Welter
* @author Xu, Yuan
* Implementation of NaothModule
*/
#include "NaothModule.h"
#include "PlatformInterface/Platform.h"

using namespace naoth;

static NaothModule* theModule = NULL;

inline static void motion_wrapper_pre()
{
  theModule->motionCallbackPre();
}

inline static void motion_wrapper_post()
{
  theModule->motionCallbackPost();
}

NaothModule::NaothModule(ALPtr<ALBroker> pB, const std::string& pName ):
  ALModule(pB, pName ),
  pBroker(pB),
  motionFrame(0)
{
  theModule = this;

 // Describe the module here
  setModuleDescription( "Naoth-controlunit of the robot" );
  // Define callable methods with there description
  functionName( "init", "NaothModule",  "Initialize Controller" );
  BIND_METHOD( NaothModule::init );
}

NaothModule::~NaothModule()
{

  delete theCognition;
  delete theMotion;

}

bool NaothModule::innerTest()
{
  bool result = true;
  // put here codes dedicaced to autotest this module.
  // return false if fail, success otherwise
  return result;
}

std::string NaothModule::version()
{
  //return ALTOOLS_VERSION( NAOTH );
  return std::string(NAOTH_VERSION);
}

void NaothModule::init()
{
  //int cognition_interval = 60000;
  int cognition_interval =   40000;

  cout << "Init OutputThread" << endl;

  cout << "Initializing Controller" << endl;
  NaoController::getInstance().init(pBroker);

  getParentBroker()->getProxy("DCM")->getModule()->atPreProcess(motion_wrapper_pre);
  getParentBroker()->getProxy("DCM")->getModule()->atPostProcess(motion_wrapper_post);

  cout << "Creating Cognition and Motion" << endl;
  theCognition = new Cognition();
  theMotion = new Motion();

  cout << "Registering Cognition and Motion" << endl;
  NaoController::getInstance().registerCallbacks(theMotion,theCognition);

  cout << "Creating Cognition-Thread" << endl;
  theCognitionThread = new CognitionThread();
  theCognitionThread->setPeriod(cognition_interval);
  theCognitionThread->setRealtime(SCHED_RR,1);
  //theCognitionThread->setRealtime(SCHED_OTHER,0);
  theCognitionThread->create();

  cout << "NaothModule:init finished!" << endl;
}

void NaothModule::motionCallbackPre()
{

  unsigned int timeStep = NaoController::getInstance().getBasicTimeStep();
  ASSERT(timeStep == 10 || timeStep == 20);

  if(timeStep == 10 || motionFrame % 2 == 0)
  {
    // we are at the moment shortly before the DCM commands are send to the
    // USB bus, so put the motion execute stuff here
    NaoController::getInstance().callMotion();
  }
}

void NaothModule::motionCallbackPost()
{

  unsigned int timeStep = NaoController::getInstance().getBasicTimeStep();
  ASSERT(timeStep == 10 || timeStep == 20);

  if(timeStep == 10 || motionFrame % 2 == 0)
  {
    // right behind the sensor update from the DCM
    // TODO: get stuff into internal buffers
  }
  motionFrame++;
}

void NaothModule::exit( )
{
  cout << "NaoTH is exiting ..."<<endl;

  theCognitionThread->stop();
  theCognitionThread->join();

  cout << "NaoTH exit is finished" << endl;
}
<commit_msg>make it run in NAO, but the motion is strange...<commit_after>/**
* @file NaothModule.cpp
*
* @author Oliver Welter
* @author Xu, Yuan
* Implementation of NaothModule
*/
#include "NaothModule.h"
#include "PlatformInterface/Platform.h"

using namespace naoth;

static NaothModule* theModule = NULL;

inline static void motion_wrapper_pre()
{
  theModule->motionCallbackPre();
}

inline static void motion_wrapper_post()
{
  theModule->motionCallbackPost();
}

NaothModule::NaothModule(ALPtr<ALBroker> pB, const std::string& pName ):
  ALModule(pB, pName ),
  pBroker(pB),
  motionFrame(0)
{
  theModule = this;

 // Describe the module here
  setModuleDescription( "Naoth-controlunit of the robot" );
  // Define callable methods with there description
  functionName( "init", "NaothModule",  "Initialize Controller" );
  BIND_METHOD( NaothModule::init );
}

NaothModule::~NaothModule()
{

  delete theCognition;
  delete theMotion;

}

bool NaothModule::innerTest()
{
  bool result = true;
  // put here codes dedicaced to autotest this module.
  // return false if fail, success otherwise
  return result;
}

std::string NaothModule::version()
{
  //return ALTOOLS_VERSION( NAOTH );
  return std::string(NAOTH_VERSION);
}

void NaothModule::init()
{
  if (!g_thread_supported())
    g_thread_init(NULL);

  //int cognition_interval = 60000;
  int cognition_interval =   40000;

  cout << "Initializing Controller" << endl;
  NaoController::getInstance().init(pBroker);

  cout << "Creating Cognition and Motion" << endl;
  theCognition = new Cognition();
  theMotion = new Motion();

  cout << "Registering Cognition and Motion" << endl;
  NaoController::getInstance().registerCallbacks(theMotion,theCognition);

  getParentBroker()->getProxy("DCM")->getModule()->atPreProcess(motion_wrapper_pre);
  getParentBroker()->getProxy("DCM")->getModule()->atPostProcess(motion_wrapper_post);

  cout << "Creating Cognition-Thread" << endl;
  theCognitionThread = new CognitionThread();
  theCognitionThread->setPeriod(cognition_interval);
  theCognitionThread->setRealtime(SCHED_RR,1);
  //theCognitionThread->setRealtime(SCHED_OTHER,0);
  theCognitionThread->create();

  cout << "NaothModule:init finished!" << endl;
}

void NaothModule::motionCallbackPre()
{

  unsigned int timeStep = NaoController::getInstance().getBasicTimeStep();
  ASSERT(timeStep == 10 || timeStep == 20);

  if(timeStep == 10 || motionFrame % 2 == 0)
  {
    // we are at the moment shortly before the DCM commands are send to the
    // USB bus, so put the motion execute stuff here
    NaoController::getInstance().callMotion();
  }
}

void NaothModule::motionCallbackPost()
{

  unsigned int timeStep = NaoController::getInstance().getBasicTimeStep();
  ASSERT(timeStep == 10 || timeStep == 20);

  if(timeStep == 10 || motionFrame % 2 == 0)
  {
    // right behind the sensor update from the DCM
    // TODO: get stuff into internal buffers
  }
  motionFrame++;
}

void NaothModule::exit( )
{
  cout << "NaoTH is exiting ..."<<endl;

  theCognitionThread->stop();
  theCognitionThread->join();

  cout << "NaoTH exit is finished" << endl;
}
<|endoftext|>


<commit_before>/*
 * Redistribution and use in source and binary forms, with or
 * without modification, are permitted provided that the following
 * conditions are met:
 *
 * 1. Redistributions of source code must retain the above
 *    copyright notice, this list of conditions and the
 *    following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above
 *    copyright notice, this list of conditions and the following
 *    disclaimer in the documentation and/or other materials
 *    provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
 * <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */
#include "iproto_port.h"
#include "iproto_constants.h"

/* m_ - msgpack meta, k_ - key, v_ - value */
struct iproto_header_bin {
	uint8_t m_len;                          /* MP_UINT32 */
	uint32_t v_len;                         /* length */
	uint8_t m_header;                       /* MP_MAP */
	uint8_t k_code;                         /* IPROTO_REQUEST_TYPE */
	uint8_t m_code;                         /* MP_UINT32 */
	uint32_t v_code;                        /* response status */
	uint8_t k_sync;                         /* IPROTO_SYNC */
	uint8_t m_sync;                         /* MP_UIN64 */
	uint64_t v_sync;                        /* sync */
} __attribute__((packed));

static const struct iproto_header_bin iproto_header_bin = {
	0xce, 0, 0x82, IPROTO_REQUEST_TYPE, 0xce, 0, IPROTO_SYNC, 0xcf, 0
};

struct iproto_body_bin {
	uint8_t m_body;                    /* MP_MAP */
	uint8_t k_data;                    /* IPROTO_DATA or IPROTO_ERROR */
	uint8_t m_data;                    /* MP_STR or MP_ARRAY */
	uint32_t v_data_len;               /* string length of array size */
} __attribute__((packed));

static const struct iproto_body_bin iproto_body_bin = {
	0x81, IPROTO_DATA, 0xdd, 0
};

static const struct iproto_body_bin iproto_error_bin = {
	0x81, IPROTO_ERROR, 0xdb, 0
};

/** Return a 4-byte numeric error code, with status flags. */
static inline uint32_t
iproto_encode_error(uint32_t error)
{
	return error | IPROTO_TYPE_ERROR;
}

void
iproto_reply_ping(struct obuf *out, uint64_t sync)
{
	struct iproto_header_bin reply = iproto_header_bin;
	reply.v_len = mp_bswap_u32(sizeof(iproto_header_bin) - 5);
	reply.v_sync = mp_bswap_u64(sync);
	obuf_dup(out, &reply, sizeof(reply));
}

static inline uint32_t
get_errcode(const Exception *e)
{
	const ClientError *error = dynamic_cast<const ClientError *>(e);
	if (error)
		return error->errcode();
	return ClientError::get_code_for_foreign_exception(e);
}

void
iproto_reply_error(struct obuf *out, const Exception *e, uint64_t sync)
{
	uint32_t msg_len = strlen(e->errmsg());
	uint32_t errcode = get_errcode(e);

	struct iproto_header_bin header = iproto_header_bin;
	struct iproto_body_bin body = iproto_error_bin;

	uint32_t len = sizeof(header) - 5 + sizeof(body) + msg_len;
	header.v_len = mp_bswap_u32(len);
	header.v_code = mp_bswap_u32(iproto_encode_error(errcode));
	header.v_sync = mp_bswap_u64(sync);

	body.v_data_len = mp_bswap_u32(msg_len);

	obuf_dup(out, &header, sizeof(header));
	obuf_dup(out, &body, sizeof(body));
	obuf_dup(out, e->errmsg(), msg_len);
}

static inline struct iproto_port *
iproto_port(struct port *port)
{
	return (struct iproto_port *) port;
}

enum { SVP_SIZE = sizeof(iproto_header_bin) + sizeof(iproto_body_bin) };

static inline void
iproto_port_eof(struct port *ptr)
{
	struct iproto_port *port = iproto_port(ptr);
	/* found == 0 means add_tuple wasn't called at all. */
	if (port->found == 0) {
		port->svp = obuf_book(port->buf, SVP_SIZE);
		port->size += SVP_SIZE;
	}

	uint32_t len = port->size - 5;

	struct iproto_header_bin header = iproto_header_bin;
	header.v_len = mp_bswap_u32(len);
	header.v_sync = mp_bswap_u64(port->sync);

	struct iproto_body_bin body = iproto_body_bin;
	body.v_data_len = mp_bswap_u32(port->found);

	char *pos = (char *) obuf_svp_to_ptr(port->buf, &port->svp);
	memcpy(pos, &header, sizeof(header));
	memcpy(pos + sizeof(header), &body, sizeof(body));
}

static inline void
iproto_port_add_tuple(struct port *ptr, struct tuple *tuple)
{
	struct iproto_port *port = iproto_port(ptr);
	if (++port->found == 1) {
		/* Found the first tuple, add header. */
		port->svp = obuf_book(port->buf, SVP_SIZE);
		port->size += SVP_SIZE;
	}
	tuple_to_obuf(tuple, port->buf);
	port->size += tuple->bsize;
}

struct port_vtab iproto_port_vtab = {
	iproto_port_add_tuple,
	iproto_port_eof,
};
<commit_msg>make iproto answer to be 3 part even for ping<commit_after>/*
 * Redistribution and use in source and binary forms, with or
 * without modification, are permitted provided that the following
 * conditions are met:
 *
 * 1. Redistributions of source code must retain the above
 *    copyright notice, this list of conditions and the
 *    following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above
 *    copyright notice, this list of conditions and the following
 *    disclaimer in the documentation and/or other materials
 *    provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
 * <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */
#include "iproto_port.h"
#include "iproto_constants.h"

/* m_ - msgpack meta, k_ - key, v_ - value */
struct iproto_header_bin {
	uint8_t m_len;                          /* MP_UINT32 */
	uint32_t v_len;                         /* length */
	uint8_t m_header;                       /* MP_MAP */
	uint8_t k_code;                         /* IPROTO_REQUEST_TYPE */
	uint8_t m_code;                         /* MP_UINT32 */
	uint32_t v_code;                        /* response status */
	uint8_t k_sync;                         /* IPROTO_SYNC */
	uint8_t m_sync;                         /* MP_UIN64 */
	uint64_t v_sync;                        /* sync */
} __attribute__((packed));

static const struct iproto_header_bin iproto_header_bin = {
	0xce, 0, 0x82, IPROTO_REQUEST_TYPE, 0xce, 0, IPROTO_SYNC, 0xcf, 0
};

struct iproto_body_bin {
	uint8_t m_body;                    /* MP_MAP */
	uint8_t k_data;                    /* IPROTO_DATA or IPROTO_ERROR */
	uint8_t m_data;                    /* MP_STR or MP_ARRAY */
	uint32_t v_data_len;               /* string length of array size */
} __attribute__((packed));

static const struct iproto_body_bin iproto_body_bin = {
	0x81, IPROTO_DATA, 0xdd, 0
};

static const struct iproto_body_bin iproto_error_bin = {
	0x81, IPROTO_ERROR, 0xdb, 0
};

/** Return a 4-byte numeric error code, with status flags. */
static inline uint32_t
iproto_encode_error(uint32_t error)
{
	return error | IPROTO_TYPE_ERROR;
}

void
iproto_reply_ping(struct obuf *out, uint64_t sync)
{
	struct iproto_header_bin reply = iproto_header_bin;
	reply.v_len = mp_bswap_u32(sizeof(iproto_header_bin) - 5 + 1);
	reply.v_sync = mp_bswap_u64(sync);
	uint8_t empty_map[1] = { 0x80 };
	obuf_dup(out, &reply, sizeof(reply));
	obuf_dup(out, &empty_map, sizeof(empty_map));
}

static inline uint32_t
get_errcode(const Exception *e)
{
	const ClientError *error = dynamic_cast<const ClientError *>(e);
	if (error)
		return error->errcode();
	return ClientError::get_code_for_foreign_exception(e);
}

void
iproto_reply_error(struct obuf *out, const Exception *e, uint64_t sync)
{
	uint32_t msg_len = strlen(e->errmsg());
	uint32_t errcode = get_errcode(e);

	struct iproto_header_bin header = iproto_header_bin;
	struct iproto_body_bin body = iproto_error_bin;

	uint32_t len = sizeof(header) - 5 + sizeof(body) + msg_len;
	header.v_len = mp_bswap_u32(len);
	header.v_code = mp_bswap_u32(iproto_encode_error(errcode));
	header.v_sync = mp_bswap_u64(sync);

	body.v_data_len = mp_bswap_u32(msg_len);

	obuf_dup(out, &header, sizeof(header));
	obuf_dup(out, &body, sizeof(body));
	obuf_dup(out, e->errmsg(), msg_len);
}

static inline struct iproto_port *
iproto_port(struct port *port)
{
	return (struct iproto_port *) port;
}

enum { SVP_SIZE = sizeof(iproto_header_bin) + sizeof(iproto_body_bin) };

static inline void
iproto_port_eof(struct port *ptr)
{
	struct iproto_port *port = iproto_port(ptr);
	/* found == 0 means add_tuple wasn't called at all. */
	if (port->found == 0) {
		port->svp = obuf_book(port->buf, SVP_SIZE);
		port->size += SVP_SIZE;
	}

	uint32_t len = port->size - 5;

	struct iproto_header_bin header = iproto_header_bin;
	header.v_len = mp_bswap_u32(len);
	header.v_sync = mp_bswap_u64(port->sync);

	struct iproto_body_bin body = iproto_body_bin;
	body.v_data_len = mp_bswap_u32(port->found);

	char *pos = (char *) obuf_svp_to_ptr(port->buf, &port->svp);
	memcpy(pos, &header, sizeof(header));
	memcpy(pos + sizeof(header), &body, sizeof(body));
}

static inline void
iproto_port_add_tuple(struct port *ptr, struct tuple *tuple)
{
	struct iproto_port *port = iproto_port(ptr);
	if (++port->found == 1) {
		/* Found the first tuple, add header. */
		port->svp = obuf_book(port->buf, SVP_SIZE);
		port->size += SVP_SIZE;
	}
	tuple_to_obuf(tuple, port->buf);
	port->size += tuple->bsize;
}

struct port_vtab iproto_port_vtab = {
	iproto_port_add_tuple,
	iproto_port_eof,
};
<|endoftext|>


<commit_before>#include "TextureLoader.h"

TextureLoader::TextureLoader(std::string const & url) :
m_objectsTexture(new sf::Texture()),
m_floorTexture(new sf::Texture()),
m_characterTexture(new sf::Texture())
{
	loadTexture(url);
}

TextureLoader::~TextureLoader()
{
	delete(m_floorTexture);
	delete(m_objectsTexture);
	delete(m_characterTexture);
}

sf::Texture * TextureLoader::getFloorTexture() const
{
	return m_floorTexture;
}

sf::Texture * TextureLoader::getObjectsTexture() const
{
	return m_objectsTexture;
}

sf::Texture * TextureLoader::getCharacterTexture() const
{
	return m_characterTexture;
}

//On passe l'url du dossier de Textures
void TextureLoader::loadTexture(std::string const & url)
{
	if(!m_floorTexture->loadFromFile((url + "floor/tileset.png").c_str()))
    {
		std::cerr << "Error when loading the texture of the floor" << std::endl;
        throw LoadingErrorException;
    }

	if(!m_objectsTexture->loadFromFile((url + "objects/.png").c_str()))
    {
		std::cerr << "Error when loading the texture of the objects" << std::endl;
        throw LoadingErrorException;
    }

	if(!m_characterTexture->loadFromFile((url + "character/.png").c_str()))
    {
		std::cerr << "Error when loading the texture of the character" << std::endl;
        throw LoadingErrorException;
    }
}
<commit_msg>tileset pour le mobilier<commit_after>#include "TextureLoader.h"

TextureLoader::TextureLoader(std::string const & url) :
m_objectsTexture(new sf::Texture()),
m_floorTexture(new sf::Texture()),
m_characterTexture(new sf::Texture())
{
	loadTexture(url);
}

TextureLoader::~TextureLoader()
{
	delete(m_floorTexture);
	delete(m_objectsTexture);
	delete(m_characterTexture);
}

sf::Texture * TextureLoader::getFloorTexture() const
{
	return m_floorTexture;
}

sf::Texture * TextureLoader::getObjectsTexture() const
{
	return m_objectsTexture;
}

sf::Texture * TextureLoader::getCharacterTexture() const
{
	return m_characterTexture;
}

//On passe l'url du dossier de Textures
void TextureLoader::loadTexture(std::string const & url)
{
	if(!m_floorTexture->loadFromFile((url + "floor/tileset.png").c_str()))
    {
		std::cerr << "Error when loading the texture of the floor" << std::endl;
        throw LoadingErrorException;
    }

	if(!m_objectsTexture->loadFromFile((url + "mobilier/tileset.png").c_str()))
    {
		std::cerr << "Error when loading the texture of the objects" << std::endl;
        throw LoadingErrorException;
    }

	if(!m_characterTexture->loadFromFile((url + "character/.png").c_str()))
    {
		std::cerr << "Error when loading the texture of the character" << std::endl;
        throw LoadingErrorException;
    }
}
<|endoftext|>


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

#include "paddle/fluid/framework/details/computation_op_handle.h"

#include <string>

namespace paddle {
namespace framework {
namespace details {
ComputationOpHandle::ComputationOpHandle(const OpDesc &op_desc, Scope *scope,
                                         platform::Place place)
    : op_(framework::OpRegistry::CreateOp(op_desc)),
      scope_(scope),
      place_(place) {}

void ComputationOpHandle::RunImpl() {
  WaitInputVarGenerated(place_);

  this->RunAndRecordEvent([this] {
    VLOG(3) << "begin run op type is " << op_->Type();
    op_->Run(*scope_->FindVar(kLocalExecScopeName)->Get<Scope *>(), place_);
    VLOG(3) << "end run op type is " << op_->Type();
  });
}

bool ComputationOpHandle::NeedWait(VarHandleBase *in_var) {
  bool need_wait =
      in_var && in_var->generated_op_ &&
      in_var->generated_op_->DeviceContext(place_) != dev_ctxes_[place_];
  return need_wait;
}

std::string ComputationOpHandle::Name() const { return op_->Type(); }
}  // namespace details
}  // namespace framework
}  // namespace paddle
<commit_msg>update<commit_after>//   Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "paddle/fluid/framework/details/computation_op_handle.h"

#include <string>

namespace paddle {
namespace framework {
namespace details {
ComputationOpHandle::ComputationOpHandle(const OpDesc &op_desc, Scope *scope,
                                         platform::Place place)
    : op_(framework::OpRegistry::CreateOp(op_desc)),
      scope_(scope),
      place_(place) {}

void ComputationOpHandle::RunImpl() {
  WaitInputVarGenerated(place_);

  this->RunAndRecordEvent([this] {
    op_->Run(*scope_->FindVar(kLocalExecScopeName)->Get<Scope *>(), place_);
  });
}

bool ComputationOpHandle::NeedWait(VarHandleBase *in_var) {
  bool need_wait =
      in_var && in_var->generated_op_ &&
      in_var->generated_op_->DeviceContext(place_) != dev_ctxes_[place_];
  return need_wait;
}

std::string ComputationOpHandle::Name() const { return op_->Type(); }
}  // namespace details
}  // namespace framework
}  // namespace paddle
<|endoftext|>


<commit_before><commit_msg>legion: Minor fix for replaying mapper outputs<commit_after><|endoftext|>


<commit_before><commit_msg>INTEGRATION: CWS tl01 (1.7.262); FILE MERGED 2004/02/11 14:57:29 gt 1.7.262.2: RESYNC: (1.7-1.8); FILE MERGED 2003/10/07 14:33:37 dr 1.7.262.1: #112060# Hangul/Hanja Conversion in Calc<commit_after><|endoftext|>


<commit_before><commit_msg>INTEGRATION: CWS c09tosrc (1.35.90); FILE MERGED 2007/06/20 13:37:39 rt 1.35.90.2: Remove warnings. 2007/06/20 11:29:17 cd 1.35.90.1: #i78694# Calc must support XTransferableSupplier interface<commit_after><|endoftext|>


<commit_before>/* bzflag
 * Copyright (c) 1993 - 2005 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

/* interface header */
#include "Roaming.h"

/* common headers */
#include "BZDBCache.h"
#include "AnsiCodes.h"

/* local headers */
#include "ScoreboardRenderer.h"

// initialize the singleton
template <>
Roaming* Singleton<Roaming>::_instance = (Roaming*)0;

Roaming::Roaming() : view(roamViewDisabled),
		     targetManual(-1),
		     targetWinner(-1),
		     targetFlag(-1) {
  resetCamera();
}

void Roaming::resetCamera(void) {
  camera.pos[0] = 0.0f;
  camera.pos[1] = 0.0f;
  camera.pos[2] = BZDB.eval(StateDatabase::BZDB_MUZZLEHEIGHT);
  camera.theta = 0.0f;
  camera.zoom = 60.0f;
  camera.phi = -0.0f;
}

void Roaming::setCamera(RoamingCamera* newCam) {
  memcpy(&camera, newCam, sizeof(RoamingCamera));
}

void Roaming::setMode(RoamingView newView) {
  if (!(LocalPlayer::getMyTank() || devDriving)) {
    view = newView;
  } else if (LocalPlayer::getMyTank()->getTeam() == ObserverTeam) {
    // disallow disabling roaming in observer mode
    if ((newView == roamViewDisabled) && !devDriving)
      view = (RoamingView)(roamViewDisabled + 1);
    else
      view = newView;
  } else {
    // don't allow roaming for non-observers
    if (newView != roamViewDisabled)
      view = roamViewDisabled;
    else
      view = newView;
  }
  // make sure we have a valid target
  changeTarget(next);
  changeTarget(previous);
}

void Roaming::changeTarget(Roaming::RoamingTarget target, int explicitIndex) {
  bool found = false;

  World* world = World::getWorld();
  if (!world) {
    DEBUG4("Roaming::changeTarget() no world, switching to free roaming\n");
    view = roamViewFree;
    buildRoamingLabel();
    return;
  }

  if (view == roamViewFree || view == roamViewDisabled) {
    // do nothing
    found = true;
  } else if (view == roamViewFlag) {
    if (target == explicitSet) {
      targetFlag = explicitIndex;
      found = true;
    } else {
      int i, j;
      const int maxFlags = world->getMaxFlags();
      for (i = 1; i < maxFlags; ++i) {
	if (target == next) {
	  j = (targetFlag + i) % maxFlags;
	} else if (target == previous) {
	  j = (targetFlag - i + maxFlags) % maxFlags;
	}
	const Flag& flag = world->getFlag(j);
	if (flag.type->flagTeam != NoTeam) {
	  targetFlag = j;
	  found = true;
	  break;
	}
      }
    }
  } else {
    if (target == explicitSet) {
      targetManual = targetWinner = explicitIndex;
      found = true;
    } else {
      int i, j;
      for (i = 0; i < world->getCurMaxPlayers(); ++i) {
	if (target == next) {
	  j = (targetManual + i + 2) % (world->getCurMaxPlayers() + 1) - 1;
	} else if (target == previous) {
	  j = (targetManual - i + world->getCurMaxPlayers() + 1) % (world->getCurMaxPlayers() + 1) - 1;
	}
	if ((j == -1)
	    || (world->getPlayer(j)
		&& (world->getPlayer(j)->getTeam() != ObserverTeam)
		&& world->getPlayer(j)->isAlive())) {
	  targetManual = targetWinner = j;
	  found = true;
	  break;
	}
      }
    }
  }

  if (!found)
    view = roamViewFree;

  buildRoamingLabel();
}

void Roaming::buildRoamingLabel(void) {
  std::string playerString = "";

  World* world = World::getWorld();

  // follow the important tank
  if (targetManual == -1) {
    Player* top = NULL;
    if (world && world->allowRabbit()) {
      // follow the white rabbit
      top = world->getCurrentRabbit();
      if (top != NULL) {
	playerString = "Rabbit ";
	targetWinner = top->getId();
      }
    }
    if (top == NULL) {
      // find the leader
      top = ScoreboardRenderer::getLeader(&playerString);
      if (top == NULL) {
	targetWinner = 0;
      } else {
	targetWinner = top->getId();
      }
    }
  }

  Player* tracked = NULL;
  if (!devDriving) {
    if (world) {
      tracked = world->getPlayer(targetWinner);
    }
  } else {
    tracked = LocalPlayer::getMyTank();
  }

  if (world && tracked) {
    if (BZDBCache::colorful) {
      int color = tracked->getTeam();
      if (world->allowRabbit() && (color == RogueTeam)) {
	// hunters are orange (hack)
	color = OrangeColor;
      } else if (color < 0 || color > 4) {
	// non-teamed, rabbit are white (same as observer)
	color = WhiteColor;
      }
      playerString += ColorStrings[color];
    }
    playerString += tracked->getCallSign();

    const FlagType* flag = tracked->getFlag();
    if (flag != Flags::Null) {
      if (BZDBCache::colorful) {
	playerString += ColorStrings[CyanColor] + " / ";
	if (flag->flagTeam != NoTeam) {
	  playerString += ColorStrings[flag->flagTeam];
	} else {
	  playerString += ColorStrings[WhiteColor];
	}
      } else {
	playerString += " / ";
      }
      if (flag->endurance == FlagNormal) {
	playerString += flag->flagName;
      } else {
	playerString += flag->flagAbbv;
      }
    }

    switch (view) {
      case roamViewTrack: {
	roamingLabel = "Tracking " + playerString;
	break;
      }
      case roamViewFollow: {
	roamingLabel = "Following " + playerString;
	break;
      }
      case roamViewFP: {
	roamingLabel = "Driving with " + playerString;
	break;
      }
      case roamViewFlag: {
	roamingLabel = std::string("Tracking ")
	  + world->getFlag(targetFlag).type->flagName + " Flag";
	break;
      }
      default: {
	roamingLabel = "Roaming";
	break;
      }
    }
  } else {
    roamingLabel = "Roaming";
  }
}

void Roaming::updatePosition(RoamingCamera* dc, float dt) {
  World* world = World::getWorld();

  // are we tracking?
  bool tracking = false;
  const float* trackPos;
  if (view == roamViewTrack) {
    Player *target;
    if (!devDriving) {
      if (world && (targetWinner < world->getCurMaxPlayers())) {
	target = world->getPlayer(targetWinner);
      } else {
	target = NULL;
      }
    } else {
      target = LocalPlayer::getMyTank();
    }
    if (target != NULL) {
      trackPos = target->getPosition();
      tracking = true;
    }
  }
  else if (view == roamViewFlag) {
    if ((world != NULL) && (targetFlag < world->getMaxFlags())) {
      Flag &flag = world->getFlag(targetFlag);
      trackPos = flag.position;
      tracking = true;
    }
  }

  // modify X and Y coords
  if (!tracking) {
    const float c = cosf(camera.theta * (float)(M_PI / 180.0f));
    const float s = sinf(camera.theta * (float)(M_PI / 180.0f));
    camera.pos[0] += dt * (c * dc->pos[0] - s * dc->pos[1]);
    camera.pos[1] += dt * (c * dc->pos[1] + s * dc->pos[0]);
    camera.theta  += dt * dc->theta;
    camera.phi    += dt * dc->phi;
  } else {
    float dx = camera.pos[0] - trackPos[0];
    float dy = camera.pos[1] - trackPos[1];
    float dist = sqrtf((dx * dx) + (dy * dy));

    float nomDist = 4.0f * BZDBCache::tankSpeed;
    if (nomDist == 0.0f) {
      nomDist = 100.0f;
    }
    float distFactor =  (dist / nomDist);
    if (distFactor < 0.25f) {
      distFactor = 0.25f;
    }
    float newDist = dist - (dt * distFactor * dc->pos[0]);

    const float minDist = BZDBCache::tankLength * 0.5f;
    if (newDist < minDist) {
      if (dist >= minDist) {
	newDist = minDist;
      } else {
	newDist = dist;
      }
    }
    float scale = 0.0f;
    if (dist > 0.0f) {
      scale = newDist / dist;
    }
    dx = dx * scale;
    dy = dy * scale;
    if (fabsf(dx) < 0.001f) dx = 0.001f;
    if (fabsf(dy) < 0.001f) dy = 0.001f;
    const float dtheta = -(dt * dc->theta * (float)(M_PI / 180.0f));
    const float c = cosf(dtheta);
    const float s = sinf(dtheta);
    camera.pos[0] = trackPos[0] + ((c * dx) - (s * dy));
    camera.pos[1] = trackPos[1] + ((c * dy) + (s * dx));
    // setup so that free roam stays in the last state
    camera.theta = atan2f(trackPos[1] - camera.pos[1], trackPos[0] - camera.pos[0]);
    camera.theta *= (float)(180.0f / M_PI);
    camera.phi = atan2f(trackPos[2] - camera.pos[2], newDist);
    camera.phi *= (float)(180.0f / M_PI);
  }

  // modify Z coordinate
  camera.pos[2] += dt * dc->pos[2];
  float muzzleHeight = BZDB.eval(StateDatabase::BZDB_MUZZLEHEIGHT);
  if (camera.pos[2] < muzzleHeight) {
    camera.pos[2] = muzzleHeight;
    dc->pos[2] = 0.0f;
  }

  // adjust zoom
  camera.zoom += dt * dc->zoom;
  if (camera.zoom < BZDB.eval("roamZoomMin")) {
    camera.zoom = BZDB.eval("roamZoomMin");
  }
  else if (camera.zoom > BZDB.eval("roamZoomMax")) {
    camera.zoom = BZDB.eval("roamZoomMax");
  }
}

// Local Variables: ***
// mode: C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8
<commit_msg>looser observer selection, better for admining<commit_after>/* bzflag
 * Copyright (c) 1993 - 2005 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

/* interface header */
#include "Roaming.h"

/* common headers */
#include "BZDBCache.h"
#include "AnsiCodes.h"

/* local headers */
#include "ScoreboardRenderer.h"

// initialize the singleton
template <>
Roaming* Singleton<Roaming>::_instance = (Roaming*)0;

Roaming::Roaming() : view(roamViewDisabled),
		     targetManual(-1),
		     targetWinner(-1),
		     targetFlag(-1) {
  resetCamera();
}

void Roaming::resetCamera(void) {
  camera.pos[0] = 0.0f;
  camera.pos[1] = 0.0f;
  camera.pos[2] = BZDB.eval(StateDatabase::BZDB_MUZZLEHEIGHT);
  camera.theta = 0.0f;
  camera.zoom = 60.0f;
  camera.phi = -0.0f;
}

void Roaming::setCamera(RoamingCamera* newCam) {
  memcpy(&camera, newCam, sizeof(RoamingCamera));
}

void Roaming::setMode(RoamingView newView) {
  if (!(LocalPlayer::getMyTank() || devDriving)) {
    view = newView;
  } else if (LocalPlayer::getMyTank()->getTeam() == ObserverTeam) {
    // disallow disabling roaming in observer mode
    if ((newView == roamViewDisabled) && !devDriving)
      view = (RoamingView)(roamViewDisabled + 1);
    else
      view = newView;
  } else {
    // don't allow roaming for non-observers
    if (newView != roamViewDisabled)
      view = roamViewDisabled;
    else
      view = newView;
  }
  // make sure we have a valid target
  changeTarget(next);
  changeTarget(previous);
}

void Roaming::changeTarget(Roaming::RoamingTarget target, int explicitIndex) {
  bool found = false;

  World* world = World::getWorld();
  if (!world) {
    DEBUG4("Roaming::changeTarget() no world, switching to free roaming\n");
    view = roamViewFree;
    buildRoamingLabel();
    return;
  }

  if (view == roamViewFree || view == roamViewDisabled) {
    // do nothing
    found = true;
  } else if (view == roamViewFlag) {
    if (target == explicitSet) {
      targetFlag = explicitIndex;
      found = true;
    } else {
      int i, j;
      const int maxFlags = world->getMaxFlags();
      for (i = 1; i < maxFlags; ++i) {
	if (target == next) {
	  j = (targetFlag + i) % maxFlags;
	} else if (target == previous) {
	  j = (targetFlag - i + maxFlags) % maxFlags;
	}
	const Flag& flag = world->getFlag(j);
	if (flag.type->flagTeam != NoTeam) {
	  targetFlag = j;
	  found = true;
	  break;
	}
      }
    }
  } else {
    if (target == explicitSet) {
      targetManual = targetWinner = explicitIndex;
      found = true;
    } else {
      int i, j;
      for (i = 0; i < world->getCurMaxPlayers(); ++i) {
	if (target == next) {
	  j = (targetManual + i + 2) % (world->getCurMaxPlayers() + 1) - 1;
	} else if (target == previous) {
	  j = (targetManual - i + world->getCurMaxPlayers() + 1) % (world->getCurMaxPlayers() + 1) - 1;
	}
	if ((j == -1) ||
	    (world->getPlayer(j) && (world->getPlayer(j)->getTeam() != ObserverTeam))) {
	  targetManual = targetWinner = j;
	  found = true;
	  break;
	}
      }
    }
  }

  if (!found)
    view = roamViewFree;

  buildRoamingLabel();
}

void Roaming::buildRoamingLabel(void) {
  std::string playerString = "";

  World* world = World::getWorld();

  // follow the important tank
  if (targetManual == -1) {
    Player* top = NULL;
    if (world && world->allowRabbit()) {
      // follow the white rabbit
      top = world->getCurrentRabbit();
      if (top != NULL) {
	playerString = "Rabbit ";
	targetWinner = top->getId();
      }
    }
    if (top == NULL) {
      // find the leader
      top = ScoreboardRenderer::getLeader(&playerString);
      if (top == NULL) {
	targetWinner = 0;
      } else {
	targetWinner = top->getId();
      }
    }
  }

  Player* tracked = NULL;
  if (!devDriving) {
    if (world) {
      tracked = world->getPlayer(targetWinner);
    }
  } else {
    tracked = LocalPlayer::getMyTank();
  }

  if (world && tracked) {
    if (BZDBCache::colorful) {
      int color = tracked->getTeam();
      if (world->allowRabbit() && (color == RogueTeam)) {
	// hunters are orange (hack)
	color = OrangeColor;
      } else if (color < 0 || color > 4) {
	// non-teamed, rabbit are white (same as observer)
	color = WhiteColor;
      }
      playerString += ColorStrings[color];
    }
    playerString += tracked->getCallSign();

    const FlagType* flag = tracked->getFlag();
    if (flag != Flags::Null) {
      if (BZDBCache::colorful) {
	playerString += ColorStrings[CyanColor] + " / ";
	if (flag->flagTeam != NoTeam) {
	  playerString += ColorStrings[flag->flagTeam];
	} else {
	  playerString += ColorStrings[WhiteColor];
	}
      } else {
	playerString += " / ";
      }
      if (flag->endurance == FlagNormal) {
	playerString += flag->flagName;
      } else {
	playerString += flag->flagAbbv;
      }
    }

    switch (view) {
      case roamViewTrack: {
	roamingLabel = "Tracking " + playerString;
	break;
      }
      case roamViewFollow: {
	roamingLabel = "Following " + playerString;
	break;
      }
      case roamViewFP: {
	roamingLabel = "Driving with " + playerString;
	break;
      }
      case roamViewFlag: {
	roamingLabel = std::string("Tracking ")
	  + world->getFlag(targetFlag).type->flagName + " Flag";
	break;
      }
      default: {
	roamingLabel = "Roaming";
	break;
      }
    }
  } else {
    roamingLabel = "Roaming";
  }
}

void Roaming::updatePosition(RoamingCamera* dc, float dt) {
  World* world = World::getWorld();

  // are we tracking?
  bool tracking = false;
  const float* trackPos;
  if (view == roamViewTrack) {
    Player *target;
    if (!devDriving) {
      if (world && (targetWinner < world->getCurMaxPlayers())) {
	target = world->getPlayer(targetWinner);
      } else {
	target = NULL;
      }
    } else {
      target = LocalPlayer::getMyTank();
    }
    if (target != NULL) {
      trackPos = target->getPosition();
      tracking = true;
    }
  }
  else if (view == roamViewFlag) {
    if ((world != NULL) && (targetFlag < world->getMaxFlags())) {
      Flag &flag = world->getFlag(targetFlag);
      trackPos = flag.position;
      tracking = true;
    }
  }

  // modify X and Y coords
  if (!tracking) {
    const float c = cosf(camera.theta * (float)(M_PI / 180.0f));
    const float s = sinf(camera.theta * (float)(M_PI / 180.0f));
    camera.pos[0] += dt * (c * dc->pos[0] - s * dc->pos[1]);
    camera.pos[1] += dt * (c * dc->pos[1] + s * dc->pos[0]);
    camera.theta  += dt * dc->theta;
    camera.phi    += dt * dc->phi;
  } else {
    float dx = camera.pos[0] - trackPos[0];
    float dy = camera.pos[1] - trackPos[1];
    float dist = sqrtf((dx * dx) + (dy * dy));

    float nomDist = 4.0f * BZDBCache::tankSpeed;
    if (nomDist == 0.0f) {
      nomDist = 100.0f;
    }
    float distFactor =  (dist / nomDist);
    if (distFactor < 0.25f) {
      distFactor = 0.25f;
    }
    float newDist = dist - (dt * distFactor * dc->pos[0]);

    const float minDist = BZDBCache::tankLength * 0.5f;
    if (newDist < minDist) {
      if (dist >= minDist) {
	newDist = minDist;
      } else {
	newDist = dist;
      }
    }
    float scale = 0.0f;
    if (dist > 0.0f) {
      scale = newDist / dist;
    }
    dx = dx * scale;
    dy = dy * scale;
    if (fabsf(dx) < 0.001f) dx = 0.001f;
    if (fabsf(dy) < 0.001f) dy = 0.001f;
    const float dtheta = -(dt * dc->theta * (float)(M_PI / 180.0f));
    const float c = cosf(dtheta);
    const float s = sinf(dtheta);
    camera.pos[0] = trackPos[0] + ((c * dx) - (s * dy));
    camera.pos[1] = trackPos[1] + ((c * dy) + (s * dx));
    // setup so that free roam stays in the last state
    camera.theta = atan2f(trackPos[1] - camera.pos[1], trackPos[0] - camera.pos[0]);
    camera.theta *= (float)(180.0f / M_PI);
    camera.phi = atan2f(trackPos[2] - camera.pos[2], newDist);
    camera.phi *= (float)(180.0f / M_PI);
  }

  // modify Z coordinate
  camera.pos[2] += dt * dc->pos[2];
  float muzzleHeight = BZDB.eval(StateDatabase::BZDB_MUZZLEHEIGHT);
  if (camera.pos[2] < muzzleHeight) {
    camera.pos[2] = muzzleHeight;
    dc->pos[2] = 0.0f;
  }

  // adjust zoom
  camera.zoom += dt * dc->zoom;
  if (camera.zoom < BZDB.eval("roamZoomMin")) {
    camera.zoom = BZDB.eval("roamZoomMin");
  }
  else if (camera.zoom > BZDB.eval("roamZoomMax")) {
    camera.zoom = BZDB.eval("roamZoomMax");
  }
}

// Local Variables: ***
// mode: C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8
<|endoftext|>