<commit_before>#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <kms++/kms++.h>

namespace py = pybind11;

using namespace kms;
using namespace std;

void init_pykmsbase(py::module &m)
{
	py::class_<Card>(m, "Card")
			.def(py::init<>())
			.def_property_readonly("fd", &Card::fd)
			.def_property_readonly("get_first_connected_connector", &Card::get_first_connected_connector)

			// XXX pybind11 can't handle vector<T*> where T is non-copyable, and complains:
			// RuntimeError: return_value_policy = move, but the object is neither movable nor copyable!
			// So we do this manually.
			.def_property_readonly("connectors", [](Card* self) {
				vector<unique_ptr<Connector, py::nodelete>> v;
				for (Connector* p : self->get_connectors())
					v.push_back(unique_ptr<Connector, py::nodelete>(p));
				return v;
			})

			.def_property_readonly("planes", [](Card* self) {
				vector<unique_ptr<Plane, py::nodelete>> v;
				for (Plane* p : self->get_planes())
					v.push_back(unique_ptr<Plane, py::nodelete>(p));
				return v;
			})

			.def_property_readonly("has_atomic", &Card::has_atomic)
			.def("get_prop", (Property* (Card::*)(uint32_t) const)&Card::get_prop)
			;

	py::class_<DrmObject, unique_ptr<DrmObject, py::nodelete>>(m, "DrmObject")
			.def_property_readonly("id", &DrmObject::id)
			.def_property_readonly("idx", &DrmObject::idx)
			.def_property_readonly("card", &DrmObject::card)
			;

	py::class_<DrmPropObject, DrmObject, unique_ptr<DrmPropObject, py::nodelete>>(m, "DrmPropObject")
			.def("refresh_props", &DrmPropObject::refresh_props)
			.def_property_readonly("prop_map", &DrmPropObject::get_prop_map)
			.def("get_prop_value", (uint64_t (DrmPropObject::*)(const string&) const)&DrmPropObject::get_prop_value)
			.def("set_prop_value",(int (DrmPropObject::*)(const string&, uint64_t)) &DrmPropObject::set_prop_value)
			.def("get_prop_value_as_blob", &DrmPropObject::get_prop_value_as_blob)
			.def("get_prop", &DrmPropObject::get_prop)
			;

	py::class_<Connector, DrmPropObject, unique_ptr<Connector, py::nodelete>>(m, "Connector")
			.def_property_readonly("fullname", &Connector::fullname)
			.def("get_default_mode", &Connector::get_default_mode)
			.def("get_current_crtc", &Connector::get_current_crtc)
			.def("get_possible_crtcs", &Connector::get_possible_crtcs)
			.def("get_modes", &Connector::get_modes)
			.def("get_mode", (Videomode (Connector::*)(const string& mode) const)&Connector::get_mode)
			.def("get_mode", (Videomode (Connector::*)(unsigned xres, unsigned yres, float refresh, bool ilace) const)&Connector::get_mode)
			.def("connected", &Connector::connected)
			.def("__repr__", [](const Connector& o) { return "<pykms.Connector " + to_string(o.id()) + ">"; })
			.def("refresh", &Connector::refresh)
			;

	py::class_<Crtc, DrmPropObject, unique_ptr<Crtc, py::nodelete>>(m, "Crtc")
			.def("set_mode", (int (Crtc::*)(Connector*, const Videomode&))&Crtc::set_mode)
			.def("set_mode", (int (Crtc::*)(Connector*, Framebuffer&, const Videomode&))&Crtc::set_mode)
			.def("disable_mode", &Crtc::disable_mode)
			.def("page_flip",
			     [](Crtc* self, Framebuffer& fb, uint32_t data)
				{
					self->page_flip(fb, (void*)(intptr_t)data);
				}, py::arg("fb"), py::arg("data") = 0)
			.def("set_plane", &Crtc::set_plane)
			.def_property_readonly("possible_planes", &Crtc::get_possible_planes)
			.def_property_readonly("primary_plane", &Crtc::get_primary_plane)
			.def_property_readonly("mode", &Crtc::mode)
			.def_property_readonly("mode_valid", &Crtc::mode_valid)
			.def("__repr__", [](const Crtc& o) { return "<pykms.Crtc " + to_string(o.id()) + ">"; })
			.def("refresh", &Crtc::refresh)
			;

	py::class_<Encoder, DrmPropObject, unique_ptr<Encoder, py::nodelete>>(m, "Encoder")
			.def("refresh", &Encoder::refresh)
			;

	py::class_<Plane, DrmPropObject, unique_ptr<Plane, py::nodelete>>(m, "Plane")
			.def("supports_crtc", &Plane::supports_crtc)
			.def_property_readonly("formats", &Plane::get_formats)
			.def_property_readonly("plane_type", &Plane::plane_type)
			.def("__repr__", [](const Plane& o) { return "<pykms.Plane " + to_string(o.id()) + ">"; })
			;

	py::enum_<PlaneType>(m, "PlaneType")
			.value("Overlay", PlaneType::Overlay)
			.value("Primary", PlaneType::Primary)
			.value("Cursor", PlaneType::Cursor)
			;

	py::class_<Property, DrmObject, unique_ptr<Property, py::nodelete>>(m, "Property")
			.def_property_readonly("name", &Property::name)
			.def_property_readonly("enums", &Property::get_enums)
			;

	py::class_<Blob>(m, "Blob")
			.def("__init__", [](Blob& instance, Card& card, py::buffer buf) {
				py::buffer_info info = buf.request();
				if (info.ndim != 1)
					throw std::runtime_error("Incompatible buffer dimension!");

				new (&instance) Blob(card, info.ptr, info.size * info.itemsize);
			})
			.def_property_readonly("data", &Blob::data)

			// XXX pybind11 doesn't support a base object (DrmObject) with custom holder-type,
			// and a subclass with standard holder-type.
			// So we just copy the DrmObject members here.
			// Note that this means that python thinks we don't derive from DrmObject
			.def_property_readonly("id", &DrmObject::id)
			.def_property_readonly("idx", &DrmObject::idx)
			.def_property_readonly("card", &DrmObject::card)
			;

	py::class_<Framebuffer>(m, "Framebuffer")
			.def_property_readonly("width", &Framebuffer::width)
			.def_property_readonly("height", &Framebuffer::height)

			// XXX pybind11 doesn't support a base object (DrmObject) with custom holder-type,
			// and a subclass with standard holder-type.
			// So we just copy the DrmObject members here.
			// Note that this means that python thinks we don't derive from DrmObject
			.def_property_readonly("id", &DrmObject::id)
			.def_property_readonly("idx", &DrmObject::idx)
			.def_property_readonly("card", &DrmObject::card)
			;

	py::class_<DumbFramebuffer, Framebuffer>(m, "DumbFramebuffer")
			.def(py::init<Card&, uint32_t, uint32_t, const string&>(),
			     py::keep_alive<1, 2>())	// Keep Card alive until this is destructed
			.def(py::init<Card&, uint32_t, uint32_t, PixelFormat>(),
			     py::keep_alive<1, 2>())	// Keep Card alive until this is destructed
			.def_property_readonly("format", &DumbFramebuffer::format)
			.def_property_readonly("num_planes", &DumbFramebuffer::num_planes)
			.def("fd", &DumbFramebuffer::prime_fd)
			.def("stride", &DumbFramebuffer::stride)
			.def("offset", &DumbFramebuffer::offset)
			;

	py::class_<ExtFramebuffer, Framebuffer>(m, "ExtFramebuffer")
			.def(py::init<Card&, uint32_t, uint32_t, PixelFormat, vector<int>, vector<uint32_t>, vector<uint32_t>>(),
			     py::keep_alive<1, 2>())	// Keep Card alive until this is destructed
			;

	py::enum_<PixelFormat>(m, "PixelFormat")
			.value("Undefined", PixelFormat::Undefined)

			.value("NV12", PixelFormat::NV12)
			.value("NV21", PixelFormat::NV21)

			.value("UYVY", PixelFormat::UYVY)
			.value("YUYV", PixelFormat::YUYV)
			.value("YVYU", PixelFormat::YVYU)
			.value("VYUY", PixelFormat::VYUY)

			.value("XRGB8888", PixelFormat::XRGB8888)
			.value("XBGR8888", PixelFormat::XBGR8888)
			.value("ARGB8888", PixelFormat::ARGB8888)
			.value("ABGR8888", PixelFormat::ABGR8888)

			.value("RGB888", PixelFormat::RGB888)
			.value("BGR888", PixelFormat::BGR888)

			.value("RGB565", PixelFormat::RGB565)
			.value("BGR565", PixelFormat::BGR565)
			;

	py::enum_<SyncPolarity>(m, "SyncPolarity")
			.value("Undefined", SyncPolarity::Undefined)
			.value("Positive", SyncPolarity::Positive)
			.value("Negative", SyncPolarity::Negative)
			;

	py::class_<Videomode>(m, "Videomode")
			.def(py::init<>())

			.def_readwrite("name", &Videomode::name)

			.def_readwrite("clock", &Videomode::clock)

			.def_readwrite("hdisplay", &Videomode::hdisplay)
			.def_readwrite("hsync_start", &Videomode::hsync_start)
			.def_readwrite("hsync_end", &Videomode::hsync_end)
			.def_readwrite("htotal", &Videomode::htotal)

			.def_readwrite("vdisplay", &Videomode::vdisplay)
			.def_readwrite("vsync_start", &Videomode::vsync_start)
			.def_readwrite("vsync_end", &Videomode::vsync_end)
			.def_readwrite("vtotal", &Videomode::vtotal)

			.def_readwrite("vrefresh", &Videomode::vrefresh)

			.def_readwrite("flags", &Videomode::flags)
			.def_readwrite("type", &Videomode::type)

			.def("__repr__", [](const Videomode& vm) { return "<pykms.Videomode " + to_string(vm.hdisplay) + "x" + to_string(vm.vdisplay) + ">"; })

			.def("to_blob", &Videomode::to_blob)

			.def_property("hsync", &Videomode::hsync, &Videomode::set_hsync)
			.def_property("vsync", &Videomode::vsync, &Videomode::set_vsync)
			;

	m.def("videomode_from_timings", &videomode_from_timings);

	py::class_<AtomicReq>(m, "AtomicReq")
			.def(py::init<Card&>(),
			     py::keep_alive<1, 2>())	// Keep Card alive until this is destructed
			.def("add", (void (AtomicReq::*)(DrmPropObject*, const string&, uint64_t)) &AtomicReq::add)
			.def("add", (void (AtomicReq::*)(DrmPropObject*, const map<string, uint64_t>&)) &AtomicReq::add)
			.def("test", &AtomicReq::test, py::arg("allow_modeset") = false)
			.def("commit",
			     [](AtomicReq* self, uint32_t data, bool allow)
				{
					return self->commit((void*)(intptr_t)data, allow);
				}, py::arg("data") = 0, py::arg("allow_modeset") = false)
			.def("commit_sync", &AtomicReq::commit_sync, py::arg("allow_modeset") = false)
			;
}
<commit_msg>pykms: keep Card alive until Blob is gone<commit_after>#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <kms++/kms++.h>

namespace py = pybind11;

using namespace kms;
using namespace std;

void init_pykmsbase(py::module &m)
{
	py::class_<Card>(m, "Card")
			.def(py::init<>())
			.def_property_readonly("fd", &Card::fd)
			.def_property_readonly("get_first_connected_connector", &Card::get_first_connected_connector)

			// XXX pybind11 can't handle vector<T*> where T is non-copyable, and complains:
			// RuntimeError: return_value_policy = move, but the object is neither movable nor copyable!
			// So we do this manually.
			.def_property_readonly("connectors", [](Card* self) {
				vector<unique_ptr<Connector, py::nodelete>> v;
				for (Connector* p : self->get_connectors())
					v.push_back(unique_ptr<Connector, py::nodelete>(p));
				return v;
			})

			.def_property_readonly("planes", [](Card* self) {
				vector<unique_ptr<Plane, py::nodelete>> v;
				for (Plane* p : self->get_planes())
					v.push_back(unique_ptr<Plane, py::nodelete>(p));
				return v;
			})

			.def_property_readonly("has_atomic", &Card::has_atomic)
			.def("get_prop", (Property* (Card::*)(uint32_t) const)&Card::get_prop)
			;

	py::class_<DrmObject, unique_ptr<DrmObject, py::nodelete>>(m, "DrmObject")
			.def_property_readonly("id", &DrmObject::id)
			.def_property_readonly("idx", &DrmObject::idx)
			.def_property_readonly("card", &DrmObject::card)
			;

	py::class_<DrmPropObject, DrmObject, unique_ptr<DrmPropObject, py::nodelete>>(m, "DrmPropObject")
			.def("refresh_props", &DrmPropObject::refresh_props)
			.def_property_readonly("prop_map", &DrmPropObject::get_prop_map)
			.def("get_prop_value", (uint64_t (DrmPropObject::*)(const string&) const)&DrmPropObject::get_prop_value)
			.def("set_prop_value",(int (DrmPropObject::*)(const string&, uint64_t)) &DrmPropObject::set_prop_value)
			.def("get_prop_value_as_blob", &DrmPropObject::get_prop_value_as_blob)
			.def("get_prop", &DrmPropObject::get_prop)
			;

	py::class_<Connector, DrmPropObject, unique_ptr<Connector, py::nodelete>>(m, "Connector")
			.def_property_readonly("fullname", &Connector::fullname)
			.def("get_default_mode", &Connector::get_default_mode)
			.def("get_current_crtc", &Connector::get_current_crtc)
			.def("get_possible_crtcs", &Connector::get_possible_crtcs)
			.def("get_modes", &Connector::get_modes)
			.def("get_mode", (Videomode (Connector::*)(const string& mode) const)&Connector::get_mode)
			.def("get_mode", (Videomode (Connector::*)(unsigned xres, unsigned yres, float refresh, bool ilace) const)&Connector::get_mode)
			.def("connected", &Connector::connected)
			.def("__repr__", [](const Connector& o) { return "<pykms.Connector " + to_string(o.id()) + ">"; })
			.def("refresh", &Connector::refresh)
			;

	py::class_<Crtc, DrmPropObject, unique_ptr<Crtc, py::nodelete>>(m, "Crtc")
			.def("set_mode", (int (Crtc::*)(Connector*, const Videomode&))&Crtc::set_mode)
			.def("set_mode", (int (Crtc::*)(Connector*, Framebuffer&, const Videomode&))&Crtc::set_mode)
			.def("disable_mode", &Crtc::disable_mode)
			.def("page_flip",
			     [](Crtc* self, Framebuffer& fb, uint32_t data)
				{
					self->page_flip(fb, (void*)(intptr_t)data);
				}, py::arg("fb"), py::arg("data") = 0)
			.def("set_plane", &Crtc::set_plane)
			.def_property_readonly("possible_planes", &Crtc::get_possible_planes)
			.def_property_readonly("primary_plane", &Crtc::get_primary_plane)
			.def_property_readonly("mode", &Crtc::mode)
			.def_property_readonly("mode_valid", &Crtc::mode_valid)
			.def("__repr__", [](const Crtc& o) { return "<pykms.Crtc " + to_string(o.id()) + ">"; })
			.def("refresh", &Crtc::refresh)
			;

	py::class_<Encoder, DrmPropObject, unique_ptr<Encoder, py::nodelete>>(m, "Encoder")
			.def("refresh", &Encoder::refresh)
			;

	py::class_<Plane, DrmPropObject, unique_ptr<Plane, py::nodelete>>(m, "Plane")
			.def("supports_crtc", &Plane::supports_crtc)
			.def_property_readonly("formats", &Plane::get_formats)
			.def_property_readonly("plane_type", &Plane::plane_type)
			.def("__repr__", [](const Plane& o) { return "<pykms.Plane " + to_string(o.id()) + ">"; })
			;

	py::enum_<PlaneType>(m, "PlaneType")
			.value("Overlay", PlaneType::Overlay)
			.value("Primary", PlaneType::Primary)
			.value("Cursor", PlaneType::Cursor)
			;

	py::class_<Property, DrmObject, unique_ptr<Property, py::nodelete>>(m, "Property")
			.def_property_readonly("name", &Property::name)
			.def_property_readonly("enums", &Property::get_enums)
			;

	py::class_<Blob>(m, "Blob")
			.def("__init__", [](Blob& instance, Card& card, py::buffer buf) {
					py::buffer_info info = buf.request();
					if (info.ndim != 1)
						throw std::runtime_error("Incompatible buffer dimension!");

					new (&instance) Blob(card, info.ptr, info.size * info.itemsize);
				},
				py::keep_alive<1, 3>())	// Keep Card alive until this is destructed

			.def_property_readonly("data", &Blob::data)

			// XXX pybind11 doesn't support a base object (DrmObject) with custom holder-type,
			// and a subclass with standard holder-type.
			// So we just copy the DrmObject members here.
			// Note that this means that python thinks we don't derive from DrmObject
			.def_property_readonly("id", &DrmObject::id)
			.def_property_readonly("idx", &DrmObject::idx)
			.def_property_readonly("card", &DrmObject::card)
			;

	py::class_<Framebuffer>(m, "Framebuffer")
			.def_property_readonly("width", &Framebuffer::width)
			.def_property_readonly("height", &Framebuffer::height)

			// XXX pybind11 doesn't support a base object (DrmObject) with custom holder-type,
			// and a subclass with standard holder-type.
			// So we just copy the DrmObject members here.
			// Note that this means that python thinks we don't derive from DrmObject
			.def_property_readonly("id", &DrmObject::id)
			.def_property_readonly("idx", &DrmObject::idx)
			.def_property_readonly("card", &DrmObject::card)
			;

	py::class_<DumbFramebuffer, Framebuffer>(m, "DumbFramebuffer")
			.def(py::init<Card&, uint32_t, uint32_t, const string&>(),
			     py::keep_alive<1, 2>())	// Keep Card alive until this is destructed
			.def(py::init<Card&, uint32_t, uint32_t, PixelFormat>(),
			     py::keep_alive<1, 2>())	// Keep Card alive until this is destructed
			.def_property_readonly("format", &DumbFramebuffer::format)
			.def_property_readonly("num_planes", &DumbFramebuffer::num_planes)
			.def("fd", &DumbFramebuffer::prime_fd)
			.def("stride", &DumbFramebuffer::stride)
			.def("offset", &DumbFramebuffer::offset)
			;

	py::class_<ExtFramebuffer, Framebuffer>(m, "ExtFramebuffer")
			.def(py::init<Card&, uint32_t, uint32_t, PixelFormat, vector<int>, vector<uint32_t>, vector<uint32_t>>(),
			     py::keep_alive<1, 2>())	// Keep Card alive until this is destructed
			;

	py::enum_<PixelFormat>(m, "PixelFormat")
			.value("Undefined", PixelFormat::Undefined)

			.value("NV12", PixelFormat::NV12)
			.value("NV21", PixelFormat::NV21)

			.value("UYVY", PixelFormat::UYVY)
			.value("YUYV", PixelFormat::YUYV)
			.value("YVYU", PixelFormat::YVYU)
			.value("VYUY", PixelFormat::VYUY)

			.value("XRGB8888", PixelFormat::XRGB8888)
			.value("XBGR8888", PixelFormat::XBGR8888)
			.value("ARGB8888", PixelFormat::ARGB8888)
			.value("ABGR8888", PixelFormat::ABGR8888)

			.value("RGB888", PixelFormat::RGB888)
			.value("BGR888", PixelFormat::BGR888)

			.value("RGB565", PixelFormat::RGB565)
			.value("BGR565", PixelFormat::BGR565)
			;

	py::enum_<SyncPolarity>(m, "SyncPolarity")
			.value("Undefined", SyncPolarity::Undefined)
			.value("Positive", SyncPolarity::Positive)
			.value("Negative", SyncPolarity::Negative)
			;

	py::class_<Videomode>(m, "Videomode")
			.def(py::init<>())

			.def_readwrite("name", &Videomode::name)

			.def_readwrite("clock", &Videomode::clock)

			.def_readwrite("hdisplay", &Videomode::hdisplay)
			.def_readwrite("hsync_start", &Videomode::hsync_start)
			.def_readwrite("hsync_end", &Videomode::hsync_end)
			.def_readwrite("htotal", &Videomode::htotal)

			.def_readwrite("vdisplay", &Videomode::vdisplay)
			.def_readwrite("vsync_start", &Videomode::vsync_start)
			.def_readwrite("vsync_end", &Videomode::vsync_end)
			.def_readwrite("vtotal", &Videomode::vtotal)

			.def_readwrite("vrefresh", &Videomode::vrefresh)

			.def_readwrite("flags", &Videomode::flags)
			.def_readwrite("type", &Videomode::type)

			.def("__repr__", [](const Videomode& vm) { return "<pykms.Videomode " + to_string(vm.hdisplay) + "x" + to_string(vm.vdisplay) + ">"; })

			.def("to_blob", &Videomode::to_blob)

			.def_property("hsync", &Videomode::hsync, &Videomode::set_hsync)
			.def_property("vsync", &Videomode::vsync, &Videomode::set_vsync)
			;

	m.def("videomode_from_timings", &videomode_from_timings);

	py::class_<AtomicReq>(m, "AtomicReq")
			.def(py::init<Card&>(),
			     py::keep_alive<1, 2>())	// Keep Card alive until this is destructed
			.def("add", (void (AtomicReq::*)(DrmPropObject*, const string&, uint64_t)) &AtomicReq::add)
			.def("add", (void (AtomicReq::*)(DrmPropObject*, const map<string, uint64_t>&)) &AtomicReq::add)
			.def("test", &AtomicReq::test, py::arg("allow_modeset") = false)
			.def("commit",
			     [](AtomicReq* self, uint32_t data, bool allow)
				{
					return self->commit((void*)(intptr_t)data, allow);
				}, py::arg("data") = 0, py::arg("allow_modeset") = false)
			.def("commit_sync", &AtomicReq::commit_sync, py::arg("allow_modeset") = false)
			;
}
<|endoftext|>


<commit_before>/*
    This file is part of KDE Kontact.

    Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org>

    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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

    As a special exception, permission is given to link this program
    with any edition of Qt, and distribute the resulting executable,
    without including the source code for Qt in the source distribution.
*/

#include "aboutdialog.h"
#include "aboutdialog.moc"

#include "core.h"
#include "plugin.h"

#include <klocale.h>
#include <kiconloader.h>
#include <kaboutdata.h>
#include <kactivelabel.h>
#include <ktextbrowser.h>

#include <qlayout.h>
#include <qlabel.h>

#include <kdebug.h>

using namespace Kontact;

AboutDialog::AboutDialog( Kontact::Core *core, const char *name )
  : KDialogBase( IconList, i18n("About Kontact"), Ok, Ok, core, name, false,
                 true ),
    mCore( core )
{
  addAboutData( i18n("Kontact Container"), QString( "kontact" ),
                KGlobal::instance()->aboutData() );

  QValueList<Plugin*> plugins = mCore->pluginList();
  QValueList<Plugin*>::ConstIterator end = plugins.end();
  QValueList<Plugin*>::ConstIterator it = plugins.begin();
  for ( ; it != end; ++it ) {
    addAboutPlugin( *it );
  }

  addLicenseText( KGlobal::instance()->aboutData() );
}

void AboutDialog::addAboutPlugin( Kontact::Plugin *plugin )
{
  addAboutData( plugin->title(), plugin->icon(), plugin->aboutData() );
}

void AboutDialog::addAboutData( const QString &title, const QString &icon,
                                const KAboutData *about )
{
  QPixmap pixmap = KGlobal::iconLoader()->loadIcon( icon,
                                                    KIcon::Desktop, 48 );

  QFrame *topFrame = addPage( title, QString::null, pixmap );

  QBoxLayout *topLayout = new QVBoxLayout( topFrame );

  if ( !about ) {
    QLabel *label = new QLabel( i18n("No about information available."),
                                topFrame );
    topLayout->addWidget( label );
  } else {
    QString text;

    text += "
" + about->programName() + "
";

    text += i18n("Version %1
").arg( about->version() );

    if (!about->shortDescription().isEmpty()) {
      text += "
" + about->shortDescription() + "
" +
               about->copyrightStatement() + "
";
    }

    QString home = about->homepage();
    if ( !home.isEmpty() ) {
      text += "" + home + "
";
    }

    text.replace( "\n", "
" );

    KActiveLabel *label = new KActiveLabel( text, topFrame );
    label->setAlignment( AlignTop );
    topLayout->addWidget( label );

    QTextEdit *personView = new QTextEdit( topFrame );
    personView->setReadOnly( true );
    topLayout->addWidget( personView, 1 );

    text = "";

    QValueList<KAboutPerson> authors = about->authors();
    if ( !authors.isEmpty() ) {
      text += i18n("
Authors:
");

      QValueList<KAboutPerson>::ConstIterator it;
      for( it = authors.begin(); it != authors.end(); ++it ) {
        text += formatPerson( (*it).name(), (*it).emailAddress() );
        if (!(*it).task().isEmpty()) text += "" + (*it).task() + "
";
      }
    }

    QValueList<KAboutPerson> credits = about->credits();
    if ( !credits.isEmpty() ) {
      text += i18n("
Thanks to:
");

      QValueList<KAboutPerson>::ConstIterator it;
      for( it = credits.begin(); it != credits.end(); ++it ) {
        text += formatPerson( (*it).name(), (*it).emailAddress() );
        if (!(*it).task().isEmpty()) text += "" + (*it).task() + "
";
      }
    }

    QValueList<KAboutTranslator> translators = about->translators();
    if ( !translators.isEmpty() ) {
      text += i18n("
Translators:
");

      QValueList<KAboutTranslator>::ConstIterator it;
      for( it = translators.begin(); it != translators.end(); ++it ) {
       text += formatPerson( (*it).name(), (*it).emailAddress() );
      }
    }

    personView->setText( text );
  }
}

QString AboutDialog::formatPerson( const QString &name, const QString &email )
{
  QString text = name;
  if ( !email.isEmpty() ) {
    text += " <" + email + ">";
  }
  text += "
";
  return text;
}

void AboutDialog::addLicenseText(const KAboutData *about)
{
  if ( !about || about->license().isEmpty() ) return;

  QPixmap pixmap = KGlobal::iconLoader()->loadIcon( "signature",
                                                    KIcon::Desktop, 48 );

  QString title = i18n("%1 license").arg(about->programName());

  QFrame *topFrame = addPage( title, QString::null, pixmap );
  QBoxLayout *topLayout = new QVBoxLayout( topFrame );

  KTextBrowser *textBrowser = new KTextBrowser( topFrame );
  textBrowser->setText( QString("
%1
").arg(about->license()) );

  topLayout->addWidget(textBrowser);
}
<commit_msg>CVS_SILENT i18n style guide fix<commit_after>/*
    This file is part of KDE Kontact.

    Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org>

    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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

    As a special exception, permission is given to link this program
    with any edition of Qt, and distribute the resulting executable,
    without including the source code for Qt in the source distribution.
*/

#include "aboutdialog.h"
#include "aboutdialog.moc"

#include "core.h"
#include "plugin.h"

#include <klocale.h>
#include <kiconloader.h>
#include <kaboutdata.h>
#include <kactivelabel.h>
#include <ktextbrowser.h>

#include <qlayout.h>
#include <qlabel.h>

#include <kdebug.h>

using namespace Kontact;

AboutDialog::AboutDialog( Kontact::Core *core, const char *name )
  : KDialogBase( IconList, i18n("About Kontact"), Ok, Ok, core, name, false,
                 true ),
    mCore( core )
{
  addAboutData( i18n("Kontact Container"), QString( "kontact" ),
                KGlobal::instance()->aboutData() );

  QValueList<Plugin*> plugins = mCore->pluginList();
  QValueList<Plugin*>::ConstIterator end = plugins.end();
  QValueList<Plugin*>::ConstIterator it = plugins.begin();
  for ( ; it != end; ++it ) {
    addAboutPlugin( *it );
  }

  addLicenseText( KGlobal::instance()->aboutData() );
}

void AboutDialog::addAboutPlugin( Kontact::Plugin *plugin )
{
  addAboutData( plugin->title(), plugin->icon(), plugin->aboutData() );
}

void AboutDialog::addAboutData( const QString &title, const QString &icon,
                                const KAboutData *about )
{
  QPixmap pixmap = KGlobal::iconLoader()->loadIcon( icon,
                                                    KIcon::Desktop, 48 );

  QFrame *topFrame = addPage( title, QString::null, pixmap );

  QBoxLayout *topLayout = new QVBoxLayout( topFrame );

  if ( !about ) {
    QLabel *label = new QLabel( i18n("No about information available."),
                                topFrame );
    topLayout->addWidget( label );
  } else {
    QString text;

    text += "
" + about->programName() + "
";

    text += i18n("Version %1
").arg( about->version() );

    if (!about->shortDescription().isEmpty()) {
      text += "
" + about->shortDescription() + "
" +
               about->copyrightStatement() + "
";
    }

    QString home = about->homepage();
    if ( !home.isEmpty() ) {
      text += "" + home + "
";
    }

    text.replace( "\n", "
" );

    KActiveLabel *label = new KActiveLabel( text, topFrame );
    label->setAlignment( AlignTop );
    topLayout->addWidget( label );

    QTextEdit *personView = new QTextEdit( topFrame );
    personView->setReadOnly( true );
    topLayout->addWidget( personView, 1 );

    text = "";

    QValueList<KAboutPerson> authors = about->authors();
    if ( !authors.isEmpty() ) {
      text += i18n("
Authors:
");

      QValueList<KAboutPerson>::ConstIterator it;
      for( it = authors.begin(); it != authors.end(); ++it ) {
        text += formatPerson( (*it).name(), (*it).emailAddress() );
        if (!(*it).task().isEmpty()) text += "" + (*it).task() + "
";
      }
    }

    QValueList<KAboutPerson> credits = about->credits();
    if ( !credits.isEmpty() ) {
      text += i18n("
Thanks to:
");

      QValueList<KAboutPerson>::ConstIterator it;
      for( it = credits.begin(); it != credits.end(); ++it ) {
        text += formatPerson( (*it).name(), (*it).emailAddress() );
        if (!(*it).task().isEmpty()) text += "" + (*it).task() + "
";
      }
    }

    QValueList<KAboutTranslator> translators = about->translators();
    if ( !translators.isEmpty() ) {
      text += i18n("
Translators:
");

      QValueList<KAboutTranslator>::ConstIterator it;
      for( it = translators.begin(); it != translators.end(); ++it ) {
       text += formatPerson( (*it).name(), (*it).emailAddress() );
      }
    }

    personView->setText( text );
  }
}

QString AboutDialog::formatPerson( const QString &name, const QString &email )
{
  QString text = name;
  if ( !email.isEmpty() ) {
    text += " <" + email + ">";
  }
  text += "
";
  return text;
}

void AboutDialog::addLicenseText(const KAboutData *about)
{
  if ( !about || about->license().isEmpty() ) return;

  QPixmap pixmap = KGlobal::iconLoader()->loadIcon( "signature",
                                                    KIcon::Desktop, 48 );

  QString title = i18n("%1 License").arg(about->programName());

  QFrame *topFrame = addPage( title, QString::null, pixmap );
  QBoxLayout *topLayout = new QVBoxLayout( topFrame );

  KTextBrowser *textBrowser = new KTextBrowser( topFrame );
  textBrowser->setText( QString("
%1
").arg(about->license()) );

  topLayout->addWidget(textBrowser);
}
<|endoftext|>


<commit_before>#include <gflags/gflags.h>
#include <stddef.h>
#include <chrono>
#include <cmath>
#include <cstdint>
#include <memory>
#include <random>
#include <string>
#include <utility>
#include <vector>

#include "ncode_common/src/common.h"
#include "ncode_common/src/file.h"
#include "ncode_common/src/logging.h"
#include "ncode_common/src/lp/demand_matrix.h"
#include "ncode_common/src/net/algorithm.h"
#include "ncode_common/src/net/net_common.h"
#include "ncode_common/src/perfect_hash.h"
#include "ncode_common/src/strutil.h"
#include "ncode_common/src/substitute.h"
#include "ncode_common/src/thread_runner.h"
#include "opt/opt.h"
#include "topology_input.h"

DEFINE_string(output_pattern,
              "demand_matrices/scale_factor_$2/locality_$1/$0_$3.demands",
              "Traffic matrices will be saved to files named after this "
              "pattern, with $0 replaced by the topology name, $1 replaced by "
              "locality, $2 replaced by scale factor and $3 replaced by a "
              "unique integer identifier.");
DEFINE_double(min_scale_factor, 1.3,
              "The generated matrix should be scaleable by at least this much "
              "without becoming unfeasible.");
DEFINE_double(locality, 0.0,
              "How much of does locality factor into the traffic matrix.");
DEFINE_uint64(seed, 1ul, "Seed for the generated TM.");
DEFINE_uint64(tm_count, 1, "Number of TMs to generate.");
DEFINE_uint64(threads, 2, "Number of threads to use.");

// Generates a DemandMatrix using a scheme based on Roughan's '93 CCR paper. The
// method there is extended to support geographic locality.
class DemandGenerator {
 public:
  DemandGenerator(const nc::net::GraphStorage* graph)
      : sp_({}, graph->AdjacencyList(), nullptr, nullptr),
        graph_(graph),
        sum_inverse_delays_squared_(0) {
    for (nc::net::GraphNodeIndex src : graph_->AllNodes()) {
      for (nc::net::GraphNodeIndex dst : graph_->AllNodes()) {
        if (src == dst) {
          continue;
        }

        double distance = sp_.GetDistance(src, dst).count();
        sum_inverse_delays_squared_ += std::pow(1.0 / distance, 2);
      }
    }
  }

  // Produces a demand matrix. The matrix is not guaranteed to the satisfiable.
  std::unique_ptr<nc::lp::DemandMatrix> SinglePass(nc::net::Bandwidth mean,
                                                   std::mt19937* rnd) const {
    // Will start by getting the total incoming/outgoing traffic at each node.
    // These will come from an exponential distribution with the given mean.
    std::exponential_distribution<double> dist(1.0 / mean.Mbps());
    nc::net::GraphNodeMap<double> incoming_traffic_Mbps;
    nc::net::GraphNodeMap<double> outgoing_traffic_Mbps;
    double total_Mbps = 0;
    double sum_in = 0;
    double sum_out = 0;
    for (nc::net::GraphNodeIndex node : graph_->AllNodes()) {
      double in = dist(*rnd);
      double out = dist(*rnd);
      incoming_traffic_Mbps[node] = in;
      outgoing_traffic_Mbps[node] = out;
      total_Mbps += in + out;
      sum_in += in;
      sum_out += out;
    }
    double sum_product = sum_in * sum_out;

    // Time to compute the demand for each aggregate.
    double total_p = 0;
    std::vector<nc::lp::DemandMatrixElement> elements;
    for (nc::net::GraphNodeIndex src : graph_->AllNodes()) {
      for (nc::net::GraphNodeIndex dst : graph_->AllNodes()) {
        double gravity_p = incoming_traffic_Mbps.GetValueOrDie(src) *
                           outgoing_traffic_Mbps.GetValueOrDie(dst) /
                           sum_product;
        if (src == dst) {
          total_p += gravity_p;
          continue;
        }

        double value_Mbps = gravity_p * total_Mbps;
        total_p += gravity_p;
        auto bw = nc::net::Bandwidth::FromMBitsPerSecond(value_Mbps);
        if (bw > nc::net::Bandwidth::Zero()) {
          elements.push_back({src, dst, bw});
        }
      }
    }
    CHECK(std::abs(total_p - 1.0) < 0.0001) << "Not a distribution " << total_p;

    return nc::make_unique<nc::lp::DemandMatrix>(elements, graph_);
  }

  // Like above, but for a single source.
  static std::unique_ptr<nc::lp::DemandMatrix> LocalizeSource(
      nc::net::GraphNodeIndex src_node, const nc::lp::DemandMatrix& matrix,
      double locality) {
    // Need to first get the current distribution.
    std::vector<nc::lp::DemandMatrixElement> new_demands;
    nc::net::Bandwidth total_demand = nc::net::Bandwidth::Zero();
    nc::net::GraphNodeMap<nc::net::Bandwidth> demands;
    for (const auto& element : matrix.elements()) {
      if (element.src != src_node) {
        // All other demands are copied over to the output.
        new_demands.emplace_back(element);
        continue;
      }

      demands[element.dst] += element.demand;
      total_demand += element.demand;
    }

    if (total_demand == nc::net::Bandwidth::Zero()) {
      // No demand coming out of the source.
      return nc::make_unique<nc::lp::DemandMatrix>(new_demands, matrix.graph());
    }

    // Now figure out what the distribution entirely based on locality would be.
    const nc::net::GraphStorage* graph = matrix.graph();
    nc::net::GraphNodeSet to = graph->AllNodes();
    to.Remove(src_node);

    nc::net::ShortestPath sp_tree(src_node, to, {}, graph->AdjacencyList(),
                                  nullptr, nullptr);
    double sum_delays_inverse = 0;
    for (nc::net::GraphNodeIndex dst : to) {
      nc::net::Delay delay = sp_tree.GetPathDistance(dst);
      sum_delays_inverse += 1.0 / delay.count();
    }

    nc::net::GraphNodeMap<double> local_probabilities;
    for (nc::net::GraphNodeIndex dst : to) {
      nc::net::Delay delay = sp_tree.GetPathDistance(dst);
      local_probabilities[dst] = 1.0 / (delay.count() * sum_delays_inverse);
    }

    // Now to get the mixture distribution.
    double total_p = 0;
    for (nc::net::GraphNodeIndex dst : to) {
      double current_p = demands[dst] / total_demand;
      double local_p = local_probabilities.GetValueOrDie(dst);
      double new_p = current_p * (1 - locality) + locality * local_p;
      total_p += new_p;
      new_demands.emplace_back(src_node, dst, total_demand * new_p);
    }
    CHECK(std::abs(total_p - 1.0) < 0.0001) << "Not a distribution " << total_p;

    return nc::make_unique<nc::lp::DemandMatrix>(new_demands, graph);
  }

  // Makes a demand matrix more local. If locality is 0 demands are not changed
  // if locality is 1. All traffic coming out of a node will be distributed
  // inversely proportional to SP delay from node to other nodes.
  static std::unique_ptr<nc::lp::DemandMatrix> Localize(
      const nc::lp::DemandMatrix& matrix, double locality) {
    std::unique_ptr<nc::lp::DemandMatrix> out;
    for (const auto& element : matrix.elements()) {
      if (out) {
        out = LocalizeSource(element.src, *out, locality);
      } else {
        out = LocalizeSource(element.src, matrix, locality);
      }
    }

    return out;
  }

  // Returns a random matrix with the given commodity scale factor. Will
  // repeatedly call SinglePass to generate a series of matrices with the
  // highest mean rate that the commodity scale factor allows.
  std::unique_ptr<nc::lp::DemandMatrix> Generate(double commodity_scale_factor,
                                                 double locality,
                                                 std::mt19937* rnd) const {
    CHECK(commodity_scale_factor >= 1.0);
    CHECK(locality >= 0);
    CHECK(locality <= 1);

    auto demand_matrix =
        SinglePass(nc::net::Bandwidth::FromGBitsPerSecond(1), rnd);
    demand_matrix = Localize(*demand_matrix, locality);
    double csf = demand_matrix->MaxCommodityScaleFactor({}, 1.0);
    CHECK(csf != 0);
    CHECK(csf == csf);
    demand_matrix = demand_matrix->Scale(csf);
    demand_matrix = demand_matrix->Scale(1.0 / commodity_scale_factor);
    LOG(INFO) << "M " << csf;
    return demand_matrix;
  }

 private:
  // For the locality constraints will also need the delays of the N*(N-1)
  // shortest paths in the graph.
  nc::net::AllPairShortestPath sp_;

  // The graph.
  const nc::net::GraphStorage* graph_;

  // Sum of 1 / D_i where D_i is the delay of the shortest path of the i-th
  // IE-pair
  double sum_inverse_delays_squared_;

  DISALLOW_COPY_AND_ASSIGN(DemandGenerator);
};

using DemandMatrixVector = std::vector<std::unique_ptr<nc::lp::DemandMatrix>>;
using Input = std::pair<const ctr::TopologyAndFilename*, uint32_t>;

// Generates a single traffic matrix for a given graph.
void ProcessMatrix(const Input& input) {
  std::string topology_filename = input.first->file;
  topology_filename = nc::File::ExtractFileName(topology_filename);
  topology_filename = nc::Split(topology_filename, ".").front();

  const std::vector<std::string>& node_order = input.first->node_order;
  uint32_t id = input.second;

  DemandGenerator generator(input.first->graph.get());
  std::mt19937 gen(FLAGS_seed + id);
  auto demand_matrix =
      generator.Generate(FLAGS_min_scale_factor, FLAGS_locality, &gen);

  // Will ignore all aggregates less than 1Mbps.
  //  demand_matrix =
  //      demand_matrix->Filter([](const nc::lp::DemandMatrixElement& element) {
  //        return element.demand < nc::net::Bandwidth::FromMBitsPerSecond(1);
  //      });

  std::string output_location =
      nc::Substitute(FLAGS_output_pattern.c_str(), topology_filename,
                     FLAGS_locality, FLAGS_min_scale_factor, id);
  std::string directory = nc::File::ExtractDirectoryName(output_location);
  if (directory != "") {
    nc::File::RecursivelyCreateDir(directory, 0777);
  }

  LOG(INFO) << "Will write " << demand_matrix->ToString() << " to "
            << output_location;
  nc::File::WriteStringToFileOrDie(demand_matrix->ToRepetita(node_order),
                                   output_location);
}

int main(int argc, char** argv) {
  gflags::ParseCommandLineFlags(&argc, &argv, true);
  std::vector<ctr::TopologyAndFilename> topologies = ctr::GetTopologyInputs();

  std::vector<Input> inputs;
  uint32_t id = 0;
  for (const auto& topology : topologies) {
    for (size_t i = 0; i < FLAGS_tm_count; ++i) {
      inputs.emplace_back(&topology, id++);
    }
  }

  nc::RunInParallel<Input>(
      inputs, [](const Input& input) { ProcessMatrix(input); }, FLAGS_threads);
}
<commit_msg>updated tm_gen<commit_after>#include <gflags/gflags.h>
#include <stddef.h>
#include <chrono>
#include <cmath>
#include <cstdint>
#include <memory>
#include <random>
#include <string>
#include <utility>
#include <vector>

#include "ncode_common/src/common.h"
#include "ncode_common/src/file.h"
#include "ncode_common/src/logging.h"
#include "ncode_common/src/lp/demand_matrix.h"
#include "ncode_common/src/net/algorithm.h"
#include "ncode_common/src/net/net_common.h"
#include "ncode_common/src/perfect_hash.h"
#include "ncode_common/src/strutil.h"
#include "ncode_common/src/substitute.h"
#include "ncode_common/src/thread_runner.h"
#include "opt/opt.h"
#include "topology_input.h"

DEFINE_string(output_pattern,
              "demand_matrices/scale_factor_$2/locality_$1/$0_$3.demands",
              "Traffic matrices will be saved to files named after this "
              "pattern, with $0 replaced by the topology name, $1 replaced by "
              "locality, $2 replaced by scale factor and $3 replaced by a "
              "unique integer identifier.");
DEFINE_double(min_scale_factor, 1.3,
              "The generated matrix should be scaleable by at least this much "
              "without becoming unfeasible.");
DEFINE_double(locality, 0.0,
              "How much of does locality factor into the traffic matrix.");
DEFINE_uint64(seed, 1ul, "Seed for the generated TM.");
DEFINE_uint64(tm_count, 1, "Number of TMs to generate.");
DEFINE_uint64(threads, 2, "Number of threads to use.");

static void AddSumConstraints(
    const nc::net::GraphNodeMap<nc::net::Bandwidth>& demands,
    const nc::net::GraphNodeMap<std::vector<nc::lp::VariableIndex>>& vars,
    std::vector<nc::lp::ProblemMatrixElement>* problem_matrix,
    nc::lp::Problem* lp_problem) {
  for (const auto& node_and_demand : demands) {
    nc::net::GraphNodeIndex node = node_and_demand.first;
    double demand_Mbps = *node_and_demand.second->Mbps();

    nc::lp::ConstraintIndex constraint = lp_problem->AddConstraint();
    lp_problem->SetConstraintRange(constraint, demand_Mbps, demand_Mbps);
    for (nc::lp::VariableIndex var : vars.GetValueOrDie(node)) {
      problem_matrix->emplace_back(constraint, var, 1.0);
    }
  }
}

// Generates a demand distribution based on either incoming traffic or incoming
// traffic and outgoing traffic levels. The distribution will be as local as
// possible (will have cost per byte minimized).
std::unique_ptr<nc::lp::DemandMatrix> LPDemandGenerate(
    const nc::lp::DemandMatrix& seed_matrix, double fraction_allowance) {
  nc::net::GraphNodeMap<nc::net::Bandwidth> demand_out;
  nc::net::GraphNodeMap<nc::net::Bandwidth> demand_in;
  nc::net::GraphNodeMap<std::vector<nc::lp::VariableIndex>> vars_in;
  nc::net::GraphNodeMap<std::vector<nc::lp::VariableIndex>> vars_out;

  const nc::net::GraphStorage* graph = seed_matrix.graph();
  nc::net::AllPairShortestPath sp({}, graph->AdjacencyList(), nullptr, nullptr);

  nc::lp::Problem lp_problem(nc::lp::MINIMIZE);
  for (const auto& element : seed_matrix.elements()) {
    demand_out[element.src] += element.demand;
    demand_in[element.dst] += element.demand;

    nc::lp::VariableIndex var = lp_problem.AddVariable();
    vars_out[element.src].emplace_back(var);
    vars_in[element.dst].emplace_back(var);

    double element_demand = element.demand.Mbps();
    double min = element_demand * (1 - fraction_allowance);
    double max = element_demand * (1 + fraction_allowance);
    min = std::max(0.0, min);
    lp_problem.SetVariableRange(var, min, max);

    double obj_c = sp.GetDistance(element.src, element.dst).count();
    lp_problem.SetObjectiveCoefficient(var, obj_c * element_demand);
  }

  std::vector<nc::lp::ProblemMatrixElement> problem_matrix;
  AddSumConstraints(demand_in, vars_in, &problem_matrix, &lp_problem);
  AddSumConstraints(demand_out, vars_out, &problem_matrix, &lp_problem);
}

// Generates a DemandMatrix using a scheme based on Roughan's '93 CCR paper. The
// method there is extended to support geographic locality.
class DemandGenerator {
 public:
  DemandGenerator(const nc::net::GraphStorage* graph)
      : sp_({}, graph->AdjacencyList(), nullptr, nullptr),
        graph_(graph),
        sum_inverse_delays_squared_(0) {
    for (nc::net::GraphNodeIndex src : graph_->AllNodes()) {
      for (nc::net::GraphNodeIndex dst : graph_->AllNodes()) {
        if (src == dst) {
          continue;
        }

        double distance = sp_.GetDistance(src, dst).count();
        sum_inverse_delays_squared_ += std::pow(1.0 / distance, 2);
      }
    }
  }

  // Produces a demand matrix. The matrix is not guaranteed to the satisfiable.
  std::unique_ptr<nc::lp::DemandMatrix> SinglePass(nc::net::Bandwidth mean,
                                                   std::mt19937* rnd) const {
    // Will start by getting the total incoming/outgoing traffic at each node.
    // These will come from an exponential distribution with the given mean.
    std::exponential_distribution<double> dist(1.0 / mean.Mbps());
    nc::net::GraphNodeMap<double> incoming_traffic_Mbps;
    nc::net::GraphNodeMap<double> outgoing_traffic_Mbps;
    double total_Mbps = 0;
    double sum_in = 0;
    double sum_out = 0;
    for (nc::net::GraphNodeIndex node : graph_->AllNodes()) {
      double in = dist(*rnd);
      double out = dist(*rnd);
      incoming_traffic_Mbps[node] = in;
      outgoing_traffic_Mbps[node] = out;
      total_Mbps += in + out;
      sum_in += in;
      sum_out += out;
    }
    double sum_product = sum_in * sum_out;

    // Time to compute the demand for each aggregate.
    double total_p = 0;
    std::vector<nc::lp::DemandMatrixElement> elements;
    for (nc::net::GraphNodeIndex src : graph_->AllNodes()) {
      for (nc::net::GraphNodeIndex dst : graph_->AllNodes()) {
        double gravity_p = incoming_traffic_Mbps.GetValueOrDie(src) *
                           outgoing_traffic_Mbps.GetValueOrDie(dst) /
                           sum_product;
        if (src == dst) {
          total_p += gravity_p;
          continue;
        }

        double value_Mbps = gravity_p * total_Mbps;
        total_p += gravity_p;
        auto bw = nc::net::Bandwidth::FromMBitsPerSecond(value_Mbps);
        if (bw > nc::net::Bandwidth::Zero()) {
          elements.push_back({src, dst, bw});
        }
      }
    }
    CHECK(std::abs(total_p - 1.0) < 0.0001) << "Not a distribution " << total_p;

    return nc::make_unique<nc::lp::DemandMatrix>(elements, graph_);
  }

  // Like above, but for a single source.
  static std::unique_ptr<nc::lp::DemandMatrix> LocalizeSource(
      nc::net::GraphNodeIndex src_node, const nc::lp::DemandMatrix& matrix,
      double locality) {
    // Need to first get the current distribution.
    std::vector<nc::lp::DemandMatrixElement> new_demands;
    nc::net::Bandwidth total_demand = nc::net::Bandwidth::Zero();
    nc::net::GraphNodeMap<nc::net::Bandwidth> demands;
    for (const auto& element : matrix.elements()) {
      if (element.src != src_node) {
        // All other demands are copied over to the output.
        new_demands.emplace_back(element);
        continue;
      }

      demands[element.dst] += element.demand;
      total_demand += element.demand;
    }

    if (total_demand == nc::net::Bandwidth::Zero()) {
      // No demand coming out of the source.
      return nc::make_unique<nc::lp::DemandMatrix>(new_demands, matrix.graph());
    }

    // Now figure out what the distribution entirely based on locality would be.
    const nc::net::GraphStorage* graph = matrix.graph();
    nc::net::GraphNodeSet to = graph->AllNodes();
    to.Remove(src_node);

    nc::net::ShortestPath sp_tree(src_node, to, {}, graph->AdjacencyList(),
                                  nullptr, nullptr);
    double sum_delays_inverse = 0;
    for (nc::net::GraphNodeIndex dst : to) {
      nc::net::Delay delay = sp_tree.GetPathDistance(dst);
      sum_delays_inverse += 1.0 / delay.count();
    }

    nc::net::GraphNodeMap<double> local_probabilities;
    for (nc::net::GraphNodeIndex dst : to) {
      nc::net::Delay delay = sp_tree.GetPathDistance(dst);
      local_probabilities[dst] = 1.0 / (delay.count() * sum_delays_inverse);
    }

    // Now to get the mixture distribution.
    double total_p = 0;
    for (nc::net::GraphNodeIndex dst : to) {
      double current_p = demands[dst] / total_demand;
      double local_p = local_probabilities.GetValueOrDie(dst);
      double new_p = current_p * (1 - locality) + locality * local_p;
      total_p += new_p;
      new_demands.emplace_back(src_node, dst, total_demand * new_p);
    }
    CHECK(std::abs(total_p - 1.0) < 0.0001) << "Not a distribution " << total_p;

    return nc::make_unique<nc::lp::DemandMatrix>(new_demands, graph);
  }

  // Makes a demand matrix more local. If locality is 0 demands are not changed
  // if locality is 1. All traffic coming out of a node will be distributed
  // inversely proportional to SP delay from node to other nodes.
  static std::unique_ptr<nc::lp::DemandMatrix> Localize(
      const nc::lp::DemandMatrix& matrix, double locality) {
    std::unique_ptr<nc::lp::DemandMatrix> out;
    for (const auto& element : matrix.elements()) {
      if (out) {
        out = LocalizeSource(element.src, *out, locality);
      } else {
        out = LocalizeSource(element.src, matrix, locality);
      }
    }

    return out;
  }

  // Makes a demand matrix more local. Unlike Localize() this one preserves both
  // traffic going into a node and traffic leaving a node.
  static std::unique_ptr<nc::lp::DemandMatrix> LocalizeBoth(
      const nc::lp::DemandMatrix& matrix, double locality) {}

  // Returns a random matrix with the given commodity scale factor. Will
  // repeatedly call SinglePass to generate a series of matrices with the
  // highest mean rate that the commodity scale factor allows.
  std::unique_ptr<nc::lp::DemandMatrix> Generate(double commodity_scale_factor,
                                                 double locality,
                                                 std::mt19937* rnd) const {
    CHECK(commodity_scale_factor >= 1.0);
    CHECK(locality >= 0);
    CHECK(locality <= 1);

    auto demand_matrix =
        SinglePass(nc::net::Bandwidth::FromGBitsPerSecond(1), rnd);
    demand_matrix = Localize(*demand_matrix, locality);
    double csf = demand_matrix->MaxCommodityScaleFactor({}, 1.0);
    CHECK(csf != 0);
    CHECK(csf == csf);
    demand_matrix = demand_matrix->Scale(csf);
    demand_matrix = demand_matrix->Scale(1.0 / commodity_scale_factor);
    LOG(INFO) << "M " << csf;
    return demand_matrix;
  }

 private:
  // For the locality constraints will also need the delays of the N*(N-1)
  // shortest paths in the graph.
  nc::net::AllPairShortestPath sp_;

  // The graph.
  const nc::net::GraphStorage* graph_;

  // Sum of 1 / D_i where D_i is the delay of the shortest path of the i-th
  // IE-pair
  double sum_inverse_delays_squared_;

  DISALLOW_COPY_AND_ASSIGN(DemandGenerator);
};

using DemandMatrixVector = std::vector<std::unique_ptr<nc::lp::DemandMatrix>>;
using Input = std::pair<const ctr::TopologyAndFilename*, uint32_t>;

// Generates a single traffic matrix for a given graph.
void ProcessMatrix(const Input& input) {
  std::string topology_filename = input.first->file;
  topology_filename = nc::File::ExtractFileName(topology_filename);
  topology_filename = nc::Split(topology_filename, ".").front();

  const std::vector<std::string>& node_order = input.first->node_order;
  uint32_t id = input.second;

  DemandGenerator generator(input.first->graph.get());
  std::mt19937 gen(FLAGS_seed + id);
  auto demand_matrix =
      generator.Generate(FLAGS_min_scale_factor, FLAGS_locality, &gen);

  // Will ignore all aggregates less than 1Mbps.
  //  demand_matrix =
  //      demand_matrix->Filter([](const nc::lp::DemandMatrixElement& element) {
  //        return element.demand < nc::net::Bandwidth::FromMBitsPerSecond(1);
  //      });

  std::string output_location =
      nc::Substitute(FLAGS_output_pattern.c_str(), topology_filename,
                     FLAGS_locality, FLAGS_min_scale_factor, id);
  std::string directory = nc::File::ExtractDirectoryName(output_location);
  if (directory != "") {
    nc::File::RecursivelyCreateDir(directory, 0777);
  }

  LOG(INFO) << "Will write " << demand_matrix->ToString() << " to "
            << output_location;
  nc::File::WriteStringToFileOrDie(demand_matrix->ToRepetita(node_order),
                                   output_location);
}

int main(int argc, char** argv) {
  gflags::ParseCommandLineFlags(&argc, &argv, true);
  std::vector<ctr::TopologyAndFilename> topologies = ctr::GetTopologyInputs();

  std::vector<Input> inputs;
  uint32_t id = 0;
  for (const auto& topology : topologies) {
    for (size_t i = 0; i < FLAGS_tm_count; ++i) {
      inputs.emplace_back(&topology, id++);
    }
  }

  nc::RunInParallel<Input>(
      inputs, [](const Input& input) { ProcessMatrix(input); }, FLAGS_threads);
}
<|endoftext|>


<commit_before>/*
 * Copyright 2016-2017 gtalent2@gmail.com
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#include <iostream>
#include <QColor>
#include <QImage>
#include <QMap>
#include <core/gba/gba.hpp>
#include <common/point.hpp>
#include <ox/clargs/clargs.hpp>
#include <ox/fs/filesystem.hpp>

using namespace std;
using namespace ox;
using namespace ox::clargs;
using namespace ox::fs;
using namespace nostalgia::core;
using namespace nostalgia::common;

uint8_t *loadFileBuff(QString path, ::size_t *sizeOut = nullptr) {
	auto file = fopen(path.toUtf8(), "rb");
	if (file) {
		fseek(file, 0, SEEK_END);
		const auto size = ftell(file);
		rewind(file);
		auto buff = new uint8_t[size];
		auto itemsRead = fread(buff, size, 1, file);
		fclose(file);
		if (sizeOut) {
			*sizeOut = itemsRead ? size : 0;
		}
		return buff;
	} else {
		return nullptr;
	}
}

uint16_t toGbaColor(QColor c) {
	auto r = ((uint32_t) c.red()) >> 3;
	auto g = ((uint32_t) c.green()) >> 3;
	auto b = ((uint32_t) c.blue()) >> 3;
	return (r << 10) | (g << 5) | (b << 0);
}

int pointToIdx(int w, int x, int y) {
	const auto colLength = 64;
	const auto rowLength = (w / 8) * colLength;
	const auto colStart = colLength * (x / 8);
	const auto rowStart = rowLength * (y / 8);
	const auto colOffset = x % 8;
	const auto rowOffset = (y % 8) * 8;
	return colStart + colOffset + rowStart + rowOffset;
}

int run(ClArgs args) {
	Error err = 0;
	QString argInPath = args.getString("img").c_str();
	QString argFsPath = args.getString("fs").c_str();
	auto argCompact = args.getBool("c");

	QImage src(argInPath);

	if (!src.isNull()) {
		QMap<QRgb, int> colors;
		const auto imgDataBuffSize = sizeof(Pallete) - 1 + src.width() * src.height();
		uint8_t imgDataBuff[imgDataBuffSize];
		GbaImageData *id = (GbaImageData*) imgDataBuff;
		int colorId = 0;

		// copy pixels as color ids
		for (int x = 0; x < src.colorCount(); x++) {
			for (int y = 0; y < src.colorCount(); y++) {
				auto destI = pointToIdx(src.width(), x, y);
				auto c = src.pixel(x, y);
				if (!colors.contains(c)) {
					colors[c] = colorId;
					colorId++;
				}
				((uint8_t*) &id->tiles)[destI] = colors[c];
			}
		}

		// store colors in palette with the corresponding color id
		for (auto key : colors.keys()) {
			auto colorId = colors[key];
			id->pal[colorId] = toGbaColor(key);
		}

		size_t fsBuffSize;
		auto fsBuff = loadFileBuff(argFsPath, &fsBuffSize);
		if (fsBuff && !err) {
			auto fs = createFileSystem(fsBuff, fsBuffSize);

			if (fs) {
				fs = expandCopyCleanup(fs, fs->size() + fs->spaceNeeded(imgDataBuffSize));
				fsBuff = fs->buff(); // update fsBuff pointer in case there is a new buff
				err |= fs->write(1, imgDataBuff, imgDataBuffSize);

				if (argCompact) {
					fs->resize();
				}

				auto fsFile = fopen(argFsPath.toUtf8(), "wb");
				if (fsFile) {
					err = fwrite(fsBuff, fs->size(), 1, fsFile) != 1;
					err |= fclose(fsFile);
					if (err) {
						cerr << "Could not write to file system file.\n";
					}
				} else {
					err = 2;
				}

				delete fs;
			} else {
				err = 3;
			}
		}

		delete[] fsBuff;
	} else {
		err = 4;
	}

	return err;
}

int main(int argc, const char **args) {
	return run(ClArgs(argc, args));
}
<commit_msg>Adjust nost-pack image data buffer size<commit_after>/*
 * Copyright 2016-2017 gtalent2@gmail.com
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#include <iostream>
#include <QColor>
#include <QImage>
#include <QMap>
#include <core/gba/gba.hpp>
#include <common/point.hpp>
#include <ox/clargs/clargs.hpp>
#include <ox/fs/filesystem.hpp>

using namespace std;
using namespace ox;
using namespace ox::clargs;
using namespace ox::fs;
using namespace nostalgia::core;
using namespace nostalgia::common;

uint8_t *loadFileBuff(QString path, ::size_t *sizeOut = nullptr) {
	auto file = fopen(path.toUtf8(), "rb");
	if (file) {
		fseek(file, 0, SEEK_END);
		const auto size = ftell(file);
		rewind(file);
		auto buff = new uint8_t[size];
		auto itemsRead = fread(buff, size, 1, file);
		fclose(file);
		if (sizeOut) {
			*sizeOut = itemsRead ? size : 0;
		}
		return buff;
	} else {
		return nullptr;
	}
}

uint16_t toGbaColor(QColor c) {
	auto r = ((uint32_t) c.red()) >> 3;
	auto g = ((uint32_t) c.green()) >> 3;
	auto b = ((uint32_t) c.blue()) >> 3;
	return (r << 10) | (g << 5) | (b << 0);
}

int pointToIdx(int w, int x, int y) {
	const auto colLength = 64;
	const auto rowLength = (w / 8) * colLength;
	const auto colStart = colLength * (x / 8);
	const auto rowStart = rowLength * (y / 8);
	const auto colOffset = x % 8;
	const auto rowOffset = (y % 8) * 8;
	return colStart + colOffset + rowStart + rowOffset;
}

int run(ClArgs args) {
	Error err = 0;
	QString argInPath = args.getString("img").c_str();
	QString argFsPath = args.getString("fs").c_str();
	auto argCompact = args.getBool("c");

	QImage src(argInPath);

	if (!src.isNull()) {
		QMap<QRgb, int> colors;
		const auto imgDataBuffSize = sizeof(Pallete) + src.width() * src.height();
		uint8_t imgDataBuff[imgDataBuffSize];
		GbaImageData *id = (GbaImageData*) imgDataBuff;
		int colorId = 0;

		// copy pixels as color ids
		for (int x = 0; x < src.colorCount(); x++) {
			for (int y = 0; y < src.colorCount(); y++) {
				auto destI = pointToIdx(src.width(), x, y);
				auto c = src.pixel(x, y);
				if (!colors.contains(c)) {
					colors[c] = colorId;
					colorId++;
				}
				((uint8_t*) &id->tiles)[destI] = colors[c];
			}
		}

		// store colors in palette with the corresponding color id
		for (auto key : colors.keys()) {
			auto colorId = colors[key];
			id->pal[colorId] = toGbaColor(key);
		}

		size_t fsBuffSize;
		auto fsBuff = loadFileBuff(argFsPath, &fsBuffSize);
		if (fsBuff && !err) {
			auto fs = createFileSystem(fsBuff, fsBuffSize);

			if (fs) {
				fs = expandCopyCleanup(fs, fs->size() + fs->spaceNeeded(imgDataBuffSize));
				fsBuff = fs->buff(); // update fsBuff pointer in case there is a new buff
				err |= fs->write(1, imgDataBuff, imgDataBuffSize);

				if (argCompact) {
					fs->resize();
				}

				auto fsFile = fopen(argFsPath.toUtf8(), "wb");
				if (fsFile) {
					err = fwrite(fsBuff, fs->size(), 1, fsFile) != 1;
					err |= fclose(fsFile);
					if (err) {
						cerr << "Could not write to file system file.\n";
					}
				} else {
					err = 2;
				}

				delete fs;
			} else {
				err = 3;
			}
		}

		delete[] fsBuff;
	} else {
		err = 4;
	}

	return err;
}

int main(int argc, const char **args) {
	return run(ClArgs(argc, args));
}
<|endoftext|>


<commit_before>#include "thp/provider.hpp"

using namespace std;

static ProviderInfo info = {
    "WPILib (2016)",
    false, true
};

static void (*_state_callback_periodic)(bool,bool,bool,bool);
static void (*_state_callback_transition)(bool,bool,bool,bool);

static Logger _provider_logger("THP - WPILib (2016)");
static THP_Base_Robot *robot;

ProviderInfo *provider_info() {
    return &info;
}

void provider_preinit() { }
void provider_init() {
    if (!HALInitialize()) {
        _provider_logger.fatal("HAL could not be initialized");
        throw new std::exception("HAL could not be initialized");
    }
    HALReport(HALUsageReporting::kResourceType_Language,
              HALUsageReporting::kLanguage_CPlusPlus);

    robot = new THP_Base_Robot();
    RobotBase::robotSetup(robot);
}

void provider_free() {
    free(robot);
}

void thp_state_set_callback(void (*callback_periodic)(bool,bool,bool,bool), void (*callback_transition)(bool,bool,bool,bool)) {
    _state_callback_periodic = callback_periodic;
    _state_callback_transition = callback_transition;
}

void thp_state_call_periodic(bool disabled, bool auton, bool teleop, bool test) {
    _state_callback_periodic(disabled, auton, teleop, test);
}

void thp_state_call_init(bool disabled, bool auton, bool teleop, bool test) {
    _state_callback_transition(disabled, auton, teleop, test);
}<commit_msg>Fix WPI Cross Compile<commit_after>#include "thp/provider.hpp"
#include "thp/wpi/base_robot.hpp"

#include "WPILib.h"

#include "toast/logger.hpp"

using namespace std;
using namespace Toast;

static ProviderInfo info = {
    "WPILib (2016)",
    false, true
};

static void (*_state_callback_periodic)(bool,bool,bool,bool);
static void (*_state_callback_transition)(bool,bool,bool,bool);

static Logger _provider_logger("THP - WPILib (2016)");
static THP_Base_Robot *robot;

ProviderInfo *provider_info() {
    return &info;
}

void provider_preinit() { }
void provider_init() {
    if (!HALInitialize()) {
        _provider_logger.severe("HAL could not be initialized");
        throw "HAL could not be initialized";
    }
    HALReport(HALUsageReporting::kResourceType_Language,
              HALUsageReporting::kLanguage_CPlusPlus);

    robot = new THP_Base_Robot();
    RobotBase::robotSetup(robot);
}

void provider_free() {
    free(robot);
}

void thp_state_set_callback(void (*callback_periodic)(bool,bool,bool,bool), void (*callback_transition)(bool,bool,bool,bool)) {
    _state_callback_periodic = callback_periodic;
    _state_callback_transition = callback_transition;
}

void thp_state_call_periodic(bool disabled, bool auton, bool teleop, bool test) {
    _state_callback_periodic(disabled, auton, teleop, test);
}

void thp_state_call_init(bool disabled, bool auton, bool teleop, bool test) {
    _state_callback_transition(disabled, auton, teleop, test);
}<|endoftext|>


<commit_before>#include <nan.h>
#include <vector>
#include "sass_context_wrapper.h"
#include "custom_function_bridge.h"
#include "create_string.h"
#include "sass_types/factory.h"

Sass_Import_List sass_importer(const char* cur_path, Sass_Importer_Entry cb, struct Sass_Compiler* comp)
{
  void* cookie = sass_importer_get_cookie(cb);
  struct Sass_Import* previous = sass_compiler_get_last_import(comp);
  const char* prev_path = sass_import_get_path(previous);
  sass_context_wrapper* ctx_w = static_cast<sass_context_wrapper*>(cookie);
  CustomImporterBridge& bridge = *(static_cast<CustomImporterBridge*>(cookie));

  std::vector<void*> argv;
  argv.push_back((void*)cur_path);
  argv.push_back((void*)prev_path);

  return bridge(argv);
}

union Sass_Value* sass_custom_function(const union Sass_Value* s_args, Sass_Function_Entry cb, struct Sass_Options* opts)
{
  void* cookie = sass_function_get_cookie(cb);
  CustomFunctionBridge& bridge = *(static_cast<CustomFunctionBridge*>(cookie));

  std::vector<void*> argv;
  for (unsigned l = sass_list_get_length(s_args), i = 0; i < l; i++) {
    argv.push_back((void*)sass_list_get_value(s_args, i));
  }

  try {
    return bridge(argv);
  }
  catch (const std::exception& e) {
    return sass_make_error(e.what());
  }
}

void ExtractOptions(Local<Object> options, void* cptr, sass_context_wrapper* ctx_w, bool is_file, bool is_sync) {
  NanScope();

  struct Sass_Context* ctx;

  NanAssignPersistent(ctx_w->result, options->Get(NanNew("result"))->ToObject());

  if (is_file) {
    ctx_w->fctx = (struct Sass_File_Context*) cptr;
    ctx = sass_file_context_get_context(ctx_w->fctx);
  }
  else {
    ctx_w->dctx = (struct Sass_Data_Context*) cptr;
    ctx = sass_data_context_get_context(ctx_w->dctx);
  }

  struct Sass_Options* sass_options = sass_context_get_options(ctx);

  ctx_w->is_sync = is_sync;

  if (!is_sync) {
    ctx_w->request.data = ctx_w;

    // async (callback) style
    Local<Function> success_callback = Local<Function>::Cast(options->Get(NanNew("success")));
    Local<Function> error_callback = Local<Function>::Cast(options->Get(NanNew("error")));

    ctx_w->success_callback = new NanCallback(success_callback);
    ctx_w->error_callback = new NanCallback(error_callback);
  }

  if (!is_file) {
    ctx_w->file = create_string(options->Get(NanNew("file")));
    sass_option_set_input_path(sass_options, ctx_w->file);
  }

  int indent_len = options->Get(NanNew("indentWidth"))->Int32Value();

  ctx_w->indent = (char*)malloc(indent_len + 1);

  strcpy(ctx_w->indent, std::string(
    indent_len,
    options->Get(NanNew("indentType"))->Int32Value() == 1 ? '\t' : ' '
    ).c_str());

  ctx_w->linefeed = create_string(options->Get(NanNew("linefeed")));
  ctx_w->include_path = create_string(options->Get(NanNew("includePaths")));
  ctx_w->out_file = create_string(options->Get(NanNew("outFile")));
  ctx_w->source_map = create_string(options->Get(NanNew("sourceMap")));
  ctx_w->source_map_root = create_string(options->Get(NanNew("sourceMapRoot")));

  sass_option_set_output_path(sass_options, ctx_w->out_file);
  sass_option_set_output_style(sass_options, (Sass_Output_Style)options->Get(NanNew("style"))->Int32Value());
  sass_option_set_is_indented_syntax_src(sass_options, options->Get(NanNew("indentedSyntax"))->BooleanValue());
  sass_option_set_source_comments(sass_options, options->Get(NanNew("sourceComments"))->BooleanValue());
  sass_option_set_omit_source_map_url(sass_options, options->Get(NanNew("omitSourceMapUrl"))->BooleanValue());
  sass_option_set_source_map_embed(sass_options, options->Get(NanNew("sourceMapEmbed"))->BooleanValue());
  sass_option_set_source_map_contents(sass_options, options->Get(NanNew("sourceMapContents"))->BooleanValue());
  sass_option_set_source_map_file(sass_options, ctx_w->source_map);
  sass_option_set_source_map_root(sass_options, ctx_w->source_map_root);
  sass_option_set_include_path(sass_options, ctx_w->include_path);
  sass_option_set_precision(sass_options, options->Get(NanNew("precision"))->Int32Value());
  sass_option_set_indent(sass_options, ctx_w->indent);
  sass_option_set_linefeed(sass_options, ctx_w->linefeed);

  Local<Value> importer_callback = options->Get(NanNew("importer"));

  if (importer_callback->IsFunction()) {
    Local<Function> importer = Local<Function>::Cast(importer_callback);
    auto bridge = std::make_shared<CustomImporterBridge>(new NanCallback(importer), ctx_w->is_sync);
    ctx_w->importer_bridges.push_back(bridge);

    Sass_Importer_List c_importers = sass_make_importer_list(1);
    c_importers[0] = sass_make_importer(sass_importer, 0, bridge.get());

    sass_option_set_c_importers(sass_options, c_importers);
  }
  else if (importer_callback->IsArray()) {
    Handle<Array> importers = Handle<Array>::Cast(importer_callback);
    Sass_Importer_List c_importers = sass_make_importer_list(importers->Length());

    for (size_t i = 0; i < importers->Length(); ++i) {
      Local<Function> callback = Local<Function>::Cast(importers->Get(static_cast<uint32_t>(i)));

      auto bridge = std::make_shared<CustomImporterBridge>(new NanCallback(callback), ctx_w->is_sync);
      ctx_w->importer_bridges.push_back(bridge);

      c_importers[i] = sass_make_importer(sass_importer, importers->Length() - i - 1, bridge.get());
    }

    sass_option_set_c_importers(sass_options, c_importers);
  }

  Local<Value> custom_functions = options->Get(NanNew("functions"));

  if (custom_functions->IsObject()) {
    Local<Object> functions = Local<Object>::Cast(custom_functions);
    Local<Array> signatures = functions->GetOwnPropertyNames();
    unsigned num_signatures = signatures->Length();
    Sass_Function_List fn_list = sass_make_function_list(num_signatures);

    for (unsigned i = 0; i < num_signatures; i++) {
      Local<String> signature = Local<String>::Cast(signatures->Get(NanNew(i)));
      Local<Function> callback = Local<Function>::Cast(functions->Get(signature));

      auto bridge = std::make_shared<CustomFunctionBridge>(new NanCallback(callback), ctx_w->is_sync);
      ctx_w->function_bridges.push_back(bridge);

      Sass_Function_Entry fn = sass_make_function(create_string(signature), sass_custom_function, bridge.get());
      sass_function_set_list_entry(fn_list, i, fn);
    }

    sass_option_set_c_functions(sass_options, fn_list);
  }
}

void GetStats(sass_context_wrapper* ctx_w, Sass_Context* ctx) {
  NanScope();

  char** included_files = sass_context_get_included_files(ctx);
  Handle<Array> arr = NanNew<Array>();

  if (included_files) {
    for (int i = 0; included_files[i] != nullptr; ++i) {
      arr->Set(i, NanNew<String>(included_files[i]));
    }
  }

  NanNew(ctx_w->result)->Get(NanNew("stats"))->ToObject()->Set(NanNew("includedFiles"), arr);
}

int GetResult(sass_context_wrapper* ctx_w, Sass_Context* ctx, bool is_sync = false) {
  NanScope();

  int status = sass_context_get_error_status(ctx);

  if (status == 0) {
    const char* css = sass_context_get_output_string(ctx);
    const char* map = sass_context_get_source_map_string(ctx);

    NanNew(ctx_w->result)->Set(NanNew("css"), NanNewBufferHandle(css, static_cast<uint32_t>(strlen(css))));

    GetStats(ctx_w, ctx);

    if (map) {
      NanNew(ctx_w->result)->Set(NanNew("map"), NanNewBufferHandle(map, static_cast<uint32_t>(strlen(map))));
    }
  }
  else if (is_sync) {
    NanNew(ctx_w->result)->Set(NanNew("error"), NanNew<String>(sass_context_get_error_json(ctx)));
  }

  return status;
}

void MakeCallback(uv_work_t* req) {
  NanScope();

  TryCatch try_catch;
  sass_context_wrapper* ctx_w = static_cast<sass_context_wrapper*>(req->data);
  struct Sass_Context* ctx;

  if (ctx_w->dctx) {
    ctx = sass_data_context_get_context(ctx_w->dctx);
  }
  else {
    ctx = sass_file_context_get_context(ctx_w->fctx);
  }

  int status = GetResult(ctx_w, ctx);

  if (status == 0 && ctx_w->success_callback) {
    // if no error, do callback(null, result)
    ctx_w->success_callback->Call(0, 0);
  }
  else if (ctx_w->error_callback) {
    // if error, do callback(error)
    const char* err = sass_context_get_error_json(ctx);
    Local<Value> argv[] = {
      NanNew<String>(err)
    };
    ctx_w->error_callback->Call(1, argv);
  }
  if (try_catch.HasCaught()) {
    node::FatalException(try_catch);
  }

  sass_free_context_wrapper(ctx_w);
}

NAN_METHOD(render) {
  NanScope();

  Local<Object> options = args[0]->ToObject();
  char* source_string = create_string(options->Get(NanNew("data")));
  struct Sass_Data_Context* dctx = sass_make_data_context(source_string);
  sass_context_wrapper* ctx_w = sass_make_context_wrapper();

  ExtractOptions(options, dctx, ctx_w, false, false);

  int status = uv_queue_work(uv_default_loop(), &ctx_w->request, compile_it, (uv_after_work_cb)MakeCallback);

  assert(status == 0);

  NanReturnUndefined();
}

NAN_METHOD(render_sync) {
  NanScope();

  Local<Object> options = args[0]->ToObject();
  char* source_string = create_string(options->Get(NanNew("data")));
  struct Sass_Data_Context* dctx = sass_make_data_context(source_string);
  struct Sass_Context* ctx = sass_data_context_get_context(dctx);
  sass_context_wrapper* ctx_w = sass_make_context_wrapper();

  ExtractOptions(options, dctx, ctx_w, false, true);

  compile_data(dctx);

  int result = GetResult(ctx_w, ctx, true);

  sass_free_context_wrapper(ctx_w);

  NanReturnValue(NanNew<Boolean>(result == 0));
}

NAN_METHOD(render_file) {
  NanScope();

  Local<Object> options = args[0]->ToObject();
  char* input_path = create_string(options->Get(NanNew("file")));
  struct Sass_File_Context* fctx = sass_make_file_context(input_path);
  sass_context_wrapper* ctx_w = sass_make_context_wrapper();

  ExtractOptions(options, fctx, ctx_w, true, false);

  int status = uv_queue_work(uv_default_loop(), &ctx_w->request, compile_it, (uv_after_work_cb)MakeCallback);

  assert(status == 0);

  NanReturnUndefined();
}

NAN_METHOD(render_file_sync) {
  NanScope();

  Local<Object> options = args[0]->ToObject();
  char* input_path = create_string(options->Get(NanNew("file")));
  struct Sass_File_Context* fctx = sass_make_file_context(input_path);
  struct Sass_Context* ctx = sass_file_context_get_context(fctx);
  sass_context_wrapper* ctx_w = sass_make_context_wrapper();

  ExtractOptions(options, fctx, ctx_w, true, true);
  compile_file(fctx);

  int result = GetResult(ctx_w, ctx, true);

  free(input_path);
  sass_free_context_wrapper(ctx_w);

  NanReturnValue(NanNew<Boolean>(result == 0));
}

NAN_METHOD(libsass_version) {
  NanScope();
  NanReturnValue(NanNew<String>(libsass_version()));
}

void RegisterModule(v8::Handle<v8::Object> target) {
  NODE_SET_METHOD(target, "render", render);
  NODE_SET_METHOD(target, "renderSync", render_sync);
  NODE_SET_METHOD(target, "renderFile", render_file);
  NODE_SET_METHOD(target, "renderFileSync", render_file_sync);
  NODE_SET_METHOD(target, "libsassVersion", libsass_version);
  SassTypes::Factory::initExports(target);
}

NODE_MODULE(binding, RegisterModule);
<commit_msg>Remove unused ctx_w<commit_after>#include <nan.h>
#include <vector>
#include "sass_context_wrapper.h"
#include "custom_function_bridge.h"
#include "create_string.h"
#include "sass_types/factory.h"

Sass_Import_List sass_importer(const char* cur_path, Sass_Importer_Entry cb, struct Sass_Compiler* comp)
{
  void* cookie = sass_importer_get_cookie(cb);
  struct Sass_Import* previous = sass_compiler_get_last_import(comp);
  const char* prev_path = sass_import_get_path(previous);
  CustomImporterBridge& bridge = *(static_cast<CustomImporterBridge*>(cookie));

  std::vector<void*> argv;
  argv.push_back((void*)cur_path);
  argv.push_back((void*)prev_path);

  return bridge(argv);
}

union Sass_Value* sass_custom_function(const union Sass_Value* s_args, Sass_Function_Entry cb, struct Sass_Options* opts)
{
  void* cookie = sass_function_get_cookie(cb);
  CustomFunctionBridge& bridge = *(static_cast<CustomFunctionBridge*>(cookie));

  std::vector<void*> argv;
  for (unsigned l = sass_list_get_length(s_args), i = 0; i < l; i++) {
    argv.push_back((void*)sass_list_get_value(s_args, i));
  }

  try {
    return bridge(argv);
  }
  catch (const std::exception& e) {
    return sass_make_error(e.what());
  }
}

void ExtractOptions(Local<Object> options, void* cptr, sass_context_wrapper* ctx_w, bool is_file, bool is_sync) {
  NanScope();

  struct Sass_Context* ctx;

  NanAssignPersistent(ctx_w->result, options->Get(NanNew("result"))->ToObject());

  if (is_file) {
    ctx_w->fctx = (struct Sass_File_Context*) cptr;
    ctx = sass_file_context_get_context(ctx_w->fctx);
  }
  else {
    ctx_w->dctx = (struct Sass_Data_Context*) cptr;
    ctx = sass_data_context_get_context(ctx_w->dctx);
  }

  struct Sass_Options* sass_options = sass_context_get_options(ctx);

  ctx_w->is_sync = is_sync;

  if (!is_sync) {
    ctx_w->request.data = ctx_w;

    // async (callback) style
    Local<Function> success_callback = Local<Function>::Cast(options->Get(NanNew("success")));
    Local<Function> error_callback = Local<Function>::Cast(options->Get(NanNew("error")));

    ctx_w->success_callback = new NanCallback(success_callback);
    ctx_w->error_callback = new NanCallback(error_callback);
  }

  if (!is_file) {
    ctx_w->file = create_string(options->Get(NanNew("file")));
    sass_option_set_input_path(sass_options, ctx_w->file);
  }

  int indent_len = options->Get(NanNew("indentWidth"))->Int32Value();

  ctx_w->indent = (char*)malloc(indent_len + 1);

  strcpy(ctx_w->indent, std::string(
    indent_len,
    options->Get(NanNew("indentType"))->Int32Value() == 1 ? '\t' : ' '
    ).c_str());

  ctx_w->linefeed = create_string(options->Get(NanNew("linefeed")));
  ctx_w->include_path = create_string(options->Get(NanNew("includePaths")));
  ctx_w->out_file = create_string(options->Get(NanNew("outFile")));
  ctx_w->source_map = create_string(options->Get(NanNew("sourceMap")));
  ctx_w->source_map_root = create_string(options->Get(NanNew("sourceMapRoot")));

  sass_option_set_output_path(sass_options, ctx_w->out_file);
  sass_option_set_output_style(sass_options, (Sass_Output_Style)options->Get(NanNew("style"))->Int32Value());
  sass_option_set_is_indented_syntax_src(sass_options, options->Get(NanNew("indentedSyntax"))->BooleanValue());
  sass_option_set_source_comments(sass_options, options->Get(NanNew("sourceComments"))->BooleanValue());
  sass_option_set_omit_source_map_url(sass_options, options->Get(NanNew("omitSourceMapUrl"))->BooleanValue());
  sass_option_set_source_map_embed(sass_options, options->Get(NanNew("sourceMapEmbed"))->BooleanValue());
  sass_option_set_source_map_contents(sass_options, options->Get(NanNew("sourceMapContents"))->BooleanValue());
  sass_option_set_source_map_file(sass_options, ctx_w->source_map);
  sass_option_set_source_map_root(sass_options, ctx_w->source_map_root);
  sass_option_set_include_path(sass_options, ctx_w->include_path);
  sass_option_set_precision(sass_options, options->Get(NanNew("precision"))->Int32Value());
  sass_option_set_indent(sass_options, ctx_w->indent);
  sass_option_set_linefeed(sass_options, ctx_w->linefeed);

  Local<Value> importer_callback = options->Get(NanNew("importer"));

  if (importer_callback->IsFunction()) {
    Local<Function> importer = Local<Function>::Cast(importer_callback);
    auto bridge = std::make_shared<CustomImporterBridge>(new NanCallback(importer), ctx_w->is_sync);
    ctx_w->importer_bridges.push_back(bridge);

    Sass_Importer_List c_importers = sass_make_importer_list(1);
    c_importers[0] = sass_make_importer(sass_importer, 0, bridge.get());

    sass_option_set_c_importers(sass_options, c_importers);
  }
  else if (importer_callback->IsArray()) {
    Handle<Array> importers = Handle<Array>::Cast(importer_callback);
    Sass_Importer_List c_importers = sass_make_importer_list(importers->Length());

    for (size_t i = 0; i < importers->Length(); ++i) {
      Local<Function> callback = Local<Function>::Cast(importers->Get(static_cast<uint32_t>(i)));

      auto bridge = std::make_shared<CustomImporterBridge>(new NanCallback(callback), ctx_w->is_sync);
      ctx_w->importer_bridges.push_back(bridge);

      c_importers[i] = sass_make_importer(sass_importer, importers->Length() - i - 1, bridge.get());
    }

    sass_option_set_c_importers(sass_options, c_importers);
  }

  Local<Value> custom_functions = options->Get(NanNew("functions"));

  if (custom_functions->IsObject()) {
    Local<Object> functions = Local<Object>::Cast(custom_functions);
    Local<Array> signatures = functions->GetOwnPropertyNames();
    unsigned num_signatures = signatures->Length();
    Sass_Function_List fn_list = sass_make_function_list(num_signatures);

    for (unsigned i = 0; i < num_signatures; i++) {
      Local<String> signature = Local<String>::Cast(signatures->Get(NanNew(i)));
      Local<Function> callback = Local<Function>::Cast(functions->Get(signature));

      auto bridge = std::make_shared<CustomFunctionBridge>(new NanCallback(callback), ctx_w->is_sync);
      ctx_w->function_bridges.push_back(bridge);

      Sass_Function_Entry fn = sass_make_function(create_string(signature), sass_custom_function, bridge.get());
      sass_function_set_list_entry(fn_list, i, fn);
    }

    sass_option_set_c_functions(sass_options, fn_list);
  }
}

void GetStats(sass_context_wrapper* ctx_w, Sass_Context* ctx) {
  NanScope();

  char** included_files = sass_context_get_included_files(ctx);
  Handle<Array> arr = NanNew<Array>();

  if (included_files) {
    for (int i = 0; included_files[i] != nullptr; ++i) {
      arr->Set(i, NanNew<String>(included_files[i]));
    }
  }

  NanNew(ctx_w->result)->Get(NanNew("stats"))->ToObject()->Set(NanNew("includedFiles"), arr);
}

int GetResult(sass_context_wrapper* ctx_w, Sass_Context* ctx, bool is_sync = false) {
  NanScope();

  int status = sass_context_get_error_status(ctx);

  if (status == 0) {
    const char* css = sass_context_get_output_string(ctx);
    const char* map = sass_context_get_source_map_string(ctx);

    NanNew(ctx_w->result)->Set(NanNew("css"), NanNewBufferHandle(css, static_cast<uint32_t>(strlen(css))));

    GetStats(ctx_w, ctx);

    if (map) {
      NanNew(ctx_w->result)->Set(NanNew("map"), NanNewBufferHandle(map, static_cast<uint32_t>(strlen(map))));
    }
  }
  else if (is_sync) {
    NanNew(ctx_w->result)->Set(NanNew("error"), NanNew<String>(sass_context_get_error_json(ctx)));
  }

  return status;
}

void MakeCallback(uv_work_t* req) {
  NanScope();

  TryCatch try_catch;
  sass_context_wrapper* ctx_w = static_cast<sass_context_wrapper*>(req->data);
  struct Sass_Context* ctx;

  if (ctx_w->dctx) {
    ctx = sass_data_context_get_context(ctx_w->dctx);
  }
  else {
    ctx = sass_file_context_get_context(ctx_w->fctx);
  }

  int status = GetResult(ctx_w, ctx);

  if (status == 0 && ctx_w->success_callback) {
    // if no error, do callback(null, result)
    ctx_w->success_callback->Call(0, 0);
  }
  else if (ctx_w->error_callback) {
    // if error, do callback(error)
    const char* err = sass_context_get_error_json(ctx);
    Local<Value> argv[] = {
      NanNew<String>(err)
    };
    ctx_w->error_callback->Call(1, argv);
  }
  if (try_catch.HasCaught()) {
    node::FatalException(try_catch);
  }

  sass_free_context_wrapper(ctx_w);
}

NAN_METHOD(render) {
  NanScope();

  Local<Object> options = args[0]->ToObject();
  char* source_string = create_string(options->Get(NanNew("data")));
  struct Sass_Data_Context* dctx = sass_make_data_context(source_string);
  sass_context_wrapper* ctx_w = sass_make_context_wrapper();

  ExtractOptions(options, dctx, ctx_w, false, false);

  int status = uv_queue_work(uv_default_loop(), &ctx_w->request, compile_it, (uv_after_work_cb)MakeCallback);

  assert(status == 0);

  NanReturnUndefined();
}

NAN_METHOD(render_sync) {
  NanScope();

  Local<Object> options = args[0]->ToObject();
  char* source_string = create_string(options->Get(NanNew("data")));
  struct Sass_Data_Context* dctx = sass_make_data_context(source_string);
  struct Sass_Context* ctx = sass_data_context_get_context(dctx);
  sass_context_wrapper* ctx_w = sass_make_context_wrapper();

  ExtractOptions(options, dctx, ctx_w, false, true);

  compile_data(dctx);

  int result = GetResult(ctx_w, ctx, true);

  sass_free_context_wrapper(ctx_w);

  NanReturnValue(NanNew<Boolean>(result == 0));
}

NAN_METHOD(render_file) {
  NanScope();

  Local<Object> options = args[0]->ToObject();
  char* input_path = create_string(options->Get(NanNew("file")));
  struct Sass_File_Context* fctx = sass_make_file_context(input_path);
  sass_context_wrapper* ctx_w = sass_make_context_wrapper();

  ExtractOptions(options, fctx, ctx_w, true, false);

  int status = uv_queue_work(uv_default_loop(), &ctx_w->request, compile_it, (uv_after_work_cb)MakeCallback);

  assert(status == 0);

  NanReturnUndefined();
}

NAN_METHOD(render_file_sync) {
  NanScope();

  Local<Object> options = args[0]->ToObject();
  char* input_path = create_string(options->Get(NanNew("file")));
  struct Sass_File_Context* fctx = sass_make_file_context(input_path);
  struct Sass_Context* ctx = sass_file_context_get_context(fctx);
  sass_context_wrapper* ctx_w = sass_make_context_wrapper();

  ExtractOptions(options, fctx, ctx_w, true, true);
  compile_file(fctx);

  int result = GetResult(ctx_w, ctx, true);

  free(input_path);
  sass_free_context_wrapper(ctx_w);

  NanReturnValue(NanNew<Boolean>(result == 0));
}

NAN_METHOD(libsass_version) {
  NanScope();
  NanReturnValue(NanNew<String>(libsass_version()));
}

void RegisterModule(v8::Handle<v8::Object> target) {
  NODE_SET_METHOD(target, "render", render);
  NODE_SET_METHOD(target, "renderSync", render_sync);
  NODE_SET_METHOD(target, "renderFile", render_file);
  NODE_SET_METHOD(target, "renderFileSync", render_file_sync);
  NODE_SET_METHOD(target, "libsassVersion", libsass_version);
  SassTypes::Factory::initExports(target);
}

NODE_MODULE(binding, RegisterModule);
<|endoftext|>


<commit_before>#include "PolychrHAUM.h"

#ifdef BUILD_PC
#include <stdio.h>
long long millis();
extern int pc_btn_pwr;
extern int pc_btn_1;
extern int pc_btn_2;
#else
#include "Arduino.h"
#endif

namespace polychrhaum {

void PolychrHAUMcommon::setup() {
	btn1.init();
	btn2.init();
	btn_power.init();
	power.init();
	leds.init();
#ifndef BUILD_PC
	pinMode(pin_btn1, INPUT_PULLUP);
	pinMode(pin_btn2, INPUT_PULLUP);
	pinMode(pin_power_btn, INPUT_PULLUP);
	Serial.begin(115200);
#endif
	last_btn_time = millis();
	last_frame_time = millis();
}

void PolychrHAUMcommon::loop_step() {
	long time = millis();

	// Compute button press
	if (time >= last_btn_time + dtms / 4) {
		last_btn_time = time;
#ifdef BUILD_PC
		btn_power.compute(pc_btn_pwr);
		btn1.compute(pc_btn_1);
		btn2.compute(pc_btn_2);
#else
		btn_power.compute(!digitalRead(pin_power_btn));
		btn1.compute(!digitalRead(pin_btn1));
		btn2.compute(!digitalRead(pin_btn2));
#endif
	}

	// Compute animation
	if (time >= last_frame_time + dtms + adj_time) {
		last_frame_time = time;

		// Power management
		if (!power.is_powered()) {
			if (btn_power.touched() || btn1.touched() || btn2.touched())
				power.poweron();
		} else {
			if (btn_power.slpressed())
				power.poweroff();
		}

		// Potentiometers
#ifndef BUILD_PC
		if (pin_pot_light >= 0) {
			int val = analogRead(pin_pot_light) >> 2;
			leds.set_brightness(val);
		}
		if (pin_pot_speed >= 0) {
			int val = analogRead(pin_pot_speed);
			adj_time = (1 - (val / 640.0)) * dtms * 3 - dtms / 2;
			if (val > 640)
				adj_time = 0;
		}
#endif
		// Animation
		leds.update();
		leds.clear();
		if (fct_animate)
			fct_animate();

		// Reset buttons reports
		btn1.endframe();
		btn2.endframe();
		btn_power.endframe();
	}
}

void PolychrHAUMcommon::log(const char *msg) {
#ifdef BUILD_PC
	printf("%s", msg);
	fflush(stdout);
#else
	Serial.print(msg);
#endif
}

void PolychrHAUMcommon::log(int msg) {
#ifdef BUILD_PC
	printf("%d", msg);
	fflush(stdout);
#else
	Serial.print(msg);
#endif
}

void PolychrHAUMcommon::send_data(char type, char data[4]) {
	char msg[7];
	/* Note: we do not use snprintf because we do not want the null-terminator and data is fixed in size anyway */
	sprintf(msg, "\x11%c%c%c%c%c\x12", type, data[0], data[1], data[2], data[3]);
#ifdef BUILD_PC
        fwrite(msg, sizeof(msg), 1, stdout);
#else
        Serial.write(msg, sizeof(msg));
#endif
}

};

<commit_msg>Fix send_data<commit_after>#include "PolychrHAUM.h"

#ifdef BUILD_PC
#include <stdio.h>
long long millis();
extern int pc_btn_pwr;
extern int pc_btn_1;
extern int pc_btn_2;
#else
#include "Arduino.h"
#endif

namespace polychrhaum {

void PolychrHAUMcommon::setup() {
	btn1.init();
	btn2.init();
	btn_power.init();
	power.init();
	leds.init();
#ifndef BUILD_PC
	pinMode(pin_btn1, INPUT_PULLUP);
	pinMode(pin_btn2, INPUT_PULLUP);
	pinMode(pin_power_btn, INPUT_PULLUP);
	Serial.begin(115200);
#endif
	last_btn_time = millis();
	last_frame_time = millis();
}

void PolychrHAUMcommon::loop_step() {
	long time = millis();

	// Compute button press
	if (time >= last_btn_time + dtms / 4) {
		last_btn_time = time;
#ifdef BUILD_PC
		btn_power.compute(pc_btn_pwr);
		btn1.compute(pc_btn_1);
		btn2.compute(pc_btn_2);
#else
		btn_power.compute(!digitalRead(pin_power_btn));
		btn1.compute(!digitalRead(pin_btn1));
		btn2.compute(!digitalRead(pin_btn2));
#endif
	}

	// Compute animation
	if (time >= last_frame_time + dtms + adj_time) {
		last_frame_time = time;

		// Power management
		if (!power.is_powered()) {
			if (btn_power.touched() || btn1.touched() || btn2.touched())
				power.poweron();
		} else {
			if (btn_power.slpressed())
				power.poweroff();
		}

		// Potentiometers
#ifndef BUILD_PC
		if (pin_pot_light >= 0) {
			int val = analogRead(pin_pot_light) >> 2;
			leds.set_brightness(val);
		}
		if (pin_pot_speed >= 0) {
			int val = analogRead(pin_pot_speed);
			adj_time = (1 - (val / 640.0)) * dtms * 3 - dtms / 2;
			if (val > 640)
				adj_time = 0;
		}
#endif
		// Animation
		leds.update();
		leds.clear();
		if (fct_animate)
			fct_animate();

		// Reset buttons reports
		btn1.endframe();
		btn2.endframe();
		btn_power.endframe();
	}
}

void PolychrHAUMcommon::log(const char *msg) {
#ifdef BUILD_PC
	printf("%s", msg);
	fflush(stdout);
#else
	Serial.print(msg);
#endif
}

void PolychrHAUMcommon::log(int msg) {
#ifdef BUILD_PC
	printf("%d", msg);
	fflush(stdout);
#else
	Serial.print(msg);
#endif
}

void PolychrHAUMcommon::send_data(char type, char data[4]) {
	char msg[8];
	snprintf(msg, sizeof(msg), "\x11%c%c%c%c%c\x12", type, data[0], data[1], data[2], data[3]);
#ifdef BUILD_PC
	fwrite(msg, sizeof(msg) - 1, 1, stdout);
	fflush(stdout);
#else
	Serial.write(msg, sizeof(msg) - 1);
#endif
}

};

<|endoftext|>


<commit_before>#include "extract.hpp"
#include "../huffman/decompress.hpp"

#include<fstream>
#include<vector>
#include<experimental/filesystem>

namespace fs = std::experimental::filesystem;

void extract(const char* in_file, const char* out_dir) {
	std::ifstream in(in_file);
	extract(in, out_dir);
}

void extract(std::istream& in_stream, const char* out_dir) {
	std::istreambuf_iterator<char> in_iterator(in_stream);

	std::vector<std::string> filenames;

	std::string fn;
	while(true) {
		char next = *in_iterator;
		++in_iterator;
		if(next == '\0') {
			if(fn.empty()) break;
			filenames.push_back(fn);
			fn.clear();
		}
		else {
			fn.push_back(next);
		}
	}

	BinaryRead bin_in(in_iterator);
	for(auto& fn : filenames) {
		std::string full_name = fs::path(out_dir) / fn;
		const auto ind = full_name.find_last_of("/");
		fs::create_directories(full_name.substr(0, ind));

		std::ofstream out(full_name);
		std::ostreambuf_iterator<char> out_iterator(out);
		decompress(bin_in, out_iterator);
	}
}
<commit_msg>Use filesystem library parent_path()<commit_after>#include "extract.hpp"
#include "../huffman/decompress.hpp"

#include<fstream>
#include<vector>
#include<experimental/filesystem>

namespace fs = std::experimental::filesystem;

void extract(const char* in_file, const char* out_dir) {
	std::ifstream in(in_file);
	extract(in, out_dir);
}

void extract(std::istream& in_stream, const char* out_dir) {
	std::istreambuf_iterator<char> in_iterator(in_stream);

	std::vector<std::string> filenames;

	std::string fn;
	while(true) {
		char next = *in_iterator;
		++in_iterator;
		if(next == '\0') {
			if(fn.empty()) break;
			filenames.push_back(fn);
			fn.clear();
		}
		else {
			fn.push_back(next);
		}
	}

	BinaryRead bin_in(in_iterator);
	for(auto& fn : filenames) {
		auto full_name = fs::path(out_dir) / fn;
		fs::create_directories(full_name.parent_path());

		std::ofstream out(full_name);
		std::ostreambuf_iterator<char> out_iterator(out);
		decompress(bin_in, out_iterator);
	}
}
<|endoftext|>


<commit_before>#include <Kernel/Scheduler.hh>
#include <Kernel/Thread.hh>
#include <Kernel/Process.hh>
#include <Kernel/Watchdog.hh>

#include <cstdio>

#include <spinlock.h>

using namespace Kernel;

Thread* idleListHeadM = 0;
Thread* idleListTailM = 0;
Thread* readyListHeadM = 0;
Thread* readyListTailM = 0;
Thread* currentThread = 0;

static spinlock_softirq_t schedulerLock = SPINLOCK_SOFTIRQ_STATIC_INITIALIZER;

namespace
{
   Process* currentProcess = 0;
};

void
Scheduler::setCurrentProcess(Process* process)
{
   currentProcess = process;
}

Process*
Scheduler::getCurrentProcess()
{
   return currentProcess;
}

void
Scheduler::init()
{
   static Thread thread0(Kernel::Thread::KernelThread);
//   static Process process0;

   thread0.init0(KernelStackStart);

   setCurrentThread(&thread0);

   readyListHeadM = &thread0;
   readyListTailM = &thread0;

   idleListHeadM = 0;
   idleListTailM = 0;
}

void
Scheduler::setCurrentThread(Thread* thread)
{
   currentThread = thread;
}

Thread*
Scheduler::getCurrentThread()
{
   return currentThread;
}

void
Scheduler::insert(Thread* t)
{
   printf("Scheduler: inserting thread %lu\n", t->getId());

   spinlock_softirq_enter(&schedulerLock);

   if (readyListTailM == 0)
   {
      assert(readyListHeadM == 0);
      assert(t->nextM == 0);

      readyListTailM = t;
      readyListHeadM = t;
   }
   else
   {
      Thread* oldTail = readyListTailM;
      readyListTailM = t;

      oldTail->nextM = t;
   }

   spinlock_softirq_exit(&schedulerLock);
}

void
Scheduler::schedule()
{
   spinlock_softirq_enter(&schedulerLock);

   Thread* lastRunning = getCurrentThread();

   if (readyListTailM)
   {
      readyListTailM->nextM = lastRunning;
   }
   readyListTailM = lastRunning;

   Thread* next = readyListHeadM;
   KASSERT(next != 0);

   readyListHeadM = readyListHeadM->nextM;
   setCurrentThread(next);

   spinlock_softirq_exit(&schedulerLock);

   Watchdog::kick();
}
<commit_msg>Just use stl list for scheduling<commit_after>#include <Kernel/Scheduler.hh>
#include <Kernel/Thread.hh>
#include <Kernel/Process.hh>
#include <Kernel/Watchdog.hh>

#include <cstdio>
#include <list>

#include <spinlock.h>

using namespace Kernel;

Thread* currentThread = 0;

static spinlock_softirq_t schedulerLock = SPINLOCK_SOFTIRQ_STATIC_INITIALIZER;

namespace
{
   Process* currentProcess = 0;

   std::list<Thread*>* readyList;
   std::list<Thread*>* idleList;
};

void
Scheduler::setCurrentProcess(Process* process)
{
   currentProcess = process;
}

Process*
Scheduler::getCurrentProcess()
{
   return currentProcess;
}

void
Scheduler::init()
{
   static std::list<Thread*> readyListInstance;
   static std::list<Thread*> idleListInstance;

   readyList = &readyListInstance;
   idleList = &idleListInstance;

   static Thread thread0(Kernel::Thread::KernelThread);
//   static Process process0;

   thread0.init0(KernelStackStart);

   setCurrentThread(&thread0);

   readyList->push_back(&thread0);
}

void
Scheduler::setCurrentThread(Thread* thread)
{
   currentThread = thread;
}

Thread*
Scheduler::getCurrentThread()
{
   return currentThread;
}

void
Scheduler::insert(Thread* t)
{
   printf("Scheduler: inserting thread %lu\n", t->getId());

   spinlock_softirq_enter(&schedulerLock);

   readyList->push_back(t);

   spinlock_softirq_exit(&schedulerLock);
}

void
Scheduler::schedule()
{
   spinlock_softirq_enter(&schedulerLock);

   // move interrupted thread to end of ready list
   Thread* lastRunning = getCurrentThread();
   readyList->push_back(lastRunning);

   // schedule the first thread in the ready list
   Thread* next = readyList->front();
   KASSERT(next != 0);
   readyList->pop_front();
   setCurrentThread(next);

   spinlock_softirq_exit(&schedulerLock);

   Watchdog::kick();
}
<|endoftext|>