<commit_before>// Copyright (c) 2010 Hewlett-Packard Development Company, L.P. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

extern "C" {
    #include <mlt/framework/mlt_producer.h>
    #include <mlt/framework/mlt_frame.h>
}
#include <webvfx/image.h>
#include "factory.h"
#include "service_locker.h"
#include "service_manager.h"

static const char* kWebVfxProducerPropertyName = "WebVfxProducer";
static const char* kWebVfxPositionPropertyName = "webvfx.position";

static int producerGetImage(mlt_frame frame, uint8_t **buffer, mlt_image_format *format, int *width, int *height, int /*writable*/) {
    int error = 0;
    mlt_properties properties = MLT_FRAME_PROPERTIES(frame);
    mlt_producer producer = (mlt_producer)mlt_properties_get_data(properties, kWebVfxProducerPropertyName, NULL);
    mlt_properties producer_props = MLT_PRODUCER_PROPERTIES(producer);
    int size;
    int bpp;
    bool hasTransparency = false;
    {
        MLTWebVfx::ServiceLocker locker(MLT_PRODUCER_SERVICE(producer));
        if (!locker.initialize(*width, *height))
        return 1;

        if (mlt_properties_get_int( producer_props, "transparent") ) {
            *format = mlt_image_rgb24a;
            hasTransparency = true;
        }
        else {
            *format = mlt_image_rgb24;
        }
        // Get bpp from image format
        mlt_image_format_size(*format, 0, 0, &bpp);
        size = *width * *height * bpp;
        *buffer = (uint8_t*)mlt_pool_alloc(size);

        // When not using transparency, this will make the background black...
        memset( *buffer, 255, size );
        WebVfx::Image outputImage(*buffer, *width, *height, size, hasTransparency);
        locker.getManager()->render(&outputImage,
                                    mlt_properties_get_position(properties, kWebVfxPositionPropertyName),
                                    mlt_producer_get_length(producer), hasTransparency);
	}
    mlt_frame_set_image(frame, *buffer, size, mlt_pool_release);
    if (hasTransparency) {
	// Create the alpha channel
	int alpha_size = *width * *height;
	uint8_t *alpha = (uint8_t *)mlt_pool_alloc( alpha_size );
	// Initialise the alpha
	memset( alpha, 255, alpha_size );
	mlt_frame_set_alpha(frame, alpha, alpha_size, mlt_pool_release);
    }

    mlt_properties_set_int(properties, "meta.media.width", *width);
    mlt_properties_set_int(properties, "meta.media.height", *height);
    return error;
}

static int getFrame(mlt_producer producer, mlt_frame_ptr frame, int /*index*/) {
    // Generate a frame
    *frame = mlt_frame_init(MLT_PRODUCER_SERVICE(producer));

    if (*frame) {
        // Obtain properties of frame and producer
        mlt_properties properties = MLT_FRAME_PROPERTIES(*frame);

        // Obtain properties of producer
        //mlt_properties producer_props = MLT_PRODUCER_PROPERTIES(producer);

        // Set the producer on the frame properties
        mlt_properties_set_data(properties, kWebVfxProducerPropertyName, producer, 0, NULL, NULL);

        // Update timecode on the frame we're creating
        mlt_position position = mlt_producer_position(producer);
        mlt_frame_set_position(*frame, position);
        mlt_properties_set_position(properties, kWebVfxPositionPropertyName, position);

        // Push the get_image method
        mlt_frame_push_get_image(*frame, producerGetImage);
    }

    // Calculate the next timecode
    mlt_producer_prepare_next(producer);

    return 0;
}

static void producer_close( mlt_producer parent )
{
    // Close the parent
    parent->close = NULL;
    mlt_producer_close( parent );
    // Free the memory
    free( parent );
}

mlt_service MLTWebVfx::createProducer(mlt_profile profile) {
    mlt_producer producer = mlt_producer_new(profile);
    if (producer) {
        producer->get_frame = getFrame;
        producer->close = (mlt_destructor) producer_close;
        mlt_properties properties = MLT_PRODUCER_PROPERTIES( producer );
        mlt_properties_set_int( properties, "meta.media.progressive", 1 );
        mlt_properties_set_int( properties, "meta.media.sample_aspect_num", 1 );
        mlt_properties_set_int( properties, "meta.media.sample_aspect_den", 1 );
        return MLT_PRODUCER_SERVICE(producer);
    }
    return 0;
}
<commit_msg>Fix crash in transitions because of missing progressive flag, fix indent<commit_after>// Copyright (c) 2010 Hewlett-Packard Development Company, L.P. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

extern "C" {
    #include <mlt/framework/mlt_producer.h>
    #include <mlt/framework/mlt_frame.h>
}
#include <webvfx/image.h>
#include "factory.h"
#include "service_locker.h"
#include "service_manager.h"

static const char* kWebVfxProducerPropertyName = "WebVfxProducer";
static const char* kWebVfxPositionPropertyName = "webvfx.position";

static int producerGetImage(mlt_frame frame, uint8_t **buffer, mlt_image_format *format, int *width, int *height, int /*writable*/) {
    int error = 0;
    mlt_properties properties = MLT_FRAME_PROPERTIES(frame);
    mlt_producer producer = (mlt_producer)mlt_properties_get_data(properties, kWebVfxProducerPropertyName, NULL);
    mlt_properties producer_props = MLT_PRODUCER_PROPERTIES(producer);
    int size;
    int bpp;
    bool hasTransparency = false;
    {
        MLTWebVfx::ServiceLocker locker(MLT_PRODUCER_SERVICE(producer));
        if (!locker.initialize(*width, *height))
        return 1;

        if (mlt_properties_get_int( producer_props, "transparent") ) {
            *format = mlt_image_rgb24a;
            hasTransparency = true;
        }
        else {
            *format = mlt_image_rgb24;
        }
        // Get bpp from image format
        mlt_image_format_size(*format, 0, 0, &bpp);
        size = *width * *height * bpp;
        *buffer = (uint8_t*)mlt_pool_alloc(size);

        // When not using transparency, this will make the background black...
        memset( *buffer, 255, size );
        WebVfx::Image outputImage(*buffer, *width, *height, size, hasTransparency);
        locker.getManager()->render(&outputImage,
                                    mlt_properties_get_position(properties, kWebVfxPositionPropertyName),
                                    mlt_producer_get_length(producer), hasTransparency);
    }
    mlt_frame_set_image(frame, *buffer, size, mlt_pool_release);
    if (hasTransparency) {
        // Create the alpha channel
        int alpha_size = *width * *height;
        uint8_t *alpha = (uint8_t *)mlt_pool_alloc( alpha_size );
        // Initialise the alpha
        memset( alpha, 255, alpha_size );
        mlt_frame_set_alpha(frame, alpha, alpha_size, mlt_pool_release);
    }

    mlt_properties_set_int(properties, "meta.media.width", *width);
    mlt_properties_set_int(properties, "meta.media.height", *height);
    return error;
}

static int getFrame(mlt_producer producer, mlt_frame_ptr frame, int /*index*/) {
    // Generate a frame
    *frame = mlt_frame_init(MLT_PRODUCER_SERVICE(producer));

    if (*frame) {
        // Obtain properties of frame and producer
        mlt_properties properties = MLT_FRAME_PROPERTIES(*frame);

        // Set the producer on the frame properties
        mlt_properties_set_data(properties, kWebVfxProducerPropertyName, producer, 0, NULL, NULL);

        // Update timecode on the frame we're creating
        mlt_position position = mlt_producer_position(producer);
        mlt_frame_set_position(*frame, position);
        mlt_properties_set_position(properties, kWebVfxPositionPropertyName, position);

        // Set producer-specific frame properties
        mlt_properties_set_int(properties, "progressive", 1);

        // Push the get_image method
        mlt_frame_push_get_image(*frame, producerGetImage);
    }

    // Calculate the next timecode
    mlt_producer_prepare_next(producer);

    return 0;
}

static void producer_close( mlt_producer parent )
{
    // Close the parent
    parent->close = NULL;
    mlt_producer_close( parent );
    // Free the memory
    free( parent );
}

mlt_service MLTWebVfx::createProducer(mlt_profile profile) {
    mlt_producer producer = mlt_producer_new(profile);
    if (producer) {
        producer->get_frame = getFrame;
        producer->close = (mlt_destructor) producer_close;
        mlt_properties properties = MLT_PRODUCER_PROPERTIES( producer );
        mlt_properties_set_int( properties, "meta.media.progressive", 1 );
        mlt_properties_set_int( properties, "meta.media.sample_aspect_num", 1 );
        mlt_properties_set_int( properties, "meta.media.sample_aspect_den", 1 );
        return MLT_PRODUCER_SERVICE(producer);
    }
    return 0;
}
<|endoftext|>


<commit_before>#pragma once

#include <eosio/trace_api/common.hpp>
#include <eosio/trace_api/trace.hpp>
#include <eosio/trace_api/extract_util.hpp>
#include <exception>
#include <functional>
#include <map>

namespace eosio { namespace trace_api {

using chain::transaction_id_type;
using chain::packed_transaction;

template <typename StoreProvider>
class chain_extraction_impl_type {
public:
   /**
    * Chain Extractor for capturing transaction traces, action traces, and block info.
    * @param store provider of append & append_lib
    * @param except_handler called on exceptions, logging if any is left to the user
    */
   chain_extraction_impl_type( StoreProvider store, exception_handler except_handler )
   : store(std::move(store))
   , except_handler(std::move(except_handler))
   {}

   /// connect to chain controller applied_transaction signal
   void signal_applied_transaction( const chain::transaction_trace_ptr& trace, const chain::packed_transaction_ptr& ptrx ) {
      on_applied_transaction( trace, ptrx );
   }

   /// connect to chain controller accepted_block signal
   void signal_accepted_block( const chain::block_state_ptr& bsp ) {
      on_accepted_block( bsp );
   }

   /// connect to chain controller irreversible_block signal
   void signal_irreversible_block( const chain::block_state_ptr& bsp ) {
      on_irreversible_block( bsp );
   }

private:
   static bool is_onblock(const chain::transaction_trace_ptr& p) {
      if (p->action_traces.empty())
         return false;
      const auto& act = p->action_traces[0].act;
      if (act.account != eosio::chain::config::system_account_name || act.name != N(onblock) ||
          act.authorization.size() != 1)
         return false;
      const auto& auth = act.authorization[0];
      return auth.actor == eosio::chain::config::system_account_name &&
             auth.permission == eosio::chain::config::active_name;
   }

   void on_applied_transaction(const chain::transaction_trace_ptr& trace, const chain::packed_transaction_ptr& t) {
      if( !trace->receipt ) return;
      // include only executed transactions; soft_fail included so that onerror (and any inlines via onerror) are included
      if((trace->receipt->status != chain::transaction_receipt_header::executed &&
          trace->receipt->status != chain::transaction_receipt_header::soft_fail)) {
         return;
      }
      if( is_onblock( trace )) {
         onblock_trace.emplace( cache_trace{trace, t} );
      } else if( trace->failed_dtrx_trace ) {
         cached_traces[trace->failed_dtrx_trace->id] = {trace, t};
      } else {
         cached_traces[trace->id] = {trace, t};
      }
   }

   void on_accepted_block(const chain::block_state_ptr& block_state) {
      store_block_trace( block_state );
   }

   void on_irreversible_block( const chain::block_state_ptr& block_state ) {
      store_lib( block_state );
   }

   void store_block_trace( const chain::block_state_ptr& block_state ) {
      try {
         block_trace_v1 bt = create_block_trace_v1( block_state );

         std::vector<transaction_trace_v1>& traces = bt.transactions_v1;
         traces.reserve( block_state->block->transactions.size() + 1 );
         if( onblock_trace )
            traces.emplace_back( to_transaction_trace_v1( {*onblock_trace} ));
         for( const auto& r : block_state->block->transactions ) {
            transaction_id_type id;
            if( r.trx.contains<transaction_id_type>()) {
               id = r.trx.get<transaction_id_type>();
            } else {
               id = r.trx.get<packed_transaction>().id();
            }
            const auto it = cached_traces.find( id );
            if( it != cached_traces.end() ) {
               traces.emplace_back( to_transaction_trace_v1( it->second ));
            }
         }
         cached_traces.clear();
         onblock_trace.reset();

         store.append( std::move( bt ) );

      } catch( ... ) {
         except_handler( MAKE_EXCEPTION_WITH_CONTEXT( std::current_exception() ) );
      }
   }

   void store_lib( const chain::block_state_ptr& bsp ) {
      try {
         store.append_lib( bsp->block_num );
      } catch( ... ) {
         except_handler( MAKE_EXCEPTION_WITH_CONTEXT( std::current_exception() ) );
      }
   }

private:
   StoreProvider                                                store;
   exception_handler                                            except_handler;
   std::map<transaction_id_type, cache_trace>                   cached_traces;
   fc::optional<cache_trace>                                    onblock_trace;

};

}}<commit_msg>Remove unneded {}<commit_after>#pragma once

#include <eosio/trace_api/common.hpp>
#include <eosio/trace_api/trace.hpp>
#include <eosio/trace_api/extract_util.hpp>
#include <exception>
#include <functional>
#include <map>

namespace eosio { namespace trace_api {

using chain::transaction_id_type;
using chain::packed_transaction;

template <typename StoreProvider>
class chain_extraction_impl_type {
public:
   /**
    * Chain Extractor for capturing transaction traces, action traces, and block info.
    * @param store provider of append & append_lib
    * @param except_handler called on exceptions, logging if any is left to the user
    */
   chain_extraction_impl_type( StoreProvider store, exception_handler except_handler )
   : store(std::move(store))
   , except_handler(std::move(except_handler))
   {}

   /// connect to chain controller applied_transaction signal
   void signal_applied_transaction( const chain::transaction_trace_ptr& trace, const chain::packed_transaction_ptr& ptrx ) {
      on_applied_transaction( trace, ptrx );
   }

   /// connect to chain controller accepted_block signal
   void signal_accepted_block( const chain::block_state_ptr& bsp ) {
      on_accepted_block( bsp );
   }

   /// connect to chain controller irreversible_block signal
   void signal_irreversible_block( const chain::block_state_ptr& bsp ) {
      on_irreversible_block( bsp );
   }

private:
   static bool is_onblock(const chain::transaction_trace_ptr& p) {
      if (p->action_traces.empty())
         return false;
      const auto& act = p->action_traces[0].act;
      if (act.account != eosio::chain::config::system_account_name || act.name != N(onblock) ||
          act.authorization.size() != 1)
         return false;
      const auto& auth = act.authorization[0];
      return auth.actor == eosio::chain::config::system_account_name &&
             auth.permission == eosio::chain::config::active_name;
   }

   void on_applied_transaction(const chain::transaction_trace_ptr& trace, const chain::packed_transaction_ptr& t) {
      if( !trace->receipt ) return;
      // include only executed transactions; soft_fail included so that onerror (and any inlines via onerror) are included
      if((trace->receipt->status != chain::transaction_receipt_header::executed &&
          trace->receipt->status != chain::transaction_receipt_header::soft_fail)) {
         return;
      }
      if( is_onblock( trace )) {
         onblock_trace.emplace( cache_trace{trace, t} );
      } else if( trace->failed_dtrx_trace ) {
         cached_traces[trace->failed_dtrx_trace->id] = {trace, t};
      } else {
         cached_traces[trace->id] = {trace, t};
      }
   }

   void on_accepted_block(const chain::block_state_ptr& block_state) {
      store_block_trace( block_state );
   }

   void on_irreversible_block( const chain::block_state_ptr& block_state ) {
      store_lib( block_state );
   }

   void store_block_trace( const chain::block_state_ptr& block_state ) {
      try {
         block_trace_v1 bt = create_block_trace_v1( block_state );

         std::vector<transaction_trace_v1>& traces = bt.transactions_v1;
         traces.reserve( block_state->block->transactions.size() + 1 );
         if( onblock_trace )
            traces.emplace_back( to_transaction_trace_v1( *onblock_trace ));
         for( const auto& r : block_state->block->transactions ) {
            transaction_id_type id;
            if( r.trx.contains<transaction_id_type>()) {
               id = r.trx.get<transaction_id_type>();
            } else {
               id = r.trx.get<packed_transaction>().id();
            }
            const auto it = cached_traces.find( id );
            if( it != cached_traces.end() ) {
               traces.emplace_back( to_transaction_trace_v1( it->second ));
            }
         }
         cached_traces.clear();
         onblock_trace.reset();

         store.append( std::move( bt ) );

      } catch( ... ) {
         except_handler( MAKE_EXCEPTION_WITH_CONTEXT( std::current_exception() ) );
      }
   }

   void store_lib( const chain::block_state_ptr& bsp ) {
      try {
         store.append_lib( bsp->block_num );
      } catch( ... ) {
         except_handler( MAKE_EXCEPTION_WITH_CONTEXT( std::current_exception() ) );
      }
   }

private:
   StoreProvider                                                store;
   exception_handler                                            except_handler;
   std::map<transaction_id_type, cache_trace>                   cached_traces;
   fc::optional<cache_trace>                                    onblock_trace;

};

}}<|endoftext|>


<commit_before>#include "getusername.h"
#include <errno.h>
#include <langinfo.h>
#include <locale.h>
#include <unistd.h>
#include <string>

using namespace std;

const string utf8 = "UTF-8";

// https://msdn.microsoft.com/en-us/library/windows/desktop/ms724432(v=vs.85).aspx
// Sets errno to:
//     ERROR_INVALID_PARAMETER - parameter is not valid
//     ERROR_BAD_ENVIRONMENT - locale is not UTF-8
//     ERROR_TOO_MANY_OPEN_FILES - already have the maximum allowed number of open files
//     ERROR_NO_ASSOCIATION - calling process has no controlling terminal
//     ERROR_INSUFFICIENT_BUFFER - buffer not large enough to hold username string
//     ERROR_NO_SUCH_USER - there was no corresponding entry in the utmp-file
//     ERROR_OUTOFMEMORY - insufficient memory to allocate passwd structure
//     ERROR_NO_ASSOCIATION - standard input didn't refer to a terminal
//     ERROR_INVALID_FUNCTION - getlogin_r() returned an unrecognized error code
//
// Returns:
//     1 - succeeded
//     0 - failed
BOOL GetUserName(WCHAR_T *lpBuffer, LPDWORD lpnSize)
{
	errno = 0;

	// Check parameters
	if (!lpBuffer || !lpnSize) {
		errno = ERROR_INVALID_PARAMETER;
		return 0;
	}

	// Select locale from environment
	setlocale(LC_ALL, "");
	// Check that locale is UTF-8
	if (nl_langinfo(CODESET) != utf8) {
		errno = ERROR_BAD_ENVIRONMENT;
		return 0;
	}

	// Get username from system in a thread-safe manner
	char userName[*lpnSize];
	int err = getlogin_r(userName, *lpnSize);
	// Map errno to Win32 Error Codes
	if (err != 0) {
		switch (errno) {
		case EMFILE:
		case ENFILE:
			errno = ERROR_TOO_MANY_OPEN_FILES;
			break;
		case ENXIO:
			errno = ERROR_NO_ASSOCIATION;
			break;
		case ERANGE:
			errno = ERROR_INSUFFICIENT_BUFFER;
			break;
		case ENOENT:
			errno = ERROR_NO_SUCH_USER;
			break;
		case ENOMEM:
			errno = ERROR_OUTOFMEMORY;
			break;
		case ENOTTY:
			errno = ERROR_NO_ASSOCIATION;
			break;
		default:
			errno = ERROR_INVALID_FUNCTION;
		}
		return 0;
	}

	// TODO: Convert to char* to wchar* (UTF-8 to UTF-16 LE w/o BOM)

	// Unfortunately codecvt is not yet supported by G++, othwerise:
	// wstring_convert<std::codecvt_utf8_utf16<char16_t>,char16_t> conversion;

	// TODO: Use PAL's Unicode converters

	// TODO: set the lpnSize to the userName length (see msdn)

	return 1;
}

<commit_msg>Convert get_login_r to UTF-16 and return<commit_after>#include "getusername.h"
#include <errno.h>
#include <langinfo.h>
#include <locale.h>
#include <unistd.h>
#include <string>
#include <vector>
#include <scxcorelib/scxstrencodingconv.h>

using std::string;
using std::vector;

using SCXCoreLib::Utf8ToUtf16le;

const string utf8 = "UTF-8";

// https://msdn.microsoft.com/en-us/library/windows/desktop/ms724432(v=vs.85).aspx
// Sets errno to:
//     ERROR_INVALID_PARAMETER - parameter is not valid
//     ERROR_BAD_ENVIRONMENT - locale is not UTF-8
//     ERROR_TOO_MANY_OPEN_FILES - already have the maximum allowed number of open files
//     ERROR_NO_ASSOCIATION - calling process has no controlling terminal
//     ERROR_INSUFFICIENT_BUFFER - buffer not large enough to hold username string
//     ERROR_NO_SUCH_USER - there was no corresponding entry in the utmp-file
//     ERROR_OUTOFMEMORY - insufficient memory to allocate passwd structure
//     ERROR_NO_ASSOCIATION - standard input didn't refer to a terminal
//     ERROR_INVALID_FUNCTION - getlogin_r() returned an unrecognized error code
//
// Returns:
//     1 - succeeded
//     0 - failed
BOOL GetUserName(WCHAR_T *lpBuffer, LPDWORD lpnSize)
{
	errno = 0;

	// Check parameters
	if (!lpBuffer || !lpnSize) {
		errno = ERROR_INVALID_PARAMETER;
		return 0;
	}

	// Select locale from environment
	setlocale(LC_ALL, "");
	// Check that locale is UTF-8
	if (nl_langinfo(CODESET) != utf8) {
		errno = ERROR_BAD_ENVIRONMENT;
		return 0;
	}

	// Get username from system in a thread-safe manner
	char userName[*lpnSize];
	int err = getlogin_r(userName, *lpnSize);
	// Map errno to Win32 Error Codes
	if (err != 0) {
		switch (errno) {
		case EMFILE:
		case ENFILE:
			errno = ERROR_TOO_MANY_OPEN_FILES;
			break;
		case ENXIO:
			errno = ERROR_NO_ASSOCIATION;
			break;
		case ERANGE:
			errno = ERROR_INSUFFICIENT_BUFFER;
			break;
		case ENOENT:
			errno = ERROR_NO_SUCH_USER;
			break;
		case ENOMEM:
			errno = ERROR_OUTOFMEMORY;
			break;
		case ENOTTY:
			errno = ERROR_NO_ASSOCIATION;
			break;
		default:
			errno = ERROR_INVALID_FUNCTION;
		}
		return 0;
	}

	// Convert to char * to WCHAR_T * (UTF-8 to UTF-16 LE w/o BOM)
	string input = string(userName);
	vector<unsigned char> output;
	Utf8ToUtf16le(input, output);

	if (output.size()/2 + 1 > *lpnSize) {
		errno = ERROR_INSUFFICIENT_BUFFER;
		return 0;
	}

	// Add two null bytes (because it's UTF-16)
	output.push_back('\0');
	output.push_back('\0');

	memcpy(lpBuffer, &output[0], output.size());
	*lpnSize = output.size()/2;

	return 1;
}
<|endoftext|>


<commit_before>#include "qfiletrans.h"
#include "session.h"
#include "utils/qapparg.h"

#include <QBuffer>
#include <QXmppUtils.h>
#include <QTextCodec>
#include <QSettings>

#include <QFile>

QFileTrans::QFileTrans(QObject *parent):QXmppClient(parent),transferManager(0)
{
    bool check;
    Q_UNUSED(check);

    // add transfer manager
    transferManager = new QXmppTransferManager();
    addExtension(transferManager);
    transferManager->setSupportedMethods(QXmppTransferJob::SocksMethod);
    transferManager->setSupportedMethods(QXmppTransferJob::InBandMethod);

}
void QFileTrans::setRecipient(const QString &recipient)
{
    m_recipient = recipient;
}

/// A file transfer failed.

void QFileTrans::slotError(QXmppTransferJob::Error error)
{
    qDebug() << "Transmission failed:" << error;
}

/// A file transfer request was received.

void QFileTrans::slotFileReceived(QXmppTransferJob *job)
{

}

/// A file transfer finished.

void QFileTrans::slotFinished()
{
    qDebug() << "Transmission finished";
}

/// A presence was received

void QFileTrans::slotPresenceReceived(const QXmppPresence &presence)
{
    bool check;
    Q_UNUSED(check);

    // if we don't have a recipient, or if the presence is not from the recipient,
    // do nothing
    if (m_recipient.isEmpty() ||
        QXmppUtils::jidToBareJid(presence.from()) != m_recipient ||
        presence.type() != QXmppPresence::Available)
        return;

    // send the file and connect to the job's signals
    QXmppTransferJob *job = transferManager->sendFile(presence.from(), ":/example_3_transferHandling.cpp", "example source code");

    check = connect(job, SIGNAL(error(QXmppTransferJob::Error)),
                    this, SLOT(slotError(QXmppTransferJob::Error)));
    Q_ASSERT(check);

    check = connect(job, SIGNAL(finished()),
                    this, SLOT(slotFinished()));
    Q_ASSERT(check);

    check = connect(job, SIGNAL(progress(qint64,qint64)),
                    this, SLOT(slotProgress(qint64,qint64)));
    Q_ASSERT(check);
}

/// A file transfer has made progress.

void QFileTrans::slotProgress(qint64 done, qint64 total)
{
    qDebug() << "Transmission progress:" << done << "/" << total;
}
QXmppTransferJob  * QFileTrans::sendFile(const QString recipient, const QString file)
{
    bool check;
    Q_UNUSED(check);
    QXmppTransferJob *job = transferManager->sendFile(recipient, file, "");
    return job;
}
void QFileTrans::login(QString usr, QString pwd, QString domain, QString host,LoginType type)
{
    QString jid;
    QFile logf("log.txt");
    logf.open(QIODevice::Append);

    jid = usr + tr("@") + domain + "/safe";
    logf.write(jid.toLocal8Bit());
    logf.write("\r\n");
    logf.write(domain.toLocal8Bit());
    logf.write("\r\n");
    logf.write(host.toLocal8Bit());
    logf.write("\r\n");

    logf.close();
    if ( type == CA)
    {

         pwd = usr + ":" + pwd;
    }
    Session::Instance()->setJID(jid);
    logger()->setLoggingType(QXmppLogger::StdoutLogging);
    configuration().setDomain(domain);
    configuration().setHost(host);
    configuration().setJid(jid);
    configuration().setPassword(pwd);
    configuration().setPort(5222);

    configuration().setStreamSecurityMode(QXmppConfiguration::TLSDisabled);
    connectToServer( configuration() );
    Session::Instance()->setJID(jid);
    Session::Instance()->SetPassWord(pwd);
    QSettings   set;
    set.setValue("usr",usr);
    set.setValue("pwd",pwd);
    set.setValue("domain",domain);
    set.setValue("svr",host);
    set.setValue("xmpp_jid",jid);
    set.setValue("xmpp_pwd",pwd);

    QAppArg::ref().argCount() = 5;
    QAppArg::ref().argList().clear();
    QAppArg::ref().argList()<<usr<<pwd<<domain<<host;
}

void QFileTrans::qxmpp_sendMessage(QString to, QString msg)
{
    sendMessage(to,msg);
}
void QFileTrans::qxmpp_sendData(QString data)
{
    sendData(data.toLocal8Bit());
}
<commit_msg>SASL To Plain<commit_after>#include "qfiletrans.h"
#include "session.h"
#include "utils/qapparg.h"

#include <QBuffer>
#include <QXmppUtils.h>
#include <QTextCodec>
#include <QSettings>

#include <QFile>

QFileTrans::QFileTrans(QObject *parent):QXmppClient(parent),transferManager(0)
{
    bool check;
    Q_UNUSED(check);

    // add transfer manager
    transferManager = new QXmppTransferManager();
    addExtension(transferManager);
    transferManager->setSupportedMethods(QXmppTransferJob::SocksMethod);
    transferManager->setSupportedMethods(QXmppTransferJob::InBandMethod);

}
void QFileTrans::setRecipient(const QString &recipient)
{
    m_recipient = recipient;
}

/// A file transfer failed.

void QFileTrans::slotError(QXmppTransferJob::Error error)
{
    qDebug() << "Transmission failed:" << error;
}

/// A file transfer request was received.

void QFileTrans::slotFileReceived(QXmppTransferJob *job)
{

}

/// A file transfer finished.

void QFileTrans::slotFinished()
{
    qDebug() << "Transmission finished";
}

/// A presence was received

void QFileTrans::slotPresenceReceived(const QXmppPresence &presence)
{
    bool check;
    Q_UNUSED(check);

    // if we don't have a recipient, or if the presence is not from the recipient,
    // do nothing
    if (m_recipient.isEmpty() ||
        QXmppUtils::jidToBareJid(presence.from()) != m_recipient ||
        presence.type() != QXmppPresence::Available)
        return;

    // send the file and connect to the job's signals
    QXmppTransferJob *job = transferManager->sendFile(presence.from(), ":/example_3_transferHandling.cpp", "example source code");

    check = connect(job, SIGNAL(error(QXmppTransferJob::Error)),
                    this, SLOT(slotError(QXmppTransferJob::Error)));
    Q_ASSERT(check);

    check = connect(job, SIGNAL(finished()),
                    this, SLOT(slotFinished()));
    Q_ASSERT(check);

    check = connect(job, SIGNAL(progress(qint64,qint64)),
                    this, SLOT(slotProgress(qint64,qint64)));
    Q_ASSERT(check);
}

/// A file transfer has made progress.

void QFileTrans::slotProgress(qint64 done, qint64 total)
{
    qDebug() << "Transmission progress:" << done << "/" << total;
}
QXmppTransferJob  * QFileTrans::sendFile(const QString recipient, const QString file)
{
    bool check;
    Q_UNUSED(check);
    QXmppTransferJob *job = transferManager->sendFile(recipient, file, "");
    return job;
}
void QFileTrans::login(QString usr, QString pwd, QString domain, QString host,LoginType type)
{
    QString jid;
    QFile logf("log.txt");
    logf.open(QIODevice::Append);

    jid = usr + tr("@") + domain + "/safe";
    logf.write(jid.toLocal8Bit());
    logf.write("\r\n");
    logf.write(domain.toLocal8Bit());
    logf.write("\r\n");
    logf.write(host.toLocal8Bit());
    logf.write("\r\n");

    logf.close();
    if ( type == CA)
    {

         pwd = usr + ":" + pwd;
    }
    Session::Instance()->setJID(jid);
//    logger()->setLoggingType(QXmppLogger::StdoutLogging);
    configuration().setDomain(domain);
    configuration().setHost(host);
    configuration().setJid(jid);
    configuration().setPassword(pwd);
    configuration().setPort(5222);

    configuration().setSaslAuthMechanism("PLAIN");
    configuration().setStreamSecurityMode(QXmppConfiguration::TLSDisabled);
    connectToServer( configuration() );
    Session::Instance()->setJID(jid);
    Session::Instance()->SetPassWord(pwd);
    QSettings   set;
    set.setValue("usr",usr);
    set.setValue("pwd",pwd);
    set.setValue("domain",domain);
    set.setValue("svr",host);
    set.setValue("xmpp_jid",jid);
    set.setValue("xmpp_pwd",pwd);

    QAppArg::ref().argCount() = 5;
    QAppArg::ref().argList().clear();
    QAppArg::ref().argList()<<usr<<pwd<<domain<<host;
}

void QFileTrans::qxmpp_sendMessage(QString to, QString msg)
{
    sendMessage(to,msg);
}
void QFileTrans::qxmpp_sendData(QString data)
{
    sendData(data.toLocal8Bit());
}
<|endoftext|>


<commit_before>//
// RowVector/instance_method_get.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2014 Rick Yang (rick68 at gmail dot 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/.
//

#ifndef EIGENJS_ROWVECTOR_INSTANCE_METHOD_GET_HPP
#define EIGENJS_ROWVECTOR_INSTANCE_METHOD_GET_HPP

namespace EigenJS {

EIGENJS_INSTANCE_METHOD(RowVector, get,
{
  NanScope();

  if (args.Length() == 1 &&
      args[0]->IsNumber()
  ) {
    const RowVector* const& obj =
        node::ObjectWrap::Unwrap<RowVector>(args.This());
    const typename RowVector::value_type& rowvector = **obj;
    const typename RowVector::value_type::Index& col = args[0]->Int32Value();

    if (RowVector::is_out_of_range(rowvector, col, 0)) {
      NanReturnUndefined();
    }

    const typename RowVector::scalar_type& value = rowvector(0, col);
    NanReturnValue(NanNew(value));
  }

  EIGENJS_THROW_ERROR_INVALID_ARGUMENT()
  NanReturnUndefined();
})

}  // namespace EigenJS

#endif  // EIGENJS_ROWVECTOR_INSTANCE_METHOD_GET_HPP
<commit_msg>src: fixed a mistake<commit_after>//
// RowVector/instance_method_get.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2014 Rick Yang (rick68 at gmail dot 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/.
//

#ifndef EIGENJS_ROWVECTOR_INSTANCE_METHOD_GET_HPP
#define EIGENJS_ROWVECTOR_INSTANCE_METHOD_GET_HPP

namespace EigenJS {

EIGENJS_INSTANCE_METHOD(RowVector, get,
{
  NanScope();

  if (args.Length() == 1 &&
      args[0]->IsNumber()
  ) {
    const RowVector* const& obj =
        node::ObjectWrap::Unwrap<RowVector>(args.This());
    const typename RowVector::value_type& rowvector = **obj;
    const typename RowVector::value_type::Index& col = args[0]->Int32Value();

    if (RowVector::is_out_of_range(rowvector, 0, col)) {
      NanReturnUndefined();
    }

    const typename RowVector::scalar_type& value = rowvector(0, col);
    NanReturnValue(NanNew(value));
  }

  EIGENJS_THROW_ERROR_INVALID_ARGUMENT()
  NanReturnUndefined();
})

}  // namespace EigenJS

#endif  // EIGENJS_ROWVECTOR_INSTANCE_METHOD_GET_HPP
<|endoftext|>


<commit_before>

#include "Scheduler_node.hpp"

#include <Eigen/Dense>
#include <exception>
#include <iostream>
#include <map>
#include <node.h>
#include <pthread.h>
#include <queue>
#include <stdio.h>
#include <uv.h>
#include <v8.h>

#include "../../Algorithms/ProximalGradientDescent.hpp"
#include "../../Algorithms/IterativeUpdate.hpp"
#include "../../Algorithms/Algorithm.hpp"
#include "../../Algorithms/AlgorithmOptions.hpp"
#include "../../Algorithms/HypoTestPlaceHolder.h"
#include "../../Models/ModelOptions.hpp"
#include "../Job.hpp"
#include "../Scheduler.hpp"
#include "../../JSON/JsonCoder.hpp"

using namespace Eigen;
using namespace std;
using namespace v8;

// Sets the X matrix of a given model.
// Arguments: job_id, JSON matrix
void setX(const FunctionCallbackInfo<Value>& args) {
	bool result = false;
	Isolate* isolate = args.GetIsolate();
	if (ArgsHaveJobID(args, 0)) {
		const int job_id = (int)Local<Number>::Cast(args[0])->Value();
		Local<v8::Array> ar = Local<v8::Array>::Cast(args[1]);
		MatrixXd* mat = v8toEigen(ar);
		result = Scheduler::Instance()->setX(job_id, *mat);
	}
	args.GetReturnValue().Set(Boolean::New(isolate, result));
}

// Sets the Y matrix of a given model.
// Arguments: job_id, JSON matrix
void setY(const FunctionCallbackInfo<Value>& args) {
	bool result = false;
	Isolate* isolate = args.GetIsolate();
	if (ArgsHaveJobID(args, 0)) {
		const int job_id = (int)Local<Number>::Cast(args[0])->Value();
		Local<v8::Array> ar = Local<v8::Array>::Cast(args[1]);
		MatrixXd* mat = v8toEigen(ar);
		result = Scheduler::Instance()->setY(job_id, *mat);
	}
	args.GetReturnValue().Set(Boolean::New(isolate, result));
}

// Arguments: job_id, string of attribute name, matrix to use
void setModelAttributeMatrix(const FunctionCallbackInfo<Value>& args) {
	bool result = false;
	Isolate* isolate = args.GetIsolate();
	if (ArgsHaveJobID(args, 0)) {
		const int job_id = (int)Local<Number>::Cast(args[0])->Value();
		const string attribute_name(*v8::String::Utf8Value(args[1]->ToString()));
		Local<v8::Array> ar = Local<v8::Array>::Cast(args[2]);
		MatrixXd* mat = v8toEigen(ar);
		result = Scheduler::Instance()->setModelAttributeMatrix(job_id, attribute_name, mat);
	}
	args.GetReturnValue().Set(Boolean::New(isolate, result));
}

// Creates a new job, but does not run it. Synchronous.
// Arguments: JSON to be converted to JobOptions_t
void newJob(const v8::FunctionCallbackInfo<v8::Value>& args) {
	Isolate* isolate = args.GetIsolate();
	Handle<Object> options_v8 = Handle<Object>::Cast(args[0]);
	const JobOptions_t& options = JobOptions_t(isolate, options_v8);
	try {
		const int id = Scheduler::Instance()->newJob(options);
		if (id < 0) {
			isolate->ThrowException(Exception::Error(
				String::NewFromUtf8(isolate, "Could not add another job")));
			return;
		}

		Local<Integer> retval = Integer::New(isolate, id);
		args.GetReturnValue().Set(retval);
	} catch (const exception& e) {
		isolate->ThrowException(Exception::Error(
			String::NewFromUtf8(isolate, e.what())));
		return;
	}
}

// Maybe begins the training of an algorithm, given the job number.
// Asynchronous.
// Arguments: int job_id, function callback
void startJob(const v8::FunctionCallbackInfo<v8::Value>& args) {
	Isolate* isolate = args.GetIsolate();
	// Inspect arguments.
	try {
		if (!ArgsHaveJobID(args, 0)) {
			args.GetReturnValue().Set(Boolean::New(isolate, false));
			return;
		}

		const int job_id = (int)Local<Number>::Cast(args[0])->Value();
		Job_t* job = Scheduler::Instance()->getJob(job_id);
		job->exception = nullptr;
		job->callback.Reset(isolate, Local<Function>::Cast(args[1]));
		job->job_id = job_id;
		bool result = Scheduler::Instance()->startJob(job_id, trainAlgorithmComplete);
		usleep(1);	// let the execution thread start -- necessary?
		if (job->exception) {
			rethrow_exception(job->exception);
		}
		args.GetReturnValue().Set(Boolean::New(isolate, result));
	} catch (const exception& e) {
		isolate->ThrowException(Exception::Error(
			String::NewFromUtf8(isolate, e.what())));
		args.GetReturnValue().Set(Boolean::New(isolate, false));
	}
}

// Checks the status of an algorithm, given the algorithm's job number.
// Currently synchronous.
// Arguments: int job_id
void checkJob(const v8::FunctionCallbackInfo<v8::Value>& args) {
	Isolate* isolate = args.GetIsolate();

	// Check argument types.
	if (!ArgsHaveJobID(args, 0)) {
		args.GetReturnValue().Set(Boolean::New(isolate, false));
		return;
	}

	int job_id = (int)Local<Number>::Cast(args[0])->Value();
	const double progress = Scheduler::Instance()->checkJobProgress(job_id);
	Local<Number> retval = Number::New(isolate, progress);
	args.GetReturnValue().Set(retval);
}

// Gets the results of a job, given the job's id.
// Synchronous.
// Arguments: int job_id
// Returns: MatrixXd of results, empty on error.
void getJobResult(const v8::FunctionCallbackInfo<v8::Value>& args) {
	Isolate* isolate = args.GetIsolate();
	try {
		// Check argument types.
		if (!ArgsHaveJobID(args, 0)) {
			args.GetReturnValue().Set(Boolean::New(isolate, false));
			return;
		}

		int job_id = (int)Local<Number>::Cast(args[0])->Value();
		const MatrixXd& result = Scheduler::Instance()->getJobResult(job_id);
		Local<v8::Array> obj = v8::Array::New(isolate);
		// TODO: Fewer convserions to return a matrix [Issue: https://github.com/blengerich/GenAMap_V2/issues/17]
		obj->Set(0, v8::String::NewFromUtf8(isolate, JsonCoder::getInstance().encodeMatrix(result).c_str()));
		args.GetReturnValue().Set(obj);
	}
	catch (const exception& e) {
		isolate->ThrowException(Exception::Error(
			String::NewFromUtf8(isolate, e.what())));
	}
}

// Cancels a potentially running Algorithm.
// Synchronous.
// Arguments: int job_id
// Returns: boolean representing success.
void cancelJob(const v8::FunctionCallbackInfo<v8::Value>& args) {
	Isolate* isolate = args.GetIsolate();

	// Check argument types.
	if (!ArgsHaveJobID(args, 0)) {
		args.GetReturnValue().Set(Boolean::New(isolate, false));
		return;
	}
	try {
		const int job_id = (int)Local<Integer>::Cast(args[0])->Value();
		const bool success = Scheduler::Instance()->cancelJob(job_id);
		Handle<Boolean> retval = Boolean::New(isolate, success);
		args.GetReturnValue().Set(retval);
	} catch(const exception& e) {
		isolate->ThrowException(Exception::Error(
			String::NewFromUtf8(isolate, e.what())));
	}
}

// Arguments: job_id
void deleteJob(const v8::FunctionCallbackInfo<v8::Value>& args) {
	Isolate* isolate = args.GetIsolate();

	if (!ArgsHaveJobID(args, 0)) {
		args.GetReturnValue().Set(Boolean::New(isolate, false));
		return;
	}

	const int job_id = (int)Local<Integer>::Cast(args[0])->Value();
	const bool success = Scheduler::Instance()->deleteJob(job_id);
	Handle<Boolean> retval = Boolean::New(isolate, success);
	args.GetReturnValue().Set(retval);
}

/////////////////////////////////
// Helper Functions
/////////////////////////////////

// Handles packaging of algorithm results to return to the frontend.
// Called by libuv in event loop when async training completes.
void trainAlgorithmComplete(uv_work_t* req, int status) {
	// Runs in event loop when algorithm completes.
	Isolate* isolate = Isolate::GetCurrent();
	HandleScope handleScope(isolate);
	Job_t* job = static_cast<Job_t*>(req->data);
	Local<v8::Array> obj = v8::Array::New(isolate);

	try {
		// Pack up the data to be returned to JS
		const MatrixXd& result = Scheduler::Instance()->getJobResult(job->job_id);
		// TODO: Fewer convserions to return a matrix [Issue: https://github.com/blengerich/GenAMap_V2/issues/17]
		obj->Set(0, v8::String::NewFromUtf8(isolate, JsonCoder::getInstance().encodeMatrix(result).c_str()));

		if (status < 0) { //libuv error
			throw runtime_error("Libuv error (check server)");
		}
		if (job->exception) {
			rethrow_exception(job->exception);
		}
	} catch(const exception& e) {
		// If the job failed, the second entry in the array is the exception text.
		// Is this really a good way to return data? It is different than the result from getJobResult()
		obj->Set(1, v8::String::NewFromUtf8(isolate, e.what()));
	}

	Handle<Value> argv[] = { obj };
	// execute the callback
	Local<Function>::New(isolate, job->callback)->Call(
		isolate->GetCurrentContext()->Global(), 1, argv);
	job->callback.Reset();
}

MatrixXd* v8toEigen(Local<v8::Array>& ar) {
	const unsigned int rows = ar->Length();
	Local<v8::Array> props = Local<v8::Object>::Cast(ar->Get(0))->GetPropertyNames();
	const unsigned int cols = props->Length();
	Eigen::MatrixXd* mat = new Eigen::MatrixXd(rows, cols);

	for (unsigned int i=0; i<rows; i++) {
		for (unsigned int j=0; j<cols; j++) {
			(*mat)(i,j) = (double)Local<v8::Object>::Cast(ar->Get(i))->Get(props->Get(j))->NumberValue();
		}
	}
	return mat;
}

// Checks that the argument in the supplied position is a number type.
// Doesn't check that it is a valid job ID.
bool ArgsHaveJobID(const FunctionCallbackInfo<Value>& args, const int position) {
	Isolate* isolate = args.GetIsolate();
	if (args.Length() < 1) {
		isolate->ThrowException(Exception::TypeError(
			String::NewFromUtf8(isolate, "Must supply a job id.")));
		args.GetReturnValue().Set(Boolean::New(isolate, false));
		return false;
	}

	if (!(args[0]->IsNumber())) {
		isolate->ThrowException(Exception::TypeError(
			String::NewFromUtf8(isolate, "Job id must be a number.")));
		args.GetReturnValue().Set(Boolean::New(isolate, false));
		return false;
	}

	return true;
}

/* Deprecated - only interacting with jobs now
// Creates a new algorithm, but does not run it. Currently synchronous.
// Arguments: JSON to be converted to AlgorithmOptions_t
void newAlgorithm(const FunctionCallbackInfo<Value>& args) {
	Isolate* isolate = args.GetIsolate();

	if (args.Length() < 1) {
		isolate->ThrowException(Exception::TypeError(
			String::NewFromUtf8(isolate, "Wrong number of arguments")));
		return;
	}

	Handle<Object> options_v8 = Handle<Object>::Cast(args[0]);
	const AlgorithmOptions_t& options = AlgorithmOptions_t(isolate, options_v8);

	const int id = Scheduler::Instance()->newAlgorithm(options);
	if (id < 0) {
		isolate->ThrowException(Exception::Error(
			String::NewFromUtf8(isolate, "Could not add another algorithm.")));
		return;
	}

	Local<Integer> retval = Integer::New(isolate, id);
	args.GetReturnValue().Set(retval);
}

// Creates a new model, but does not run it. Synchronous.
// Arguments: JSON to be converted to ModelOptions_t
void newModel(const FunctionCallbackInfo<Value>& args) {
	Isolate* isolate = args.GetIsolate();
	Handle<Object> options_v8 = Handle<Object>::Cast(args[0]);
	const ModelOptions_t& options = ModelOptions_t(isolate, options_v8);
	const int id = Scheduler::Instance()->newModel(options);
	if (id < 0) {
		isolate->ThrowException(Exception::Error(
			String::NewFromUtf8(isolate, "Could not add another model")));
		return;
	}

	Local<Integer> retval = Integer::New(isolate, id);
	args.GetReturnValue().Set(retval);
}

// Arguments: int alg_id
// Returns: boolean for success
void deleteAlgorithm(const v8::FunctionCallbackInfo<v8::Value>& args) {
	Isolate* isolate = args.GetIsolate();
	const int algorithm_id = (int)Local<Integer>::Cast(args[0])->Value();
	const bool success = Scheduler::Instance()->deleteAlgorithm(algorithm_id);
	Handle<Boolean> retval = Boolean::New(isolate, success);
	args.GetReturnValue().Set(retval);
}

// Arguments: int model_id
void deleteModel(const v8::FunctionCallbackInfo<v8::Value>& args) {
	Isolate* isolate = args.GetIsolate();
	const int model_id = (int)Local<Integer>::Cast(args[0])->Value();
	const bool success = Scheduler::Instance()->deleteModel(model_id);
	Handle<Boolean> retval = Boolean::New(isolate, success);
	args.GetReturnValue().Set(retval);
}

*/
<commit_msg>Remove matrix conversion TODO<commit_after>

#include "Scheduler_node.hpp"

#include <Eigen/Dense>
#include <exception>
#include <iostream>
#include <map>
#include <node.h>
#include <pthread.h>
#include <queue>
#include <stdio.h>
#include <uv.h>
#include <v8.h>

#include "../../Algorithms/ProximalGradientDescent.hpp"
#include "../../Algorithms/IterativeUpdate.hpp"
#include "../../Algorithms/Algorithm.hpp"
#include "../../Algorithms/AlgorithmOptions.hpp"
#include "../../Algorithms/HypoTestPlaceHolder.h"
#include "../../Models/ModelOptions.hpp"
#include "../Job.hpp"
#include "../Scheduler.hpp"
#include "../../JSON/JsonCoder.hpp"

using namespace Eigen;
using namespace std;
using namespace v8;

// Sets the X matrix of a given model.
// Arguments: job_id, JSON matrix
void setX(const FunctionCallbackInfo<Value>& args) {
	bool result = false;
	Isolate* isolate = args.GetIsolate();
	if (ArgsHaveJobID(args, 0)) {
		const int job_id = (int)Local<Number>::Cast(args[0])->Value();
		Local<v8::Array> ar = Local<v8::Array>::Cast(args[1]);
		MatrixXd* mat = v8toEigen(ar);
		result = Scheduler::Instance()->setX(job_id, *mat);
	}
	args.GetReturnValue().Set(Boolean::New(isolate, result));
}

// Sets the Y matrix of a given model.
// Arguments: job_id, JSON matrix
void setY(const FunctionCallbackInfo<Value>& args) {
	bool result = false;
	Isolate* isolate = args.GetIsolate();
	if (ArgsHaveJobID(args, 0)) {
		const int job_id = (int)Local<Number>::Cast(args[0])->Value();
		Local<v8::Array> ar = Local<v8::Array>::Cast(args[1]);
		MatrixXd* mat = v8toEigen(ar);
		result = Scheduler::Instance()->setY(job_id, *mat);
	}
	args.GetReturnValue().Set(Boolean::New(isolate, result));
}

// Arguments: job_id, string of attribute name, matrix to use
void setModelAttributeMatrix(const FunctionCallbackInfo<Value>& args) {
	bool result = false;
	Isolate* isolate = args.GetIsolate();
	if (ArgsHaveJobID(args, 0)) {
		const int job_id = (int)Local<Number>::Cast(args[0])->Value();
		const string attribute_name(*v8::String::Utf8Value(args[1]->ToString()));
		Local<v8::Array> ar = Local<v8::Array>::Cast(args[2]);
		MatrixXd* mat = v8toEigen(ar);
		result = Scheduler::Instance()->setModelAttributeMatrix(job_id, attribute_name, mat);
	}
	args.GetReturnValue().Set(Boolean::New(isolate, result));
}

// Creates a new job, but does not run it. Synchronous.
// Arguments: JSON to be converted to JobOptions_t
void newJob(const v8::FunctionCallbackInfo<v8::Value>& args) {
	Isolate* isolate = args.GetIsolate();
	Handle<Object> options_v8 = Handle<Object>::Cast(args[0]);
	const JobOptions_t& options = JobOptions_t(isolate, options_v8);
	try {
		const int id = Scheduler::Instance()->newJob(options);
		if (id < 0) {
			isolate->ThrowException(Exception::Error(
				String::NewFromUtf8(isolate, "Could not add another job")));
			return;
		}

		Local<Integer> retval = Integer::New(isolate, id);
		args.GetReturnValue().Set(retval);
	} catch (const exception& e) {
		isolate->ThrowException(Exception::Error(
			String::NewFromUtf8(isolate, e.what())));
		return;
	}
}

// Maybe begins the training of an algorithm, given the job number.
// Asynchronous.
// Arguments: int job_id, function callback
void startJob(const v8::FunctionCallbackInfo<v8::Value>& args) {
	Isolate* isolate = args.GetIsolate();
	// Inspect arguments.
	try {
		if (!ArgsHaveJobID(args, 0)) {
			args.GetReturnValue().Set(Boolean::New(isolate, false));
			return;
		}

		const int job_id = (int)Local<Number>::Cast(args[0])->Value();
		Job_t* job = Scheduler::Instance()->getJob(job_id);
		job->exception = nullptr;
		job->callback.Reset(isolate, Local<Function>::Cast(args[1]));
		job->job_id = job_id;
		bool result = Scheduler::Instance()->startJob(job_id, trainAlgorithmComplete);
		usleep(1);	// let the execution thread start -- necessary?
		if (job->exception) {
			rethrow_exception(job->exception);
		}
		args.GetReturnValue().Set(Boolean::New(isolate, result));
	} catch (const exception& e) {
		isolate->ThrowException(Exception::Error(
			String::NewFromUtf8(isolate, e.what())));
		args.GetReturnValue().Set(Boolean::New(isolate, false));
	}
}

// Checks the status of an algorithm, given the algorithm's job number.
// Currently synchronous.
// Arguments: int job_id
void checkJob(const v8::FunctionCallbackInfo<v8::Value>& args) {
	Isolate* isolate = args.GetIsolate();

	// Check argument types.
	if (!ArgsHaveJobID(args, 0)) {
		args.GetReturnValue().Set(Boolean::New(isolate, false));
		return;
	}

	int job_id = (int)Local<Number>::Cast(args[0])->Value();
	const double progress = Scheduler::Instance()->checkJobProgress(job_id);
	Local<Number> retval = Number::New(isolate, progress);
	args.GetReturnValue().Set(retval);
}

// Gets the results of a job, given the job's id.
// Synchronous.
// Arguments: int job_id
// Returns: MatrixXd of results, empty on error.
void getJobResult(const v8::FunctionCallbackInfo<v8::Value>& args) {
	Isolate* isolate = args.GetIsolate();
	try {
		// Check argument types.
		if (!ArgsHaveJobID(args, 0)) {
			args.GetReturnValue().Set(Boolean::New(isolate, false));
			return;
		}

		int job_id = (int)Local<Number>::Cast(args[0])->Value();
		const MatrixXd& result = Scheduler::Instance()->getJobResult(job_id);
		Local<v8::Array> obj = v8::Array::New(isolate);
		obj->Set(0, v8::String::NewFromUtf8(isolate, JsonCoder::getInstance().encodeMatrix(result).c_str()));
		args.GetReturnValue().Set(obj);
	}
	catch (const exception& e) {
		isolate->ThrowException(Exception::Error(
			String::NewFromUtf8(isolate, e.what())));
	}
}

// Cancels a potentially running Algorithm.
// Synchronous.
// Arguments: int job_id
// Returns: boolean representing success.
void cancelJob(const v8::FunctionCallbackInfo<v8::Value>& args) {
	Isolate* isolate = args.GetIsolate();

	// Check argument types.
	if (!ArgsHaveJobID(args, 0)) {
		args.GetReturnValue().Set(Boolean::New(isolate, false));
		return;
	}
	try {
		const int job_id = (int)Local<Integer>::Cast(args[0])->Value();
		const bool success = Scheduler::Instance()->cancelJob(job_id);
		Handle<Boolean> retval = Boolean::New(isolate, success);
		args.GetReturnValue().Set(retval);
	} catch(const exception& e) {
		isolate->ThrowException(Exception::Error(
			String::NewFromUtf8(isolate, e.what())));
	}
}

// Arguments: job_id
void deleteJob(const v8::FunctionCallbackInfo<v8::Value>& args) {
	Isolate* isolate = args.GetIsolate();

	if (!ArgsHaveJobID(args, 0)) {
		args.GetReturnValue().Set(Boolean::New(isolate, false));
		return;
	}

	const int job_id = (int)Local<Integer>::Cast(args[0])->Value();
	const bool success = Scheduler::Instance()->deleteJob(job_id);
	Handle<Boolean> retval = Boolean::New(isolate, success);
	args.GetReturnValue().Set(retval);
}

/////////////////////////////////
// Helper Functions
/////////////////////////////////

// Handles packaging of algorithm results to return to the frontend.
// Called by libuv in event loop when async training completes.
void trainAlgorithmComplete(uv_work_t* req, int status) {
	// Runs in event loop when algorithm completes.
	Isolate* isolate = Isolate::GetCurrent();
	HandleScope handleScope(isolate);
	Job_t* job = static_cast<Job_t*>(req->data);
	Local<v8::Array> obj = v8::Array::New(isolate);

	try {
		// Pack up the data to be returned to JS
		const MatrixXd& result = Scheduler::Instance()->getJobResult(job->job_id);
		// TODO: Fewer convserions to return a matrix [Issue: https://github.com/blengerich/GenAMap_V2/issues/17]
		obj->Set(0, v8::String::NewFromUtf8(isolate, JsonCoder::getInstance().encodeMatrix(result).c_str()));

		if (status < 0) { //libuv error
			throw runtime_error("Libuv error (check server)");
		}
		if (job->exception) {
			rethrow_exception(job->exception);
		}
	} catch(const exception& e) {
		// If the job failed, the second entry in the array is the exception text.
		// Is this really a good way to return data? It is different than the result from getJobResult()
		obj->Set(1, v8::String::NewFromUtf8(isolate, e.what()));
	}

	Handle<Value> argv[] = { obj };
	// execute the callback
	Local<Function>::New(isolate, job->callback)->Call(
		isolate->GetCurrentContext()->Global(), 1, argv);
	job->callback.Reset();
}

MatrixXd* v8toEigen(Local<v8::Array>& ar) {
	const unsigned int rows = ar->Length();
	Local<v8::Array> props = Local<v8::Object>::Cast(ar->Get(0))->GetPropertyNames();
	const unsigned int cols = props->Length();
	Eigen::MatrixXd* mat = new Eigen::MatrixXd(rows, cols);

	for (unsigned int i=0; i<rows; i++) {
		for (unsigned int j=0; j<cols; j++) {
			(*mat)(i,j) = (double)Local<v8::Object>::Cast(ar->Get(i))->Get(props->Get(j))->NumberValue();
		}
	}
	return mat;
}

// Checks that the argument in the supplied position is a number type.
// Doesn't check that it is a valid job ID.
bool ArgsHaveJobID(const FunctionCallbackInfo<Value>& args, const int position) {
	Isolate* isolate = args.GetIsolate();
	if (args.Length() < 1) {
		isolate->ThrowException(Exception::TypeError(
			String::NewFromUtf8(isolate, "Must supply a job id.")));
		args.GetReturnValue().Set(Boolean::New(isolate, false));
		return false;
	}

	if (!(args[0]->IsNumber())) {
		isolate->ThrowException(Exception::TypeError(
			String::NewFromUtf8(isolate, "Job id must be a number.")));
		args.GetReturnValue().Set(Boolean::New(isolate, false));
		return false;
	}

	return true;
}

/* Deprecated - only interacting with jobs now
// Creates a new algorithm, but does not run it. Currently synchronous.
// Arguments: JSON to be converted to AlgorithmOptions_t
void newAlgorithm(const FunctionCallbackInfo<Value>& args) {
	Isolate* isolate = args.GetIsolate();

	if (args.Length() < 1) {
		isolate->ThrowException(Exception::TypeError(
			String::NewFromUtf8(isolate, "Wrong number of arguments")));
		return;
	}

	Handle<Object> options_v8 = Handle<Object>::Cast(args[0]);
	const AlgorithmOptions_t& options = AlgorithmOptions_t(isolate, options_v8);

	const int id = Scheduler::Instance()->newAlgorithm(options);
	if (id < 0) {
		isolate->ThrowException(Exception::Error(
			String::NewFromUtf8(isolate, "Could not add another algorithm.")));
		return;
	}

	Local<Integer> retval = Integer::New(isolate, id);
	args.GetReturnValue().Set(retval);
}

// Creates a new model, but does not run it. Synchronous.
// Arguments: JSON to be converted to ModelOptions_t
void newModel(const FunctionCallbackInfo<Value>& args) {
	Isolate* isolate = args.GetIsolate();
	Handle<Object> options_v8 = Handle<Object>::Cast(args[0]);
	const ModelOptions_t& options = ModelOptions_t(isolate, options_v8);
	const int id = Scheduler::Instance()->newModel(options);
	if (id < 0) {
		isolate->ThrowException(Exception::Error(
			String::NewFromUtf8(isolate, "Could not add another model")));
		return;
	}

	Local<Integer> retval = Integer::New(isolate, id);
	args.GetReturnValue().Set(retval);
}

// Arguments: int alg_id
// Returns: boolean for success
void deleteAlgorithm(const v8::FunctionCallbackInfo<v8::Value>& args) {
	Isolate* isolate = args.GetIsolate();
	const int algorithm_id = (int)Local<Integer>::Cast(args[0])->Value();
	const bool success = Scheduler::Instance()->deleteAlgorithm(algorithm_id);
	Handle<Boolean> retval = Boolean::New(isolate, success);
	args.GetReturnValue().Set(retval);
}

// Arguments: int model_id
void deleteModel(const v8::FunctionCallbackInfo<v8::Value>& args) {
	Isolate* isolate = args.GetIsolate();
	const int model_id = (int)Local<Integer>::Cast(args[0])->Value();
	const bool success = Scheduler::Instance()->deleteModel(model_id);
	Handle<Boolean> retval = Boolean::New(isolate, success);
	args.GetReturnValue().Set(retval);
}

*/
<|endoftext|>


<commit_before>// Copyright (c) 2016 Till Kolditz
//
// 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:   TestModuloInverseComputation.cpp
 * Author: Till Kolditz <till.kolditz@gmail.com>
 *
 * Created on 20. Februar 2017, 18:21
 */

#include <cstdlib>
#include <iostream>
#include <iomanip>

#include <boost/multiprecision/cpp_int.hpp>

#include "Util/Euclidean.hpp"
#include "Util/Stopwatch.hpp"

using boost::multiprecision::uint128_t;

const size_t wCmin = 16;
const size_t wCmax = 127;
const size_t wAmin = 3;
//const size_t wAmax = 16;

uint64_t convert(uint128_t & source) {
    uint64_t target = 0;
    const unsigned limb_num = source.backend().size(); // number of limbs
    const unsigned limb_bits = sizeof(boost::multiprecision::limb_type) * CHAR_BIT; // size of limb in bits
    for (unsigned i = 0; i < limb_num && ((i * limb_bits) < (sizeof(target) * 8)); ++i) {
        target |= (source.backend().limbs()[i]) << (i * limb_bits);
    }
    return target;
}

int main(int argc, char ** argv) {
    if (argc != 2) {
        std::cerr << "Usage: " << argv[0] << " <totalnum [#iterations]>" << std::endl;
        return 1;
    }

    size_t TOTALNUM = strtoll(argv[1], nullptr, 0);
    uint128_t result;
    // volatile uint64_t result64;

    std::cout << TOTALNUM << " iterations per combination of |A| and |C|." << std::endl;
    std::cout << "|C|";
    for (size_t wA = wAmin; wA <= wCmax; ++wA) {
        std::cout << '\t' << wA;
    }
    std::cout << std::endl;

    for (size_t wC = wCmin; wC <= wCmax; ++wC) {
        std::cout << wC;
        for (size_t wA = wAmin; wA <= (wC - (wCmin - (wAmin - 1))); ++wA) {
            std::cout << "\t-";
        }
        for (size_t wA = (wC - (wCmin - (wAmin - 1))); wA < wC; ++wA) {
            uint128_t A(1);
            A <<= (wA - 1);
            A += 1;
            Stopwatch sw;
            for (size_t i = 0; i < TOTALNUM; ++i) {
                result = ext_euclidean(A, wC);
                // result64 = convert(result);
            }
            auto nanoseconds = sw.Current();
            std::cout << '\t' << std::hex << std::showbase << A << ':' << std::dec << std::noshowbase << nanoseconds;
        }
        std::cout << std::endl;
    }
}
<commit_msg>run from code word width 3 to 127 use smallest integer possible for euclidean computation<commit_after>// Copyright (c) 2016 Till Kolditz
//
// 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:   TestModuloInverseComputation.cpp
 * Author: Till Kolditz <till.kolditz@gmail.com>
 *
 * Created on 20. Februar 2017, 18:21
 */

#include <cstdlib>
#include <iostream>
#include <iomanip>

#include <boost/multiprecision/cpp_int.hpp>

#include "Util/Euclidean.hpp"
#include "Util/Stopwatch.hpp"

using boost::multiprecision::uint128_t;

const size_t wCmin = 3;
const size_t wCmax = 127;
const size_t wAmin = 2;
//const size_t wAmax = 16;

uint64_t convert(uint128_t & source) {
    uint64_t target = 0;
    const unsigned limb_num = source.backend().size(); // number of limbs
    const unsigned limb_bits = sizeof(boost::multiprecision::limb_type) * CHAR_BIT; // size of limb in bits
    for (unsigned i = 0; i < limb_num && ((i * limb_bits) < (sizeof(target) * 8)); ++i) {
        target |= (source.backend().limbs()[i]) << (i * limb_bits);
    }
    return target;
}

template<typename T>
T test(size_t TOTALNUM, size_t wC) {
    T result(0);
    std::cout << wC;
#ifdef DEBUG
    for (size_t wA = wAmin; wA <= (wC - (wCmin - (wAmin - 1))); ++wA) {
        std::cout << "\t-";
    }
    for (size_t wA = (wC - (wCmin - (wAmin - 1))); wA < wC; ++wA) {
#else
    for (size_t wA = wAmin; wA < wC; ++wA) {
#endif
        T A(1);
        A <<= (wA - 1);
        A += 1;
        Stopwatch sw;
        for (size_t i = 0; i < TOTALNUM; ++i) {
            result = ext_euclidean(A, wC);
            // result64 = convert(result);
        }
        auto nanoseconds = sw.Current();
#ifdef DEBUG
        std::cout << '\t' << std::hex << std::showbase << A << ':' << std::dec << std::noshowbase << nanoseconds;
#else
        std::cout << '\t' << nanoseconds;
#endif
    }
    std::cout << std::endl;
    return result;
}

int main(int argc, char ** argv) {
    if (argc != 2) {
        std::cerr << "Usage: " << argv[0] << " <totalnum [#iterations]>" << std::endl;
        return 1;
    }

    size_t TOTALNUM = strtoll(argv[1], nullptr, 0);
// volatile uint64_t result64;

    std::cout << TOTALNUM << " iterations per combination of |A| and |C|." << std::endl;
    std::cout << "|C|";
    for (size_t wA = wAmin; wA <= wCmax; ++wA) {
        std::cout << '\t' << wA;
    }
    std::cout << std::endl;

    for (size_t wC = wCmin; wC <= wCmax; ++wC) {
        if (wC < 8) {
            __attribute__((unused))  volatile uint8_t result = test<uint8_t>(TOTALNUM, wC);
        } else if (wC < 16) {
            __attribute__((unused))  volatile uint16_t result = test<uint16_t>(TOTALNUM, wC);
        } else if (wC < 32) {
            __attribute__((unused))  volatile uint32_t result = test<uint32_t>(TOTALNUM, wC);
        } else if (wC < 64) {
            __attribute__((unused))  volatile uint64_t result = test<uint64_t>(TOTALNUM, wC);
        } else if (wC < 128) {
            __attribute__((unused))  volatile uint128_t result = test<uint128_t>(TOTALNUM, wC);
        } else {
            throw std::runtime_error("unsupported code word widht");
        }
    }
}
<|endoftext|>


<commit_before>//
//  round_thing.cc
//  AirHockey
//
//  Created by Jonathan Sharkey on 10-04-14.
//  Copyright 2010 Sharkable. All rights reserved.
//

#include "airhockey/entities/round_thing.h"

#include <cmath>

#include "airhockey/entities/paddle.h"
#include "airhockey/entities/puck.h"
#include "gameengine/game_engine.h"
#include "gameengine/resource_loader.h"
#include "gameengine/touch.h"
#include "soundengine/sound_player.h"

RoundThing::RoundThing(sp<GameEngine> game_engine)
    : sprite_(game_engine),
      x_(0),
      y_(0),
      old_x_(0),
      old_y_(0),
      vx_(0),
      vy_(0),
      radius_(0),
      mass_(0),
      friction_(0),
      grabbed_(false),
      grabbed_touch_(NULL),
      active_(true) {
}

RoundThing::RoundThing(sp<GameEngine> game_engine, string texture_name)
    : sprite_(game_engine, texture_name),
      x_(0),
      y_(0),
      old_x_(0),
      old_y_(0),
      vx_(0),
      vy_(0),
      radius_(0),
      mass_(0),
      friction_(0),
      grabbed_(false),
      grabbed_touch_(NULL),
      active_(true) {
}

RoundThing::~RoundThing() {
  if (sprite_.texture().data_loaded()) {
    ResourceLoader::Instance().ReleaseResource(sprite_.texture());
  }
}

void RoundThing::ApplyFriction() {
  if (!is_grabbed()) {
    vx_ *= friction_;
    vy_ *= friction_;
  }
}

void RoundThing::MaybeBounceOff(RoundThing *other) {
  // TODO optimize this function.
  // For now I'm just getting it to work.

  double dxFull = x_ - other->x();
  double dyFull = y_ - other->y();
  double radiusTotal = other->radius() + radius_;
//  double v = sqrt(self.vx * self.vx + self.vy * self.vy);
//  double otherV = sqrt(other.vx * other.vx + other.vy * other.vy);

  if (dxFull*dxFull + dyFull*dyFull <= radiusTotal*radiusTotal) {
    // Normalize N
    double nL = sqrt(dxFull*dxFull + dyFull*dyFull);
    double dx = dxFull / nL;
    double dy = dyFull / nL;

    // *** Move the round things outside of each other. ***
    double vFraction = mass_ / (other->mass() + mass_);

    if ((grabbed_ && !other->is_grabbed() && other->IsMovable()) || !IsMovable()) {
      vFraction = 1;
    } else if ((!grabbed_ && other->is_grabbed()) || !other->IsMovable()) {
      vFraction = 0;
    }

    double diff = sqrt(radiusTotal*radiusTotal) - nL;
    other->set_x(other->x() - dx * diff * vFraction);
    other->set_y(other->y() - dy * diff * vFraction);
    vFraction = 1 - vFraction;
    x_ += dx * diff * vFraction;
    y_ += dy * diff * vFraction;

    // *** Now change the direction based on the bounce. ***

    // Based on this: http://stackoverflow.com/questions/573084/how-to-calculate-bounce-angle
    // But it had some problems.
    // Looked at Wikipedia dot product article to help.
    double vDn = vx_ * dx + vy_ * dy;
    double ux = dx * vDn;
    double uy = dy * vDn;
    double wx = vx_ - ux;
    double wy = vy_ - uy;

    double othervDn_ = other->vx() * dx + other->vy() * dy;
    double otherux_ = dx * othervDn_;
    double otheruy_ = dy * othervDn_;
    double otherwx_ = other->vx() - otherux_;
    double otherwy_ = other->vy() - otheruy_;

    double newux_ = (ux * (mass_ - other->mass()) + 2.0 * other->mass() * otherux_) / (mass_ + other->mass());
    double newuy_ = (uy * (mass_ - other->mass()) + 2.0 * other->mass() * otheruy_) / (mass_ + other->mass());

    double newother_ux_ = (otherux_ * (other->mass() - mass_) + 2.0 * mass_ * ux) / (mass_ + other->mass());
    double newother_uy_ = (otheruy_ * (other->mass() - mass_) + 2.0 * mass_ * uy) / (mass_ + other->mass());

    if (!is_grabbed() && IsMovable()) {
      vx_ = newux_ + wx;
      vy_ = newuy_ + wy;
    }

    if (!other->is_grabbed() && other->IsMovable()) {
      other->set_vx(newother_ux_ + otherwx_);
      other->set_vy(newother_uy_ + otherwy_);
    }

    double newVSquared = vx_ * vx_ + vy_ * vy_;
    double newOtherVSquared = other->vx() * other->vx() + other->vy() * other->vy();

    if (newVSquared > (MAX_SPEED*MAX_SPEED)) {
      double newV = sqrt(newVSquared);
      double newRatio = MAX_SPEED / newV;
      vx_ *= newRatio;
      vy_ *= newRatio;
    }
    if (newOtherVSquared > (MAX_SPEED*MAX_SPEED)) {
      double newOtherV = sqrt(newOtherVSquared);
      double newRatio = MAX_SPEED / newOtherV;
      other->set_vx(other->vx() * newRatio);
      other->set_vy(other->vy() * newRatio);
    }

    DidBounceOff(other);
  }
}

bool RoundThing::ContainsTouch(Touch *touch) {
  double dx = touch->location().x - x_;
  double dy = touch->location().y - y_;
  return (dx*dx + dy*dy <= radius_*radius_);
}

bool RoundThing::Overlaps(RoundThing * thing) {
  double dx = thing->x() - x_;
  double dy = thing->y() - y_;
  double totalRadius = thing->radius() + radius_;
  return (dx*dx + dy*dy <= totalRadius*totalRadius);
}

bool RoundThing::IsGrabbable() {
  return false;
}

bool RoundThing::IsMovable() {
  return true;
}

// ViewEntity

void RoundThing::Update() {
  if (!IsMovable() || !is_active()) {
    return;
  }

  if (!grabbed_) {
    x_ += vx_;
    y_ += vy_;
  } else {
    vx_ = vx_ * 0.75 + (x_ - old_x_) * 0.25;
    vy_ = vy_ * 0.75 + (y_ - old_y_) * 0.25;
    old_x_ = x_;
    old_y_ = y_;
  }
}

void RoundThing::Render() {
  if (active_) {
    sprite_.DrawAtPoint(game_point_make(x_ - sprite_.content_size().width / 2,
                                        y_ - sprite_.content_size().height / 2));
  }
}

void RoundThing::TouchesBegan(vector<Touch> touches) {
  if (!IsGrabbable() || !is_active() || is_grabbed()) {
    return;
  }
  for (int i = 0; i < touches.size(); i++) {
    if (ContainsTouch(&touches[i])) {
      grabbed_ = true;
      grabbed_touch_ = touches[i].identifier();
      TouchesMoved(touches);
      vx_ = 0;
      vy_ = 0;
      // Set oldX_ and oldY_ here so that the velocity stays around 0.
      // This is when you touch the outside of the RoundThing and it
      // snaps to center on your touch, it doesn't have a really high
      // initial velocity.
      old_x_ = x_;
      old_y_ = y_;
    }
  }
}

void RoundThing::TouchesMoved(vector<Touch> touches) {
  Touch* correctTouch = NULL;
  for (int i = 0; i < touches.size(); i++) {
    if (touches[i].identifier() == grabbed_touch_) {
      correctTouch = &touches[i];
      break;
    }
  }
  if (grabbed_ && correctTouch != NULL) {
    GamePoint p = correctTouch->location();
    x_ = p.x;
    y_ = p.y;
  }
}

void RoundThing::TouchesEnded(vector<Touch> touches) {
  Touch* correctTouch = NULL;
  for (int i = 0; i < touches.size(); i++) {
    if (touches[i].identifier() == grabbed_touch_) {
      correctTouch = &touches[i];
      break;
    }
  }
  if (grabbed_ && correctTouch != NULL) {
    grabbed_ = false;
    grabbed_touch_ = NULL;
  }
}

void RoundThing::ClearTouches() {
  grabbed_ = false;
  grabbed_touch_ = NULL;
}

//bool RoundThing::isGrabbable() {
//  return false;
//}
//
//bool RoundThing::isMovable() {
//  return true;
//}
//
//bool RoundThing::containsTouch(Touch *touch) {
//  double dx = touch->location().x - x_;
//  double dy = touch->location().y - y_;
//  return (dx*dx + dy*dy <= radius_*radius_);
//}
//
//bool RoundThing::overlaps(RoundThing * thing) {
//  double dx = thing->getX() - x_;
//  double dy = thing->getY() - y_;
//  double totalRadius = thing->getRadius() + radius_;
//  return (dx*dx + dy*dy <= totalRadius*totalRadius);
//}
<commit_msg>Fixed physics bugs! BIG DEAL.<commit_after>//
//  round_thing.cc
//  AirHockey
//
//  Created by Jonathan Sharkey on 10-04-14.
//  Copyright 2010 Sharkable. All rights reserved.
//

#include "airhockey/entities/round_thing.h"

#include <cmath>

#include "airhockey/entities/paddle.h"
#include "airhockey/entities/puck.h"
#include "gameengine/game_engine.h"
#include "gameengine/resource_loader.h"
#include "gameengine/touch.h"
#include "soundengine/sound_player.h"

RoundThing::RoundThing(sp<GameEngine> game_engine)
    : sprite_(game_engine),
      x_(0),
      y_(0),
      old_x_(0),
      old_y_(0),
      vx_(0),
      vy_(0),
      radius_(0),
      mass_(0),
      friction_(0),
      grabbed_(false),
      grabbed_touch_(NULL),
      active_(true) {
}

RoundThing::RoundThing(sp<GameEngine> game_engine, string texture_name)
    : sprite_(game_engine, texture_name),
      x_(0),
      y_(0),
      old_x_(0),
      old_y_(0),
      vx_(0),
      vy_(0),
      radius_(0),
      mass_(0),
      friction_(0),
      grabbed_(false),
      grabbed_touch_(NULL),
      active_(true) {
}

RoundThing::~RoundThing() {
  if (sprite_.texture().data_loaded()) {
    ResourceLoader::Instance().ReleaseResource(sprite_.texture());
  }
}

void RoundThing::ApplyFriction() {
  if (!is_grabbed()) {
    vx_ *= friction_;
    vy_ *= friction_;
  }
}

void RoundThing::MaybeBounceOff(RoundThing *other) {
  // TODO optimize this function.
  // For now I'm just getting it to work.

  double dxFull = x_ - other->x();
  double dyFull = y_ - other->y();
  double radiusTotal = other->radius() + radius_;
//  double v = sqrt(self.vx * self.vx + self.vy * self.vy);
//  double otherV = sqrt(other.vx * other.vx + other.vy * other.vy);

  if (dxFull*dxFull + dyFull*dyFull <= radiusTotal*radiusTotal) {
    // Normalize N
    double nL = sqrt(dxFull*dxFull + dyFull*dyFull);
    double dx = dxFull / nL;
    double dy = dyFull / nL;

    // *** Move the round things outside of each other. ***
    double vFraction = mass_ / (other->mass() + mass_);

    if ((grabbed_ && !other->is_grabbed() && other->IsMovable()) || !IsMovable()) {
      vFraction = 1;
    } else if ((!grabbed_ && other->is_grabbed()) || !other->IsMovable()) {
      vFraction = 0;
    }

    double diff = sqrt(radiusTotal*radiusTotal) - nL;
    other->set_x(other->x() - dx * diff * vFraction);
    other->set_y(other->y() - dy * diff * vFraction);
    vFraction = 1 - vFraction;
    x_ += dx * diff * vFraction;
    y_ += dy * diff * vFraction;

    // *** Now change the direction based on the bounce. ***

    // Based on this: http://stackoverflow.com/questions/573084/how-to-calculate-bounce-angle
    // But it had some problems.
    // Looked at Wikipedia dot product article to help.
    double vDn = vx_ * dx + vy_ * dy;
    double ux = dx * vDn;
    double uy = dy * vDn;
    double wx = vx_ - ux;
    double wy = vy_ - uy;

    double othervDn_ = other->vx() * -dx + other->vy() * -dy;
    double otherux_ = -dx * othervDn_;
    double otheruy_ = -dy * othervDn_;
    double otherwx_ = other->vx() - otherux_;
    double otherwy_ = other->vy() - otheruy_;

    double newux_ = (ux * fabs(mass_ - other->mass()) - 2.0 * other->mass() * otherux_) /
        (mass_ + other->mass());
    double newuy_ = (uy * fabs(mass_ - other->mass()) - 2.0 * other->mass() * otheruy_) /
        (mass_ + other->mass());

    double newother_ux_ = (otherux_ * fabs(other->mass() - mass_) - 2.0 * mass_ * ux) /
        (mass_ + other->mass());
    double newother_uy_ = (otheruy_ * fabs(other->mass() - mass_) - 2.0 * mass_ * uy) /
        (mass_ + other->mass());

    if (!is_grabbed() && IsMovable()) {
      vx_ = wx - newux_;
      vy_ = wy - newuy_;
    }

    if (!other->is_grabbed() && other->IsMovable()) {
      other->set_vx(otherwx_ - newother_ux_);
      other->set_vy(otherwy_ - newother_uy_);
    }

    double newVSquared = vx_ * vx_ + vy_ * vy_;
    double newOtherVSquared = other->vx() * other->vx() + other->vy() * other->vy();

    if (newVSquared > (MAX_SPEED*MAX_SPEED)) {
      double newV = sqrt(newVSquared);
      double newRatio = MAX_SPEED / newV;
      vx_ *= newRatio;
      vy_ *= newRatio;
    }
    if (newOtherVSquared > (MAX_SPEED*MAX_SPEED)) {
      double newOtherV = sqrt(newOtherVSquared);
      double newRatio = MAX_SPEED / newOtherV;
      other->set_vx(other->vx() * newRatio);
      other->set_vy(other->vy() * newRatio);
    }

    DidBounceOff(other);
  }
}

bool RoundThing::ContainsTouch(Touch *touch) {
  double dx = touch->location().x - x_;
  double dy = touch->location().y - y_;
  return (dx*dx + dy*dy <= radius_*radius_);
}

bool RoundThing::Overlaps(RoundThing * thing) {
  double dx = thing->x() - x_;
  double dy = thing->y() - y_;
  double totalRadius = thing->radius() + radius_;
  return (dx*dx + dy*dy <= totalRadius*totalRadius);
}

bool RoundThing::IsGrabbable() {
  return false;
}

bool RoundThing::IsMovable() {
  return true;
}

// ViewEntity

void RoundThing::Update() {
  if (!IsMovable() || !is_active()) {
    return;
  }

  if (!grabbed_) {
    x_ += vx_;
    y_ += vy_;
  } else {
    vx_ = vx_ * 0.75 + (x_ - old_x_) * 0.25;
    vy_ = vy_ * 0.75 + (y_ - old_y_) * 0.25;
    old_x_ = x_;
    old_y_ = y_;
  }
}

void RoundThing::Render() {
  if (active_) {
    sprite_.DrawAtPoint(game_point_make(x_ - sprite_.content_size().width / 2,
                                        y_ - sprite_.content_size().height / 2));
  }
}

void RoundThing::TouchesBegan(vector<Touch> touches) {
  if (!IsGrabbable() || !is_active() || is_grabbed()) {
    return;
  }
  for (int i = 0; i < touches.size(); i++) {
    if (ContainsTouch(&touches[i])) {
      grabbed_ = true;
      grabbed_touch_ = touches[i].identifier();
      TouchesMoved(touches);
      vx_ = 0;
      vy_ = 0;
      // Set oldX_ and oldY_ here so that the velocity stays around 0.
      // This is when you touch the outside of the RoundThing and it
      // snaps to center on your touch, it doesn't have a really high
      // initial velocity.
      old_x_ = x_;
      old_y_ = y_;
    }
  }
}

void RoundThing::TouchesMoved(vector<Touch> touches) {
  Touch* correctTouch = NULL;
  for (int i = 0; i < touches.size(); i++) {
    if (touches[i].identifier() == grabbed_touch_) {
      correctTouch = &touches[i];
      break;
    }
  }
  if (grabbed_ && correctTouch != NULL) {
    GamePoint p = correctTouch->location();
    x_ = p.x;
    y_ = p.y;
  }
}

void RoundThing::TouchesEnded(vector<Touch> touches) {
  Touch* correctTouch = NULL;
  for (int i = 0; i < touches.size(); i++) {
    if (touches[i].identifier() == grabbed_touch_) {
      correctTouch = &touches[i];
      break;
    }
  }
  if (grabbed_ && correctTouch != NULL) {
    grabbed_ = false;
    grabbed_touch_ = NULL;
  }
}

void RoundThing::ClearTouches() {
  grabbed_ = false;
  grabbed_touch_ = NULL;
}

//bool RoundThing::isGrabbable() {
//  return false;
//}
//
//bool RoundThing::isMovable() {
//  return true;
//}
//
//bool RoundThing::containsTouch(Touch *touch) {
//  double dx = touch->location().x - x_;
//  double dy = touch->location().y - y_;
//  return (dx*dx + dy*dy <= radius_*radius_);
//}
//
//bool RoundThing::overlaps(RoundThing * thing) {
//  double dx = thing->getX() - x_;
//  double dy = thing->getY() - y_;
//  double totalRadius = thing->getRadius() + radius_;
//  return (dx*dx + dy*dy <= totalRadius*totalRadius);
//}
<|endoftext|>


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

#include <znc/Chan.h>
#include <znc/IRCNetwork.h>

using std::map;

class CFloodDetachMod : public CModule {
public:
	MODCONSTRUCTOR(CFloodDetachMod) {
		m_iThresholdSecs = 0;
		m_iThresholdMsgs = 0;
	}

	~CFloodDetachMod() {
	}

	void Save() {
		// We save the settings twice because the module arguments can
		// be more easily edited via webadmin, while the SetNV() stuff
		// survives e.g. /msg *status reloadmod ctcpflood.
		SetNV("secs", CString(m_iThresholdSecs));
		SetNV("msgs", CString(m_iThresholdMsgs));

		SetArgs(CString(m_iThresholdMsgs) + " " + CString(m_iThresholdSecs));
	}

	bool OnLoad(const CString& sArgs, CString& sMessage) {
		m_iThresholdMsgs = sArgs.Token(0).ToUInt();
		m_iThresholdSecs = sArgs.Token(1).ToUInt();

		if (m_iThresholdMsgs == 0 || m_iThresholdSecs == 0) {
			m_iThresholdMsgs = GetNV("msgs").ToUInt();
			m_iThresholdSecs = GetNV("secs").ToUInt();
		}

		if (m_iThresholdSecs == 0)
			m_iThresholdSecs = 2;
		if (m_iThresholdMsgs == 0)
			m_iThresholdMsgs = 5;

		Save();

		return true;
	}

	void OnIRCDisconnected() {
		m_chans.clear();
	}

	void Cleanup() {
		Limits::iterator it;
		time_t now = time(NULL);

		for (it = m_chans.begin(); it != m_chans.end(); ++it) {
			// The timeout for this channel did not expire yet?
			if (it->second.first + (time_t)m_iThresholdSecs >= now)
				continue;

			CChan *pChan = m_pNetwork->FindChan(it->first);
			if (it->second.second >= m_iThresholdMsgs
					&& pChan && pChan->IsDetached()) {
				// The channel is detached and it is over the
				// messages limit. Since we only track those
				// limits for non-detached channels or for
				// channels which we detached, this means that
				// we detached because of a flood.

				PutModule("Flood in [" + pChan->GetName() + "] is over, "
						"re-attaching...");
				// No buffer playback, makes sense, doesn't it?
				pChan->ClearBuffer();
				pChan->JoinUser();
			}

			Limits::iterator it2 = it++;
			m_chans.erase(it2);

			// Without this Bad Things (tm) could happen
			if (it == m_chans.end())
				break;
		}
	}

	void Message(CChan& Channel) {
		Limits::iterator it;
		time_t now = time(NULL);

		// First: Clean up old entries and reattach where necessary
		Cleanup();

		it = m_chans.find(Channel.GetName());

		if (it == m_chans.end()) {
			// We don't track detached channels
			if (Channel.IsDetached())
				return;

			// This is the first message for this channel, start a
			// new timeout.
			std::pair<time_t, unsigned int> tmp(now, 1);
			m_chans[Channel.GetName()] = tmp;
			return;
		}

		// No need to check it->second.first (expiry time), since
		// Cleanup() would have removed it if it was expired.

		if (it->second.second >= m_iThresholdMsgs) {
			// The channel already hit the limit and we detached the
			// user, but it is still being flooded, reset the timeout
			it->second.first = now;
			it->second.second++;
			return;
		}

		it->second.second++;

		if (it->second.second < m_iThresholdMsgs)
			return;

		// The channel hit the limit, reset the timeout so that we keep
		// it detached for longer.
		it->second.first = now;

		Channel.DetachUser();
		PutModule("Channel [" + Channel.GetName() + "] was "
				"flooded, you've been detached");
	}

	EModRet OnChanMsg(CNick& Nick, CChan& Channel, CString& sMessage) {
		Message(Channel);
		return CONTINUE;
	}

	// This also catches OnChanAction()
	EModRet OnChanCTCP(CNick& Nick, CChan& Channel, CString& sMessage) {
		Message(Channel);
		return CONTINUE;
	}

	EModRet OnChanNotice(CNick& Nick, CChan& Channel, CString& sMessage) {
		Message(Channel);
		return CONTINUE;
	}

	EModRet OnTopic(CNick& Nick, CChan& Channel, CString& sTopic) {
		Message(Channel);
		return CONTINUE;
	}

	void OnModCommand(const CString& sCommand) {
		const CString& sCmd = sCommand.Token(0);
		const CString& sArg = sCommand.Token(1, true);

		if (sCmd.Equals("secs") && !sArg.empty()) {
			m_iThresholdSecs = sArg.ToUInt();
			if (m_iThresholdSecs == 0)
				m_iThresholdSecs = 1;

			PutModule("Set seconds limit to [" + CString(m_iThresholdSecs) + "]");
			Save();
		} else if (sCmd.Equals("lines") && !sArg.empty()) {
			m_iThresholdMsgs = sArg.ToUInt();
			if (m_iThresholdMsgs == 0)
				m_iThresholdMsgs = 2;

			PutModule("Set lines limit to [" + CString(m_iThresholdMsgs) + "]");
			Save();
		} else if (sCmd.Equals("show")) {
			PutModule("Current limit is " + CString(m_iThresholdMsgs) + " lines "
					"in " + CString(m_iThresholdSecs) + " secs.");
		} else {
			PutModule("Commands: show, secs <limit>, lines <limit>");
		}
	}
private:
	typedef map<CString, std::pair<time_t, unsigned int> > Limits;
	Limits m_chans;
	unsigned int m_iThresholdSecs;
	unsigned int m_iThresholdMsgs;
};

template<> void TModInfo<CFloodDetachMod>(CModInfo& Info) {
	Info.SetWikiPage("flooddetach");
	Info.SetHasArgs(true);
	Info.SetArgsHelpText("This user module takes up to two arguments. Arguments are msgs and secs numbers.");
}

USERMODULEDEFS(CFloodDetachMod, "Detach channels when flooded")
<commit_msg>Refactor flooddetach to use command callbacks<commit_after>/*
 * Copyright (C) 2004-2014 ZNC, see the NOTICE file for details.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <znc/Chan.h>
#include <znc/IRCNetwork.h>

using std::map;

class CFloodDetachMod : public CModule {
public:
	MODCONSTRUCTOR(CFloodDetachMod) {
		m_iThresholdSecs = 0;
		m_iThresholdMsgs = 0;

		AddHelpCommand();
		AddCommand("Show", static_cast<CModCommand::ModCmdFunc>(&CFloodDetachMod::ShowCommand), "");
		AddCommand("Secs", static_cast<CModCommand::ModCmdFunc>(&CFloodDetachMod::SecsCommand), "[<limit>]");
		AddCommand("Lines", static_cast<CModCommand::ModCmdFunc>(&CFloodDetachMod::LinesCommand), "[<limit>]");
	}

	~CFloodDetachMod() {
	}

	void Save() {
		// We save the settings twice because the module arguments can
		// be more easily edited via webadmin, while the SetNV() stuff
		// survives e.g. /msg *status reloadmod ctcpflood.
		SetNV("secs", CString(m_iThresholdSecs));
		SetNV("msgs", CString(m_iThresholdMsgs));

		SetArgs(CString(m_iThresholdMsgs) + " " + CString(m_iThresholdSecs));
	}

	bool OnLoad(const CString& sArgs, CString& sMessage) {
		m_iThresholdMsgs = sArgs.Token(0).ToUInt();
		m_iThresholdSecs = sArgs.Token(1).ToUInt();

		if (m_iThresholdMsgs == 0 || m_iThresholdSecs == 0) {
			m_iThresholdMsgs = GetNV("msgs").ToUInt();
			m_iThresholdSecs = GetNV("secs").ToUInt();
		}

		if (m_iThresholdSecs == 0)
			m_iThresholdSecs = 2;
		if (m_iThresholdMsgs == 0)
			m_iThresholdMsgs = 5;

		Save();

		return true;
	}

	void OnIRCDisconnected() {
		m_chans.clear();
	}

	void Cleanup() {
		Limits::iterator it;
		time_t now = time(NULL);

		for (it = m_chans.begin(); it != m_chans.end(); ++it) {
			// The timeout for this channel did not expire yet?
			if (it->second.first + (time_t)m_iThresholdSecs >= now)
				continue;

			CChan *pChan = m_pNetwork->FindChan(it->first);
			if (it->second.second >= m_iThresholdMsgs
					&& pChan && pChan->IsDetached()) {
				// The channel is detached and it is over the
				// messages limit. Since we only track those
				// limits for non-detached channels or for
				// channels which we detached, this means that
				// we detached because of a flood.

				PutModule("Flood in [" + pChan->GetName() + "] is over, "
						"re-attaching...");
				// No buffer playback, makes sense, doesn't it?
				pChan->ClearBuffer();
				pChan->JoinUser();
			}

			Limits::iterator it2 = it++;
			m_chans.erase(it2);

			// Without this Bad Things (tm) could happen
			if (it == m_chans.end())
				break;
		}
	}

	void Message(CChan& Channel) {
		Limits::iterator it;
		time_t now = time(NULL);

		// First: Clean up old entries and reattach where necessary
		Cleanup();

		it = m_chans.find(Channel.GetName());

		if (it == m_chans.end()) {
			// We don't track detached channels
			if (Channel.IsDetached())
				return;

			// This is the first message for this channel, start a
			// new timeout.
			std::pair<time_t, unsigned int> tmp(now, 1);
			m_chans[Channel.GetName()] = tmp;
			return;
		}

		// No need to check it->second.first (expiry time), since
		// Cleanup() would have removed it if it was expired.

		if (it->second.second >= m_iThresholdMsgs) {
			// The channel already hit the limit and we detached the
			// user, but it is still being flooded, reset the timeout
			it->second.first = now;
			it->second.second++;
			return;
		}

		it->second.second++;

		if (it->second.second < m_iThresholdMsgs)
			return;

		// The channel hit the limit, reset the timeout so that we keep
		// it detached for longer.
		it->second.first = now;

		Channel.DetachUser();
		PutModule("Channel [" + Channel.GetName() + "] was "
				"flooded, you've been detached");
	}

	EModRet OnChanMsg(CNick& Nick, CChan& Channel, CString& sMessage) {
		Message(Channel);
		return CONTINUE;
	}

	// This also catches OnChanAction()
	EModRet OnChanCTCP(CNick& Nick, CChan& Channel, CString& sMessage) {
		Message(Channel);
		return CONTINUE;
	}

	EModRet OnChanNotice(CNick& Nick, CChan& Channel, CString& sMessage) {
		Message(Channel);
		return CONTINUE;
	}

	EModRet OnTopic(CNick& Nick, CChan& Channel, CString& sTopic) {
		Message(Channel);
		return CONTINUE;
	}

	void ShowCommand(const CString& sLine) {
		PutModule("Current limit is " + CString(m_iThresholdMsgs) + " lines "
				"in " + CString(m_iThresholdSecs) + " secs.");
	}

	void SecsCommand(const CString& sLine) {
		const CString sArg = sLine.Token(1, true);

		if (!sArg.empty()) {
			m_iThresholdSecs = sArg.ToUInt();
			if (m_iThresholdSecs == 0)
				m_iThresholdSecs = 1;

			PutModule("Set seconds limit to [" + CString(m_iThresholdSecs) + "]");
			Save();
		}
	}

	void LinesCommand(const CString& sLine) {
		const CString sArg = sLine.Token(1, true);

		if (!sArg.empty()) {
			m_iThresholdMsgs = sArg.ToUInt();
			if (m_iThresholdMsgs == 0)
				m_iThresholdMsgs = 2;

			PutModule("Set lines limit to [" + CString(m_iThresholdMsgs) + "]");
			Save();
		}
	}

private:
	typedef map<CString, std::pair<time_t, unsigned int> > Limits;
	Limits m_chans;
	unsigned int m_iThresholdSecs;
	unsigned int m_iThresholdMsgs;
};

template<> void TModInfo<CFloodDetachMod>(CModInfo& Info) {
	Info.SetWikiPage("flooddetach");
	Info.SetHasArgs(true);
	Info.SetArgsHelpText("This user module takes up to two arguments. Arguments are msgs and secs numbers.");
}

USERMODULEDEFS(CFloodDetachMod, "Detach channels when flooded")
<|endoftext|>