<commit_before>#include "Keyboard.h"
#include "Camera.h"
#include "ClothSimulator.h"
#include "DrawingSettings.h"

// OpenGL imports
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>

Keyboard* Keyboard::instance = 0;

Keyboard* Keyboard::getInstance()
{
    if(instance == 0)
    {
        instance = new Keyboard();
    }

    return instance;
}

Keyboard::Keyboard() :
    angleIncrement(0.015625),    // 2^(-6)
    translationIncrement(0.125), // 2^(-3)
    spacebarPressed(false)
{}

void Keyboard::resetKeyboardStatus()
{
    for(int i = 0; i < 256; i += 1)
    {
        keyboardStatus[i] = false;
    }
}

// Note that these are the CONTINUOUS actions only. For toggle state actions,
// take care of it before the array of keyboard button status is enabled.
void Keyboard::applyNormalKeyboardActions()
{
    Camera* camera = ClothSimulator::getInstance()->getScene()->getCamera();

    for(int key = 0; key < 256; key += 1)
    {
        // if the key is being continuously held down
        if(keyboardStatus[key])
        {
            switch(key)
            {
                // world axis camera controls
                case 'a':
                    camera->rotateAroundYAxisWorld(-angleIncrement);
                    break;
                case 'd':
                    camera->rotateAroundYAxisWorld(angleIncrement);
                    break;
                case 's':
                    camera->rotateAroundXAxisWorld(-angleIncrement);
                    break;
                case 'w':
                    camera->rotateAroundXAxisWorld(angleIncrement);
                    break;
                case 'q':
                    camera->rotateAroundZAxisWorld(-angleIncrement);
                    break;
                case 'e':
                    camera->rotateAroundZAxisWorld(angleIncrement);
                    break;

                // yaw, pitch and roll camera controls
                case 'k':
                    // turn camera "down" one notch
                    camera->rotateAroundXAxisObject(angleIncrement);
                    break;
                case 'i':
                    // turn camera "up" one notch
                    camera->rotateAroundXAxisObject(-angleIncrement);
                    break;
                case 'j':
                    // turn camera "left" one notch
                    camera->rotateAroundYAxisObject(angleIncrement);
                    break;
                case 'l':
                    // turn camera "right" one notch
                    camera->rotateAroundYAxisObject(-angleIncrement);
                    break;
                case 'u':
                    // tilt camera "left" one notch
                    camera->rotateAroundZAxisObject(-angleIncrement);
                    break;
                case 'o':
                    // tilt camera "right" one notch
                    camera->rotateAroundZAxisObject(angleIncrement);
                    break;

                // camera translation controls
                case 'f':
                    // translate camera left
                    camera->translate(camera->getUpDirection().cross(camera->getViewDirection()).normalize() * translationIncrement);
                    break;
                case 'h':
                    // translate camera right
                    camera->translate(camera->getViewDirection().cross(camera->getUpDirection()).normalize() * translationIncrement);
                    break;
                case 't':
                    // translate camera up
                    camera->translate(camera->getUpDirection().normalize() * translationIncrement);
                    break;
                case 'g':
                    // translate camera down
                    camera->translate(-camera->getUpDirection().normalize() * translationIncrement);
                    break;
                case 'r':
                    // translate camera back
                    camera->translate(-camera->getViewDirection().normalize() * translationIncrement);
                    break;
                case 'z':
                    // translate camera front
                    camera->translate(camera->getViewDirection().normalize() * translationIncrement);
                    break;

                default:
                    break;
            } // end switch(key)
        } // end if(keyboardStatus[key])
    } // end loop
}

// Put toggle keyboard controls here, and continuous ones in the "default" part of
// the switch statement
void Keyboard::handleNormalKeyboardInput(unsigned char key, int x, int y)
{
    DrawingSettings* drawingSettings = DrawingSettings::getInstance();

    switch(key)
    {
        case '1':
            drawingSettings->toggleDrawArrowsEnabled();
            break;
        case '2':
            drawingSettings->toggleDrawFloorEnabled();
            break;
        case '3':
            drawingSettings->toggleDrawTrianglesEnabled();
            break;
        case 32:
            spacebarPressed = !spacebarPressed;

            if(spacebarPressed)
            {
                drawingSettings->setTimeStep(0.0001);
            }
            else
            {
                drawingSettings->setTimeStep(0.0);
            }

        default:
            // toggle enable state for keyboard buttons which are to be
            // continuously applied (like rotations, translations, ...)
            keyboardStatus[key] = true;
            break;
    }

}

void Keyboard::handleNormalKeyboardRelease(unsigned char key, int x, int y)
{
    // toggle disable state for keyboard buttons which are to be
    // continuously applied (like rotations, translations, ...)
    keyboardStatus[key] = false;
}

void Keyboard::handleSpecialKeyboardInput(int key, int x, int y)
{
    DrawingSettings* drawingSettings = DrawingSettings::getInstance();

    switch(key)
    {
        case GLUT_KEY_F1:
            showHelp();
            break;
        case GLUT_KEY_F2:
            ClothSimulator::getInstance()->getScene()->getCamera()->loadCameraSetup();
            break;
        case GLUT_KEY_F3:
            ClothSimulator::getInstance()->getScene()->getCamera()->showCameraStatus();
            break;
        case GLUT_KEY_F4:
            DrawingSettings::getInstance()->showDrawStatus();
            break;
        case GLUT_KEY_F5:
            drawingSettings->toggleDrawStructuralConstraintsEnabled();
            break;
        case GLUT_KEY_F6:
            drawingSettings->toggleDrawShearConstraintsEnabled();
            break;
        case GLUT_KEY_F7:
            break;
        case GLUT_KEY_F8:
            break;
        case GLUT_KEY_F9:
            drawingSettings->toggleDrawNodesEnabled();
            break;
        case GLUT_KEY_F10:
            drawingSettings->toggleDrawWireFrameEnabled();
            break;
        case GLUT_KEY_F11:
            drawingSettings->toggleDrawWorldAxisEnabled();
            break;
        case GLUT_KEY_F12:
            drawingSettings->toggleDrawSpheresEnabled();
            break;

        default:
            break;
    }
}

void Keyboard::showHelp()
{
    std::cout << "******************************************" << std::endl;
    std::cout << "********           help           ********" << std::endl;
    std::cout << "******************************************" << std::endl;

    std::cout << std::endl;

    std::cout << "ESC: exit cloth simulator" << std::endl;

    std::cout << std::endl;

    // help controls
    std::cout << "help controls:" << std::endl;
    std::cout << "  F1: show help" << std::endl;

    std::cout << std::endl;

    std::cout << "camera position reset:" << std::endl;
    std::cout << "  F2: reset camera position" << std::endl;

    std::cout << std::endl;

    std::cout << "status controls:" << std::endl;
    std::cout << "  F3: show camera status" << std::endl;
    std::cout << "  F4: show draw   status" << std::endl;

    std::cout << std::endl;

    // drawing controls
    std::cout << "drawing controls:" << std::endl;
    std::cout << "  F5 : toggle draw structural      constraints" << std::endl;
    std::cout << "  F6 : toggle draw shear           constraints" << std::endl;
    std::cout << "  F7 : toggle draw structural bend constraints" << std::endl;
    std::cout << "  F8 : toggle draw shear      bend constraints" << std::endl;
    std::cout << "  F9 : toggle draw nodes" << std::endl;
    std::cout << "  F10: toggle draw wireframe" << std::endl;
    std::cout << "  F11: toggle draw world axis" << std::endl;
    std::cout << "  F12: toggle draw spheres" << std::endl;
    std::cout << "  1  : toggle draw arrows" << std::endl;
    std::cout << "  2  : toggle draw floor" << std::endl;
    std::cout << "  3  : toggle draw triangles" << std::endl;

    std::cout << std::endl;

    // yaw, pitch and roll camera controls
    std::cout << "camera object rotation controls:" << std::endl;
    std::cout << "  j: yaw   left " << std::endl;
    std::cout << "  l: yaw   right" << std::endl;
    std::cout << "  k: pitch down " << std::endl;
    std::cout << "  i: pitch up   " << std::endl;
    std::cout << "  u: roll  left " << std::endl;
    std::cout << "  o: roll  right" << std::endl;

    std::cout << std::endl;

    // world camera controls
    std::cout << "camera world rotation controls:" << std::endl;
    std::cout << "  s: rotate camera left  around world X axis" << std::endl;
    std::cout << "  w: rotate camera right around world X axis" << std::endl;
    std::cout << "  a: rotate camera left  around world Y axis" << std::endl;
    std::cout << "  d: rotate camera right around world Y axis" << std::endl;
    std::cout << "  e: rotate camera left  around world Z axis" << std::endl;
    std::cout << "  q: rotate camera right around world Z axis" << std::endl;

    std::cout << std::endl;

    // camera position controls
    std::cout << "camera translation controls:" << std::endl;
    std::cout << "  f: translate camera left" << std::endl;
    std::cout << "  h: translate camera right" << std::endl;
    std::cout << "  t: translate camera up" << std::endl;
    std::cout << "  g: translate camera down" << std::endl;
    std::cout << "  r: translate camera back" << std::endl;
    std::cout << "  z: translate camera front" << std::endl;

    std::cout << std::endl;
}<commit_msg>updated help controls<commit_after>#include "Keyboard.h"
#include "Camera.h"
#include "ClothSimulator.h"
#include "DrawingSettings.h"

// OpenGL imports
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>

Keyboard* Keyboard::instance = 0;

Keyboard* Keyboard::getInstance()
{
    if(instance == 0)
    {
        instance = new Keyboard();
    }

    return instance;
}

Keyboard::Keyboard() :
    angleIncrement(0.015625),    // 2^(-6)
    translationIncrement(0.125), // 2^(-3)
    spacebarPressed(false)
{}

void Keyboard::resetKeyboardStatus()
{
    for(int i = 0; i < 256; i += 1)
    {
        keyboardStatus[i] = false;
    }
}

// Note that these are the CONTINUOUS actions only. For toggle state actions,
// take care of it before the array of keyboard button status is enabled.
void Keyboard::applyNormalKeyboardActions()
{
    Camera* camera = ClothSimulator::getInstance()->getScene()->getCamera();

    for(int key = 0; key < 256; key += 1)
    {
        // if the key is being continuously held down
        if(keyboardStatus[key])
        {
            switch(key)
            {
                // world axis camera controls
                case 'a':
                    camera->rotateAroundYAxisWorld(-angleIncrement);
                    break;
                case 'd':
                    camera->rotateAroundYAxisWorld(angleIncrement);
                    break;
                case 's':
                    camera->rotateAroundXAxisWorld(-angleIncrement);
                    break;
                case 'w':
                    camera->rotateAroundXAxisWorld(angleIncrement);
                    break;
                case 'q':
                    camera->rotateAroundZAxisWorld(-angleIncrement);
                    break;
                case 'e':
                    camera->rotateAroundZAxisWorld(angleIncrement);
                    break;

                // yaw, pitch and roll camera controls
                case 'k':
                    // turn camera "down" one notch
                    camera->rotateAroundXAxisObject(angleIncrement);
                    break;
                case 'i':
                    // turn camera "up" one notch
                    camera->rotateAroundXAxisObject(-angleIncrement);
                    break;
                case 'j':
                    // turn camera "left" one notch
                    camera->rotateAroundYAxisObject(angleIncrement);
                    break;
                case 'l':
                    // turn camera "right" one notch
                    camera->rotateAroundYAxisObject(-angleIncrement);
                    break;
                case 'u':
                    // tilt camera "left" one notch
                    camera->rotateAroundZAxisObject(-angleIncrement);
                    break;
                case 'o':
                    // tilt camera "right" one notch
                    camera->rotateAroundZAxisObject(angleIncrement);
                    break;

                // camera translation controls
                case 'f':
                    // translate camera left
                    camera->translate(camera->getUpDirection().cross(camera->getViewDirection()).normalize() * translationIncrement);
                    break;
                case 'h':
                    // translate camera right
                    camera->translate(camera->getViewDirection().cross(camera->getUpDirection()).normalize() * translationIncrement);
                    break;
                case 't':
                    // translate camera up
                    camera->translate(camera->getUpDirection().normalize() * translationIncrement);
                    break;
                case 'g':
                    // translate camera down
                    camera->translate(-camera->getUpDirection().normalize() * translationIncrement);
                    break;
                case 'r':
                    // translate camera back
                    camera->translate(-camera->getViewDirection().normalize() * translationIncrement);
                    break;
                case 'z':
                    // translate camera front
                    camera->translate(camera->getViewDirection().normalize() * translationIncrement);
                    break;

                default:
                    break;
            } // end switch(key)
        } // end if(keyboardStatus[key])
    } // end loop
}

// Put toggle keyboard controls here, and continuous ones in the "default" part of
// the switch statement
void Keyboard::handleNormalKeyboardInput(unsigned char key, int x, int y)
{
    DrawingSettings* drawingSettings = DrawingSettings::getInstance();

    switch(key)
    {
        case '1':
            drawingSettings->toggleDrawArrowsEnabled();
            break;
        case '2':
            drawingSettings->toggleDrawFloorEnabled();
            break;
        case '3':
            drawingSettings->toggleDrawTrianglesEnabled();
            break;
        case 32:
            spacebarPressed = !spacebarPressed;

            if(spacebarPressed)
            {
                drawingSettings->setTimeStep(0.0001);
            }
            else
            {
                drawingSettings->setTimeStep(0.0);
            }

        default:
            // toggle enable state for keyboard buttons which are to be
            // continuously applied (like rotations, translations, ...)
            keyboardStatus[key] = true;
            break;
    }

}

void Keyboard::handleNormalKeyboardRelease(unsigned char key, int x, int y)
{
    // toggle disable state for keyboard buttons which are to be
    // continuously applied (like rotations, translations, ...)
    keyboardStatus[key] = false;
}

void Keyboard::handleSpecialKeyboardInput(int key, int x, int y)
{
    DrawingSettings* drawingSettings = DrawingSettings::getInstance();

    switch(key)
    {
        case GLUT_KEY_F1:
            showHelp();
            break;
        case GLUT_KEY_F2:
            ClothSimulator::getInstance()->getScene()->getCamera()->loadCameraSetup();
            break;
        case GLUT_KEY_F3:
            ClothSimulator::getInstance()->getScene()->getCamera()->showCameraStatus();
            break;
        case GLUT_KEY_F4:
            DrawingSettings::getInstance()->showDrawStatus();
            break;
        case GLUT_KEY_F5:
            drawingSettings->toggleDrawStructuralConstraintsEnabled();
            break;
        case GLUT_KEY_F6:
            drawingSettings->toggleDrawShearConstraintsEnabled();
            break;
        case GLUT_KEY_F7:
            break;
        case GLUT_KEY_F8:
            break;
        case GLUT_KEY_F9:
            drawingSettings->toggleDrawNodesEnabled();
            break;
        case GLUT_KEY_F10:
            drawingSettings->toggleDrawWireFrameEnabled();
            break;
        case GLUT_KEY_F11:
            drawingSettings->toggleDrawWorldAxisEnabled();
            break;
        case GLUT_KEY_F12:
            drawingSettings->toggleDrawSpheresEnabled();
            break;

        default:
            break;
    }
}

void Keyboard::showHelp()
{
    std::cout << "******************************************" << std::endl;
    std::cout << "********           help           ********" << std::endl;
    std::cout << "******************************************" << std::endl;

    std::cout << std::endl;

    std::cout << "ESC: exit cloth simulator" << std::endl;

    std::cout << std::endl;

    // help controls
    std::cout << "help controls:" << std::endl;
    std::cout << "  F1: show help" << std::endl;

    std::cout << std::endl;

    std::cout << "camera position reset:" << std::endl;
    std::cout << "  F2: reset camera position" << std::endl;

    std::cout << std::endl;

    std::cout << "status controls:" << std::endl;
    std::cout << "  F3: show camera status" << std::endl;
    std::cout << "  F4: show draw   status" << std::endl;

    std::cout << std::endl;

    // drawing controls
    std::cout << "drawing controls:" << std::endl;
    std::cout << "  F5   : toggle draw structural      constraints" << std::endl;
    std::cout << "  F6   : toggle draw shear           constraints" << std::endl;
    std::cout << "  F7   : toggle draw structural bend constraints" << std::endl;
    std::cout << "  F8   : toggle draw shear      bend constraints" << std::endl;
    std::cout << "  F9   : toggle draw nodes" << std::endl;
    std::cout << "  F10  : toggle draw wireframe" << std::endl;
    std::cout << "  F11  : toggle draw world axis" << std::endl;
    std::cout << "  F12  : toggle draw spheres" << std::endl;
    std::cout << "  1    : toggle draw arrows" << std::endl;
    std::cout << "  2    : toggle draw floor" << std::endl;
    std::cout << "  3    : toggle draw triangles" << std::endl;
    std::cout << "  space: toggle pause" << std::endl;

    std::cout << std::endl;

    // yaw, pitch and roll camera controls
    std::cout << "camera object rotation controls:" << std::endl;
    std::cout << "  j: yaw   left " << std::endl;
    std::cout << "  l: yaw   right" << std::endl;
    std::cout << "  k: pitch down " << std::endl;
    std::cout << "  i: pitch up   " << std::endl;
    std::cout << "  u: roll  left " << std::endl;
    std::cout << "  o: roll  right" << std::endl;

    std::cout << std::endl;

    // world camera controls
    std::cout << "camera world rotation controls:" << std::endl;
    std::cout << "  s: rotate camera left  around world X axis" << std::endl;
    std::cout << "  w: rotate camera right around world X axis" << std::endl;
    std::cout << "  a: rotate camera left  around world Y axis" << std::endl;
    std::cout << "  d: rotate camera right around world Y axis" << std::endl;
    std::cout << "  e: rotate camera left  around world Z axis" << std::endl;
    std::cout << "  q: rotate camera right around world Z axis" << std::endl;

    std::cout << std::endl;

    // camera position controls
    std::cout << "camera translation controls:" << std::endl;
    std::cout << "  f: translate camera left" << std::endl;
    std::cout << "  h: translate camera right" << std::endl;
    std::cout << "  t: translate camera up" << std::endl;
    std::cout << "  g: translate camera down" << std::endl;
    std::cout << "  r: translate camera back" << std::endl;
    std::cout << "  z: translate camera front" << std::endl;

    std::cout << std::endl;
}<|endoftext|>


<commit_before>#ifndef _HARDWARE_HXX_
#define _HARDWARE_HXX_

#include "TivaGPIO.hxx"
#include "DummyGPIO.hxx"
#include "driverlib/rom_map.h"
#include "utils/GpioInitializer.hxx"

GPIO_PIN(SW1, GpioInputPU, F, 4);
GPIO_PIN(SW2, GpioInputPU, F, 0);

GPIO_PIN(LED_RED_RAW, LedPin, F, 1);
GPIO_PIN(LED_GREEN, LedPin, F, 3);
GPIO_PIN(LED_BLUE, LedPin, F, 2);

typedef LED_RED_RAW_Pin BLINKER_RAW_Pin;

GPIO_HWPIN(RAILCOM_CH1, GpioHwPin, B, 0, U1RX, UART);

GPIO_HWPIN(UART0RX, GpioHwPin, A, 0, U0RX, UART);
GPIO_HWPIN(UART0TX, GpioHwPin, A, 1, U0TX, UART);

GPIO_PIN(USB1, GpioUSBAPin, D, 4);
GPIO_PIN(USB2, GpioUSBAPin, D, 5);

GPIO_HWPIN(CAN0RX, GpioHwPin, E, 4, CAN0RX, CAN);
GPIO_HWPIN(CAN0TX, GpioHwPin, E, 5, CAN0TX, CAN);

typedef GpioInitializer<                          //
    SW1_Pin, SW2_Pin,                             //
    RAILCOM_CH1_Pin,                              //
    LED_RED_RAW_Pin, LED_GREEN_Pin, LED_BLUE_Pin, //
    USB1_Pin, USB2_Pin,                           //
    UART0RX_Pin, UART0TX_Pin,                     //
    CAN0RX_Pin, CAN0TX_Pin> GpioInit;

namespace TDebug {
using Resync = DummyPin;
using NextPacket = DummyPin;
};

#endif // _HARDWARE_HXX_
<commit_msg>Switches the 123 launchpad's blinker to the blue LED.<commit_after>#ifndef _HARDWARE_HXX_
#define _HARDWARE_HXX_

#include "TivaGPIO.hxx"
#include "DummyGPIO.hxx"
#include "BlinkerGPIO.hxx"
#include "driverlib/rom_map.h"
#include "utils/GpioInitializer.hxx"

GPIO_PIN(SW1, GpioInputPU, F, 4);
GPIO_PIN(SW2, GpioInputPU, F, 0);

GPIO_PIN(LED_RED, LedPin, F, 1);
GPIO_PIN(LED_GREEN, LedPin, F, 3);
GPIO_PIN(LED_BLUE_RAW, LedPin, F, 2);

typedef LED_BLUE_RAW_Pin BLINKER_RAW_Pin;
typedef BLINKER_Pin LED_BLUE_Pin;

GPIO_HWPIN(RAILCOM_CH1, GpioHwPin, B, 0, U1RX, UART);

GPIO_HWPIN(UART0RX, GpioHwPin, A, 0, U0RX, UART);
GPIO_HWPIN(UART0TX, GpioHwPin, A, 1, U0TX, UART);

GPIO_PIN(USB1, GpioUSBAPin, D, 4);
GPIO_PIN(USB2, GpioUSBAPin, D, 5);

GPIO_HWPIN(CAN0RX, GpioHwPin, E, 4, CAN0RX, CAN);
GPIO_HWPIN(CAN0TX, GpioHwPin, E, 5, CAN0TX, CAN);

typedef GpioInitializer<                          //
    SW1_Pin, SW2_Pin,                             //
    RAILCOM_CH1_Pin,                              //
    LED_RED_Pin, LED_GREEN_Pin, LED_BLUE_RAW_Pin, //
    USB1_Pin, USB2_Pin,                           //
    UART0RX_Pin, UART0TX_Pin,                     //
    CAN0RX_Pin, CAN0TX_Pin> GpioInit;

namespace TDebug {
using Resync = DummyPin;
using NextPacket = DummyPin;
};

#endif // _HARDWARE_HXX_
<|endoftext|>


<commit_before>#ifndef __STDAIR_BOM_BOMCHILDRENHOLDERIMP_HPP
#define __STDAIR_BOM_BOMCHILDRENHOLDERIMP_HPP

// //////////////////////////////////////////////////////////////////////
// Import section
// //////////////////////////////////////////////////////////////////////
// C
#include <assert.h>
// STL
#include <vector>
#include <string>
#include <map>
//STDAIR
#include <stdair/bom/BomChildrenHolder.hpp>
#include <stdair/bom/BomIterator.hpp>

namespace stdair {

  /** Template class aimed at holding a list and a map of children BOM
      structure of a dedicated type. */
  template <typename BOM_CONTENT_CHILD>
  class BomChildrenHolderImp : public BomChildrenHolder {
    friend class FacBomStructure;

    /** Retrieve associated bom structure type. */
    typedef typename BOM_CONTENT_CHILD::BomStructure_T BomStructure_T;

  public:
    /** Define lists of children BOM structures. */
    typedef std::vector<BomStructure_T*> BomChildrenOrderedList_T;
    typedef std::map<const std::string, BomStructure_T*> BomChildrenList_T;

    /** Define the different types of iterators. */
    typedef BomConstIterator_T<BOM_CONTENT_CHILD,
                               typename BomChildrenOrderedList_T::const_iterator> ListConstIterator_T;
    typedef BomConstIterator_T<BOM_CONTENT_CHILD,
                               typename BomChildrenOrderedList_T::const_reverse_iterator> ListConstReverseIterator_T;
    typedef BomIterator_T<BOM_CONTENT_CHILD,
                          typename BomChildrenOrderedList_T::iterator> ListIterator_T;
    typedef BomIterator_T<BOM_CONTENT_CHILD,
                          typename BomChildrenOrderedList_T::reverse_iterator> ListReverseIterator_T;
    typedef BomConstIterator_T<BOM_CONTENT_CHILD,
                               typename BomChildrenList_T::const_iterator> MapConstIterator_T;
    typedef BomConstIterator_T<BOM_CONTENT_CHILD,
                               typename BomChildrenList_T::const_reverse_iterator> MapConstReverseIterator_T;
    typedef BomIterator_T<BOM_CONTENT_CHILD,
                          typename BomChildrenList_T::iterator> MapIterator_T;
    typedef BomIterator_T<BOM_CONTENT_CHILD,
                          typename BomChildrenList_T::reverse_iterator> MapReverseIterator_T;

  public:
    // /////////// Display support methods /////////
    /** Dump a Business Object into an output stream.
        @param ostream& the output stream. */
    void toStream (std::ostream& ioOut) const { ioOut << toString(); }

    /** Read a Business Object from an input stream.
        @param istream& the input stream. */
    void fromStream (std::istream& ioIn) { }

   /** Get the serialised version of the Business Object. */
    std::string toString() const { return std::string (""); }

    /** Get a string describing the whole key (differentiating two objects
        at any level). */
    const std::string describeKey() const { return std::string (""); }

    /** Get a string describing the short key (differentiating two objects
        at the same level). */
    const std::string describeShortKey() const { return std::string (""); }

    /** Dump a Business Object into an output stream.
        @param ostream& the output stream. */
    void describeFull (std::ostringstream& ioOut) const {
      // Initialise the index
      unsigned short lIdx = 0;

      for (typename BomChildrenOrderedList_T::const_iterator itChild =
             _bomChildrenOrderedList.begin();
           itChild != _bomChildrenOrderedList.end(); ++itChild, ++lIdx) {
        const BomStructure_T* lCurrentChild_ptr = *itChild;
        ioOut << "[" << lIdx << "]: ";
        lCurrentChild_ptr->describeFull (ioOut);
      }
    }

    // /////////// Iteration methods //////////
    /** Initialise the internal const iterators on bom objects:
        return the iterator at the begining of the list. */
    ListConstIterator_T listConstIteratorBegin () const {
      return _bomChildrenOrderedList.begin();
    }

    /** Initialise the internal const iterators on bom objects:
        return the iterator past the end of the list. */
    ListConstIterator_T listConstIteratorEnd () const {
      return _bomChildrenOrderedList.end();
    }

    /** Initialise the internal const reverse iterators on bom objects:
        return the reverse iterator at the rbegining of the list. */
    ListConstReverseIterator_T listConstIteratorRBegin () const {
      return _bomChildrenOrderedList.rbegin();
    }

    /** Initialise the internal const reverse iterators on bom objects:
        return the reverse iterator past the rend of the list. */
    ListConstReverseIterator_T listConstIteratorREnd () const {
      return _bomChildrenOrderedList.rend();
    }

    /** Initialise the internal iterators on bom objects:
        return the iterator at the begining of the list. */
    ListIterator_T listIteratorBegin () const {
      return _bomChildrenOrderedList.begin();
    }

    /** Initialise the internal iterators on bom objects:
        return the iterator past the end of the list. */
    ListIterator_T listIteratorEnd () const {
      return _bomChildrenOrderedList.end();
    }

    /** Initialise the internal reverse iterators on bom objects:
        return the reverse iterator at the rbegining of the list. */
    ListReverseIterator_T listIteratorRBegin () const {
      return _bomChildrenOrderedList.rbegin();
    }

    /** Initialise the internal reverse iterators on bom objects:
        return the reverse iterator past the rend of the list. */
    ListReverseIterator_T listIteratorREnd () const {
      return _bomChildrenOrderedList.rend();
    }

    /** Initialise the internal const iterators on bom objects:
        return the iterator at the begining of the map. */
    MapConstIterator_T mapConstIteratorBegin () const {
      return _bomChildrenList.begin();
    }

    /** Initialise the internal const iterators on bom objects:
        return the iterator past the end of the map. */
    MapConstIterator_T mapConstIteratorEnd () const {
      return _bomChildrenList.end();
    }

    /** Initialise the internal const reverse iterators on bom objects:
        return the reverse iterator at the rbegining of the map. */
    MapConstReverseIterator_T mapConstIteratorRBegin () const {
      return _bomChildrenList.rbegin();
    }

    /** Initialise the internal const reverse iterators on bom objects:
        return the reverse iterator past the rend of the map. */
    MapConstReverseIterator_T mapConstIteratorREnd () const {
      return _bomChildrenList.rend();
    }

    /** Initialise the internal iterators on bom objects:
        return the iterator at the begining of the map. */
    MapIterator_T mapIteratorBegin () const {
      return _bomChildrenList.begin();
    }

    /** Initialise the internal iterators on bom objects:
        return the iterator past the end of the map. */
    MapIterator_T mapIteratorEnd () const {
      return _bomChildrenList.end();
    }

    /** Initialise the internal reverse iterators on bom objects:
        return the reverse iterator at the rbegining of the map. */
    MapReverseIterator_T mapIteratorRBegin () const {
      return _bomChildrenList.rbegin();
    }

    /** Initialise the internal reverse iterators on bom objects:
        return the reverse iterator past the rend of the map. */
    MapReverseIterator_T mapIteratorREnd () const {
      return _bomChildrenList.rend();
    }

  private:
    /** Constructors are private so as to force the usage of the Factory
        layer. */
    /** Default constructors. */
    BomChildrenHolderImp () { }
    BomChildrenHolderImp (const BomChildrenHolderImp&);

    /** Destructor. */
    ~BomChildrenHolderImp() { }

  private:
    ///////////// Attributes //////////////
    /** List of children BOM structures. */
    BomChildrenList_T _bomChildrenList;

    /** Map of children BOM structures with their key. */
    BomChildrenOrderedList_T _bomChildrenOrderedList;
  };

}
#endif // __STDAIR_BOM_BOMCHILDRENHOLDERIMP_HPP

<commit_msg>Small change in some functions.<commit_after>#ifndef __STDAIR_BOM_BOMCHILDRENHOLDERIMP_HPP
#define __STDAIR_BOM_BOMCHILDRENHOLDERIMP_HPP

// //////////////////////////////////////////////////////////////////////
// Import section
// //////////////////////////////////////////////////////////////////////
// C
#include <assert.h>
// STL
#include <vector>
#include <string>
#include <map>
//STDAIR
#include <stdair/bom/BomChildrenHolder.hpp>
#include <stdair/bom/BomIterator.hpp>

namespace stdair {

  /** Template class aimed at holding a list and a map of children BOM
      structure of a dedicated type. */
  template <typename BOM_CONTENT_CHILD>
  class BomChildrenHolderImp : public BomChildrenHolder {
    friend class FacBomStructure;

    /** Retrieve associated bom structure type. */
    typedef typename BOM_CONTENT_CHILD::BomStructure_T BomStructure_T;

  public:
    /** Define lists of children BOM structures. */
    typedef std::vector<BomStructure_T*> BomChildrenOrderedList_T;
    typedef std::map<const std::string, BomStructure_T*> BomChildrenList_T;

    /** Define the different types of iterators. */
    typedef BomConstIterator_T<BOM_CONTENT_CHILD,
                               typename BomChildrenOrderedList_T::const_iterator> ListConstIterator_T;
    typedef BomConstIterator_T<BOM_CONTENT_CHILD,
                               typename BomChildrenOrderedList_T::const_reverse_iterator> ListConstReverseIterator_T;
    typedef BomIterator_T<BOM_CONTENT_CHILD,
                          typename BomChildrenOrderedList_T::iterator> ListIterator_T;
    typedef BomIterator_T<BOM_CONTENT_CHILD,
                          typename BomChildrenOrderedList_T::reverse_iterator> ListReverseIterator_T;
    typedef BomConstIterator_T<BOM_CONTENT_CHILD,
                               typename BomChildrenList_T::const_iterator> MapConstIterator_T;
    typedef BomConstIterator_T<BOM_CONTENT_CHILD,
                               typename BomChildrenList_T::const_reverse_iterator> MapConstReverseIterator_T;
    typedef BomIterator_T<BOM_CONTENT_CHILD,
                          typename BomChildrenList_T::iterator> MapIterator_T;
    typedef BomIterator_T<BOM_CONTENT_CHILD,
                          typename BomChildrenList_T::reverse_iterator> MapReverseIterator_T;

  public:
    // /////////// Display support methods /////////
    /** Dump a Business Object into an output stream.
        @param ostream& the output stream. */
    void toStream (std::ostream& ioOut) const { ioOut << toString(); }

    /** Read a Business Object from an input stream.
        @param istream& the input stream. */
    void fromStream (std::istream& ioIn) { }

   /** Get the serialised version of the Business Object. */
    std::string toString() const { return std::string (""); }

    /** Get a string describing the whole key (differentiating two objects
        at any level). */
    const std::string describeKey() const { return std::string (""); }

    /** Get a string describing the short key (differentiating two objects
        at the same level). */
    const std::string describeShortKey() const { return std::string (""); }

    /** Dump a Business Object into an output stream.
        @param ostream& the output stream. */
    void describeFull (std::ostringstream& ioOut) const {
      // Initialise the index
      unsigned short lIdx = 0;

      for (typename BomChildrenOrderedList_T::const_iterator itChild =
             _bomChildrenOrderedList.begin();
           itChild != _bomChildrenOrderedList.end(); ++itChild, ++lIdx) {
        const BomStructure_T* lCurrentChild_ptr = *itChild;
        ioOut << "[" << lIdx << "]: ";
        lCurrentChild_ptr->describeFull (ioOut);
      }
    }

    // /////////// Iteration methods //////////
    /** Initialise the internal const iterators on bom objects:
        return the iterator at the begining of the list. */
    ListConstIterator_T listConstIteratorBegin () const {
      return _bomChildrenOrderedList.begin();
    }

    /** Initialise the internal const iterators on bom objects:
        return the iterator past the end of the list. */
    ListConstIterator_T listConstIteratorEnd () const {
      return _bomChildrenOrderedList.end();
    }

    /** Initialise the internal const reverse iterators on bom objects:
        return the reverse iterator at the rbegining of the list. */
    ListConstReverseIterator_T listConstIteratorRBegin () const {
      return _bomChildrenOrderedList.rbegin();
    }

    /** Initialise the internal const reverse iterators on bom objects:
        return the reverse iterator past the rend of the list. */
    ListConstReverseIterator_T listConstIteratorREnd () const {
      return _bomChildrenOrderedList.rend();
    }

    /** Initialise the internal iterators on bom objects:
        return the iterator at the begining of the list. */
    ListIterator_T listIteratorBegin () const {
      return ListIterator_T(_bomChildrenOrderedList.begin());
    }

    /** Initialise the internal iterators on bom objects:
        return the iterator past the end of the list. */
    ListIterator_T listIteratorEnd () const {
      return ListIterator_T(_bomChildrenOrderedList.end());
    }

    /** Initialise the internal reverse iterators on bom objects:
        return the reverse iterator at the rbegining of the list. */
    ListReverseIterator_T listIteratorRBegin () const {
      return ListReverseIterator_T(_bomChildrenOrderedList.rbegin());
    }

    /** Initialise the internal reverse iterators on bom objects:
        return the reverse iterator past the rend of the list. */
    ListReverseIterator_T listIteratorREnd () const {
      return ListReverseIterator_T(_bomChildrenOrderedList.rend());
    }

    /** Initialise the internal const iterators on bom objects:
        return the iterator at the begining of the map. */
    MapConstIterator_T mapConstIteratorBegin () const {
      return _bomChildrenList.begin();
    }

    /** Initialise the internal const iterators on bom objects:
        return the iterator past the end of the map. */
    MapConstIterator_T mapConstIteratorEnd () const {
      return _bomChildrenList.end();
    }

    /** Initialise the internal const reverse iterators on bom objects:
        return the reverse iterator at the rbegining of the map. */
    MapConstReverseIterator_T mapConstIteratorRBegin () const {
      return _bomChildrenList.rbegin();
    }

    /** Initialise the internal const reverse iterators on bom objects:
        return the reverse iterator past the rend of the map. */
    MapConstReverseIterator_T mapConstIteratorREnd () const {
      return _bomChildrenList.rend();
    }

    /** Initialise the internal iterators on bom objects:
        return the iterator at the begining of the map. */
    MapIterator_T mapIteratorBegin () const {
      return MapIterator_T(_bomChildrenList.begin());
    }

    /** Initialise the internal iterators on bom objects:
        return the iterator past the end of the map. */
    MapIterator_T mapIteratorEnd () const {
      return MapIterator_T(_bomChildrenList.end());
    }

    /** Initialise the internal reverse iterators on bom objects:
        return the reverse iterator at the rbegining of the map. */
    MapReverseIterator_T mapIteratorRBegin () const {
      return MapReverseIterator_T(_bomChildrenList.rbegin());
    }

    /** Initialise the internal reverse iterators on bom objects:
        return the reverse iterator past the rend of the map. */
    MapReverseIterator_T mapIteratorREnd () const {
      return MapReverseIterator_T(_bomChildrenList.rend());
    }

  private:
    /** Constructors are private so as to force the usage of the Factory
        layer. */
    /** Default constructors. */
    BomChildrenHolderImp () { }
    BomChildrenHolderImp (const BomChildrenHolderImp&);

    /** Destructor. */
    ~BomChildrenHolderImp() { }

  private:
    ///////////// Attributes //////////////
    /** List of children BOM structures. */
    BomChildrenList_T _bomChildrenList;

    /** Map of children BOM structures with their key. */
    BomChildrenOrderedList_T _bomChildrenOrderedList;
  };

}
#endif // __STDAIR_BOM_BOMCHILDRENHOLDERIMP_HPP

<|endoftext|>


<commit_before>// ShapeTools.cpp
// Copyright (c) 2009, Dan Heeks
// This program is released under the BSD license. See the file COPYING for details.

#include "stdafx.h"
#include "ShapeTools.h"
#include "Vertex.h"

void CreateFacesAndEdges(TopoDS_Shape shape, CFaceList* faces, CEdgeList* edges, CVertexList* vertices)
{
	// create the face objects
	TopTools_MapOfShape edgeMap;
	for (TopExp_Explorer expFace(shape, TopAbs_FACE); expFace.More(); expFace.Next())
	{
		TopoDS_Face F = TopoDS::Face(expFace.Current());
		CFace* new_object = new CFace(F);
		faces->Add(new_object, NULL);

		// create the edge objects from each face
		for (TopExp_Explorer expEdge(F, TopAbs_EDGE); expEdge.More(); expEdge.Next())
		{
			edgeMap.Add(expEdge.Current());
		}
	}

	// create the vertex object
	for (TopExp_Explorer expVertex(shape, TopAbs_VERTEX); expVertex.More(); expVertex.Next())
	{
		TopoDS_Vertex v = TopoDS::Vertex(expVertex.Current());
		CVertex* new_object = new CVertex(v);
		vertices->Add(new_object, NULL);
	}

	TopTools_MapIteratorOfMapOfShape It(edgeMap);
	std::map<const TopoDS_Shape*, CEdge*> edge_finder;
	for (;It.More(); It.Next())
	{
		const TopoDS_Shape &E = It.Key();
		CEdge* new_object = new CEdge(TopoDS::Edge(E));
		edges->Add(new_object, NULL);
		edge_finder.insert( std::pair<const TopoDS_Shape*, CEdge*>(&E, new_object) );
	}

	// make an edge map for each face
	std::map< CFace*, TopTools_MapOfShape*> face_edge_maps;
	for(HeeksObj* object = faces->GetFirstChild(); object; object = faces->GetNextChild())
	{
		CFace* face = (CFace*)object;
		TopTools_MapOfShape* newEdgeMap = new TopTools_MapOfShape;
		face_edge_maps.insert( std::make_pair(face, newEdgeMap) );

		for (TopExp_Explorer expEdge(face->Face(), TopAbs_EDGE); expEdge.More(); expEdge.Next())
		{
			const TopoDS_Shape &E = expEdge.Current();
			newEdgeMap->Add(E);
		}
	}

	// for each edge, find which faces it belongs to
	for(HeeksObj* object = edges->GetFirstChild(); object; object = edges->GetNextChild())
	{
		CEdge* edge = (CEdge*)object;

		const TopoDS_Shape &E = edge->Edge();

		// test each face
		for(std::map< CFace*, TopTools_MapOfShape*>::iterator It = face_edge_maps.begin(); It != face_edge_maps.end(); It++)
		{
			CFace* face = It->first;
			TopTools_MapOfShape *map = It->second;
			if(map->Contains(E)){
				face->m_edges.push_back(edge);
			}
		}
	}

	// create the face loops
	std::set<HeeksObj*> edges_to_delete;
	for(HeeksObj* object = faces->GetFirstChild(); object; object = faces->GetNextChild())
	{
		CFace* face = (CFace*)object;
		const TopoDS_Shape &F = face->Face();

		TopoDS_Wire outerWire=BRepTools::OuterWire(TopoDS::Face(F));

		for (TopExp_Explorer expWire(F, TopAbs_WIRE); expWire.More(); expWire.Next())
		{
			const TopoDS_Shape &W = expWire.Current();
			bool is_outer = W.IsSame(outerWire) != 0;
			std::list<CEdge*> edges;

			TopAbs_Orientation wo = W.Orientation();
			bool bwo = (wo == TopAbs_FORWARD);
			TopAbs_Orientation fwo = F.Orientation();
			bool bfwo = (fwo == TopAbs_FORWARD);
			bool ooooo = (bwo == bfwo);

			for(BRepTools_WireExplorer expEdge(TopoDS::Wire(W)); expEdge.More(); expEdge.Next())
			{
				// look through the face's existing edges to find the CEdge*
				for(CEdge* edge = face->GetFirstEdge(); edge; edge = face->GetNextEdge())
				{
					const TopoDS_Shape &E = edge->Edge();
					if(E.IsSame(expEdge.Current())) {
						edges.push_back(edge);
						edge->m_faces.push_back(face);
						break;
					}
				}
			}

			std::list<CEdge*> edges_for_loop;
			for(std::list<CEdge*>::iterator It = edges.begin(); It != edges.end(); It++){
				CEdge* edge = *It;
				if(edge->m_faces.size() == 2 && edge->m_faces.front() == edge->m_faces.back()){
					if(edges_for_loop.size() > 0){
						CLoop* new_loop = new CLoop(face, ooooo, edges_for_loop, is_outer);
						face->m_loops.push_back(new_loop);
						edges_for_loop.clear();
					}
					edges_to_delete.insert(edge);
					face->m_edges.clear();
				}
				else{
					edges_for_loop.push_back(edge);
				}
			}
			if(edges_for_loop.size() > 0){
				CLoop* new_loop = new CLoop(face, ooooo, edges_for_loop, is_outer);
				face->m_loops.push_back(new_loop);
			}
		}
	}

	// delete edges
	edges->Clear(edges_to_delete);

	// calculate face senses
	for(HeeksObj* object = edges->GetFirstChild(); object; object = edges->GetNextChild())
	{
		CEdge* edge = (CEdge*)object;
		const TopoDS_Shape &E1 = edge->Edge();
		for(CFace* face = edge->GetFirstFace(); face; face = edge->GetNextFace())
		{
			bool sense = false;
			const TopoDS_Shape &F = face->Face();
			for (TopExp_Explorer expEdge(F, TopAbs_EDGE); expEdge.More(); expEdge.Next())
			{
				const TopoDS_Shape &E2 = expEdge.Current(); // this is the edge on the face
				if(E1.IsSame(E2))// same edge, but maybe different orientation
				{
					if(E1.IsEqual(E2))sense = true; // same orientation too
					break; // same edge ( ignore the face's other edges )
				}
			}
			edge->m_face_senses.push_back(sense); // one sense for each face, for each edge
		}
	}

	// delete the maps
	for(std::map< CFace*, TopTools_MapOfShape*>::iterator It = face_edge_maps.begin(); It != face_edge_maps.end(); It++)
	{
		TopTools_MapOfShape *map = It->second;
		delete map;
	}

#if _DEBUG
	// test InFaceSense
	for(HeeksObj* object = edges->GetFirstChild(); object; object = edges->GetNextChild())
	{
		CEdge* edge = (CEdge*)object;

		for(CFace* face = edge->GetFirstFace(); face; face = edge->GetNextFace())
		{
			bool in_face_sense = edge->InFaceSense(face);

			bool here = false;
			here = true;
		}
	}
#endif
}

<commit_msg>edge ids were not the same each time<commit_after>// ShapeTools.cpp
// Copyright (c) 2009, Dan Heeks
// This program is released under the BSD license. See the file COPYING for details.

#include "stdafx.h"
#include "ShapeTools.h"
#include "Vertex.h"

void CreateFacesAndEdges(TopoDS_Shape shape, CFaceList* faces, CEdgeList* edges, CVertexList* vertices)
{
	// create the face objects
	TopTools_MapOfShape edgeMap;
	for (TopExp_Explorer expFace(shape, TopAbs_FACE); expFace.More(); expFace.Next())
	{
		TopoDS_Face F = TopoDS::Face(expFace.Current());
		CFace* new_object = new CFace(F);
		faces->Add(new_object, NULL);

		// create the edge objects from each face
		for (TopExp_Explorer expEdge(F, TopAbs_EDGE); expEdge.More(); expEdge.Next())
		{
			edgeMap.Add(expEdge.Current());
		}
	}

	// create the vertex object
	for (TopExp_Explorer expVertex(shape, TopAbs_VERTEX); expVertex.More(); expVertex.Next())
	{
		TopoDS_Vertex v = TopoDS::Vertex(expVertex.Current());
		CVertex* new_object = new CVertex(v);
		vertices->Add(new_object, NULL);
	}

	// create the edge objects
	for (TopExp_Explorer expEdge(shape, TopAbs_EDGE); expEdge.More(); expEdge.Next())
	{
		TopoDS_Edge E = TopoDS::Edge(expEdge.Current());
		CEdge* new_object = new CEdge(E);
		edges->Add(new_object, NULL);
	}

	// make an edge map for each face
	std::map< CFace*, TopTools_MapOfShape*> face_edge_maps;
	for(HeeksObj* object = faces->GetFirstChild(); object; object = faces->GetNextChild())
	{
		CFace* face = (CFace*)object;
		TopTools_MapOfShape* newEdgeMap = new TopTools_MapOfShape;
		face_edge_maps.insert( std::make_pair(face, newEdgeMap) );

		for (TopExp_Explorer expEdge(face->Face(), TopAbs_EDGE); expEdge.More(); expEdge.Next())
		{
			const TopoDS_Shape &E = expEdge.Current();
			newEdgeMap->Add(E);
		}
	}

	// for each edge, find which faces it belongs to
	for(HeeksObj* object = edges->GetFirstChild(); object; object = edges->GetNextChild())
	{
		CEdge* edge = (CEdge*)object;

		const TopoDS_Shape &E = edge->Edge();

		// test each face
		for(std::map< CFace*, TopTools_MapOfShape*>::iterator It = face_edge_maps.begin(); It != face_edge_maps.end(); It++)
		{
			CFace* face = It->first;
			TopTools_MapOfShape *map = It->second;
			if(map->Contains(E)){
				face->m_edges.push_back(edge);
			}
		}
	}

	// create the face loops
	std::set<HeeksObj*> edges_to_delete;
	for(HeeksObj* object = faces->GetFirstChild(); object; object = faces->GetNextChild())
	{
		CFace* face = (CFace*)object;
		const TopoDS_Shape &F = face->Face();

		TopoDS_Wire outerWire=BRepTools::OuterWire(TopoDS::Face(F));

		for (TopExp_Explorer expWire(F, TopAbs_WIRE); expWire.More(); expWire.Next())
		{
			const TopoDS_Shape &W = expWire.Current();
			bool is_outer = W.IsSame(outerWire) != 0;
			std::list<CEdge*> edges;

			TopAbs_Orientation wo = W.Orientation();
			bool bwo = (wo == TopAbs_FORWARD);
			TopAbs_Orientation fwo = F.Orientation();
			bool bfwo = (fwo == TopAbs_FORWARD);
			bool ooooo = (bwo == bfwo);

			for(BRepTools_WireExplorer expEdge(TopoDS::Wire(W)); expEdge.More(); expEdge.Next())
			{
				// look through the face's existing edges to find the CEdge*
				for(CEdge* edge = face->GetFirstEdge(); edge; edge = face->GetNextEdge())
				{
					const TopoDS_Shape &E = edge->Edge();
					if(E.IsSame(expEdge.Current())) {
						edges.push_back(edge);
						edge->m_faces.push_back(face);
						break;
					}
				}
			}

			std::list<CEdge*> edges_for_loop;
			for(std::list<CEdge*>::iterator It = edges.begin(); It != edges.end(); It++){
				CEdge* edge = *It;
				if(edge->m_faces.size() == 2 && edge->m_faces.front() == edge->m_faces.back()){
					if(edges_for_loop.size() > 0){
						CLoop* new_loop = new CLoop(face, ooooo, edges_for_loop, is_outer);
						face->m_loops.push_back(new_loop);
						edges_for_loop.clear();
					}
					edges_to_delete.insert(edge);
					face->m_edges.clear();
				}
				else{
					edges_for_loop.push_back(edge);
				}
			}
			if(edges_for_loop.size() > 0){
				CLoop* new_loop = new CLoop(face, ooooo, edges_for_loop, is_outer);
				face->m_loops.push_back(new_loop);
			}
		}
	}

	// delete edges
	edges->Clear(edges_to_delete);

	// calculate face senses
	for(HeeksObj* object = edges->GetFirstChild(); object; object = edges->GetNextChild())
	{
		CEdge* edge = (CEdge*)object;
		const TopoDS_Shape &E1 = edge->Edge();
		for(CFace* face = edge->GetFirstFace(); face; face = edge->GetNextFace())
		{
			bool sense = false;
			const TopoDS_Shape &F = face->Face();
			for (TopExp_Explorer expEdge(F, TopAbs_EDGE); expEdge.More(); expEdge.Next())
			{
				const TopoDS_Shape &E2 = expEdge.Current(); // this is the edge on the face
				if(E1.IsSame(E2))// same edge, but maybe different orientation
				{
					if(E1.IsEqual(E2))sense = true; // same orientation too
					break; // same edge ( ignore the face's other edges )
				}
			}
			edge->m_face_senses.push_back(sense); // one sense for each face, for each edge
		}
	}

	// delete the maps
	for(std::map< CFace*, TopTools_MapOfShape*>::iterator It = face_edge_maps.begin(); It != face_edge_maps.end(); It++)
	{
		TopTools_MapOfShape *map = It->second;
		delete map;
	}

#if _DEBUG
	// test InFaceSense
	for(HeeksObj* object = edges->GetFirstChild(); object; object = edges->GetNextChild())
	{
		CEdge* edge = (CEdge*)object;

		for(CFace* face = edge->GetFirstFace(); face; face = edge->GetNextFace())
		{
			bool in_face_sense = edge->InFaceSense(face);

			bool here = false;
			here = true;
		}
	}
#endif
}

<|endoftext|>


<commit_before>/*
 * Part of tivars_lib_cpp
 * (C) 2015-2018 Adrien "Adriweb" Bertrand
 * https://github.com/adriweb/tivars_lib_cpp
 * License: MIT
 */

#include "TIVarTypes.h"
#include "utils.h"

using namespace std;

namespace tivars
{
    unordered_map<string, TIVarType> types;

// Wrap the makeDataFromStr function by one that adds the type/subtype in the options
// Ideally, the handlers would parse the string and select the correct handler to dispatch...
#define make_generic_handler_pair(cls, type) make_pair([](const std::string& str, const options_t& options) -> data_t { \
    options_t options_withType = options;                                                                               \
    options_withType["_type"] = type;                                                                                \
    return (cls::makeDataFromString)(str, options_withType);                                                            \
}, &cls::makeStringFromData)

#define GenericRealHandlerPairWithType(type)    make_generic_handler_pair(TH_GenericReal,    type)
#define GenericComplexHandlerPairWithType(type) make_generic_handler_pair(TH_GenericComplex, type)
#define GenericListHandlerPairWithType(type)    make_generic_handler_pair(TH_GenericList,    type)

    /**
     *  Make and insert the associative arrays for the type.
     *
     * @param string    name        The name of the type
     * @param int       id          The ID of the type
     * @param vector    exts        The extensions the type can have, ordered by feature flags.
     * @param pair      handlers    The data2str and str2data funcs
     */
    void TIVarTypes::insertType(string name, int id, const vector<string>& exts, const handler_pair_t& handlers)
    {
        TIVarType varType(id, name, exts, handlers);
        string id_str = to_string(id);
        types[name]   = varType;
        types[id_str] = varType;
        for (const string& ext : exts)
        {
            if (!ext.empty() && !types.count(ext))
            {
                types[ext] = varType;
            }
        }
    }

    // 82+/83+/84+ are grouped since only the clock is the difference, and it doesn't have an actual varType.
    // For number vartypes, Real and Complex are the generic handlers we use, they'll dispatch to specific ones.
    void TIVarTypes::initTIVarTypesArray() // order: 82     83    82A  82+/83+  84+C  84+CE  83PCE
                                           //                     84+T   84+         84+CE-T
    {
        insertType("Unknown",                -1,  {  "" ,   "" ,   "" ,   "" ,   "" ,   "" ,   "" });

        /* Standard types */
        insertType("Real",                 0x00,  {"82n", "83n", "8xn", "8xn", "8xn", "8xn", "8xn"},  GenericRealHandlerPairWithType(0x00) );
        insertType("RealList",             0x01,  {"82l", "83l", "8xl", "8xl", "8xl", "8xl", "8xl"},  GenericListHandlerPairWithType(0x00) );
        insertType("Matrix",               0x02,  {"82m", "83m", "8xm", "8xm", "8xm", "8xm", "8xm"},  make_handler_pair(TH_Matrix) );
        insertType("Equation",             0x03,  {"82y", "83y", "8xy", "8xy", "8xy", "8xy", "8xy"},  make_handler_pair(TH_Tokenized) );
        insertType("String",               0x04,  {"82s", "83s", "8xs", "8xs", "8xs", "8xs", "8xs"},  make_handler_pair(TH_Tokenized) );
        insertType("Program",              0x05,  {"82p", "83p", "8xp", "8xp", "8xp", "8xp", "8xp"},  make_handler_pair(TH_Tokenized) );
        insertType("ProtectedProgram",     0x06,  {"82p", "83p", "8xp", "8xp", "8xp", "8xp", "8xp"},  make_handler_pair(TH_Tokenized) );
        insertType("Picture",              0x07,  {  "" ,   "" , "8xi", "8xi", "8ci", "8ci", "8ci"});
        insertType("GraphDataBase",        0x08,  {"82d", "83d", "8xd", "8xd", "8xd", "8xd", "8xd"});
        insertType("Complex",              0x0C,  {  "" , "83c", "8xc", "8xc", "8xc", "8xc", "8xc"},  GenericComplexHandlerPairWithType(0x0C) );
        insertType("ComplexList",          0x0D,  {  "" , "83l", "8xl", "8xl", "8xl", "8xl", "8xl"},  GenericListHandlerPairWithType(0x0C) );
        insertType("WindowSettings",       0x0F,  {"82w", "83w", "8xw", "8xw", "8xw", "8xw", "8xw"});
        insertType("RecallWindow",         0x10,  {"82z", "83z", "8xz", "8xz", "8xz", "8xz", "8xz"});
        insertType("TableRange",           0x11,  {"82t", "83t", "8xt", "8xt", "8xt", "8xt", "8xt"});
        insertType("Backup",               0x13,  {"82b", "83b",   "" , "8xb", "8cb",   "" ,   "" });
        insertType("AppVar",               0x15,  {  "" ,   "" ,   "" , "8xv", "8xv", "8xv", "8xv"},  make_handler_pair(TH_AppVar) );
        insertType("TemporaryItem",        0x16,  {  "" ,   "" ,   "" ,   "" ,   "" ,   "" ,   "" });
        insertType("GroupObject",          0x17,  {"82g", "83g", "8xg", "8xg", "8xg", "8cg", "8cg"});
        insertType("RealFraction",         0x18,  {  "" ,   "" ,   "" , "8xn", "8xn", "8xn", "8xn"},  GenericRealHandlerPairWithType(0x18) );
        insertType("Image",                0x1A,  {  "" ,   "" ,   "" ,   "" ,   "" , "8ca", "8ca"});

        /* Exact values (TI-83 Premium CE) */
        /* See https://docs.google.com/document/d/1P_OUbnZMZFg8zuOPJHAx34EnwxcQZ8HER9hPeOQ_dtI */
        insertType("ExactComplexFrac",     0x1B,  {  "" ,   "" ,   "" ,   "" ,   "" ,   "" , "8xc"},  GenericComplexHandlerPairWithType(0x1B) );
        insertType("ExactRealRadical",     0x1C,  {  "" ,   "" ,   "" ,   "" ,   "" ,   "" , "8xn"},  GenericRealHandlerPairWithType(0x1C)    );
        insertType("ExactComplexRadical",  0x1D,  {  "" ,   "" ,   "" ,   "" ,   "" ,   "" , "8xc"},  GenericComplexHandlerPairWithType(0x1D) );
        insertType("ExactComplexPi",       0x1E,  {  "" ,   "" ,   "" ,   "" ,   "" ,   "" , "8xc"},  GenericComplexHandlerPairWithType(0x1E) );
        insertType("ExactComplexPiFrac",   0x1F,  {  "" ,   "" ,   "" ,   "" ,   "" ,   "" , "8xc"},  GenericComplexHandlerPairWithType(0x1F) );
        insertType("ExactRealPi",          0x20,  {  "" ,   "" ,   "" ,   "" ,   "" ,   "" , "8xn"},  GenericRealHandlerPairWithType(0x20)    );
        insertType("ExactRealPiFrac",      0x21,  {  "" ,   "" ,   "" ,   "" ,   "" ,   "" , "8xn"},  GenericRealHandlerPairWithType(0x21)    );

        /* System/Flash-related things */
        insertType("OperatingSystem",      0x23,  {"82u", "83u", "82u", "8xu", "8cu", "8eu", "8pu"});
        insertType("FlashApp",             0x24,  {  "" ,   "" ,   "" , "8xk", "8ck", "8ek", "8ek"});
        insertType("Certificate",          0x25,  {  "" ,   "" ,   "" , "8xq", "8cq",   "" ,   "" });
        insertType("CertificateMemory",    0x27,  {  "" ,   "" ,   "" ,   "" ,   "" ,   "" ,   "" });
        insertType("Clock",                0x29,  {  "" ,   "" ,   "" ,   "" ,   "" ,   "" ,   "" });
        insertType("FlashLicense",         0x3E,  {  "" ,   "" ,   "" ,   "" ,   "" ,   "" ,   "" });

        // WindowSettings clone thing
        types["0x0B"] = types["0x0F"];
    }

    /**
     * @param   int     id     The type ID
     * @return  string          The type name for that ID
     */
    string TIVarTypes::getNameFromID(int id)
    {
        string id_str = to_string(id);
        if (id != -1 && types.count(id_str))
        {
            return types[id_str].getName();
        } else {
            return "Unknown";
        }
    }

    /**
     * @param   string  name   The type name
     * @return  int             The type ID for that name
     */
    int TIVarTypes::getIDFromName(string name)
    {
        if (!name.empty() && types.count(name))
        {
            return types[name].getId();
        } else {
            return -1;
        }
    }

    /**
     * @param   int     id     The type ID
     * @return  string[]        The array of extensions for that ID
     */
    vector<string> TIVarTypes::getExtensionsFromTypeID(int id)
    {
        string id_str = to_string(id);
        if (id != -1 && types.count(id_str))
        {
            return types[id_str].getExts();
        } else {
            return {};
        }
    }

    /**
     * @param   string  name
     * @return  string[]        The array of extensions for that ID
     */
    vector<string> TIVarTypes::getExtensionsFromName(string name)
    {
        if (!name.empty() && types.count(name))
        {
            return types[name].getExts();
        } else {
            return {};
        }
    }

    bool TIVarTypes::isValidID(int id)
    {
        string id_str = to_string(id);
        return (id != -1 && types.count(id_str));
    }

    bool TIVarTypes::isValidName(const string& name)
    {
        return (!name.empty() && types.count(name));
    }
}

//TIVarTypes::initTIVarTypesArray();
<commit_msg>Simplify generic macro in TIVarTypes.cpp<commit_after>/*
 * Part of tivars_lib_cpp
 * (C) 2015-2018 Adrien "Adriweb" Bertrand
 * https://github.com/adriweb/tivars_lib_cpp
 * License: MIT
 */

#include "TIVarTypes.h"
#include "utils.h"

using namespace std;

namespace tivars
{
    unordered_map<string, TIVarType> types;

// Wrap the makeDataFromStr function by one that adds the type/subtype in the options
// Ideally, the handlers would parse the string and select the correct handler to dispatch...
#define GenericHandlerPair(which, type) make_pair([](const std::string& str, const options_t& options) -> data_t { \
    options_t options_withType = options;                                                                          \
    options_withType["_type"] = type;                                                                              \
    return (TH_Generic##which::makeDataFromString)(str, options_withType);                                         \
}, &TH_Generic##which::makeStringFromData)

    /**
     *  Make and insert the associative arrays for the type.
     *
     * @param string    name        The name of the type
     * @param int       id          The ID of the type
     * @param vector    exts        The extensions the type can have, ordered by feature flags.
     * @param pair      handlers    The data2str and str2data funcs
     */
    void TIVarTypes::insertType(string name, int id, const vector<string>& exts, const handler_pair_t& handlers)
    {
        TIVarType varType(id, name, exts, handlers);
        string id_str = to_string(id);
        types[name]   = varType;
        types[id_str] = varType;
        for (const string& ext : exts)
        {
            if (!ext.empty() && !types.count(ext))
            {
                types[ext] = varType;
            }
        }
    }

    // 82+/83+/84+ are grouped since only the clock is the difference, and it doesn't have an actual varType.
    // For number vartypes, Real and Complex are the generic handlers we use, they'll dispatch to specific ones.
    void TIVarTypes::initTIVarTypesArray() // order: 82     83    82A  82+/83+  84+C  84+CE  83PCE
                                           //                     84+T   84+         84+CE-T
    {
        insertType("Unknown",                -1,  {  "" ,   "" ,   "" ,   "" ,   "" ,   "" ,   "" });

        /* Standard types */
        insertType("Real",                 0x00,  {"82n", "83n", "8xn", "8xn", "8xn", "8xn", "8xn"},  GenericHandlerPair(Real, 0x00)  );
        insertType("RealList",             0x01,  {"82l", "83l", "8xl", "8xl", "8xl", "8xl", "8xl"},  GenericHandlerPair(List, 0x00)  );
        insertType("Matrix",               0x02,  {"82m", "83m", "8xm", "8xm", "8xm", "8xm", "8xm"},  make_handler_pair(TH_Matrix)    );
        insertType("Equation",             0x03,  {"82y", "83y", "8xy", "8xy", "8xy", "8xy", "8xy"},  make_handler_pair(TH_Tokenized) );
        insertType("String",               0x04,  {"82s", "83s", "8xs", "8xs", "8xs", "8xs", "8xs"},  make_handler_pair(TH_Tokenized) );
        insertType("Program",              0x05,  {"82p", "83p", "8xp", "8xp", "8xp", "8xp", "8xp"},  make_handler_pair(TH_Tokenized) );
        insertType("ProtectedProgram",     0x06,  {"82p", "83p", "8xp", "8xp", "8xp", "8xp", "8xp"},  make_handler_pair(TH_Tokenized) );
        insertType("Picture",              0x07,  {  "" ,   "" , "8xi", "8xi", "8ci", "8ci", "8ci"});
        insertType("GraphDataBase",        0x08,  {"82d", "83d", "8xd", "8xd", "8xd", "8xd", "8xd"});
        insertType("Complex",              0x0C,  {  "" , "83c", "8xc", "8xc", "8xc", "8xc", "8xc"},  GenericHandlerPair(Complex, 0x0C) );
        insertType("ComplexList",          0x0D,  {  "" , "83l", "8xl", "8xl", "8xl", "8xl", "8xl"},  GenericHandlerPair(List,    0x0C) );
        insertType("WindowSettings",       0x0F,  {"82w", "83w", "8xw", "8xw", "8xw", "8xw", "8xw"});
        insertType("RecallWindow",         0x10,  {"82z", "83z", "8xz", "8xz", "8xz", "8xz", "8xz"});
        insertType("TableRange",           0x11,  {"82t", "83t", "8xt", "8xt", "8xt", "8xt", "8xt"});
        insertType("Backup",               0x13,  {"82b", "83b",   "" , "8xb", "8cb",   "" ,   "" });
        insertType("AppVar",               0x15,  {  "" ,   "" ,   "" , "8xv", "8xv", "8xv", "8xv"},  make_handler_pair(TH_AppVar) );
        insertType("TemporaryItem",        0x16,  {  "" ,   "" ,   "" ,   "" ,   "" ,   "" ,   "" });
        insertType("GroupObject",          0x17,  {"82g", "83g", "8xg", "8xg", "8xg", "8cg", "8cg"});
        insertType("RealFraction",         0x18,  {  "" ,   "" ,   "" , "8xn", "8xn", "8xn", "8xn"},  GenericHandlerPair(Real, 0x18) );
        insertType("Image",                0x1A,  {  "" ,   "" ,   "" ,   "" ,   "" , "8ca", "8ca"});

        /* Exact values (TI-83 Premium CE) */
        /* See https://docs.google.com/document/d/1P_OUbnZMZFg8zuOPJHAx34EnwxcQZ8HER9hPeOQ_dtI */
        insertType("ExactComplexFrac",     0x1B,  {  "" ,   "" ,   "" ,   "" ,   "" ,   "" , "8xc"},  GenericHandlerPair(Complex, 0x1B) );
        insertType("ExactRealRadical",     0x1C,  {  "" ,   "" ,   "" ,   "" ,   "" ,   "" , "8xn"},  GenericHandlerPair(Real,    0x1C) );
        insertType("ExactComplexRadical",  0x1D,  {  "" ,   "" ,   "" ,   "" ,   "" ,   "" , "8xc"},  GenericHandlerPair(Complex, 0x1D) );
        insertType("ExactComplexPi",       0x1E,  {  "" ,   "" ,   "" ,   "" ,   "" ,   "" , "8xc"},  GenericHandlerPair(Complex, 0x1E) );
        insertType("ExactComplexPiFrac",   0x1F,  {  "" ,   "" ,   "" ,   "" ,   "" ,   "" , "8xc"},  GenericHandlerPair(Complex, 0x1F) );
        insertType("ExactRealPi",          0x20,  {  "" ,   "" ,   "" ,   "" ,   "" ,   "" , "8xn"},  GenericHandlerPair(Real,    0x20) );
        insertType("ExactRealPiFrac",      0x21,  {  "" ,   "" ,   "" ,   "" ,   "" ,   "" , "8xn"},  GenericHandlerPair(Real,    0x21) );

        /* System/Flash-related things */
        insertType("OperatingSystem",      0x23,  {"82u", "83u", "82u", "8xu", "8cu", "8eu", "8pu"});
        insertType("FlashApp",             0x24,  {  "" ,   "" ,   "" , "8xk", "8ck", "8ek", "8ek"});
        insertType("Certificate",          0x25,  {  "" ,   "" ,   "" , "8xq", "8cq",   "" ,   "" });
        insertType("CertificateMemory",    0x27,  {  "" ,   "" ,   "" ,   "" ,   "" ,   "" ,   "" });
        insertType("Clock",                0x29,  {  "" ,   "" ,   "" ,   "" ,   "" ,   "" ,   "" });
        insertType("FlashLicense",         0x3E,  {  "" ,   "" ,   "" ,   "" ,   "" ,   "" ,   "" });

        // WindowSettings clone thing
        types["0x0B"] = types["0x0F"];
    }

    /**
     * @param   int     id     The type ID
     * @return  string          The type name for that ID
     */
    string TIVarTypes::getNameFromID(int id)
    {
        string id_str = to_string(id);
        if (id != -1 && types.count(id_str))
        {
            return types[id_str].getName();
        } else {
            return "Unknown";
        }
    }

    /**
     * @param   string  name   The type name
     * @return  int             The type ID for that name
     */
    int TIVarTypes::getIDFromName(string name)
    {
        if (!name.empty() && types.count(name))
        {
            return types[name].getId();
        } else {
            return -1;
        }
    }

    /**
     * @param   int     id     The type ID
     * @return  string[]        The array of extensions for that ID
     */
    vector<string> TIVarTypes::getExtensionsFromTypeID(int id)
    {
        string id_str = to_string(id);
        if (id != -1 && types.count(id_str))
        {
            return types[id_str].getExts();
        } else {
            return {};
        }
    }

    /**
     * @param   string  name
     * @return  string[]        The array of extensions for that ID
     */
    vector<string> TIVarTypes::getExtensionsFromName(string name)
    {
        if (!name.empty() && types.count(name))
        {
            return types[name].getExts();
        } else {
            return {};
        }
    }

    bool TIVarTypes::isValidID(int id)
    {
        string id_str = to_string(id);
        return (id != -1 && types.count(id_str));
    }

    bool TIVarTypes::isValidName(const string& name)
    {
        return (!name.empty() && types.count(name));
    }
}

//TIVarTypes::initTIVarTypesArray();
<|endoftext|>


<commit_before>/* Copyright 2013-present Barefoot Networks, Inc.
 *
 * 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.
 */

/*
 * Antonin Bas (antonin@barefootnetworks.com)
 *
 */

#ifdef P4THRIFT
#include <p4thrift/protocol/TBinaryProtocol.h>
#include <p4thrift/transport/TSocket.h>
#include <p4thrift/transport/TTransportUtils.h>
#include <p4thrift/protocol/TMultiplexedProtocol.h>

namespace thrift_provider = p4::thrift;
#else
#include <thrift/protocol/TBinaryProtocol.h>
#include <thrift/transport/TSocket.h>
#include <thrift/transport/TTransportUtils.h>
#include <thrift/protocol/TMultiplexedProtocol.h>

namespace thrift_provider = apache::thrift;
#endif

#include <bm/bm_apps/learn.h>
#include <bm/Standard.h>
#include <bm/SimplePre.h>

#include <nanomsg/pubsub.h>

#include <iostream>
#include <string>

#include <cassert>

#include "nn.h"

namespace bm_apps {

namespace runtime = bm_runtime::standard;

namespace {

struct learn_hdr_t {
  char sub_topic[4];
  int switch_id;
  int cxt_id;
  int list_id;
  uint64_t buffer_id;
  unsigned int num_samples;
  char _padding[4];
} __attribute__((packed));

}  // namespace

LearnListener::LearnListener(const std::string &learn_socket,
                             const std::string &thrift_addr,
                             const int thrift_port)
  : socket_name(learn_socket),
    thrift_addr(thrift_addr), thrift_port(thrift_port) {
  (void) this->thrift_port;  // clang unused private field warning
}

LearnListener::~LearnListener() {
  {
    std::unique_lock<std::mutex> lock(mutex);
    stop_listen_thread = true;
  }
  listen_thread.join();
}

void
LearnListener::register_cb(const LearnCb &cb, void *cookie) {
  std::unique_lock<std::mutex> lock(mutex);
  cb_fn = cb;
  cb_cookie = cookie;
}

void
LearnListener::ack_buffer(cxt_id_t cxt_id, list_id_t list_id,
                          buffer_id_t buffer_id) {
  assert(bm_client);
  bm_client->bm_learning_ack_buffer(cxt_id, list_id, buffer_id);
}

void
LearnListener::start() {
  using thrift_provider::protocol::TProtocol;
  using thrift_provider::protocol::TBinaryProtocol;
  using thrift_provider::protocol::TMultiplexedProtocol;
  using thrift_provider::transport::TSocket;
  using thrift_provider::transport::TTransport;
  using thrift_provider::transport::TBufferedTransport;

  boost::shared_ptr<TTransport> tsocket(new TSocket("localhost", 9090));
  boost::shared_ptr<TTransport> transport(new TBufferedTransport(tsocket));
  boost::shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport));

  boost::shared_ptr<TMultiplexedProtocol> standard_protocol(
      new TMultiplexedProtocol(protocol, "standard"));

  bm_client = boost::shared_ptr<runtime::StandardClient>(
      new runtime::StandardClient(standard_protocol));

  transport->open();

  listen_thread = std::thread(&LearnListener::listen_loop, this);
}

void
LearnListener::listen_loop() {
  nn::socket s(AF_SP, NN_SUB);
  // only subscribe to learn notifications
  s.setsockopt(NN_SUB, NN_SUB_SUBSCRIBE, "LEA", 3);
  int to = 200;
  s.setsockopt(NN_SOL_SOCKET, NN_RCVTIMEO, &to, sizeof(to));
  s.connect(socket_name.c_str());

  struct nn_msghdr msghdr;
  struct nn_iovec iov[2];
  learn_hdr_t learn_hdr;
  char data[4096];
  iov[0].iov_base = &learn_hdr;
  iov[0].iov_len = sizeof(learn_hdr);
  iov[1].iov_base = data;
  iov[1].iov_len = sizeof(data);  // apparently only max size needed ?
  memset(&msghdr, 0, sizeof(msghdr));
  msghdr.msg_iov = iov;
  msghdr.msg_iovlen = 2;

  while (true) {
    if (s.recvmsg(&msghdr, 0) <= 0) {
      std::unique_lock<std::mutex> lock(mutex);
      if (stop_listen_thread) return;
      continue;
    }

    LearnCb cb_fn_;
    void *cb_cookie_;
    std::cout << "I received " << learn_hdr.num_samples << " samples\n";

    {
      std::unique_lock<std::mutex> lock(mutex);
      // I don't believe this is expensive
      cb_fn_ = cb_fn;
      cb_cookie_ = cb_cookie;
    }

    if (!cb_fn_) {
      std::cout << "No callback\n";
      continue;
    }

    std::cout << "Calling callback function\n";
    MsgInfo info = {learn_hdr.switch_id, learn_hdr.cxt_id, learn_hdr.list_id,
                    learn_hdr.buffer_id, learn_hdr.num_samples};
    cb_fn_(info, data, cb_cookie_);
  }
}

}  // namespace bm_apps
<commit_msg>Use right thrift socket in bm_apps::LearnListener (#285)<commit_after>/* Copyright 2013-present Barefoot Networks, Inc.
 *
 * 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.
 */

/*
 * Antonin Bas (antonin@barefootnetworks.com)
 *
 */

#ifdef P4THRIFT
#include <p4thrift/protocol/TBinaryProtocol.h>
#include <p4thrift/transport/TSocket.h>
#include <p4thrift/transport/TTransportUtils.h>
#include <p4thrift/protocol/TMultiplexedProtocol.h>

namespace thrift_provider = p4::thrift;
#else
#include <thrift/protocol/TBinaryProtocol.h>
#include <thrift/transport/TSocket.h>
#include <thrift/transport/TTransportUtils.h>
#include <thrift/protocol/TMultiplexedProtocol.h>

namespace thrift_provider = apache::thrift;
#endif

#include <bm/bm_apps/learn.h>
#include <bm/Standard.h>
#include <bm/SimplePre.h>

#include <nanomsg/pubsub.h>

#include <iostream>
#include <string>

#include <cassert>

#include "nn.h"

namespace bm_apps {

namespace runtime = bm_runtime::standard;

namespace {

struct learn_hdr_t {
  char sub_topic[4];
  int switch_id;
  int cxt_id;
  int list_id;
  uint64_t buffer_id;
  unsigned int num_samples;
  char _padding[4];
} __attribute__((packed));

}  // namespace

LearnListener::LearnListener(const std::string &learn_socket,
                             const std::string &thrift_addr,
                             const int thrift_port)
  : socket_name(learn_socket),
    thrift_addr(thrift_addr), thrift_port(thrift_port) { }

LearnListener::~LearnListener() {
  {
    std::unique_lock<std::mutex> lock(mutex);
    stop_listen_thread = true;
  }
  listen_thread.join();
}

void
LearnListener::register_cb(const LearnCb &cb, void *cookie) {
  std::unique_lock<std::mutex> lock(mutex);
  cb_fn = cb;
  cb_cookie = cookie;
}

void
LearnListener::ack_buffer(cxt_id_t cxt_id, list_id_t list_id,
                          buffer_id_t buffer_id) {
  assert(bm_client);
  bm_client->bm_learning_ack_buffer(cxt_id, list_id, buffer_id);
}

void
LearnListener::start() {
  using thrift_provider::protocol::TProtocol;
  using thrift_provider::protocol::TBinaryProtocol;
  using thrift_provider::protocol::TMultiplexedProtocol;
  using thrift_provider::transport::TSocket;
  using thrift_provider::transport::TTransport;
  using thrift_provider::transport::TBufferedTransport;

  boost::shared_ptr<TTransport> tsocket(new TSocket(thrift_addr, thrift_port));
  boost::shared_ptr<TTransport> transport(new TBufferedTransport(tsocket));
  boost::shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport));

  boost::shared_ptr<TMultiplexedProtocol> standard_protocol(
      new TMultiplexedProtocol(protocol, "standard"));

  bm_client = boost::shared_ptr<runtime::StandardClient>(
      new runtime::StandardClient(standard_protocol));

  transport->open();

  listen_thread = std::thread(&LearnListener::listen_loop, this);
}

void
LearnListener::listen_loop() {
  nn::socket s(AF_SP, NN_SUB);
  // only subscribe to learn notifications
  s.setsockopt(NN_SUB, NN_SUB_SUBSCRIBE, "LEA", 3);
  int to = 200;
  s.setsockopt(NN_SOL_SOCKET, NN_RCVTIMEO, &to, sizeof(to));
  s.connect(socket_name.c_str());

  struct nn_msghdr msghdr;
  struct nn_iovec iov[2];
  learn_hdr_t learn_hdr;
  char data[4096];
  iov[0].iov_base = &learn_hdr;
  iov[0].iov_len = sizeof(learn_hdr);
  iov[1].iov_base = data;
  iov[1].iov_len = sizeof(data);  // apparently only max size needed ?
  memset(&msghdr, 0, sizeof(msghdr));
  msghdr.msg_iov = iov;
  msghdr.msg_iovlen = 2;

  while (true) {
    if (s.recvmsg(&msghdr, 0) <= 0) {
      std::unique_lock<std::mutex> lock(mutex);
      if (stop_listen_thread) return;
      continue;
    }

    LearnCb cb_fn_;
    void *cb_cookie_;
    std::cout << "I received " << learn_hdr.num_samples << " samples\n";

    {
      std::unique_lock<std::mutex> lock(mutex);
      // I don't believe this is expensive
      cb_fn_ = cb_fn;
      cb_cookie_ = cb_cookie;
    }

    if (!cb_fn_) {
      std::cout << "No callback\n";
      continue;
    }

    std::cout << "Calling callback function\n";
    MsgInfo info = {learn_hdr.switch_id, learn_hdr.cxt_id, learn_hdr.list_id,
                    learn_hdr.buffer_id, learn_hdr.num_samples};
    cb_fn_(info, data, cb_cookie_);
  }
}

}  // namespace bm_apps
<|endoftext|>


<commit_before>#include "Counter.h"

namespace mtg {

Counter::Counter(std::string name, int powerModifier, int toughnessModifier):
    name_(name),
    powerModifier_(powerModifier),
    toughnessModifier_(toughnessModifier)
{}

bool Counter::operator==(Counter const & other) const
{
    return name_ == other.name_;
}

Counter Counter::poison("poison");
Counter Counter::plusOneOne("+1/+1",1,1);
Counter Counter::minusOneOne("-1/-1",-1,-1);
Counter Counter::age("age");
Counter Counter::time("time");
Counter Counter::levelUp("levelUp");
Counter Counter::loyalty("loyalty");

}
<commit_msg>added missed functions<commit_after>#include "Counter.h"

namespace mtg {

Counter::Counter(std::string name, int powerModifier, int toughnessModifier):
    name_(name),
    powerModifier_(powerModifier),
    toughnessModifier_(toughnessModifier)
{}

bool Counter::operator==(Counter const & other) const
{
    return name_ == other.name_;
}

std::string Counter::name() const { return name_; }
int Counter::powerModifier() const { return powerModifier_; }
int Counter::toughnessModifier() const { return toughnessModifier_; }

Counter Counter::poison("poison");
Counter Counter::plusOneOne("+1/+1",1,1);
Counter Counter::minusOneOne("-1/-1",-1,-1);
Counter Counter::age("age");
Counter Counter::time("time");
Counter Counter::levelUp("levelUp");
Counter Counter::loyalty("loyalty");

}
<|endoftext|>


<commit_before>#include "exporter.h"
#include "cell.h"
#include "gtest/gtest.h"
#include "test_util.h"

namespace bdm {

TEST(ExportTest, ConductExportToFile) {
  // set up cells and their positions
  Cell cell1;
  cell1.SetPosition({0.5, 1, 0});
  cell1.SetDiameter(10);
  Cell cell2;
  cell2.SetPosition({-5, 5, 0.9});
  cell2.SetDiameter(10);

  auto cells = Cell::NewEmptySoa();
  cells.push_back(cell1);
  cells.push_back(cell2);

  /// Test the standard file exporter
  auto exp_basic = ExporterFactory::GenerateExporter<SoaCell>(kBasic);
  exp_basic->ToFile(cells, "TestBasicExporter.dat");
  std::ifstream t;
  std::stringstream buffer;
  t.open("TestBasicExporter.dat");
  std::string line;
  std::getline(t, line);
  EXPECT_EQ("[0.5,1,0]", line);
  std::getline(t, line);
  EXPECT_EQ("[-5,5,0.9]", line);
  std::getline(t, line);
  EXPECT_EQ("", line);
  t.close();
  remove("TestBasicExporter.dat");

  /// Test the Matlab file exporter
  auto exp_matlab = ExporterFactory::GenerateExporter<SoaCell>(kMatlab);
  exp_matlab->ToFile(cells, "TestMatlabExporter.m");
  t.open("TestMatlabExporter.m");
  std::getline(t, line);
  EXPECT_EQ("CellPos = zeros(2,3);", line);
  std::getline(t, line);
  EXPECT_EQ("CellPos(1,1:3) = [0.5,1,0];", line);
  std::getline(t, line);
  EXPECT_EQ("CellPos(2,1:3) = [-5,5,0.9];", line);
  std::getline(t, line);
  EXPECT_EQ("", line);
  t.close();
  remove("TestMatlabExporter.m");

  /// Test the NeuroML file exporter
  auto exp_neuroml = ExporterFactory::GenerateExporter<SoaCell>(kNeuroML);
  exp_neuroml->ToFile(cells, "TestNeuroMLExporter.m");
  t.open("TestNeuroMLExporter.m");
  std::getline(t, line);
  EXPECT_EQ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>", line);
  for (int i = 0; i < 5; ++i) {
    std::getline(t, line);
  }
  EXPECT_EQ("   lengthUnits=\"micrometer\" ", line);
  for (int i = 0; i < 30; ++i) {
    std::getline(t, line);
  }
  EXPECT_EQ("</neuroml>", line);
  t.close();
  remove("TestNeuroMLExporter.m");

  /// Test the Paraview exporter
  auto exp_paraview = ExporterFactory::GenerateExporter<SoaCell>(kParaview);
  exp_paraview->CreatePVDFile("TestResultsParaview", 1, 1.0);
  exp_paraview->ToFile(cells, "TestResultsParaview");
  t.open("TestResultsParaview.pvd");
  std::getline(t, line);
  EXPECT_EQ("<?xml version=\"1.0\"?>", line);
  std::getline(t, line);
  EXPECT_EQ(
      "<VTKFile type=\"Collection\" version=\"0.1\" "
      "byte_order=\"LittleEndian\">",
      line);
  std::getline(t, line);
  EXPECT_EQ("<Collection>", line);
  std::getline(t, line);
  EXPECT_EQ(
      "<DataSet timestep=\"0\" group=\"\" part=\"0\" "
      "file=\"TestResultsParaview-0.vtu\">",
      line);
  std::getline(t, line);
  EXPECT_EQ("</Collection>", line);
  remove("TestResultsParaview.pvd");
  t.close();
  remove("TestResultsParaview.pvd");

  t.open("TestResultsParaview-1.vtu");
  std::getline(t, line);
  EXPECT_EQ(
      "<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" "
      "byte_order=\"LittleEndian\">",
      line);
  for (int i = 0; i < 5; ++i) {
    std::getline(t, line);
  }
  EXPECT_EQ(" 0.5 1 0 -5 5 0.9", line);
  for (int i = 0; i < 20; ++i) {
    std::getline(t, line);
  }
  EXPECT_EQ(" 0 0 0 0 0 0", line);
  for (int i = 0; i < 16; ++i) {
    std::getline(t, line);
  }
  EXPECT_EQ("</VTKFile>", line);
  remove("TestResultsParaview-1.vtu");
}
}  // namespace bdm
<commit_msg>Add checks for EOF<commit_after>#include "exporter.h"
#include "cell.h"
#include "gtest/gtest.h"
#include "test_util.h"

namespace bdm {

TEST(ExportTest, ConductExportToFile) {
  // set up cells and their positions
  Cell cell1;
  cell1.SetPosition({0.5, 1, 0});
  cell1.SetDiameter(10);
  Cell cell2;
  cell2.SetPosition({-5, 5, 0.9});
  cell2.SetDiameter(10);

  auto cells = Cell::NewEmptySoa();
  cells.push_back(cell1);
  cells.push_back(cell2);

  /// Test the standard file exporter
  auto exp_basic = ExporterFactory::GenerateExporter<SoaCell>(kBasic);
  exp_basic->ToFile(cells, "TestBasicExporter.dat");
  std::ifstream ifs;
  ifs.open("TestBasicExporter.dat");
  std::string line;
  std::getline(ifs, line);
  EXPECT_EQ("[0.5,1,0]", line);
  std::getline(ifs, line);
  EXPECT_EQ("[-5,5,0.9]", line);
  EXPECT_FALSE(std::getline(ifs, line));
  EXPECT_EQ("", line);
  ifs.close();
  remove("TestBasicExporter.dat");

  /// Test the Matlab file exporter
  auto exp_matlab = ExporterFactory::GenerateExporter<SoaCell>(kMatlab);
  exp_matlab->ToFile(cells, "TestMatlabExporter.m");
  ifs.open("TestMatlabExporter.m");
  std::getline(ifs, line);
  EXPECT_EQ("CellPos = zeros(2,3);", line);
  std::getline(ifs, line);
  EXPECT_EQ("CellPos(1,1:3) = [0.5,1,0];", line);
  std::getline(ifs, line);
  EXPECT_EQ("CellPos(2,1:3) = [-5,5,0.9];", line);
  EXPECT_FALSE(std::getline(ifs, line));
  EXPECT_EQ("", line);
  ifs.close();
  remove("TestMatlabExporter.m");

  /// Test the NeuroML file exporter
  auto exp_neuroml = ExporterFactory::GenerateExporter<SoaCell>(kNeuroML);
  exp_neuroml->ToFile(cells, "TestNeuroMLExporter.m");
  ifs.open("TestNeuroMLExporter.m");
  std::getline(ifs, line);
  EXPECT_EQ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>", line);
  for (int i = 0; i < 5; ++i) {
    std::getline(ifs, line);
  }
  EXPECT_EQ("   lengthUnits=\"micrometer\" ", line);
  for (int i = 0; i < 30; ++i) {
    std::getline(ifs, line);
  }
  EXPECT_EQ("</neuroml>", line);
  EXPECT_FALSE(std::getline(ifs, line));
  EXPECT_EQ("", line);
  ifs.close();
  remove("TestNeuroMLExporter.m");

  /// Test the Paraview exporter
  auto exp_paraview = ExporterFactory::GenerateExporter<SoaCell>(kParaview);
  exp_paraview->CreatePVDFile("TestResultsParaview", 1, 1.0);
  exp_paraview->ToFile(cells, "TestResultsParaview");
  ifs.open("TestResultsParaview.pvd");
  std::getline(ifs, line);
  EXPECT_EQ("<?xml version=\"1.0\"?>", line);
  std::getline(ifs, line);
  EXPECT_EQ(
      "<VTKFile type=\"Collection\" version=\"0.1\" "
      "byte_order=\"LittleEndian\">",
      line);
  std::getline(ifs, line);
  EXPECT_EQ("<Collection>", line);
  std::getline(ifs, line);
  EXPECT_EQ(
      "<DataSet timestep=\"0\" group=\"\" part=\"0\" "
      "file=\"TestResultsParaview-0.vtu\">",
      line);
  std::getline(ifs, line);
  EXPECT_EQ("</Collection>", line);
  std::getline(ifs, line);
  EXPECT_EQ("</VTKFile>", line);
  EXPECT_FALSE(std::getline(ifs, line));
  EXPECT_EQ("", line);
  ifs.close();
  remove("TestResultsParaview.pvd");

  ifs.open("TestResultsParaview-1.vtu");
  std::getline(ifs, line);
  EXPECT_EQ(
      "<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" "
      "byte_order=\"LittleEndian\">",
      line);
  for (int i = 0; i < 5; ++i) {
    std::getline(ifs, line);
  }
  EXPECT_EQ(" 0.5 1 0 -5 5 0.9", line);
  for (int i = 0; i < 20; ++i) {
    std::getline(ifs, line);
  }
  EXPECT_EQ(" 0 0 0 0 0 0", line);
  for (int i = 0; i < 16; ++i) {
    std::getline(ifs, line);
  }
  EXPECT_EQ("</VTKFile>", line);
  EXPECT_FALSE(std::getline(ifs, line));
  EXPECT_EQ("", line);
  ifs.close();
  remove("TestResultsParaview-1.vtu");
}
}  // namespace bdm
<|endoftext|>


<commit_before>/*
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

#include "TypeAnalysisCallGraphGenerationPass.h"

#include "DexUtil.h"
#include "GlobalTypeAnalysisPass.h"
#include "MethodOverrideGraph.h"
#include "Walkers.h"

using namespace call_graph;
using namespace type_analyzer;

namespace mog = method_override_graph;

namespace {

class TypeAnalysisBasedStrategy : public MultipleCalleeBaseStrategy {
 public:
  explicit TypeAnalysisBasedStrategy(
      const Scope& scope,
      std::shared_ptr<type_analyzer::global::GlobalTypeAnalyzer> gta)
      : MultipleCalleeBaseStrategy(scope), m_gta(std::move(gta)) {
    walk::parallel::code(scope, [](DexMethod*, IRCode& code) {
      code.build_cfg(/* editable */ false);
      code.cfg().calculate_exit_block();
    });
  }

  CallSites get_callsites(const DexMethod* method) const override {
    CallSites callsites;
    auto* code = const_cast<IRCode*>(method->get_code());
    if (code == nullptr) {
      return callsites;
    }
    auto lta = m_gta->get_local_analysis(method);
    for (const auto& block : code->cfg().blocks()) {
      auto env = lta->get_entry_state_at(block);
      if (env.is_bottom()) {
        // Unreachable
        continue;
      }
      for (auto& mie : InstructionIterable(block)) {
        auto* insn = mie.insn;
        // Replay analysis for individual instruction
        lta->analyze_instruction(insn, &env);
        if (!opcode::is_an_invoke(insn->opcode())) {
          continue;
        }
        auto* resolved_callee = this->resolve_callee(method, insn);
        if (resolved_callee == nullptr) {
          continue;
        }
        if (!is_definitely_virtual(resolved_callee)) {
          // Not true virtual call
          if (resolved_callee->is_concrete()) {
            callsites.emplace_back(resolved_callee, code->iterator_to(mie));
          }
        } else {
          get_callsites_for_true_virtual_call(code, resolved_callee, env, mie,
                                              callsites);
        }
      }
    }
    return callsites;
  }

 protected:
  void get_callsites_for_true_virtual_call(IRCode* code,
                                           DexMethod* resolved_callee,
                                           const DexTypeEnvironment& env,
                                           MethodItemEntry& invoke,
                                           CallSites& callsites) const {
    auto* insn = invoke.insn;
    auto* callee_ref = insn->get_method();
    auto domain = env.get(insn->src(0));
    auto analysis_cls = domain.get_dex_cls();
    if (analysis_cls) {
      resolved_callee =
          resolve_method(*analysis_cls, callee_ref->get_name(),
                         callee_ref->get_proto(), opcode_to_search(insn));
    }
    // Add callees to callsites
    if (resolved_callee->is_concrete()) {
      callsites.emplace_back(resolved_callee, code->iterator_to(invoke));
    }
    if (insn->opcode() != OPCODE_INVOKE_SUPER) {
      const auto& overriding_methods = mog::get_overriding_methods(
          *m_method_override_graph, resolved_callee);
      for (auto overriding_method : overriding_methods) {
        callsites.emplace_back(overriding_method, code->iterator_to(invoke));
      }
    }
  }

  std::shared_ptr<type_analyzer::global::GlobalTypeAnalyzer> m_gta;
};

} // namespace

void TypeAnalysisCallGraphGenerationPass::run_pass(DexStoresVector& stores,
                                                   ConfigFiles& config,
                                                   PassManager& mgr) {
  auto analysis = mgr.get_preserved_analysis<GlobalTypeAnalysisPass>();
  always_assert(analysis);
  auto gta = analysis->get_result();
  always_assert(gta);

  Scope scope = build_class_scope(stores);
  m_result = std::make_shared<call_graph::Graph>(
      TypeAnalysisBasedStrategy(scope, gta));
}

static TypeAnalysisCallGraphGenerationPass s_pass;
<commit_msg>Enable TypeAnalysisCallGraphGenerationPass<commit_after>/*
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

#include "TypeAnalysisCallGraphGenerationPass.h"

#include "DexUtil.h"
#include "GlobalTypeAnalysisPass.h"
#include "MethodOverrideGraph.h"
#include "Walkers.h"

using namespace call_graph;
using namespace type_analyzer;

namespace mog = method_override_graph;

namespace {

void report_stats(const Graph& graph, PassManager& mgr) {
  auto stats = get_num_nodes_edges(graph);
  mgr.incr_metric("callgraph_nodes", stats.num_nodes);
  mgr.incr_metric("callgraph_edges", stats.num_edges);
  mgr.incr_metric("callgraph_callsites", stats.num_callsites);
  TRACE(TYPE, 2, "TypeAnalysisCallGraphGenerationPass Stats:");
  TRACE(TYPE, 2, " callgraph nodes = %u", stats.num_nodes);
  TRACE(TYPE, 2, " callgraph edges = %u", stats.num_edges);
  TRACE(TYPE, 2, " callgraph callsites = %u", stats.num_callsites);
}

/*
 * We can resolve the class of an invoke-interface target. In that case, we want
 * to adjust the MethodSearch type to be Virtual.
 */
MethodSearch get_method_search(const DexClass* analysis_cls,
                               IRInstruction* insn) {
  auto ms = opcode_to_search(insn);
  if (ms == MethodSearch::Interface && !is_interface(analysis_cls)) {
    ms = MethodSearch::Virtual;
  }
  return ms;
}

class TypeAnalysisBasedStrategy : public MultipleCalleeBaseStrategy {
 public:
  explicit TypeAnalysisBasedStrategy(
      const Scope& scope,
      std::shared_ptr<type_analyzer::global::GlobalTypeAnalyzer> gta)
      : MultipleCalleeBaseStrategy(scope), m_gta(std::move(gta)) {
    walk::parallel::code(scope, [](DexMethod*, IRCode& code) {
      code.build_cfg(/* editable */ false);
      code.cfg().calculate_exit_block();
    });
  }

  CallSites get_callsites(const DexMethod* method) const override {
    CallSites callsites;
    auto* code = const_cast<IRCode*>(method->get_code());
    if (code == nullptr) {
      return callsites;
    }
    auto lta = m_gta->get_local_analysis(method);
    for (const auto& block : code->cfg().blocks()) {
      auto env = lta->get_entry_state_at(block);
      if (env.is_bottom()) {
        // Unreachable
        continue;
      }
      for (auto& mie : InstructionIterable(block)) {
        auto* insn = mie.insn;
        // Replay analysis for individual instruction
        lta->analyze_instruction(insn, &env);
        if (!opcode::is_an_invoke(insn->opcode())) {
          continue;
        }
        auto* resolved_callee = this->resolve_callee(method, insn);
        if (resolved_callee == nullptr) {
          continue;
        }
        if (!is_definitely_virtual(resolved_callee) ||
            opcode::is_invoke_super(insn->opcode())) {
          // Not true virtual call
          if (resolved_callee->is_concrete()) {
            callsites.emplace_back(resolved_callee, code->iterator_to(mie));
          }
        } else {
          get_callsites_for_true_virtual_call(code, resolved_callee, env, mie,
                                              callsites);
        }
      }
    }
    return callsites;
  }

 protected:
  void get_callsites_for_true_virtual_call(IRCode* code,
                                           DexMethod* resolved_callee,
                                           const DexTypeEnvironment& env,
                                           MethodItemEntry& invoke,
                                           CallSites& callsites) const {
    auto* insn = invoke.insn;
    auto* callee_ref = insn->get_method();
    auto domain = env.get(insn->src(0));
    auto analysis_cls = domain.get_dex_cls();
    DexMethod* analysis_resolved_callee = nullptr;
    if (analysis_cls) {
      auto method_search = get_method_search(*analysis_cls, insn);
      analysis_resolved_callee =
          resolve_method(*analysis_cls, callee_ref->get_name(),
                         callee_ref->get_proto(), method_search);
      if (analysis_resolved_callee) {
        resolved_callee = analysis_resolved_callee;
      } else {
        // If the analysis type is too generic and we cannot resolve a concrete
        // callee based on that type, we fall back to the method reference at
        // the call site.
        TRACE(TYPE, 5, "Unresolved callee at %s for analysis cls %s",
              SHOW(insn), SHOW(*analysis_cls));
      }
    }

    // Add callees to callsites
    if (resolved_callee->is_concrete()) {
      callsites.emplace_back(resolved_callee, code->iterator_to(invoke));
    }
    always_assert(!opcode::is_invoke_super(insn->opcode()));
    const auto& overriding_methods =
        mog::get_overriding_methods(*m_method_override_graph, resolved_callee);
    for (auto overriding_method : overriding_methods) {
      callsites.emplace_back(overriding_method, code->iterator_to(invoke));
    }
  }

  std::shared_ptr<type_analyzer::global::GlobalTypeAnalyzer> m_gta;
};

} // namespace

void TypeAnalysisCallGraphGenerationPass::run_pass(DexStoresVector& stores,
                                                   ConfigFiles& config,
                                                   PassManager& mgr) {
  auto analysis = mgr.get_preserved_analysis<GlobalTypeAnalysisPass>();
  always_assert(analysis);
  auto gta = analysis->get_result();
  always_assert(gta);

  Scope scope = build_class_scope(stores);
  m_result = std::make_shared<call_graph::Graph>(
      TypeAnalysisBasedStrategy(scope, gta));
  always_assert(m_result);
  report_stats(*m_result, mgr);
}

static TypeAnalysisCallGraphGenerationPass s_pass;
<|endoftext|>