<commit_before>// Time:  O(n * (C(2n, n) - C(2n, n - 1)))
// Space: O(n^2 * (C(2n, n) - C(2n, n - 1)))

class Solution {
  public:
    vector<int> diffWaysToCompute(string input) {
        vector<vector<vector<int>>> lookup(input.length() + 1,
                                           vector<vector<int>>(input.length() + 1, vector<int>()));
        return diffWaysToComputeRecu(input, 0, input.length(), lookup);
    }

    vector<int> diffWaysToComputeRecu(const string& input,
                                      const int start, const int end,
                                      vector<vector<vector<int>>>& lookup) {
        if (start == end) {
            return {};
        }

        if (!lookup[start][end].empty()) {
            return lookup[start][end];
        }

        vector<int> result;
        int i = start;
        while (i < end && !isOperator(input[i])) {
            ++i;
        }
        if (i == end) {
            result.emplace_back(move(stoi(input.substr(start, end - start))));
            return result;
        }

        i = start;
        while (i < end) {
            while (i < end && !isOperator(input[i])) {
                ++i;
            }
            if (i < end) {
                vector<int> left = diffWaysToComputeRecu(input, start, i, lookup);
                vector<int> right = diffWaysToComputeRecu(input, i + 1, end, lookup);
                for (int j = 0; j < left.size(); ++j) {
                    for(int k = 0; k < right.size(); ++k) {
                        result.emplace_back(move(compute(input[i],left[j], right[k])));
                    }
                }
            }
            ++i;
        }
        lookup[start][end] = move(result);
        return lookup[start][end];
    }

    bool isOperator(const char c){
        return string("+-*").find(string(1, c)) != string::npos;
    }

    int compute(const char c, const int left, const int right){
        switch (c) {
            case '+':
                return left + right;
            case '-':
                return left - right;
            case '*':
                return left * right;
            default:
                return 0;
        }
        return 0;
    }
};

// Time:  O(n^2 * (C(2n, n) - C(2n, n - 1)))
// Space: O(C(2n, n) - C(2n, n - 1))
class Solution2 {
  public:
    vector<int> diffWaysToCompute(string input) {
        return diffWaysToComputeRecu(input, 0, input.length());
    }

    vector<int> diffWaysToComputeRecu(const string& input,
                                      const int start, const int end) {
        if (start == end) {
            return {};
        }

        vector<int> result;
        int i = start;
        while (i < end && !isOperator(input[i])) {
            ++i;
        }
        if (i == end) {
            result.emplace_back(move(stoi(input.substr(start, end - start))));
            return result;
        }

        i = start;
        while (i < end) {
            while (i < end && !isOperator(input[i])) {
                ++i;
            }
            if (i < end) {
                vector<int> left = diffWaysToComputeRecu(input, start, i);
                vector<int> right = diffWaysToComputeRecu(input, i + 1, end);
                for (int j = 0; j < left.size(); ++j) {
                    for(int k = 0; k < right.size(); ++k) {
                        result.emplace_back(move(compute(input[i],left[j], right[k])));
                    }
                }
            }
            ++i;
        }
        return result;
    }

    bool isOperator(const char c){
        return string("+-*").find(string(1, c)) != string::npos;
    }

    int compute(const char c, const int left, const int right){
        switch (c) {
            case '+':
                return left + right;
            case '-':
                return left - right;
            case '*':
                return left * right;
            default:
                return 0;
        }
        return 0;
    }
};
<commit_msg>Update different-ways-to-add-parentheses.cpp<commit_after>// Time:  O(n * (C(2n, n) - C(2n, n - 1)))
// Space: O(n^2 * (C(2n, n) - C(2n, n - 1)))

class Solution {
  public:
    vector<int> diffWaysToCompute(string input) {
        vector<vector<vector<int>>> lookup(input.length() + 1,
                                           vector<vector<int>>(input.length() + 1, vector<int>()));
        return diffWaysToComputeRecu(input, 0, input.length(), lookup);
    }

    vector<int> diffWaysToComputeRecu(const string& input,
                                      const int start, const int end,
                                      vector<vector<vector<int>>>& lookup) {
        if (start == end) {
            return {};
        }

        if (!lookup[start][end].empty()) {
            return lookup[start][end];
        }

        vector<int> result;
        int i = start;
        while (i < end && !isOperator(input[i])) {
            ++i;
        }
        if (i == end) {
            result.emplace_back(move(stoi(input.substr(start, end - start))));
            return result;
        }

        i = start;
        while (i < end) {
            while (i < end && !isOperator(input[i])) {
                ++i;
            }
            if (i < end) {
                vector<int> left = diffWaysToComputeRecu(input, start, i, lookup);
                vector<int> right = diffWaysToComputeRecu(input, i + 1, end, lookup);
                for (int j = 0; j < left.size(); ++j) {
                    for(int k = 0; k < right.size(); ++k) {
                        result.emplace_back(move(compute(input[i],left[j], right[k])));
                    }
                }
            }
            ++i;
        }
        lookup[start][end] = move(result);
        return lookup[start][end];
    }

    bool isOperator(const char c){
        return string("+-*").find(string(1, c)) != string::npos;
    }

    int compute(const char c, const int left, const int right){
        switch (c) {
            case '+':
                return left + right;
            case '-':
                return left - right;
            case '*':
                return left * right;
            default:
                return 0;
        }
        return 0;
    }
};

// Time:  O(n^2 * (C(2n, n) - C(2n, n - 1)))
// Space: O(C(2n, n) - C(2n, n - 1))
class Solution2 {
  public:
    vector<int> diffWaysToCompute(string input) {
        vector<int> result;
        for (int i = 0; i < input.size(); ++i) {
            char cur = input[i];
            if (cur == '+' || cur == '-' || cur == '*') {
                vector<int> left = diffWaysToCompute(input.substr(0, i));
                vector<int> right = diffWaysToCompute(input.substr(i + 1));
                for (const auto& num1 : left) {
                    for (const auto& num2 : right) {
                        if (cur == '+') {
                            result.emplace_back(num1 + num2);
                        } else if (cur == '-') {
                            result.emplace_back(num1 - num2);
                        } else {
                            result.emplace_back(num1 * num2);
                        }
                    }
                }
            }
        }
        // if the input string contains only number
        if (result.empty()) {
            result.emplace_back(stoi(input));
        }
        return result;
    }
};
<|endoftext|>


<commit_before>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2015.  All rights reserved
 */
#include    "../../StroikaPreComp.h"

#include    <cstdio>
#include    <random>

#if     qPlatform_POSIX
//@todo see how many of these includes are needed
#include    <unistd.h>
#include    <arpa/inet.h>
#include    <net/if.h>
#include    <netinet/in.h>
#include    <netdb.h>
#include    <sys/socket.h>
#include    <sys/ioctl.h>
#if     qPlatform_Linux
#include    <linux/types.h>     // needed on RedHat5
#include    <linux/ethtool.h>
#include    <linux/sockios.h>
#endif
#elif   qPlatform_Windows
#include    <WinSock2.h>
#include    <WS2tcpip.h>
#include    <Iphlpapi.h>
#include    <netioapi.h>
#endif

#include    "../../Characters/CString/Utilities.h"
#include    "../../Characters/Format.h"
#include    "../../Containers/Collection.h"
#include    "../../Containers/Mapping.h"
#include    "../../Execution/ErrNoException.h"
#include    "../../Execution/Finally.h"
#if     qPlatform_Windows
#include    "../../../Foundation/Execution/Platform/Windows/Exception.h"
#endif
#include    "../../Execution/Synchronized.h"
#include    "../../Memory/SmallStackBuffer.h"

#include    "Socket.h"

#include    "Interface.h"

using   namespace   Stroika::Foundation;
using   namespace   Stroika::Foundation::Containers;
using   namespace   Stroika::Foundation::Execution;
using   namespace   Stroika::Foundation::Memory;
using   namespace   Stroika::Foundation::IO;
using   namespace   Stroika::Foundation::IO::Network;

// Comment this in to turn on aggressive noisy DbgTrace in this module
//#define   USE_NOISY_TRACE_IN_THIS_MODULE_       1

#if     defined (_MSC_VER)
// support use of Iphlpapi - but better to reference here than in lib entry of project file cuz
// easiser to see/modularize (and only pulled in if this module is referenced)
#pragma comment (lib, "Iphlpapi.lib")
#endif

/*
 ********************************************************************************
 **************************** Network::Interface ********************************
 ********************************************************************************
 */
const Configuration::EnumNames<Interface::Status>   Interface::Stroika_Enum_Names(Status)
{
    { Interface::Status::eConnected, L"Connected" },
    { Interface::Status::eRunning, L"Running" },
};

const Configuration::EnumNames<Interface::Type>   Interface::Stroika_Enum_Names(Type)
{
    { Interface::Type::eLoopback, L"Loopback" },
    { Interface::Type::eWiredEthernet, L"WiredEthernet" },
    { Interface::Type::eWIFI, L"WIFI" },
    { Interface::Type::eTunnel, L"Tunnel" },
    { Interface::Type::eOther, L"Other" },
};

#if     qPlatform_Linux
// Hack for centos5 support:
//      Overload with linux version so other one wins, but this gets called if other doesnt exist
//      TRY --LGP 2015-05-19
template    <typename HACK = int>
static __inline__ __u32 ethtool_cmd_speed (const struct ethtool_cmd* ep, HACK i = 0)
{
    //return (ep->speed_hi << 16) | ep->speed;
    return ep->speed;
}
#endif

namespace {
    // Windows uses '-' as separator, and linux ':'. Pick arbitrarily (more linux machines
    // than windows, or soon will be)
    auto     PrintMacAddr_ (const uint8_t* macaddrBytes, const uint8_t* macaddrBytesEnd) -> String {
        Require (macaddrBytesEnd - macaddrBytes == 6);
        char     buf[100] {};
        (void)snprintf (buf, sizeof (buf), "%02x:%02x:%02x:%02x:%02x:%02x",
                        macaddrBytes[0], macaddrBytes[1],
                        macaddrBytes[2], macaddrBytes[3],
                        macaddrBytes[4], macaddrBytes[5]
                       );
        return String::FromAscii (buf);
    };
}

/*
 ********************************************************************************
 ************************** Network::GetInterfaces ******************************
 ********************************************************************************
 */
Traversal::Iterable<Interface>  Network::GetInterfaces ()
{
#if     USE_NOISY_TRACE_IN_THIS_MODULE_
    Debug::TraceContextBumper ctx ("Network::GetInterfaces");
#endif
    Collection<Interface>   result;
#if     qPlatform_POSIX
    auto getFlags = [] (int sd, const char* name) {
        struct ifreq ifreq {};
        Characters::CString::Copy (ifreq.ifr_name, NEltsOf (ifreq.ifr_name), name);

        int r = ::ioctl (sd, SIOCGIFFLAGS, (char*)&ifreq);
        Assert (r == 0);
        return ifreq.ifr_flags;
    };

    struct ifreq    ifreqs[128] {};
    struct ifconf   ifconf {};
    ifconf.ifc_req = ifreqs;
    ifconf.ifc_len = sizeof(ifreqs);

    int sd = ::socket (PF_INET, SOCK_STREAM, 0);
    Assert (sd >= 0);
    Execution::Finally cleanup ([sd] () {
        ::close (sd);
    });

    int r = ::ioctl (sd, SIOCGIFCONF, (char*)&ifconf);
    Assert (r == 0);

    for (int i = 0; i < ifconf.ifc_len / sizeof(struct ifreq); ++i) {
#if     USE_NOISY_TRACE_IN_THIS_MODULE_
        DbgTrace ("interface: ifr_name=%s; ifr_addr.sa_family = %d", ifreqs[i].ifr_name, ifreqs[i].ifr_addr.sa_family);
#endif
#if     qPlatform_AIX
        // I don't understand the logic behind this, but without this, we get errors
        // in getFlags(). We could check there - and handle that with an extra return value, but this
        // is simpler.
        //
        // And - its somewhat prescribed in https://www.ibm.com/developerworks/community/forums/html/topic?id=77777777-0000-0000-0000-000014698597
        //
        if (ifreqs[i].ifr_addr.sa_family != AF_INET and ifreqs[i].ifr_addr.sa_family != AF_INET6 and ifreqs[i].ifr_addr.sa_family != AF_LINK) {
            // Skip interfaces not bound to and IPv4 or IPv6 address, or AF_LINK (not sure what later is used for)
            // this list of exceptions arrived at experimentally on the one AIX machine I tested (so not good)
            continue;
        }
#endif
        Interface   newInterface;
        String interfaceName { String::FromSDKString (ifreqs[i].ifr_name) };
        newInterface.fInternalInterfaceID = interfaceName;
        newInterface.fFriendlyName = interfaceName;         // not great - maybe find better name - but this will do for now...
        int flags = getFlags (sd, ifreqs[i].ifr_name);

        if (flags & IFF_LOOPBACK) {
            newInterface.fType = Interface::Type::eLoopback;
        }
        else {
            // NYI
            newInterface.fType = Interface::Type::eWiredEthernet;    // WAY - not the right way to tell!
        }

        if (::ioctl (sd, SIOCGIFHWADDR, &ifr) == 0 and ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER) {
            newInterface.fHwardwareAddress = PrintMacAddr_ (reinterpret_cast<const uint8_t*> (ifr.ifr_hwaddr.sa_data), reinterpret_cast<const uint8_t*> (ifr.ifr_hwaddr.sa_data) + 6);
        }

#if     qPlatform_AIX
        {
            auto getSpeed = [] (int sd, const char* name) -> Optional<uint64_t> {
                struct ifreq ifreq;
                (void)::memset (&ifreq, 0, sizeof (ifreq));
                Characters::CString::Copy (ifreq.ifr_name, NEltsOf (ifreq.ifr_name), name);
                int r = ioctl (sd, SIOCGIFBAUDRATE, &ifreq);
                if (r != 0)
                {
                    DbgTrace ("No speed for interface %s, errno=%d", name, errno);
                    return Optional<uint64_t> ();
                }
                return ifreq.ifr_baudrate;
            };
            newInterface.fTransmitSpeedBaud = getSpeed (sd, ifreqs[i].ifr_name);
            newInterface.fReceiveLinkSpeedBaud = newInterface.fTransmitSpeedBaud;
        }
#elif   qPlatform_Linux
        {
            auto getSpeed = [] (int sd, const char* name) -> Optional<uint64_t> {
                struct ifreq ifreq {};
                Characters::CString::Copy (ifreq.ifr_name, NEltsOf (ifreq.ifr_name), name);
                struct ethtool_cmd edata {};
                ifreq.ifr_data = reinterpret_cast<caddr_t> (&edata);
                edata.cmd = ETHTOOL_GSET;
                int r = ioctl(sd, SIOCETHTOOL, &ifreq);
                if (r != 0)
                {
                    DbgTrace ("No speed for interface %s, errno=%d", name, errno);
                    return Optional<uint64_t> ();
                }
                constexpr uint64_t kMegabit_ = 1000 * 1000;
                DbgTrace ("ethtool_cmd_speed (&edata)=%d", ethtool_cmd_speed (&edata));
                switch (ethtool_cmd_speed (&edata))
                {
                    case SPEED_10:
                        return 10 * kMegabit_;
                    case SPEED_100:
                        return 100 * kMegabit_;
                    case SPEED_1000:
                        return 1000 * kMegabit_;
                    case SPEED_2500:
                        return 2500 * kMegabit_;
                    case SPEED_10000:
                        return 10000 * kMegabit_;
                    default:
                        return Optional<uint64_t> ();
                }
            };
            newInterface.fTransmitSpeedBaud = getSpeed (sd, ifreqs[i].ifr_name);
            newInterface.fReceiveLinkSpeedBaud = newInterface.fTransmitSpeedBaud;
        }
#endif

        {
            Containers::Set<Interface::Status>  status;
            if (flags & IFF_RUNNING) {
                // not right!!! But a start...
                status.Add (Interface::Status::eConnected);
                status.Add (Interface::Status::eRunning);
            }
            newInterface.fStatus = status;
        }
        newInterface.fBindings.Add (InternetAddress (((struct sockaddr_in*)&ifreqs[i].ifr_addr)->sin_addr));    // @todo fix so works for ipv6 addresses as well!
        result.Add (newInterface);
    }
#elif   qPlatform_Windows
    ULONG flags = GAA_FLAG_INCLUDE_PREFIX;
    ULONG family = AF_UNSPEC;       // Both IPv4 and IPv6 addresses
    Memory::SmallStackBuffer<Byte>  buf(0);
Again:
    ULONG ulOutBufLen = static_cast<ULONG> (buf.GetSize ());
    PIP_ADAPTER_ADDRESSES   pAddresses = reinterpret_cast<PIP_ADAPTER_ADDRESSES> (buf.begin ());
    // NB: we use GetAdapaterAddresses () instead of GetInterfaceInfo  () so we get non-ipv4 addresses
    DWORD dwRetVal = ::GetAdaptersAddresses (family, flags, nullptr, pAddresses, &ulOutBufLen);
    if (dwRetVal == NO_ERROR) {
        for (PIP_ADAPTER_ADDRESSES currAddresses  = pAddresses; currAddresses != nullptr; currAddresses = currAddresses->Next) {
            Interface   newInterface;
            String      adapterName     { String::FromNarrowSDKString (currAddresses->AdapterName) };
            newInterface.fInternalInterfaceID = adapterName;
            newInterface.fFriendlyName = currAddresses->FriendlyName;
            newInterface.fDescription = currAddresses->Description;
            switch (currAddresses->IfType) {
                case    IF_TYPE_SOFTWARE_LOOPBACK:
                    newInterface.fType = Interface::Type::eLoopback;
                    break;
                case    IF_TYPE_IEEE80211:
                    newInterface.fType = Interface::Type::eWIFI;
                    break;
                case    IF_TYPE_ETHERNET_CSMACD:
                    newInterface.fType = Interface::Type::eWiredEthernet;
                    break;
                default:
                    newInterface.fType = Interface::Type::eOther;
                    break;
            }
            if (currAddresses->TunnelType != TUNNEL_TYPE_NONE) {
                newInterface.fType = Interface::Type::eTunnel;
            }
            switch (currAddresses->OperStatus) {
                case    IfOperStatusUp:
                    newInterface.fStatus = Set<Interface::Status> ({Interface::Status::eConnected, Interface::Status::eRunning});
                    break;
                case    IfOperStatusDown:
                    newInterface.fStatus = Set<Interface::Status> ();
                    break;
                default:
                    // Dont know how to interpret the other status states
                    break;
            }
            for (PIP_ADAPTER_UNICAST_ADDRESS pu = currAddresses->FirstUnicastAddress; pu != nullptr; pu = pu->Next) {
                SocketAddress sa { pu->Address };
                if (sa.IsInternetAddress ()) {
                    newInterface.fBindings.Add (sa.GetInternetAddress ());
                }
            }
            for (PIP_ADAPTER_ANYCAST_ADDRESS pa = currAddresses->FirstAnycastAddress; pa != nullptr; pa = pa->Next) {
                SocketAddress sa { pa->Address };
                if (sa.IsInternetAddress ()) {
                    newInterface.fBindings.Add (sa.GetInternetAddress ());
                }
            }
            for (PIP_ADAPTER_MULTICAST_ADDRESS  pm = currAddresses->FirstMulticastAddress; pm != nullptr; pm = pm->Next) {
                SocketAddress sa { pm->Address };
                if (sa.IsInternetAddress ()) {
                    newInterface.fBindings.Add (sa.GetInternetAddress ());
                }
            }

            if (currAddresses->PhysicalAddressLength == 6) {
                newInterface.fHwardwareAddress = PrintMacAddr_ (currAddresses->PhysicalAddress, currAddresses->PhysicalAddress + 6);
            }

#if     (NTDDI_VERSION >= NTDDI_WIN6)
            newInterface.fTransmitSpeedBaud = currAddresses->TransmitLinkSpeed;
            newInterface.fReceiveLinkSpeedBaud = currAddresses->ReceiveLinkSpeed;
#endif
            result.Add (newInterface);
        }
    }
    else if (dwRetVal == ERROR_BUFFER_OVERFLOW) {
        buf.GrowToSize (ulOutBufLen);
        goto Again;
    }
    else if (dwRetVal == ERROR_NO_DATA) {
        DbgTrace ("There are no network adapters with IPv4 enabled on the local system");
    }
    else {
        Execution::Platform::Windows::Exception::DoThrow (dwRetVal);
    }
#else
    AssertNotImplemented ();
#endif
    return result;
}

/*
 ********************************************************************************
 ************************** Network::GetInterfaceById ***************************
 ********************************************************************************
 */
Optional<Interface>  Network::GetInterfaceById (const String& internalInterfaceID)
{
#if     USE_NOISY_TRACE_IN_THIS_MODULE_
    Debug::TraceContextBumper ctx ("Network::GetInterfaceById");
#endif
    // @todo - a much more efficent implemenation - maybe good enuf to use caller staleness cache with a few seconds staleness
    for (Interface i : Network::GetInterfaces ()) {
        if (i.fInternalInterfaceID == internalInterfaceID) {
#if     USE_NOISY_TRACE_IN_THIS_MODULE_
            DbgTrace (L"found interface %s", internalInterfaceID.c_str ());
#endif
            return i;
        }
    }
#if     USE_NOISY_TRACE_IN_THIS_MODULE_
    DbgTrace (L"interface %s not found", internalInterfaceID.c_str ());
#endif
    return Optional<Interface> ();
}
<commit_msg>fixed newInterface.fHwardwareAddress for Unix<commit_after>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2015.  All rights reserved
 */
#include    "../../StroikaPreComp.h"

#include    <cstdio>
#include    <random>

#if     qPlatform_POSIX
//@todo see how many of these includes are needed
#include    <unistd.h>
#include    <arpa/inet.h>
#include    <net/if.h>
#include    <netinet/in.h>
#include    <netdb.h>
#include    <sys/socket.h>
#include    <sys/ioctl.h>
#include    <net/if_arp.h>
#if     qPlatform_Linux
#include    <linux/types.h>     // needed on RedHat5
#include    <linux/ethtool.h>
#include    <linux/sockios.h>
#endif
#elif   qPlatform_Windows
#include    <WinSock2.h>
#include    <WS2tcpip.h>
#include    <Iphlpapi.h>
#include    <netioapi.h>
#endif

#include    "../../Characters/CString/Utilities.h"
#include    "../../Characters/Format.h"
#include    "../../Containers/Collection.h"
#include    "../../Containers/Mapping.h"
#include    "../../Execution/ErrNoException.h"
#include    "../../Execution/Finally.h"
#if     qPlatform_Windows
#include    "../../../Foundation/Execution/Platform/Windows/Exception.h"
#endif
#include    "../../Execution/Synchronized.h"
#include    "../../Memory/SmallStackBuffer.h"

#include    "Socket.h"

#include    "Interface.h"

using   namespace   Stroika::Foundation;
using   namespace   Stroika::Foundation::Containers;
using   namespace   Stroika::Foundation::Execution;
using   namespace   Stroika::Foundation::Memory;
using   namespace   Stroika::Foundation::IO;
using   namespace   Stroika::Foundation::IO::Network;

// Comment this in to turn on aggressive noisy DbgTrace in this module
//#define   USE_NOISY_TRACE_IN_THIS_MODULE_       1

#if     defined (_MSC_VER)
// support use of Iphlpapi - but better to reference here than in lib entry of project file cuz
// easiser to see/modularize (and only pulled in if this module is referenced)
#pragma comment (lib, "Iphlpapi.lib")
#endif

/*
 ********************************************************************************
 **************************** Network::Interface ********************************
 ********************************************************************************
 */
const Configuration::EnumNames<Interface::Status>   Interface::Stroika_Enum_Names(Status)
{
    { Interface::Status::eConnected, L"Connected" },
    { Interface::Status::eRunning, L"Running" },
};

const Configuration::EnumNames<Interface::Type>   Interface::Stroika_Enum_Names(Type)
{
    { Interface::Type::eLoopback, L"Loopback" },
    { Interface::Type::eWiredEthernet, L"WiredEthernet" },
    { Interface::Type::eWIFI, L"WIFI" },
    { Interface::Type::eTunnel, L"Tunnel" },
    { Interface::Type::eOther, L"Other" },
};

#if     qPlatform_Linux
// Hack for centos5 support:
//      Overload with linux version so other one wins, but this gets called if other doesnt exist
//      TRY --LGP 2015-05-19
template    <typename HACK = int>
static __inline__ __u32 ethtool_cmd_speed (const struct ethtool_cmd* ep, HACK i = 0)
{
    //return (ep->speed_hi << 16) | ep->speed;
    return ep->speed;
}
#endif

namespace {
    // Windows uses '-' as separator, and linux ':'. Pick arbitrarily (more linux machines
    // than windows, or soon will be)
    auto     PrintMacAddr_ (const uint8_t* macaddrBytes, const uint8_t* macaddrBytesEnd) -> String {
        Require (macaddrBytesEnd - macaddrBytes == 6);
        char     buf[100] {};
        (void)snprintf (buf, sizeof (buf), "%02x:%02x:%02x:%02x:%02x:%02x",
                        macaddrBytes[0], macaddrBytes[1],
                        macaddrBytes[2], macaddrBytes[3],
                        macaddrBytes[4], macaddrBytes[5]
                       );
        return String::FromAscii (buf);
    };
}

/*
 ********************************************************************************
 ************************** Network::GetInterfaces ******************************
 ********************************************************************************
 */
Traversal::Iterable<Interface>  Network::GetInterfaces ()
{
#if     USE_NOISY_TRACE_IN_THIS_MODULE_
    Debug::TraceContextBumper ctx ("Network::GetInterfaces");
#endif
    Collection<Interface>   result;
#if     qPlatform_POSIX
    auto getFlags = [] (int sd, const char* name) {
        struct ifreq ifreq {};
        Characters::CString::Copy (ifreq.ifr_name, NEltsOf (ifreq.ifr_name), name);

        int r = ::ioctl (sd, SIOCGIFFLAGS, (char*)&ifreq);
        Assert (r == 0);
        return ifreq.ifr_flags;
    };

    struct ifreq    ifreqs[128] {};
    struct ifconf   ifconf {};
    ifconf.ifc_req = ifreqs;
    ifconf.ifc_len = sizeof(ifreqs);

    int sd = ::socket (PF_INET, SOCK_STREAM, 0);
    Assert (sd >= 0);
    Execution::Finally cleanup ([sd] () {
        ::close (sd);
    });

    int r = ::ioctl (sd, SIOCGIFCONF, (char*)&ifconf);
    Assert (r == 0);

    for (int i = 0; i < ifconf.ifc_len / sizeof(struct ifreq); ++i) {
#if     USE_NOISY_TRACE_IN_THIS_MODULE_
        DbgTrace ("interface: ifr_name=%s; ifr_addr.sa_family = %d", ifreqs[i].ifr_name, ifreqs[i].ifr_addr.sa_family);
#endif
#if     qPlatform_AIX
        // I don't understand the logic behind this, but without this, we get errors
        // in getFlags(). We could check there - and handle that with an extra return value, but this
        // is simpler.
        //
        // And - its somewhat prescribed in https://www.ibm.com/developerworks/community/forums/html/topic?id=77777777-0000-0000-0000-000014698597
        //
        if (ifreqs[i].ifr_addr.sa_family != AF_INET and ifreqs[i].ifr_addr.sa_family != AF_INET6 and ifreqs[i].ifr_addr.sa_family != AF_LINK) {
            // Skip interfaces not bound to and IPv4 or IPv6 address, or AF_LINK (not sure what later is used for)
            // this list of exceptions arrived at experimentally on the one AIX machine I tested (so not good)
            continue;
        }
#endif
        Interface   newInterface;
        String interfaceName { String::FromSDKString (ifreqs[i].ifr_name) };
        newInterface.fInternalInterfaceID = interfaceName;
        newInterface.fFriendlyName = interfaceName;         // not great - maybe find better name - but this will do for now...
        int flags = getFlags (sd, ifreqs[i].ifr_name);

        if (flags & IFF_LOOPBACK) {
            newInterface.fType = Interface::Type::eLoopback;
        }
        else {
            // NYI
            newInterface.fType = Interface::Type::eWiredEthernet;    // WAY - not the right way to tell!
        }

        {
            ifreq   tmp = ifreqs[i];
            if (::ioctl (sd, SIOCGIFHWADDR, &tmp) == 0 and tmp.ifr_hwaddr.sa_family == ARPHRD_ETHER) {
                newInterface.fHwardwareAddress = PrintMacAddr_ (reinterpret_cast<const uint8_t*> (tmp.ifr_hwaddr.sa_data), reinterpret_cast<const uint8_t*> (tmp.ifr_hwaddr.sa_data) + 6);
            }
        }

#if     qPlatform_AIX
        {
            auto getSpeed = [] (int sd, const char* name) -> Optional<uint64_t> {
                struct ifreq ifreq;
                (void)::memset (&ifreq, 0, sizeof (ifreq));
                Characters::CString::Copy (ifreq.ifr_name, NEltsOf (ifreq.ifr_name), name);
                int r = ioctl (sd, SIOCGIFBAUDRATE, &ifreq);
                if (r != 0)
                {
                    DbgTrace ("No speed for interface %s, errno=%d", name, errno);
                    return Optional<uint64_t> ();
                }
                return ifreq.ifr_baudrate;
            };
            newInterface.fTransmitSpeedBaud = getSpeed (sd, ifreqs[i].ifr_name);
            newInterface.fReceiveLinkSpeedBaud = newInterface.fTransmitSpeedBaud;
        }
#elif   qPlatform_Linux
        {
            auto getSpeed = [] (int sd, const char* name) -> Optional<uint64_t> {
                struct ifreq ifreq {};
                Characters::CString::Copy (ifreq.ifr_name, NEltsOf (ifreq.ifr_name), name);
                struct ethtool_cmd edata {};
                ifreq.ifr_data = reinterpret_cast<caddr_t> (&edata);
                edata.cmd = ETHTOOL_GSET;
                int r = ioctl(sd, SIOCETHTOOL, &ifreq);
                if (r != 0)
                {
                    DbgTrace ("No speed for interface %s, errno=%d", name, errno);
                    return Optional<uint64_t> ();
                }
                constexpr uint64_t kMegabit_ = 1000 * 1000;
                DbgTrace ("ethtool_cmd_speed (&edata)=%d", ethtool_cmd_speed (&edata));
                switch (ethtool_cmd_speed (&edata))
                {
                    case SPEED_10:
                        return 10 * kMegabit_;
                    case SPEED_100:
                        return 100 * kMegabit_;
                    case SPEED_1000:
                        return 1000 * kMegabit_;
                    case SPEED_2500:
                        return 2500 * kMegabit_;
                    case SPEED_10000:
                        return 10000 * kMegabit_;
                    default:
                        return Optional<uint64_t> ();
                }
            };
            newInterface.fTransmitSpeedBaud = getSpeed (sd, ifreqs[i].ifr_name);
            newInterface.fReceiveLinkSpeedBaud = newInterface.fTransmitSpeedBaud;
        }
#endif

        {
            Containers::Set<Interface::Status>  status;
            if (flags & IFF_RUNNING) {
                // not right!!! But a start...
                status.Add (Interface::Status::eConnected);
                status.Add (Interface::Status::eRunning);
            }
            newInterface.fStatus = status;
        }
        newInterface.fBindings.Add (InternetAddress (((struct sockaddr_in*)&ifreqs[i].ifr_addr)->sin_addr));    // @todo fix so works for ipv6 addresses as well!
        result.Add (newInterface);
    }
#elif   qPlatform_Windows
    ULONG flags = GAA_FLAG_INCLUDE_PREFIX;
    ULONG family = AF_UNSPEC;       // Both IPv4 and IPv6 addresses
    Memory::SmallStackBuffer<Byte>  buf(0);
Again:
    ULONG ulOutBufLen = static_cast<ULONG> (buf.GetSize ());
    PIP_ADAPTER_ADDRESSES   pAddresses = reinterpret_cast<PIP_ADAPTER_ADDRESSES> (buf.begin ());
    // NB: we use GetAdapaterAddresses () instead of GetInterfaceInfo  () so we get non-ipv4 addresses
    DWORD dwRetVal = ::GetAdaptersAddresses (family, flags, nullptr, pAddresses, &ulOutBufLen);
    if (dwRetVal == NO_ERROR) {
        for (PIP_ADAPTER_ADDRESSES currAddresses  = pAddresses; currAddresses != nullptr; currAddresses = currAddresses->Next) {
            Interface   newInterface;
            String      adapterName     { String::FromNarrowSDKString (currAddresses->AdapterName) };
            newInterface.fInternalInterfaceID = adapterName;
            newInterface.fFriendlyName = currAddresses->FriendlyName;
            newInterface.fDescription = currAddresses->Description;
            switch (currAddresses->IfType) {
                case    IF_TYPE_SOFTWARE_LOOPBACK:
                    newInterface.fType = Interface::Type::eLoopback;
                    break;
                case    IF_TYPE_IEEE80211:
                    newInterface.fType = Interface::Type::eWIFI;
                    break;
                case    IF_TYPE_ETHERNET_CSMACD:
                    newInterface.fType = Interface::Type::eWiredEthernet;
                    break;
                default:
                    newInterface.fType = Interface::Type::eOther;
                    break;
            }
            if (currAddresses->TunnelType != TUNNEL_TYPE_NONE) {
                newInterface.fType = Interface::Type::eTunnel;
            }
            switch (currAddresses->OperStatus) {
                case    IfOperStatusUp:
                    newInterface.fStatus = Set<Interface::Status> ({Interface::Status::eConnected, Interface::Status::eRunning});
                    break;
                case    IfOperStatusDown:
                    newInterface.fStatus = Set<Interface::Status> ();
                    break;
                default:
                    // Dont know how to interpret the other status states
                    break;
            }
            for (PIP_ADAPTER_UNICAST_ADDRESS pu = currAddresses->FirstUnicastAddress; pu != nullptr; pu = pu->Next) {
                SocketAddress sa { pu->Address };
                if (sa.IsInternetAddress ()) {
                    newInterface.fBindings.Add (sa.GetInternetAddress ());
                }
            }
            for (PIP_ADAPTER_ANYCAST_ADDRESS pa = currAddresses->FirstAnycastAddress; pa != nullptr; pa = pa->Next) {
                SocketAddress sa { pa->Address };
                if (sa.IsInternetAddress ()) {
                    newInterface.fBindings.Add (sa.GetInternetAddress ());
                }
            }
            for (PIP_ADAPTER_MULTICAST_ADDRESS  pm = currAddresses->FirstMulticastAddress; pm != nullptr; pm = pm->Next) {
                SocketAddress sa { pm->Address };
                if (sa.IsInternetAddress ()) {
                    newInterface.fBindings.Add (sa.GetInternetAddress ());
                }
            }

            if (currAddresses->PhysicalAddressLength == 6) {
                newInterface.fHwardwareAddress = PrintMacAddr_ (currAddresses->PhysicalAddress, currAddresses->PhysicalAddress + 6);
            }

#if     (NTDDI_VERSION >= NTDDI_WIN6)
            newInterface.fTransmitSpeedBaud = currAddresses->TransmitLinkSpeed;
            newInterface.fReceiveLinkSpeedBaud = currAddresses->ReceiveLinkSpeed;
#endif
            result.Add (newInterface);
        }
    }
    else if (dwRetVal == ERROR_BUFFER_OVERFLOW) {
        buf.GrowToSize (ulOutBufLen);
        goto Again;
    }
    else if (dwRetVal == ERROR_NO_DATA) {
        DbgTrace ("There are no network adapters with IPv4 enabled on the local system");
    }
    else {
        Execution::Platform::Windows::Exception::DoThrow (dwRetVal);
    }
#else
    AssertNotImplemented ();
#endif
    return result;
}

/*
 ********************************************************************************
 ************************** Network::GetInterfaceById ***************************
 ********************************************************************************
 */
Optional<Interface>  Network::GetInterfaceById (const String& internalInterfaceID)
{
#if     USE_NOISY_TRACE_IN_THIS_MODULE_
    Debug::TraceContextBumper ctx ("Network::GetInterfaceById");
#endif
    // @todo - a much more efficent implemenation - maybe good enuf to use caller staleness cache with a few seconds staleness
    for (Interface i : Network::GetInterfaces ()) {
        if (i.fInternalInterfaceID == internalInterfaceID) {
#if     USE_NOISY_TRACE_IN_THIS_MODULE_
            DbgTrace (L"found interface %s", internalInterfaceID.c_str ());
#endif
            return i;
        }
    }
#if     USE_NOISY_TRACE_IN_THIS_MODULE_
    DbgTrace (L"interface %s not found", internalInterfaceID.c_str ());
#endif
    return Optional<Interface> ();
}
<|endoftext|>


<commit_before>/*
 * LuaSceneObject.cpp
 *
 *  Created on: 27/05/2011
 *      Author: victor
 */

#include "LuaSceneObject.h"
#include "SceneObject.h"
#include "server/zone/objects/creature/CreatureObject.h"
#include "server/zone/objects/cell/CellObject.h"
#include "server/zone/packets/cell/UpdateCellPermissionsMessage.h"

const char LuaSceneObject::className[] = "LuaSceneObject";

Luna<LuaSceneObject>::RegType LuaSceneObject::Register[] = {
		{ "_setObject", &LuaSceneObject::_setObject },
		{ "getParent", &LuaSceneObject::getParent },
		{ "getObjectID", &LuaSceneObject::getObjectID },
		{ "getPositionX", &LuaSceneObject::getPositionX },
		{ "getPositionY", &LuaSceneObject::getPositionY },
		{ "getPositionZ", &LuaSceneObject::getPositionZ },
		{ "getParentID", &LuaSceneObject::getParentID },
		{ "isInRangeWithObject", &LuaSceneObject::isInRangeWithObject },
		{ "getDistanceTo", &LuaSceneObject::getDistanceTo },
		{ "updateDirection", &LuaSceneObject::updateDirection },
		{ "getServerObjectCRC", &LuaSceneObject::getServerObjectCRC },
		{ "showFlyText", &LuaSceneObject::showFlyText },
		{ "getContainerObject", &LuaSceneObject::getContainerObject },
		{ "getContainerObjectsSize", &LuaSceneObject::getContainerObjectsSize },
		{ "getSlottedObject", &LuaSceneObject::getSlottedObject },
		{ "transferObject", &LuaSceneObject::transferObject },
//		{ "removeObject", &LuaSceneObject::removeObject },
		{ "getGameObjectType", &LuaSceneObject::getGameObjectType },
		{ "faceObject", &LuaSceneObject::faceObject },
		{ "destroyObjectFromWorld", &LuaSceneObject::destroyObjectFromWorld },
		{ "isCreatureObject", &LuaSceneObject::isCreatureObject },
		{ "updateCellPermission", &LuaSceneObject::updateCellPermission },
		{ "sendTo", &LuaSceneObject::sendTo },
		{ "getCustomObjectName", &LuaSceneObject::getCustomObjectName },
		{ "getContainerObjectById", &LuaSceneObject::getContainerObjectById },
		{ "setDirectionalHeading", &LuaSceneObject::setDirectionalHeading },
		{ 0, 0 }
};

LuaSceneObject::LuaSceneObject(lua_State *L) {
	realObject = (SceneObject*)lua_touserdata(L, 1);
}

LuaSceneObject::~LuaSceneObject(){
}

int LuaSceneObject::_setObject(lua_State* L) {
	realObject = (SceneObject*)lua_touserdata(L, -1);

	return 0;
}

int LuaSceneObject::getPositionX(lua_State* L) {
	lua_pushnumber(L, realObject->getPositionX());

	return 1;
}

int LuaSceneObject::getPositionZ(lua_State* L) {
	lua_pushnumber(L, realObject->getPositionZ());

	return 1;
}

int LuaSceneObject::getPositionY(lua_State* L) {
	lua_pushnumber(L, realObject->getPositionY());

	return 1;
}

int LuaSceneObject::getObjectID(lua_State* L) {
	lua_pushinteger(L, realObject->getObjectID());

	return 1;
}

int LuaSceneObject::getParentID(lua_State* L) {
	lua_pushinteger(L, realObject->getParentID());

	return 1;
}

int LuaSceneObject::isInRange(lua_State* L) {
//public boolean isInRange(float x, float y, float range) {
	float range = lua_tonumber(L, -1);
	float y = lua_tonumber(L, -2);
	float x = lua_tonumber(L, -3);

	bool res = (static_cast<QuadTreeEntry*>(realObject))->isInRange(x, y, range);

	lua_pushnumber(L, res);

	return 1;
}

int LuaSceneObject::getGameObjectType(lua_State* L) {
	uint32 type = realObject->getGameObjectType();

	lua_pushnumber(L, type);

	return 1;
}

int LuaSceneObject::getDistanceTo(lua_State* L) {
	SceneObject* obj = (SceneObject*)lua_touserdata(L, -1);

	float res = realObject->getDistanceTo(obj);

	lua_pushnumber(L, res);

	return 1;
}

int LuaSceneObject::getServerObjectCRC(lua_State* L) {
	uint32 crc = realObject->getServerObjectCRC();

	lua_pushnumber(L, crc);

	return 1;
}

int LuaSceneObject::faceObject(lua_State* L) {
	SceneObject* obj = (SceneObject*)lua_touserdata(L, -1);

	realObject->faceObject(obj);

	return 0;
}

int LuaSceneObject::isInRangeWithObject(lua_State* L) {
	float range = lua_tonumber(L, -1);
	SceneObject* obj = (SceneObject*)lua_touserdata(L, -2);

	bool res = realObject->isInRange(obj, range);

	lua_pushnumber(L, res);

	return 1;
}

int LuaSceneObject::getParent(lua_State* L) {
	SceneObject* obj = realObject->getParent();

	lua_pushlightuserdata(L, obj);

	return 1;
}

int LuaSceneObject::getContainerObject(lua_State* L) {
	int idx = lua_tonumber(L, -1);

	SceneObject* obj = realObject->getContainerObject(idx);

	lua_pushlightuserdata(L, obj);

	return 1;
}

int LuaSceneObject::getContainerObjectById(lua_State* L) {
	uint64 objectID = lua_tointeger(L, -1);

	SceneObject* obj = realObject->getContainerObject(objectID);

	lua_pushlightuserdata(L, obj);

	return 1;
}

int LuaSceneObject::getSlottedObject(lua_State* L) {
	String slot = lua_tostring(L, -1);

	SceneObject* obj = realObject->getSlottedObject(slot);

	lua_pushlightuserdata(L, obj);

	return 1;
}

int LuaSceneObject::transferObject(lua_State* L) {
	//transferObject(SceneObject object, int containmentType, boolean notifyClient = false);

	bool notifyClient = lua_tonumber(L, -1);
	int containmentType = lua_tonumber(L, -2);
	SceneObject* obj = (SceneObject*) lua_touserdata(L, -3);

	realObject->transferObject(obj, containmentType, notifyClient);

	return 0;
}

/*int LuaSceneObject::removeObject(lua_State* L) {

	//removeObject(SceneObject object, boolean notifyClient = false);

	bool notifyClient = lua_tonumber(L, -1);
	SceneObject* obj = (SceneObject*) lua_touserdata(L, -2);

	realObject->removeObject(obj, notifyClient);

	return 0;
}*/

int LuaSceneObject::getContainerObjectsSize(lua_State* L) {
	int num = realObject->getContainerObjectsSize();

	lua_pushnumber(L, num);

	return 1;
}

int LuaSceneObject::showFlyText(lua_State* L) {
	//final string file, final string uax, byte red, byte green, byte blue

	byte blue = lua_tonumber(L, -1);
	byte green = lua_tonumber(L, -2);
	byte red = lua_tonumber(L, -3);

	String aux = lua_tostring(L, -4);
	String file = lua_tostring(L, -5);

	realObject->showFlyText(file, aux, red, green, blue);

	return 0;
}

int LuaSceneObject::updateDirection(lua_State* L) {
	//void updateDirection(float fw, float fx, float fy, float fz);

	float fz = lua_tonumber(L, -1);
	float fy = lua_tonumber(L, -2);
	float fx = lua_tonumber(L, -3);
	float fw = lua_tonumber(L, -4);

	realObject->updateDirection(fw, fx, fy, fz);

	return 0;
}

int LuaSceneObject::destroyObjectFromWorld(lua_State* L) {
	realObject->destroyObjectFromWorld(true);

	return 0;
}

int LuaSceneObject::isCreatureObject(lua_State* L) {
	bool val = realObject->isCreatureObject();

	lua_pushboolean(L, val);

	return 1;
}

int LuaSceneObject::updateCellPermission(lua_State* L) {
	//realObject->info("getting values",true);
	int allowEntry = lua_tonumber(L, -2);
	CreatureObject* obj = (CreatureObject*)lua_touserdata(L, -1);
	//realObject->info("allowentry:" + String::valueOf(allowEntry), true);
	if (obj == NULL)
		return 0;

	//realObject->info("values not NULL", true);

	if (!realObject->isCellObject()) {
		realObject->info("Unknown entity error: Cell", true);
		return 0;
	}

	if (!obj->isCreatureObject()) {
		//realObject->info("Unknown entity error: Creature", true);
		obj->info("Unknown entity error: Creature", true);
		return 0;
	}

	//realObject->info("checks are fine", true);

	BaseMessage* perm = new UpdateCellPermissionsMessage(realObject->getObjectID(), allowEntry);
	obj->sendMessage(perm);

	return 0;
}

int LuaSceneObject::wlock(lua_State* L) {
	return 0;
}

int LuaSceneObject::unlock(lua_State* L) {
	return 0;
}

int LuaSceneObject::sendTo(lua_State* L) {
	SceneObject* obj = (SceneObject*) lua_touserdata(L, -1);

	realObject->sendTo(obj, true);

	return 0;
}

int LuaSceneObject::getCustomObjectName(lua_State* L) {
	String objname = realObject->getCustomObjectName().toString();

	lua_pushstring(L, objname);

	return 1;
}

int LuaSceneObject::setDirectionalHeading(lua_State* L) {
	int heading = lua_tointeger(L, -1);
	SceneObject* obj = (SceneObject*) lua_touserdata(L, -2);

	realObject->setDirection(heading);

	return 0;
}
<commit_msg>[fixed] Hopefully fixes a lua issue that crashes when Sith Altar is missing from inventory.<commit_after>/*
 * LuaSceneObject.cpp
 *
 *  Created on: 27/05/2011
 *      Author: victor
 */

#include "LuaSceneObject.h"
#include "SceneObject.h"
#include "server/zone/objects/creature/CreatureObject.h"
#include "server/zone/objects/cell/CellObject.h"
#include "server/zone/packets/cell/UpdateCellPermissionsMessage.h"

const char LuaSceneObject::className[] = "LuaSceneObject";

Luna<LuaSceneObject>::RegType LuaSceneObject::Register[] = {
		{ "_setObject", &LuaSceneObject::_setObject },
		{ "getParent", &LuaSceneObject::getParent },
		{ "getObjectID", &LuaSceneObject::getObjectID },
		{ "getPositionX", &LuaSceneObject::getPositionX },
		{ "getPositionY", &LuaSceneObject::getPositionY },
		{ "getPositionZ", &LuaSceneObject::getPositionZ },
		{ "getParentID", &LuaSceneObject::getParentID },
		{ "isInRangeWithObject", &LuaSceneObject::isInRangeWithObject },
		{ "getDistanceTo", &LuaSceneObject::getDistanceTo },
		{ "updateDirection", &LuaSceneObject::updateDirection },
		{ "getServerObjectCRC", &LuaSceneObject::getServerObjectCRC },
		{ "showFlyText", &LuaSceneObject::showFlyText },
		{ "getContainerObject", &LuaSceneObject::getContainerObject },
		{ "getContainerObjectsSize", &LuaSceneObject::getContainerObjectsSize },
		{ "getSlottedObject", &LuaSceneObject::getSlottedObject },
		{ "transferObject", &LuaSceneObject::transferObject },
//		{ "removeObject", &LuaSceneObject::removeObject },
		{ "getGameObjectType", &LuaSceneObject::getGameObjectType },
		{ "faceObject", &LuaSceneObject::faceObject },
		{ "destroyObjectFromWorld", &LuaSceneObject::destroyObjectFromWorld },
		{ "isCreatureObject", &LuaSceneObject::isCreatureObject },
		{ "updateCellPermission", &LuaSceneObject::updateCellPermission },
		{ "sendTo", &LuaSceneObject::sendTo },
		{ "getCustomObjectName", &LuaSceneObject::getCustomObjectName },
		{ "getContainerObjectById", &LuaSceneObject::getContainerObjectById },
		{ "setDirectionalHeading", &LuaSceneObject::setDirectionalHeading },
		{ 0, 0 }
};

LuaSceneObject::LuaSceneObject(lua_State *L) {
	realObject = (SceneObject*)lua_touserdata(L, 1);
}

LuaSceneObject::~LuaSceneObject(){
}

int LuaSceneObject::_setObject(lua_State* L) {
	realObject = (SceneObject*)lua_touserdata(L, -1);

	return 0;
}

int LuaSceneObject::getPositionX(lua_State* L) {
	lua_pushnumber(L, realObject->getPositionX());

	return 1;
}

int LuaSceneObject::getPositionZ(lua_State* L) {
	lua_pushnumber(L, realObject->getPositionZ());

	return 1;
}

int LuaSceneObject::getPositionY(lua_State* L) {
	lua_pushnumber(L, realObject->getPositionY());

	return 1;
}

int LuaSceneObject::getObjectID(lua_State* L) {
	lua_pushinteger(L, realObject->getObjectID());

	return 1;
}

int LuaSceneObject::getParentID(lua_State* L) {
	lua_pushinteger(L, realObject->getParentID());

	return 1;
}

int LuaSceneObject::isInRange(lua_State* L) {
//public boolean isInRange(float x, float y, float range) {
	float range = lua_tonumber(L, -1);
	float y = lua_tonumber(L, -2);
	float x = lua_tonumber(L, -3);

	bool res = (static_cast<QuadTreeEntry*>(realObject))->isInRange(x, y, range);

	lua_pushnumber(L, res);

	return 1;
}

int LuaSceneObject::getGameObjectType(lua_State* L) {
	uint32 type = realObject->getGameObjectType();

	lua_pushnumber(L, type);

	return 1;
}

int LuaSceneObject::getDistanceTo(lua_State* L) {
	SceneObject* obj = (SceneObject*)lua_touserdata(L, -1);

	float res = realObject->getDistanceTo(obj);

	lua_pushnumber(L, res);

	return 1;
}

int LuaSceneObject::getServerObjectCRC(lua_State* L) {
	uint32 crc = realObject->getServerObjectCRC();

	lua_pushnumber(L, crc);

	return 1;
}

int LuaSceneObject::faceObject(lua_State* L) {
	SceneObject* obj = (SceneObject*)lua_touserdata(L, -1);

	realObject->faceObject(obj);

	return 0;
}

int LuaSceneObject::isInRangeWithObject(lua_State* L) {
	float range = lua_tonumber(L, -1);
	SceneObject* obj = (SceneObject*)lua_touserdata(L, -2);

	bool res = realObject->isInRange(obj, range);

	lua_pushnumber(L, res);

	return 1;
}

int LuaSceneObject::getParent(lua_State* L) {
	SceneObject* obj = realObject->getParent();

	lua_pushlightuserdata(L, obj);

	return 1;
}

int LuaSceneObject::getContainerObject(lua_State* L) {
	int idx = lua_tonumber(L, -1);

	SceneObject* obj = realObject->getContainerObject(idx);

	lua_pushlightuserdata(L, obj);

	return 1;
}

int LuaSceneObject::getContainerObjectById(lua_State* L) {
	uint64 objectID = lua_tointeger(L, -1);

	SceneObject* obj = realObject->getContainerObject(objectID);

	if (obj != NULL) {
		lua_pushlightuserdata(L, obj);
	} else {
		lua_pushnil(L);
	}

	return 1;
}

int LuaSceneObject::getSlottedObject(lua_State* L) {
	String slot = lua_tostring(L, -1);

	SceneObject* obj = realObject->getSlottedObject(slot);

	lua_pushlightuserdata(L, obj);

	return 1;
}

int LuaSceneObject::transferObject(lua_State* L) {
	//transferObject(SceneObject object, int containmentType, boolean notifyClient = false);

	bool notifyClient = lua_tonumber(L, -1);
	int containmentType = lua_tonumber(L, -2);
	SceneObject* obj = (SceneObject*) lua_touserdata(L, -3);

	realObject->transferObject(obj, containmentType, notifyClient);

	return 0;
}

/*int LuaSceneObject::removeObject(lua_State* L) {

	//removeObject(SceneObject object, boolean notifyClient = false);

	bool notifyClient = lua_tonumber(L, -1);
	SceneObject* obj = (SceneObject*) lua_touserdata(L, -2);

	realObject->removeObject(obj, notifyClient);

	return 0;
}*/

int LuaSceneObject::getContainerObjectsSize(lua_State* L) {
	int num = realObject->getContainerObjectsSize();

	lua_pushnumber(L, num);

	return 1;
}

int LuaSceneObject::showFlyText(lua_State* L) {
	//final string file, final string uax, byte red, byte green, byte blue

	byte blue = lua_tonumber(L, -1);
	byte green = lua_tonumber(L, -2);
	byte red = lua_tonumber(L, -3);

	String aux = lua_tostring(L, -4);
	String file = lua_tostring(L, -5);

	realObject->showFlyText(file, aux, red, green, blue);

	return 0;
}

int LuaSceneObject::updateDirection(lua_State* L) {
	//void updateDirection(float fw, float fx, float fy, float fz);

	float fz = lua_tonumber(L, -1);
	float fy = lua_tonumber(L, -2);
	float fx = lua_tonumber(L, -3);
	float fw = lua_tonumber(L, -4);

	realObject->updateDirection(fw, fx, fy, fz);

	return 0;
}

int LuaSceneObject::destroyObjectFromWorld(lua_State* L) {
	realObject->destroyObjectFromWorld(true);

	return 0;
}

int LuaSceneObject::isCreatureObject(lua_State* L) {
	bool val = realObject->isCreatureObject();

	lua_pushboolean(L, val);

	return 1;
}

int LuaSceneObject::updateCellPermission(lua_State* L) {
	//realObject->info("getting values",true);
	int allowEntry = lua_tonumber(L, -2);
	CreatureObject* obj = (CreatureObject*)lua_touserdata(L, -1);
	//realObject->info("allowentry:" + String::valueOf(allowEntry), true);
	if (obj == NULL)
		return 0;

	//realObject->info("values not NULL", true);

	if (!realObject->isCellObject()) {
		realObject->info("Unknown entity error: Cell", true);
		return 0;
	}

	if (!obj->isCreatureObject()) {
		//realObject->info("Unknown entity error: Creature", true);
		obj->info("Unknown entity error: Creature", true);
		return 0;
	}

	//realObject->info("checks are fine", true);

	BaseMessage* perm = new UpdateCellPermissionsMessage(realObject->getObjectID(), allowEntry);
	obj->sendMessage(perm);

	return 0;
}

int LuaSceneObject::wlock(lua_State* L) {
	return 0;
}

int LuaSceneObject::unlock(lua_State* L) {
	return 0;
}

int LuaSceneObject::sendTo(lua_State* L) {
	SceneObject* obj = (SceneObject*) lua_touserdata(L, -1);

	realObject->sendTo(obj, true);

	return 0;
}

int LuaSceneObject::getCustomObjectName(lua_State* L) {
	String objname = realObject->getCustomObjectName().toString();

	lua_pushstring(L, objname);

	return 1;
}

int LuaSceneObject::setDirectionalHeading(lua_State* L) {
	int heading = lua_tointeger(L, -1);
	SceneObject* obj = (SceneObject*) lua_touserdata(L, -2);

	realObject->setDirection(heading);

	return 0;
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
 *
 * This file is part of Orfeo Toolbox
 *
 *     https://www.orfeo-toolbox.org/
 *
 * 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 "otbVectorImage.h"
#include "itkVector.h"
#include "otbImage.h"
#include "otbImageFileReader.h"
#include "otbImageFileWriter.h"
#include "otbStreamingWarpImageFilter.h"

// Images definition
const unsigned int Dimension = 2;
typedef double                                      PixelType;
typedef otb::Image<PixelType, Dimension>            ImageType;
typedef itk::Vector<PixelType, 2>                   DisplacementValueType;
typedef otb::Image<DisplacementValueType, Dimension> DisplacementFieldType;

  // Warper
  typedef otb::StreamingWarpImageFilter<ImageType, ImageType, DisplacementFieldType> ImageWarperType;

int otbStreamingWarpImageFilter(int argc, char* argv[])
{
  if (argc != 5)
    {
    std::cout << "usage: " << argv[0] << "infname deffname outfname radius" << std::endl;
    return EXIT_SUCCESS;
    }

  // Input parameters
  const char * infname = argv[1];
  const char * deffname = argv[2];
  const char * outfname = argv[3];
  const double maxdef = atoi(argv[4]);

  // Change default output origin
  ImageType::PointType origin;
  origin.Fill(0.5);

  // Reader/Writer
  typedef otb::ImageFileReader<ImageType>            ReaderType;
  typedef otb::ImageFileReader<DisplacementFieldType> DisplacementReaderType;
  typedef otb::ImageFileWriter<ImageType>   WriterType;

  // Objects creation
  DisplacementReaderType::Pointer displacementReader = DisplacementReaderType::New();
  ReaderType::Pointer            reader = ReaderType::New();
  WriterType::Pointer            writer = WriterType::New();
  ImageWarperType::Pointer       warper = ImageWarperType::New();

  // Reading
  reader->SetFileName(infname);
  displacementReader->SetFileName(deffname);

  // Warping
  DisplacementValueType maxDisplacement;
  maxDisplacement.Fill(maxdef);
  warper->SetMaximumDisplacement(maxDisplacement);
  warper->SetInput(reader->GetOutput());
  warper->SetDisplacementField(displacementReader->GetOutput());
  warper->SetOutputOrigin(origin);

  // Writing
  writer->SetInput(warper->GetOutput());
  writer->SetFileName(outfname);
  writer->Update();

  return EXIT_SUCCESS;
}

int otbStreamingWarpImageFilterEmptyRegion(int, const char**)
{
  ImageType:: Pointer inputPtr = ImageType::New();

  ImageType::RegionType largestRegion;
  ImageType::SizeType largestSize = {{10,10}};
  ImageType::IndexType largestIndex = {{1,1}};

  largestRegion.SetIndex(largestIndex);
  largestRegion.SetSize(largestSize);

  inputPtr->SetRegions(largestRegion);

  ImageType::RegionType emptyRegion;
  ImageType::SizeType emptySize = {{0,0}};
  ImageType::IndexType emptyIndex = {{0,0}};
  emptyRegion.SetSize(emptySize);
  emptyRegion.SetIndex(emptyIndex);

  inputPtr->SetRequestedRegion(emptyRegion);
  inputPtr->SetBufferedRegion(emptyRegion);

  DisplacementFieldType::Pointer dispPtr = DisplacementFieldType::New();
  dispPtr->SetRegions(largestRegion);
  dispPtr->Allocate();

  DisplacementValueType v;
  v[0]=-100;
  v[1]=-100;
  dispPtr->FillBuffer(v);

  ImageWarperType::Pointer warper = ImageWarperType::New();

  warper->SetDisplacementField(dispPtr);
  warper->SetInput(inputPtr);

  ImageType::PointType outputOrigin;
  outputOrigin.Fill(0);
  warper->SetOutputOrigin(outputOrigin);

  // requested region for full output is completely outside largest
  // possible region of input
  warper->GetOutput()->UpdateOutputInformation();

  // Before bugfix this would lead to famous ITK exception outside of
  // largest possible region
  warper->GetOutput()->PropagateRequestedRegion();

  // After requested region has been propagated, we need to be sure
  // that requested region can be cropped by largest region
  auto requestedRegion = inputPtr->GetRequestedRegion();

  if (! requestedRegion.Crop(inputPtr->GetLargestPossibleRegion()) )
    {
    std::cerr<<"Requested region can not be cropped by largest region"<<std::endl;
    return EXIT_FAILURE;
    }

  // And we also need to check that requested region is not largest
  // region
  if( inputPtr->GetRequestedRegion().GetNumberOfPixels() != 0)
    {
    std::cerr<<"Requested region should have {{0, 0}} size"<<std::endl;
    return EXIT_FAILURE;
    }

  return EXIT_SUCCESS;
}
<commit_msg>COMP: attempt to fix windows builds 2/2<commit_after>/*
 * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
 *
 * This file is part of Orfeo Toolbox
 *
 *     https://www.orfeo-toolbox.org/
 *
 * 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 "otbVectorImage.h"
#include "itkVector.h"
#include "otbImage.h"
#include "otbImageFileReader.h"
#include "otbImageFileWriter.h"
#include "otbStreamingWarpImageFilter.h"

// Images definition
const unsigned int Dimension = 2;
typedef double                                      PixelType;
typedef otb::Image<PixelType, Dimension>            ImageType;
typedef itk::Vector<PixelType, 2>                   DisplacementValueType;
typedef otb::Image<DisplacementValueType, Dimension> DisplacementFieldType;

  // Warper
  typedef otb::StreamingWarpImageFilter<ImageType, ImageType, DisplacementFieldType> ImageWarperType;

int otbStreamingWarpImageFilter(int argc, char* argv[])
{
  if (argc != 5)
    {
    std::cout << "usage: " << argv[0] << "infname deffname outfname radius" << std::endl;
    return EXIT_SUCCESS;
    }

  // Input parameters
  const char * infname = argv[1];
  const char * deffname = argv[2];
  const char * outfname = argv[3];
  const double maxdef = atoi(argv[4]);

  // Change default output origin
  ImageType::PointType origin;
  origin.Fill(0.5);

  // Reader/Writer
  typedef otb::ImageFileReader<ImageType>            ReaderType;
  typedef otb::ImageFileReader<DisplacementFieldType> DisplacementReaderType;
  typedef otb::ImageFileWriter<ImageType>   WriterType;

  // Objects creation
  DisplacementReaderType::Pointer displacementReader = DisplacementReaderType::New();
  ReaderType::Pointer            reader = ReaderType::New();
  WriterType::Pointer            writer = WriterType::New();
  ImageWarperType::Pointer       warper = ImageWarperType::New();

  // Reading
  reader->SetFileName(infname);
  displacementReader->SetFileName(deffname);

  // Warping
  DisplacementValueType maxDisplacement;
  maxDisplacement.Fill(maxdef);
  warper->SetMaximumDisplacement(maxDisplacement);
  warper->SetInput(reader->GetOutput());
  warper->SetDisplacementField(displacementReader->GetOutput());
  warper->SetOutputOrigin(origin);

  // Writing
  writer->SetInput(warper->GetOutput());
  writer->SetFileName(outfname);
  writer->Update();

  return EXIT_SUCCESS;
}

int otbStreamingWarpImageFilterEmptyRegion(int itkNotUsed(argc), char* itkNotUsed(argv)[])
{
  ImageType:: Pointer inputPtr = ImageType::New();

  ImageType::RegionType largestRegion;
  ImageType::SizeType largestSize = {{10,10}};
  ImageType::IndexType largestIndex = {{1,1}};

  largestRegion.SetIndex(largestIndex);
  largestRegion.SetSize(largestSize);

  inputPtr->SetRegions(largestRegion);

  ImageType::RegionType emptyRegion;
  ImageType::SizeType emptySize = {{0,0}};
  ImageType::IndexType emptyIndex = {{0,0}};
  emptyRegion.SetSize(emptySize);
  emptyRegion.SetIndex(emptyIndex);

  inputPtr->SetRequestedRegion(emptyRegion);
  inputPtr->SetBufferedRegion(emptyRegion);

  DisplacementFieldType::Pointer dispPtr = DisplacementFieldType::New();
  dispPtr->SetRegions(largestRegion);
  dispPtr->Allocate();

  DisplacementValueType v;
  v[0]=-100;
  v[1]=-100;
  dispPtr->FillBuffer(v);

  ImageWarperType::Pointer warper = ImageWarperType::New();

  warper->SetDisplacementField(dispPtr);
  warper->SetInput(inputPtr);

  ImageType::PointType outputOrigin;
  outputOrigin.Fill(0);
  warper->SetOutputOrigin(outputOrigin);

  // requested region for full output is completely outside largest
  // possible region of input
  warper->GetOutput()->UpdateOutputInformation();

  // Before bugfix this would lead to famous ITK exception outside of
  // largest possible region
  warper->GetOutput()->PropagateRequestedRegion();

  // After requested region has been propagated, we need to be sure
  // that requested region can be cropped by largest region
  auto requestedRegion = inputPtr->GetRequestedRegion();

  if (! requestedRegion.Crop(inputPtr->GetLargestPossibleRegion()) )
    {
    std::cerr<<"Requested region can not be cropped by largest region"<<std::endl;
    return EXIT_FAILURE;
    }

  // And we also need to check that requested region is not largest
  // region
  if( inputPtr->GetRequestedRegion().GetNumberOfPixels() != 0)
    {
    std::cerr<<"Requested region should have {{0, 0}} size"<<std::endl;
    return EXIT_FAILURE;
    }

  return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>// CommonFunc.cpp -- source file
/*
 * Author: Ivan Chapkailo (septimomend)
 * Date:   02.07.2017
 *
 * © 2017 Ivan Chapkailo. All rights reserved
 * e-mail: chapkailo.ivan@gmail.com
 */

#include "stdafx.h"
#include "CommonFunc.h"

Common::Common()
{
  m_All = tml.getAllControllerObj();
  m_pCnfg = m_All->getConfigObj();
}

Common::Common(AllControllers* all) : m_pCnfg(all->getConfigObj())
{
}

void Common::openFile(char *filename)
{
  free(m_pCnfg->pFilename);                                                       // free pFilename becouse strdup uses malloc and in next func
                                                                                // call need to free memory
  m_pCnfg->pFilename = strdup(filename);                                          // duplicate filename to pFilename

  m_All->pickSyntaxClr();

  FILE* fln = fopen(filename, "r");                                                // open file foe reading
  if (!fln)                                                                        // if can't to open file
    tml.emergencyDestruction("fopen");                                            // forced closure

  char* pStr = NULL;
  size_t strUSZ = 0;                                                              // size
  ssize_t strSSZ;                                                                 // signed size
  while ((strSSZ = getline(&pStr, &strUSZ, fln)) != -1)                            // while strUSZ size of pStr that reads from file fp
  {
    while (strSSZ > 0 && (pStr[strSSZ - 1] == '\n' || pStr[strSSZ - 1] == '\r'))  // if this is end of line
      strSSZ--;                                                                   // decrease line size
    m_pCnfg->setRow(m_pCnfg->rowCount, pStr, strSSZ);                             // set rows from file
  }
  free(pStr);
  fclose(fln);                                                                    // close file
  m_pCnfg->smear = 0;                                                             // no changes in now opened file
}

void detectCallback(char* query, int key)
{
  // TODO
}

void Common::save()
{
  // TODO
}

void Common::find()
{
  // TODO
}

void Common::drawRows(Adbfr* abfr);
{
  // TODO
}

void Common::drawStatusBar(Adbfr* abfr)
{
  // TODO
}

void Common::drawMessageBar(Adbfr* abfr)
{
  // TODO
}

void Common::scrolling()
{
  // TODO
}

void Common::statusMsg(const char *fmt, ...)
{
  va_list arg;         // for unknown number of parameters
  va_start(arg, fmt);  // initialize arg
  vsnprintf(cnfg.statusMessage, sizeof(cnfg.statusMessage), fmt, arg); // output parameters to statusMessage
  va_end(arg); // end
  cnfg.statusMessageTime = time(NULL); // gets time
}

void Common::updateScreen()
{
  scrolling();

  m_abfr = ADBFR_IMPL; // implement to NULL

  m_abfr.reallocateBfr("\x1b[?25l", 6); // reallocate data
  m_abfr.reallocateBfr("\x1b[H", 3);    // reallocate data

  /*
   * draw rows, message bar and status bar
   */
  drawRows(&m_abfr);
  drawStatusBar(&m_abfr);
  drawMessageBar(&m_abfr);

  /*
   * write to buff cursor | position
   */
  char buff[32];
  snprintf(buff, sizeof(buff), "\x1b[%d;%dH", (m_pCnfg->configY - m_pCnfg->disableRow) + 1, (m_pCnfg->rowX - m_pCnfg->disableClr) + 1);
  m_abfr.reallocateBfr(buff, strlen(buff));

  m_abfr.reallocateBfr("\x1b[?25h", 6);

  /*
   * update screen
   */
  write(STDOUT_FILENO, ab.b, ab.len);
  m_abfr.freeBfr(); // free memory
}

char* Common::callPrompt(char *prompt, void (*callback)(char*, int))
{
  size_t buffsize = 128;
  char* bfr = malloc(buffsize); // allocate memory

  size_t bufflen = 0;           // lenght
  bfr[0] = '\0';

  while (1)
  {
    statusMsg(prompt, bfr); // set prompt
    updateScreen();         // and update screen

    int key = tml.whatKey();  // read key

    if (key == DELETE_KEY || key == CTRL_KEY('h') || key == BACKSPACE)
    {
      if (bufflen != 0)         // if buffer is not empty
        bfr[--bufflen] = '\0';  // set end of row
    }
    else if (key == '\x1b')     // if this is ESC
    {
      statusMsg("");          // erase
      if (callback)           // if callback is not NULL
        callback(bfr, key);   // call func for callback which pointed by callback()
      free(bfr);              // free memory
      return NULL;            // and cancel
    }
    else if (key == '\r')     // if carriage return (move the cursor at the start of the line)
    {
      if (bufflen != 0)       // and bufflen is not empty
      {
        statusMsg("");        // clean message
        if (callback)
          callback(bfr, key); // and get callback
        return bfr;           // returning of buffer
      }
    }
    else if (!iscntrl(key) && key < 128) // checks, whether the argument, transmitted via the parameter сharacter, control character
    {
      /*
       * reallocation of buffer if needs
       */
      if (bufflen == buffsize - 1)
      {
        buffsize *= 2;
        bfr = realloc(bfr, buffsize);
      }
      bfr[bufflen++] = key; // write this key to buffer
      bfr[bufflen] = '\0';  // and end of row
    }

    if (callback)
      callback(bfr, key);   // call of callback
  }
}

void Common::moveCursor(int key)
{
  // instancing RowController
  // if empty - to zero position, else to the end of row
  //
  RowController* pRowctrl = (m_pCnfg->configY >= m_pCnfg->rowCount) ? NULL : &m_pCnfg->pRowObj[m_pCnfg->configY];

  switch (key)
  {
    case ARROW_LEFT:
      if (m_pCnfg->configX != 0)                                    // if horizontal position isn't zero
      {
        m_pCnfg->configX--;                                         // move left
      }
      else if (m_pCnfg->configY > 0)                                // else if there is at least 1 row
      {
        m_pCnfg->configY--;                                         // move to that row
        m_pCnfg->configX = m_pCnfg->pRowObj[m_pCnfg->configY].size; // and to the end of that row
      }
      break;
    case ARROW_RIGHT:
      if (pRowctrl && m_pCnfg->configX < pRowctrl->size)            // if there is row and if cursor is not in the end of row
      {
        m_pCnfg->configX++;                                         // move cursor right along of row
      }
      else if (pRowctrl && m_pCnfg->configX == pRowctrl->size)      // if there is row and cursor in the end of this row
      {
        m_pCnfg->configY++;                                         // move to next row
        E.cx = 0;                                                   // on zero position
      }
      break;
    case ARROW_UP:
      if (m_pCnfg->configY != 0)                                    // if there is at least 1 row
      {
        m_pCnfg->configY--;                                         // move up
      }
      break;
    case ARROW_DOWN:
      if (m_pCnfg->configY < m_pCnfg->rowCount)                     // if cursor is not on last row
      {
        m_pCnfg->configY++;                                         // move down
      }
      break;
  }
}

void Common::processingKeypress()
{
  static int sQuitCounter = EDITORRMEND_QUIT_COUNTER;                // counter clicking for exit

  int key = whatKey();                                               // read key

  switch (key)
  {
    case '\r':                                                       // if carriage return (Enter key)
      setNewline();                                                   // set newline
      break;

    case CTRL_KEY('q'):
      if (m_pCnfg->smear && sQuitCounter > 0)                        // if there is any changes and counter > 0
      {
        statusMsg("! File was changed and unsaved and data can be lost after exiting. "
                  "Press Ctrl-Q %d more times to exit.", sQuitCounter);
        sQuitCounter--;                                              // counter decrement
        return;
      }
      write(STDOUT_FILENO, "\x1b[2J", 4);
      write(STDOUT_FILENO, "\x1b[H", 3);
      exit(0);
      break;

    case CTRL_KEY('s'):
      save();                                                       // TODO: save changes
      break;

    case HOME_KEY:
    m_pCnfg->configX = 0;                                           // to the row beginning
      break;

    case END_KEY:
      if (m_pCnfg->configY < m_pCnfg->rowCount)                     // if not last row
        m_pCnfg->configX = m_pCnfg->pRowObj[m_pCnfg->configY].size; // to the end of row
      break;

    case CTRL_KEY('f'):
      find();                                                       // find func
      break;

    case BACKSPACE:
    case CTRL_KEY('h'):
    case DELETE_KEY:
      if (key == DELETE_KEY)
        moveCursor(ARROW_RIGHT);                                    // move cursor right
      deleteChar();                                                 // delete char
      break;

    // page up/down
    //
    case PAGE_UP:
    case PAGE_DOWN:
      {
        if (key == PAGE_UP)
        {
          m_pCnfg->configY = m_pCnfg->disableRow;                    // move page up
        }
        else if (key == PAGE_DOWN)
        {
          m_pCnfg->configY = m_pCnfg->disableRow + m_pCnfg->enableRow - 1; // move page down
          if (m_pCnfg->configY > m_pCnfg->rowCount)
            m_pCnfg->configY = m_pCnfg->rowCount;
        }

        int times = m_pCnfg->enableRow;
        while (times--)
          moveCursor(key == PAGE_UP ? ARROW_UP : ARROW_DOWN);
      }
      break;

    case ARROW_UP:
    case ARROW_DOWN:
    case ARROW_LEFT:
    case ARROW_RIGHT:
      moveCursor(key);
      break;

    case CTRL_KEY('l'):
    case '\x1b':
      break;

    default:
      setChar(key);   // just write chars
      break;
  }

  sQuitCounter = EDITORRMEND_QUIT_COUNTER;
}
<commit_msg>implemented saving function<commit_after>// CommonFunc.cpp -- source file
/*
 * Author: Ivan Chapkailo (septimomend)
 * Date:   02.07.2017
 *
 * © 2017 Ivan Chapkailo. All rights reserved
 * e-mail: chapkailo.ivan@gmail.com
 */

#include "stdafx.h"
#include "CommonFunc.h"

Common::Common()
{
  m_pAll = tml.getAllControllerObj();
  m_pCnfg = m_pAll->getConfigObj();
}

Common::Common(AllControllers* all) : m_pCnfg(all->getConfigObj())
{
}

void Common::openFile(char *filename)
{
  free(m_pCnfg->pFilename);                                                       // free pFilename becouse strdup uses malloc and in next func
                                                                                // call need to free memory
  m_pCnfg->pFilename = strdup(filename);                                          // duplicate filename to pFilename

  m_pAll->pickSyntaxClr();

  FILE* fln = fopen(filename, "r");                                                // open file foe reading
  if (!fln)                                                                        // if can't to open file
    tml.emergencyDestruction("fopen");                                            // forced closure

  char* pStr = NULL;
  size_t strUSZ = 0;                                                              // size
  ssize_t strSSZ;                                                                 // signed size
  while ((strSSZ = getline(&pStr, &strUSZ, fln)) != -1)                            // while strUSZ size of pStr that reads from file fp
  {
    while (strSSZ > 0 && (pStr[strSSZ - 1] == '\n' || pStr[strSSZ - 1] == '\r'))  // if this is end of line
      strSSZ--;                                                                   // decrease line size
    m_pCnfg->setRow(m_pCnfg->rowCount, pStr, strSSZ);                             // set rows from file
  }
  free(pStr);
  fclose(fln);                                                                    // close file
  m_pCnfg->smear = 0;                                                             // no changes in now opened file
}

void detectCallback(char* query, int key)
{
  // TODO
}

void Common::save()
{
  if (m_pCnfg->pFilename == NULL)                                               // if no falename
  {
    m_pCnfg->pFilename = callPrompt("Save as: %s (ESC - cancel)", NULL);        // set message
    if (m_pCnfg->pFilename == NULL)                                             // if filename still is not
    {
      statusMsg("Saving operation is canceled");                                // lead out status message about cancelling
      return;                                                                   // and go out of save function
    }
    m_pAll->pickSyntaxClr();                                                    // colorize text in dependence of filename extension
  }

  size_t sz;
  char *pBuff = m_pCnfg->row2Str(&sz);                                          // get strings and size of these

  int fd = open(m_pCnfg->pFilename, O_RDWR | O_CREAT, 0644);                    // open the file for read/write and if the file does not exist, it will be created
                                                                                // 0644 - look here: https://stackoverflow.com/questions/18415904/what-does-mode-t-0644-mean
  if (fd != -1)
  {
    if (ftruncate(fd, sz) != -1)                                                // set file size
    {
      if (write(fd, pBuff, sz) == sz)                                           // if writing from buffer to file is success
      {
        close(fd);                                                              // close
        free(pBuff);                                                            // free memory
        m_pCnfg->smear = 0;                                                     // no changes in syntax after copying to file
        statusMsg("%d bytes is written successfully", sz);                      // set status message
        return;                                                                 // go out
      }
    }
    close(fd);                                                                  // if can't change size - close file
  }
  free(pBuff);                                                                  // free buffer
  statusMsg("Saving operation has error: %s", strerror(errno));                 // lead out error about
}

void Common::find()
{
  // TODO
}

void Common::drawRows(Adbfr* abfr);
{
  // TODO
}

void Common::drawStatusBar(Adbfr* abfr)
{
  // TODO
}

void Common::drawMessageBar(Adbfr* abfr)
{
  // TODO
}

void Common::scrolling()
{
  // TODO
}

void Common::statusMsg(const char *fmt, ...)
{
  va_list arg;         // for unknown number of parameters
  va_start(arg, fmt);  // initialize arg
  vsnprintf(cnfg.statusMessage, sizeof(cnfg.statusMessage), fmt, arg); // output parameters to statusMessage
  va_end(arg); // end
  cnfg.statusMessageTime = time(NULL); // gets time
}

void Common::updateScreen()
{
  scrolling();

  m_abfr = ADBFR_IMPL; // implement to NULL

  m_abfr.reallocateBfr("\x1b[?25l", 6); // reallocate data
  m_abfr.reallocateBfr("\x1b[H", 3);    // reallocate data

  /*
   * draw rows, message bar and status bar
   */
  drawRows(&m_abfr);
  drawStatusBar(&m_abfr);
  drawMessageBar(&m_abfr);

  /*
   * write to buff cursor | position
   */
  char buff[32];
  snprintf(buff, sizeof(buff), "\x1b[%d;%dH", (m_pCnfg->configY - m_pCnfg->disableRow) + 1, (m_pCnfg->rowX - m_pCnfg->disableClr) + 1);
  m_abfr.reallocateBfr(buff, strlen(buff));

  m_abfr.reallocateBfr("\x1b[?25h", 6);

  /*
   * update screen
   */
  write(STDOUT_FILENO, ab.b, ab.len);
  m_abfr.freeBfr(); // free memory
}

char* Common::callPrompt(char *prompt, void (*callback)(char*, int))
{
  size_t buffsize = 128;
  char* bfr = malloc(buffsize); // allocate memory

  size_t bufflen = 0;           // lenght
  bfr[0] = '\0';

  while (1)
  {
    statusMsg(prompt, bfr); // set prompt
    updateScreen();         // and update screen

    int key = tml.whatKey();  // read key

    if (key == DELETE_KEY || key == CTRL_KEY('h') || key == BACKSPACE)
    {
      if (bufflen != 0)         // if buffer is not empty
        bfr[--bufflen] = '\0';  // set end of row
    }
    else if (key == '\x1b')     // if this is ESC
    {
      statusMsg("");          // erase
      if (callback)           // if callback is not NULL
        callback(bfr, key);   // call func for callback which pointed by callback()
      free(bfr);              // free memory
      return NULL;            // and cancel
    }
    else if (key == '\r')     // if carriage return (move the cursor at the start of the line)
    {
      if (bufflen != 0)       // and bufflen is not empty
      {
        statusMsg("");        // clean message
        if (callback)
          callback(bfr, key); // and get callback
        return bfr;           // returning of buffer
      }
    }
    else if (!iscntrl(key) && key < 128) // checks, whether the argument, transmitted via the parameter сharacter, control character
    {
      /*
       * reallocation of buffer if needs
       */
      if (bufflen == buffsize - 1)
      {
        buffsize *= 2;
        bfr = realloc(bfr, buffsize);
      }
      bfr[bufflen++] = key; // write this key to buffer
      bfr[bufflen] = '\0';  // and end of row
    }

    if (callback)
      callback(bfr, key);   // call of callback
  }
}

void Common::moveCursor(int key)
{
  // instancing RowController
  // if empty - to zero position, else to the end of row
  //
  RowController* pRowctrl = (m_pCnfg->configY >= m_pCnfg->rowCount) ? NULL : &m_pCnfg->pRowObj[m_pCnfg->configY];

  switch (key)
  {
    case ARROW_LEFT:
      if (m_pCnfg->configX != 0)                                    // if horizontal position isn't zero
      {
        m_pCnfg->configX--;                                         // move left
      }
      else if (m_pCnfg->configY > 0)                                // else if there is at least 1 row
      {
        m_pCnfg->configY--;                                         // move to that row
        m_pCnfg->configX = m_pCnfg->pRowObj[m_pCnfg->configY].size; // and to the end of that row
      }
      break;
    case ARROW_RIGHT:
      if (pRowctrl && m_pCnfg->configX < pRowctrl->size)            // if there is row and if cursor is not in the end of row
      {
        m_pCnfg->configX++;                                         // move cursor right along of row
      }
      else if (pRowctrl && m_pCnfg->configX == pRowctrl->size)      // if there is row and cursor in the end of this row
      {
        m_pCnfg->configY++;                                         // move to next row
        E.cx = 0;                                                   // on zero position
      }
      break;
    case ARROW_UP:
      if (m_pCnfg->configY != 0)                                    // if there is at least 1 row
      {
        m_pCnfg->configY--;                                         // move up
      }
      break;
    case ARROW_DOWN:
      if (m_pCnfg->configY < m_pCnfg->rowCount)                     // if cursor is not on last row
      {
        m_pCnfg->configY++;                                         // move down
      }
      break;
  }
}

void Common::processingKeypress()
{
  static int sQuitCounter = EDITORRMEND_QUIT_COUNTER;                // counter clicking for exit

  int key = whatKey();                                               // read key

  switch (key)
  {
    case '\r':                                                       // if carriage return (Enter key)
      setNewline();                                                   // set newline
      break;

    case CTRL_KEY('q'):
      if (m_pCnfg->smear && sQuitCounter > 0)                        // if there is any changes and counter > 0
      {
        statusMsg("! File was changed and unsaved and data can be lost after exiting. "
                  "Press Ctrl-Q %d more times to exit.", sQuitCounter);
        sQuitCounter--;                                              // counter decrement
        return;
      }
      write(STDOUT_FILENO, "\x1b[2J", 4);
      write(STDOUT_FILENO, "\x1b[H", 3);
      exit(0);
      break;

    case CTRL_KEY('s'):
      save();                                                       // TODO: save changes
      break;

    case HOME_KEY:
    m_pCnfg->configX = 0;                                           // to the row beginning
      break;

    case END_KEY:
      if (m_pCnfg->configY < m_pCnfg->rowCount)                     // if not last row
        m_pCnfg->configX = m_pCnfg->pRowObj[m_pCnfg->configY].size; // to the end of row
      break;

    case CTRL_KEY('f'):
      find();                                                       // find func
      break;

    case BACKSPACE:
    case CTRL_KEY('h'):
    case DELETE_KEY:
      if (key == DELETE_KEY)
        moveCursor(ARROW_RIGHT);                                    // move cursor right
      deleteChar();                                                 // delete char
      break;

    // page up/down
    //
    case PAGE_UP:
    case PAGE_DOWN:
      {
        if (key == PAGE_UP)
        {
          m_pCnfg->configY = m_pCnfg->disableRow;                    // move page up
        }
        else if (key == PAGE_DOWN)
        {
          m_pCnfg->configY = m_pCnfg->disableRow + m_pCnfg->enableRow - 1; // move page down
          if (m_pCnfg->configY > m_pCnfg->rowCount)
            m_pCnfg->configY = m_pCnfg->rowCount;
        }

        int times = m_pCnfg->enableRow;
        while (times--)
          moveCursor(key == PAGE_UP ? ARROW_UP : ARROW_DOWN);
      }
      break;

    case ARROW_UP:
    case ARROW_DOWN:
    case ARROW_LEFT:
    case ARROW_RIGHT:
      moveCursor(key);
      break;

    case CTRL_KEY('l'):
    case '\x1b':
      break;

    default:
      setChar(key);   // just write chars
      break;
  }

  sQuitCounter = EDITORRMEND_QUIT_COUNTER;
}
<|endoftext|>


<commit_before>/*************************************************************************
* Copyright(c) 1998-2008, ALICE Experiment at CERN, All rights reserved. *
*                                                                        *
* Author: The ALICE Off-line Project.                                    *
* Contributors are mentioned in the code where appropriate.              *
*                                                                        *
* Permission to use, copy, modify and distribute this software and its   *
* documentation strictly for non-commercial purposes is hereby granted   *
* without fee, provided that the above copyright notice appears in all   *
* copies and that both the copyright notice and this permission notice   *
* appear in the supporting documentation. The authors make no claims     *
* about the suitability of this software for any purpose. It is          *
* provided "as is" without express or implied warranty.                  *
**************************************************************************/

/**********************************
 * create an event and perform    *
 * flow analysis 'on the fly'     *
 *                                *
 * authors: Raimond Snellings     *
 *           (snelling@nikhef.nl) *
 *          Ante Bilandzic        *
 *           (anteb@nikhef.nl)    *
 *********************************/

#include "Riostream.h"
#include "TMath.h"
#include "TF1.h"
#include "TRandom3.h"

#include "AliFlowEventSimpleMakerOnTheFly.h"
#include "AliFlowEventSimple.h"
#include "AliFlowTrackSimple.h"

ClassImp(AliFlowEventSimpleMakerOnTheFly)

//========================================================================

AliFlowEventSimpleMakerOnTheFly::AliFlowEventSimpleMakerOnTheFly(UInt_t iseed):
  fMultiplicityOfRP(0),
  fMultiplicitySpreadOfRP(0.),
  fV1RP(0.),
  fV1SpreadRP(0.),
  fV2RP(0.),
  fV2SpreadRP(0.),
  fPtSpectra(NULL),
  fPhiDistribution(NULL),
  fMyTRandom3(NULL),
  fCount(0)
 {
  // constructor
   fMyTRandom3 = new TRandom3(iseed);
 }

//========================================================================

AliFlowEventSimpleMakerOnTheFly::~AliFlowEventSimpleMakerOnTheFly()
{
 // destructor
  if (fPtSpectra) delete fPtSpectra;
  if (fPhiDistribution) delete fPhiDistribution;
  if (fMyTRandom3) delete  fMyTRandom3;
}

//========================================================================

AliFlowEventSimple* AliFlowEventSimpleMakerOnTheFly::CreateEventOnTheFly()
{
  // method to create event on the fly

  AliFlowEventSimple* pEvent = new AliFlowEventSimple(fMultiplicityOfRP);

  //reaction plane
  Double_t fMCReactionPlaneAngle = fMyTRandom3->Uniform(0.,TMath::TwoPi());

  // pt:
  Double_t dPtMin = 0.; // to be improved
  Double_t dPtMax = 10.; // to be improved

  fPtSpectra = new TF1("fPtSpectra","[0]*x*TMath::Exp(-x*x)",dPtMin,dPtMax);
  fPtSpectra->SetParName(0,"Multiplicity of RPs");
  // sampling the multiplicity:
  Int_t fNewMultiplicityOfRP = fMyTRandom3->Gaus(fMultiplicityOfRP,fMultiplicitySpreadOfRP);
  fPtSpectra->SetParameter(0,fNewMultiplicityOfRP);

  // phi:
  Double_t dPhiMin = 0.; // to be improved
  Double_t dPhiMax = TMath::TwoPi(); // to be improved

  fPhiDistribution = new TF1("fPhiDistribution","1+2.*[0]*TMath::Cos(x)+2.*[1]*TMath::Cos(2*x)",dPhiMin,dPhiMax);

  // sampling the V1:
  fPhiDistribution->SetParName(0,"directed flow");
  if(fV1RP>0.0) fV1RP = fMyTRandom3->Gaus(fV1RP,fV1SpreadRP);
  fPhiDistribution->SetParameter(0,fV1RP);

  // sampling the V2:
  fPhiDistribution->SetParName(1,"elliptic flow");
  fV2RP = fMyTRandom3->Gaus(fV2RP,fV2SpreadRP);
  fPhiDistribution->SetParameter(1,fV2RP);

  // eta:
  Double_t dEtaMin = -1.; // to be improved
  Double_t dEtaMax = 1.; // to be improved

  Int_t iGoodTracks = 0;
  Int_t iSelParticlesRP = 0;
  Int_t iSelParticlesPOI = 0;
  for(Int_t i=0;i<fNewMultiplicityOfRP;i++) {
    AliFlowTrackSimple* pTrack = new AliFlowTrackSimple();
    pTrack->SetPt(fPtSpectra->GetRandom());
    pTrack->SetEta(fMyTRandom3->Uniform(dEtaMin,dEtaMax));
    pTrack->SetPhi(fPhiDistribution->GetRandom()+fMCReactionPlaneAngle);
    pTrack->SetForRPSelection(kTRUE);
    iSelParticlesRP++;
    pTrack->SetForPOISelection(kTRUE);
    iSelParticlesPOI++;

    pEvent->TrackCollection()->Add(pTrack);
    iGoodTracks++;
  }

  pEvent->SetEventNSelTracksRP(iSelParticlesRP);
  pEvent->SetNumberOfTracks(iGoodTracks);//tracks used either for RP or for POI selection
  pEvent->SetMCReactionPlaneAngle(fMCReactionPlaneAngle);

  if (!fMCReactionPlaneAngle == 0) cout<<" MC Reaction Plane Angle = "<<  fMCReactionPlaneAngle << endl;
  else cout<<" MC Reaction Plane Angle = unknown "<< endl;

  cout<<" iGoodTracks = "<< iGoodTracks << endl;
  cout<<" # of RP selected tracks = "<<iSelParticlesRP<<endl;
  cout<<" # of POI selected tracks = "<<iSelParticlesPOI<<endl;
  cout << "# " << ++fCount << " events processed" << endl;

  delete fPhiDistribution;
  delete fPtSpectra;
  return pEvent;

} // end of CreateEventOnTheFly()

<commit_msg>a few more fixes for the fluctuations<commit_after>/*************************************************************************
* Copyright(c) 1998-2008, ALICE Experiment at CERN, All rights reserved. *
*                                                                        *
* Author: The ALICE Off-line Project.                                    *
* Contributors are mentioned in the code where appropriate.              *
*                                                                        *
* Permission to use, copy, modify and distribute this software and its   *
* documentation strictly for non-commercial purposes is hereby granted   *
* without fee, provided that the above copyright notice appears in all   *
* copies and that both the copyright notice and this permission notice   *
* appear in the supporting documentation. The authors make no claims     *
* about the suitability of this software for any purpose. It is          *
* provided "as is" without express or implied warranty.                  *
**************************************************************************/

/**********************************
 * create an event and perform    *
 * flow analysis 'on the fly'     *
 *                                *
 * authors: Raimond Snellings     *
 *           (snelling@nikhef.nl) *
 *          Ante Bilandzic        *
 *           (anteb@nikhef.nl)    *
 *********************************/

#include "Riostream.h"
#include "TMath.h"
#include "TF1.h"
#include "TRandom3.h"

#include "AliFlowEventSimpleMakerOnTheFly.h"
#include "AliFlowEventSimple.h"
#include "AliFlowTrackSimple.h"

ClassImp(AliFlowEventSimpleMakerOnTheFly)

//========================================================================

AliFlowEventSimpleMakerOnTheFly::AliFlowEventSimpleMakerOnTheFly(UInt_t iseed):
  fMultiplicityOfRP(0),
  fMultiplicitySpreadOfRP(0.),
  fV1RP(0.),
  fV1SpreadRP(0.),
  fV2RP(0.),
  fV2SpreadRP(0.),
  fPtSpectra(NULL),
  fPhiDistribution(NULL),
  fMyTRandom3(NULL),
  fCount(0)
 {
  // constructor
   fMyTRandom3 = new TRandom3(iseed);
 }

//========================================================================

AliFlowEventSimpleMakerOnTheFly::~AliFlowEventSimpleMakerOnTheFly()
{
 // destructor
  if (fPtSpectra) delete fPtSpectra;
  if (fPhiDistribution) delete fPhiDistribution;
  if (fMyTRandom3) delete  fMyTRandom3;
}

//========================================================================

AliFlowEventSimple* AliFlowEventSimpleMakerOnTheFly::CreateEventOnTheFly()
{
  // method to create event on the fly

  AliFlowEventSimple* pEvent = new AliFlowEventSimple(fMultiplicityOfRP);

  //reaction plane
  Double_t fMCReactionPlaneAngle = fMyTRandom3->Uniform(0.,TMath::TwoPi());

  // pt:
  Double_t dPtMin = 0.; // to be improved
  Double_t dPtMax = 10.; // to be improved

  fPtSpectra = new TF1("fPtSpectra","[0]*x*TMath::Exp(-x*x)",dPtMin,dPtMax);
  fPtSpectra->SetParName(0,"Multiplicity of RPs");
  // sampling the multiplicity:
  Int_t fNewMultiplicityOfRP = fMyTRandom3->Gaus(fMultiplicityOfRP,fMultiplicitySpreadOfRP);
  fPtSpectra->SetParameter(0,fNewMultiplicityOfRP);

  // phi:
  Double_t dPhiMin = 0.; // to be improved
  Double_t dPhiMax = TMath::TwoPi(); // to be improved

  fPhiDistribution = new TF1("fPhiDistribution","1+2.*[0]*TMath::Cos(x)+2.*[1]*TMath::Cos(2*x)",dPhiMin,dPhiMax);

  // sampling the V1:
  fPhiDistribution->SetParName(0,"directed flow");
  Double_t fNewV1RP=0.;
  if(fV1RP>0.0) {fNewV1RP = fMyTRandom3->Gaus(fV1RP,fV1SpreadRP);}
  fPhiDistribution->SetParameter(0,fNewV1RP);

  // sampling the V2:
  fPhiDistribution->SetParName(1,"elliptic flow");
  Double_t fNewV2RP = fMyTRandom3->Gaus(fV2RP,fV2SpreadRP);
  fPhiDistribution->SetParameter(1,fNewV2RP);

  // eta:
  Double_t dEtaMin = -1.; // to be improved
  Double_t dEtaMax = 1.; // to be improved

  Int_t iGoodTracks = 0;
  Int_t iSelParticlesRP = 0;
  Int_t iSelParticlesPOI = 0;
  for(Int_t i=0;i<fNewMultiplicityOfRP;i++) {
    AliFlowTrackSimple* pTrack = new AliFlowTrackSimple();
    pTrack->SetPt(fPtSpectra->GetRandom());
    pTrack->SetEta(fMyTRandom3->Uniform(dEtaMin,dEtaMax));
    pTrack->SetPhi(fPhiDistribution->GetRandom()+fMCReactionPlaneAngle);
    pTrack->SetForRPSelection(kTRUE);
    iSelParticlesRP++;
    pTrack->SetForPOISelection(kTRUE);
    iSelParticlesPOI++;

    pEvent->TrackCollection()->Add(pTrack);
    iGoodTracks++;
  }

  pEvent->SetEventNSelTracksRP(iSelParticlesRP);
  pEvent->SetNumberOfTracks(iGoodTracks);//tracks used either for RP or for POI selection
  pEvent->SetMCReactionPlaneAngle(fMCReactionPlaneAngle);

  if (!fMCReactionPlaneAngle == 0) cout<<" MC Reaction Plane Angle = "<<  fMCReactionPlaneAngle << endl;
  else cout<<" MC Reaction Plane Angle = unknown "<< endl;

  cout<<" iGoodTracks = "<< iGoodTracks << endl;
  cout<<" # of RP selected tracks = "<<iSelParticlesRP<<endl;
  cout<<" # of POI selected tracks = "<<iSelParticlesPOI<<endl;
  cout << "# " << ++fCount << " events processed" << endl;

  delete fPhiDistribution;
  delete fPtSpectra;
  return pEvent;

} // end of CreateEventOnTheFly()

<|endoftext|>


<commit_before>/* Joey Button
 *
 *
 */

#include <stdio.h>
#include "opencv2/opencv.hpp"

using namespace cv;
using namespace std;

const char *win = "video";

void drawCircle( Mat img, Point center )
{
 int thickness = -1;
 int lineType = 8;

 circle( img,
         center,
         32.0,
         Scalar( 0, 0, 255 ),
         thickness,
         lineType );
}

int main()
{
    int cam = 0; // default camera
    VideoCapture cap(cam);
    if (!cap.isOpened()) {
	fprintf(stderr, "cannot open camera %d\n", cam);
	exit(1);
    }

    //namedWindow(win);
    namedWindow(win, 1);
    Mat frame, screen;
    Point pt;
    pt.x = 500;
    pt.y = 0;
    int momentumY = 10;
    int momentumX = 0;

    while (1) {
        cap >> frame;
        cvtColor(frame, screen, CV_LOAD_IMAGE_COLOR);

        pt.x += momentumX;
        pt.y += momentumY;

        if(pt.y<990){
          momentumY += 1;
        }else {
          momentumY = -(momentumY/2);
        }
        if (momentumY*momentumY <= 49 && pt.y > 990){
          momentumY =0;
        }

        //This will zero out the entire image, and draw a red circle

        Mat BGRChannels[3];
        split(screen,BGRChannels);                                  // split the BGR channesl
        BGRChannels[1]=Mat::zeros(screen.rows,screen.cols,CV_8UC1); // removing Green channel
        BGRChannels[0]=Mat::zeros(screen.rows,screen.cols,CV_8UC1); // removing Green channel
        BGRChannels[2]=Mat::zeros(screen.rows,screen.cols,CV_8UC1); // removing Green channel
        merge(BGRChannels,3,screen);

        drawCircle(screen,pt);

                            // pack the image

        imshow(win, screen);
        if (waitKey(30) >= 0) // wait up to 30 msec
	    break;
    }

    return 0;
}

/*
    Mat BGRChannels[3];
    split(screen,BGRChannels); // split the BGR channesl
    BGRChannels[1]=Mat::zeros(screen.rows,screen.cols,CV_8UC1);// removing Green channel
    merge(BGRChannels,3,screen); // pack the image

    waitKey(0);
*/
<commit_msg>Still confused<commit_after>/*
 * Joey Button
 *
 *
 */

#include <stdio.h>
#include "opencv2/opencv.hpp"

using namespace cv;
using namespace std;

const char *win = "video";

void drawCircle(Mat img, Point center)
{
    int thickness = -1;
    int lineType = 8;

    circle( img,
            center,
            32.0,
            Scalar( 0, 0, 255 ),
            thickness,
            lineType);
}

int main()
{
    int cam = 0; // default camera
    VideoCapture cap(cam);
    if (!cap.isOpened()) {
        fprintf(stderr, "cannot open camera %d\n", cam);
        exit(1);
    }

    // namedWindow(win);
    namedWindow(win, 1);
    Mat frame, screen;
    Point pt;
    pt.x = 500;
    pt.y = 0;
    int momentumY = 10;     // initial momentum hardcoded as 10
    int momentumX = 0;

    while (1) {
        cap >> frame;
        cvtColor(frame, screen, CV_LOAD_IMAGE_COLOR);

        pt.x += momentumX;
        pt.y += momentumY;

        if (pt.y < 990) {                   // not at bottom
            momentumY += 1;
        } else {
            momentumY = -(momentumY * .5);   // bounce back up and halt it
        }
        if (momentumY * momentumY <= 49 && pt.y > 990){
            momentumY = 0;
        }

        // This will zero out the entire image, and draw a red circle

        Mat BGRChannels[3];
        split(screen, BGRChannels);                                  // split the BGR channesl
        BGRChannels[1] = Mat::zeros(screen.rows, screen.cols, CV_8UC1); // removing Green channel
        BGRChannels[0] = Mat::zeros(screen.rows, screen.cols, CV_8UC1); // removing Green channel
        BGRChannels[2] = Mat::zeros(screen.rows, screen.cols, CV_8UC1); // removing Green channel
        // TODO: what?

        merge(BGRChannels, 3, screen);

        drawCircle(screen, pt);

        // pack the image
        imshow(win, screen);
        if (waitKey(30) >= 0) // wait up to 30 msec
	        break;
    }

    return 0;
}

/*
    Mat BGRChannels[3];
    split(screen,BGRChannels); // split the BGR channesl
    BGRChannels[1]=Mat::zeros(screen.rows,screen.cols,CV_8UC1);// removing Green channel
    merge(BGRChannels,3,screen); // pack the image

    waitKey(0);
*/
<|endoftext|>