<commit_before>/* Copyright 2019 Benjamin Worpitz, Erik Zenker, Matthias Werner
 *
 * This file is part of Alpaka.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#pragma once

#ifdef ALPAKA_ACC_CPU_BT_OMP4_ENABLED

#if _OPENMP < 201307
    #error If ALPAKA_ACC_CPU_BT_OMP4_ENABLED is set, the compiler has to support OpenMP 4.0 or higher!
#endif

#include <alpaka/dev/DevOmp4.hpp>
#include <alpaka/kernel/TaskKernelCpuOmp4.hpp>
#include <alpaka/queue/QueueOmp4Blocking.hpp>

#include <alpaka/core/Assert.hpp>
#include <alpaka/dim/DimIntegralConst.hpp>
#include <alpaka/extent/Traits.hpp>
#include <alpaka/mem/view/Traits.hpp>
#include <alpaka/meta/Integral.hpp>
#include <alpaka/vec/Vec.hpp>
#include <alpaka/core/Assert.hpp>
#include <alpaka/idx/Accessors.hpp>
#include <alpaka/workdiv/WorkDivHelpers.hpp>

#include <cstring>

namespace alpaka
{
    namespace dev
    {
        class DevOmp4;
    }
}

namespace alpaka
{
    namespace mem
    {
        namespace view
        {
            namespace omp4
            {
                namespace detail
                {
                    //#############################################################################
                    //! The OMP4 device ND memory set kernel.
                    class MemSetKernel
                    {
                    public:
                        //-----------------------------------------------------------------------------
                        //! The kernel entry point.
                        //!
                        //! \tparam TAcc The accelerator environment to be executed on.
                        //! \tparam TElem element type.
                        //! \tparam TExtent extent type.
                        //! \param acc The accelerator to be executed on.
                        //! \param val value to set.
                        //! \param dst target mem ptr.
                        //! \param extent area to set.
                        ALPAKA_NO_HOST_ACC_WARNING
                        template<
                            typename TAcc,
                            typename TElem,
                            typename TExtent>
                        ALPAKA_FN_ACC auto operator()(
                            TAcc const & acc,
                            TElem const val,
                            TElem * dst,
                            TExtent extent) const
                        -> void
                        {
                            using Idx = typename idx::traits::IdxType<TAcc>::type;
                            Idx const gridThreadIdx(alpaka::idx::getIdx<alpaka::Grid, alpaka::Threads>(acc));
                            Idx const threadElemExtent(alpaka::workdiv::getWorkDiv<alpaka::Thread, alpaka::Elems>(acc));
                            Idx const idxThreadFirstElem = getIdxThreadFirstElem(acc, gridThreadIdx, threadElemExtent);
                            const auto idx = idxThreadFirstElem.prod();
                            constexpr auto lastDim = dim::Dim<TAcc>::value - 1;
                            const auto lastIdx = std::min(idx + threadElemExtent[lastDim], extent[lastDim]);

                            if(idx < extent.prod())
                            {
                                // assuming elements = {1,1,1,...,n}
                                for(; idx<lastIdx; ++idx)
                                {
                                    dst[idx] = val;
                                }
                            }
                        }
                    };
                }
            }

            namespace traits
            {
                //#############################################################################
                //! The OMP4 device memory set trait specialization.
                template<
                    typename TDim>
                struct CreateTaskSet<
                    TDim,
                    dev::DevOmp4>
                {
                    using Idx = std::size_t;
                    //-----------------------------------------------------------------------------
                    template<
                        typename TExtent,
                        typename TView>
                    ALPAKA_FN_HOST static auto createTaskSet(
                        TView & view,
                        std::uint8_t const & byte,
                        TExtent const & extent)
                    -> kernel::TaskKernelCpuOmp4<
                        TDim,
                        Idx,
                        view::omp4::detail::MemSetKernel,
                        std::uint8_t,
                        vec::Vec<Idx, TDim>
                        >
                    {
                        auto elementsPerThread = vec::Vec<Idx, TDim>::all(1u);
                        elementsPerThread[TDim::value-1] = 4;
                        // Let alpaka calculate good block and grid sizes given our full problem extent
                        alpaka::workdiv::WorkDivMembers<TDim, Idx> const workDiv(
                            alpaka::workdiv::getValidWorkDiv<acc::AccCpuOmp4<TDim,Idx>>(
                                dev::getDev(view),
                                extent,
                                elementsPerThread,
                                false,
                                alpaka::workdiv::GridBlockExtentSubDivRestrictions::Unrestricted));
                        return
                            kernel::createTaskKernel<acc::AccCpuOmp4<TDim,Idx>>(
                                    workDiv,
                                    view::omp4::detail::MemSetKernel(),
                                    byte,
                                    alpaka::mem::view::getPtrNative(view),
                                    extent
                                    );
                    }
                };
            }
        }
    }
}

#endif
<commit_msg>omp4: Fix mem/buf/Set<commit_after>/* Copyright 2019 Benjamin Worpitz, Erik Zenker, Matthias Werner
 *
 * This file is part of Alpaka.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#pragma once

#ifdef ALPAKA_ACC_CPU_BT_OMP4_ENABLED

#if _OPENMP < 201307
    #error If ALPAKA_ACC_CPU_BT_OMP4_ENABLED is set, the compiler has to support OpenMP 4.0 or higher!
#endif

#include <alpaka/dev/DevOmp4.hpp>
#include <alpaka/kernel/TaskKernelCpuOmp4.hpp>
#include <alpaka/queue/QueueOmp4Blocking.hpp>

#include <alpaka/core/Assert.hpp>
#include <alpaka/dim/DimIntegralConst.hpp>
#include <alpaka/extent/Traits.hpp>
#include <alpaka/mem/view/Traits.hpp>
#include <alpaka/meta/Integral.hpp>
#include <alpaka/vec/Vec.hpp>
#include <alpaka/extent/Traits.hpp>
#include <alpaka/core/Assert.hpp>
#include <alpaka/idx/Accessors.hpp>
#include <alpaka/workdiv/WorkDivHelpers.hpp>

#include <cstring>

namespace alpaka
{
    namespace dev
    {
        class DevOmp4;
    }
}

namespace alpaka
{
    namespace mem
    {
        namespace view
        {
            namespace omp4
            {
                namespace detail
                {
                    //#############################################################################
                    //! The OMP4 device ND memory set kernel.
                    class MemSetKernel
                    {
                    public:
                        //-----------------------------------------------------------------------------
                        //! The kernel entry point.
                        //!
                        //! \tparam TAcc The accelerator environment to be executed on.
                        //! \tparam TElem element type.
                        //! \tparam TExtent extent type.
                        //! \param acc The accelerator to be executed on.
                        //! \param val value to set.
                        //! \param dst target mem ptr.
                        //! \param extent area to set.
                        ALPAKA_NO_HOST_ACC_WARNING
                        template<
                            typename TAcc,
                            typename TElem,
                            typename TExtent>
                        ALPAKA_FN_ACC auto operator()(
                            TAcc const & acc,
                            TElem const val,
                            TElem * dst,
                            TExtent extent) const
                        -> void
                        {
                            auto const gridThreadIdx(alpaka::idx::getIdx<alpaka::Grid, alpaka::Threads>(acc));
                            auto const threadElemExtent(alpaka::workdiv::getWorkDiv<alpaka::Thread, alpaka::Elems>(acc));
                            auto const idxThreadFirstElem = idx::getIdxThreadFirstElem(acc, gridThreadIdx, threadElemExtent);
                            auto idx = idxThreadFirstElem.prod();
                            constexpr auto lastDim = dim::Dim<TAcc>::value - 1;
                            const auto lastIdx = std::min(idx + threadElemExtent[lastDim], extent[lastDim]);

                            if(idx < extent.prod())
                            {
                                // assuming elements = {1,1,1,...,n}
                                for(; idx<lastIdx; ++idx)
                                {
                                    dst[idx] = val;
                                }
                            }
                        }
                    };
                }
            }

            namespace traits
            {
                //#############################################################################
                //! The OMP4 device memory set trait specialization.
                template<
                    typename TDim>
                struct CreateTaskSet<
                    TDim,
                    dev::DevOmp4>
                {
                    using Idx = std::size_t;
                    //-----------------------------------------------------------------------------
                    template<
                        typename TExtent,
                        typename TView>
                    ALPAKA_FN_HOST static auto createTaskSet(
                        TView & view,
                        std::uint8_t const & byte,
                        TExtent const & extent)
                    -> kernel::TaskKernelCpuOmp4<
                        TDim,
                        Idx,
                        view::omp4::detail::MemSetKernel,
                        std::uint8_t,
                        std::uint8_t*,
                        decltype(alpaka::extent::getExtentVec(extent))
                        >
                    {
                        auto elementsPerThread = vec::Vec<TDim, Idx>::all(1u);
                        elementsPerThread[TDim::value-1] = 4;
                        // Let alpaka calculate good block and grid sizes given our full problem extent
                        alpaka::workdiv::WorkDivMembers<TDim, Idx> const workDiv(
                            alpaka::workdiv::getValidWorkDiv<acc::AccCpuOmp4<TDim,Idx>>(
                                dev::getDev(view),
                                extent,
                                elementsPerThread,
                                false,
                                alpaka::workdiv::GridBlockExtentSubDivRestrictions::Unrestricted));
                        return
                            kernel::createTaskKernel<acc::AccCpuOmp4<TDim,Idx>>(
                                    workDiv,
                                    view::omp4::detail::MemSetKernel(),
                                    byte,
                                    reinterpret_cast<std::uint8_t*>(alpaka::mem::view::getPtrNative(view)),
                                    alpaka::extent::getExtentVec(extent)
                                    );
                    }
                };
            }
        }
    }
}

#endif
<|endoftext|>


<commit_before>/* mk_baseline_wplane_map.cpp

  Copyright (C) 2015 Braam Research, LLC.
 */

#include <omp.h>
#include <string.h>

#include "common.h"
#include "OskarBinReader.h"

void mkBlWpMap(const WMaxMin * bl_ws, int numBaselines, double wstep, BlWMap * bl_wis)
{
  double cmax, cmin;
  for (int i = 0; i < numBaselines; i++) {
    cmax = bl_ws[i].maxw/wstep;
    cmin = bl_ws[i].minw/wstep;
    bl_wis[i].bl = i;
    /*
    if (cmax > 0.0)
      bl_wis[i].wp = round(cmax);
    else if (cmin < 0.0)
      bl_wis[i].wp = round(cmin);
    else
      bl_wis[i].wp = 0;
     */
    // Use minimum instead of maximum
    // to make things easier at the moment,
    // because this determines max support handled by
    // threadblock in Romein-like algorithm and if it
    // is greater than that determined by current data point
    // we point to nonsensical GCF data.
    if (cmax < 0.0)
      bl_wis[i].wp = int(round(cmax));
    else if (cmin > 0.0)
      bl_wis[i].wp = int(round(cmin));
    else
      bl_wis[i].wp = 0;
  }
}

long long count_points(BlWMap * m, int n){
  long long res = 0;
  for(int i = 0; i < n; i++) {
    int supp = get_supp(m[i].wp);
    res += supp * supp;
  }
  return res;
}

// This function is required to
//   correctly calculate GCF, namely we
//   need to know the correct w's mean value
//   for each w-plane.
void calcAccums(
    const Double3 uvw[]
  // We retain separate sum and num of points info
  //   because it is a valuable information
  , /*out*/ double sums[]
  , /*out*/ int npts[]
  , double wstep
  , int numDataPoints // baselines * channels * timesteps
  , int numOfWPlanes
  ) {
  int nthreads;

#pragma omp parallel
#pragma omp single
  nthreads = omp_get_num_threads();

  memset(sums, 0, sizeof(double) * numOfWPlanes);
  memset(npts, 0, sizeof(int) * numOfWPlanes);

  // VLAs. Requires GNU extension.
  double tmpsums[nthreads-1][numOfWPlanes];
  int tmpnpts[nthreads-1][numOfWPlanes];

  #pragma omp parallel
  {
    int _thread = omp_get_thread_num();
    double * _sums;
    int * _npts;
    if (_thread == 0) {
      _sums = sums;
      _npts = npts;
    } else {
      _sums = tmpsums[_thread - 1];
      _npts = tmpnpts[_thread - 1];
    }
    memset(_sums, 0, sizeof(double) * numOfWPlanes);
    memset(_npts, 0, sizeof(int) * numOfWPlanes);

    double w;
    int wplane;
    #pragma omp for schedule(dynamic)
    for(int n = 0; n < numDataPoints; n++) {
      w = uvw[n].w / wstep;
      wplane = int(round(w));
      _sums[wplane] += w;
      _npts[wplane]++;
    }
  }
  // Simple linear addition (it is faster than starting any threads here)
  // Don't use any fancy AVX tricks because of
  // a negligibility of the whole processing time.
  for(int i=0; i<nthreads-1; i++)
  for(int j=0; j<numOfWPlanes; j++) {
    sums[j] += tmpsums[i][j];
    npts[j] += tmpnpts[i][j];
  }
}
<commit_msg>W-means calculation fix (forgot that w is 0-centered).<commit_after>/* mk_baseline_wplane_map.cpp

  Copyright (C) 2015 Braam Research, LLC.
 */

#include <omp.h>
#include <string.h>

#include "common.h"
#include "OskarBinReader.h"

void mkBlWpMap(const WMaxMin * bl_ws, int numBaselines, double wstep, BlWMap * bl_wis)
{
  double cmax, cmin;
  for (int i = 0; i < numBaselines; i++) {
    cmax = bl_ws[i].maxw/wstep;
    cmin = bl_ws[i].minw/wstep;
    bl_wis[i].bl = i;
    /*
    if (cmax > 0.0)
      bl_wis[i].wp = round(cmax);
    else if (cmin < 0.0)
      bl_wis[i].wp = round(cmin);
    else
      bl_wis[i].wp = 0;
     */
    // Use minimum instead of maximum
    // to make things easier at the moment,
    // because this determines max support handled by
    // threadblock in Romein-like algorithm and if it
    // is greater than that determined by current data point
    // we point to nonsensical GCF data.
    if (cmax < 0.0)
      bl_wis[i].wp = int(round(cmax));
    else if (cmin > 0.0)
      bl_wis[i].wp = int(round(cmin));
    else
      bl_wis[i].wp = 0;
  }
}

long long count_points(BlWMap * m, int n){
  long long res = 0;
  for(int i = 0; i < n; i++) {
    int supp = get_supp(m[i].wp);
    res += supp * supp;
  }
  return res;
}

// This function is required to
//   correctly calculate GCF, namely we
//   need to know the correct w's mean value
//   for each w-plane.
void calcAccums(
    const Double3 uvw[]
  // We retain separate sum and num of points info
  //   because it is a valuable information
  , /*out*/ double sums[]
  , /*out*/ int npts[]
  , double wstep
  , int numDataPoints // baselines * channels * timesteps
  , int numOfWPlanes
  ) {
  int nthreads;
  int center = numOfWPlanes / 2;

#pragma omp parallel
#pragma omp single
  nthreads = omp_get_num_threads();

  memset(sums, 0, sizeof(double) * numOfWPlanes);
  memset(npts, 0, sizeof(int) * numOfWPlanes);

  // VLAs. Requires GNU extension.
  double tmpsums[nthreads-1][numOfWPlanes];
  int tmpnpts[nthreads-1][numOfWPlanes];

  #pragma omp parallel
  {
    int _thread = omp_get_thread_num();
    double * _sums;
    int * _npts;
    if (_thread == 0) {
      _sums = sums;
      _npts = npts;
    } else {
      _sums = tmpsums[_thread - 1];
      _npts = tmpnpts[_thread - 1];
    }
    memset(_sums, 0, sizeof(double) * numOfWPlanes);
    memset(_npts, 0, sizeof(int) * numOfWPlanes);

    // Center _sums and _npts
    _sums += center;
    _npts += center;
    double w;
    int wplane;
    #pragma omp for schedule(dynamic)
    for(int n = 0; n < numDataPoints; n++) {
      w = uvw[n].w / wstep;
      wplane = int(round(w));
      _sums[wplane] += w;
      _npts[wplane]++;
    }
  }
  // Simple linear addition (it is faster than starting any threads here)
  // Don't use any fancy AVX tricks because of
  // a negligibility of the whole processing time.
  for(int i=0; i<nthreads-1; i++)
  for(int j=0; j<numOfWPlanes; j++) {
    sums[j] += tmpsums[i][j];
    npts[j] += tmpnpts[i][j];
  }
}
<|endoftext|>


<commit_before>#include <stingray/stingraykit/stingraykit/time/NtpTimestamp.h>

namespace stingray
{

	NtpTimestamp::NtpTimestamp(const u64 timestamp) : _timestamp(timestamp) { }

	u64 NtpTimestamp::GetNtpTimestamp() const { return _timestamp; }

	Time NtpTimestamp::ToTime() const
	{
		u32 integerPart = _timestamp >> 32;
		u64 seconds = integerPart - DifferenceBetweenUnixNtpTime;

		u32 fractionPart = _timestamp - integerPart;
		u64 milliSeconds = fractionPart / (1UL << 32);

		return Time(seconds * 1000 + milliSeconds);
	};

	NtpTimestamp NtpTimestamp::FromTime(const Time& time)
	{
		u32 integerPart = time.GetMilliseconds() / 1000 +  DifferenceBetweenUnixNtpTime;
		u32 fractionPart = time.GetMilliseconds() / 1000 * (1UL << 32);

		u64 timestamp = ((u64)integerPart << 32) | fractionPart;

		return NtpTimestamp(timestamp);
	}

}
<commit_msg>Fixed warnings<commit_after>#include <stingray/stingraykit/stingraykit/time/NtpTimestamp.h>

namespace stingray
{

	NtpTimestamp::NtpTimestamp(const u64 timestamp) : _timestamp(timestamp) { }

	u64 NtpTimestamp::GetNtpTimestamp() const { return _timestamp; }

	Time NtpTimestamp::ToTime() const
	{
		u32 integerPart = _timestamp >> 32;
		u64 seconds = integerPart - DifferenceBetweenUnixNtpTime;

		u32 fractionPart = _timestamp - integerPart;
		u64 milliSeconds = fractionPart / ((u64)1 << 32);

		return Time(seconds * 1000 + milliSeconds);
	};

	NtpTimestamp NtpTimestamp::FromTime(const Time& time)
	{
		u32 integerPart = time.GetMilliseconds() / 1000 +  DifferenceBetweenUnixNtpTime;
		u32 fractionPart = time.GetMilliseconds() / 1000 * ((u64)1 << 32);

		u64 timestamp = ((u64)integerPart << 32) | fractionPart;

		return NtpTimestamp(timestamp);
	}

}
<|endoftext|>


<commit_before>#pragma once

#if (__cplusplus >= 201103L || \
     (defined(_MSC_VER) && _MSC_VER >= 1800))
#define BRYNET_HAVE_LANG_CXX11 1
#endif

#if (__cplusplus >= 201402L || \
     (defined(_MSC_VER) && _MSC_VER >= 1900))
#define BRYNET_HAVE_LANG_CXX14 1
#endif

#if (__cplusplus >= 201703L || \
     (defined(_MSC_VER) && _MSC_VER >= 1910))
#define BRYNET_HAVE_LANG_CXX17 1
#endif<commit_msg>Fix build(VS2017 without /std:c++17)<commit_after>#pragma once

#if (__cplusplus >= 201103L || \
     (defined(_MSC_VER) && _MSC_VER >= 1800))
#define BRYNET_HAVE_LANG_CXX11 1
#endif

#if (__cplusplus >= 201402L || \
     (defined(_MSC_VER) && _MSC_VER >= 1900))
#define BRYNET_HAVE_LANG_CXX14 1
#endif

#if (__cplusplus >= 201703L || \
     (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L))
#define BRYNET_HAVE_LANG_CXX17 1
#endif<|endoftext|>


<commit_before>/*
 Copyright (C) 2012 by Ivan Safrin

 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 "PolyUIVScrollBar.h"
#include "PolyConfig.h"
#include "PolyInputEvent.h"
#include "PolyLabel.h"
#include "PolyCoreServices.h"
#include "PolyCore.h"

using namespace Polycode;

UIVScrollBar::UIVScrollBar(Number width, Number height, Number initialRatio) : UIElement() {

	scrollValue = 0;

	Config *conf = CoreServices::getInstance()->getConfig();

	minHandleSize = conf->getNumericValue("Polycode", "uiScrollHandleMinSize");

	Number st = conf->getNumericValue("Polycode", "uiScrollBgSkinT");
	Number sr = conf->getNumericValue("Polycode", "uiScrollBgSkinR");
	Number sb = conf->getNumericValue("Polycode", "uiScrollBgSkinB");
	Number sl = conf->getNumericValue("Polycode", "uiScrollBgSkinL");
	padding = conf->getNumericValue("Polycode", "uiScrollBgSkinPadding");

	bgBox = new UIBox(conf->getStringValue("Polycode", "uiScrollBgSkin"),
					  st,sr,sb,sl,
					  width, height);

	bgBox->processInputEvents = true;
	bgBox->addEventListener(this, InputEvent::EVENT_MOUSEDOWN);
	bgBox->addEventListener(this, InputEvent::EVENT_MOUSEOVER);
	addChild(bgBox);

	st = conf->getNumericValue("Polycode", "uiScrollHandleSkinT");
	sr = conf->getNumericValue("Polycode", "uiScrollHandleSkinR");
	sb = conf->getNumericValue("Polycode", "uiScrollHandleSkinB");
	sl = conf->getNumericValue("Polycode", "uiScrollHandleSkinL");

	if(initialRatio > 1)
		initialRatio = 1;

	scrollHandleHeight = height*initialRatio;

	if(scrollHandleHeight < minHandleSize)
		scrollHandleHeight = minHandleSize;

	handleBox = new UIBox(conf->getStringValue("Polycode", "uiScrollHandleSkin"),
					  st,sr,sb,sl,
					  width-(padding*2),scrollHandleHeight);
	handleBox->setPosition(padding, padding);
	addChild(handleBox);

	handleBox->addEventListener(this, InputEvent::EVENT_MOUSEUP);
	handleBox->addEventListener(this, InputEvent::EVENT_MOUSEUP_OUTSIDE);
	handleBox->addEventListener(this, InputEvent::EVENT_MOUSEDOWN);
	handleBox->addEventListener(this, InputEvent::EVENT_MOUSEOVER);
	handleBox->processInputEvents = true;
	handleBox->blockMouseInput = true;

	dragRectHeight = height-(padding*2)-scrollHandleHeight;
	handleBox->setDragLimits(Rectangle(padding,padding,width-(padding*2)-(width-(padding*2)), dragRectHeight));

	lastPositionY = handleBox->getPosition().y;

	setHeight(height);
	setWidth(width);

	tickSize = 0.01;
}

void UIVScrollBar::Resize(int newHeight) {
	bgBox->resizeBox(getWidth(), newHeight);
	setHeight(newHeight);
	dragRectHeight = getHeight()-(padding*2)-scrollHandleHeight;
	handleBox->setDragLimits(Rectangle(padding,padding,getWidth()-(padding*2)-(getWidth()-(padding*2)), dragRectHeight));
}

void UIVScrollBar::Update() {

	if(lastPositionY != handleBox->getPosition().y) {
		lastPositionY = handleBox->getPosition().y;
		scrollValue = (lastPositionY-padding)/dragRectHeight;
		if(scrollValue < 0){
			scrollValue = 0;
			handleBox->setPositionY((scrollValue * dragRectHeight) + padding);
		}

		if(scrollValue > 1) {
			scrollValue = 1;
			handleBox->setPositionY((scrollValue * dragRectHeight) + padding);
		}
		dispatchEvent(new Event(), Event::CHANGE_EVENT);
	}
}

void UIVScrollBar::scrollTo(Number scrollValue) {
	handleBox->setPositionY((scrollValue * dragRectHeight) + padding);
}

void UIVScrollBar::Scroll(Number amount) {
	Number newValue = scrollValue+amount;
	if(newValue > 1.0)
		newValue = 1.0;
	if(newValue < 0.0)
		newValue = 0.0;
	handleBox->setPositionY(((newValue) * dragRectHeight) + padding);
}

void UIVScrollBar::setHandleRatio(Number newRatio) {

	scrollHandleHeight = getHeight()*newRatio;

	if(scrollHandleHeight < minHandleSize)
		scrollHandleHeight = minHandleSize;

	dragRectHeight = getHeight()-(padding*2)-scrollHandleHeight;
	handleBox->resizeBox(handleBox->getWidth(), scrollHandleHeight);
	handleBox->setDragLimits(Rectangle(padding,padding,getWidth()-(padding*2)-(getWidth()-(padding*2)), dragRectHeight));

	if(enabled && handleBox->getPosition().y > dragRectHeight) {
		handleBox->setPositionY(dragRectHeight);
	}

}

void UIVScrollBar::onMouseWheelUp(Number x, Number y) {
	scrollUpOneTick();
}

void UIVScrollBar::onMouseWheelDown(Number x, Number y) {
	scrollDownOneTick();
}

void UIVScrollBar::setTickSize(Number newTickSize) {
	tickSize = newTickSize;
}

void UIVScrollBar::scrollUpOneTick() {
	Scroll(-tickSize);
}

void UIVScrollBar::scrollDownOneTick() {
	Scroll(tickSize);
}

Number UIVScrollBar::getScrollValue() {
	return scrollValue;
}

void UIVScrollBar::handleEvent(Event *event) {
	if(event->getDispatcher() == bgBox) {
		InputEvent *inputEvent = (InputEvent*)event;
		switch(event->getEventCode()) {
			case InputEvent::EVENT_MOUSEOVER:
				CoreServices::getInstance()->getCore()->setCursor(Core::CURSOR_ARROW);
			break;
			case InputEvent::EVENT_MOUSEDOWN:
				if(inputEvent->mousePosition.y < handleBox->getPosition().y)  {
					Number newPos = handleBox->getPosition().y - scrollHandleHeight/2;
					if(newPos < padding)
						newPos = padding;
					handleBox->setPositionY(newPos);
				} else {
					Number newPos = handleBox->getPosition().y + scrollHandleHeight/2;
					if(newPos > dragRectHeight)
						newPos = dragRectHeight;
					handleBox->setPositionY(newPos);
				}
			break;
		}
	}

	if(event->getDispatcher() == handleBox) {
		InputEvent *inputEvent = (InputEvent*)event;
		switch(event->getEventCode()) {
			case InputEvent::EVENT_MOUSEOVER:
				CoreServices::getInstance()->getCore()->setCursor(Core::CURSOR_ARROW);
			break;
			case InputEvent::EVENT_MOUSEUP:
			case InputEvent::EVENT_MOUSEUP_OUTSIDE:
				handleBox->stopDrag();
				break;
			case InputEvent::EVENT_MOUSEDOWN:
				handleBox->startDrag(inputEvent->mousePosition.x,inputEvent->mousePosition.y);
				break;
		}
	}
}

UIVScrollBar::~UIVScrollBar() {
    if(!ownsChildren) {
        delete bgBox;
        delete handleBox;
    }
}
<commit_msg>Increase standard UIVScrollBar scroll speed, it makes it feel much more natural. (I'm not the only one who was annoyed by that: #543)<commit_after>/*
 Copyright (C) 2012 by Ivan Safrin

 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 "PolyUIVScrollBar.h"
#include "PolyConfig.h"
#include "PolyInputEvent.h"
#include "PolyLabel.h"
#include "PolyCoreServices.h"
#include "PolyCore.h"

using namespace Polycode;

UIVScrollBar::UIVScrollBar(Number width, Number height, Number initialRatio) : UIElement() {

	scrollValue = 0;

	Config *conf = CoreServices::getInstance()->getConfig();

	minHandleSize = conf->getNumericValue("Polycode", "uiScrollHandleMinSize");

	Number st = conf->getNumericValue("Polycode", "uiScrollBgSkinT");
	Number sr = conf->getNumericValue("Polycode", "uiScrollBgSkinR");
	Number sb = conf->getNumericValue("Polycode", "uiScrollBgSkinB");
	Number sl = conf->getNumericValue("Polycode", "uiScrollBgSkinL");
	padding = conf->getNumericValue("Polycode", "uiScrollBgSkinPadding");

	bgBox = new UIBox(conf->getStringValue("Polycode", "uiScrollBgSkin"),
					  st,sr,sb,sl,
					  width, height);

	bgBox->processInputEvents = true;
	bgBox->addEventListener(this, InputEvent::EVENT_MOUSEDOWN);
	bgBox->addEventListener(this, InputEvent::EVENT_MOUSEOVER);
	addChild(bgBox);

	st = conf->getNumericValue("Polycode", "uiScrollHandleSkinT");
	sr = conf->getNumericValue("Polycode", "uiScrollHandleSkinR");
	sb = conf->getNumericValue("Polycode", "uiScrollHandleSkinB");
	sl = conf->getNumericValue("Polycode", "uiScrollHandleSkinL");

	if(initialRatio > 1)
		initialRatio = 1;

	scrollHandleHeight = height*initialRatio;

	if(scrollHandleHeight < minHandleSize)
		scrollHandleHeight = minHandleSize;

	handleBox = new UIBox(conf->getStringValue("Polycode", "uiScrollHandleSkin"),
					  st,sr,sb,sl,
					  width-(padding*2),scrollHandleHeight);
	handleBox->setPosition(padding, padding);
	addChild(handleBox);

	handleBox->addEventListener(this, InputEvent::EVENT_MOUSEUP);
	handleBox->addEventListener(this, InputEvent::EVENT_MOUSEUP_OUTSIDE);
	handleBox->addEventListener(this, InputEvent::EVENT_MOUSEDOWN);
	handleBox->addEventListener(this, InputEvent::EVENT_MOUSEOVER);
	handleBox->processInputEvents = true;
	handleBox->blockMouseInput = true;

	dragRectHeight = height-(padding*2)-scrollHandleHeight;
	handleBox->setDragLimits(Rectangle(padding,padding,width-(padding*2)-(width-(padding*2)), dragRectHeight));

	lastPositionY = handleBox->getPosition().y;

	setHeight(height);
	setWidth(width);

	tickSize = 0.1;
}

void UIVScrollBar::Resize(int newHeight) {
	bgBox->resizeBox(getWidth(), newHeight);
	setHeight(newHeight);
	dragRectHeight = getHeight()-(padding*2)-scrollHandleHeight;
	handleBox->setDragLimits(Rectangle(padding,padding,getWidth()-(padding*2)-(getWidth()-(padding*2)), dragRectHeight));
}

void UIVScrollBar::Update() {

	if(lastPositionY != handleBox->getPosition().y) {
		lastPositionY = handleBox->getPosition().y;
		scrollValue = (lastPositionY-padding)/dragRectHeight;
		if(scrollValue < 0){
			scrollValue = 0;
			handleBox->setPositionY((scrollValue * dragRectHeight) + padding);
		}

		if(scrollValue > 1) {
			scrollValue = 1;
			handleBox->setPositionY((scrollValue * dragRectHeight) + padding);
		}
		dispatchEvent(new Event(), Event::CHANGE_EVENT);
	}
}

void UIVScrollBar::scrollTo(Number scrollValue) {
	handleBox->setPositionY((scrollValue * dragRectHeight) + padding);
}

void UIVScrollBar::Scroll(Number amount) {
	Number newValue = scrollValue+amount;
	if(newValue > 1.0)
		newValue = 1.0;
	if(newValue < 0.0)
		newValue = 0.0;
	handleBox->setPositionY(((newValue) * dragRectHeight) + padding);
}

void UIVScrollBar::setHandleRatio(Number newRatio) {

	scrollHandleHeight = getHeight()*newRatio;

	if(scrollHandleHeight < minHandleSize)
		scrollHandleHeight = minHandleSize;

	dragRectHeight = getHeight()-(padding*2)-scrollHandleHeight;
	handleBox->resizeBox(handleBox->getWidth(), scrollHandleHeight);
	handleBox->setDragLimits(Rectangle(padding,padding,getWidth()-(padding*2)-(getWidth()-(padding*2)), dragRectHeight));

	if(enabled && handleBox->getPosition().y > dragRectHeight) {
		handleBox->setPositionY(dragRectHeight);
	}

}

void UIVScrollBar::onMouseWheelUp(Number x, Number y) {
	scrollUpOneTick();
}

void UIVScrollBar::onMouseWheelDown(Number x, Number y) {
	scrollDownOneTick();
}

void UIVScrollBar::setTickSize(Number newTickSize) {
	tickSize = newTickSize;
}

void UIVScrollBar::scrollUpOneTick() {
	Scroll(-tickSize);
}

void UIVScrollBar::scrollDownOneTick() {
	Scroll(tickSize);
}

Number UIVScrollBar::getScrollValue() {
	return scrollValue;
}

void UIVScrollBar::handleEvent(Event *event) {
	if(event->getDispatcher() == bgBox) {
		InputEvent *inputEvent = (InputEvent*)event;
		switch(event->getEventCode()) {
			case InputEvent::EVENT_MOUSEOVER:
				CoreServices::getInstance()->getCore()->setCursor(Core::CURSOR_ARROW);
			break;
			case InputEvent::EVENT_MOUSEDOWN:
				if(inputEvent->mousePosition.y < handleBox->getPosition().y)  {
					Number newPos = handleBox->getPosition().y - scrollHandleHeight/2;
					if(newPos < padding)
						newPos = padding;
					handleBox->setPositionY(newPos);
				} else {
					Number newPos = handleBox->getPosition().y + scrollHandleHeight/2;
					if(newPos > dragRectHeight)
						newPos = dragRectHeight;
					handleBox->setPositionY(newPos);
				}
			break;
		}
	}

	if(event->getDispatcher() == handleBox) {
		InputEvent *inputEvent = (InputEvent*)event;
		switch(event->getEventCode()) {
			case InputEvent::EVENT_MOUSEOVER:
				CoreServices::getInstance()->getCore()->setCursor(Core::CURSOR_ARROW);
			break;
			case InputEvent::EVENT_MOUSEUP:
			case InputEvent::EVENT_MOUSEUP_OUTSIDE:
				handleBox->stopDrag();
				break;
			case InputEvent::EVENT_MOUSEDOWN:
				handleBox->startDrag(inputEvent->mousePosition.x,inputEvent->mousePosition.y);
				break;
		}
	}
}

UIVScrollBar::~UIVScrollBar() {
    if(!ownsChildren) {
        delete bgBox;
        delete handleBox;
    }
}
<|endoftext|>


<commit_before>//=======================================================================
// Copyright (c) 2014-2017 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#pragma once

#include "cpp_utils/algorithm.hpp" // For parallel_shuffle

#include "etl/etl.hpp"

#include "dll/util/labels.hpp"
#include "dll/util/timers.hpp"
#include "dll/util/batch.hpp" // For make_batch
#include "dll/test.hpp"
#include "dll/dbn_traits.hpp"

#include "dll/trainer/sgd_context.hpp" // TODO Remove later

namespace dll {

template <typename Iterator>
struct range {
private:
    Iterator first;
    Iterator last;

public:
    range(Iterator first, Iterator last)
            : first(first), last(last) {}

    Iterator begin() const {
        return first;
    }

    Iterator end() const {
        return last;
    }
};

template <typename Iterator>
range<Iterator> make_range(Iterator first, Iterator last) {
    return {first, last};
}

/*!
 * \brief A generic trainer for Deep Belief Network
 *
 * This trainer use the specified trainer of the DBN to perform supervised
 * fine-tuning.
 */
template <typename DBN>
struct dbn_trainer {
    using dbn_t = DBN;
    using error_type = typename dbn_t::weight;

    template <typename R>
    using trainer_t = typename dbn_t::desc::template trainer_t<R>;

    template <typename R>
    using watcher_t = typename dbn_t::desc::template watcher_t<R>;

    template <typename Iterator, typename LIterator>
    error_type train(DBN& dbn, Iterator first, Iterator last, LIterator lfirst, LIterator llast, size_t max_epochs) const {
        auto error_function = [&dbn, first, last, lfirst, llast]() {
            return test_set(dbn, first, last, lfirst, llast,
                            [](dbn_t& dbn, auto& image) { return dbn.predict(image); });
        };

        auto label_transformer = [](const auto& value, size_t n) {
            return dll::make_fake_etl(value, n);
        };

        auto input_transformer = [](const auto& /*value*/){
            // NOP
        };

        return train_impl(dbn, false, first, last, lfirst, llast, max_epochs, error_function, input_transformer, label_transformer);
    }

    template <typename Iterator>
    error_type train_ae(DBN& dbn, Iterator first, Iterator last, size_t max_epochs) const {
        auto error_function = [&dbn, first, last]() {
            return test_set_ae(dbn, first, last);
        };

        auto label_transformer = [](const auto& value, size_t /*n*/) {
            return value;
        };

        auto input_transformer = [](const auto& /*value*/){
            // NOP
        };

        return train_impl(dbn, true, first, last, first, last, max_epochs, error_function, input_transformer, label_transformer);
    }

    template <typename Iterator>
    error_type train_dae(DBN& dbn, Iterator first, Iterator last, size_t max_epochs, double corrupt) const {
        auto error_function = [&dbn, first, last]() {
            return test_set_ae(dbn, first, last);
        };

        auto label_transformer = [](const auto& value, size_t /*n*/) {
            return value;
        };

        auto input_transformer = [corrupt](auto&& value){
            static std::random_device rd;
            static std::default_random_engine g(rd());

            std::uniform_real_distribution<double> dist(0.0, 1000.0);

            for(auto& v :  value){
                v *= dist(g) < corrupt * 1000.0 ? 0.0 : 1.0;
            }
        };

        return train_impl(dbn, true, first, last, first, last, max_epochs, error_function, input_transformer, label_transformer);
    }

    template <typename D, typename It>
    static void copy_inputs(D& dest, It first, It last) {
        size_t i = 0;

        while (first != last) {
            dest(i++) = *first++;
        }
    }

    template <typename Iterator, typename LIterator, typename Error, typename InputTransformer, typename LabelTransformer>
    error_type train_impl(DBN& dbn, bool ae, Iterator first, Iterator last, LIterator lfirst, LIterator /*llast*/, size_t max_epochs, Error error_function, InputTransformer input_transformer, LabelTransformer label_transformer) const {
        dll::auto_timer timer("dbn::trainer::train_impl");

        decltype(auto) input_layer = dbn.template layer_get<dbn_t::input_layer_n>();
        decltype(auto) output_layer = dbn.template layer_get<dbn_t::output_layer_n>();

        decltype(auto) first_layer = dbn.template layer_get<0>();
        decltype(auto) last_layer  = dbn.template layer_get<dbn_t::layers - 1>();

        using input_layer_t  = typename dbn_t::template layer_type<dbn_t::input_layer_n>;
        using output_layer_t = typename dbn_t::template layer_type<dbn_t::output_layer_n>;

        constexpr const auto batch_size     = std::decay_t<DBN>::batch_size;
        constexpr const auto big_batch_size = std::decay_t<DBN>::big_batch_size;

        //Initialize the momentum
        dbn.momentum = dbn.initial_momentum;

        //Initialize the watcher
        watcher_t<dbn_t> watcher;

        watcher.fine_tuning_begin(dbn);

        auto trainer = std::make_unique<trainer_t<dbn_t>>(dbn);

        trainer->set_autoencoder(ae);

        //Initialize the trainer if necessary
        trainer->init_training(batch_size);

        error_type error = 0.0;

        if (!dbn.batch_mode()) {
            dll::auto_timer timer("dbn::trainer::train_impl::fast");

            // The number of elements on which to train
            const size_t n = std::distance(first, last);

            // Prepare the data

            // TODO Create correctly the type for conv
            etl::dyn_matrix<typename input_layer_t::weight, 2> data(n, input_layer.input_size());

            for(size_t l = 0; l < n; ++l){
                data(l) = *first++;
            }

            // Prepare the labels

            etl::dyn_matrix<typename output_layer_t::weight, 2> labels(n, output_layer.output_size(), typename output_layer_t::weight(0.0));

            for(size_t l = 0; l < n; ++l){
                labels(l) = label_transformer(*lfirst++, output_layer.output_size());
            }

            //Compute the number of batches
            auto batches = n / batch_size + (n % batch_size == 0 ? 0 : 1);

            // Prepare a fast error function using the contiguous memory

            auto error_function_batch = [&] () {
                if(ae){
                    return error_function();
                } else {
                    //Note: Ideally, this should be done without
                    //using the SGD context, but this would mean
                    //a complete overhault of creation of batches...

                    decltype(auto) input_ctx = input_layer.template get_sgd_context<dbn_t>();
                    decltype(auto) first_ctx = first_layer.template get_sgd_context<dbn_t>();
                    decltype(auto) last_ctx  = last_layer.template get_sgd_context<dbn_t>();

                    double error = 0.0;

                    //Train one mini-batch at a time
                    for (size_t i = 0; i < batches; ++i) {
                        auto start = i * batch_size;
                        auto end   = std::min(start + batch_size, n);

                        input_ctx.input = slice(data, start, end);

                        first_layer.batch_activate_hidden(first_ctx.output, first_ctx.input);

                        dbn.for_each_layer_pair([](auto& layer_1, auto& layer_2) {
                            auto& ctx1 = layer_1.template get_sgd_context<dbn_t>();
                            auto& ctx2 = layer_2.template get_sgd_context<dbn_t>();

                            ctx2.input = ctx1.output;
                            layer_2.batch_activate_hidden(ctx2.output, ctx2.input);
                        });

                        // TODO Review this calculation
                        // The result is correct, but can probably be done in a more clean way

                        // TODO This is not correct for ae!
                        for(size_t b = 0; b < end - start; ++b){
                            error += std::min(1.0, (double) etl::sum(abs(labels(start + b) - one_if_max(last_ctx.output(b)))));
                        }
                    }

                    return error / n;
                }
            };

            //Train for max_epochs epoch
            for (size_t epoch = 0; epoch < max_epochs; ++epoch) {
                dll::auto_timer timer("dbn::trainer::train_impl::epoch");

                // Shuffle before the epoch if necessary
                if(dbn_traits<dbn_t>::shuffle()){
                    static std::random_device rd;
                    static std::mt19937_64 g(rd());

                    etl::parallel_shuffle(data, labels);
                }

                double loss = 0;

                //Train one mini-batch at a time
                for (size_t i = 0; i < batches; ++i) {
                    dll::auto_timer timer("dbn::trainer::train_impl::epoch::batch");

                    const auto start = i * batch_size;
                    const auto end   = std::min(start + batch_size, n);

                    double batch_error;
                    double batch_loss;
                    std::tie(batch_error, batch_loss) = trainer->train_batch(
                        epoch,
                        slice(data, start, end),
                        slice(labels, start, end),
                        input_transformer);

                    if(dbn_traits<dbn_t>::is_verbose()){
                        watcher.ft_batch_end(epoch, i, batches, batch_error, batch_loss, error_function_batch(), dbn);
                    }

                    loss += batch_loss;
                }

                loss /= batches;

                // Save the last error
                auto last_error = error;

                // Compute the error at this epoch

                {
                    dll::auto_timer timer("dbn::trainer::train_impl::epoch::error");

                    error = error_function_batch();
                }

                //After some time increase the momentum
                if (dbn_traits<dbn_t>::has_momentum() && epoch == dbn.final_momentum_epoch) {
                    dbn.momentum = dbn.final_momentum;
                }

                watcher.ft_epoch_end(epoch, error, loss, dbn);

                //Once the goal is reached, stop training
                if (error <= dbn.goal) {
                    break;
                }

                if (dbn_traits<dbn_t>::lr_driver() == lr_driver_type::BOLD) {
                    if (epoch) {
                        if (error > last_error + 1e-8) {
                            //Error increased
                            dbn.learning_rate *= dbn.lr_bold_dec;
                            watcher.lr_adapt(dbn);
                            dbn.restore_weights();
                        } else if (error < last_error - 1e-10) {
                            //Error decreased
                            dbn.learning_rate *= dbn.lr_bold_inc;
                            watcher.lr_adapt(dbn);
                            dbn.backup_weights();
                        } else {
                            //Error didn't change enough
                            dbn.backup_weights();
                        }
                    } else {
                        dbn.backup_weights();
                    }
                }

                if (dbn_traits<dbn_t>::lr_driver() == lr_driver_type::STEP) {
                    if (epoch && epoch % dbn.lr_step_size == 0) {
                        dbn.learning_rate *= dbn.lr_step_gamma;
                        watcher.lr_adapt(dbn);
                    }
                }
            }
        } else {
            auto total_batch_size = big_batch_size * batch_size;

            //Prepare some space for converted data
            etl::dyn_matrix<typename input_layer_t::weight, 2> input_cache(total_batch_size, input_layer.input_size());
            etl::dyn_matrix<typename output_layer_t::weight, 2> label_cache(total_batch_size, output_layer.output_size());

            //Train for max_epochs epoch
            for (size_t epoch = 0; epoch < max_epochs; ++epoch) {
                auto it = first;
                auto lit = lfirst;

                double loss = 0.0;

                size_t n = 0;

                //Train all mini-batches
                while (it != last) {
                    label_cache = 0.0;

                    //Fill the input caches
                    size_t i = 0;
                    while (it != last && i < total_batch_size) {
                        input_cache(i) = *it++;
                        label_cache(i) = label_transformer(*lit++, output_layer.output_size());

                        ++i;
                        ++n;
                    }

                    auto full_batches = i / batch_size;

                    //Train all the full batches
                    for (size_t b = 0; b < full_batches; ++b) {
                        const auto start       = b * batch_size;
                        const auto end         = (b + 1) * batch_size;

                        double batch_error;
                        double batch_loss;
                        std::tie(batch_error, batch_loss) = trainer->train_batch(
                            epoch,
                            slice(input_cache, start, end),
                            slice(label_cache, start, end),
                            input_transformer);

                        if(dbn_traits<dbn_t>::is_verbose()){
                            watcher.ft_batch_end(epoch, batch_error, batch_loss, error_function(), dbn);
                        }

                        loss += batch_loss;
                    }

                    //Train the last incomplete batch, if any
                    if (i % batch_size > 0) {
                        const auto start       = full_batches * batch_size;
                        const auto end         = i;

                        double batch_error;
                        double batch_loss;
                        std::tie(batch_error, batch_loss) = trainer->train_batch(
                            epoch,
                            slice(input_cache, start, end),
                            slice(label_cache, start, end),
                            input_transformer);

                        if(dbn_traits<dbn_t>::is_verbose()){
                            watcher.ft_batch_end(epoch, batch_error, batch_loss, error_function(), dbn);
                        }

                        loss += batch_loss;
                    }
                }

                error = error_function();
                loss /= n;

                //After some time increase the momentum
                if (dbn_traits<dbn_t>::has_momentum() && epoch == dbn.final_momentum_epoch) {
                    dbn.momentum = dbn.final_momentum;
                }

                watcher.ft_epoch_end(epoch, error, loss, dbn);

                //Once the goal is reached, stop training
                if (error <= dbn.goal) {
                    break;
                }
            }
        }

        watcher.fine_tuning_end(dbn);

        return error;
    }
};

} //end of dll namespace
<commit_msg>Unify error function in fast mode<commit_after>//=======================================================================
// Copyright (c) 2014-2017 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#pragma once

#include "cpp_utils/algorithm.hpp" // For parallel_shuffle

#include "etl/etl.hpp"

#include "dll/util/labels.hpp"
#include "dll/util/timers.hpp"
#include "dll/util/batch.hpp" // For make_batch
#include "dll/test.hpp"
#include "dll/dbn_traits.hpp"

#include "dll/trainer/sgd_context.hpp" // TODO Remove later

namespace dll {

template <typename Iterator>
struct range {
private:
    Iterator first;
    Iterator last;

public:
    range(Iterator first, Iterator last)
            : first(first), last(last) {}

    Iterator begin() const {
        return first;
    }

    Iterator end() const {
        return last;
    }
};

template <typename Iterator>
range<Iterator> make_range(Iterator first, Iterator last) {
    return {first, last};
}

/*!
 * \brief A generic trainer for Deep Belief Network
 *
 * This trainer use the specified trainer of the DBN to perform supervised
 * fine-tuning.
 */
template <typename DBN>
struct dbn_trainer {
    using dbn_t = DBN;
    using error_type = typename dbn_t::weight;

    template <typename R>
    using trainer_t = typename dbn_t::desc::template trainer_t<R>;

    template <typename R>
    using watcher_t = typename dbn_t::desc::template watcher_t<R>;

    template <typename Iterator, typename LIterator>
    error_type train(DBN& dbn, Iterator first, Iterator last, LIterator lfirst, LIterator llast, size_t max_epochs) const {
        auto error_function = [&dbn, first, last, lfirst, llast]() {
            return test_set(dbn, first, last, lfirst, llast,
                            [](dbn_t& dbn, auto& image) { return dbn.predict(image); });
        };

        auto label_transformer = [](const auto& value, size_t n) {
            return dll::make_fake_etl(value, n);
        };

        auto input_transformer = [](const auto& /*value*/){
            // NOP
        };

        return train_impl(dbn, false, first, last, lfirst, llast, max_epochs, error_function, input_transformer, label_transformer);
    }

    template <typename Iterator>
    error_type train_ae(DBN& dbn, Iterator first, Iterator last, size_t max_epochs) const {
        auto error_function = [&dbn, first, last]() {
            return test_set_ae(dbn, first, last);
        };

        auto label_transformer = [](const auto& value, size_t /*n*/) {
            return value;
        };

        auto input_transformer = [](const auto& /*value*/){
            // NOP
        };

        return train_impl(dbn, true, first, last, first, last, max_epochs, error_function, input_transformer, label_transformer);
    }

    template <typename Iterator>
    error_type train_dae(DBN& dbn, Iterator first, Iterator last, size_t max_epochs, double corrupt) const {
        auto error_function = [&dbn, first, last]() {
            return test_set_ae(dbn, first, last);
        };

        auto label_transformer = [](const auto& value, size_t /*n*/) {
            return value;
        };

        auto input_transformer = [corrupt](auto&& value){
            static std::random_device rd;
            static std::default_random_engine g(rd());

            std::uniform_real_distribution<double> dist(0.0, 1000.0);

            for(auto& v :  value){
                v *= dist(g) < corrupt * 1000.0 ? 0.0 : 1.0;
            }
        };

        return train_impl(dbn, true, first, last, first, last, max_epochs, error_function, input_transformer, label_transformer);
    }

    template <typename D, typename It>
    static void copy_inputs(D& dest, It first, It last) {
        size_t i = 0;

        while (first != last) {
            dest(i++) = *first++;
        }
    }

    template <typename Iterator, typename LIterator, typename Error, typename InputTransformer, typename LabelTransformer>
    error_type train_impl(DBN& dbn, bool ae, Iterator first, Iterator last, LIterator lfirst, LIterator /*llast*/, size_t max_epochs, Error error_function, InputTransformer input_transformer, LabelTransformer label_transformer) const {
        dll::auto_timer timer("dbn::trainer::train_impl");

        decltype(auto) input_layer = dbn.template layer_get<dbn_t::input_layer_n>();
        decltype(auto) output_layer = dbn.template layer_get<dbn_t::output_layer_n>();

        using input_layer_t  = typename dbn_t::template layer_type<dbn_t::input_layer_n>;
        using output_layer_t = typename dbn_t::template layer_type<dbn_t::output_layer_n>;

        constexpr const auto batch_size     = std::decay_t<DBN>::batch_size;
        constexpr const auto big_batch_size = std::decay_t<DBN>::big_batch_size;

        //Initialize the momentum
        dbn.momentum = dbn.initial_momentum;

        //Initialize the watcher
        watcher_t<dbn_t> watcher;

        watcher.fine_tuning_begin(dbn);

        auto trainer = std::make_unique<trainer_t<dbn_t>>(dbn);

        trainer->set_autoencoder(ae);

        //Initialize the trainer if necessary
        trainer->init_training(batch_size);

        error_type error = 0.0;

        if (!dbn.batch_mode()) {
            dll::auto_timer timer("dbn::trainer::train_impl::fast");

            // The number of elements on which to train
            const size_t n = std::distance(first, last);

            // Prepare the data

            // TODO Create correctly the type for conv
            etl::dyn_matrix<typename input_layer_t::weight, 2> data(n, input_layer.input_size());

            for(size_t l = 0; l < n; ++l){
                data(l) = *first++;
            }

            // Prepare the labels

            etl::dyn_matrix<typename output_layer_t::weight, 2> labels(n, output_layer.output_size(), typename output_layer_t::weight(0.0));

            for(size_t l = 0; l < n; ++l){
                labels(l) = label_transformer(*lfirst++, output_layer.output_size());
            }

            //Compute the number of batches
            auto batches = n / batch_size + (n % batch_size == 0 ? 0 : 1);

            // Prepare a fast error function using the contiguous memory

            auto error_function_batch = [&] () {
                double error = 0.0;

                //Train one mini-batch at a time
                for (size_t i = 0; i < batches; ++i) {
                    auto start = i * batch_size;
                    auto end   = std::min(start + batch_size, n);

                    decltype(auto) output = dbn.forward_batch(slice(data, start, end));

                    if(ae){
                        for(size_t b = 0; b < end - start; ++b){
                            error += mean(abs(labels(start + b) - output(b)));
                        }
                    } else {
                        // TODO Review this calculation
                        // The result is correct, but can probably be done in a more clean way

                        for(size_t b = 0; b < end - start; ++b){
                            error += std::min(1.0, (double) etl::sum(abs(labels(start + b) - one_if_max(output(b)))));
                        }
                    }
                }

                return error / n;
            };

            //Train for max_epochs epoch
            for (size_t epoch = 0; epoch < max_epochs; ++epoch) {
                dll::auto_timer timer("dbn::trainer::train_impl::epoch");

                // Shuffle before the epoch if necessary
                if(dbn_traits<dbn_t>::shuffle()){
                    static std::random_device rd;
                    static std::mt19937_64 g(rd());

                    etl::parallel_shuffle(data, labels);
                }

                double loss = 0;

                //Train one mini-batch at a time
                for (size_t i = 0; i < batches; ++i) {
                    dll::auto_timer timer("dbn::trainer::train_impl::epoch::batch");

                    const auto start = i * batch_size;
                    const auto end   = std::min(start + batch_size, n);

                    double batch_error;
                    double batch_loss;
                    std::tie(batch_error, batch_loss) = trainer->train_batch(
                        epoch,
                        slice(data, start, end),
                        slice(labels, start, end),
                        input_transformer);

                    if(dbn_traits<dbn_t>::is_verbose()){
                        watcher.ft_batch_end(epoch, i, batches, batch_error, batch_loss, error_function_batch(), dbn);
                    }

                    loss += batch_loss;
                }

                loss /= batches;

                // Save the last error
                auto last_error = error;

                // Compute the error at this epoch

                {
                    dll::auto_timer timer("dbn::trainer::train_impl::epoch::error");

                    error = error_function_batch();
                }

                //After some time increase the momentum
                if (dbn_traits<dbn_t>::has_momentum() && epoch == dbn.final_momentum_epoch) {
                    dbn.momentum = dbn.final_momentum;
                }

                watcher.ft_epoch_end(epoch, error, loss, dbn);

                //Once the goal is reached, stop training
                if (error <= dbn.goal) {
                    break;
                }

                if (dbn_traits<dbn_t>::lr_driver() == lr_driver_type::BOLD) {
                    if (epoch) {
                        if (error > last_error + 1e-8) {
                            //Error increased
                            dbn.learning_rate *= dbn.lr_bold_dec;
                            watcher.lr_adapt(dbn);
                            dbn.restore_weights();
                        } else if (error < last_error - 1e-10) {
                            //Error decreased
                            dbn.learning_rate *= dbn.lr_bold_inc;
                            watcher.lr_adapt(dbn);
                            dbn.backup_weights();
                        } else {
                            //Error didn't change enough
                            dbn.backup_weights();
                        }
                    } else {
                        dbn.backup_weights();
                    }
                }

                if (dbn_traits<dbn_t>::lr_driver() == lr_driver_type::STEP) {
                    if (epoch && epoch % dbn.lr_step_size == 0) {
                        dbn.learning_rate *= dbn.lr_step_gamma;
                        watcher.lr_adapt(dbn);
                    }
                }
            }
        } else {
            auto total_batch_size = big_batch_size * batch_size;

            //Prepare some space for converted data
            etl::dyn_matrix<typename input_layer_t::weight, 2> input_cache(total_batch_size, input_layer.input_size());
            etl::dyn_matrix<typename output_layer_t::weight, 2> label_cache(total_batch_size, output_layer.output_size());

            //Train for max_epochs epoch
            for (size_t epoch = 0; epoch < max_epochs; ++epoch) {
                auto it = first;
                auto lit = lfirst;

                double loss = 0.0;

                size_t n = 0;

                //Train all mini-batches
                while (it != last) {
                    label_cache = 0.0;

                    //Fill the input caches
                    size_t i = 0;
                    while (it != last && i < total_batch_size) {
                        input_cache(i) = *it++;
                        label_cache(i) = label_transformer(*lit++, output_layer.output_size());

                        ++i;
                        ++n;
                    }

                    auto full_batches = i / batch_size;

                    //Train all the full batches
                    for (size_t b = 0; b < full_batches; ++b) {
                        const auto start       = b * batch_size;
                        const auto end         = (b + 1) * batch_size;

                        double batch_error;
                        double batch_loss;
                        std::tie(batch_error, batch_loss) = trainer->train_batch(
                            epoch,
                            slice(input_cache, start, end),
                            slice(label_cache, start, end),
                            input_transformer);

                        if(dbn_traits<dbn_t>::is_verbose()){
                            watcher.ft_batch_end(epoch, batch_error, batch_loss, error_function(), dbn);
                        }

                        loss += batch_loss;
                    }

                    //Train the last incomplete batch, if any
                    if (i % batch_size > 0) {
                        const auto start       = full_batches * batch_size;
                        const auto end         = i;

                        double batch_error;
                        double batch_loss;
                        std::tie(batch_error, batch_loss) = trainer->train_batch(
                            epoch,
                            slice(input_cache, start, end),
                            slice(label_cache, start, end),
                            input_transformer);

                        if(dbn_traits<dbn_t>::is_verbose()){
                            watcher.ft_batch_end(epoch, batch_error, batch_loss, error_function(), dbn);
                        }

                        loss += batch_loss;
                    }
                }

                error = error_function();
                loss /= n;

                //After some time increase the momentum
                if (dbn_traits<dbn_t>::has_momentum() && epoch == dbn.final_momentum_epoch) {
                    dbn.momentum = dbn.final_momentum;
                }

                watcher.ft_epoch_end(epoch, error, loss, dbn);

                //Once the goal is reached, stop training
                if (error <= dbn.goal) {
                    break;
                }
            }
        }

        watcher.fine_tuning_end(dbn);

        return error;
    }
};

} //end of dll namespace
<|endoftext|>


<commit_before>// -------------------------------------------------------------------------
//    @FileName      :    NFCLuaScriptModule.cpp
//    @Author           :    LvSheng.Huang
//    @Date             :    2013-01-02
//    @Module           :    NFCLuaScriptModule
//    @Desc             :
// -------------------------------------------------------------------------

#include "NFCLuaScriptModule.h"
#include "NFLuaScriptPlugin.h"
#include <assert.h>

#define TRY_RUN_GLOBAL_SCRIPT_FUN0(strFuncName)  try{luacpp::call<void>(lw, strFuncName);} catch (string &err){printf("%s\n", err.c_str());}
#define TRY_RUN_GLOBAL_SCRIPT_FUN1(strFuncName, arg1)  try{luacpp::call<void>(lw, strFuncName, arg1);} catch (string &err){printf("%s\n", err.c_str());}

bool NFCLuaScriptModule::Init()
{
	mnTime = pPluginManager->GetNowTime();

	//std::shared_ptr<NFILogicClass> pClass = m_pLogicClassModule->First();
	//while (pClass.get())
	//{
	//	std::shared_ptr<NFIComponent> pComponent = pClass->GetComponentManager()->First();
	//	while (pComponent.get())
	//	{
	//		if (!CheckCompomentStatus(pComponent->GetComponentName()))
	//		{
	//			assert(0);
	//		}

	//		pComponent = pClass->GetComponentManager()->Next();
	//	}

	//	pClass = m_pLogicClassModule->Next();
	//}

	m_pKernelModule = pPluginManager->FindModule<NFIKernelModule>("NFCKernelModule");
	m_pLogicClassModule = pPluginManager->FindModule<NFILogicClassModule>("NFCLogicClassModule");
	m_pElementInfoModule = pPluginManager->FindModule<NFIElementInfoModule>("NFCElementInfoModule");

	assert(NULL != m_pKernelModule);
	assert(NULL != m_pLogicClassModule);
	assert(NULL != m_pElementInfoModule);

	Regisger();

	try
	{
		lw.dofile("script_init.lua");
	}
	catch (string &err)
	{
		printf("%s\n", err.c_str());
		assert(0);
	}

	TRY_RUN_GLOBAL_SCRIPT_FUN1("init_script_system", m_pKernelModule);

	std::string sTest = "Test";
	TRY_RUN_GLOBAL_SCRIPT_FUN1("load_script_file", sTest)

	TRY_RUN_GLOBAL_SCRIPT_FUN0("Init");

	return true;
}

bool NFCLuaScriptModule::AfterInit()
{
	TRY_RUN_GLOBAL_SCRIPT_FUN0("AfterInit");

	//add all callback
	m_pKernelModule->ResgisterCommonPropertyEvent(this, &NFCLuaScriptModule::OnPropertyCommEvent);
	m_pKernelModule->ResgisterCommonRecordEvent(this, &NFCLuaScriptModule::OnRecordCommonEvent);
	m_pKernelModule->ResgisterCommonClassEvent(this, &NFCLuaScriptModule::OnClassCommonEvent);

	return true;
}

bool NFCLuaScriptModule::Shut()
{
	TRY_RUN_GLOBAL_SCRIPT_FUN0("Shut");

	return true;
}

bool NFCLuaScriptModule::Execute()
{
	//10秒钟reload一次
	if (pPluginManager->GetNowTime()- mnTime > 10)
	{
		mnTime = pPluginManager->GetNowTime();

		TRY_RUN_GLOBAL_SCRIPT_FUN0("Execute");

		TRY_RUN_GLOBAL_SCRIPT_FUN0("reload_script_list")

	}

	return true;
}

bool NFCLuaScriptModule::BeforeShut()
{
	TRY_RUN_GLOBAL_SCRIPT_FUN0("BeforeShut");

	return true;
}

int NFCLuaScriptModule::OnPropertyCommEvent(const NFGUID& self, const std::string& strPropertyName, const NFIDataList::TData& oldVar, const NFIDataList::TData& newVar)
{
	DoPropertyCommEvent(self, strPropertyName, oldVar, newVar);

	return 0;
}

int NFCLuaScriptModule::OnRecordCommonEvent(const NFGUID& self, const RECORD_EVENT_DATA& xEventData, const NFIDataList::TData& oldVar, const NFIDataList::TData& newVar)
{
	DoRecordCommonEvent(self, xEventData, oldVar, newVar);

	return 0;
}

int NFCLuaScriptModule::OnClassCommonEvent(const NFGUID& self, const std::string& strClassName, const CLASS_OBJECT_EVENT eClassEvent, const NFIDataList& var)
{
	DoClassCommonEvent(m_pLogicClassModule, self, strClassName, eClassEvent, var);

	return 0;
}

int NFCLuaScriptModule::DoScript(const NFGUID& self, const std::string& strComponentName, const std::string& strFunction, const NFCDataList& arg)
{
	try
	{
		//fflua.call<void>(strFunction.c_str(), (NFINT64)m_pKernelModule, &self, &arg);
		luacpp::call<void>(lw, strFunction.c_str(), (NFINT64)m_pKernelModule, self, arg);
	}
	catch (string &err)
	{
		printf("%s\n", err.c_str());
		return 0;
	}

	return 1;
}

int NFCLuaScriptModule::DoEventScript(const NFGUID& self, const int nEventID, const std::string& strComponentName, const std::string& strFunction, const NFCDataList& arg)
{
	try
	{
		//fflua.call<void>(strFunction.c_str(), (NFINT64)m_pKernelModule, &self, nEventID, &arg);
		luacpp::call<void>(lw, strFunction.c_str(), (NFINT64)m_pKernelModule, self, nEventID, arg);
	}
	catch (string &err)
	{
		printf("%s\n", err.c_str());
		return 0;
	}
	return 1;
}

int NFCLuaScriptModule::DoHeartBeatScript(const NFGUID& self, const std::string& strHeartBeat, const float fTime, const int nCount, std::string& strComponentName, const std::string& strFunction)
{
	try
	{
		//fflua.call<void>(strFunction.c_str(), (NFINT64)m_pKernelModule, &self, strHeartBeat.c_str(), fTime, nCount);
		luacpp::call<void>(lw, strFunction.c_str(), (NFINT64)m_pKernelModule, self, strHeartBeat.c_str(), fTime, nCount);
	}
	catch (string &err)
	{
		printf("%s\n", err.c_str());
		return 0;
	}
	return 1;
}

int NFCLuaScriptModule::DoScriptPropertyCallBack(const NFGUID& self, const std::string& strPropertyName, const std::string& strComponentName, const std::string& strFunction, const NFIDataList::TData& oldVar, const NFIDataList::TData& newVar)
{
	try
	{
		//fflua.call<void>(strFunction.c_str(), (NFINT64)m_pKernelModule, &self, strPropertyName.c_str(), &oldVar, &newVar);
		luacpp::call<void>(lw, strFunction.c_str(), (NFINT64)m_pKernelModule, self, strPropertyName.c_str(), oldVar, newVar);
	}
	catch (string &err)
	{
		printf("%s\n", err.c_str());
		return 0;
	}
	return 1;
}

int NFCLuaScriptModule::DoScriptRecordCallBack(const NFGUID& self, const std::string& strRecordName, const std::string& strComponentName, const std::string& strFunction, const int nOpType, const int nRow, const int nCol, const NFCDataList::TData& oldVar, const NFCDataList::TData& newVar)
{
	try
	{
		//fflua.call<void>(strFunction.c_str(), (NFINT64)m_pKernelModule, &self, strRecordName.c_str(), nOpType, nRow, nCol, &oldVar, &newVar);
		luacpp::call<void>(lw, strFunction.c_str(), (NFINT64)m_pKernelModule, self, strRecordName.c_str(), nOpType, nRow, nCol, oldVar, newVar);
	}
	catch (string &err)
	{
		printf("%s\n", err.c_str());
		return 0;
	}
	return 1;
}

bool NFCLuaScriptModule::Regisger()
{
	luacpp::reg_cclass<NFGUID>::_reg(lw, "NFGUID")
		.constructor<void>()//ÎÞ²Î¹¹Ôì
		//.constructor<const test_class_A&>()//Ò»¸ö²ÎÊý¹¹Ôì
		.method("GetData", &NFGUID::GetData)
		.method("SetData", &NFGUID::SetData)
		.method("GetHead", &NFGUID::GetHead)
		.method("SetHead", &NFGUID::SetHead);

	luacpp::reg_cclass<NFIDataList>::_reg(lw, "NFIDataList");

	luacpp::reg_cclass<NFCDataList>::_reg(lw, "NFCDataList")
		.constructor<void>()//ÎÞ²Î¹¹Ôì
		//.constructor<const test_class_A&>()//Ò»¸ö²ÎÊý¹¹Ôì
		.method("IsEmpty", &NFCDataList::IsEmpty)
		.method("GetCount", &NFCDataList::GetCount)
		.method("Type", &NFCDataList::Type)
		.method("AddInt", &NFCDataList::AddInt)
		.method("AddFloat", &NFCDataList::AddFloat)
		.method("AddString", &NFCDataList::AddStringFromChar)
		.method("AddObject", &NFCDataList::AddObject)
		.method("SetInt", &NFCDataList::SetInt)
		.method("SetFloat", &NFCDataList::SetFloat)
		.method("SetString", &NFCDataList::SetString)
		.method("SetObject", &NFCDataList::SetObject)
		.method("Int", &NFCDataList::Int)
		.method("Float", &NFCDataList::Float)
		.method("String", &NFCDataList::String)
		.method("Object", &NFCDataList::Object);

	luacpp::reg_cclass<NFCDataList::TData>::_reg(lw, "TData")
		.constructor<void>()//ÎÞ²Î¹¹Ôì
		.method("GetFloat", &NFCDataList::TData::GetFloat)
		.method("GetInt", &NFCDataList::TData::GetInt)
		.method("GetObjectA", &NFCDataList::TData::GetObjectA)
		.method("GetString", &NFCDataList::TData::GetCharArr)
		.method("GetType", &NFCDataList::TData::GetType)
		.method("IsNullValue", &NFCDataList::TData::IsNullValue)
		.method("SetFloat", &NFCDataList::TData::SetFloat)
		.method("SetInt", &NFCDataList::TData::SetInt)
		.method("SetObject", &NFCDataList::TData::SetObject)
		.method("SetString", &NFCDataList::TData::SetString)
		.method("StringValEx", &NFCDataList::TData::StringValEx)
		.property("GetData", &NFCDataList::TData::variantData);

	luacpp::reg_cfun(lw, "DoEvent", &KernelModule_DoEvent);
	luacpp::reg_cfun(lw, "ExistElement", &KernelModule_ExistElement);
	luacpp::reg_cfun(lw, "GetElementPropertyInt", &KernelModule_GetElementPropertyInt);
	luacpp::reg_cfun(lw, "GetElementPropertyFloat", &KernelModule_GetElementPropertyFloat);
	luacpp::reg_cfun(lw, "GetElementPropertyString", &KernelModule_GetElementPropertyString);
	luacpp::reg_cfun(lw, "AddPropertyCallBack", &KernelModule_AddPropertyCallBack);
	luacpp::reg_cfun(lw, "AddRecordCallBack", &KernelModule_AddRecordCallBack);
	luacpp::reg_cfun(lw, "AddEventCallBack", &KernelModule_AddEventCallBack);
	luacpp::reg_cfun(lw, "AddHeartBeat", &KernelModule_AddHeartBeat);
	luacpp::reg_cfun(lw, "FindHeartBeat", &KernelModule_FindHeartBeat);
	luacpp::reg_cfun(lw, "RemoveHeartBeat", &KernelModule_RemoveHeartBeat);
	luacpp::reg_cfun(lw, "ExistContainer", &KernelModule_ExistContainer);
	luacpp::reg_cfun(lw, "SetPropertyInt", &KernelModule_SetPropertyInt);
	luacpp::reg_cfun(lw, "SetPropertyFloat", &KernelModule_SetPropertyFloat);
	luacpp::reg_cfun(lw, "SetPropertyString", &KernelModule_SetPropertyString);
	luacpp::reg_cfun(lw, "SetPropertyObject", &KernelModule_SetPropertyObject);
	luacpp::reg_cfun(lw, "GetPropertyInt", &KernelModule_GetPropertyInt);
	luacpp::reg_cfun(lw, "GetPropertyFloat", &KernelModule_GetPropertyFloat);
	luacpp::reg_cfun(lw, "GetPropertyString", &KernelModule_GetPropertyString);
	luacpp::reg_cfun(lw, "GetPropertyObject", &KernelModule_GetPropertyObject);
	luacpp::reg_cfun(lw, "SetRecordInt", &KernelModule_SetRecordInt);
	luacpp::reg_cfun(lw, "SetRecordFloat", &KernelModule_SetRecordFloat);
	luacpp::reg_cfun(lw, "SetRecordString", &KernelModule_SetRecordString);
	luacpp::reg_cfun(lw, "SetRecordObject", &KernelModule_SetRecordObject);
	luacpp::reg_cfun(lw, "GetRecordInt", &KernelModule_GetRecordInt);
	luacpp::reg_cfun(lw, "GetRecordFloat", &KernelModule_GetRecordFloat);
	luacpp::reg_cfun(lw, "GetRecordString", &KernelModule_GetRecordString);
	luacpp::reg_cfun(lw, "GetRecordObject", &KernelModule_GetRecordObject);
	luacpp::reg_cfun(lw, "AddRow", &KernelModule_AddRow);

	return true;
}

int NFCLuaScriptModule::DoClassCommonScript(const NFGUID& self, const std::string& strComponentName, const std::string& strFunction)
{
	try
	{
		//fflua.call<void>(strFunction.c_str(), (NFINT64)m_pKernelModule);
		luacpp::call<void>(lw, strFunction.c_str(), (NFINT64)m_pKernelModule, self);
	}
	catch (string &err)
	{
		printf("%s\n", err.c_str());
		return 0;
	}
	return 0;
}
<commit_msg>optimize reload lua script<commit_after>// -------------------------------------------------------------------------
//    @FileName      :    NFCLuaScriptModule.cpp
//    @Author           :    LvSheng.Huang
//    @Date             :    2013-01-02
//    @Module           :    NFCLuaScriptModule
//    @Desc             :
// -------------------------------------------------------------------------

#include "NFCLuaScriptModule.h"
#include "NFLuaScriptPlugin.h"
#include <assert.h>

#define TRY_RUN_GLOBAL_SCRIPT_FUN0(strFuncName)  try{luacpp::call<void>(lw, strFuncName);} catch (string &err){printf("%s\n", err.c_str());}
#define TRY_RUN_GLOBAL_SCRIPT_FUN1(strFuncName, arg1)  try{luacpp::call<void>(lw, strFuncName, arg1);} catch (string &err){printf("%s\n", err.c_str());}

#define TRY_LOAD_SCRIPT_FLE(strFileName)  try{lw.dofile(strFileName);} catch (string &err){printf("%s\n", err.c_str());}

bool NFCLuaScriptModule::Init()
{
	mnTime = pPluginManager->GetNowTime();

	//std::shared_ptr<NFILogicClass> pClass = m_pLogicClassModule->First();
	//while (pClass.get())
	//{
	//	std::shared_ptr<NFIComponent> pComponent = pClass->GetComponentManager()->First();
	//	while (pComponent.get())
	//	{
	//		if (!CheckCompomentStatus(pComponent->GetComponentName()))
	//		{
	//			assert(0);
	//		}

	//		pComponent = pClass->GetComponentManager()->Next();
	//	}

	//	pClass = m_pLogicClassModule->Next();
	//}

	m_pKernelModule = pPluginManager->FindModule<NFIKernelModule>("NFCKernelModule");
	m_pLogicClassModule = pPluginManager->FindModule<NFILogicClassModule>("NFCLogicClassModule");
	m_pElementInfoModule = pPluginManager->FindModule<NFIElementInfoModule>("NFCElementInfoModule");

	assert(NULL != m_pKernelModule);
	assert(NULL != m_pLogicClassModule);
	assert(NULL != m_pElementInfoModule);

	Regisger();

	TRY_LOAD_SCRIPT_FLE("script_init.lua");
	TRY_RUN_GLOBAL_SCRIPT_FUN1("init_script_system", m_pKernelModule);
	TRY_LOAD_SCRIPT_FLE("script_list.lua");

	TRY_RUN_GLOBAL_SCRIPT_FUN0("Init");

	return true;
}

bool NFCLuaScriptModule::AfterInit()
{
	TRY_RUN_GLOBAL_SCRIPT_FUN0("AfterInit");

	//add all callback
	m_pKernelModule->ResgisterCommonPropertyEvent(this, &NFCLuaScriptModule::OnPropertyCommEvent);
	m_pKernelModule->ResgisterCommonRecordEvent(this, &NFCLuaScriptModule::OnRecordCommonEvent);
	m_pKernelModule->ResgisterCommonClassEvent(this, &NFCLuaScriptModule::OnClassCommonEvent);

	return true;
}

bool NFCLuaScriptModule::Shut()
{
	TRY_RUN_GLOBAL_SCRIPT_FUN0("Shut");

	return true;
}

bool NFCLuaScriptModule::Execute()
{
	//10秒钟reload一次
	if (pPluginManager->GetNowTime()- mnTime > 5)
	{
		mnTime = pPluginManager->GetNowTime();

		TRY_RUN_GLOBAL_SCRIPT_FUN0("Execute");

		TRY_LOAD_SCRIPT_FLE("script_reload.lua")

	}

	return true;
}

bool NFCLuaScriptModule::BeforeShut()
{
	TRY_RUN_GLOBAL_SCRIPT_FUN0("BeforeShut");

	return true;
}

int NFCLuaScriptModule::OnPropertyCommEvent(const NFGUID& self, const std::string& strPropertyName, const NFIDataList::TData& oldVar, const NFIDataList::TData& newVar)
{
	DoPropertyCommEvent(self, strPropertyName, oldVar, newVar);

	return 0;
}

int NFCLuaScriptModule::OnRecordCommonEvent(const NFGUID& self, const RECORD_EVENT_DATA& xEventData, const NFIDataList::TData& oldVar, const NFIDataList::TData& newVar)
{
	DoRecordCommonEvent(self, xEventData, oldVar, newVar);

	return 0;
}

int NFCLuaScriptModule::OnClassCommonEvent(const NFGUID& self, const std::string& strClassName, const CLASS_OBJECT_EVENT eClassEvent, const NFIDataList& var)
{
	DoClassCommonEvent(m_pLogicClassModule, self, strClassName, eClassEvent, var);

	return 0;
}

int NFCLuaScriptModule::DoScript(const NFGUID& self, const std::string& strComponentName, const std::string& strFunction, const NFCDataList& arg)
{
	try
	{
		//fflua.call<void>(strFunction.c_str(), (NFINT64)m_pKernelModule, &self, &arg);
		luacpp::call<void>(lw, strFunction.c_str(), (NFINT64)m_pKernelModule, self, arg);
	}
	catch (string &err)
	{
		printf("%s\n", err.c_str());
		return 0;
	}

	return 1;
}

int NFCLuaScriptModule::DoEventScript(const NFGUID& self, const int nEventID, const std::string& strComponentName, const std::string& strFunction, const NFCDataList& arg)
{
	try
	{
		//fflua.call<void>(strFunction.c_str(), (NFINT64)m_pKernelModule, &self, nEventID, &arg);
		luacpp::call<void>(lw, strFunction.c_str(), (NFINT64)m_pKernelModule, self, nEventID, arg);
	}
	catch (string &err)
	{
		printf("%s\n", err.c_str());
		return 0;
	}
	return 1;
}

int NFCLuaScriptModule::DoHeartBeatScript(const NFGUID& self, const std::string& strHeartBeat, const float fTime, const int nCount, std::string& strComponentName, const std::string& strFunction)
{
	try
	{
		//fflua.call<void>(strFunction.c_str(), (NFINT64)m_pKernelModule, &self, strHeartBeat.c_str(), fTime, nCount);
		luacpp::call<void>(lw, strFunction.c_str(), (NFINT64)m_pKernelModule, self, strHeartBeat.c_str(), fTime, nCount);
	}
	catch (string &err)
	{
		printf("%s\n", err.c_str());
		return 0;
	}
	return 1;
}

int NFCLuaScriptModule::DoScriptPropertyCallBack(const NFGUID& self, const std::string& strPropertyName, const std::string& strComponentName, const std::string& strFunction, const NFIDataList::TData& oldVar, const NFIDataList::TData& newVar)
{
	try
	{
		//fflua.call<void>(strFunction.c_str(), (NFINT64)m_pKernelModule, &self, strPropertyName.c_str(), &oldVar, &newVar);
		luacpp::call<void>(lw, strFunction.c_str(), (NFINT64)m_pKernelModule, self, strPropertyName.c_str(), oldVar, newVar);
	}
	catch (string &err)
	{
		printf("%s\n", err.c_str());
		return 0;
	}
	return 1;
}

int NFCLuaScriptModule::DoScriptRecordCallBack(const NFGUID& self, const std::string& strRecordName, const std::string& strComponentName, const std::string& strFunction, const int nOpType, const int nRow, const int nCol, const NFCDataList::TData& oldVar, const NFCDataList::TData& newVar)
{
	try
	{
		//fflua.call<void>(strFunction.c_str(), (NFINT64)m_pKernelModule, &self, strRecordName.c_str(), nOpType, nRow, nCol, &oldVar, &newVar);
		luacpp::call<void>(lw, strFunction.c_str(), (NFINT64)m_pKernelModule, self, strRecordName.c_str(), nOpType, nRow, nCol, oldVar, newVar);
	}
	catch (string &err)
	{
		printf("%s\n", err.c_str());
		return 0;
	}
	return 1;
}

bool NFCLuaScriptModule::Regisger()
{
	luacpp::reg_cclass<NFGUID>::_reg(lw, "NFGUID")
		.constructor<void>()//ÎÞ²Î¹¹Ôì
		//.constructor<const test_class_A&>()//Ò»¸ö²ÎÊý¹¹Ôì
		.method("GetData", &NFGUID::GetData)
		.method("SetData", &NFGUID::SetData)
		.method("GetHead", &NFGUID::GetHead)
		.method("SetHead", &NFGUID::SetHead);

	luacpp::reg_cclass<NFIDataList>::_reg(lw, "NFIDataList");

	luacpp::reg_cclass<NFCDataList>::_reg(lw, "NFCDataList")
		.constructor<void>()//ÎÞ²Î¹¹Ôì
		//.constructor<const test_class_A&>()//Ò»¸ö²ÎÊý¹¹Ôì
		.method("IsEmpty", &NFCDataList::IsEmpty)
		.method("GetCount", &NFCDataList::GetCount)
		.method("Type", &NFCDataList::Type)
		.method("AddInt", &NFCDataList::AddInt)
		.method("AddFloat", &NFCDataList::AddFloat)
		.method("AddString", &NFCDataList::AddStringFromChar)
		.method("AddObject", &NFCDataList::AddObject)
		.method("SetInt", &NFCDataList::SetInt)
		.method("SetFloat", &NFCDataList::SetFloat)
		.method("SetString", &NFCDataList::SetString)
		.method("SetObject", &NFCDataList::SetObject)
		.method("Int", &NFCDataList::Int)
		.method("Float", &NFCDataList::Float)
		.method("String", &NFCDataList::String)
		.method("Object", &NFCDataList::Object);

	luacpp::reg_cclass<NFCDataList::TData>::_reg(lw, "TData")
		.constructor<void>()//ÎÞ²Î¹¹Ôì
		.method("GetFloat", &NFCDataList::TData::GetFloat)
		.method("GetInt", &NFCDataList::TData::GetInt)
		.method("GetObjectA", &NFCDataList::TData::GetObjectA)
		.method("GetString", &NFCDataList::TData::GetCharArr)
		.method("GetType", &NFCDataList::TData::GetType)
		.method("IsNullValue", &NFCDataList::TData::IsNullValue)
		.method("SetFloat", &NFCDataList::TData::SetFloat)
		.method("SetInt", &NFCDataList::TData::SetInt)
		.method("SetObject", &NFCDataList::TData::SetObject)
		.method("SetString", &NFCDataList::TData::SetString)
		.method("StringValEx", &NFCDataList::TData::StringValEx)
		.property("GetData", &NFCDataList::TData::variantData);

	luacpp::reg_cfun(lw, "DoEvent", &KernelModule_DoEvent);
	luacpp::reg_cfun(lw, "ExistElement", &KernelModule_ExistElement);
	luacpp::reg_cfun(lw, "GetElementPropertyInt", &KernelModule_GetElementPropertyInt);
	luacpp::reg_cfun(lw, "GetElementPropertyFloat", &KernelModule_GetElementPropertyFloat);
	luacpp::reg_cfun(lw, "GetElementPropertyString", &KernelModule_GetElementPropertyString);
	luacpp::reg_cfun(lw, "AddPropertyCallBack", &KernelModule_AddPropertyCallBack);
	luacpp::reg_cfun(lw, "AddRecordCallBack", &KernelModule_AddRecordCallBack);
	luacpp::reg_cfun(lw, "AddEventCallBack", &KernelModule_AddEventCallBack);
	luacpp::reg_cfun(lw, "AddHeartBeat", &KernelModule_AddHeartBeat);
	luacpp::reg_cfun(lw, "FindHeartBeat", &KernelModule_FindHeartBeat);
	luacpp::reg_cfun(lw, "RemoveHeartBeat", &KernelModule_RemoveHeartBeat);
	luacpp::reg_cfun(lw, "ExistContainer", &KernelModule_ExistContainer);
	luacpp::reg_cfun(lw, "SetPropertyInt", &KernelModule_SetPropertyInt);
	luacpp::reg_cfun(lw, "SetPropertyFloat", &KernelModule_SetPropertyFloat);
	luacpp::reg_cfun(lw, "SetPropertyString", &KernelModule_SetPropertyString);
	luacpp::reg_cfun(lw, "SetPropertyObject", &KernelModule_SetPropertyObject);
	luacpp::reg_cfun(lw, "GetPropertyInt", &KernelModule_GetPropertyInt);
	luacpp::reg_cfun(lw, "GetPropertyFloat", &KernelModule_GetPropertyFloat);
	luacpp::reg_cfun(lw, "GetPropertyString", &KernelModule_GetPropertyString);
	luacpp::reg_cfun(lw, "GetPropertyObject", &KernelModule_GetPropertyObject);
	luacpp::reg_cfun(lw, "SetRecordInt", &KernelModule_SetRecordInt);
	luacpp::reg_cfun(lw, "SetRecordFloat", &KernelModule_SetRecordFloat);
	luacpp::reg_cfun(lw, "SetRecordString", &KernelModule_SetRecordString);
	luacpp::reg_cfun(lw, "SetRecordObject", &KernelModule_SetRecordObject);
	luacpp::reg_cfun(lw, "GetRecordInt", &KernelModule_GetRecordInt);
	luacpp::reg_cfun(lw, "GetRecordFloat", &KernelModule_GetRecordFloat);
	luacpp::reg_cfun(lw, "GetRecordString", &KernelModule_GetRecordString);
	luacpp::reg_cfun(lw, "GetRecordObject", &KernelModule_GetRecordObject);
	luacpp::reg_cfun(lw, "AddRow", &KernelModule_AddRow);

	return true;
}

int NFCLuaScriptModule::DoClassCommonScript(const NFGUID& self, const std::string& strComponentName, const std::string& strFunction)
{
	try
	{
		//fflua.call<void>(strFunction.c_str(), (NFINT64)m_pKernelModule);
		luacpp::call<void>(lw, strFunction.c_str(), (NFINT64)m_pKernelModule, self);
	}
	catch (string &err)
	{
		printf("%s\n", err.c_str());
		return 0;
	}
	return 0;
}
<|endoftext|>