<commit_before>/*
*  Copyright 2016 Ivan Ryabov
*
*  Licensed under the Apache License, Version 2.0 (the "License");
*  you may not use this file except in compliance with the License.
*  You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*/
/*******************************************************************************
 * @file: io/sharedMemory.cpp
 *
 *  Created by soultaker on 03/07/16.
*******************************************************************************/
#include <solace/io/sharedMemory.hpp>

#include <sys/mman.h>
#include <sys/stat.h>        /* For mode constants */
#include <sys/types.h>
#include <fcntl.h>           /* For O_* constants */
#include <unistd.h>

using Solace::String;
using Solace::Path;
using Solace::MemoryView;
using Solace::ByteBuffer;
using Solace::IO::ISelectable;
using Solace::IO::File;
using Solace::IO::SharedMemory;

using Solace::IllegalArgumentException;
using Solace::IO::IOException;

const int SharedMemory::Protection::None = PROT_NONE;
const int SharedMemory::Protection::Read = PROT_READ;
const int SharedMemory::Protection::Write = PROT_WRITE;
const int SharedMemory::Protection::Exec = PROT_EXEC;

SharedMemory::SharedMemory(const poll_id fd) noexcept : _fd(fd)
{

}

SharedMemory::SharedMemory(SharedMemory&& other): _fd(other._fd) {
    other.invalidateFd();

    // Note: It's ok if we have moved content from a closed file to have this->_fd == InvalidFd
}

SharedMemory::~SharedMemory() {
    // FIXME: This can throw! Is there any way to avoid it?

    if (isOpen()) {
        close();
    }
}

SharedMemory::poll_id SharedMemory::validateFd() const {
    if (!isOpen()) {
        raise<NotOpen>();
    }

    return _fd;
}

bool SharedMemory::isOpen() const {
    return !isClosed();
}

bool SharedMemory::isClosed() const {
    return (_fd == File::InvalidFd);
}

void SharedMemory::close() {
    const auto fd = validateFd();
    const auto result = ::close(fd);

    if (result) {
        raise<IOException>(errno, "close");
    }

    invalidateFd();
}

SharedMemory::size_type SharedMemory::size() const {
    const auto fd = validateFd();

    struct stat sb;
    if (fstat(fd, &sb )) {
        raise<IOException>(errno, "fstat");
    }

    return sb.st_size;
}

SharedMemory::poll_id SharedMemory::invalidateFd() {
    auto oldFd = _fd;

    _fd = File::InvalidFd;

    return oldFd;
}

SharedMemory SharedMemory::fromFd(poll_id fid) {
    return { fid };
}

SharedMemory SharedMemory::create(const Path& pathname, size_type memSize, File::AccessMode mode, int permissionsMode) {

    if (memSize == 0) {
        raise<IOException>("Invalid size");
    }

    int oflags = 0;
    switch (mode) {
    case File::AccessMode::ReadOnly:
        oflags = O_RDONLY;
        break;
    case File::AccessMode::WriteOnly:
        oflags = O_WRONLY;
        break;
    case File::AccessMode::ReadWrite:
        oflags = O_RDWR;
        break;
    }

    mode_t omode = permissionsMode;

    const auto& pathString = pathname.toString();
    auto fd = shm_open(pathString.c_str(), O_CREAT | oflags, omode);

    if (fd == -1) {
        raise<IOException>(errno, "shm_open");
    }

    if (ftruncate(fd, memSize) == -1) {
        raise<IOException>(errno, "ftruncate");
    }

    return { fd };
}

SharedMemory SharedMemory::open(const Path& pathname, File::AccessMode mode) {
    int oflags = 0;
    switch (mode) {
    case File::AccessMode::ReadOnly:
        oflags = O_RDONLY;
        break;
    case File::AccessMode::WriteOnly:
        oflags = O_WRONLY;
        break;
    case File::AccessMode::ReadWrite:
        oflags = O_RDWR;
        break;
    }

    const auto& pathString = pathname.toString();
    auto fd = shm_open(pathString.c_str(), oflags, 0);

    if (fd == -1) {
        raise<IOException>(errno, "shm_open");
    }

    return { fd };
}

void SharedMemory::unlink(const Path& pathname) {
    const auto& pathString = pathname.toString();

    if (shm_unlink(pathString.c_str())) {
        raise<IOException>(errno, "shm_unlink");
    }
}

SharedMemory::MappedMemoryView
SharedMemory::map(SharedMemory::MappingAccess mapping, int access, size_type mapSize) {

    const auto fd = validateFd();

    const int flags = (mapping == MappingAccess::Private)
            ? MAP_PRIVATE
            : MAP_SHARED;

    if (mapSize == 0)
        mapSize = size();

    auto addr = mmap(NULL, mapSize, access, flags, fd, 0);
    if (addr == MAP_FAILED) {
        raise<IOException>(errno, "mmap");
    }

    return MappedMemoryView(mapSize, addr);
}

SharedMemory::MappedMemoryView::MappedMemoryView(size_type newSize, void* dataAddress):
    MemoryView(newSize, dataAddress)
{

}

SharedMemory::MappedMemoryView::~MappedMemoryView() {
    munmap(dataAddress(), size());
// raise<IOException>(errno, "mmap");
}
<commit_msg>Fix compilation warning on old compilers<commit_after>/*
*  Copyright 2016 Ivan Ryabov
*
*  Licensed under the Apache License, Version 2.0 (the "License");
*  you may not use this file except in compliance with the License.
*  You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*/
/*******************************************************************************
 * @file: io/sharedMemory.cpp
 *
 *  Created by soultaker on 03/07/16.
*******************************************************************************/
#include <solace/io/sharedMemory.hpp>

#include <sys/mman.h>
#include <sys/stat.h>        /* For mode constants */
#include <sys/types.h>
#include <fcntl.h>           /* For O_* constants */
#include <unistd.h>

using Solace::String;
using Solace::Path;
using Solace::MemoryView;
using Solace::ByteBuffer;
using Solace::IO::ISelectable;
using Solace::IO::File;
using Solace::IO::SharedMemory;

using Solace::IllegalArgumentException;
using Solace::IO::IOException;

const int SharedMemory::Protection::None = PROT_NONE;
const int SharedMemory::Protection::Read = PROT_READ;
const int SharedMemory::Protection::Write = PROT_WRITE;
const int SharedMemory::Protection::Exec = PROT_EXEC;

SharedMemory::SharedMemory(const poll_id fd) noexcept : _fd(fd)
{

}

SharedMemory::SharedMemory(SharedMemory&& other): _fd(other._fd) {
    other.invalidateFd();

    // Note: It's ok if we have moved content from a closed file to have this->_fd == InvalidFd
}

SharedMemory::~SharedMemory() {
    // FIXME: This can throw! Is there any way to avoid it?

    if (isOpen()) {
        close();
    }
}

SharedMemory::poll_id SharedMemory::validateFd() const {
    if (!isOpen()) {
        raise<NotOpen>();
    }

    return _fd;
}

bool SharedMemory::isOpen() const {
    return !isClosed();
}

bool SharedMemory::isClosed() const {
    return (_fd == File::InvalidFd);
}

void SharedMemory::close() {
    const auto fd = validateFd();
    const auto result = ::close(fd);

    if (result) {
        raise<IOException>(errno, "close");
    }

    invalidateFd();
}

SharedMemory::size_type SharedMemory::size() const {
    const auto fd = validateFd();

    struct stat sb;
    if (fstat(fd, &sb )) {
        raise<IOException>(errno, "fstat");
    }

    return sb.st_size;
}

SharedMemory::poll_id SharedMemory::invalidateFd() {
    auto oldFd = _fd;

    _fd = File::InvalidFd;

    return oldFd;
}

SharedMemory SharedMemory::fromFd(poll_id fid) {
    return { fid };
}

SharedMemory SharedMemory::create(const Path& pathname, size_type memSize, File::AccessMode mode, int permissionsMode) {

    if (memSize == 0) {
        raise<IOException>("Invalid size");
    }

    int oflags = 0;
    switch (mode) {
    case File::AccessMode::ReadOnly:
        oflags = O_RDONLY;
        break;
    case File::AccessMode::WriteOnly:
        oflags = O_WRONLY;
        break;
    case File::AccessMode::ReadWrite:
        oflags = O_RDWR;
        break;
    }

    mode_t omode = permissionsMode;

    const auto& pathString = pathname.toString();
    auto fd = shm_open(pathString.c_str(), O_CREAT | oflags, omode);

    if (fd == -1) {
        raise<IOException>(errno, "shm_open");
    }

    if (ftruncate(fd, memSize) == -1) {
        raise<IOException>(errno, "ftruncate");
    }

    return { fd };
}

SharedMemory SharedMemory::open(const Path& pathname, File::AccessMode mode) {
    int oflags = 0;
    switch (mode) {
    case File::AccessMode::ReadOnly:
        oflags = O_RDONLY;
        break;
    case File::AccessMode::WriteOnly:
        oflags = O_WRONLY;
        break;
    case File::AccessMode::ReadWrite:
        oflags = O_RDWR;
        break;
    }

    const auto& pathString = pathname.toString();
    auto fd = shm_open(pathString.c_str(), oflags, 0);

    if (fd == -1) {
        raise<IOException>(errno, "shm_open");
    }

    return { fd };
}

void SharedMemory::unlink(const Path& pathname) {
    const auto& pathString = pathname.toString();

    if (shm_unlink(pathString.c_str())) {
        raise<IOException>(errno, "shm_unlink");
    }
}

SharedMemory::MappedMemoryView
SharedMemory::map(SharedMemory::MappingAccess mapping, int access, size_type mapSize) {

    const auto fd = validateFd();

    const int flags = (mapping == MappingAccess::Private)
            ? MAP_PRIVATE
            : MAP_SHARED;

    if (mapSize == 0)
        mapSize = size();

    auto addr = mmap(NULL, mapSize, access, flags, fd, 0);
    if (addr == MAP_FAILED) {
        raise<IOException>(errno, "mmap");
    }

    return MappedMemoryView(mapSize, addr);
}

SharedMemory::MappedMemoryView::MappedMemoryView(size_type newSize, void* data):
    MemoryView(newSize, data)
{

}

SharedMemory::MappedMemoryView::~MappedMemoryView() {
    munmap(dataAddress(), size());
// raise<IOException>(errno, "mmap");
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2014, webvariants GmbH, http://www.webvariants.de
 *
 * This file is released under the terms of the MIT license. You can find the
 * complete text in the attached LICENSE file or online at:
 *
 * http://www.opensource.org/licenses/mit-license.php
 *
 * @author: Tino Rusch (tino.rusch@webvariants.de)
 */

#include "util/Any.h"
#include "world/ComponentManager.h"

#include "apiserver/TCPApiServerComponent.h"
#include "auth/AuthControllerComponent.h"
#include "db/DBComponent.h"
#include "enginestarter/EngineStarterComponent.h"
#include "events/EventManagerComponent.h"
#include "heartbeat/HeartBeatComponent.h"
#include "iocontroller/IOControllerComponent.h"
#include "sessions/SessionManagerComponent.h"
#include "states/StateControllerComponent.h"
#include "syscall/SysCallControllerComponent.h"
#include "webstack/HttpServerComponent.h"

std::shared_ptr<Susi::System::ComponentManager> createSusiComponentManager(Susi::Util::Any::Object config){
	using Susi::System::ComponentManager;
	using Susi::System::Component;
	using Susi::Util::Any;

	auto manager = std::make_shared<Susi::System::ComponentManager>(config);

	manager->registerComponent("eventsystem",[](ComponentManager * mgr, Any & config){
		size_t threads = 4;
		size_t queuelen = 32;
		if(config["threads"].isInteger()){
			threads = static_cast<long>(config["threads"]);
		}
		if(config["queuelen"].isInteger()){
			queuelen = static_cast<long>(config["queuelen"]);
		}
		return std::shared_ptr<Component>{new Susi::Events::ManagerComponent{threads,queuelen}};
	});

	manager->registerComponent("heartbeat",[](ComponentManager * mgr, Any & config){
		return std::shared_ptr<Component>{new Susi::HeartBeatComponent{mgr}};
	});

	manager->registerDependency("heartbeat","eventsystem");

	manager->registerComponent("dbmanager", [](ComponentManager * mgr, Any & config) {
		return std::shared_ptr<Component>{new Susi::DB::DBComponent{mgr, config}};
	});

	manager->registerComponent("authcontroller", [](ComponentManager * mgr, Any & config) {
		std::string db_identifier{""};
		if(config["db_identifier"].isString()){
			db_identifier = static_cast<std::string>(config["db_identifier"]);
		}
		return std::shared_ptr<Component>{new Susi::Auth::ControllerComponent{mgr, db_identifier}};
	});

	manager->registerDependency("authcontroller","eventsystem");

	manager->registerComponent("tcpapiserver", [](ComponentManager * mgr, Any & config) {
		std::string address{""};
		size_t threads{4};
		size_t backlog{16};
		if(config["address"].isString()){
			address = static_cast<std::string>(config["address"]);
		}
		if(config["threads"].isInteger()){
			threads =  static_cast<long>(config["threads"]);
		}
		if(config["backlog"].isInteger()){
			backlog =  static_cast<long>(config["backlog"]);
		}
		return std::shared_ptr<Component>{new Susi::Api::TCPApiServerComponent{mgr, address, threads, backlog}};
	});

	manager->registerDependency("tcpapiserver","eventsystem");

	manager->registerComponent("enginestarter", [](ComponentManager * mgr, Any & config) {
		std::string path{""};
		if(config["path"].isString()){
			path = static_cast<std::string>(config["path"]);
		}
		return std::shared_ptr<Component>{new Susi::EngineStarter::StarterComponent{mgr, path}};
	});

	manager->registerDependency("enginestarter","eventsystem");

	manager->registerComponent("iocontroller", [](ComponentManager * mgr, Any & config) {
		std::string base_path{""};
		if(config["base_path"].isString()){
			base_path = static_cast<std::string>(config["base_path"]);
		}
		return std::shared_ptr<Component>{new Susi::IOControllerComponent{mgr, base_path}};
	});

	manager->registerDependency("iocontroller","eventsystem");

	manager->registerComponent("sessionmanager", [](ComponentManager * mgr, Any & config) {
		std::chrono::milliseconds stdSessionLifetime{10000};
		std::chrono::milliseconds checkInterval{1000};
		if(config["stdSessionLifetime"].isInteger()){
			stdSessionLifetime =  std::chrono::milliseconds{static_cast<int>(config["stdSessionLifetime"])};
		}
		if(config["checkInterval"].isInteger()){
			checkInterval =  std::chrono::milliseconds{static_cast<int>(config["checkInterval"])};
		}
		return std::shared_ptr<Component>{new Susi::Sessions::SessionManagerComponent{mgr, stdSessionLifetime, checkInterval}};
	});

	manager->registerDependency("sessionmanager","eventsystem");

	manager->registerComponent("statecontroller", [](ComponentManager * mgr, Any & config) {
		std::string file{""};
		if(config["file"].isString()){
			file = static_cast<std::string>(config["file"]);
		}
		return std::shared_ptr<Component>{new Susi::States::StateControllerComponent{mgr, file}};
	});

	manager->registerDependency("statecontroller","eventsystem");

	manager->registerComponent("syscallcontroller", [](ComponentManager * mgr, Any & config) {
		std::string config_path{""};
		if(config["config_path"].isString()){
			config_path = static_cast<std::string>(config["config_path"]);
		}
		return std::shared_ptr<Component>{new Susi::Syscall::SyscallControllerComponent{mgr, config_path}};
	});

	manager->registerDependency("syscallcontroller","eventsystem");

	manager->registerComponent("httpserver", [](ComponentManager * mgr, Any & config) {
		std::string address{""};
		if(config["address"].isString()){
			address = static_cast<std::string>(config["address"]);
		}
		std::string assetRoot{""};
		if(config["assetRoot"].isString()){
			assetRoot = static_cast<std::string>(config["assetRoot"]);
		}
		return std::shared_ptr<Component>{new Susi::HttpServerComponent{mgr, address, assetRoot}};
	});

	manager->registerDependency("httpserver","eventsystem");

	return manager;
}
<commit_msg>added dependencies<commit_after>/*
 * Copyright (c) 2014, webvariants GmbH, http://www.webvariants.de
 *
 * This file is released under the terms of the MIT license. You can find the
 * complete text in the attached LICENSE file or online at:
 *
 * http://www.opensource.org/licenses/mit-license.php
 *
 * @author: Tino Rusch (tino.rusch@webvariants.de)
 */

#include "util/Any.h"
#include "world/ComponentManager.h"

#include "apiserver/TCPApiServerComponent.h"
#include "auth/AuthControllerComponent.h"
#include "db/DBComponent.h"
#include "enginestarter/EngineStarterComponent.h"
#include "events/EventManagerComponent.h"
#include "heartbeat/HeartBeatComponent.h"
#include "iocontroller/IOControllerComponent.h"
#include "sessions/SessionManagerComponent.h"
#include "states/StateControllerComponent.h"
#include "syscall/SysCallControllerComponent.h"
#include "webstack/HttpServerComponent.h"

std::shared_ptr<Susi::System::ComponentManager> createSusiComponentManager(Susi::Util::Any::Object config){
	using Susi::System::ComponentManager;
	using Susi::System::Component;
	using Susi::Util::Any;

	auto manager = std::make_shared<Susi::System::ComponentManager>(config);

	manager->registerComponent("eventsystem",[](ComponentManager * mgr, Any & config){
		size_t threads = 4;
		size_t queuelen = 32;
		if(config["threads"].isInteger()){
			threads = static_cast<long>(config["threads"]);
		}
		if(config["queuelen"].isInteger()){
			queuelen = static_cast<long>(config["queuelen"]);
		}
		return std::shared_ptr<Component>{new Susi::Events::ManagerComponent{threads,queuelen}};
	});

	manager->registerComponent("heartbeat",[](ComponentManager * mgr, Any & config){
		return std::shared_ptr<Component>{new Susi::HeartBeatComponent{mgr}};
	});

	manager->registerDependency("heartbeat","eventsystem");

	manager->registerComponent("dbmanager", [](ComponentManager * mgr, Any & config) {
		return std::shared_ptr<Component>{new Susi::DB::DBComponent{mgr, config}};
	});

	manager->registerDependency("dbmanager","eventsystem");

	manager->registerComponent("authcontroller", [](ComponentManager * mgr, Any & config) {
		std::string db_identifier{""};
		if(config["db_identifier"].isString()){
			db_identifier = static_cast<std::string>(config["db_identifier"]);
		}
		return std::shared_ptr<Component>{new Susi::Auth::ControllerComponent{mgr, db_identifier}};
	});

	manager->registerDependency("authcontroller","eventsystem");
	manager->registerDependency("heartbeat","dbmanager");

	manager->registerComponent("tcpapiserver", [](ComponentManager * mgr, Any & config) {
		std::string address{""};
		size_t threads{4};
		size_t backlog{16};
		if(config["address"].isString()){
			address = static_cast<std::string>(config["address"]);
		}
		if(config["threads"].isInteger()){
			threads =  static_cast<long>(config["threads"]);
		}
		if(config["backlog"].isInteger()){
			backlog =  static_cast<long>(config["backlog"]);
		}
		return std::shared_ptr<Component>{new Susi::Api::TCPApiServerComponent{mgr, address, threads, backlog}};
	});

	manager->registerDependency("tcpapiserver","eventsystem");

	manager->registerComponent("enginestarter", [](ComponentManager * mgr, Any & config) {
		std::string path{""};
		if(config["path"].isString()){
			path = static_cast<std::string>(config["path"]);
		}
		return std::shared_ptr<Component>{new Susi::EngineStarter::StarterComponent{mgr, path}};
	});

	manager->registerDependency("enginestarter","eventsystem");

	manager->registerComponent("iocontroller", [](ComponentManager * mgr, Any & config) {
		std::string base_path{""};
		if(config["base_path"].isString()){
			base_path = static_cast<std::string>(config["base_path"]);
		}
		return std::shared_ptr<Component>{new Susi::IOControllerComponent{mgr, base_path}};
	});

	manager->registerDependency("iocontroller","eventsystem");

	manager->registerComponent("sessionmanager", [](ComponentManager * mgr, Any & config) {
		std::chrono::milliseconds stdSessionLifetime{10000};
		std::chrono::milliseconds checkInterval{1000};
		if(config["stdSessionLifetime"].isInteger()){
			stdSessionLifetime =  std::chrono::milliseconds{static_cast<int>(config["stdSessionLifetime"])};
		}
		if(config["checkInterval"].isInteger()){
			checkInterval =  std::chrono::milliseconds{static_cast<int>(config["checkInterval"])};
		}
		return std::shared_ptr<Component>{new Susi::Sessions::SessionManagerComponent{mgr, stdSessionLifetime, checkInterval}};
	});

	manager->registerDependency("sessionmanager","eventsystem");

	manager->registerComponent("statecontroller", [](ComponentManager * mgr, Any & config) {
		std::string file{""};
		if(config["file"].isString()){
			file = static_cast<std::string>(config["file"]);
		}
		return std::shared_ptr<Component>{new Susi::States::StateControllerComponent{mgr, file}};
	});

	manager->registerDependency("statecontroller","eventsystem");
	manager->registerDependency("statecontroller","iocontroller");

	manager->registerComponent("syscallcontroller", [](ComponentManager * mgr, Any & config) {
		std::string config_path{""};
		if(config["config_path"].isString()){
			config_path = static_cast<std::string>(config["config_path"]);
		}
		return std::shared_ptr<Component>{new Susi::Syscall::SyscallControllerComponent{mgr, config_path}};
	});

	manager->registerDependency("syscallcontroller","eventsystem");
	manager->registerDependency("syscallcontroller","iocontroller");

	manager->registerComponent("httpserver", [](ComponentManager * mgr, Any & config) {
		std::string address{""};
		if(config["address"].isString()){
			address = static_cast<std::string>(config["address"]);
		}
		std::string assetRoot{""};
		if(config["assetRoot"].isString()){
			assetRoot = static_cast<std::string>(config["assetRoot"]);
		}
		return std::shared_ptr<Component>{new Susi::HttpServerComponent{mgr, address, assetRoot}};
	});

	manager->registerDependency("httpserver","eventsystem");
	manager->registerDependency("httpserver","tcpapiserver");

	return manager;
}
<|endoftext|>


<commit_before>#ifndef STAN_MODEL_MODEL_BASE_CRTP_HPP
#define STAN_MODEL_MODEL_BASE_CRTP_HPP

#include <stan/model/model_base.hpp>
#include <iostream>
#include <utility>
#include <vector>

namespace stan {
namespace model {

/**
 * Base class employing the curiously recursive template pattern for
 * static inheritance to adapt templated `log_prob` and `write_array`
 * methods to their untemplated virtual counterparts declared in
 * `model_base`.
 *
 * The derived class `M` is required to implement the following two
 * pairs of template functions,
 *
 * ```
 * template <bool propto, bool jacobian, typename T>
 * T log_prob(std::vector<T>& params_r,
 *            std::vector<int>& params_i,
 *            std::ostream* msgs = 0) const;

 * template <bool propto, bool jacobian, typename T>
 * T log_prob(Eigen::Matrix<T, -1, 1>& params_r,
 *            std::ostream* msgs = 0) const;
 * ```
 *
 * and
 *
 * ```
 * template <typename RNG>
 * void write_array(RNG& base_rng,
 *                  std::vector<double>& params_r,
 *                  std::vector<int>& params_i,
 *                  std::vector<double>& vars,
 *                  bool include_tparams = true,
 *                  bool include_gqs = true,
 *                  std::ostream* msgs = 0) const;
 *
 * template <typename RNG>
 * void write_array(RNG& base_rng,
 *                  Eigen::Matrix<double, -1, 1>& params_r,
 *                  Eigen::Matrix<double, -1, 1>& vars,
 *                  bool include_tparams = true,
 *                  bool include_gqs = true,
 *                  std::ostream* msgs = 0) const
 * ```
 *
 *
The derived class `M` must be declared following the curiously
 * recursive template pattern, for example, if `M` is `foo_model`,
 * then `foo_model` should be declared as
 *
 * ```
 * class foo_model : public stan::model::model_base_crtp<foo_model> { ... };
 * ```
 *
 * The recursion arises when the type of the declared class appears as
 * a template parameter in the class it extends.  For example,
 * `foo_model` is declared to extend `model_base_crtp<foo_model>`.  In
 * general, the template parameter `M` for this class is called the
 * derived class, and must be declared to extend `foo_model<M>`.
 *
 * @tparam M type of derived model, which must implemented the
 * template methods defined in the class documentation
 */
template <typename M>
class model_base_crtp : public stan::model::model_base {
 public:
  /**
   * Construct a model with the specified number of real unconstrained
   * parameters.
   *
   * @param[in] num_params_r number of real unconstrained parameters
   */
  explicit model_base_crtp(size_t num_params_r) : model_base(num_params_r) {}

  /**
   * Destroy this class.  This is required to be virtual to allow
   * subclass references to clean up superclasses, but is otherwise a
   * no-op.
   */
  virtual ~model_base_crtp() {}

  inline double log_prob(Eigen::VectorXd& theta,
                         std::ostream* msgs) const override {
    return static_cast<const M*>(this)->template log_prob<false, false, double>(
        theta, msgs);
  }
  inline math::var log_prob(Eigen::Matrix<math::var, -1, 1>& theta,
                            std::ostream* msgs) const override {
    return static_cast<const M*>(this)->template log_prob<false, false>(theta,
                                                                        msgs);
  }

  inline double log_prob_jacobian(Eigen::VectorXd& theta,
                                  std::ostream* msgs) const override {
    return static_cast<const M*>(this)->template log_prob<false, true>(theta,
                                                                       msgs);
  }
  inline math::var log_prob_jacobian(Eigen::Matrix<math::var, -1, 1>& theta,
                                     std::ostream* msgs) const override {
    return static_cast<const M*>(this)->template log_prob<false, true>(theta,
                                                                       msgs);
  }

  inline double log_prob_propto(Eigen::VectorXd& theta,
                                std::ostream* msgs) const override {
    return static_cast<const M*>(this)->template log_prob<true, false>(theta,
                                                                       msgs);
  }
  inline math::var log_prob_propto(Eigen::Matrix<math::var, -1, 1>& theta,
                                   std::ostream* msgs) const override {
    return static_cast<const M*>(this)->template log_prob<true, false>(theta,
                                                                       msgs);
  }

  inline double log_prob_propto_jacobian(Eigen::VectorXd& theta,
                                         std::ostream* msgs) const override {
    return static_cast<const M*>(this)->template log_prob<true, true>(theta,
                                                                      msgs);
  }
  inline math::var log_prob_propto_jacobian(
      Eigen::Matrix<math::var, -1, 1>& theta,
      std::ostream* msgs) const override {
    return static_cast<const M*>(this)->template log_prob<true, true>(theta,
                                                                      msgs);
  }

  void write_array(boost::ecuyer1988& rng, Eigen::VectorXd& theta,
                   Eigen::VectorXd& vars, bool include_tparams = true,
                   bool include_gqs = true,
                   std::ostream* msgs = 0) const override {
    return static_cast<const M*>(this)->template write_array(
        rng, theta, vars, include_tparams, include_gqs, msgs);
  }

  // TODO(carpenter): remove redundant std::vector methods below here =====
  // ======================================================================

  inline double log_prob(std::vector<double>& theta, std::vector<int>& theta_i,
                         std::ostream* msgs) const override {
    return static_cast<const M*>(this)->template log_prob<false, false>(
        theta, theta_i, msgs);
  }
  inline math::var log_prob(std::vector<math::var>& theta,
                            std::vector<int>& theta_i,
                            std::ostream* msgs) const override {
    return static_cast<const M*>(this)->template log_prob<false, false>(
        theta, theta_i, msgs);
  }

  inline double log_prob_jacobian(std::vector<double>& theta,
                                  std::vector<int>& theta_i,
                                  std::ostream* msgs) const override {
    return static_cast<const M*>(this)->template log_prob<false, true>(
        theta, theta_i, msgs);
  }
  inline math::var log_prob_jacobian(std::vector<math::var>& theta,
                                     std::vector<int>& theta_i,
                                     std::ostream* msgs) const override {
    return static_cast<const M*>(this)->template log_prob<false, true>(
        theta, theta_i, msgs);
  }

  inline double log_prob_propto(std::vector<double>& theta,
                                std::vector<int>& theta_i,
                                std::ostream* msgs) const override {
    return static_cast<const M*>(this)->template log_prob<true, false>(
        theta, theta_i, msgs);
  }
  inline math::var log_prob_propto(std::vector<math::var>& theta,
                                   std::vector<int>& theta_i,
                                   std::ostream* msgs) const override {
    return static_cast<const M*>(this)->template log_prob<true, false>(
        theta, theta_i, msgs);
  }

  inline double log_prob_propto_jacobian(std::vector<double>& theta,
                                         std::vector<int>& theta_i,
                                         std::ostream* msgs) const override {
    return static_cast<const M*>(this)->template log_prob<true, true>(
        theta, theta_i, msgs);
  }
  inline math::var log_prob_propto_jacobian(std::vector<math::var>& theta,
                                            std::vector<int>& theta_i,
                                            std::ostream* msgs) const override {
    return static_cast<const M*>(this)->template log_prob<true, true>(
        theta, theta_i, msgs);
  }

  void write_array(boost::ecuyer1988& rng, std::vector<double>& theta,
                   std::vector<int>& theta_i, std::vector<double>& vars,
                   bool include_tparams = true, bool include_gqs = true,
                   std::ostream* msgs = 0) const override {
    return static_cast<const M*>(this)->template write_array(
        rng, theta, theta_i, vars, include_tparams, include_gqs, msgs);
  }

  void transform_inits(const io::var_context& context,
                       Eigen::VectorXd& params_r, std::ostream* msgs) const {
    return static_cast<const M*>(this)->template transform_inits(
        context, params_r, msgs);
  }

  void transform_inits(Eigen::VectorXd& input_r, Eigen::VectorXd& params_r,
                       std::ostream* msgs) const {
    return static_cast<const M*>(this)->template transform_inits(
        input_r, params_r, msgs);
  }
};

}  // namespace model
}  // namespace stan
#endif
<commit_msg>add const override to transform_inits()<commit_after>#ifndef STAN_MODEL_MODEL_BASE_CRTP_HPP
#define STAN_MODEL_MODEL_BASE_CRTP_HPP

#include <stan/model/model_base.hpp>
#include <iostream>
#include <utility>
#include <vector>

namespace stan {
namespace model {

/**
 * Base class employing the curiously recursive template pattern for
 * static inheritance to adapt templated `log_prob` and `write_array`
 * methods to their untemplated virtual counterparts declared in
 * `model_base`.
 *
 * The derived class `M` is required to implement the following two
 * pairs of template functions,
 *
 * ```
 * template <bool propto, bool jacobian, typename T>
 * T log_prob(std::vector<T>& params_r,
 *            std::vector<int>& params_i,
 *            std::ostream* msgs = 0) const;

 * template <bool propto, bool jacobian, typename T>
 * T log_prob(Eigen::Matrix<T, -1, 1>& params_r,
 *            std::ostream* msgs = 0) const;
 * ```
 *
 * and
 *
 * ```
 * template <typename RNG>
 * void write_array(RNG& base_rng,
 *                  std::vector<double>& params_r,
 *                  std::vector<int>& params_i,
 *                  std::vector<double>& vars,
 *                  bool include_tparams = true,
 *                  bool include_gqs = true,
 *                  std::ostream* msgs = 0) const;
 *
 * template <typename RNG>
 * void write_array(RNG& base_rng,
 *                  Eigen::Matrix<double, -1, 1>& params_r,
 *                  Eigen::Matrix<double, -1, 1>& vars,
 *                  bool include_tparams = true,
 *                  bool include_gqs = true,
 *                  std::ostream* msgs = 0) const
 * ```
 *
 *
The derived class `M` must be declared following the curiously
 * recursive template pattern, for example, if `M` is `foo_model`,
 * then `foo_model` should be declared as
 *
 * ```
 * class foo_model : public stan::model::model_base_crtp<foo_model> { ... };
 * ```
 *
 * The recursion arises when the type of the declared class appears as
 * a template parameter in the class it extends.  For example,
 * `foo_model` is declared to extend `model_base_crtp<foo_model>`.  In
 * general, the template parameter `M` for this class is called the
 * derived class, and must be declared to extend `foo_model<M>`.
 *
 * @tparam M type of derived model, which must implemented the
 * template methods defined in the class documentation
 */
template <typename M>
class model_base_crtp : public stan::model::model_base {
 public:
  /**
   * Construct a model with the specified number of real unconstrained
   * parameters.
   *
   * @param[in] num_params_r number of real unconstrained parameters
   */
  explicit model_base_crtp(size_t num_params_r) : model_base(num_params_r) {}

  /**
   * Destroy this class.  This is required to be virtual to allow
   * subclass references to clean up superclasses, but is otherwise a
   * no-op.
   */
  virtual ~model_base_crtp() {}

  inline double log_prob(Eigen::VectorXd& theta,
                         std::ostream* msgs) const override {
    return static_cast<const M*>(this)->template log_prob<false, false, double>(
        theta, msgs);
  }
  inline math::var log_prob(Eigen::Matrix<math::var, -1, 1>& theta,
                            std::ostream* msgs) const override {
    return static_cast<const M*>(this)->template log_prob<false, false>(theta,
                                                                        msgs);
  }

  inline double log_prob_jacobian(Eigen::VectorXd& theta,
                                  std::ostream* msgs) const override {
    return static_cast<const M*>(this)->template log_prob<false, true>(theta,
                                                                       msgs);
  }
  inline math::var log_prob_jacobian(Eigen::Matrix<math::var, -1, 1>& theta,
                                     std::ostream* msgs) const override {
    return static_cast<const M*>(this)->template log_prob<false, true>(theta,
                                                                       msgs);
  }

  inline double log_prob_propto(Eigen::VectorXd& theta,
                                std::ostream* msgs) const override {
    return static_cast<const M*>(this)->template log_prob<true, false>(theta,
                                                                       msgs);
  }
  inline math::var log_prob_propto(Eigen::Matrix<math::var, -1, 1>& theta,
                                   std::ostream* msgs) const override {
    return static_cast<const M*>(this)->template log_prob<true, false>(theta,
                                                                       msgs);
  }

  inline double log_prob_propto_jacobian(Eigen::VectorXd& theta,
                                         std::ostream* msgs) const override {
    return static_cast<const M*>(this)->template log_prob<true, true>(theta,
                                                                      msgs);
  }
  inline math::var log_prob_propto_jacobian(
      Eigen::Matrix<math::var, -1, 1>& theta,
      std::ostream* msgs) const override {
    return static_cast<const M*>(this)->template log_prob<true, true>(theta,
                                                                      msgs);
  }

  void write_array(boost::ecuyer1988& rng, Eigen::VectorXd& theta,
                   Eigen::VectorXd& vars, bool include_tparams = true,
                   bool include_gqs = true,
                   std::ostream* msgs = 0) const override {
    return static_cast<const M*>(this)->template write_array(
        rng, theta, vars, include_tparams, include_gqs, msgs);
  }

  // TODO(carpenter): remove redundant std::vector methods below here =====
  // ======================================================================

  inline double log_prob(std::vector<double>& theta, std::vector<int>& theta_i,
                         std::ostream* msgs) const override {
    return static_cast<const M*>(this)->template log_prob<false, false>(
        theta, theta_i, msgs);
  }
  inline math::var log_prob(std::vector<math::var>& theta,
                            std::vector<int>& theta_i,
                            std::ostream* msgs) const override {
    return static_cast<const M*>(this)->template log_prob<false, false>(
        theta, theta_i, msgs);
  }

  inline double log_prob_jacobian(std::vector<double>& theta,
                                  std::vector<int>& theta_i,
                                  std::ostream* msgs) const override {
    return static_cast<const M*>(this)->template log_prob<false, true>(
        theta, theta_i, msgs);
  }
  inline math::var log_prob_jacobian(std::vector<math::var>& theta,
                                     std::vector<int>& theta_i,
                                     std::ostream* msgs) const override {
    return static_cast<const M*>(this)->template log_prob<false, true>(
        theta, theta_i, msgs);
  }

  inline double log_prob_propto(std::vector<double>& theta,
                                std::vector<int>& theta_i,
                                std::ostream* msgs) const override {
    return static_cast<const M*>(this)->template log_prob<true, false>(
        theta, theta_i, msgs);
  }
  inline math::var log_prob_propto(std::vector<math::var>& theta,
                                   std::vector<int>& theta_i,
                                   std::ostream* msgs) const override {
    return static_cast<const M*>(this)->template log_prob<true, false>(
        theta, theta_i, msgs);
  }

  inline double log_prob_propto_jacobian(std::vector<double>& theta,
                                         std::vector<int>& theta_i,
                                         std::ostream* msgs) const override {
    return static_cast<const M*>(this)->template log_prob<true, true>(
        theta, theta_i, msgs);
  }
  inline math::var log_prob_propto_jacobian(std::vector<math::var>& theta,
                                            std::vector<int>& theta_i,
                                            std::ostream* msgs) const override {
    return static_cast<const M*>(this)->template log_prob<true, true>(
        theta, theta_i, msgs);
  }

  void write_array(boost::ecuyer1988& rng, std::vector<double>& theta,
                   std::vector<int>& theta_i, std::vector<double>& vars,
                   bool include_tparams = true, bool include_gqs = true,
                   std::ostream* msgs = 0) const override {
    return static_cast<const M*>(this)->template write_array(
        rng, theta, theta_i, vars, include_tparams, include_gqs, msgs);
  }

  void transform_inits(const io::var_context& context,
                       Eigen::VectorXd& params_r, std::ostream* msgs) const override {
    return static_cast<const M*>(this)->template transform_inits(
        context, params_r, msgs);
  }
};

}  // namespace model
}  // namespace stan
#endif
<|endoftext|>


<commit_before><commit_msg>Remove unnecessary java initializations<commit_after><|endoftext|>


<commit_before>// Copyright Daniel Wallin 2006. Use, modification and distribution is
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

#include <boost/python.hpp>
#include <libtorrent/session.hpp>

using namespace boost::python;
using namespace libtorrent;

void bind_session_settings()
{
    class_<session_settings>("session_settings")
        .def_readwrite("user_agent", &session_settings::user_agent)
        .def_readwrite("tracker_completion_timeout", &session_settings::tracker_completion_timeout)
        .def_readwrite("tracker_receive_timeout", &session_settings::tracker_receive_timeout)
        .def_readwrite("stop_tracker_timeout", &session_settings::stop_tracker_timeout)
        .def_readwrite("tracker_maximum_response_length", &session_settings::tracker_maximum_response_length)
        .def_readwrite("piece_timeout", &session_settings::piece_timeout)
        .def_readwrite("request_timeout", &session_settings::request_timeout)
        .def_readwrite("request_queue_time", &session_settings::request_queue_time)
        .def_readwrite("max_allowed_in_request_queue", &session_settings::max_allowed_in_request_queue)
        .def_readwrite("max_out_request_queue", &session_settings::max_out_request_queue)
        .def_readwrite("whole_pieces_threshold", &session_settings::whole_pieces_threshold)
        .def_readwrite("peer_timeout", &session_settings::peer_timeout)
        .def_readwrite("urlseed_timeout", &session_settings::urlseed_timeout)
        .def_readwrite("urlseed_pipeline_size", &session_settings::urlseed_pipeline_size)
        .def_readwrite("urlseed_wait_retry", &session_settings::urlseed_wait_retry)
        .def_readwrite("file_pool_size", &session_settings::file_pool_size)
        .def_readwrite("allow_multiple_connections_per_ip", &session_settings::allow_multiple_connections_per_ip)
        .def_readwrite("max_failcount", &session_settings::max_failcount)
        .def_readwrite("min_reconnect_time", &session_settings::min_reconnect_time)
        .def_readwrite("peer_connect_timeout", &session_settings::peer_connect_timeout)
        .def_readwrite("ignore_limits_on_local_network", &session_settings::ignore_limits_on_local_network)
        .def_readwrite("connection_speed", &session_settings::connection_speed)
        .def_readwrite("send_redundant_have", &session_settings::send_redundant_have)
        .def_readwrite("lazy_bitfields", &session_settings::lazy_bitfields)
        .def_readwrite("inactivity_timeout", &session_settings::inactivity_timeout)
        .def_readwrite("unchoke_interval", &session_settings::unchoke_interval)
        .def_readwrite("optimistic_unchoke_interval", &session_settings::optimistic_unchoke_interval)
        .def_readwrite("num_want", &session_settings::num_want)
        .def_readwrite("initial_picker_threshold", &session_settings::initial_picker_threshold)
        .def_readwrite("allowed_fast_set_size", &session_settings::allowed_fast_set_size)
        .def_readwrite("max_queued_disk_bytes", &session_settings::max_queued_disk_bytes)
        .def_readwrite("handshake_timeout", &session_settings::handshake_timeout)
#ifndef TORRENT_DISABLE_DHT
        .def_readwrite("use_dht_as_fallback", &session_settings::use_dht_as_fallback)
#endif
        .def_readwrite("free_torrent_hashes", &session_settings::free_torrent_hashes)
        .def_readwrite("upnp_ignore_nonrouters", &session_settings::upnp_ignore_nonrouters)
        .def_readwrite("send_buffer_watermark", &session_settings::send_buffer_watermark)
        .def_readwrite("auto_upload_slots", &session_settings::auto_upload_slots)
        .def_readwrite("auto_upload_slots_rate_based", &session_settings::auto_upload_slots_rate_based)
        .def_readwrite("use_parole_mode", &session_settings::use_parole_mode)
        .def_readwrite("cache_size", &session_settings::cache_size)
        .def_readwrite("cache_buffer_chunk_size", &session_settings::cache_buffer_chunk_size)
        .def_readwrite("cache_expiry", &session_settings::cache_expiry)
        .def_readwrite("use_read_cache", &session_settings::use_read_cache)
        .def_readwrite("disk_io_write_mode", &session_settings::disk_io_write_mode)
        .def_readwrite("disk_io_read_mode", &session_settings::disk_io_read_mode)
        .def_readwrite("coalesce_reads", &session_settings::coalesce_reads)
        .def_readwrite("coalesce_writes", &session_settings::coalesce_writes)
        .def_readwrite("outgoing_ports", &session_settings::outgoing_ports)
        .def_readwrite("peer_tos", &session_settings::peer_tos)
        .def_readwrite("active_downloads", &session_settings::active_downloads)
        .def_readwrite("active_seeds", &session_settings::active_seeds)
        .def_readwrite("active_limit", &session_settings::active_limit)
        .def_readwrite("auto_manage_prefer_seeds", &session_settings::auto_manage_prefer_seeds)
        .def_readwrite("dont_count_slow_torrents", &session_settings::dont_count_slow_torrents)
        .def_readwrite("auto_manage_interval", &session_settings::auto_manage_interval)
        .def_readwrite("share_ratio_limit", &session_settings::share_ratio_limit)
        .def_readwrite("seed_time_ratio_limit", &session_settings::seed_time_ratio_limit)
        .def_readwrite("seed_time_limit", &session_settings::seed_time_limit)
        .def_readwrite("peer_turnover", &session_settings::peer_turnover)
        .def_readwrite("peer_turnover_cutoff", &session_settings::peer_turnover_cutoff)
        .def_readwrite("close_redundant_connections", &session_settings::close_redundant_connections)
        .def_readwrite("auto_scrape_interval", &session_settings::auto_scrape_interval)
        .def_readwrite("auto_scrape_min_interval", &session_settings::auto_scrape_min_interval)
        .def_readwrite("max_peerlist_size", &session_settings::max_peerlist_size)
        .def_readwrite("max_paused_peerlist_size", &session_settings::max_paused_peerlist_size)
        .def_readwrite("min_announce_interval", &session_settings::min_announce_interval)
        .def_readwrite("prioritize_partial_pieces", &session_settings::prioritize_partial_pieces)
        .def_readwrite("auto_manage_startup", &session_settings::auto_manage_startup)
        .def_readwrite("rate_limit_ip_overhead", &session_settings::rate_limit_ip_overhead)
        .def_readwrite("announce_to_all_trackers", &session_settings::announce_to_all_trackers)
        .def_readwrite("announce_to_all_tiers", &session_settings::announce_to_all_tiers)
        .def_readwrite("prefer_udp_trackers", &session_settings::prefer_udp_trackers)
        .def_readwrite("strict_super_seeding", &session_settings::strict_super_seeding)
        .def_readwrite("seeding_piece_quota", &session_settings::seeding_piece_quota)
        .def_readwrite("max_sparse_regions", &session_settings::max_sparse_regions)
#ifndef TORRENT_DISABLE_MLOCK
        .def_readwrite("lock_disk_cache", &session_settings::lock_disk_cache)
#endif
        .def_readwrite("max_rejects", &session_settings::max_rejects)
        .def_readwrite("recv_socket_buffer_size", &session_settings::recv_socket_buffer_size)
        .def_readwrite("send_socket_buffer_size", &session_settings::send_socket_buffer_size)
        .def_readwrite("optimize_hashing_for_speed", &session_settings::optimize_hashing_for_speed)
        .def_readwrite("file_checks_delay_per_block", &session_settings::file_checks_delay_per_block)
        .def_readwrite("disk_cache_algorithm", &session_settings::disk_cache_algorithm)
        .def_readwrite("read_cache_line_size", &session_settings::read_cache_line_size)
        .def_readwrite("write_cache_line_size", &session_settings::write_cache_line_size)
        .def_readwrite("optimistic_disk_retry", &session_settings::optimistic_disk_retry)
        .def_readwrite("disable_hash_checks", &session_settings::disable_hash_checks)
        .def_readwrite("allow_reordered_disk_operations", &session_settings::allow_reordered_disk_operations)
        .def_readwrite("allow_i2p_mixed", &session_settings::allow_i2p_mixed)
        .def_readwrite("max_suggest_pieces", &session_settings::max_suggest_pieces)
        .def_readwrite("drop_skipped_requests", &session_settings::drop_skipped_requests)
        .def_readwrite("low_prio_disk", &session_settings::low_prio_disk)
        .def_readwrite("local_service_announce_interval", &session_settings::local_service_announce_interval)
        .def_readwrite("udp_tracker_token_expiry", &session_settings::udp_tracker_token_expiry)
        .def_readwrite("volatile_read_cache", &session_settings::volatile_read_cache)
        .def_readwrite("guided_read_cache", &guided_read_cache)
    ;

    enum_<proxy_settings::proxy_type>("proxy_type")
        .value("none", proxy_settings::none)
        .value("socks4", proxy_settings::socks4)
        .value("socks5", proxy_settings::socks5)
        .value("socks5_pw", proxy_settings::socks5_pw)
        .value("http", proxy_settings::http)
        .value("http_pw", proxy_settings::http_pw)
    ;

    enum_<session_settings::disk_cache_algo_t>("disk_cache_algo_t")
        .value("lru", session_settings::lru)
        .value("largest_contiguous", session_settings::largest_contiguous)
    ;

    enum_<session_settings::io_buffer_mode_t>("io_buffer_mode_t")
        .value("enable_os_cache", session_settings::enable_os_cache)
        .value("disable_os_cache_for_aligned_files", session_settings::disable_os_cache_for_aligned_files)
        .value("disable_os_cache", session_settings::disable_os_cache)
    ;

    class_<proxy_settings>("proxy_settings")
        .def_readwrite("hostname", &proxy_settings::hostname)
        .def_readwrite("port", &proxy_settings::port)
        .def_readwrite("password", &proxy_settings::password)
        .def_readwrite("username", &proxy_settings::username)
        .def_readwrite("type", &proxy_settings::type)
    ;

#ifndef TORRENT_DISABLE_DHT
    class_<dht_settings>("dht_settings")
        .def_readwrite("max_peers_reply", &dht_settings::max_peers_reply)
        .def_readwrite("search_branching", &dht_settings::search_branching)
        .def_readwrite("service_port", &dht_settings::service_port)
        .def_readwrite("max_fail_count", &dht_settings::max_fail_count)
    ;
#endif

#ifndef TORRENT_DISABLE_ENCRYPTION
    enum_<pe_settings::enc_policy>("enc_policy")
        .value("forced", pe_settings::forced)
        .value("enabled", pe_settings::enabled)
        .value("disabled", pe_settings::disabled)
    ;

    enum_<pe_settings::enc_level>("enc_level")
        .value("rc4", pe_settings::rc4)
        .value("plaintext", pe_settings::plaintext)
        .value("both", pe_settings::both)
    ;

    class_<pe_settings>("pe_settings")
        .def_readwrite("out_enc_policy", &pe_settings::out_enc_policy)
        .def_readwrite("in_enc_policy", &pe_settings::in_enc_policy)
        .def_readwrite("allowed_enc_level", &pe_settings::allowed_enc_level)
        .def_readwrite("prefer_rc4", &pe_settings::prefer_rc4)
    ;
#endif

}
<commit_msg>fixed python binding<commit_after>// Copyright Daniel Wallin 2006. Use, modification and distribution is
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

#include <boost/python.hpp>
#include <libtorrent/session.hpp>

using namespace boost::python;
using namespace libtorrent;

void bind_session_settings()
{
    class_<session_settings>("session_settings")
        .def_readwrite("user_agent", &session_settings::user_agent)
        .def_readwrite("tracker_completion_timeout", &session_settings::tracker_completion_timeout)
        .def_readwrite("tracker_receive_timeout", &session_settings::tracker_receive_timeout)
        .def_readwrite("stop_tracker_timeout", &session_settings::stop_tracker_timeout)
        .def_readwrite("tracker_maximum_response_length", &session_settings::tracker_maximum_response_length)
        .def_readwrite("piece_timeout", &session_settings::piece_timeout)
        .def_readwrite("request_timeout", &session_settings::request_timeout)
        .def_readwrite("request_queue_time", &session_settings::request_queue_time)
        .def_readwrite("max_allowed_in_request_queue", &session_settings::max_allowed_in_request_queue)
        .def_readwrite("max_out_request_queue", &session_settings::max_out_request_queue)
        .def_readwrite("whole_pieces_threshold", &session_settings::whole_pieces_threshold)
        .def_readwrite("peer_timeout", &session_settings::peer_timeout)
        .def_readwrite("urlseed_timeout", &session_settings::urlseed_timeout)
        .def_readwrite("urlseed_pipeline_size", &session_settings::urlseed_pipeline_size)
        .def_readwrite("urlseed_wait_retry", &session_settings::urlseed_wait_retry)
        .def_readwrite("file_pool_size", &session_settings::file_pool_size)
        .def_readwrite("allow_multiple_connections_per_ip", &session_settings::allow_multiple_connections_per_ip)
        .def_readwrite("max_failcount", &session_settings::max_failcount)
        .def_readwrite("min_reconnect_time", &session_settings::min_reconnect_time)
        .def_readwrite("peer_connect_timeout", &session_settings::peer_connect_timeout)
        .def_readwrite("ignore_limits_on_local_network", &session_settings::ignore_limits_on_local_network)
        .def_readwrite("connection_speed", &session_settings::connection_speed)
        .def_readwrite("send_redundant_have", &session_settings::send_redundant_have)
        .def_readwrite("lazy_bitfields", &session_settings::lazy_bitfields)
        .def_readwrite("inactivity_timeout", &session_settings::inactivity_timeout)
        .def_readwrite("unchoke_interval", &session_settings::unchoke_interval)
        .def_readwrite("optimistic_unchoke_interval", &session_settings::optimistic_unchoke_interval)
        .def_readwrite("num_want", &session_settings::num_want)
        .def_readwrite("initial_picker_threshold", &session_settings::initial_picker_threshold)
        .def_readwrite("allowed_fast_set_size", &session_settings::allowed_fast_set_size)
        .def_readwrite("max_queued_disk_bytes", &session_settings::max_queued_disk_bytes)
        .def_readwrite("handshake_timeout", &session_settings::handshake_timeout)
#ifndef TORRENT_DISABLE_DHT
        .def_readwrite("use_dht_as_fallback", &session_settings::use_dht_as_fallback)
#endif
        .def_readwrite("free_torrent_hashes", &session_settings::free_torrent_hashes)
        .def_readwrite("upnp_ignore_nonrouters", &session_settings::upnp_ignore_nonrouters)
        .def_readwrite("send_buffer_watermark", &session_settings::send_buffer_watermark)
        .def_readwrite("auto_upload_slots", &session_settings::auto_upload_slots)
        .def_readwrite("auto_upload_slots_rate_based", &session_settings::auto_upload_slots_rate_based)
        .def_readwrite("use_parole_mode", &session_settings::use_parole_mode)
        .def_readwrite("cache_size", &session_settings::cache_size)
        .def_readwrite("cache_buffer_chunk_size", &session_settings::cache_buffer_chunk_size)
        .def_readwrite("cache_expiry", &session_settings::cache_expiry)
        .def_readwrite("use_read_cache", &session_settings::use_read_cache)
        .def_readwrite("disk_io_write_mode", &session_settings::disk_io_write_mode)
        .def_readwrite("disk_io_read_mode", &session_settings::disk_io_read_mode)
        .def_readwrite("coalesce_reads", &session_settings::coalesce_reads)
        .def_readwrite("coalesce_writes", &session_settings::coalesce_writes)
        .def_readwrite("outgoing_ports", &session_settings::outgoing_ports)
        .def_readwrite("peer_tos", &session_settings::peer_tos)
        .def_readwrite("active_downloads", &session_settings::active_downloads)
        .def_readwrite("active_seeds", &session_settings::active_seeds)
        .def_readwrite("active_limit", &session_settings::active_limit)
        .def_readwrite("auto_manage_prefer_seeds", &session_settings::auto_manage_prefer_seeds)
        .def_readwrite("dont_count_slow_torrents", &session_settings::dont_count_slow_torrents)
        .def_readwrite("auto_manage_interval", &session_settings::auto_manage_interval)
        .def_readwrite("share_ratio_limit", &session_settings::share_ratio_limit)
        .def_readwrite("seed_time_ratio_limit", &session_settings::seed_time_ratio_limit)
        .def_readwrite("seed_time_limit", &session_settings::seed_time_limit)
        .def_readwrite("peer_turnover", &session_settings::peer_turnover)
        .def_readwrite("peer_turnover_cutoff", &session_settings::peer_turnover_cutoff)
        .def_readwrite("close_redundant_connections", &session_settings::close_redundant_connections)
        .def_readwrite("auto_scrape_interval", &session_settings::auto_scrape_interval)
        .def_readwrite("auto_scrape_min_interval", &session_settings::auto_scrape_min_interval)
        .def_readwrite("max_peerlist_size", &session_settings::max_peerlist_size)
        .def_readwrite("max_paused_peerlist_size", &session_settings::max_paused_peerlist_size)
        .def_readwrite("min_announce_interval", &session_settings::min_announce_interval)
        .def_readwrite("prioritize_partial_pieces", &session_settings::prioritize_partial_pieces)
        .def_readwrite("auto_manage_startup", &session_settings::auto_manage_startup)
        .def_readwrite("rate_limit_ip_overhead", &session_settings::rate_limit_ip_overhead)
        .def_readwrite("announce_to_all_trackers", &session_settings::announce_to_all_trackers)
        .def_readwrite("announce_to_all_tiers", &session_settings::announce_to_all_tiers)
        .def_readwrite("prefer_udp_trackers", &session_settings::prefer_udp_trackers)
        .def_readwrite("strict_super_seeding", &session_settings::strict_super_seeding)
        .def_readwrite("seeding_piece_quota", &session_settings::seeding_piece_quota)
        .def_readwrite("max_sparse_regions", &session_settings::max_sparse_regions)
#ifndef TORRENT_DISABLE_MLOCK
        .def_readwrite("lock_disk_cache", &session_settings::lock_disk_cache)
#endif
        .def_readwrite("max_rejects", &session_settings::max_rejects)
        .def_readwrite("recv_socket_buffer_size", &session_settings::recv_socket_buffer_size)
        .def_readwrite("send_socket_buffer_size", &session_settings::send_socket_buffer_size)
        .def_readwrite("optimize_hashing_for_speed", &session_settings::optimize_hashing_for_speed)
        .def_readwrite("file_checks_delay_per_block", &session_settings::file_checks_delay_per_block)
        .def_readwrite("disk_cache_algorithm", &session_settings::disk_cache_algorithm)
        .def_readwrite("read_cache_line_size", &session_settings::read_cache_line_size)
        .def_readwrite("write_cache_line_size", &session_settings::write_cache_line_size)
        .def_readwrite("optimistic_disk_retry", &session_settings::optimistic_disk_retry)
        .def_readwrite("disable_hash_checks", &session_settings::disable_hash_checks)
        .def_readwrite("allow_reordered_disk_operations", &session_settings::allow_reordered_disk_operations)
        .def_readwrite("allow_i2p_mixed", &session_settings::allow_i2p_mixed)
        .def_readwrite("max_suggest_pieces", &session_settings::max_suggest_pieces)
        .def_readwrite("drop_skipped_requests", &session_settings::drop_skipped_requests)
        .def_readwrite("low_prio_disk", &session_settings::low_prio_disk)
        .def_readwrite("local_service_announce_interval", &session_settings::local_service_announce_interval)
        .def_readwrite("udp_tracker_token_expiry", &session_settings::udp_tracker_token_expiry)
        .def_readwrite("volatile_read_cache", &session_settings::volatile_read_cache)
        .def_readwrite("guided_read_cache", &session_settings::guided_read_cache)
    ;

    enum_<proxy_settings::proxy_type>("proxy_type")
        .value("none", proxy_settings::none)
        .value("socks4", proxy_settings::socks4)
        .value("socks5", proxy_settings::socks5)
        .value("socks5_pw", proxy_settings::socks5_pw)
        .value("http", proxy_settings::http)
        .value("http_pw", proxy_settings::http_pw)
    ;

    enum_<session_settings::disk_cache_algo_t>("disk_cache_algo_t")
        .value("lru", session_settings::lru)
        .value("largest_contiguous", session_settings::largest_contiguous)
    ;

    enum_<session_settings::io_buffer_mode_t>("io_buffer_mode_t")
        .value("enable_os_cache", session_settings::enable_os_cache)
        .value("disable_os_cache_for_aligned_files", session_settings::disable_os_cache_for_aligned_files)
        .value("disable_os_cache", session_settings::disable_os_cache)
    ;

    class_<proxy_settings>("proxy_settings")
        .def_readwrite("hostname", &proxy_settings::hostname)
        .def_readwrite("port", &proxy_settings::port)
        .def_readwrite("password", &proxy_settings::password)
        .def_readwrite("username", &proxy_settings::username)
        .def_readwrite("type", &proxy_settings::type)
    ;

#ifndef TORRENT_DISABLE_DHT
    class_<dht_settings>("dht_settings")
        .def_readwrite("max_peers_reply", &dht_settings::max_peers_reply)
        .def_readwrite("search_branching", &dht_settings::search_branching)
        .def_readwrite("service_port", &dht_settings::service_port)
        .def_readwrite("max_fail_count", &dht_settings::max_fail_count)
    ;
#endif

#ifndef TORRENT_DISABLE_ENCRYPTION
    enum_<pe_settings::enc_policy>("enc_policy")
        .value("forced", pe_settings::forced)
        .value("enabled", pe_settings::enabled)
        .value("disabled", pe_settings::disabled)
    ;

    enum_<pe_settings::enc_level>("enc_level")
        .value("rc4", pe_settings::rc4)
        .value("plaintext", pe_settings::plaintext)
        .value("both", pe_settings::both)
    ;

    class_<pe_settings>("pe_settings")
        .def_readwrite("out_enc_policy", &pe_settings::out_enc_policy)
        .def_readwrite("in_enc_policy", &pe_settings::in_enc_policy)
        .def_readwrite("allowed_enc_level", &pe_settings::allowed_enc_level)
        .def_readwrite("prefer_rc4", &pe_settings::prefer_rc4)
    ;
#endif

}
<|endoftext|>


<commit_before><commit_msg>more detail log<commit_after><|endoftext|>


<commit_before>//------------------------------------------------------------------------------
//  d3d12MeshFactory.cc
//------------------------------------------------------------------------------
#include "Pre.h"
#include "d3d12_impl.h"
#include "d3d12Types.h"
#include "d3d12MeshFactory.h"
#include "Gfx/Resource/mesh.h"
#include "Gfx/Core/renderer.h"
#include "Gfx/Resource/gfxResourceContainer.h"

namespace Oryol {
namespace _priv {

//------------------------------------------------------------------------------
d3d12MeshFactory::d3d12MeshFactory() :
isValid(false) {
    // empty
}

//------------------------------------------------------------------------------
d3d12MeshFactory::~d3d12MeshFactory() {
    o_assert_dbg(!this->isValid);
}

//------------------------------------------------------------------------------
void
d3d12MeshFactory::Setup(const gfxPointers& ptrs) {
    o_assert_dbg(!this->isValid);
    this->isValid = true;
    this->pointers = ptrs;
}

//------------------------------------------------------------------------------
void
d3d12MeshFactory::Discard() {
    o_assert_dbg(this->isValid);
    this->pointers = gfxPointers();
    this->isValid = false;
}

//------------------------------------------------------------------------------
bool
d3d12MeshFactory::IsValid() const {
    return this->isValid;
}

//------------------------------------------------------------------------------
ResourceState::Code
d3d12MeshFactory::SetupResource(mesh& msh) {
    o_assert_dbg(this->isValid);
    if (msh.Setup.ShouldSetupEmpty()) {
        return this->createEmptyMesh(msh);
    }
    else if (msh.Setup.ShouldSetupFullScreenQuad()) {
        return this->createFullscreenQuad(msh);
    }
    else {
        o_error("d3d12MeshFactory::SetupResource(): don't know how to create mesh!\n");
        return ResourceState::InvalidState;
    }
}

//------------------------------------------------------------------------------
ResourceState::Code
d3d12MeshFactory::SetupResource(mesh& msh, const void* data, int32 size) {
    o_assert_dbg(this->isValid);
    o_assert_dbg(msh.Setup.ShouldSetupFromData());
    return this->createFromData(msh, data, size);
}

//------------------------------------------------------------------------------
void
d3d12MeshFactory::DestroyResource(mesh& msh) {
    o_assert_dbg(this->isValid);

    d3d12ResourceAllocator& resAllocator = this->pointers.renderer->d3d12Allocator;
    this->pointers.renderer->invalidateMeshState();
    const uint64 frameIndex = this->pointers.renderer->frameIndex;
    for (auto& buf : msh.buffers) {
        for (ID3D12Resource* d3d12Res : buf.d3d12DefaultBuffers) {
            if (d3d12Res) {
                resAllocator.ReleaseDeferred(frameIndex, d3d12Res);
            }
        }
        for (ID3D12Resource* d3d12Res : buf.d3d12UploadBuffers) {
            if (d3d12Res) {
                resAllocator.ReleaseDeferred(frameIndex, d3d12Res);
            }
        }
    }
    msh.Clear();
}

//------------------------------------------------------------------------------
void
d3d12MeshFactory::setupAttrs(mesh& msh) {

    VertexBufferAttrs vbAttrs;
    vbAttrs.NumVertices = msh.Setup.NumVertices;
    vbAttrs.Layout = msh.Setup.Layout;
    vbAttrs.BufferUsage = msh.Setup.VertexUsage;
    vbAttrs.StepFunction = msh.Setup.StepFunction;
    vbAttrs.StepRate = msh.Setup.StepRate;
    msh.vertexBufferAttrs = vbAttrs;

    IndexBufferAttrs ibAttrs;
    ibAttrs.NumIndices = msh.Setup.NumIndices;
    ibAttrs.Type = msh.Setup.IndicesType;
    ibAttrs.BufferUsage = msh.Setup.IndexUsage;
    msh.indexBufferAttrs = ibAttrs;
}

//------------------------------------------------------------------------------
void
d3d12MeshFactory::setupPrimGroups(mesh& msh) {
    msh.d3d12PrimTopologyType = d3d12Types::asPrimitiveTopologyType(msh.Setup.PrimType);
    msh.d3d12PrimTopology = d3d12Types::asPrimitiveTopology(msh.Setup.PrimType);
    msh.numPrimGroups = msh.Setup.NumPrimitiveGroups();
    o_assert_dbg(msh.numPrimGroups < GfxConfig::MaxNumPrimGroups);
    for (int32 i = 0; i < msh.numPrimGroups; i++) {
        msh.primGroups[i] = msh.Setup.PrimitiveGroup(i);
    }
}

//------------------------------------------------------------------------------
ResourceState::Code
d3d12MeshFactory::createFromData(mesh& msh, const void* data, int32 size) {
    o_assert_dbg(nullptr == msh.buffers[mesh::vb].d3d12DefaultBuffers[0]);
    o_assert_dbg(nullptr == msh.buffers[mesh::ib].d3d12DefaultBuffers[0]);
    o_assert_dbg(1 == msh.buffers[mesh::vb].numSlots);
    o_assert_dbg(1 == msh.buffers[mesh::ib].numSlots);
    o_assert_dbg(nullptr != data);
    o_assert_dbg(size > 0);
    o_assert_dbg(Usage::Immutable == msh.Setup.VertexUsage);
    ID3D12Device* d3d12Device = this->pointers.renderer->d3d12Device;
    o_assert_dbg(d3d12Device);

    // FIXME: might make sense to put vertices, indices, and double buffer copies
    // into a single D3D12 buffer, but need to figure out whether 64kByte alignment
    // is needed on each subsection (guess: yes)
    // also need scatter-gather-copy for this in resource allocator AllocBuffer
    // ...so far this method is a copy of the Metal meshFactory implementation

    this->setupAttrs(msh);
    this->setupPrimGroups(msh);
    const auto& vbAttrs = msh.vertexBufferAttrs;
    const auto& ibAttrs = msh.indexBufferAttrs;
    o_assert_dbg(Usage::Immutable == vbAttrs.BufferUsage);
    o_assert_dbg(IndexType::None != ibAttrs.Type ? Usage::Immutable == ibAttrs.BufferUsage : true);

    d3d12ResourceAllocator& resAllocator = this->pointers.renderer->d3d12Allocator;
    ID3D12GraphicsCommandList* cmdList = this->pointers.renderer->curCommandList();
    const uint64 frameIndex = this->pointers.renderer->frameIndex;

    // create vertex buffer
    const uint8* ptr = (const uint8*) data;
    const uint8* vertices = ptr + msh.Setup.DataVertexOffset;
    const int32 vbSize = vbAttrs.NumVertices * msh.Setup.Layout.ByteSize();
    o_assert_dbg((ptr + size) >= (vertices + vbSize));
    msh.buffers[mesh::vb].d3d12DefaultBuffers[0] = resAllocator.AllocStaticBuffer(d3d12Device, cmdList, frameIndex, vertices, vbSize);
    o_assert_dbg(nullptr != msh.buffers[mesh::vb].d3d12DefaultBuffers[0]);

    // create optional index buffer
    if (ibAttrs.Type != IndexType::None) {
        o_assert_dbg(Usage::Immutable == ibAttrs.BufferUsage);
        o_assert_dbg(InvalidIndex != msh.Setup.DataIndexOffset);
        o_assert_dbg(msh.Setup.DataIndexOffset >= (msh.Setup.DataVertexOffset + vbSize));
        const uint8* indices = ptr + msh.Setup.DataIndexOffset;
        const int32 ibSize = ibAttrs.NumIndices * IndexType::ByteSize(ibAttrs.Type);
        o_assert_dbg((ptr + size) >= (indices + ibSize));
        msh.buffers[mesh::ib].d3d12DefaultBuffers[0] = resAllocator.AllocStaticBuffer(d3d12Device, cmdList, frameIndex, indices, ibSize);
        o_assert_dbg(nullptr != msh.buffers[mesh::ib].d3d12DefaultBuffers[0]);
    }
    return ResourceState::Valid;
}

//------------------------------------------------------------------------------
ResourceState::Code
d3d12MeshFactory::createEmptyMesh(mesh& msh) {
    o_error("FIXME!");
    return ResourceState::Failed;
}

//------------------------------------------------------------------------------
ResourceState::Code
d3d12MeshFactory::createFullscreenQuad(mesh& msh) {
    o_error("FIXME!");
    return ResourceState::Failed;
}

} // namespace _priv
} // namespace Oryol
<commit_msg>D3D12: d3d12MeshFactory::CreateFullscreenQuad() implemented<commit_after>//------------------------------------------------------------------------------
//  d3d12MeshFactory.cc
//------------------------------------------------------------------------------
#include "Pre.h"
#include "d3d12_impl.h"
#include "d3d12Types.h"
#include "d3d12MeshFactory.h"
#include "Gfx/Resource/mesh.h"
#include "Gfx/Core/renderer.h"
#include "Gfx/Resource/gfxResourceContainer.h"

namespace Oryol {
namespace _priv {

//------------------------------------------------------------------------------
d3d12MeshFactory::d3d12MeshFactory() :
isValid(false) {
    // empty
}

//------------------------------------------------------------------------------
d3d12MeshFactory::~d3d12MeshFactory() {
    o_assert_dbg(!this->isValid);
}

//------------------------------------------------------------------------------
void
d3d12MeshFactory::Setup(const gfxPointers& ptrs) {
    o_assert_dbg(!this->isValid);
    this->isValid = true;
    this->pointers = ptrs;
}

//------------------------------------------------------------------------------
void
d3d12MeshFactory::Discard() {
    o_assert_dbg(this->isValid);
    this->pointers = gfxPointers();
    this->isValid = false;
}

//------------------------------------------------------------------------------
bool
d3d12MeshFactory::IsValid() const {
    return this->isValid;
}

//------------------------------------------------------------------------------
ResourceState::Code
d3d12MeshFactory::SetupResource(mesh& msh) {
    o_assert_dbg(this->isValid);
    if (msh.Setup.ShouldSetupEmpty()) {
        return this->createEmptyMesh(msh);
    }
    else if (msh.Setup.ShouldSetupFullScreenQuad()) {
        return this->createFullscreenQuad(msh);
    }
    else {
        o_error("d3d12MeshFactory::SetupResource(): don't know how to create mesh!\n");
        return ResourceState::InvalidState;
    }
}

//------------------------------------------------------------------------------
ResourceState::Code
d3d12MeshFactory::SetupResource(mesh& msh, const void* data, int32 size) {
    o_assert_dbg(this->isValid);
    o_assert_dbg(msh.Setup.ShouldSetupFromData());
    return this->createFromData(msh, data, size);
}

//------------------------------------------------------------------------------
void
d3d12MeshFactory::DestroyResource(mesh& msh) {
    o_assert_dbg(this->isValid);

    d3d12ResourceAllocator& resAllocator = this->pointers.renderer->d3d12Allocator;
    this->pointers.renderer->invalidateMeshState();
    const uint64 frameIndex = this->pointers.renderer->frameIndex;
    for (auto& buf : msh.buffers) {
        for (ID3D12Resource* d3d12Res : buf.d3d12DefaultBuffers) {
            if (d3d12Res) {
                resAllocator.ReleaseDeferred(frameIndex, d3d12Res);
            }
        }
        for (ID3D12Resource* d3d12Res : buf.d3d12UploadBuffers) {
            if (d3d12Res) {
                resAllocator.ReleaseDeferred(frameIndex, d3d12Res);
            }
        }
    }
    msh.Clear();
}

//------------------------------------------------------------------------------
void
d3d12MeshFactory::setupAttrs(mesh& msh) {

    VertexBufferAttrs vbAttrs;
    vbAttrs.NumVertices = msh.Setup.NumVertices;
    vbAttrs.Layout = msh.Setup.Layout;
    vbAttrs.BufferUsage = msh.Setup.VertexUsage;
    vbAttrs.StepFunction = msh.Setup.StepFunction;
    vbAttrs.StepRate = msh.Setup.StepRate;
    msh.vertexBufferAttrs = vbAttrs;

    IndexBufferAttrs ibAttrs;
    ibAttrs.NumIndices = msh.Setup.NumIndices;
    ibAttrs.Type = msh.Setup.IndicesType;
    ibAttrs.BufferUsage = msh.Setup.IndexUsage;
    msh.indexBufferAttrs = ibAttrs;
}

//------------------------------------------------------------------------------
void
d3d12MeshFactory::setupPrimGroups(mesh& msh) {
    msh.d3d12PrimTopologyType = d3d12Types::asPrimitiveTopologyType(msh.Setup.PrimType);
    msh.d3d12PrimTopology = d3d12Types::asPrimitiveTopology(msh.Setup.PrimType);
    msh.numPrimGroups = msh.Setup.NumPrimitiveGroups();
    o_assert_dbg(msh.numPrimGroups < GfxConfig::MaxNumPrimGroups);
    for (int32 i = 0; i < msh.numPrimGroups; i++) {
        msh.primGroups[i] = msh.Setup.PrimitiveGroup(i);
    }
}

//------------------------------------------------------------------------------
ResourceState::Code
d3d12MeshFactory::createFromData(mesh& msh, const void* data, int32 size) {
    o_assert_dbg(nullptr == msh.buffers[mesh::vb].d3d12DefaultBuffers[0]);
    o_assert_dbg(nullptr == msh.buffers[mesh::ib].d3d12DefaultBuffers[0]);
    o_assert_dbg(1 == msh.buffers[mesh::vb].numSlots);
    o_assert_dbg(1 == msh.buffers[mesh::ib].numSlots);
    o_assert_dbg(nullptr != data);
    o_assert_dbg(size > 0);
    o_assert_dbg(Usage::Immutable == msh.Setup.VertexUsage);
    ID3D12Device* d3d12Device = this->pointers.renderer->d3d12Device;
    o_assert_dbg(d3d12Device);

    // FIXME: might make sense to put vertices, indices, and double buffer copies
    // into a single D3D12 buffer, but need to figure out whether 64kByte alignment
    // is needed on each subsection (guess: yes)
    // also need scatter-gather-copy for this in resource allocator AllocBuffer
    // ...so far this method is a copy of the Metal meshFactory implementation

    this->setupAttrs(msh);
    this->setupPrimGroups(msh);
    const auto& vbAttrs = msh.vertexBufferAttrs;
    const auto& ibAttrs = msh.indexBufferAttrs;
    o_assert_dbg(Usage::Immutable == vbAttrs.BufferUsage);
    o_assert_dbg(IndexType::None != ibAttrs.Type ? Usage::Immutable == ibAttrs.BufferUsage : true);

    d3d12ResourceAllocator& resAllocator = this->pointers.renderer->d3d12Allocator;
    ID3D12GraphicsCommandList* cmdList = this->pointers.renderer->curCommandList();
    const uint64 frameIndex = this->pointers.renderer->frameIndex;

    // create vertex buffer
    const uint8* ptr = (const uint8*) data;
    const uint8* vertices = ptr + msh.Setup.DataVertexOffset;
    const int32 vbSize = vbAttrs.NumVertices * msh.Setup.Layout.ByteSize();
    o_assert_dbg((ptr + size) >= (vertices + vbSize));
    msh.buffers[mesh::vb].d3d12DefaultBuffers[0] = resAllocator.AllocStaticBuffer(d3d12Device, cmdList, frameIndex, vertices, vbSize);
    o_assert_dbg(nullptr != msh.buffers[mesh::vb].d3d12DefaultBuffers[0]);

    // create optional index buffer
    if (ibAttrs.Type != IndexType::None) {
        o_assert_dbg(Usage::Immutable == ibAttrs.BufferUsage);
        o_assert_dbg(InvalidIndex != msh.Setup.DataIndexOffset);
        o_assert_dbg(msh.Setup.DataIndexOffset >= (msh.Setup.DataVertexOffset + vbSize));
        const uint8* indices = ptr + msh.Setup.DataIndexOffset;
        const int32 ibSize = ibAttrs.NumIndices * IndexType::ByteSize(ibAttrs.Type);
        o_assert_dbg((ptr + size) >= (indices + ibSize));
        msh.buffers[mesh::ib].d3d12DefaultBuffers[0] = resAllocator.AllocStaticBuffer(d3d12Device, cmdList, frameIndex, indices, ibSize);
        o_assert_dbg(nullptr != msh.buffers[mesh::ib].d3d12DefaultBuffers[0]);
    }
    return ResourceState::Valid;
}

//------------------------------------------------------------------------------
ResourceState::Code
d3d12MeshFactory::createFullscreenQuad(mesh& msh) {
    o_assert_dbg(nullptr == msh.buffers[mesh::vb].d3d12DefaultBuffers[0]);
    o_assert_dbg(nullptr == msh.buffers[mesh::ib].d3d12DefaultBuffers[0]);
    o_assert_dbg(1 == msh.buffers[mesh::vb].numSlots);
    o_assert_dbg(1 == msh.buffers[mesh::ib].numSlots);

    VertexBufferAttrs vbAttrs;
    vbAttrs.NumVertices = 4;
    vbAttrs.BufferUsage = Usage::Immutable;
    vbAttrs.Layout.Add(VertexAttr::Position, VertexFormat::Float3);
    vbAttrs.Layout.Add(VertexAttr::TexCoord0, VertexFormat::Float2);
    vbAttrs.StepFunction = VertexStepFunction::PerVertex;
    vbAttrs.StepRate = 1;
    msh.vertexBufferAttrs = vbAttrs;

    IndexBufferAttrs ibAttrs;
    ibAttrs.NumIndices = 6;
    ibAttrs.Type = IndexType::Index16;
    ibAttrs.BufferUsage = Usage::Immutable;
    msh.indexBufferAttrs = ibAttrs;

    msh.d3d12PrimTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
    msh.d3d12PrimTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
    msh.numPrimGroups = 1;
    msh.primGroups[0] = PrimitiveGroup(0, 6);

    // vertices
    const float32 topV = msh.Setup.FullScreenQuadFlipV ? 0.0f : 1.0f;
    const float32 botV = msh.Setup.FullScreenQuadFlipV ? 1.0f : 0.0f;
    float32 vertices[] = {
        -1.0f, +1.0f, 0.0f, 0.0f, topV,     // top-left corner
        +1.0f, +1.0f, 0.0f, 1.0f, topV,     // top-right corner
        +1.0f, -1.0f, 0.0f, 1.0f, botV,     // bottom-right corner
        -1.0f, -1.0f, 0.0f, 0.0f, botV      // bottom-left corner
    };

    // indices
    uint16 indices[] = {
        0, 2, 1,            // topleft -> bottomright -> topright
        0, 3, 2,            // topleft -> bottomleft -> bottomright
    };

    // create d3d12 buffers
    ID3D12Device* d3d12Device = this->pointers.renderer->d3d12Device;
    o_assert_dbg(d3d12Device);
    d3d12ResourceAllocator& resAllocator = this->pointers.renderer->d3d12Allocator;
    ID3D12GraphicsCommandList* cmdList = this->pointers.renderer->curCommandList();
    const uint64 frameIndex = this->pointers.renderer->frameIndex;

    msh.buffers[mesh::vb].d3d12DefaultBuffers[0] = resAllocator.AllocStaticBuffer(d3d12Device, cmdList, frameIndex, vertices, sizeof(vertices));
    o_assert_dbg(nullptr != msh.buffers[mesh::vb].d3d12DefaultBuffers[0]);

    msh.buffers[mesh::ib].d3d12DefaultBuffers[0] = resAllocator.AllocStaticBuffer(d3d12Device, cmdList, frameIndex, indices, sizeof(indices));
    o_assert_dbg(nullptr != msh.buffers[mesh::ib].d3d12DefaultBuffers[0]);

    return ResourceState::Valid;
}

//------------------------------------------------------------------------------
ResourceState::Code
d3d12MeshFactory::createEmptyMesh(mesh& msh) {
    o_error("FIXME!");
    return ResourceState::Failed;
}

} // namespace _priv
} // namespace Oryol
<|endoftext|>


<commit_before>// Time:  O(n), n is the number of the integers.
// Space: O(l), l is the number of the nested lists.

/**
 * // This is the interface that allows for creating nested lists.
 * // You should not implement it, or speculate about its implementation
 * class NestedInteger {
 *   public:
 *     // Return true if this NestedInteger holds a single integer, rather than a nested list.
 *     bool isInteger() const;
 *
 *     // Return the single integer that this NestedInteger holds, if it holds a single integer
 *     // The result is undefined if this NestedInteger holds a nested list
 *     int getInteger() const;
 *
 *     // Return the nested list that this NestedInteger holds, if it holds a nested list
 *     // The result is undefined if this NestedInteger holds a single integer
 *     const vector<NestedInteger> &getList() const;
 * };
 */

// Using stack and iterator.
class NestedIterator {
public:
    using IT = vector<NestedInteger>::const_iterator;
    NestedIterator(vector<NestedInteger> &nestedList) {
        nodes_.emplace(nestedList.cbegin(), nestedList.cend());
    }

    int next() {
        return (nodes_.top().first++)->getInteger();
    }

    bool hasNext() {
        while (!nodes_.empty()) {
            auto& cur = nodes_.top();
            if (cur.first == cur.second) {
                nodes_.pop();
            } else if (cur.first->isInteger()) {
                return true;
            } else {
                auto& nestedList = cur.first->getList();
                ++cur.first;
                nodes_.emplace(nestedList.cbegin(), nestedList.cend());
            }
        }
        return false;
    }

private:
    stack<pair<IT, IT>> nodes_;
};

// Time:  O(n)
// Space: O(n)
// Using stack.
class NestedIterator2 {
public:
    NestedIterator2(vector<NestedInteger> &nestedList) {
        for (int i = static_cast<int>(nestedList.size()) - 1; i >= 0; --i) {
            nodes_.emplace(&nestedList[i]);
        }
    }

    int next() {
        auto result = nodes_.top()->getInteger();
        nodes_.pop();
        return result;
    }

    bool hasNext() {
        while (!nodes_.empty()) {
            auto *cur = nodes_.top();
            if (cur->isInteger()) {
                return true;
            }
            nodes_.pop();
            auto& children = cur->getList();
            for (int i = static_cast<int>(children.size()) - 1; i >= 0; --i) {
                nodes_.emplace(&children[i]);
            }
        }
        return false;
    }

private:
    stack<NestedInteger *> nodes_;
};

/**
 * Your NestedIterator object will be instantiated and called as such:
 * NestedIterator i(nestedList);
 * while (i.hasNext()) cout << i.next();
 */

<commit_msg>Update flatten-nested-list-iterator.cpp<commit_after>// Time:  O(n), n is the number of the integers.
// Space: O(h), h is the depth of the nested lists.

/**
 * // This is the interface that allows for creating nested lists.
 * // You should not implement it, or speculate about its implementation
 * class NestedInteger {
 *   public:
 *     // Return true if this NestedInteger holds a single integer, rather than a nested list.
 *     bool isInteger() const;
 *
 *     // Return the single integer that this NestedInteger holds, if it holds a single integer
 *     // The result is undefined if this NestedInteger holds a nested list
 *     int getInteger() const;
 *
 *     // Return the nested list that this NestedInteger holds, if it holds a nested list
 *     // The result is undefined if this NestedInteger holds a single integer
 *     const vector<NestedInteger> &getList() const;
 * };
 */

// Using stack and iterator.
class NestedIterator {
public:
    using IT = vector<NestedInteger>::const_iterator;
    NestedIterator(vector<NestedInteger> &nestedList) {
        nodes_.emplace(nestedList.cbegin(), nestedList.cend());
    }

    int next() {
        return (nodes_.top().first++)->getInteger();
    }

    bool hasNext() {
        while (!nodes_.empty()) {
            auto& cur = nodes_.top();
            if (cur.first == cur.second) {
                nodes_.pop();
            } else if (cur.first->isInteger()) {
                return true;
            } else {
                auto& nestedList = cur.first->getList();
                ++cur.first;
                nodes_.emplace(nestedList.cbegin(), nestedList.cend());
            }
        }
        return false;
    }

private:
    stack<pair<IT, IT>> nodes_;
};

// Time:  O(n)
// Space: O(n)
// Using stack.
class NestedIterator2 {
public:
    NestedIterator2(vector<NestedInteger> &nestedList) {
        for (int i = static_cast<int>(nestedList.size()) - 1; i >= 0; --i) {
            nodes_.emplace(&nestedList[i]);
        }
    }

    int next() {
        auto result = nodes_.top()->getInteger();
        nodes_.pop();
        return result;
    }

    bool hasNext() {
        while (!nodes_.empty()) {
            auto *cur = nodes_.top();
            if (cur->isInteger()) {
                return true;
            }
            nodes_.pop();
            auto& children = cur->getList();
            for (int i = static_cast<int>(children.size()) - 1; i >= 0; --i) {
                nodes_.emplace(&children[i]);
            }
        }
        return false;
    }

private:
    stack<NestedInteger *> nodes_;
};

/**
 * Your NestedIterator object will be instantiated and called as such:
 * NestedIterator i(nestedList);
 * while (i.hasNext()) cout << i.next();
 */

<|endoftext|>