<commit_before>//
//  CommandReceiverImpl.h
//  CommandTest
//
//  Created by <NAME> on 5/20/15.
//  Copyright (c) 2015 <NAME>. All rights reserved.
//

#pragma once

#include <typeindex>
#include <unordered_map>
#include <boost/mpl/for_each.hpp>

class CommandReceiverImpl : public std::enable_shared_from_this<CommandReceiverImpl>
{
public:
    using ExecutingCommands = std::unordered_map<std::type_index, std::shared_ptr<ContinuousCommand>>;
    
    virtual void ExecutingCommandsDidChange(const ExecutingCommands &executingCommands) {}
    
private:
    ExecutingCommands _ExecutingCommands;
    
public:
    template<class CommandReceiverT, class CommandT>
    void ExecuteImpl(const std::shared_ptr<CommandT> &command)
    {
        // If this assert is failing, that means someone is calling Execute on a CommandReceiver using a
        // Commnad that does not appear the in receiver's Commands set.
        BOOST_MPL_ASSERT((boost::mpl::has_key<typename CommandReceiverT::Commands, CommandT>));
        dynamic_cast<CommandReceiverT *>(this)->HandleExecute(command);
    }
    
    template<class CommandReceiverT, class CommandT>
    void BeginImpl(const std::shared_ptr<CommandT> &command)
    {
        // If this assert is failing, that means someone is calling Begin on a CommandReceiver using a
        // Continuous Command that does not appear the in receiver's ContinuousCommands set.
        BOOST_MPL_ASSERT((boost::mpl::has_key<typename CommandReceiverT::ContinuousCommands, CommandT>));
        
        auto receiver = std::dynamic_pointer_cast<CommandReceiverT>(shared_from_this());
        
        std::weak_ptr<CommandReceiverT> weakReceiver = receiver;
        std::weak_ptr<CommandT> weakCommand = command;
        
        // Wire up the End method
        command->End = [weakReceiver, weakCommand] {
            auto receiver = weakReceiver.lock();
            auto command = weakCommand.lock();
            if (receiver && command) {
                receiver->HandleEnd(command);
                
                command->SetWasEnded();
                receiver->_ExecutingCommands.erase(typeid(*command));
                receiver->ExecutingCommandsDidChange(receiver->_ExecutingCommands);
            }
        };
        
        // Wire up the Cancel method
        command->Cancel = [weakReceiver, weakCommand] {
            auto receiver = weakReceiver.lock();
            auto command = weakCommand.lock();
            if (receiver && command) {
                receiver->HandleCancel(command);
                
                command->SetWasCancelled();
                receiver->_ExecutingCommands.erase(typeid(*command));
                receiver->ExecutingCommandsDidChange(receiver->_ExecutingCommands);
            }
        };
        
        receiver->HandleBegin(command);
        
        command->SetWasBegan();
        receiver->_ExecutingCommands[typeid(*command)] = std::static_pointer_cast<ContinuousCommand>(command);
        receiver->ExecutingCommandsDidChange(receiver->_ExecutingCommands);
    }
};

#pragma mark - Template Instantiations

template<class T, typename B, typename E>
struct InstantiateCommandFunctions
{
    InstantiateCommandFunctions()
    {
        &T::template Execute<typename B::type>;
    }
    
    InstantiateCommandFunctions<T, typename boost::mpl::next<B>::type, E> next;
};
template<class T, typename E>
struct InstantiateCommandFunctions<T, E, E> {};

template<class T, typename B, typename E>
struct InstantiateContinuousCommandFunctions
{
    InstantiateContinuousCommandFunctions()
    {
        &T::template Begin<typename B::type>;
    }
    
    InstantiateCommandFunctions<T, typename boost::mpl::next<B>::type, E> next;<commit_msg>Suppress warnings<commit_after>//
//  CommandReceiverImpl.h
//  CommandTest
//
//  Created by <NAME> on 5/20/15.
//  Copyright (c) 2015 <NAME>. All rights reserved.
//

#pragma once

#include <typeindex>
#include <unordered_map>
#include <boost/mpl/for_each.hpp>

class CommandReceiverImpl : public std::enable_shared_from_this<CommandReceiverImpl>
{
public:
    using ExecutingCommands = std::unordered_map<std::type_index, std::shared_ptr<ContinuousCommand>>;
    
    virtual void ExecutingCommandsDidChange(const ExecutingCommands &executingCommands) {}
    
private:
    ExecutingCommands _ExecutingCommands;
    
public:
    template<class CommandReceiverT, class CommandT>
    void ExecuteImpl(const std::shared_ptr<CommandT> &command)
    {
        // If this assert is failing, that means someone is calling Execute on a CommandReceiver using a
        // Commnad that does not appear the in receiver's Commands set.
        BOOST_MPL_ASSERT((boost::mpl::has_key<typename CommandReceiverT::Commands, CommandT>));
        dynamic_cast<CommandReceiverT *>(this)->HandleExecute(command);
    }
    
    template<class CommandReceiverT, class CommandT>
    void BeginImpl(const std::shared_ptr<CommandT> &command)
    {
        // If this assert is failing, that means someone is calling Begin on a CommandReceiver using a
        // Continuous Command that does not appear the in receiver's ContinuousCommands set.
        BOOST_MPL_ASSERT((boost::mpl::has_key<typename CommandReceiverT::ContinuousCommands, CommandT>));
        
        auto receiver = std::dynamic_pointer_cast<CommandReceiverT>(shared_from_this());
        
        std::weak_ptr<CommandReceiverT> weakReceiver = receiver;
        std::weak_ptr<CommandT> weakCommand = command;
        
        // Wire up the End method
        command->End = [weakReceiver, weakCommand] {
            auto receiver = weakReceiver.lock();
            auto command = weakCommand.lock();
            if (receiver && command) {
                receiver->HandleEnd(command);
                
                command->SetWasEnded();
                receiver->_ExecutingCommands.erase(typeid(*command));
                receiver->ExecutingCommandsDidChange(receiver->_ExecutingCommands);
            }
        };
        
        // Wire up the Cancel method
        command->Cancel = [weakReceiver, weakCommand] {
            auto receiver = weakReceiver.lock();
            auto command = weakCommand.lock();
            if (receiver && command) {
                receiver->HandleCancel(command);
                
                command->SetWasCancelled();
                receiver->_ExecutingCommands.erase(typeid(*command));
                receiver->ExecutingCommandsDidChange(receiver->_ExecutingCommands);
            }
        };
        
        receiver->HandleBegin(command);
        
        command->SetWasBegan();
        receiver->_ExecutingCommands[typeid(*command)] = std::static_pointer_cast<ContinuousCommand>(command);
        receiver->ExecutingCommandsDidChange(receiver->_ExecutingCommands);
    }
};

#pragma mark - Template Instantiations

template<class T, typename B, typename E>
struct InstantiateCommandFunctions
{
    InstantiateCommandFunctions()
    {
        #pragma clang diagnostic push
        #pragma clang diagnostic ignored "-Wunused-value"
        &T::template Execute<typename B::type>;
        #pragma clang diagnostic pop
    }
    
    InstantiateCommandFunctions<T, typename boost::mpl::next<B>::type, E> next;
};
template<class T, typename E>
struct InstantiateCommandFunctions<T, E, E> {};

template<class T, typename B, typename E>
struct InstantiateContinuousCommandFunctions
{
    InstantiateContinuousCommandFunctions()
    {
        #pragma clang diagnostic push
        #pragma clang diagnostic ignored "-Wunused-value"
        &T::template Begin<typename B::type>;
        #pragma clang diagnostic pop
    }
    
    InstantiateCommandFunctions<T, typename boost::mpl::next<B>::type, E> next;
{'fraction_non_alphanumeric': 0.10062079668908433, 'fraction_numerical': 0.0023279875840662182, 'mean_word_length': 2.9656410256410255, 'pattern_counts': {'":': 0, '<': 61, '<?xml version=': 0, '>': 97, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4209739', 'n_tokens_mistral': 2076, 'n_tokens_neox': 2053, 'n_words': 466}