<commit_before>/*
 *  about_dialog.cpp
 *  PHD Guiding
 *
 *  Created by Sylvain Girard.
 *  Copyright (c) 2013 Sylvain Girard.
 *  All rights reserved.
 *
 *  This source code is distributed under the following "BSD" license
 *  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 Craig Stark, Stark Labs 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 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 "phd.h"
#include "about_dialog.h"
#include <wx/fs_mem.h>
#include <wx/html/htmlwin.h>

BEGIN_EVENT_TABLE(AboutDialog, wxDialog)
    EVT_HTML_LINK_CLICKED(ABOUT_LINK,AboutDialog::OnLink)
END_EVENT_TABLE()

AboutDialog::AboutDialog(void) :
wxDialog(pFrame, wxID_ANY, _T("About ") APPNAME, wxDefaultPosition, wxDefaultSize, wxCAPTION | wxCLOSE_BOX)
{
    SetBackgroundColour(*wxWHITE);

    wxBoxSizer *pSizer = new wxBoxSizer(wxHORIZONTAL);

    #include "icons/phd2_64.png.h"
    wxBitmap phd2(wxBITMAP_PNG_FROM_DATA(phd2_64));
    wxStaticBitmap *pImage = new wxStaticBitmap(this, wxID_ANY, phd2);

    wxFileSystem::AddHandler(new wxMemoryFSHandler);
    wxMemoryFSHandler::AddFile("about.html", wxString::Format(
        ""
        "
%s %s
"
        "PHD2 home page - openphdguiding.org
"
        "PHD2 open source project page

"
        ""
        "Credits:
"
        "
"
        "
"
        "Craig Stark	"
        "Bret McKee	"
        "
"
        "
"
        "Andy Galasso	"
        "Bernhard Reutner-Fischer	"
        "
"
        "
"
        "Stefan Elste	"
        "Geoffrey Hausheer	"
        "
"
        "
"
        "Jared Wellman	"
        "John Wainwright	"
        "
"
        "
"
        "Sylvain Girard	"
        "Bruce Waddington	"
        "
"
        "
"
        "Max Chen	"
        "Carsten Przygoda	"
        "
"
        "
"
        "Hans Lambermont	"
        "David Ault	"
        "
"
        "
"
        "Markus Wieczorek	"
        "Linkage	"
        "
"
        "
"
        "Robin Glover	"
        "Patrick Chevalley	"
        "
"
        "
"
        "Scott Edwards	"
        "Eiji Kaneshige	"
        "
"
        "
"
        "Konstantin Menshikoff	"
        "Jakub Bartas	"
        "
"
        "
"
        "Javier R	"
        "Oleh Malyi	"
        "
"
        "
"
        "Tsung-Chi Wu	"
        "Raffi Enficiaud	"
        "
"
        "
"
        "Sabin Fota	"
        "Dylan O'Donnell	"
        "
"
        "
"
        "Katsuhiro Kojima	"
        "	"
        "
"
        "

"
        "
"
        "
"
        "Copyright 2006-2013 Craig Stark
"
        "Copyright 2009 Geoffrey Hausheer
"
        "Copyright 2012-2013 Bret McKee
"
        "Copyright 2013 Sylvain Girard
"
        "Copyright 2013-2015 Andy Galasso
"
        "Copyright 2013-2014 Bruce Waddington
"
        "Copyright 2014 Hans Lambermont
"
        "Copyright 2014 Robin Glover
"
        "Copyright 2014-2015 Max Planck Society
"
        ""
        "", APPNAME, FULLVER));
    wxHtmlWindow *pHtml;
    pHtml = new wxHtmlWindow(this, ABOUT_LINK, wxDefaultPosition, wxSize(380, 540), wxHW_SCROLLBAR_AUTO);
    pHtml->SetBorders(0);
    pHtml->LoadPage("memory:about.html");
    pHtml->SetSize(pHtml->GetInternalRepresentation()->GetWidth(), pHtml->GetInternalRepresentation()->GetHeight());

    pSizer->Add(pImage, wxSizerFlags(0).Border(wxALL, 10));
    pSizer->Add(pHtml, wxSizerFlags(0).Border(wxALL, 10));

    wxBoxSizer *pTopLevelSizer = new wxBoxSizer(wxVERTICAL);
    pTopLevelSizer->Add(pSizer, wxSizerFlags(0).Expand());
    pTopLevelSizer->Add(CreateButtonSizer(wxOK), wxSizerFlags(0).Expand().Border(wxALL, 10));
    SetSizerAndFit(pTopLevelSizer);
}

AboutDialog::~AboutDialog(void)
{
    wxMemoryFSHandler::RemoveFile("about.html");
}

void AboutDialog::OnLink(wxHtmlLinkEvent & event)
{
    wxLaunchDefaultBrowser(event.GetLinkInfo().GetHref());
}
<commit_msg>Add Simon Taylor to About window<commit_after>/*
 *  about_dialog.cpp
 *  PHD Guiding
 *
 *  Created by Sylvain Girard.
 *  Copyright (c) 2013 Sylvain Girard.
 *  All rights reserved.
 *
 *  This source code is distributed under the following "BSD" license
 *  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 Craig Stark, Stark Labs 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 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 "phd.h"
#include "about_dialog.h"
#include <wx/fs_mem.h>
#include <wx/html/htmlwin.h>

BEGIN_EVENT_TABLE(AboutDialog, wxDialog)
    EVT_HTML_LINK_CLICKED(ABOUT_LINK,AboutDialog::OnLink)
END_EVENT_TABLE()

AboutDialog::AboutDialog(void) :
wxDialog(pFrame, wxID_ANY, _T("About ") APPNAME, wxDefaultPosition, wxDefaultSize, wxCAPTION | wxCLOSE_BOX)
{
    SetBackgroundColour(*wxWHITE);

    wxBoxSizer *pSizer = new wxBoxSizer(wxHORIZONTAL);

    #include "icons/phd2_64.png.h"
    wxBitmap phd2(wxBITMAP_PNG_FROM_DATA(phd2_64));
    wxStaticBitmap *pImage = new wxStaticBitmap(this, wxID_ANY, phd2);

    wxFileSystem::AddHandler(new wxMemoryFSHandler);
    wxMemoryFSHandler::AddFile("about.html", wxString::Format(
        ""
        "
%s %s
"
        "PHD2 home page - openphdguiding.org
"
        "PHD2 open source project page

"
        ""
        "Credits:
"
        "
"
        "
"
        "Craig Stark	"
        "Bret McKee	"
        "
"
        "
"
        "Andy Galasso	"
        "Bernhard Reutner-Fischer	"
        "
"
        "
"
        "Stefan Elste	"
        "Geoffrey Hausheer	"
        "
"
        "
"
        "Jared Wellman	"
        "John Wainwright	"
        "
"
        "
"
        "Sylvain Girard	"
        "Bruce Waddington	"
        "
"
        "
"
        "Max Chen	"
        "Carsten Przygoda	"
        "
"
        "
"
        "Hans Lambermont	"
        "David Ault	"
        "
"
        "
"
        "Markus Wieczorek	"
        "Linkage	"
        "
"
        "
"
        "Robin Glover	"
        "Patrick Chevalley	"
        "
"
        "
"
        "Scott Edwards	"
        "Eiji Kaneshige	"
        "
"
        "
"
        "Konstantin Menshikoff	"
        "Jakub Bartas	"
        "
"
        "
"
        "Javier R	"
        "Oleh Malyi	"
        "
"
        "
"
        "Tsung-Chi Wu	"
        "Raffi Enficiaud	"
        "
"
        "
"
        "Sabin Fota	"
        "Dylan O'Donnell	"
        "
"
        "
"
        "Katsuhiro Kojima	"
        "Simon Taylor	"
        "
"
        "

"
        "
"
        "
"
        "Copyright 2006-2013 Craig Stark
"
        "Copyright 2009 Geoffrey Hausheer
"
        "Copyright 2012-2013 Bret McKee
"
        "Copyright 2013 Sylvain Girard
"
        "Copyright 2013-2015 Andy Galasso
"
        "Copyright 2013-2014 Bruce Waddington
"
        "Copyright 2014 Hans Lambermont
"
        "Copyright 2014 Robin Glover
"
        "Copyright 2014-2015 Max Planck Society
"
        ""
        "", APPNAME, FULLVER));
    wxHtmlWindow *pHtml;
    pHtml = new wxHtmlWindow(this, ABOUT_LINK, wxDefaultPosition, wxSize(380, 540), wxHW_SCROLLBAR_AUTO);
    pHtml->SetBorders(0);
    pHtml->LoadPage("memory:about.html");
    pHtml->SetSize(pHtml->GetInternalRepresentation()->GetWidth(), pHtml->GetInternalRepresentation()->GetHeight());

    pSizer->Add(pImage, wxSizerFlags(0).Border(wxALL, 10));
    pSizer->Add(pHtml, wxSizerFlags(0).Border(wxALL, 10));

    wxBoxSizer *pTopLevelSizer = new wxBoxSizer(wxVERTICAL);
    pTopLevelSizer->Add(pSizer, wxSizerFlags(0).Expand());
    pTopLevelSizer->Add(CreateButtonSizer(wxOK), wxSizerFlags(0).Expand().Border(wxALL, 10));
    SetSizerAndFit(pTopLevelSizer);
}

AboutDialog::~AboutDialog(void)
{
    wxMemoryFSHandler::RemoveFile("about.html");
}

void AboutDialog::OnLink(wxHtmlLinkEvent & event)
{
    wxLaunchDefaultBrowser(event.GetLinkInfo().GetHref());
}
<|endoftext|>


<commit_before>#include <nntpchan/event.hpp>
#include <sys/types.h>
#include <sys/event.h>

namespace nntpchan
{
namespace ev
{
    template<size_t bufsz>
    struct KqueueLoop : public Loop
    {
        int kfd;
        size_t conns;
        char readbuf[bufsz];

        KqueueLoop() : kfd(kqueue()), conns(0)
        {

        };

        virtual ~KqueueLoop()
        {
            ::close(kfd);
        }

        virtual bool TrackConn(ev::io * handler)
        {
            struct kevent event;
            short filter = 0;
            if(handler->readable() || handler->acceptable())
            {
                filter |= EVFILT_READ;
            }
            if(handler->writable())
            {
                filter |= EVFILT_WRITE;
            }
            EV_SET(&event, handler->fd, filter, EV_ADD | EV_CLEAR, 0, 0, handler);
            int ret = kevent(kfd, &event, 1, nullptr, 0, nullptr);
            if(ret == -1) return false;
            if(event.flags & EV_ERROR)
            {
                std::cerr << "KqueueLoop::TrackConn() kevent failed: " << strerror(event.data) << std::endl;
                return false;
            }
            ++conns;
            return true;
        }

        virtual void UntrackConn(ev::io * handler)
        {
            struct kevent event;
            short filter = 0;
            if(handler->readable() || handler->acceptable())
            {
                filter |= EVFILT_READ;
            }
            if(handler->writable())
            {
                filter |= EVFILT_WRITE;
            }
            EV_SET(&event, handler->fd, filter, EV_DELETE, 0, 0, handler);
            int ret = kevent(kfd, &event, 1, nullptr, 0, nullptr);
            if(ret == -1 || event.flags & EV_ERROR)
            {
                std::cerr << "KqueueLoop::UntrackConn() kevent failed: " << strerror(event.data) << std::endl;
                return false;
            }
            --conns;
            return true;
        }

        virtual void Run()
        {
            struct kevent events[512];
            struct kevent * event;
            io * handler;
            int ret, idx;
            do
            {
                idx = 0;
                ret = kevent(kfd, nullptr, 0, &event, 512, nullptr);
                if(ret > 0)
                {
                    while(idx < ret)
                    {
                        event = &events[idx++];
                        handler = static_cast<io *>(ev->udata);
                        if(event->flags & EV_EOF)
                        {
                            handler->close();
                            delete handler;
                            continue;
                        }
                        if(event->filter & EVFILT_READ && handler->acceptable())
                        {
                            int backlog = event->data;
                            while(backlog)
                            {
                                handler->accept();
                                --backlog;
                            }
                        }

                        if(event->filter & EVFILT_READ && handler->readable())
                        {
                            int readed = 0;
                            int readnum = event->data;
                            while(readnum > sizeof(readbuf))
                            {
                                int r = handler->read(readbuf, sizeof(readbuf));
                                if(r > 0)
                                {
                                    readnum -= r;
                                    readed += r;
                                }
                                else
                                    readnum = 0;
                            }
                            if(readnum && readed != -1)
                            {
                               int r = handler->read(readbuf, readnum);
                               if(r > 0)
                                 readed += r;
                               else
                                 readed = r;
                            }
                        }
                        if(event->filter & EVFILT_WRITE && handler->writeable())
                        {
                            int writespace = event->data;
                            int written = handler->write(writespace);
                            if(written > 0)
                            {

                            }
                        }
                        if(!handler->keepalive())
                        {
                            handler->close();
                            delete handler;
                        }
                    }
                }
            }
            while(ret != -1);
        }
    };
}
}<commit_msg>typofix<commit_after>#include <nntpchan/event.hpp>
#include <sys/types.h>
#include <sys/event.h>

namespace nntpchan
{
namespace ev
{
    template<size_t bufsz>
    struct KqueueLoop : public Loop
    {
        int kfd;
        size_t conns;
        char readbuf[bufsz];

        KqueueLoop() : kfd(kqueue()), conns(0)
        {

        };

        virtual ~KqueueLoop()
        {
            ::close(kfd);
        }

        virtual bool TrackConn(ev::io * handler)
        {
            struct kevent event;
            short filter = 0;
            if(handler->readable() || handler->acceptable())
            {
                filter |= EVFILT_READ;
            }
            if(handler->writeable())
            {
                filter |= EVFILT_WRITE;
            }
            EV_SET(&event, handler->fd, filter, EV_ADD | EV_CLEAR, 0, 0, handler);
            int ret = kevent(kfd, &event, 1, nullptr, 0, nullptr);
            if(ret == -1) return false;
            if(event.flags & EV_ERROR)
            {
                std::cerr << "KqueueLoop::TrackConn() kevent failed: " << strerror(event.data) << std::endl;
                return false;
            }
            ++conns;
            return true;
        }

        virtual void UntrackConn(ev::io * handler)
        {
            struct kevent event;
            short filter = 0;
            if(handler->readable() || handler->acceptable())
            {
                filter |= EVFILT_READ;
            }
            if(handler->writable())
            {
                filter |= EVFILT_WRITE;
            }
            EV_SET(&event, handler->fd, filter, EV_DELETE, 0, 0, handler);
            int ret = kevent(kfd, &event, 1, nullptr, 0, nullptr);
            if(ret == -1 || event.flags & EV_ERROR)
            {
                std::cerr << "KqueueLoop::UntrackConn() kevent failed: " << strerror(event.data) << std::endl;
                return false;
            }
            --conns;
            return true;
        }

        virtual void Run()
        {
            struct kevent events[512];
            struct kevent * event;
            io * handler;
            int ret, idx;
            do
            {
                idx = 0;
                ret = kevent(kfd, nullptr, 0, &event, 512, nullptr);
                if(ret > 0)
                {
                    while(idx < ret)
                    {
                        event = &events[idx++];
                        handler = static_cast<io *>(ev->udata);
                        if(event->flags & EV_EOF)
                        {
                            handler->close();
                            delete handler;
                            continue;
                        }
                        if(event->filter & EVFILT_READ && handler->acceptable())
                        {
                            int backlog = event->data;
                            while(backlog)
                            {
                                handler->accept();
                                --backlog;
                            }
                        }

                        if(event->filter & EVFILT_READ && handler->readable())
                        {
                            int readed = 0;
                            int readnum = event->data;
                            while(readnum > sizeof(readbuf))
                            {
                                int r = handler->read(readbuf, sizeof(readbuf));
                                if(r > 0)
                                {
                                    readnum -= r;
                                    readed += r;
                                }
                                else
                                    readnum = 0;
                            }
                            if(readnum && readed != -1)
                            {
                               int r = handler->read(readbuf, readnum);
                               if(r > 0)
                                 readed += r;
                               else
                                 readed = r;
                            }
                        }
                        if(event->filter & EVFILT_WRITE && handler->writeable())
                        {
                            int writespace = event->data;
                            int written = handler->write(writespace);
                            if(written > 0)
                            {

                            }
                        }
                        if(!handler->keepalive())
                        {
                            handler->close();
                            delete handler;
                        }
                    }
                }
            }
            while(ret != -1);
        }
    };
}
}<|endoftext|>


<commit_before>//------------------------------------------------------------------------------
// Copyright (c) 2016 by contributors. 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.
//------------------------------------------------------------------------------

/*
Author: Yuze Liao and Chao Ma (mctt90@gmail.com)

This file is the implementations of Nesterov updater.
*/

#include "src/updater/nesterov_updater.h"

namespace xLearn {

// This function need to be invoked before using this class.
void Nesterov::Initialize(const HyperParam& hyper_param) {
  CHECK_GT(hyper_param.learning_rate, 0);
  CHECK_GT(hyper_param.regu_lambda_1, 0);
  CHECK_GT(hyper_param.regu_lambda_2, 0);
  CHECK_GT(hyper_param.decay_rate, 0);
  learning_rate_ = hyper_param.learning_rate;
  regu_lambda_1_ = hyper_param.regu_lambda_1;
  regu_lambda_2_ = hyper_param.regu_lambda_2;
  regu_type_ = hyper_param.regu_type;
  rho_ = hyper_param.decay_rate;
  // Allocating memory for the velocity vector
  try {
    v_.resize(hyper_param.num_param, 0.0);
  } catch (std::bad_alloc&) {
    LOG(FATAL) << "Cannot allocate enough memory for current    \
                   model parameters. Parameter size: "
               << hyper_param.num_param;
  }
}

// Nesterov updater:
// [ old_v = v ]
// [ v = rho * v - learning_rate * gradient ]
// [ x += -rho * old_v + (1+rho) * v ]
void Nesterov::Update(const index_t id,
                      const real_t grad,
                      std::vector<real_t>& param) {
  // Do not check anything here
  real_t old_v = v_[id];
  v_[id] = rho_ * v_[id] - learning_rate_ * grad;
  param[id] += -rho_ * old_v + (1+rho_) * v_[id];
}

// Update a continous space of model parameters by
// using sse/avx to speed up.
void Nesterov::BatchUpdate(const std::vector<real_t>& value,
                           const index_t start_id,
                           std::vector<real_t>& param) {
  CHECK_EQ(value.empty(), false);
  // Ensuring for sse/avx
  CHECK_EQ(value.size() % _MMX_INCREMENT, 0);
  __MX _learning_rate = _MMX_SET1_PS(learning_rate_);
  __MX _rho = _MMX_SET1_PS(rho_);
  __MX _rho_add_1 = _MMX_SET1_PS(rho_+1);
  // [ old_v = v ]
  // [ v = rho * v - learning_rate * gradient ]
  // [ x += -rho * old_v + (1+rho) * v ]
  for (int i = 0; i < value.size(); i += _MMX_INCREMENT) {
    index_t id = start_id + i;
    __MX _grad = _MMX_LOAD_PS(value.data() + i);
    __MX _v = _MMX_LOAD_PS(v_.data() + id);
    __MX _old_v = _MMX_LOAD_PS(v_.data() + id);
    __MX _w = _MMX_LOAD_PS(param.data() + id);
    _v = _MMX_SUB_PS(_MMX_MUL_PS(_rho, _v),
                     _MMX_MUL_PS(_learning_rate, _grad));
    _MMX_STORE_PS(v_.data() + id, _v);
    __MX _tmp = _MMX_SUB_PS(_MMX_MUL_PS(_rho_add_1, _v),
                            _MMX_MUL_PS(_rho, _old_v));
    _MMX_STORE_PS(param.data() + id,
                 _MMX_ADD_PS(_w, _tmp));
  }
}

} // namespace xLearn
<commit_msg>updarte nesterov<commit_after>//------------------------------------------------------------------------------
// Copyright (c) 2016 by contributors. 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.
//------------------------------------------------------------------------------

/*
Author: Yuze Liao and Chao Ma (mctt90@gmail.com)

This file is the implementations of Nesterov updater.
*/

#include "src/updater/nesterov_updater.h"

namespace xLearn {

// This function need to be invoked before using this class.
void Nesterov::Initialize(const HyperParam& hyper_param) {
  CHECK_GT(hyper_param.learning_rate, 0);
  CHECK_GT(hyper_param.regu_lambda_1, 0);
  CHECK_GT(hyper_param.regu_lambda_2, 0);
  CHECK_GT(hyper_param.decay_rate, 0);
  learning_rate_ = hyper_param.learning_rate;
  regu_lambda_1_ = hyper_param.regu_lambda_1;
  regu_lambda_2_ = hyper_param.regu_lambda_2;
  regu_type_ = hyper_param.regu_type;
  rho_ = hyper_param.decay_rate;
  // Allocating memory for the velocity vector
  try {
    v_.resize(hyper_param.num_param, 0.0);
  } catch (std::bad_alloc&) {
    LOG(FATAL) << "Cannot allocate enough memory for current    \
                   model parameters. Parameter size: "
               << hyper_param.num_param;
  }
}

// Nesterov updater:
// [ old_v = v ]
// [ v = rho * v - learning_rate * gradient ]
// [ x += -rho * old_v + (1+rho) * v ]
void Nesterov::Update(const index_t id,
                      const real_t grad,
                      std::vector<real_t>& param) {
  // Do not check anything here
  real_t old_v = v_[id];
  v_[id] = rho_ * v_[id] - learning_rate_ * grad;
  param[id] += -rho_ * old_v + (1+rho_) * v_[id];
}

// Update a continous space of model parameters by
// using sse/avx to speed up.
void Nesterov::BatchUpdate(const std::vector<real_t>& value,
                           const index_t start_id,
                           std::vector<real_t>& param) {
  CHECK_EQ(value.empty(), false);
  // Ensuring for sse/avx
  CHECK_EQ(value.size() % _MMX_INCREMENT, 0);
  __MX _learning_rate = _MMX_SET1_PS(learning_rate_);
  __MX _rho = _MMX_SET1_PS(rho_);
  __MX _rho_add_1 = _MMX_SET1_PS(rho_+1);
  // [ old_v = v ]
  // [ v = rho * v - learning_rate * gradient ]
  // [ x += -rho * old_v + (1+rho) * v ]
  for (int i = 0; i < value.size(); i += _MMX_INCREMENT) {
    index_t id = start_id + i;
    __MX _grad = _MMX_LOAD_PS(value.data() + i);
    __MX _old_v = _MMX_LOAD_PS(v_.data() + id);
    __MX _w = _MMX_LOAD_PS(param.data() + id);
    __MX _v = _MMX_SUB_PS(_MMX_MUL_PS(_rho, _old_v),
                         _MMX_MUL_PS(_learning_rate, _grad));
    _MMX_STORE_PS(v_.data() + id, _v);
    __MX _tmp = _MMX_SUB_PS(_MMX_MUL_PS(_rho_add_1, _v),
                            _MMX_MUL_PS(_rho, _old_v));
    _MMX_STORE_PS(param.data() + id,
                 _MMX_ADD_PS(_w, _tmp));
  }
}

} // namespace xLearn
<|endoftext|>


<commit_before>/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999-2000 The Apache Software Foundation.  All rights
 * reserved.
 *
 * 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.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xerces" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache\@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 APACHE SOFTWARE FOUNDATION OR
 * ITS 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.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation, and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com .  For more information
 * on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

#if !defined(XMLREGISTERCLEANUP_HPP)
#define XMLREGISTERCLEANUP_HPP

#include <util/Mutexes.hpp>

// This is a mutex for exclusive use by this class
extern XMLMutex* gXMLCleanupListMutex;

// This is the head of a list of XMLRegisterCleanup objects that
// is used during XMLPlatformUtils::Terminate() to find objects to
// clean up
class XMLRegisterCleanup;
extern XMLRegisterCleanup* gXMLCleanupList;

//
//  For internal use only.
//
//  This class is used by the platform utilities class to support
//  reinitialisation of global/static data which is lazily created.
//  Since that data is widely spread out the platform utilities
//  class cannot know about them directly. So, the code that creates such
//  objects creates an registers a cleanup for the object. The platform
//  termination call will iterate the list and delete the objects.
//
//  N.B. These objects need to be statically allocated.  I couldn't think
//  of a neat way of ensuring this - can anyone else?

class XMLRegisterCleanup
{
public :
	// The cleanup function to be called on XMLPlatformUtils::Terminate()
	typedef void (*XMLCleanupFn)();

	void doCleanup() {
		// When performing cleanup, we only do this once, but we can
		// cope if somehow we have been called twice.
		if (m_cleanupFn) {
			m_cleanupFn();
			unregisterCleanup();
		}
	}

	// This function is called during initialisation of static data to
	// register a function to be called on XMLPlatformUtils::Terminate.
	// It gives an object that uses static data an opportunity to reset
	// such data.
	void registerCleanup(XMLCleanupFn cleanupFn) {
		// Store the cleanup function
		m_cleanupFn = cleanupFn;

		// Add this object to the list head, if it is not already
		// present - which it shouldn't be.
		// This is done under a mutex to ensure thread safety.
		gXMLCleanupListMutex->lock();
		if (!m_nextCleanup && !m_prevCleanup) {
			m_nextCleanup = gXMLCleanupList;
			gXMLCleanupList = this;

			if (m_nextCleanup)
				m_nextCleanup->m_prevCleanup = this;
		}
		gXMLCleanupListMutex->unlock();
	}

	// This function can be called either from XMLPlatformUtils::Terminate
	// to state that the cleanup has been performed and should not be
	// performed again, or from code that you have written that determines
	// that cleanup is no longer necessary.
	void unregisterCleanup() {
		gXMLCleanupListMutex->lock();

		// Unlink this object from the cleanup list
		if (m_nextCleanup) m_nextCleanup->m_prevCleanup = m_prevCleanup;

		if (!m_prevCleanup) gXMLCleanupList = m_nextCleanup;
		else m_prevCleanup->m_nextCleanup = m_nextCleanup;

		gXMLCleanupListMutex->unlock();

		// Reset the object to the default state
		resetCleanup();
	}

	// The default constructor sets a state that ensures that this object
	// will do nothing
	XMLRegisterCleanup()
	{
		resetCleanup();
	}

private:
	// This is the cleanup function to be called
	XMLCleanupFn m_cleanupFn;

	// These are list pointers to the next/prev cleanup function to be called
	XMLRegisterCleanup *m_nextCleanup, *m_prevCleanup;

	// This function reinitialises the object to the default state
	void resetCleanup() {
		m_nextCleanup = 0;
		m_prevCleanup = 0;
		m_cleanupFn = 0;
	}
};

#endif
<commit_msg>[Bug#880] minor changes<commit_after>/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999-2000 The Apache Software Foundation.  All rights
 * reserved.
 *
 * 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.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xerces" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache\@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 APACHE SOFTWARE FOUNDATION OR
 * ITS 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.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation, and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com .  For more information
 * on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

#if !defined(XMLREGISTERCLEANUP_HPP)
#define XMLREGISTERCLEANUP_HPP

#include <util/Mutexes.hpp>

// This is a mutex for exclusive use by this class
extern XMLMutex* gXMLCleanupListMutex;

// This is the head of a list of XMLRegisterCleanup objects that
// is used during XMLPlatformUtils::Terminate() to find objects to
// clean up
class XMLRegisterCleanup;
extern XMLRegisterCleanup* gXMLCleanupList;

//
//  For internal use only.
//
//  This class is used by the platform utilities class to support
//  reinitialisation of global/static data which is lazily created.
//  Since that data is widely spread out the platform utilities
//  class cannot know about them directly. So, the code that creates such
//  objects creates an registers a cleanup for the object. The platform
//  termination call will iterate the list and delete the objects.
//
//  N.B. These objects need to be statically allocated.  I couldn't think
//  of a neat way of ensuring this - can anyone else?

class XMLRegisterCleanup
{
public :
	// The cleanup function to be called on XMLPlatformUtils::Terminate()
	typedef void (*XMLCleanupFn)();

	void doCleanup() {
		// When performing cleanup, we only do this once, but we can
		// cope if somehow we have been called twice.
		if (m_cleanupFn)
            m_cleanupFn();

        // We need to remove "this" from the list
        // irregardless of the cleanup Function
        unregisterCleanup();
	}

	// This function is called during initialisation of static data to
	// register a function to be called on XMLPlatformUtils::Terminate.
	// It gives an object that uses static data an opportunity to reset
	// such data.
	void registerCleanup(XMLCleanupFn cleanupFn) {
		// Store the cleanup function
		m_cleanupFn = cleanupFn;

		// Add this object to the list head, if it is not already
		// present - which it shouldn't be.
		// This is done under a mutex to ensure thread safety.
		gXMLCleanupListMutex->lock();
		if (!m_nextCleanup && !m_prevCleanup) {
			m_nextCleanup = gXMLCleanupList;
			gXMLCleanupList = this;

			if (m_nextCleanup)
				m_nextCleanup->m_prevCleanup = this;
		}
		gXMLCleanupListMutex->unlock();
	}

	// This function can be called either from XMLPlatformUtils::Terminate
	// to state that the cleanup has been performed and should not be
	// performed again, or from code that you have written that determines
	// that cleanup is no longer necessary.
	void unregisterCleanup() {
		gXMLCleanupListMutex->lock();

        //
        // To protect against some compiler's (eg hp11) optimization
        // to change "this" as they update gXMLCleanupList
        //
        // refer to
        // void XMLPlatformUtils::Terminate()
        //       ...
        //       while (gXMLCleanupList)
		//            gXMLCleanupList->doCleanup();
        //

        XMLRegisterCleanup *tmpThis = (XMLRegisterCleanup*) this;

        // Unlink this object from the cleanup list
		if (m_nextCleanup) m_nextCleanup->m_prevCleanup = m_prevCleanup;

		if (!m_prevCleanup) gXMLCleanupList = m_nextCleanup;
		else m_prevCleanup->m_nextCleanup = m_nextCleanup;

		gXMLCleanupListMutex->unlock();

		// Reset the object to the default state
		tmpThis->resetCleanup();
	}

	// The default constructor sets a state that ensures that this object
	// will do nothing
	XMLRegisterCleanup()
	{
		resetCleanup();
	}

private:
	// This is the cleanup function to be called
	XMLCleanupFn m_cleanupFn;

	// These are list pointers to the next/prev cleanup function to be called
	XMLRegisterCleanup *m_nextCleanup, *m_prevCleanup;

	// This function reinitialises the object to the default state
	void resetCleanup() {
		m_nextCleanup = 0;
		m_prevCleanup = 0;
		m_cleanupFn = 0;
	}
};

#endif
<|endoftext|>


<commit_before>#include "DrawCallBatching.h"

#include "dataset/Image.h"
#include "render/ShaderMgr.h"
#include "render/RenderContextStack.h"
#include "render/ShaderContext.h"

#include <dtex.h>

#include <gl/glew.h>

namespace d2d
{

DrawCallBatching* DrawCallBatching::m_instance = NULL;

//////////////////////////////////////////////////////////////////////////

static int TEX_ID = 0;

static void _program(int n)
{
	switch (n)
	{
	case DTEX_PROGRAM_NULL:
		ShaderMgr::Instance()->null();
		break;
	case DTEX_PROGRAM_NORMAL:
		ShaderMgr::Instance()->sprite();
		break;
	default:
		assert(0);
	}
}

static void _blend(int mode)
{
	assert(mode == 0);
//	ShaderMgr::Instance()->SetBlendMode(0);
}

static void _set_texture(int id)
{
	TEX_ID = id;
	ShaderMgr::Instance()->SetTexture(id);
}

static int _get_texture()
{
	return ShaderMgr::Instance()->GetTexID();
}

static void _set_target(int id)
{
	ShaderMgr::Instance()->SetFBO(id);
}

static int _get_target()
{
	return ShaderMgr::Instance()->GetFboID();
}

static Vector LAST_OFFSET;
static float LAST_SCALE;
static int LAST_WIDTH, LAST_HEIGHT;

static void _draw_begin()
{
	RenderContextStack* ctx_stack = RenderContextStack::Instance();

	ctx_stack->GetModelView(LAST_OFFSET, LAST_SCALE);
	ctx_stack->GetProjection(LAST_WIDTH, LAST_HEIGHT);

	ctx_stack->SetModelView(Vector(0, 0), 1);
	ctx_stack->SetProjection(2, 2);

// 	glViewport(0, 0, 2, 2);
}

static void _draw(const float vb[16])
{
	ShaderMgr* shader = ShaderMgr::Instance();
	shader->Draw(vb, TEX_ID);
}

static void _draw_end()
{
	ShaderMgr::Instance()->Flush();

	RenderContextStack* ctx_stack = RenderContextStack::Instance();
	ctx_stack->SetModelView(LAST_OFFSET, LAST_SCALE);
	ctx_stack->SetProjection(LAST_WIDTH, LAST_HEIGHT);

// 	glViewport(0, 0, ORI_WIDTH, ORI_HEIGHT);
}

#define IS_POT(x) ((x) > 0 && ((x) & ((x) -1)) == 0)

static int _texture_create(int type, int width, int height, const void* data, int channel,unsigned int id) {
	assert(type == DTEX_TF_RGBA8);

	// todo
	if ((type == DTEX_TF_RGBA8) || (IS_POT(width) && IS_POT(height))) {
		glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
	} else {
		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
	}

	GLint _format = GL_RGBA;
	GLenum _type = GL_UNSIGNED_BYTE;

	bool is_compressed = false;
	unsigned int size = 0;
	uint8_t* uncompressed = NULL;

	switch (type) {
	case DTEX_TF_RGBA8:
		is_compressed = false;
		_format = GL_RGBA;
		_type = GL_UNSIGNED_BYTE;
		break;
	case DTEX_TF_RGBA4:
		is_compressed = false;
		_format = GL_RGBA;
		_type = GL_UNSIGNED_SHORT_4_4_4_4;
		break;
	case DTEX_TF_PVR2:
#ifdef __APPLE__
		is_compressed = true;
		_type = COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;
		size = width * height * 8 * _type / 16;
#endif // __APPLE__
		break;
	case DTEX_TF_PVR4:
#ifdef __APPLE__
		is_compressed = true;
		_type = COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;
		size = width * height * 8 * _type / 16;
#else
// 		is_compressed = false;
// 		_format = GL_RGBA;
// 		_type = GL_UNSIGNED_BYTE;
// 		uncompressed = dtex_pvr_decode(data, width, height);
#endif // __APPLE__
		break;
	case DTEX_TF_ETC1:
#ifdef __ANDROID__
		is_compressed = true;
		_type = GL_ETC1_RGB8_OES;
		size = width * height * 4 / 8;
#else
		is_compressed = false;
		_format = GL_RGBA;
		_type = GL_UNSIGNED_BYTE;
#ifdef USED_IN_EDITOR
//		uncompressed = dtex_etc1_decode(data, width, height);
#endif // USED_IN_EDITOR
#endif // __ANDROID__
		break;
	default:
		dtex_fault("dtex_gl_create_texture: unknown texture type.");
	}

	glActiveTexture(GL_TEXTURE0 + channel);
	if (id == 0) {
		glGenTextures(1, (GLuint*)&id);
	}
	glBindTexture(GL_TEXTURE_2D, id);

	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

	if (is_compressed) {
		glCompressedTexImage2D(GL_TEXTURE_2D, 0, _type, width, height, 0, size, data);
	} else {
		if (uncompressed) {
			glTexImage2D(GL_TEXTURE_2D, 0, _format, (GLsizei)width, (GLsizei)height, 0, _format, _type, uncompressed);
			free(uncompressed);
		} else {
			glTexImage2D(GL_TEXTURE_2D, 0, _format, (GLsizei)width, (GLsizei)height, 0, _format, _type, data);
		}
	}

	return id;
}

static void
_texture_release(int id) {
	GLuint texid = (GLuint)id;
 	glActiveTexture(GL_TEXTURE0);
 	glDeleteTextures(1, &texid);
}

static void
_texture_update(const void* pixels, int x, int y, int w, int h, unsigned int id) {
	int old_id = ShaderMgr::Instance()->GetTexID();
 	glBindTexture(GL_TEXTURE_2D, id);
 	glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
 	glBindTexture(GL_TEXTURE_2D, old_id);
}

static int
_texture_id(int id) {
	return id;
}

//////////////////////////////////////////////////////////////////////////

static const char* CFG =
	"{ \n"
	"	\"open_c1\" : false, \n"
	"	\"open_c2\" : true, \n"
	"	\"open_c3\" : false,	 \n"
	"	\"open_cg\" : true,	 \n"
	"	\"open_cs\" : true,	 \n"
	"	\"c2_tex_size\" : 2048	\n"
	"} \n"
	;

DrawCallBatching::DrawCallBatching()
{
	dtex_shader_init(&_program, &_blend, &_set_texture, &_get_texture, &_set_target, &_get_target,
		&_draw_begin, &_draw, &_draw_end);

	dtex_gl_texture_init(&_texture_create, &_texture_release, &_texture_update, &_texture_id);

	dtexf_create(CFG);
}

DrawCallBatching::~DrawCallBatching()
{
}

void DrawCallBatching::LoadBegin()
{
	dtexf_c2_load_begin();
}

int DrawCallBatching::Load(const Image* img)
{
	const std::string& filepath = img->GetFilepath();
	std::map<std::string, int>::iterator itr = m_path2id.find(filepath);
	if (itr != m_path2id.end()) {
		return itr->second;
	}

	int key = m_path2id.size();
	m_path2id.insert(std::make_pair(filepath, key));
	dtexf_c2_load_tex(img->GetTexID(), img->GetClippedWidth(), img->GetClippedHeight(), key);

	return key;
}

void DrawCallBatching::LoadEnd()
{
	dtexf_c2_load_end();
}

void DrawCallBatching::ReloadBegin()
{
	dtexf_c2_reload_begin();
}

void DrawCallBatching::Reload(const Image* img)
{
	int key;
	std::map<std::string, int>::iterator itr = m_path2id.find(img->GetFilepath());
	assert(itr != m_path2id.end());
	key = itr->second;

	dtexf_c2_reload_tex(img->GetTexID(), img->GetOriginWidth(), img->GetOriginHeight(), key);
}

void DrawCallBatching::ReloadEnd()
{
	dtexf_c2_reload_end();
}

float* DrawCallBatching::Query(const Image* img, int* id)
{
	int key;
	std::map<std::string, int>::iterator itr = m_path2id.find(img->GetFilepath());
	if (itr != m_path2id.end()) {
		key = itr->second;
	} else {
		dtexf_c2_load_begin();
		key = Load(img);
		dtexf_c2_load_end();
	}
	return dtexf_c2_query_tex(key, id);
}

void DrawCallBatching::Clear()
{
	dtexf_c2_clear();
}

dtex_cg* DrawCallBatching::GetDtexCG()
{
	return dtexf_get_cg();
}

void DrawCallBatching::OnSize(int w, int h)
{
	dtex_set_screen(w, h, 1);
}

void DrawCallBatching::DebugDraw() const
{
	ShaderContext::Flush();
	dtexf_debug_draw();
}

DrawCallBatching* DrawCallBatching::Instance()
{
	if (!m_instance) {
		m_instance = new DrawCallBatching();
	}
	return m_instance;
}

}<commit_msg>[CHANGED] enlarge c2 texture size<commit_after>#include "DrawCallBatching.h"

#include "dataset/Image.h"
#include "render/ShaderMgr.h"
#include "render/RenderContextStack.h"
#include "render/ShaderContext.h"

#include <dtex.h>

#include <gl/glew.h>

namespace d2d
{

DrawCallBatching* DrawCallBatching::m_instance = NULL;

//////////////////////////////////////////////////////////////////////////

static int TEX_ID = 0;

static void _program(int n)
{
	switch (n)
	{
	case DTEX_PROGRAM_NULL:
		ShaderMgr::Instance()->null();
		break;
	case DTEX_PROGRAM_NORMAL:
		ShaderMgr::Instance()->sprite();
		break;
	default:
		assert(0);
	}
}

static void _blend(int mode)
{
	assert(mode == 0);
//	ShaderMgr::Instance()->SetBlendMode(0);
}

static void _set_texture(int id)
{
	TEX_ID = id;
	ShaderMgr::Instance()->SetTexture(id);
}

static int _get_texture()
{
	return ShaderMgr::Instance()->GetTexID();
}

static void _set_target(int id)
{
	ShaderMgr::Instance()->SetFBO(id);
}

static int _get_target()
{
	return ShaderMgr::Instance()->GetFboID();
}

static Vector LAST_OFFSET;
static float LAST_SCALE;
static int LAST_WIDTH, LAST_HEIGHT;

static void _draw_begin()
{
	RenderContextStack* ctx_stack = RenderContextStack::Instance();

	ctx_stack->GetModelView(LAST_OFFSET, LAST_SCALE);
	ctx_stack->GetProjection(LAST_WIDTH, LAST_HEIGHT);

	ctx_stack->SetModelView(Vector(0, 0), 1);
	ctx_stack->SetProjection(2, 2);

// 	glViewport(0, 0, 2, 2);
}

static void _draw(const float vb[16])
{
	ShaderMgr* shader = ShaderMgr::Instance();
	shader->Draw(vb, TEX_ID);
}

static void _draw_end()
{
	ShaderMgr::Instance()->Flush();

	RenderContextStack* ctx_stack = RenderContextStack::Instance();
	ctx_stack->SetModelView(LAST_OFFSET, LAST_SCALE);
	ctx_stack->SetProjection(LAST_WIDTH, LAST_HEIGHT);

// 	glViewport(0, 0, ORI_WIDTH, ORI_HEIGHT);
}

#define IS_POT(x) ((x) > 0 && ((x) & ((x) -1)) == 0)

static int _texture_create(int type, int width, int height, const void* data, int channel,unsigned int id) {
	assert(type == DTEX_TF_RGBA8);

	// todo
	if ((type == DTEX_TF_RGBA8) || (IS_POT(width) && IS_POT(height))) {
		glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
	} else {
		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
	}

	GLint _format = GL_RGBA;
	GLenum _type = GL_UNSIGNED_BYTE;

	bool is_compressed = false;
	unsigned int size = 0;
	uint8_t* uncompressed = NULL;

	switch (type) {
	case DTEX_TF_RGBA8:
		is_compressed = false;
		_format = GL_RGBA;
		_type = GL_UNSIGNED_BYTE;
		break;
	case DTEX_TF_RGBA4:
		is_compressed = false;
		_format = GL_RGBA;
		_type = GL_UNSIGNED_SHORT_4_4_4_4;
		break;
	case DTEX_TF_PVR2:
#ifdef __APPLE__
		is_compressed = true;
		_type = COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;
		size = width * height * 8 * _type / 16;
#endif // __APPLE__
		break;
	case DTEX_TF_PVR4:
#ifdef __APPLE__
		is_compressed = true;
		_type = COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;
		size = width * height * 8 * _type / 16;
#else
// 		is_compressed = false;
// 		_format = GL_RGBA;
// 		_type = GL_UNSIGNED_BYTE;
// 		uncompressed = dtex_pvr_decode(data, width, height);
#endif // __APPLE__
		break;
	case DTEX_TF_ETC1:
#ifdef __ANDROID__
		is_compressed = true;
		_type = GL_ETC1_RGB8_OES;
		size = width * height * 4 / 8;
#else
		is_compressed = false;
		_format = GL_RGBA;
		_type = GL_UNSIGNED_BYTE;
#ifdef USED_IN_EDITOR
//		uncompressed = dtex_etc1_decode(data, width, height);
#endif // USED_IN_EDITOR
#endif // __ANDROID__
		break;
	default:
		dtex_fault("dtex_gl_create_texture: unknown texture type.");
	}

	glActiveTexture(GL_TEXTURE0 + channel);
	if (id == 0) {
		glGenTextures(1, (GLuint*)&id);
	}
	glBindTexture(GL_TEXTURE_2D, id);

	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

	if (is_compressed) {
		glCompressedTexImage2D(GL_TEXTURE_2D, 0, _type, width, height, 0, size, data);
	} else {
		if (uncompressed) {
			glTexImage2D(GL_TEXTURE_2D, 0, _format, (GLsizei)width, (GLsizei)height, 0, _format, _type, uncompressed);
			free(uncompressed);
		} else {
			glTexImage2D(GL_TEXTURE_2D, 0, _format, (GLsizei)width, (GLsizei)height, 0, _format, _type, data);
		}
	}

	return id;
}

static void
_texture_release(int id) {
	GLuint texid = (GLuint)id;
 	glActiveTexture(GL_TEXTURE0);
 	glDeleteTextures(1, &texid);
}

static void
_texture_update(const void* pixels, int x, int y, int w, int h, unsigned int id) {
	int old_id = ShaderMgr::Instance()->GetTexID();
 	glBindTexture(GL_TEXTURE_2D, id);
 	glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
 	glBindTexture(GL_TEXTURE_2D, old_id);
}

static int
_texture_id(int id) {
	return id;
}

//////////////////////////////////////////////////////////////////////////

static const char* CFG =
	"{ \n"
	"	\"open_c1\" : false, \n"
	"	\"open_c2\" : true, \n"
	"	\"open_c3\" : false,	 \n"
	"	\"open_cg\" : true,	 \n"
	"	\"open_cs\" : true,	 \n"
	"	\"c2_tex_size\" : 4096	\n"
	"} \n"
	;

DrawCallBatching::DrawCallBatching()
{
	dtex_shader_init(&_program, &_blend, &_set_texture, &_get_texture, &_set_target, &_get_target,
		&_draw_begin, &_draw, &_draw_end);

	dtex_gl_texture_init(&_texture_create, &_texture_release, &_texture_update, &_texture_id);

	dtexf_create(CFG);
}

DrawCallBatching::~DrawCallBatching()
{
}

void DrawCallBatching::LoadBegin()
{
	dtexf_c2_load_begin();
}

int DrawCallBatching::Load(const Image* img)
{
	const std::string& filepath = img->GetFilepath();
	std::map<std::string, int>::iterator itr = m_path2id.find(filepath);
	if (itr != m_path2id.end()) {
		return itr->second;
	}

	int key = m_path2id.size();
	m_path2id.insert(std::make_pair(filepath, key));
	dtexf_c2_load_tex(img->GetTexID(), img->GetClippedWidth(), img->GetClippedHeight(), key);

	return key;
}

void DrawCallBatching::LoadEnd()
{
	dtexf_c2_load_end();
}

void DrawCallBatching::ReloadBegin()
{
	dtexf_c2_reload_begin();
}

void DrawCallBatching::Reload(const Image* img)
{
	int key;
	std::map<std::string, int>::iterator itr = m_path2id.find(img->GetFilepath());
	assert(itr != m_path2id.end());
	key = itr->second;

	dtexf_c2_reload_tex(img->GetTexID(), img->GetOriginWidth(), img->GetOriginHeight(), key);
}

void DrawCallBatching::ReloadEnd()
{
	dtexf_c2_reload_end();
}

float* DrawCallBatching::Query(const Image* img, int* id)
{
	int key;
	std::map<std::string, int>::iterator itr = m_path2id.find(img->GetFilepath());
	if (itr != m_path2id.end()) {
		key = itr->second;
	} else {
		dtexf_c2_load_begin();
		key = Load(img);
		dtexf_c2_load_end();
	}
	return dtexf_c2_query_tex(key, id);
}

void DrawCallBatching::Clear()
{
	dtexf_c2_clear();
}

dtex_cg* DrawCallBatching::GetDtexCG()
{
	return dtexf_get_cg();
}

void DrawCallBatching::OnSize(int w, int h)
{
	dtex_set_screen(w, h, 1);
}

void DrawCallBatching::DebugDraw() const
{
	ShaderContext::Flush();
	dtexf_debug_draw();
}

DrawCallBatching* DrawCallBatching::Instance()
{
	if (!m_instance) {
		m_instance = new DrawCallBatching();
	}
	return m_instance;
}

}<|endoftext|>


<commit_before>/*****************************************************************************
 * main.cpp: ActiveX control for VLC
 *****************************************************************************
 * Copyright (C) 2005 the VideoLAN team
 *
 * Authors: Damien Fouilleul <Damien.Fouilleul@laposte.net>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/

#include "plugin.h"
#include "utils.h"

#include <stdio.h>

#include <comcat.h>
#include <windows.h>
#include <shlwapi.h>

#include <tchar.h>

#include <_mingw.h>
#ifdef __MINGW64_VERSION_MAJOR
#include <guiddef.h>
#else /* ! __MINGW64_VERSION_MAJOR */
/*
** Widl generated code requires guiddef.h,
** which is not available under MinGW32
*/
#undef GUID_EXT
#define GUID_EXT
#include <initguid.h>
#endif /* __MINGW64_VERSION_MAJOR */

using namespace std;

#define COMPANY_STR "VideoLAN"
#define PROGRAM_STR "VLCPlugin"
#define DESCRIPTION "VLC ActiveX Plugin and IE Web Plugin"

#define THREADING_MODEL "Apartment"
#define MISC_STATUS     "131473"

#define PROGID_STR COMPANY_STR"."PROGRAM_STR

#define GUID_STRLEN 39

/*
** MingW headers & libs do not declare those
*/
static DEFINE_GUID(_CATID_InternetAware, \
	0x0DE86A58, 0x2BAA, 0x11CF, 0xA2, 0x29, 0x00,0xAA,0x00,0x3D,0x73,0x52);
static DEFINE_GUID(_CATID_SafeForInitializing, \
	0x7DD95802, 0x9882, 0x11CF, 0x9F, 0xA9, 0x00,0xAA,0x00,0x6C,0x42,0xC4);
static DEFINE_GUID(_CATID_SafeForScripting, \
	0x7DD95801, 0x9882, 0x11CF, 0x9F, 0xA9, 0x00,0xAA,0x00,0x6C,0x42,0xC4);

static LONG i_class_ref= 0;
static HINSTANCE h_instance= 0;

HMODULE DllGetModule()
{
    return h_instance;
};

STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
{
    HRESULT hr = CLASS_E_CLASSNOTAVAILABLE;

    *ppv = NULL;

    if( (CLSID_VLCPlugin == rclsid) || (CLSID_VLCPlugin2 == rclsid) )
    {
        VLCPluginClass *plugin =
            new VLCPluginClass(&i_class_ref, h_instance, rclsid);
        hr = plugin->QueryInterface(riid, ppv);
        plugin->Release();
    }
    return hr;
};

STDAPI DllCanUnloadNow(VOID)
{
    return (0 == i_class_ref) ? S_OK: S_FALSE;
};

static inline HKEY keyCreate(HKEY parentKey, LPCTSTR keyName)
{
    HKEY childKey;
    if( ERROR_SUCCESS == RegCreateKeyEx(parentKey, keyName, 0, NULL,
             REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &childKey, NULL) )
    {
        return childKey;
    }
    return NULL;
};

static inline HKEY keySet(HKEY hKey, LPCTSTR valueName,
                          const void *s, size_t len, DWORD dwType = REG_SZ)
{
    if( NULL != hKey )
    {
        RegSetValueEx(hKey, valueName, 0, dwType, (const BYTE*)s, len);
    }
    return hKey;
};

static inline HKEY keySetDef(HKEY hKey,
                             const void *s, size_t len, DWORD dwType = REG_SZ)
{
    return keySet(hKey, NULL, s, len, dwType);
};

static inline HKEY keySetDef(HKEY hKey, LPCTSTR s)
{
    return keySetDef(hKey, s, sizeof(TCHAR)*(_tcslen(s)+1), REG_SZ);
};

static inline HKEY keyClose(HKEY hKey)
{
    if( NULL != hKey )
    {
        RegCloseKey(hKey);
    }
    return NULL;
};

static void UnregisterProgID(REFCLSID rclsid, unsigned int version)
{
    OLECHAR szCLSID[GUID_STRLEN];

    StringFromGUID2(rclsid, szCLSID, GUID_STRLEN);

    TCHAR progId[sizeof(PROGID_STR)+16];
    _stprintf(progId, TEXT("%s.%u"), TEXT(PROGID_STR), version);

    SHDeleteKey(HKEY_CLASSES_ROOT, progId);

    HKEY hClsIDKey;
    if( ERROR_SUCCESS == RegOpenKeyEx(HKEY_CLASSES_ROOT, TEXT("CLSID"), 0, KEY_WRITE, &hClsIDKey) )
    {
        SHDeleteKey(hClsIDKey, szCLSID);
        RegCloseKey(hClsIDKey);
    }
};

STDAPI DllUnregisterServer(VOID)
{
    // unregister type lib from the registry
    UnRegisterTypeLib(LIBID_AXVLC, 1, 0, LOCALE_NEUTRAL, SYS_WIN32);

    // remove component categories we supports
    ICatRegister *pcr;
    if( SUCCEEDED(CoCreateInstance(CLSID_StdComponentCategoriesMgr,
            NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (void**)&pcr)) ) {
        CATID implCategories[] = {
            CATID_Control,
            CATID_PersistsToPropertyBag,
            _CATID_InternetAware,
            _CATID_SafeForInitializing,
            _CATID_SafeForScripting,
        };

        pcr->UnRegisterClassImplCategories(CLSID_VLCPlugin,
                sizeof(implCategories)/sizeof(CATID), implCategories);
        pcr->UnRegisterClassImplCategories(CLSID_VLCPlugin2,
                sizeof(implCategories)/sizeof(CATID), implCategories);
        pcr->Release();
    }

    SHDeleteKey(HKEY_CLASSES_ROOT, TEXT(PROGID_STR));

    UnregisterProgID(CLSID_VLCPlugin, 2);
    UnregisterProgID(CLSID_VLCPlugin2, 1);

    return S_OK;
};

static HRESULT RegisterClassID(HKEY hParent, REFCLSID rclsid, unsigned int version, BOOL isDefault, LPCTSTR path, size_t pathLen)
{
    TCHAR progId[sizeof(PROGID_STR)+16];
    _stprintf(progId, TEXT("%s.%u"), TEXT(PROGID_STR), version);

    TCHAR description[sizeof(DESCRIPTION)+16];
    _stprintf(description, TEXT("%s v%u"), TEXT(DESCRIPTION), version);

    HKEY hClassKey;
    {
        OLECHAR szCLSID[GUID_STRLEN];

        StringFromGUID2(rclsid, szCLSID, GUID_STRLEN);

        HKEY hProgKey = keyCreate(HKEY_CLASSES_ROOT, progId);
        if( NULL != hProgKey )
        {
            // default key value
            keySetDef(hProgKey, description);

            keyClose(keySetDef(keyCreate(hProgKey, TEXT("CLSID")),
                               szCLSID, sizeof(szCLSID)));

            //hSubKey = keyClose(keyCreate(hBaseKey, "Insertable"));

            RegCloseKey(hProgKey);
        }
        if( isDefault )
        {
            hProgKey = keyCreate(HKEY_CLASSES_ROOT, TEXT(PROGID_STR));
            if( NULL != hProgKey )
            {
                // default key value
                keySetDef(hProgKey, description);

                keyClose(keySetDef(keyCreate(hProgKey, TEXT("CLSID")),
                                   szCLSID, sizeof(szCLSID)));

                keyClose(keySetDef(keyCreate(hProgKey, TEXT("CurVer")),
                                   progId));
            }
        }
        hClassKey = keyCreate(hParent, szCLSID);
    }
    if( NULL != hClassKey )
    {
        // default key value
        keySetDef(hClassKey, description);

        // Control key value
        keyClose(keyCreate(hClassKey, TEXT("Control")));

        // Insertable key value
        //keyClose(keyCreate(hClassKey, TEXT("Insertable")));

        // ToolboxBitmap32 key value
        {
            TCHAR iconPath[pathLen+3];
            memcpy(iconPath, path, sizeof(TCHAR)*pathLen);
            _tcscpy(iconPath+pathLen, TEXT(",1"));
            keyClose(keySetDef(keyCreate(hClassKey,
                TEXT("ToolboxBitmap32")),
                iconPath, sizeof(iconPath)));
        }

#ifdef BUILD_LOCALSERVER
        // LocalServer32 key value
        keyClose(keySetDef(keyCreate(hClassKey,
            TEXT("LocalServer32"), path, sizeof(TCHAR)*(pathLen+1))));
#else
        // InprocServer32 key value
        {
            HKEY hSubKey = keySetDef(keyCreate(hClassKey,
                TEXT("InprocServer32")),
                path, sizeof(TCHAR)*(pathLen+1));
            keySet(hSubKey,
                TEXT("ThreadingModel"),
                TEXT(THREADING_MODEL), sizeof(TEXT(THREADING_MODEL)));
            keyClose(hSubKey);
        }
#endif

        // MiscStatus key value
        keyClose(keySetDef(keyCreate(hClassKey,TEXT("MiscStatus\\1")),
                           TEXT(MISC_STATUS), sizeof(TEXT(MISC_STATUS))));

        // Programmable key value
        keyClose(keyCreate(hClassKey, TEXT("Programmable")));

        // ProgID key value
        keyClose(keySetDef(keyCreate(hClassKey,TEXT("ProgID")),progId));

        // VersionIndependentProgID key value
        keyClose(keySetDef(keyCreate(hClassKey,
                                     TEXT("VersionIndependentProgID")),
                           TEXT(PROGID_STR), sizeof(TEXT(PROGID_STR))));

        // Version key value
        keyClose(keySetDef(keyCreate(hClassKey,TEXT("Version")),TEXT("1.0")));

        // TypeLib key value
        OLECHAR szLIBID[GUID_STRLEN];

        StringFromGUID2(LIBID_AXVLC, szLIBID, GUID_STRLEN);

        keyClose(keySetDef(keyCreate(hClassKey,TEXT("TypeLib")),
                           szLIBID, sizeof(szLIBID)));

        RegCloseKey(hClassKey);
    }
    return S_OK;
}

STDAPI DllRegisterServer(VOID)
{
    DllUnregisterServer();

    TCHAR DllPath[MAX_PATH];
    DWORD DllPathLen=GetModuleFileName(h_instance, DllPath, MAX_PATH) ;
    if( 0 == DllPathLen )
        return E_UNEXPECTED;
    DllPath[MAX_PATH-1] = '\0';

    HKEY hBaseKey;

    if( ERROR_SUCCESS != RegOpenKeyEx(HKEY_CLASSES_ROOT, TEXT("CLSID"),
                                      0, KEY_CREATE_SUB_KEY, &hBaseKey) )
        return SELFREG_E_CLASS;

    RegisterClassID(hBaseKey, CLSID_VLCPlugin, 1, FALSE, DllPath, DllPathLen);
    RegisterClassID(hBaseKey, CLSID_VLCPlugin2, 2, TRUE, DllPath, DllPathLen);

    RegCloseKey(hBaseKey);

    // indicate which component categories we support
    ICatRegister *pcr;
    if( SUCCEEDED(CoCreateInstance(CLSID_StdComponentCategoriesMgr,
            NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (void**)&pcr)) ) {
        CATID implCategories[] = {
            CATID_Control,
            CATID_PersistsToPropertyBag,
            _CATID_InternetAware,
            _CATID_SafeForInitializing,
            _CATID_SafeForScripting,
        };

        pcr->RegisterClassImplCategories(CLSID_VLCPlugin,
                sizeof(implCategories)/sizeof(CATID), implCategories);
        pcr->RegisterClassImplCategories(CLSID_VLCPlugin2,
                sizeof(implCategories)/sizeof(CATID), implCategories);
        pcr->Release();
    }

#ifdef BUILD_LOCALSERVER
    // replace .exe by .tlb
    _tcscpy(DllPath+DllPathLen-4, TEXT(".tlb"));
#endif

    // register type lib into the registry
    ITypeLib *typeLib;

    HRESULT result = LoadTypeLibEx(DllPath, REGKIND_REGISTER, &typeLib);
    if( SUCCEEDED(result) )
        typeLib->Release();

    return result;
};

#ifdef BUILD_LOCALSERVER

/*
** easier to debug an application than a DLL on cygwin GDB :)
*/
#include <iostream>

STDAPI_(int) WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw)
{
    MSG msg;

    if( FAILED(OleInitialize(NULL)) )
    {
        cerr << "cannot initialize OLE" << endl;
        return 1;
    }

    h_instance = hInst;

    if( FAILED(DllRegisterServer()) )
    {
        cerr << "cannot register Local Server" << endl;
        return 1;
    }

    IUnknown *classProc = NULL;

    if( FAILED(DllGetClassObject(CLSID_VLCPlugin, IID_IUnknown,
                                 (LPVOID *)&classProc)) )
        return 0;

    DWORD dwRegisterClassObject;
    DWORD dwRegisterClassObject2;

    if( FAILED(CoRegisterClassObject(CLSID_VLCPlugin, classProc,
        CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE, &dwRegisterClassObject)) )
        return 0;

    DWORD dwRegisterActiveObject;

    if( FAILED(RegisterActiveObject(classProc, CLSID_VLCPlugin,
                    ACTIVEOBJECT_WEAK, &dwRegisterActiveObject)) )
        return 0;

    if( FAILED(RegisterActiveObject(classProc, CLSID_VLCPlugin2,
                    ACTIVEOBJECT_WEAK, &dwRegisterActiveObject2)) )
        return 0;

    classProc->Release();

    /*
    * Polling messages from event queue
    */
    while( S_FALSE == DllCanUnloadNow() )
    {
        while( PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) )
        {
            if( msg.message == WM_QUIT )
                break;  // break out PeekMessage loop

            /*if(TranslateAccelerator(ghwndApp, ghAccel, &msg))
                continue;*/

            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }

        if(msg.message == WM_QUIT)
            break;  // break out main loop

        WaitMessage();
    }

    if( SUCCEEDED(RevokeActiveObject(dwRegisterActiveObject, NULL)) )
        CoRevokeClassObject(dwRegisterClassObject);

    if( SUCCEEDED(RevokeActiveObject(dwRegisterActiveObject2, NULL)) )
        CoRevokeClassObject(dwRegisterClassObject2);

    // Reached on WM_QUIT message
    OleUninitialize();
    return ((int) msg.wParam);
};

#else

STDAPI_(BOOL) DllMain(HANDLE hModule, DWORD fdwReason, LPVOID lpReserved )
{
    switch( fdwReason )
    {
        case DLL_PROCESS_ATTACH:
            h_instance = (HINSTANCE)hModule;
            break;

        default:
            break;
    }
    return TRUE;
};

#endif

<commit_msg>Revert "Revert "mingw-w64 includes objsafe.h macros""<commit_after>/*****************************************************************************
 * main.cpp: ActiveX control for VLC
 *****************************************************************************
 * Copyright (C) 2005 the VideoLAN team
 *
 * Authors: Damien Fouilleul <Damien.Fouilleul@laposte.net>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/

#include "plugin.h"
#include "utils.h"

#include <stdio.h>

#include <comcat.h>
#include <windows.h>
#include <shlwapi.h>

#include <tchar.h>

#include <_mingw.h>

#ifdef __MINGW64_VERSION_MAJOR

#include <guiddef.h>
#include <objsafe.h>

#else /* ! __MINGW64_VERSION_MAJOR */

/*
** Widl generated code requires guiddef.h,
** which is not available under MinGW32
*/
#undef GUID_EXT
#define GUID_EXT
#include <initguid.h>

/*
** Mingw32 do not declare those
*/
static DEFINE_GUID(CATID_SafeForInitializing, \
	0x7DD95802, 0x9882, 0x11CF, 0x9F, 0xA9, 0x00,0xAA,0x00,0x6C,0x42,0xC4);
static DEFINE_GUID(CATID_SafeForScripting, \
	0x7DD95801, 0x9882, 0x11CF, 0x9F, 0xA9, 0x00,0xAA,0x00,0x6C,0x42,0xC4);

#endif /* __MINGW64_VERSION_MAJOR */

using namespace std;

#define COMPANY_STR "VideoLAN"
#define PROGRAM_STR "VLCPlugin"
#define DESCRIPTION "VLC ActiveX Plugin and IE Web Plugin"

#define THREADING_MODEL "Apartment"
#define MISC_STATUS     "131473"

#define PROGID_STR COMPANY_STR"."PROGRAM_STR

#define GUID_STRLEN 39

static LONG i_class_ref= 0;
static HINSTANCE h_instance= 0;

HMODULE DllGetModule()
{
    return h_instance;
};

STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
{
    HRESULT hr = CLASS_E_CLASSNOTAVAILABLE;

    *ppv = NULL;

    if( (CLSID_VLCPlugin == rclsid) || (CLSID_VLCPlugin2 == rclsid) )
    {
        VLCPluginClass *plugin =
            new VLCPluginClass(&i_class_ref, h_instance, rclsid);
        hr = plugin->QueryInterface(riid, ppv);
        plugin->Release();
    }
    return hr;
};

STDAPI DllCanUnloadNow(VOID)
{
    return (0 == i_class_ref) ? S_OK: S_FALSE;
};

static inline HKEY keyCreate(HKEY parentKey, LPCTSTR keyName)
{
    HKEY childKey;
    if( ERROR_SUCCESS == RegCreateKeyEx(parentKey, keyName, 0, NULL,
             REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &childKey, NULL) )
    {
        return childKey;
    }
    return NULL;
};

static inline HKEY keySet(HKEY hKey, LPCTSTR valueName,
                          const void *s, size_t len, DWORD dwType = REG_SZ)
{
    if( NULL != hKey )
    {
        RegSetValueEx(hKey, valueName, 0, dwType, (const BYTE*)s, len);
    }
    return hKey;
};

static inline HKEY keySetDef(HKEY hKey,
                             const void *s, size_t len, DWORD dwType = REG_SZ)
{
    return keySet(hKey, NULL, s, len, dwType);
};

static inline HKEY keySetDef(HKEY hKey, LPCTSTR s)
{
    return keySetDef(hKey, s, sizeof(TCHAR)*(_tcslen(s)+1), REG_SZ);
};

static inline HKEY keyClose(HKEY hKey)
{
    if( NULL != hKey )
    {
        RegCloseKey(hKey);
    }
    return NULL;
};

static void UnregisterProgID(REFCLSID rclsid, unsigned int version)
{
    OLECHAR szCLSID[GUID_STRLEN];

    StringFromGUID2(rclsid, szCLSID, GUID_STRLEN);

    TCHAR progId[sizeof(PROGID_STR)+16];
    _stprintf(progId, TEXT("%s.%u"), TEXT(PROGID_STR), version);

    SHDeleteKey(HKEY_CLASSES_ROOT, progId);

    HKEY hClsIDKey;
    if( ERROR_SUCCESS == RegOpenKeyEx(HKEY_CLASSES_ROOT, TEXT("CLSID"), 0, KEY_WRITE, &hClsIDKey) )
    {
        SHDeleteKey(hClsIDKey, szCLSID);
        RegCloseKey(hClsIDKey);
    }
};

STDAPI DllUnregisterServer(VOID)
{
    // unregister type lib from the registry
    UnRegisterTypeLib(LIBID_AXVLC, 1, 0, LOCALE_NEUTRAL, SYS_WIN32);

    // remove component categories we supports
    ICatRegister *pcr;
    if( SUCCEEDED(CoCreateInstance(CLSID_StdComponentCategoriesMgr,
            NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (void**)&pcr)) ) {
        CATID implCategories[] = {
            CATID_Control,
            CATID_PersistsToPropertyBag,
            CATID_InternetAware,
            CATID_SafeForInitializing,
            CATID_SafeForScripting,
        };

        pcr->UnRegisterClassImplCategories(CLSID_VLCPlugin,
                sizeof(implCategories)/sizeof(CATID), implCategories);
        pcr->UnRegisterClassImplCategories(CLSID_VLCPlugin2,
                sizeof(implCategories)/sizeof(CATID), implCategories);
        pcr->Release();
    }

    SHDeleteKey(HKEY_CLASSES_ROOT, TEXT(PROGID_STR));

    UnregisterProgID(CLSID_VLCPlugin, 2);
    UnregisterProgID(CLSID_VLCPlugin2, 1);

    return S_OK;
};

static HRESULT RegisterClassID(HKEY hParent, REFCLSID rclsid, unsigned int version, BOOL isDefault, LPCTSTR path, size_t pathLen)
{
    TCHAR progId[sizeof(PROGID_STR)+16];
    _stprintf(progId, TEXT("%s.%u"), TEXT(PROGID_STR), version);

    TCHAR description[sizeof(DESCRIPTION)+16];
    _stprintf(description, TEXT("%s v%u"), TEXT(DESCRIPTION), version);

    HKEY hClassKey;
    {
        OLECHAR szCLSID[GUID_STRLEN];

        StringFromGUID2(rclsid, szCLSID, GUID_STRLEN);

        HKEY hProgKey = keyCreate(HKEY_CLASSES_ROOT, progId);
        if( NULL != hProgKey )
        {
            // default key value
            keySetDef(hProgKey, description);

            keyClose(keySetDef(keyCreate(hProgKey, TEXT("CLSID")),
                               szCLSID, sizeof(szCLSID)));

            //hSubKey = keyClose(keyCreate(hBaseKey, "Insertable"));

            RegCloseKey(hProgKey);
        }
        if( isDefault )
        {
            hProgKey = keyCreate(HKEY_CLASSES_ROOT, TEXT(PROGID_STR));
            if( NULL != hProgKey )
            {
                // default key value
                keySetDef(hProgKey, description);

                keyClose(keySetDef(keyCreate(hProgKey, TEXT("CLSID")),
                                   szCLSID, sizeof(szCLSID)));

                keyClose(keySetDef(keyCreate(hProgKey, TEXT("CurVer")),
                                   progId));
            }
        }
        hClassKey = keyCreate(hParent, szCLSID);
    }
    if( NULL != hClassKey )
    {
        // default key value
        keySetDef(hClassKey, description);

        // Control key value
        keyClose(keyCreate(hClassKey, TEXT("Control")));

        // Insertable key value
        //keyClose(keyCreate(hClassKey, TEXT("Insertable")));

        // ToolboxBitmap32 key value
        {
            TCHAR iconPath[pathLen+3];
            memcpy(iconPath, path, sizeof(TCHAR)*pathLen);
            _tcscpy(iconPath+pathLen, TEXT(",1"));
            keyClose(keySetDef(keyCreate(hClassKey,
                TEXT("ToolboxBitmap32")),
                iconPath, sizeof(iconPath)));
        }

#ifdef BUILD_LOCALSERVER
        // LocalServer32 key value
        keyClose(keySetDef(keyCreate(hClassKey,
            TEXT("LocalServer32"), path, sizeof(TCHAR)*(pathLen+1))));
#else
        // InprocServer32 key value
        {
            HKEY hSubKey = keySetDef(keyCreate(hClassKey,
                TEXT("InprocServer32")),
                path, sizeof(TCHAR)*(pathLen+1));
            keySet(hSubKey,
                TEXT("ThreadingModel"),
                TEXT(THREADING_MODEL), sizeof(TEXT(THREADING_MODEL)));
            keyClose(hSubKey);
        }
#endif

        // MiscStatus key value
        keyClose(keySetDef(keyCreate(hClassKey,TEXT("MiscStatus\\1")),
                           TEXT(MISC_STATUS), sizeof(TEXT(MISC_STATUS))));

        // Programmable key value
        keyClose(keyCreate(hClassKey, TEXT("Programmable")));

        // ProgID key value
        keyClose(keySetDef(keyCreate(hClassKey,TEXT("ProgID")),progId));

        // VersionIndependentProgID key value
        keyClose(keySetDef(keyCreate(hClassKey,
                                     TEXT("VersionIndependentProgID")),
                           TEXT(PROGID_STR), sizeof(TEXT(PROGID_STR))));

        // Version key value
        keyClose(keySetDef(keyCreate(hClassKey,TEXT("Version")),TEXT("1.0")));

        // TypeLib key value
        OLECHAR szLIBID[GUID_STRLEN];

        StringFromGUID2(LIBID_AXVLC, szLIBID, GUID_STRLEN);

        keyClose(keySetDef(keyCreate(hClassKey,TEXT("TypeLib")),
                           szLIBID, sizeof(szLIBID)));

        RegCloseKey(hClassKey);
    }
    return S_OK;
}

STDAPI DllRegisterServer(VOID)
{
    DllUnregisterServer();

    TCHAR DllPath[MAX_PATH];
    DWORD DllPathLen=GetModuleFileName(h_instance, DllPath, MAX_PATH) ;
    if( 0 == DllPathLen )
        return E_UNEXPECTED;
    DllPath[MAX_PATH-1] = '\0';

    HKEY hBaseKey;

    if( ERROR_SUCCESS != RegOpenKeyEx(HKEY_CLASSES_ROOT, TEXT("CLSID"),
                                      0, KEY_CREATE_SUB_KEY, &hBaseKey) )
        return SELFREG_E_CLASS;

    RegisterClassID(hBaseKey, CLSID_VLCPlugin, 1, FALSE, DllPath, DllPathLen);
    RegisterClassID(hBaseKey, CLSID_VLCPlugin2, 2, TRUE, DllPath, DllPathLen);

    RegCloseKey(hBaseKey);

    // indicate which component categories we support
    ICatRegister *pcr;
    if( SUCCEEDED(CoCreateInstance(CLSID_StdComponentCategoriesMgr,
            NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (void**)&pcr)) ) {
        CATID implCategories[] = {
            CATID_Control,
            CATID_PersistsToPropertyBag,
            CATID_InternetAware,
            CATID_SafeForInitializing,
            CATID_SafeForScripting,
        };

        pcr->RegisterClassImplCategories(CLSID_VLCPlugin,
                sizeof(implCategories)/sizeof(CATID), implCategories);
        pcr->RegisterClassImplCategories(CLSID_VLCPlugin2,
                sizeof(implCategories)/sizeof(CATID), implCategories);
        pcr->Release();
    }

#ifdef BUILD_LOCALSERVER
    // replace .exe by .tlb
    _tcscpy(DllPath+DllPathLen-4, TEXT(".tlb"));
#endif

    // register type lib into the registry
    ITypeLib *typeLib;

    HRESULT result = LoadTypeLibEx(DllPath, REGKIND_REGISTER, &typeLib);
    if( SUCCEEDED(result) )
        typeLib->Release();

    return result;
};

#ifdef BUILD_LOCALSERVER

/*
** easier to debug an application than a DLL on cygwin GDB :)
*/
#include <iostream>

STDAPI_(int) WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw)
{
    MSG msg;

    if( FAILED(OleInitialize(NULL)) )
    {
        cerr << "cannot initialize OLE" << endl;
        return 1;
    }

    h_instance = hInst;

    if( FAILED(DllRegisterServer()) )
    {
        cerr << "cannot register Local Server" << endl;
        return 1;
    }

    IUnknown *classProc = NULL;

    if( FAILED(DllGetClassObject(CLSID_VLCPlugin, IID_IUnknown,
                                 (LPVOID *)&classProc)) )
        return 0;

    DWORD dwRegisterClassObject;
    DWORD dwRegisterClassObject2;

    if( FAILED(CoRegisterClassObject(CLSID_VLCPlugin, classProc,
        CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE, &dwRegisterClassObject)) )
        return 0;

    DWORD dwRegisterActiveObject;

    if( FAILED(RegisterActiveObject(classProc, CLSID_VLCPlugin,
                    ACTIVEOBJECT_WEAK, &dwRegisterActiveObject)) )
        return 0;

    if( FAILED(RegisterActiveObject(classProc, CLSID_VLCPlugin2,
                    ACTIVEOBJECT_WEAK, &dwRegisterActiveObject2)) )
        return 0;

    classProc->Release();

    /*
    * Polling messages from event queue
    */
    while( S_FALSE == DllCanUnloadNow() )
    {
        while( PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) )
        {
            if( msg.message == WM_QUIT )
                break;  // break out PeekMessage loop

            /*if(TranslateAccelerator(ghwndApp, ghAccel, &msg))
                continue;*/

            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }

        if(msg.message == WM_QUIT)
            break;  // break out main loop

        WaitMessage();
    }

    if( SUCCEEDED(RevokeActiveObject(dwRegisterActiveObject, NULL)) )
        CoRevokeClassObject(dwRegisterClassObject);

    if( SUCCEEDED(RevokeActiveObject(dwRegisterActiveObject2, NULL)) )
        CoRevokeClassObject(dwRegisterClassObject2);

    // Reached on WM_QUIT message
    OleUninitialize();
    return ((int) msg.wParam);
};

#else

STDAPI_(BOOL) DllMain(HANDLE hModule, DWORD fdwReason, LPVOID lpReserved )
{
    switch( fdwReason )
    {
        case DLL_PROCESS_ATTACH:
            h_instance = (HINSTANCE)hModule;
            break;

        default:
            break;
    }
    return TRUE;
};

#endif

<|endoftext|>


<commit_before>/**
 * Copyright (c) 2011-2015 libbitcoin developers (see AUTHORS)
 *
 * This file is part of libbitcoin.
 *
 * libbitcoin is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License with
 * additional permissions to the one published by the Free Software
 * Foundation, either version 3 of the License, or (at your option)
 * any later version. For more information see LICENSE.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef LIBBITCOIN_ASSERT_HPP
#define LIBBITCOIN_ASSERT_HPP

#ifdef NDEBUG
    #define BITCOIN_ASSERT(expr)
    #define BITCOIN_ASSERT_MSG(expr, msg)
    #define DEBUG_ONLY(expression)
#else
    #include <cassert>
    #define BITCOIN_ASSERT(expr) assert(expr)
    #define BITCOIN_ASSERT_MSG(expr, msg) assert((expr)&&(msg))
    #define DEBUG_ONLY(expression) expression
#endif

#ifdef NDEBUG
    #define INITIALIZE_TRACK(class_name)

    template <class Shared>
    class track
    {
    protected:
        track(const std::string& log_name, const std::string&)
          : log_(log_name)
        {
        }

        const std::string log_;
    };
#else
    #include <atomic>
    #include <cstddef>
    #include <string>
    #include <bitcoin/bitcoin/utility/logger.hpp>
    #define INITIALIZE_TRACK(class_name) \
        track<class_name>::counter track<class_name>::instances(0)

    template <class Shared>
    class track
    {
    public:
        typedef std::atomic<size_t> counter;
        static counter instances;

    protected:
        track(const std::string& class_name, const std::string& log_name)
          : class_(class_name), log_(log_name)
        {
            bc::log_debug(log_)
                << class_ << "(" << ++instances << ")";
        }

        ~track()
        {
            bc::log_debug(log_)
                << "~" << class_ << "(" << --instances << ")";
        }

    private:
        const std::string class_;
        const std::string log_;
    };
#endif

#endif
<commit_msg>Add template<> keyword.<commit_after>/**
 * Copyright (c) 2011-2015 libbitcoin developers (see AUTHORS)
 *
 * This file is part of libbitcoin.
 *
 * libbitcoin is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License with
 * additional permissions to the one published by the Free Software
 * Foundation, either version 3 of the License, or (at your option)
 * any later version. For more information see LICENSE.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef LIBBITCOIN_ASSERT_HPP
#define LIBBITCOIN_ASSERT_HPP

#ifdef NDEBUG
    #define BITCOIN_ASSERT(expr)
    #define BITCOIN_ASSERT_MSG(expr, msg)
    #define DEBUG_ONLY(expression)
#else
    #include <cassert>
    #define BITCOIN_ASSERT(expr) assert(expr)
    #define BITCOIN_ASSERT_MSG(expr, msg) assert((expr)&&(msg))
    #define DEBUG_ONLY(expression) expression
#endif

#ifdef NDEBUG
    #define INITIALIZE_TRACK(class_name)

    template <class Shared>
    class track
    {
    protected:
        track(const std::string& log_name, const std::string&)
          : log_(log_name)
        {
        }

        const std::string log_;
    };
#else
    #include <atomic>
    #include <cstddef>
    #include <string>
    #include <bitcoin/bitcoin/utility/logger.hpp>
    #define INITIALIZE_TRACK(class_name) \
        template <> \
        track<class_name>::counter track<class_name>::instances(0)

    template <class Shared>
    class track
    {
    public:
        typedef std::atomic<size_t> counter;
        static counter instances;

    protected:
        track(const std::string& class_name, const std::string& log_name)
          : class_(class_name), log_(log_name)
        {
            bc::log_debug(log_)
                << class_ << "(" << ++instances << ")";
        }

        ~track()
        {
            bc::log_debug(log_)
                << "~" << class_ << "(" << --instances << ")";
        }

    private:
        const std::string class_;
        const std::string log_;
    };
#endif

#endif
<|endoftext|>


<commit_before>/*
 * File: include/commonpp/core/LoggingInterface.hpp
 * Part of commonpp.
 *
 * Distributed under the 2-clause BSD licence (See LICENCE.TXT file at the
 * project root).
 *
 * Copyright (c) 2015 Thomas Sanchez.  All rights reserved.
 *
 */

#pragma once

#include <iosfwd>

#include <commonpp/core/config.hpp>

#include <boost/log/core.hpp>
#include <boost/log/common.hpp>
#include <boost/log/sources/severity_feature.hpp>
#include <boost/log/sources/logger.hpp>
#include <boost/log/sources/severity_logger.hpp>
#include <boost/log/sources/severity_channel_logger.hpp>

#include <boost/log/expressions/keyword.hpp>
#include <boost/log/attributes.hpp>
#include <boost/log/attributes/named_scope.hpp>
#include <boost/log/attributes/scoped_attribute.hpp>

namespace commonpp
{

enum LoggingLevel
{
    trace,
    debug,
    info,
    warning,
    error,
    fatal,
};

UNUSED_ATTR static LoggingLevel to_severity(int lvl) noexcept
{
    switch (lvl)
    {
    case trace:
        return trace;
    case debug:
        return debug;
    case info:
        return info;
    case warning:
        return warning;
    case error:
        return error;
    case fatal:
        return fatal;
    }

    return info;
}

namespace core
{

std::ostream& operator<<(std::ostream& strm, LoggingLevel level);

using BasicLogger = boost::log::sources::severity_logger_mt<LoggingLevel>;
using Logger = boost::log::sources::severity_channel_logger_mt<LoggingLevel>;

#define COMPONENT(component_name)                                              \
    (boost::log::keywords::channel=component_name)

#define FWD_DECLARE_LOGGER(l, type)                                            \
    BOOST_LOG_GLOBAL_LOGGER(l##_type, type);                                   \
    extern type l;

#define DECLARE_BASIC_LOGGER(l)                                                \
    BOOST_LOG_GLOBAL_LOGGER_INIT(l##_type, ::commonpp::core::BasicLogger)      \
    {                                                                          \
        ::commonpp::core::BasicLogger logger;                                  \
        logger.add_attribute("CommonppRecord",                                 \
                             boost::log::attributes::constant<bool>(true));    \
        return logger;                                                         \
    }                                                                          \
    ::commonpp::core::BasicLogger l = l##_type::get()

#define DECLARE_LOGGER(l, component_name)                                      \
    BOOST_LOG_GLOBAL_LOGGER_INIT(l##_type, ::commonpp::core::Logger)           \
    {                                                                          \
        ::commonpp::core::Logger logger(COMPONENT(component_name));            \
        logger.add_attribute("CommonppRecord",                                 \
                             boost::log::attributes::constant<bool>(true));    \
        return logger;                                                         \
    }                                                                          \
    ::commonpp::core::Logger l = l##_type::get()

FWD_DECLARE_LOGGER(global_logger, BasicLogger);

#define LOGGER(name, component_name)                                           \
    ::commonpp::core::Logger name = []                                         \
    {                                                                          \
        ::commonpp::core::Logger l(COMPONENT(component_name));                 \
        l.add_attribute("CommonppRecord",                                      \
                        boost::log::attributes::constant<bool>(true));         \
        return l;                                                              \
    }();

#define ENABLE_CURRENT_FCT_LOGGING() BOOST_LOG_FUNCTION()

#define CREATE_LOGGER(logger, component_name)                                  \
    BOOST_LOG_INLINE_GLOBAL_LOGGER_CTOR_ARGS(                                  \
        logger##_type, ::commonpp::core::Logger, (COMPONENT(component_name))); \
    static auto& logger = []() -> decltype(logger##_type::get())               \
    {                                                                          \
        auto& l = logger##_type::get();                                        \
        l.add_attribute("CommonppRecord",                                      \
                        boost::log::attributes::constant<bool>(true));         \
        return l;                                                              \
    }();

#define LOG_SEV(l, s) BOOST_LOG_SEV(l, s)
#define GLOG_SEV(sev) LOG_SEV(::commonpp::core::global_logger, sev)
#define LOG(l, s) BOOST_LOG_SEV(l, ::commonpp::s)
#define GLOG(sev) LOG(::commonpp::core::global_logger, sev)
#define TRACE(sev) ENABLE_CURRENT_FCT_LOGGING(); GLOG(sev)
#define TRACE_LOG(l, sev) ENABLE_CURRENT_FCT_LOGGING(); LOG(l, sev)

// clang-format off
#ifndef NDEBUG
# define DLOG(l, s) BOOST_LOG_SEV(l, commonpp::s)
# define DGLOG(sev) LOG(::commonpp::core::global_logger, sev)
#else
// LOG() and GLOG() are way too complex to be in a ternary expression.
struct NullSink
{
    template <typename T>
    NullSink& operator<<(T&&)
    {
        return *this;
    }
};
// from Google glog
struct Voidify { void operator&(NullSink&){}};
# define DLOG(l, s) true ? (void)0 : commonpp::core::Voidify() & commonpp::core::NullSink()
# define DGLOG(sev) true ? (void)0 : commonpp::core::Voidify() & commonpp::core::NullSink()
#endif
// clang-format on

void init_logging();
void enable_console_logging();
void enable_builtin_syslog();
void auto_flush_console(bool b = true);
void set_logging_level(LoggingLevel level);

// default file pattern looks like: file_2008-07-05_13-44-23.1.log
void add_file_sink(const std::string& path = "file_%Y-%m-%d_%H-%M-%S.%N.log ");
void add_file_sink_rotate(
    const std::string& path = "file_%Y-%m-%d_%H-%M-%S.%N.log",
    size_t max_size = 0,
    boost::posix_time::hours period = boost::posix_time::hours(1));

// this should be called before any log happens
void set_logging_level_for_channel(const std::string& channel, LoggingLevel level);

} // namespace core
} // namespace commonpp
<commit_msg>Add debug TRACE macro, however the ENABLE_CURRENT_FCT_LOGGING might not be an expected side-effect. To be investigated.<commit_after>/*
 * File: include/commonpp/core/LoggingInterface.hpp
 * Part of commonpp.
 *
 * Distributed under the 2-clause BSD licence (See LICENCE.TXT file at the
 * project root).
 *
 * Copyright (c) 2015 Thomas Sanchez.  All rights reserved.
 *
 */

#pragma once

#include <iosfwd>

#include <commonpp/core/config.hpp>

#include <boost/log/core.hpp>
#include <boost/log/common.hpp>
#include <boost/log/sources/severity_feature.hpp>
#include <boost/log/sources/logger.hpp>
#include <boost/log/sources/severity_logger.hpp>
#include <boost/log/sources/severity_channel_logger.hpp>

#include <boost/log/expressions/keyword.hpp>
#include <boost/log/attributes.hpp>
#include <boost/log/attributes/named_scope.hpp>
#include <boost/log/attributes/scoped_attribute.hpp>

namespace commonpp
{

enum LoggingLevel
{
    trace,
    debug,
    info,
    warning,
    error,
    fatal,
};

UNUSED_ATTR static LoggingLevel to_severity(int lvl) noexcept
{
    switch (lvl)
    {
    case trace:
        return trace;
    case debug:
        return debug;
    case info:
        return info;
    case warning:
        return warning;
    case error:
        return error;
    case fatal:
        return fatal;
    }

    return info;
}

namespace core
{

std::ostream& operator<<(std::ostream& strm, LoggingLevel level);

using BasicLogger = boost::log::sources::severity_logger_mt<LoggingLevel>;
using Logger = boost::log::sources::severity_channel_logger_mt<LoggingLevel>;

#define COMPONENT(component_name)                                              \
    (boost::log::keywords::channel=component_name)

#define FWD_DECLARE_LOGGER(l, type)                                            \
    BOOST_LOG_GLOBAL_LOGGER(l##_type, type);                                   \
    extern type l;

#define DECLARE_BASIC_LOGGER(l)                                                \
    BOOST_LOG_GLOBAL_LOGGER_INIT(l##_type, ::commonpp::core::BasicLogger)      \
    {                                                                          \
        ::commonpp::core::BasicLogger logger;                                  \
        logger.add_attribute("CommonppRecord",                                 \
                             boost::log::attributes::constant<bool>(true));    \
        return logger;                                                         \
    }                                                                          \
    ::commonpp::core::BasicLogger l = l##_type::get()

#define DECLARE_LOGGER(l, component_name)                                      \
    BOOST_LOG_GLOBAL_LOGGER_INIT(l##_type, ::commonpp::core::Logger)           \
    {                                                                          \
        ::commonpp::core::Logger logger(COMPONENT(component_name));            \
        logger.add_attribute("CommonppRecord",                                 \
                             boost::log::attributes::constant<bool>(true));    \
        return logger;                                                         \
    }                                                                          \
    ::commonpp::core::Logger l = l##_type::get()

FWD_DECLARE_LOGGER(global_logger, BasicLogger);

#define LOGGER(name, component_name)                                           \
    ::commonpp::core::Logger name = []                                         \
    {                                                                          \
        ::commonpp::core::Logger l(COMPONENT(component_name));                 \
        l.add_attribute("CommonppRecord",                                      \
                        boost::log::attributes::constant<bool>(true));         \
        return l;                                                              \
    }();

#define ENABLE_CURRENT_FCT_LOGGING() BOOST_LOG_FUNCTION()

#define CREATE_LOGGER(logger, component_name)                                  \
    BOOST_LOG_INLINE_GLOBAL_LOGGER_CTOR_ARGS(                                  \
        logger##_type, ::commonpp::core::Logger, (COMPONENT(component_name))); \
    static auto& logger = []() -> decltype(logger##_type::get())               \
    {                                                                          \
        auto& l = logger##_type::get();                                        \
        l.add_attribute("CommonppRecord",                                      \
                        boost::log::attributes::constant<bool>(true));         \
        return l;                                                              \
    }();

#define LOG_SEV(l, s) BOOST_LOG_SEV(l, s)
#define GLOG_SEV(sev) LOG_SEV(::commonpp::core::global_logger, sev)
#define LOG(l, s) BOOST_LOG_SEV(l, ::commonpp::s)
#define GLOG(sev) LOG(::commonpp::core::global_logger, sev)
#define TRACE(sev) ENABLE_CURRENT_FCT_LOGGING(); GLOG(sev)
#define TRACE_LOG(l, sev) ENABLE_CURRENT_FCT_LOGGING(); LOG(l, sev)

// clang-format off
#ifndef NDEBUG
# define DLOG(l, s) BOOST_LOG_SEV(l, commonpp::s)
# define DGLOG(sev) LOG(::commonpp::core::global_logger, sev)
#else
// LOG() and GLOG() are way too complex to be in a ternary expression.
struct NullSink
{
    template <typename T>
    NullSink& operator<<(T&&)
    {
        return *this;
    }
};
// from Google glog
struct Voidify { void operator&(NullSink&){}};
# define DLOG(l, s) true ? (void)0 : commonpp::core::Voidify() & commonpp::core::NullSink()
# define DGLOG(sev) true ? (void)0 : commonpp::core::Voidify() & commonpp::core::NullSink()
#endif
// clang-format on

#define DTRACE(sev)                                                            \
    ENABLE_CURRENT_FCT_LOGGING();                                              \
    DGLOG(sev)
#define DTRACE_LOG(l, sev)                                                     \
    ENABLE_CURRENT_FCT_LOGGING();                                              \
    DLOG(l, sev)

void init_logging();
void enable_console_logging();
void enable_builtin_syslog();
void auto_flush_console(bool b = true);
void set_logging_level(LoggingLevel level);

// default file pattern looks like: file_2008-07-05_13-44-23.1.log
void add_file_sink(const std::string& path = "file_%Y-%m-%d_%H-%M-%S.%N.log ");
void add_file_sink_rotate(
    const std::string& path = "file_%Y-%m-%d_%H-%M-%S.%N.log",
    size_t max_size = 0,
    boost::posix_time::hours period = boost::posix_time::hours(1));

// this should be called before any log happens
void set_logging_level_for_channel(const std::string& channel, LoggingLevel level);

} // namespace core
} // namespace commonpp
<|endoftext|>