<commit_before>//===--- TerminalReaderWin.cpp - Input From Windows Console -----*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file defines the interface for reading from Window's cmd.exe console.
//
//  Axel Naumann <axel@cern.ch>, 2011-05-12
//===----------------------------------------------------------------------===//

#ifdef WIN32

#include "textinput/StreamReaderWin.h"

#include <io.h>
#include <stdio.h>
#include <Windows.h>

// MSVC 7.1 is missing these definitions:
#ifndef ENABLE_QUICK_EDIT_MODE
# define ENABLE_QUICK_EDIT_MODE 0x0040
#endif
#ifndef ENABLE_EXTENDED_FLAGS
# define ENABLE_EXTENDED_FLAGS 0x0080
#endif
#ifndef ENABLE_LINE_INPUT
# define ENABLE_LINE_INPUT 0x0002
#endif
#ifndef ENABLE_PROCESSED_INPUT
# define ENABLE_PROCESSED_INPUT 0x0001
#endif
#ifndef ENABLE_ECHO_INPUT
# define ENABLE_ECHO_INPUT 0x0004
#endif
#ifndef ENABLE_INSERT_MODE
# define ENABLE_INSERT_MODE 0x0020
#endif
// End MSVC 7.1 quirks

namespace textinput {
  StreamReaderWin::StreamReaderWin(): fHaveInputFocus(false), fIsConsole(true),
    fOldMode(0), fMyMode(0) {
    fIn = ::GetStdHandle(STD_INPUT_HANDLE);
    fIsConsole = ::GetConsoleMode(fIn, &fOldMode) != 0;
    fMyMode = fOldMode | ENABLE_QUICK_EDIT_MODE | ENABLE_EXTENDED_FLAGS;
    fMyMode = fOldMode & ~(ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT
      | ENABLE_ECHO_INPUT | ENABLE_INSERT_MODE);
  }

  StreamReaderWin::~StreamReaderWin() {}

  void
  StreamReaderWin::GrabInputFocus() {
    if (fHaveInputFocus) return;
    if (fIsConsole && !SetConsoleMode(fIn, fMyMode)) {
      fIsConsole = false;
    }
    fHaveInputFocus = true;
  }

  void
  StreamReaderWin::ReleaseInputFocus() {
    if (!fHaveInputFocus) return;
    if (fIsConsole && !SetConsoleMode(fIn, fOldMode)) {
      fIsConsole = false;
    }
    fHaveInputFocus = false;
  }

  bool
  StreamReaderWin::HavePendingInput() {
    DWORD ret = ::WaitForSingleObject(fIn, 0);
    if (ret == WAIT_FAILED) {
      HandleError("waiting for console input");
      // We don't know. Better block rather than veto input:
      return true;
    }
    return ret == WAIT_OBJECT_0;
  }

  bool
  StreamReaderWin::ReadInput(size_t& nRead, InputData& in) {
    DWORD NRead = 0;
    char C;
    if (fIsConsole) {
      INPUT_RECORD buf;
      if (!::ReadConsoleInput(fIn, &buf, 1, &NRead)) {
        HandleError("reading console input");
        return false;
      }

      switch (buf.EventType) {
      case KEY_EVENT:
      {
        if (!buf.Event.KeyEvent.bKeyDown) return false;

        WORD Key = buf.Event.KeyEvent.wVirtualKeyCode;
        if (buf.Event.KeyEvent.dwControlKeyState
          & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) {
            in.SetModifier(InputData::kModCtrl);
        }
        if ((Key >= 0x30 && Key <= 0x5A /*0-Z*/)
          || (Key >= VK_NUMPAD0 && Key <= VK_DIVIDE)
          || (Key >= VK_OEM_PLUS && Key <= VK_OEM_102)
          || Key == VK_SPACE) {
            C = buf.Event.KeyEvent.uChar.AsciiChar;
            if (buf.Event.KeyEvent.dwControlKeyState
              & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) {
               // C is already 1..
            }
        } else {
          switch (Key) {
            case VK_BACK:   in.SetExtended(InputData::kEIBackSpace); break;
            case VK_TAB:    in.SetExtended(InputData::kEITab); break;
            case VK_RETURN: in.SetExtended(InputData::kEIEnter); break;
            case VK_ESCAPE: in.SetExtended(InputData::kEIEsc); break;
            case VK_PRIOR:  in.SetExtended(InputData::kEIPgUp); break;
            case VK_NEXT:   in.SetExtended(InputData::kEIPgDown); break;
            case VK_END:    in.SetExtended(InputData::kEIEnd); break;
            case VK_HOME:   in.SetExtended(InputData::kEIHome); break;
            case VK_LEFT:   in.SetExtended(InputData::kEILeft); break;
            case VK_UP:     in.SetExtended(InputData::kEIUp); break;
            case VK_RIGHT:  in.SetExtended(InputData::kEIRight); break;
            case VK_DOWN:   in.SetExtended(InputData::kEIDown); break;
            case VK_INSERT: in.SetExtended(InputData::kEIIns); break;
            case VK_DELETE: in.SetExtended(InputData::kEIDel); break;
            case VK_F1:     in.SetExtended(InputData::kEIF1); break;
            case VK_F2:     in.SetExtended(InputData::kEIF2); break;
            case VK_F3:     in.SetExtended(InputData::kEIF3); break;
            case VK_F4:     in.SetExtended(InputData::kEIF4); break;
            case VK_F5:     in.SetExtended(InputData::kEIF5); break;
            case VK_F6:     in.SetExtended(InputData::kEIF6); break;
            case VK_F7:     in.SetExtended(InputData::kEIF7); break;
            case VK_F8:     in.SetExtended(InputData::kEIF8); break;
            case VK_F9:     in.SetExtended(InputData::kEIF9); break;
            case VK_F10:    in.SetExtended(InputData::kEIF10); break;
            case VK_F11:    in.SetExtended(InputData::kEIF11); break;
            case VK_F12:    in.SetExtended(InputData::kEIF12); break;
            default:        in.SetExtended(InputData::kEIUninitialized); return false;
          }
          return true;
        }
        break;
      }
      case WINDOW_BUFFER_SIZE_EVENT:
        in.SetExtended(InputData::kEIResizeEvent);
        ++nRead;
        return true;
        break;
      default:
        return false;
      }
    } else {
      if (!::ReadFile(fIn, &C, 1, &NRead, NULL)) {
        HandleError("reading file input");
        return false;
      }
    }
    HandleKeyEvent(C, in);
    ++nRead;
    return true;
  }

  void
  StreamReaderWin::HandleError(const char* Where) const {
    DWORD Err = GetLastError();
    LPVOID MsgBuf = 0;
    FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
      FORMAT_MESSAGE_IGNORE_INSERTS, NULL, Err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
      (LPTSTR) &MsgBuf, 0, NULL);

    printf("Error %d in textinput::StreamReaderWin %s: %s\n", Err, Where, MsgBuf);
    LocalFree(MsgBuf);
  }

  void
  StreamReaderWin::HandleKeyEvent(unsigned char C, InputData& in) {
    if (isprint(C)) {
      in.SetRaw(C);
    } else if (C < 32) {
      in.SetRaw(C);
      in.SetModifier(InputData::kModCtrl);
    } else {
      // woohoo, what's that?!
      in.SetRaw(C);
    }
  }
}
#endif // WIN32
<commit_msg>Semicolon and colon are fine characters, too: accept them as character input.<commit_after>//===--- TerminalReaderWin.cpp - Input From Windows Console -----*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file defines the interface for reading from Window's cmd.exe console.
//
//  Axel Naumann <axel@cern.ch>, 2011-05-12
//===----------------------------------------------------------------------===//

#ifdef WIN32

#include "textinput/StreamReaderWin.h"

#include <io.h>
#include <stdio.h>
#include <Windows.h>

// MSVC 7.1 is missing these definitions:
#ifndef ENABLE_QUICK_EDIT_MODE
# define ENABLE_QUICK_EDIT_MODE 0x0040
#endif
#ifndef ENABLE_EXTENDED_FLAGS
# define ENABLE_EXTENDED_FLAGS 0x0080
#endif
#ifndef ENABLE_LINE_INPUT
# define ENABLE_LINE_INPUT 0x0002
#endif
#ifndef ENABLE_PROCESSED_INPUT
# define ENABLE_PROCESSED_INPUT 0x0001
#endif
#ifndef ENABLE_ECHO_INPUT
# define ENABLE_ECHO_INPUT 0x0004
#endif
#ifndef ENABLE_INSERT_MODE
# define ENABLE_INSERT_MODE 0x0020
#endif
// End MSVC 7.1 quirks

namespace textinput {
  StreamReaderWin::StreamReaderWin(): fHaveInputFocus(false), fIsConsole(true),
    fOldMode(0), fMyMode(0) {
    fIn = ::GetStdHandle(STD_INPUT_HANDLE);
    fIsConsole = ::GetConsoleMode(fIn, &fOldMode) != 0;
    fMyMode = fOldMode | ENABLE_QUICK_EDIT_MODE | ENABLE_EXTENDED_FLAGS;
    fMyMode = fOldMode & ~(ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT
      | ENABLE_ECHO_INPUT | ENABLE_INSERT_MODE);
  }

  StreamReaderWin::~StreamReaderWin() {}

  void
  StreamReaderWin::GrabInputFocus() {
    if (fHaveInputFocus) return;
    if (fIsConsole && !SetConsoleMode(fIn, fMyMode)) {
      fIsConsole = false;
    }
    fHaveInputFocus = true;
  }

  void
  StreamReaderWin::ReleaseInputFocus() {
    if (!fHaveInputFocus) return;
    if (fIsConsole && !SetConsoleMode(fIn, fOldMode)) {
      fIsConsole = false;
    }
    fHaveInputFocus = false;
  }

  bool
  StreamReaderWin::HavePendingInput() {
    DWORD ret = ::WaitForSingleObject(fIn, 0);
    if (ret == WAIT_FAILED) {
      HandleError("waiting for console input");
      // We don't know. Better block rather than veto input:
      return true;
    }
    return ret == WAIT_OBJECT_0;
  }

  bool
  StreamReaderWin::ReadInput(size_t& nRead, InputData& in) {
    DWORD NRead = 0;
    char C;
    if (fIsConsole) {
      INPUT_RECORD buf;
      if (!::ReadConsoleInput(fIn, &buf, 1, &NRead)) {
        HandleError("reading console input");
        return false;
      }

      switch (buf.EventType) {
      case KEY_EVENT:
      {
        if (!buf.Event.KeyEvent.bKeyDown) return false;

        WORD Key = buf.Event.KeyEvent.wVirtualKeyCode;
        if (buf.Event.KeyEvent.dwControlKeyState
          & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) {
            in.SetModifier(InputData::kModCtrl);
        }
        if ((Key >= 0x30 && Key <= 0x5A /*0-Z*/)
          || (Key >= VK_NUMPAD0 && Key <= VK_DIVIDE)
          || (Key >= VK_OEM_1 && Key <= VK_OEM_102)
          || Key == VK_SPACE) {
            C = buf.Event.KeyEvent.uChar.AsciiChar;
            if (buf.Event.KeyEvent.dwControlKeyState
              & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) {
               // C is already 1..
            }
        } else {
          switch (Key) {
            case VK_BACK:   in.SetExtended(InputData::kEIBackSpace); break;
            case VK_TAB:    in.SetExtended(InputData::kEITab); break;
            case VK_RETURN: in.SetExtended(InputData::kEIEnter); break;
            case VK_ESCAPE: in.SetExtended(InputData::kEIEsc); break;
            case VK_PRIOR:  in.SetExtended(InputData::kEIPgUp); break;
            case VK_NEXT:   in.SetExtended(InputData::kEIPgDown); break;
            case VK_END:    in.SetExtended(InputData::kEIEnd); break;
            case VK_HOME:   in.SetExtended(InputData::kEIHome); break;
            case VK_LEFT:   in.SetExtended(InputData::kEILeft); break;
            case VK_UP:     in.SetExtended(InputData::kEIUp); break;
            case VK_RIGHT:  in.SetExtended(InputData::kEIRight); break;
            case VK_DOWN:   in.SetExtended(InputData::kEIDown); break;
            case VK_INSERT: in.SetExtended(InputData::kEIIns); break;
            case VK_DELETE: in.SetExtended(InputData::kEIDel); break;
            case VK_F1:     in.SetExtended(InputData::kEIF1); break;
            case VK_F2:     in.SetExtended(InputData::kEIF2); break;
            case VK_F3:     in.SetExtended(InputData::kEIF3); break;
            case VK_F4:     in.SetExtended(InputData::kEIF4); break;
            case VK_F5:     in.SetExtended(InputData::kEIF5); break;
            case VK_F6:     in.SetExtended(InputData::kEIF6); break;
            case VK_F7:     in.SetExtended(InputData::kEIF7); break;
            case VK_F8:     in.SetExtended(InputData::kEIF8); break;
            case VK_F9:     in.SetExtended(InputData::kEIF9); break;
            case VK_F10:    in.SetExtended(InputData::kEIF10); break;
            case VK_F11:    in.SetExtended(InputData::kEIF11); break;
            case VK_F12:    in.SetExtended(InputData::kEIF12); break;
            default:        in.SetExtended(InputData::kEIUninitialized); return false;
          }
          return true;
        }
        break;
      }
      case WINDOW_BUFFER_SIZE_EVENT:
        in.SetExtended(InputData::kEIResizeEvent);
        ++nRead;
        return true;
        break;
      default:
        return false;
      }
    } else {
      if (!::ReadFile(fIn, &C, 1, &NRead, NULL)) {
        HandleError("reading file input");
        return false;
      }
    }
    HandleKeyEvent(C, in);
    ++nRead;
    return true;
  }

  void
  StreamReaderWin::HandleError(const char* Where) const {
    DWORD Err = GetLastError();
    LPVOID MsgBuf = 0;
    FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
      FORMAT_MESSAGE_IGNORE_INSERTS, NULL, Err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
      (LPTSTR) &MsgBuf, 0, NULL);

    printf("Error %d in textinput::StreamReaderWin %s: %s\n", Err, Where, MsgBuf);
    LocalFree(MsgBuf);
  }

  void
  StreamReaderWin::HandleKeyEvent(unsigned char C, InputData& in) {
    if (isprint(C)) {
      in.SetRaw(C);
    } else if (C < 32) {
      in.SetRaw(C);
      in.SetModifier(InputData::kModCtrl);
    } else {
      // woohoo, what's that?!
      in.SetRaw(C);
    }
  }
}
#endif // WIN32
<|endoftext|>


<commit_before>/**
 * Splits a string with a given delimiter
 * NOTE: The delimiter should also be a string
 * Author : Deekshith Allamaneni
 * Website: www.deekshith.in
 */
#include <sstream>
#include <iostream>
#include <vector>
using namespace std;
std::vector<std::string> splitString(std::string stringToSplit, std::string delimiter){
    //std::string stringToSplit="orange,apple,mango,tomato,banana,pineapple";
    //std::string delimiter = ",";
    size_t pos = 0;
    size_t prev_pos = 0;
    std::vector<std::string> split_vector;
    bool endLoop=false;
    int i=5;
    do{
        //std::cout<<"("<<pos<<" ,";
        pos = stringToSplit.find(delimiter,prev_pos+delimiter.length());
        //std::cout<<pos<<") - ";
        if (pos==std::string::npos){
            split_vector.push_back(stringToSplit.substr(prev_pos+delimiter.length()));
            //std::cout<<stringToSplit.substr(prev_pos+delimiter.length())<<std::endl;
            break;
        }
        std::string token;
        std::string currentSplit;
        if (prev_pos==0)
            token=stringToSplit.substr( prev_pos, pos );
        else
            token=stringToSplit.substr(prev_pos+delimiter.length(),pos-(prev_pos+delimiter.length()) );
        stringstream convert(token);
        if ( !(convert >> currentSplit) )
            endLoop=true;
        split_vector.push_back(currentSplit);
        prev_pos = pos;
        //std::cout<<currentSplit<<std::endl;
    }while(!endLoop && pos!=std::string::npos);

    return split_vector;
}

int main(){
    std::vector<std::string> split_vector;
    split_vector= splitString("orange,apple,mango,tomato,banana,pineapple",",");
    for (std::vector<std::string>::iterator it = split_vector.begin(); it != split_vector.end(); ++it)
        std::cout << *it << std::endl;
    return 0;
}<commit_msg>Updated function to Split strings with any delimiter<commit_after>/**
 * Splits a string with a given delimiter
 * NOTE: The delimiter should also be a string
 * Author : Deekshith Allamaneni
 * Website: www.deekshith.in
 */
#include <sstream>
#include <iostream>
#include <vector>
//using namespace std;
std::vector<std::string> splitString(std::string stringToSplit, std::string delimiter){
    //std::string stringToSplit="orange,apple,mango,tomato,banana,pineapple";
    //std::string delimiter = ",";
    size_t pos = 0;
    size_t prev_pos = 0;
    std::vector<std::string> split_vector;
    bool endLoop=false;
    int i=5;
    do{
        //std::cout<<"("<<pos<<" ,";
        pos = stringToSplit.find(delimiter,prev_pos+delimiter.length());
        //std::cout<<pos<<") - ";
        if (pos==std::string::npos){
            split_vector.push_back(stringToSplit.substr(prev_pos+delimiter.length()));
            //std::cout<<stringToSplit.substr(prev_pos+delimiter.length())<<std::endl;
            break;
        }
        std::string token;
        std::string currentSplit;
        if (prev_pos==0)
            token=stringToSplit.substr( prev_pos, pos );
        else
            token=stringToSplit.substr(prev_pos+delimiter.length(),pos-(prev_pos+delimiter.length()) );
        std::stringstream convert(token);
        if ( !(convert >> currentSplit) )
            endLoop=true;
        split_vector.push_back(currentSplit);
        prev_pos = pos;
        //std::cout<<currentSplit<<std::endl;
    }while(!endLoop && pos!=std::string::npos);

    return split_vector;
}

int main(){
    std::vector<std::string> split_vector;
    split_vector= splitString("orange,apple,mango,tomato,banana,pineapple",",");
    for (std::vector<std::string>::iterator it = split_vector.begin(); it != split_vector.end(); ++it)
        std::cout << *it << std::endl;
    return 0;
}<|endoftext|>


<commit_before>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ash/system/ime/tray_ime.h"

#include <vector>

#include "ash/shell.h"
#include "ash/system/tray/system_tray.h"
#include "ash/system/tray/system_tray_delegate.h"
#include "ash/system/tray/tray_constants.h"
#include "ash/system/tray/tray_item_more.h"
#include "ash/system/tray/tray_views.h"
#include "base/logging.h"
#include "base/utf_string_conversions.h"
#include "grit/ash_strings.h"
#include "grit/ui_resources.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/font.h"
#include "ui/gfx/image/image.h"
#include "ui/views/controls/label.h"
#include "ui/views/layout/box_layout.h"

namespace ash {
namespace internal {

namespace tray {

class IMEDefaultView : public TrayItemMore {
 public:
  explicit IMEDefaultView(SystemTrayItem* owner)
      : TrayItemMore(owner) {
    ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();

    SetImage(bundle.GetImageNamed(
        IDR_AURA_UBER_TRAY_IME).ToSkBitmap());

    IMEInfo info;
    Shell::GetInstance()->tray_delegate()->GetCurrentIME(&info);
    UpdateLabel(info);
  }

  virtual ~IMEDefaultView() {}

  void UpdateLabel(const IMEInfo& info) {
    SetLabel(info.name);
    SetAccessibleName(info.name);
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(IMEDefaultView);
};

class IMEDetailedView : public views::View,
                        public ViewClickListener {
 public:
  IMEDetailedView(SystemTrayItem* owner, user::LoginStatus login)
      : login_(login),
        header_(NULL) {
    SetLayoutManager(new views::BoxLayout(
        views::BoxLayout::kVertical, 0, 0, 0));
    set_background(views::Background::CreateSolidBackground(kBackgroundColor));
    SystemTrayDelegate* delegate = Shell::GetInstance()->tray_delegate();
    IMEInfoList list;
    delegate->GetAvailableIMEList(&list);
    IMEPropertyInfoList property_list;
    delegate->GetCurrentIMEProperties(&property_list);
    Update(list, property_list);
  }

  virtual ~IMEDetailedView() {}

  void Update(const IMEInfoList& list,
              const IMEPropertyInfoList& property_list) {
    RemoveAllChildViews(true);

    header_ = NULL;

    AppendHeaderEntry();
    AppendIMEList(list);
    if (!property_list.empty())
      AppendIMEProperties(property_list);
    if (login_ != user::LOGGED_IN_NONE && login_ != user::LOGGED_IN_LOCKED)
      AppendSettings();

    Layout();
    SchedulePaint();
  }

 private:
  void AppendHeaderEntry() {
    header_ = CreateDetailedHeaderEntry(IDS_ASH_STATUS_TRAY_IME, this);
    AddChildView(header_);
  }

  void AppendIMEList(const IMEInfoList& list) {
    ime_map_.clear();
    views::View* imes = new views::View;
    imes->SetLayoutManager(new views::BoxLayout(
        views::BoxLayout::kVertical, 0, 0, 1));
    for (size_t i = 0; i < list.size(); i++) {
      HoverHighlightView* container = new HoverHighlightView(this);
      container->set_fixed_height(kTrayPopupItemHeight);
      container->AddLabel(list[i].name,
          list[i].selected ? gfx::Font::BOLD : gfx::Font::NORMAL);
      imes->AddChildView(container);
      ime_map_[container] = list[i].id;
    }
    imes->set_border(views::Border::CreateSolidSidedBorder(1, 0, 1, 0,
        kBorderLightColor));
    AddChildView(imes);
  }

  void AppendIMEProperties(const IMEPropertyInfoList& property_list) {
    property_map_.clear();
    views::View* properties = new views::View;
    properties->SetLayoutManager(new views::BoxLayout(
        views::BoxLayout::kVertical, 0, 0, 1));
    for (size_t i = 0; i < property_list.size(); i++) {
      HoverHighlightView* container = new HoverHighlightView(this);
      container->set_fixed_height(kTrayPopupItemHeight);
      container->AddLabel(
          property_list[i].name,
          property_list[i].selected ? gfx::Font::BOLD : gfx::Font::NORMAL);
      properties->AddChildView(container);
      property_map_[container] = property_list[i].key;
    }
    properties->set_border(views::Border::CreateSolidSidedBorder(
        0, 0, 1, 0, kBorderLightColor));
    AddChildView(properties);
  }

  void AppendSettings() {
    HoverHighlightView* container = new HoverHighlightView(this);
    container->set_fixed_height(kTrayPopupItemHeight);
    container->AddLabel(ui::ResourceBundle::GetSharedInstance().
        GetLocalizedString(IDS_ASH_STATUS_TRAY_IME_SETTINGS),
        gfx::Font::NORMAL);
    AddChildView(container);
    settings_ = container;
  }

  // Overridden from ViewClickListener.
  virtual void ClickedOn(views::View* sender) OVERRIDE {
    SystemTrayDelegate* delegate = Shell::GetInstance()->tray_delegate();
    if (sender == header_) {
      Shell::GetInstance()->tray()->ShowDefaultView();
    } else if (sender == settings_) {
      delegate->ShowIMESettings();
    } else {
      std::map<views::View*, std::string>::const_iterator ime_find;
      ime_find = ime_map_.find(sender);
      if (ime_find != ime_map_.end()) {
        std::string ime_id = ime_find->second;
        delegate->SwitchIME(ime_id);
        GetWidget()->Close();
      } else {
        std::map<views::View*, std::string>::const_iterator prop_find;
        prop_find = property_map_.find(sender);
        if (prop_find != property_map_.end()) {
          const std::string key = prop_find->second;
          delegate->ActivateIMEProperty(key);
          GetWidget()->Close();
        }
      }
    }
  }

  user::LoginStatus login_;

  std::map<views::View*, std::string> ime_map_;
  std::map<views::View*, std::string> property_map_;
  views::View* header_;
  views::View* settings_;

  DISALLOW_COPY_AND_ASSIGN(IMEDetailedView);
};

}  // namespace tray

TrayIME::TrayIME() {
}

TrayIME::~TrayIME() {
}

void TrayIME::UpdateTrayLabel(const IMEInfo& current, size_t count) {
  tray_label_->SetText(current.short_name);
  tray_label_->SetVisible(count > 1);
}

views::View* TrayIME::CreateTrayView(user::LoginStatus status) {
  tray_label_.reset(new views::Label);
  SetupLabelForTray(tray_label_.get());
  tray_label_->set_border(
      views::Border::CreateEmptyBorder(0, 2, 0, 2));
  return tray_label_.get();
}

views::View* TrayIME::CreateDefaultView(user::LoginStatus status) {
  default_.reset(new tray::IMEDefaultView(this));
  return default_.get();
}

views::View* TrayIME::CreateDetailedView(user::LoginStatus status) {
  detailed_.reset(new tray::IMEDetailedView(this, status));
  return detailed_.get();
}

void TrayIME::DestroyTrayView() {
  tray_label_.reset();
}

void TrayIME::DestroyDefaultView() {
  default_.reset();
}

void TrayIME::DestroyDetailedView() {
  detailed_.reset();
}

void TrayIME::OnIMERefresh() {
  SystemTrayDelegate* delegate = Shell::GetInstance()->tray_delegate();
  IMEInfoList list;
  IMEInfo current;
  IMEPropertyInfoList property_list;
  delegate->GetCurrentIME(&current);
  delegate->GetAvailableIMEList(&list);
  delegate->GetCurrentIMEProperties(&property_list);

  UpdateTrayLabel(current, list.size());

  if (default_.get())
    default_->UpdateLabel(current);
  if (detailed_.get())
    detailed_->Update(list, property_list);
}

}  // namespace internal
}  // namespace ash
<commit_msg>Popup detailed view for IME switch when the tray icon is not visible.<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ash/system/ime/tray_ime.h"

#include <vector>

#include "ash/shell.h"
#include "ash/system/tray/system_tray.h"
#include "ash/system/tray/system_tray_delegate.h"
#include "ash/system/tray/tray_constants.h"
#include "ash/system/tray/tray_item_more.h"
#include "ash/system/tray/tray_views.h"
#include "ash/wm/shelf_layout_manager.h"
#include "base/logging.h"
#include "base/utf_string_conversions.h"
#include "grit/ash_strings.h"
#include "grit/ui_resources.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/font.h"
#include "ui/gfx/image/image.h"
#include "ui/views/controls/label.h"
#include "ui/views/layout/box_layout.h"

namespace ash {
namespace internal {

namespace tray {

class IMEDefaultView : public TrayItemMore {
 public:
  explicit IMEDefaultView(SystemTrayItem* owner)
      : TrayItemMore(owner) {
    ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();

    SetImage(bundle.GetImageNamed(
        IDR_AURA_UBER_TRAY_IME).ToSkBitmap());

    IMEInfo info;
    Shell::GetInstance()->tray_delegate()->GetCurrentIME(&info);
    UpdateLabel(info);
  }

  virtual ~IMEDefaultView() {}

  void UpdateLabel(const IMEInfo& info) {
    SetLabel(info.name);
    SetAccessibleName(info.name);
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(IMEDefaultView);
};

class IMEDetailedView : public views::View,
                        public ViewClickListener {
 public:
  IMEDetailedView(SystemTrayItem* owner, user::LoginStatus login)
      : login_(login),
        header_(NULL) {
    SetLayoutManager(new views::BoxLayout(
        views::BoxLayout::kVertical, 0, 0, 0));
    set_background(views::Background::CreateSolidBackground(kBackgroundColor));
    SystemTrayDelegate* delegate = Shell::GetInstance()->tray_delegate();
    IMEInfoList list;
    delegate->GetAvailableIMEList(&list);
    IMEPropertyInfoList property_list;
    delegate->GetCurrentIMEProperties(&property_list);
    Update(list, property_list);
  }

  virtual ~IMEDetailedView() {}

  void Update(const IMEInfoList& list,
              const IMEPropertyInfoList& property_list) {
    RemoveAllChildViews(true);

    header_ = NULL;

    AppendHeaderEntry();
    AppendIMEList(list);
    if (!property_list.empty())
      AppendIMEProperties(property_list);
    if (login_ != user::LOGGED_IN_NONE && login_ != user::LOGGED_IN_LOCKED)
      AppendSettings();

    Layout();
    SchedulePaint();
  }

 private:
  void AppendHeaderEntry() {
    header_ = CreateDetailedHeaderEntry(IDS_ASH_STATUS_TRAY_IME, this);
    AddChildView(header_);
  }

  void AppendIMEList(const IMEInfoList& list) {
    ime_map_.clear();
    views::View* imes = new views::View;
    imes->SetLayoutManager(new views::BoxLayout(
        views::BoxLayout::kVertical, 0, 0, 1));
    for (size_t i = 0; i < list.size(); i++) {
      HoverHighlightView* container = new HoverHighlightView(this);
      container->set_fixed_height(kTrayPopupItemHeight);
      container->AddLabel(list[i].name,
          list[i].selected ? gfx::Font::BOLD : gfx::Font::NORMAL);
      imes->AddChildView(container);
      ime_map_[container] = list[i].id;
    }
    imes->set_border(views::Border::CreateSolidSidedBorder(1, 0, 1, 0,
        kBorderLightColor));
    AddChildView(imes);
  }

  void AppendIMEProperties(const IMEPropertyInfoList& property_list) {
    property_map_.clear();
    views::View* properties = new views::View;
    properties->SetLayoutManager(new views::BoxLayout(
        views::BoxLayout::kVertical, 0, 0, 1));
    for (size_t i = 0; i < property_list.size(); i++) {
      HoverHighlightView* container = new HoverHighlightView(this);
      container->set_fixed_height(kTrayPopupItemHeight);
      container->AddLabel(
          property_list[i].name,
          property_list[i].selected ? gfx::Font::BOLD : gfx::Font::NORMAL);
      properties->AddChildView(container);
      property_map_[container] = property_list[i].key;
    }
    properties->set_border(views::Border::CreateSolidSidedBorder(
        0, 0, 1, 0, kBorderLightColor));
    AddChildView(properties);
  }

  void AppendSettings() {
    HoverHighlightView* container = new HoverHighlightView(this);
    container->set_fixed_height(kTrayPopupItemHeight);
    container->AddLabel(ui::ResourceBundle::GetSharedInstance().
        GetLocalizedString(IDS_ASH_STATUS_TRAY_IME_SETTINGS),
        gfx::Font::NORMAL);
    AddChildView(container);
    settings_ = container;
  }

  // Overridden from ViewClickListener.
  virtual void ClickedOn(views::View* sender) OVERRIDE {
    SystemTrayDelegate* delegate = Shell::GetInstance()->tray_delegate();
    if (sender == header_) {
      Shell::GetInstance()->tray()->ShowDefaultView();
    } else if (sender == settings_) {
      delegate->ShowIMESettings();
    } else {
      std::map<views::View*, std::string>::const_iterator ime_find;
      ime_find = ime_map_.find(sender);
      if (ime_find != ime_map_.end()) {
        std::string ime_id = ime_find->second;
        delegate->SwitchIME(ime_id);
        GetWidget()->Close();
      } else {
        std::map<views::View*, std::string>::const_iterator prop_find;
        prop_find = property_map_.find(sender);
        if (prop_find != property_map_.end()) {
          const std::string key = prop_find->second;
          delegate->ActivateIMEProperty(key);
          GetWidget()->Close();
        }
      }
    }
  }

  user::LoginStatus login_;

  std::map<views::View*, std::string> ime_map_;
  std::map<views::View*, std::string> property_map_;
  views::View* header_;
  views::View* settings_;

  DISALLOW_COPY_AND_ASSIGN(IMEDetailedView);
};

}  // namespace tray

TrayIME::TrayIME() {
}

TrayIME::~TrayIME() {
}

void TrayIME::UpdateTrayLabel(const IMEInfo& current, size_t count) {
  tray_label_->SetText(current.short_name);
  tray_label_->SetVisible(count > 1);
}

views::View* TrayIME::CreateTrayView(user::LoginStatus status) {
  tray_label_.reset(new views::Label);
  SetupLabelForTray(tray_label_.get());
  tray_label_->set_border(
      views::Border::CreateEmptyBorder(0, 2, 0, 2));
  return tray_label_.get();
}

views::View* TrayIME::CreateDefaultView(user::LoginStatus status) {
  default_.reset(new tray::IMEDefaultView(this));
  return default_.get();
}

views::View* TrayIME::CreateDetailedView(user::LoginStatus status) {
  detailed_.reset(new tray::IMEDetailedView(this, status));
  return detailed_.get();
}

void TrayIME::DestroyTrayView() {
  tray_label_.reset();
}

void TrayIME::DestroyDefaultView() {
  default_.reset();
}

void TrayIME::DestroyDetailedView() {
  detailed_.reset();
}

void TrayIME::OnIMERefresh() {
  SystemTrayDelegate* delegate = Shell::GetInstance()->tray_delegate();
  IMEInfoList list;
  IMEInfo current;
  IMEPropertyInfoList property_list;
  delegate->GetCurrentIME(&current);
  delegate->GetAvailableIMEList(&list);
  delegate->GetCurrentIMEProperties(&property_list);

  UpdateTrayLabel(current, list.size());

  if (default_.get())
    default_->UpdateLabel(current);
  if (detailed_.get())
    detailed_->Update(list, property_list);
  else if (!Shell::GetInstance()->shelf()->IsVisible())
    PopupDetailedView(kTrayPopupAutoCloseDelayInSeconds, false);
}

}  // namespace internal
}  // namespace ash
<|endoftext|>


<commit_before>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ash/system/ime/tray_ime.h"

#include <vector>

#include "ash/shell.h"
#include "ash/system/tray/system_tray.h"
#include "ash/system/tray/system_tray_delegate.h"
#include "ash/system/tray/tray_constants.h"
#include "ash/system/tray/tray_item_more.h"
#include "ash/system/tray/tray_views.h"
#include "base/logging.h"
#include "base/utf_string_conversions.h"
#include "grit/ash_strings.h"
#include "grit/ui_resources.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/font.h"
#include "ui/gfx/image/image.h"
#include "ui/views/controls/label.h"
#include "ui/views/layout/box_layout.h"

namespace ash {
namespace internal {

namespace tray {

class IMEDefaultView : public TrayItemMore {
 public:
  explicit IMEDefaultView(SystemTrayItem* owner)
      : TrayItemMore(owner) {
    ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();

    SetImage(bundle.GetImageNamed(
        IDR_AURA_UBER_TRAY_IME).ToSkBitmap());

    IMEInfo info;
    Shell::GetInstance()->tray_delegate()->GetCurrentIME(&info);
    UpdateLabel(info);
  }

  virtual ~IMEDefaultView() {}

  void UpdateLabel(const IMEInfo& info) {
    SetLabel(info.name);
    SetAccessibleName(info.name);
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(IMEDefaultView);
};

class IMEDetailedView : public views::View,
                        public ViewClickListener {
 public:
  IMEDetailedView(SystemTrayItem* owner, user::LoginStatus login)
      : login_(login),
        header_(NULL) {
    SetLayoutManager(new views::BoxLayout(
        views::BoxLayout::kVertical, 0, 0, 0));
    set_background(views::Background::CreateSolidBackground(kBackgroundColor));
    SystemTrayDelegate* delegate = Shell::GetInstance()->tray_delegate();
    IMEInfoList list;
    delegate->GetAvailableIMEList(&list);
    IMEPropertyInfoList property_list;
    delegate->GetCurrentIMEProperties(&property_list);
    Update(list, property_list);
  }

  virtual ~IMEDetailedView() {}

  void Update(const IMEInfoList& list,
              const IMEPropertyInfoList& property_list) {
    RemoveAllChildViews(true);

    header_ = NULL;

    AppendHeaderEntry();
    AppendIMEList(list);
    if (!property_list.empty())
      AppendIMEProperties(property_list);
    if (login_ != user::LOGGED_IN_NONE && login_ != user::LOGGED_IN_LOCKED)
      AppendSettings();

    Layout();
    SchedulePaint();
  }

 private:
  void AppendHeaderEntry() {
    header_ = CreateDetailedHeaderEntry(IDS_ASH_STATUS_TRAY_IME, this);
    AddChildView(header_);
  }

  void AppendIMEList(const IMEInfoList& list) {
    ime_map_.clear();
    views::View* imes = new views::View;
    imes->SetLayoutManager(new views::BoxLayout(
        views::BoxLayout::kVertical, 0, 0, 1));
    for (size_t i = 0; i < list.size(); i++) {
      HoverHighlightView* container = new HoverHighlightView(this);
      container->set_fixed_height(kTrayPopupItemHeight);
      container->AddLabel(list[i].name,
          list[i].selected ? gfx::Font::BOLD : gfx::Font::NORMAL);
      imes->AddChildView(container);
      ime_map_[container] = list[i].id;
    }
    imes->set_border(views::Border::CreateSolidSidedBorder(1, 0, 1, 0,
        kBorderLightColor));
    AddChildView(imes);
  }

  void AppendIMEProperties(const IMEPropertyInfoList& property_list) {
    property_map_.clear();
    views::View* properties = new views::View;
    properties->SetLayoutManager(new views::BoxLayout(
        views::BoxLayout::kVertical, 0, 0, 1));
    for (size_t i = 0; i < property_list.size(); i++) {
      HoverHighlightView* container = new HoverHighlightView(this);
      container->set_fixed_height(kTrayPopupItemHeight);
      container->AddLabel(
          property_list[i].name,
          property_list[i].selected ? gfx::Font::BOLD : gfx::Font::NORMAL);
      properties->AddChildView(container);
      property_map_[container] = property_list[i].key;
    }
    properties->set_border(views::Border::CreateSolidSidedBorder(
        0, 0, 1, 0, kBorderLightColor));
    AddChildView(properties);
  }

  void AppendSettings() {
    HoverHighlightView* container = new HoverHighlightView(this);
    container->set_fixed_height(kTrayPopupItemHeight);
    container->AddLabel(ui::ResourceBundle::GetSharedInstance().
        GetLocalizedString(IDS_ASH_STATUS_TRAY_IME_SETTINGS),
        gfx::Font::NORMAL);
    AddChildView(container);
    settings_ = container;
  }

  // Overridden from ViewClickListener.
  virtual void ClickedOn(views::View* sender) OVERRIDE {
    SystemTrayDelegate* delegate = Shell::GetInstance()->tray_delegate();
    if (sender == header_) {
      Shell::GetInstance()->tray()->ShowDefaultView();
    } else if (sender == settings_) {
      delegate->ShowIMESettings();
    } else {
      std::map<views::View*, std::string>::const_iterator ime_find;
      ime_find = ime_map_.find(sender);
      if (ime_find != ime_map_.end()) {
        std::string ime_id = ime_find->second;
        delegate->SwitchIME(ime_id);
        GetWidget()->Close();
      } else {
        std::map<views::View*, std::string>::const_iterator prop_find;
        prop_find = property_map_.find(sender);
        if (prop_find != property_map_.end()) {
          const std::string key = prop_find->second;
          delegate->ActivateIMEProperty(key);
          GetWidget()->Close();
        }
      }
    }
  }

  user::LoginStatus login_;

  std::map<views::View*, std::string> ime_map_;
  std::map<views::View*, std::string> property_map_;
  views::View* header_;
  views::View* settings_;

  DISALLOW_COPY_AND_ASSIGN(IMEDetailedView);
};

}  // namespace tray

TrayIME::TrayIME() {
}

TrayIME::~TrayIME() {
}

void TrayIME::UpdateTrayLabel(const IMEInfo& current, size_t count) {
  tray_label_->SetText(current.short_name);
  tray_label_->SetVisible(count > 1);
}

views::View* TrayIME::CreateTrayView(user::LoginStatus status) {
  tray_label_.reset(new views::Label);
  SetupLabelForTray(tray_label_.get());
  tray_label_->set_border(
      views::Border::CreateEmptyBorder(0, 2, 0, 2));
  return tray_label_.get();
}

views::View* TrayIME::CreateDefaultView(user::LoginStatus status) {
  default_.reset(new tray::IMEDefaultView(this));
  return default_.get();
}

views::View* TrayIME::CreateDetailedView(user::LoginStatus status) {
  detailed_.reset(new tray::IMEDetailedView(this, status));
  return detailed_.get();
}

void TrayIME::DestroyTrayView() {
  tray_label_.reset();
}

void TrayIME::DestroyDefaultView() {
  default_.reset();
}

void TrayIME::DestroyDetailedView() {
  detailed_.reset();
}

void TrayIME::OnIMERefresh() {
  SystemTrayDelegate* delegate = Shell::GetInstance()->tray_delegate();
  IMEInfoList list;
  IMEInfo current;
  IMEPropertyInfoList property_list;
  delegate->GetCurrentIME(&current);
  delegate->GetAvailableIMEList(&list);
  delegate->GetCurrentIMEProperties(&property_list);

  UpdateTrayLabel(current, list.size());

  if (default_.get())
    default_->UpdateLabel(current);
  if (detailed_.get())
    detailed_->Update(list, property_list);
}

}  // namespace internal
}  // namespace ash
<commit_msg>Do not display keyboard tray if there is only 1 language input method.<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ash/system/ime/tray_ime.h"

#include <vector>

#include "ash/shell.h"
#include "ash/system/tray/system_tray.h"
#include "ash/system/tray/system_tray_delegate.h"
#include "ash/system/tray/tray_constants.h"
#include "ash/system/tray/tray_item_more.h"
#include "ash/system/tray/tray_views.h"
#include "base/logging.h"
#include "base/utf_string_conversions.h"
#include "grit/ash_strings.h"
#include "grit/ui_resources.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/font.h"
#include "ui/gfx/image/image.h"
#include "ui/views/controls/label.h"
#include "ui/views/layout/box_layout.h"

namespace ash {
namespace internal {

namespace tray {

class IMEDefaultView : public TrayItemMore {
 public:
  explicit IMEDefaultView(SystemTrayItem* owner)
      : TrayItemMore(owner) {
    ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();

    SetImage(bundle.GetImageNamed(
        IDR_AURA_UBER_TRAY_IME).ToSkBitmap());

    IMEInfo info;
    Shell::GetInstance()->tray_delegate()->GetCurrentIME(&info);
    UpdateLabel(info);
  }

  virtual ~IMEDefaultView() {}

  void UpdateLabel(const IMEInfo& info) {
    SetLabel(info.name);
    SetAccessibleName(info.name);
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(IMEDefaultView);
};

class IMEDetailedView : public views::View,
                        public ViewClickListener {
 public:
  IMEDetailedView(SystemTrayItem* owner, user::LoginStatus login)
      : login_(login),
        header_(NULL) {
    SetLayoutManager(new views::BoxLayout(
        views::BoxLayout::kVertical, 0, 0, 0));
    set_background(views::Background::CreateSolidBackground(kBackgroundColor));
    SystemTrayDelegate* delegate = Shell::GetInstance()->tray_delegate();
    IMEInfoList list;
    delegate->GetAvailableIMEList(&list);
    IMEPropertyInfoList property_list;
    delegate->GetCurrentIMEProperties(&property_list);
    Update(list, property_list);
  }

  virtual ~IMEDetailedView() {}

  void Update(const IMEInfoList& list,
              const IMEPropertyInfoList& property_list) {
    RemoveAllChildViews(true);

    header_ = NULL;

    AppendHeaderEntry();
    AppendIMEList(list);
    if (!property_list.empty())
      AppendIMEProperties(property_list);
    if (login_ != user::LOGGED_IN_NONE && login_ != user::LOGGED_IN_LOCKED)
      AppendSettings();

    Layout();
    SchedulePaint();
  }

 private:
  void AppendHeaderEntry() {
    header_ = CreateDetailedHeaderEntry(IDS_ASH_STATUS_TRAY_IME, this);
    AddChildView(header_);
  }

  void AppendIMEList(const IMEInfoList& list) {
    ime_map_.clear();
    views::View* imes = new views::View;
    imes->SetLayoutManager(new views::BoxLayout(
        views::BoxLayout::kVertical, 0, 0, 1));
    for (size_t i = 0; i < list.size(); i++) {
      HoverHighlightView* container = new HoverHighlightView(this);
      container->set_fixed_height(kTrayPopupItemHeight);
      container->AddLabel(list[i].name,
          list[i].selected ? gfx::Font::BOLD : gfx::Font::NORMAL);
      imes->AddChildView(container);
      ime_map_[container] = list[i].id;
    }
    imes->set_border(views::Border::CreateSolidSidedBorder(1, 0, 1, 0,
        kBorderLightColor));
    AddChildView(imes);
  }

  void AppendIMEProperties(const IMEPropertyInfoList& property_list) {
    property_map_.clear();
    views::View* properties = new views::View;
    properties->SetLayoutManager(new views::BoxLayout(
        views::BoxLayout::kVertical, 0, 0, 1));
    for (size_t i = 0; i < property_list.size(); i++) {
      HoverHighlightView* container = new HoverHighlightView(this);
      container->set_fixed_height(kTrayPopupItemHeight);
      container->AddLabel(
          property_list[i].name,
          property_list[i].selected ? gfx::Font::BOLD : gfx::Font::NORMAL);
      properties->AddChildView(container);
      property_map_[container] = property_list[i].key;
    }
    properties->set_border(views::Border::CreateSolidSidedBorder(
        0, 0, 1, 0, kBorderLightColor));
    AddChildView(properties);
  }

  void AppendSettings() {
    HoverHighlightView* container = new HoverHighlightView(this);
    container->set_fixed_height(kTrayPopupItemHeight);
    container->AddLabel(ui::ResourceBundle::GetSharedInstance().
        GetLocalizedString(IDS_ASH_STATUS_TRAY_IME_SETTINGS),
        gfx::Font::NORMAL);
    AddChildView(container);
    settings_ = container;
  }

  // Overridden from ViewClickListener.
  virtual void ClickedOn(views::View* sender) OVERRIDE {
    SystemTrayDelegate* delegate = Shell::GetInstance()->tray_delegate();
    if (sender == header_) {
      Shell::GetInstance()->tray()->ShowDefaultView();
    } else if (sender == settings_) {
      delegate->ShowIMESettings();
    } else {
      std::map<views::View*, std::string>::const_iterator ime_find;
      ime_find = ime_map_.find(sender);
      if (ime_find != ime_map_.end()) {
        std::string ime_id = ime_find->second;
        delegate->SwitchIME(ime_id);
        GetWidget()->Close();
      } else {
        std::map<views::View*, std::string>::const_iterator prop_find;
        prop_find = property_map_.find(sender);
        if (prop_find != property_map_.end()) {
          const std::string key = prop_find->second;
          delegate->ActivateIMEProperty(key);
          GetWidget()->Close();
        }
      }
    }
  }

  user::LoginStatus login_;

  std::map<views::View*, std::string> ime_map_;
  std::map<views::View*, std::string> property_map_;
  views::View* header_;
  views::View* settings_;

  DISALLOW_COPY_AND_ASSIGN(IMEDetailedView);
};

}  // namespace tray

TrayIME::TrayIME() {
}

TrayIME::~TrayIME() {
}

void TrayIME::UpdateTrayLabel(const IMEInfo& current, size_t count) {
  tray_label_->SetText(current.short_name);
  tray_label_->SetVisible(count > 1);
}

views::View* TrayIME::CreateTrayView(user::LoginStatus status) {
  tray_label_.reset(new views::Label);
  SetupLabelForTray(tray_label_.get());
  tray_label_->set_border(
      views::Border::CreateEmptyBorder(0, 2, 0, 2));
  return tray_label_.get();
}

views::View* TrayIME::CreateDefaultView(user::LoginStatus status) {
  SystemTrayDelegate* delegate = Shell::GetInstance()->tray_delegate();
  IMEInfoList list;
  IMEPropertyInfoList property_list;
  delegate->GetAvailableIMEList(&list);
  delegate->GetCurrentIMEProperties(&property_list);
  if (list.size() <= 1 && property_list.size() <= 1)
    return NULL;
  default_.reset(new tray::IMEDefaultView(this));
  return default_.get();
}

views::View* TrayIME::CreateDetailedView(user::LoginStatus status) {
  detailed_.reset(new tray::IMEDetailedView(this, status));
  return detailed_.get();
}

void TrayIME::DestroyTrayView() {
  tray_label_.reset();
}

void TrayIME::DestroyDefaultView() {
  default_.reset();
}

void TrayIME::DestroyDetailedView() {
  detailed_.reset();
}

void TrayIME::OnIMERefresh() {
  SystemTrayDelegate* delegate = Shell::GetInstance()->tray_delegate();
  IMEInfoList list;
  IMEInfo current;
  IMEPropertyInfoList property_list;
  delegate->GetCurrentIME(&current);
  delegate->GetAvailableIMEList(&list);
  delegate->GetCurrentIMEProperties(&property_list);

  UpdateTrayLabel(current, list.size());

  if (default_.get())
    default_->UpdateLabel(current);
  if (detailed_.get())
    detailed_->Update(list, property_list);
}

}  // namespace internal
}  // namespace ash
<|endoftext|>


<commit_before>#include <zlib.h>
#include <lcm/lcm-cpp.hpp>

#include <lcmtypes/bot_core/planar_lidar_t.hpp>
#include <lcmtypes/bot_core/pointcloud_t.hpp>
#include <lcmtypes/bot_core/pose_t.hpp>
#include <lcmtypes/bot_core/rigid_transform_t.hpp>

#include <boost/shared_ptr.hpp>
#include "lidar-odometry.hpp"
#include <ConciseArgs>

#include <bot_param/param_client.h>
#include <bot_frames/bot_frames.h>

using namespace std;

struct CommandLineConfig
{
  bool use_velodyne;
  bool init_with_message; // initialize off of a pose or vicon
  std::string input_channel;
  std::string output_channel;
  std::string init_channel;
};

class App{
  public:
    App(boost::shared_ptr<lcm::LCM> &lcm_, const CommandLineConfig& cl_cfg_);

    ~App(){
    }

  private:
    boost::shared_ptr<lcm::LCM> lcm_;
    const CommandLineConfig cl_cfg_;

    BotParam* botparam_;
    BotFrames* botframes_;

    void lidarHandler(const lcm::ReceiveBuffer* rbuf, const std::string& channel, const  bot_core::planar_lidar_t* msg);
    void pointCloudHandler(const lcm::ReceiveBuffer* rbuf, const std::string& channel, const  bot_core::pointcloud_t* msg);
    LidarOdom* lidarOdom_;

    Eigen::Isometry3d body_to_lidar_; // Fixed tf from the lidar to the robot's base link
    Eigen::Isometry3d world_to_body_init_; // Captures the position of the body frame in world at launch
    Eigen::Isometry3d world_to_body_now_; // running position estimate

    // Init handlers:
    void rigidTransformInitHandler(const lcm::ReceiveBuffer* rbuf, const std::string& channel, const  bot_core::rigid_transform_t* msg);
    void poseInitHandler(const lcm::ReceiveBuffer* rbuf, const std::string& channel, const  bot_core::pose_t* msg);
    void initState( const double trans[3], const double quat[4]);
    bool pose_initialized_;

    bot_core::pose_t getPoseAsBotPose(Eigen::Isometry3d pose, int64_t utime);

    int get_trans_with_utime(BotFrames *bot_frames,
        const char *from_frame, const char *to_frame, int64_t utime,
        Eigen::Isometry3d& mat);
};

App::App(boost::shared_ptr<lcm::LCM> &lcm_, const CommandLineConfig& cl_cfg_) :
       lcm_(lcm_), cl_cfg_(cl_cfg_){

  // Set up frames and config:
  botparam_ = bot_param_new_from_server(lcm_->getUnderlyingLCM(), 0);
  botframes_= bot_frames_get_global(lcm_->getUnderlyingLCM(), botparam_);

  if (cl_cfg_.use_velodyne){
    lcm_->subscribe("VELODYNE_HORIZONTAL",&App::pointCloudHandler,this);
    int status = get_trans_with_utime( botframes_ ,  "VELODYNE", "body"  , 0, body_to_lidar_);
  }else{
    lcm_->subscribe(cl_cfg_.input_channel ,&App::lidarHandler,this);
    int status = get_trans_with_utime( botframes_ ,  cl_cfg_.input_channel, "body"  , 0, body_to_lidar_);
    std::cout << "Body to Lidar from param: " << std::endl;
    std::cout << body_to_lidar_.matrix() << std::endl;

  }

  pose_initialized_ = false;
  if (!cl_cfg_.init_with_message){
    std::cout << "Init internal est using default\n";
    world_to_body_init_ = Eigen::Isometry3d::Identity();

    /*
    world_to_body_init_.setIdentity();
    world_to_body_init_.translation()  << 1.2, 1.67, 0.32;
    Eigen::Quaterniond q(-0.045668, -0.004891, -0.00909, 0.9989);
    world_to_body_init_.rotate(q);
    bot_core::pose_t pose_msg_body = getPoseAsBotPose( world_to_lidar_init_ , 0);
    lcm_->publish("POSE_BODY_ALT", &pose_msg_body );
    pose_initialized_ = true;
    */

    pose_initialized_ = true;
  }else{
    lcm_->subscribe("VICON_BODY|VICON_FRONTPLATE",&App::rigidTransformInitHandler,this);
    lcm_->subscribe(cl_cfg_.init_channel,&App::poseInitHandler,this);
    std::cout << "Waiting for Init message to LIDAR estimator\n";
  }

  lidarOdom_ = new LidarOdom(lcm_);
}

int App::get_trans_with_utime(BotFrames *bot_frames,
        const char *from_frame, const char *to_frame, int64_t utime,
        Eigen::Isometry3d & mat){
  int status;
  double matx[16];
  status = bot_frames_get_trans_mat_4x4_with_utime( bot_frames, from_frame,  to_frame, utime, matx);
  for (int i = 0; i < 4; ++i) {
    for (int j = 0; j < 4; ++j) {
      mat(i,j) = matx[i*4+j];
    }
  }

  return status;
}

bot_core::pose_t App::getPoseAsBotPose(Eigen::Isometry3d pose, int64_t utime){
  bot_core::pose_t pose_msg;
  pose_msg.utime =   utime;
  pose_msg.pos[0] = pose.translation().x();
  pose_msg.pos[1] = pose.translation().y();
  pose_msg.pos[2] = pose.translation().z();
  Eigen::Quaterniond r_x(pose.rotation());
  pose_msg.orientation[0] =  r_x.w();
  pose_msg.orientation[1] =  r_x.x();
  pose_msg.orientation[2] =  r_x.y();
  pose_msg.orientation[3] =  r_x.z();
  return pose_msg;
}

void App::lidarHandler(const lcm::ReceiveBuffer* rbuf,
     const std::string& channel, const  bot_core::planar_lidar_t* msg){
  if (!pose_initialized_){
    std::cout << "Estimate not initialised, exiting lidarHandler\n";
    return;
  }

  // 1. Update LIDAR Odometry
  std::vector<float> ranges_copy = msg->ranges;
  float* ranges = &ranges_copy[0];
  lidarOdom_->doOdometry(ranges, msg->nranges, msg->rad0, msg->radstep, msg->utime);

  // 2. Determine the body position using the LIDAR motion estimate:
  Eigen::Isometry3d lidar_init_to_lidar_now = lidarOdom_->getCurrentPose();
  Eigen::Isometry3d world_to_lidar_now = world_to_body_init_*body_to_lidar_*lidar_init_to_lidar_now;
  world_to_body_now_ = world_to_lidar_now * body_to_lidar_.inverse();

  //bot_core::pose_t pose_msg = getPoseAsBotPose( lidar_init_to_lidar_now , msg->utime);
  //lcm_->publish("POSE_BODY_ALT", &pose_msg );
  bot_core::pose_t pose_msg_body = getPoseAsBotPose( world_to_body_now_ , msg->utime);
  lcm_->publish(cl_cfg_.output_channel, &pose_msg_body );
}

void App::pointCloudHandler(const lcm::ReceiveBuffer* rbuf,
     const std::string& channel, const  bot_core::pointcloud_t* msg){
  if (!pose_initialized_){
    std::cout << "Estimate not initialised, exiting pointCloudHandler\n";
    return;
  }

  // 1. Update LIDAR Odometry
  std::vector<float> x;
  std::vector<float> y;
  for (int i=0;i<msg->n_points; i++){
    x.push_back( msg->points[i][0] );
    y.push_back( msg->points[i][1] );
  }

  lidarOdom_->doOdometry(x, y, msg->n_points, msg->utime);

  // 2. Determine the body position using the LIDAR motion estimate:
  Eigen::Isometry3d lidar_init_to_lidar_now = lidarOdom_->getCurrentPose();
  Eigen::Isometry3d world_to_lidar_now = world_to_body_init_*body_to_lidar_*lidar_init_to_lidar_now;
  world_to_body_now_ = world_to_lidar_now * body_to_lidar_.inverse();

  //bot_core::pose_t pose_msg = getPoseAsBotPose( world_to_lidar_now , msg->utime);
  //lcm_->publish("POSE_BODY_ALT", &pose_msg );
  bot_core::pose_t pose_msg_body = getPoseAsBotPose( world_to_body_now_ , msg->utime);
  lcm_->publish(cl_cfg_.output_channel, &pose_msg_body );
}

void App::initState(const double trans[3], const double quat[4]){
  if ( !cl_cfg_.init_with_message || pose_initialized_ ){
    return;
  }

  std::cout << "Init internal est using rigid transform or pose\n";

  world_to_body_init_.setIdentity();
  world_to_body_init_.translation()  << trans[0], trans[1] , trans[2];
  Eigen::Quaterniond quatE = Eigen::Quaterniond(quat[0], quat[1],
                                               quat[2], quat[3]);
  world_to_body_init_.rotate(quatE);
  pose_initialized_ = TRUE;
}

void App::rigidTransformInitHandler(const lcm::ReceiveBuffer* rbuf, const std::string& channel, const  bot_core::rigid_transform_t* msg){
  initState(msg->trans, msg->quat);
}

void App::poseInitHandler(const lcm::ReceiveBuffer* rbuf, const std::string& channel, const  bot_core::pose_t* msg){
  initState(msg->pos, msg->orientation);
}

int main(int argc, char **argv){
  CommandLineConfig cl_cfg;
  cl_cfg.use_velodyne = false;
  cl_cfg.init_with_message = TRUE;
  cl_cfg.input_channel = "HOKUYO_SCAN";
  cl_cfg.output_channel = "POSE_BODY";
  cl_cfg.init_channel = "POSE_VICON";

  ConciseArgs parser(argc, argv, "simple-fusion");
  parser.add(cl_cfg.init_with_message, "g", "init_with_message", "Bootstrap internal estimate using VICON or POSE_INIT");
  parser.add(cl_cfg.input_channel, "s", "input_channel", "Input LIDAR scan message");
  parser.add(cl_cfg.output_channel, "o", "output_channel", "Output message e.g POSE_BODY");
  parser.add(cl_cfg.use_velodyne, "v", "use_velodyne", "Use a velodyne instead of the LIDAR");
  parser.add(cl_cfg.init_channel, "i", "init_channel", "Read the init message from this channel, e.g., POSE_VICON");
  parser.parse();

  boost::shared_ptr<lcm::LCM> lcm(new lcm::LCM);
  if(!lcm->good()){
    std::cerr <<"ERROR: lcm is not good()" <<std::endl;
  }
  App app= App(lcm, cl_cfg);
  while(0 == lcm->handle());
}
<commit_msg>use c string<commit_after>#include <zlib.h>
#include <lcm/lcm-cpp.hpp>

#include <lcmtypes/bot_core/planar_lidar_t.hpp>
#include <lcmtypes/bot_core/pointcloud_t.hpp>
#include <lcmtypes/bot_core/pose_t.hpp>
#include <lcmtypes/bot_core/rigid_transform_t.hpp>

#include <boost/shared_ptr.hpp>
#include "lidar-odometry.hpp"
#include <ConciseArgs>

#include <bot_param/param_client.h>
#include <bot_frames/bot_frames.h>

using namespace std;

struct CommandLineConfig
{
  bool use_velodyne;
  bool init_with_message; // initialize off of a pose or vicon
  std::string input_channel;
  std::string output_channel;
  std::string init_channel;
};

class App{
  public:
    App(boost::shared_ptr<lcm::LCM> &lcm_, const CommandLineConfig& cl_cfg_);

    ~App(){
    }

  private:
    boost::shared_ptr<lcm::LCM> lcm_;
    const CommandLineConfig cl_cfg_;

    BotParam* botparam_;
    BotFrames* botframes_;

    void lidarHandler(const lcm::ReceiveBuffer* rbuf, const std::string& channel, const  bot_core::planar_lidar_t* msg);
    void pointCloudHandler(const lcm::ReceiveBuffer* rbuf, const std::string& channel, const  bot_core::pointcloud_t* msg);
    LidarOdom* lidarOdom_;

    Eigen::Isometry3d body_to_lidar_; // Fixed tf from the lidar to the robot's base link
    Eigen::Isometry3d world_to_body_init_; // Captures the position of the body frame in world at launch
    Eigen::Isometry3d world_to_body_now_; // running position estimate

    // Init handlers:
    void rigidTransformInitHandler(const lcm::ReceiveBuffer* rbuf, const std::string& channel, const  bot_core::rigid_transform_t* msg);
    void poseInitHandler(const lcm::ReceiveBuffer* rbuf, const std::string& channel, const  bot_core::pose_t* msg);
    void initState( const double trans[3], const double quat[4]);
    bool pose_initialized_;

    bot_core::pose_t getPoseAsBotPose(Eigen::Isometry3d pose, int64_t utime);

    int get_trans_with_utime(BotFrames *bot_frames,
        const char *from_frame, const char *to_frame, int64_t utime,
        Eigen::Isometry3d& mat);
};

App::App(boost::shared_ptr<lcm::LCM> &lcm_, const CommandLineConfig& cl_cfg_) :
       lcm_(lcm_), cl_cfg_(cl_cfg_){

  // Set up frames and config:
  botparam_ = bot_param_new_from_server(lcm_->getUnderlyingLCM(), 0);
  botframes_= bot_frames_get_global(lcm_->getUnderlyingLCM(), botparam_);

  if (cl_cfg_.use_velodyne){
    lcm_->subscribe("VELODYNE_HORIZONTAL",&App::pointCloudHandler,this);
    int status = get_trans_with_utime( botframes_ ,  "VELODYNE", "body"  , 0, body_to_lidar_);
  }else{
    lcm_->subscribe(cl_cfg_.input_channel ,&App::lidarHandler,this);
    int status = get_trans_with_utime( botframes_ ,  cl_cfg_.input_channel.c_str() , "body"  , 0, body_to_lidar_);
    std::cout << "Body to Lidar from param: " << std::endl;
    std::cout << body_to_lidar_.matrix() << std::endl;

  }

  pose_initialized_ = false;
  if (!cl_cfg_.init_with_message){
    std::cout << "Init internal est using default\n";
    world_to_body_init_ = Eigen::Isometry3d::Identity();

    /*
    world_to_body_init_.setIdentity();
    world_to_body_init_.translation()  << 1.2, 1.67, 0.32;
    Eigen::Quaterniond q(-0.045668, -0.004891, -0.00909, 0.9989);
    world_to_body_init_.rotate(q);
    bot_core::pose_t pose_msg_body = getPoseAsBotPose( world_to_lidar_init_ , 0);
    lcm_->publish("POSE_BODY_ALT", &pose_msg_body );
    pose_initialized_ = true;
    */

    pose_initialized_ = true;
  }else{
    lcm_->subscribe("VICON_BODY|VICON_FRONTPLATE",&App::rigidTransformInitHandler,this);
    lcm_->subscribe(cl_cfg_.init_channel,&App::poseInitHandler,this);
    std::cout << "Waiting for Init message to LIDAR estimator\n";
  }

  lidarOdom_ = new LidarOdom(lcm_);
}

int App::get_trans_with_utime(BotFrames *bot_frames,
        const char *from_frame, const char *to_frame, int64_t utime,
        Eigen::Isometry3d & mat){
  int status;
  double matx[16];
  status = bot_frames_get_trans_mat_4x4_with_utime( bot_frames, from_frame,  to_frame, utime, matx);
  for (int i = 0; i < 4; ++i) {
    for (int j = 0; j < 4; ++j) {
      mat(i,j) = matx[i*4+j];
    }
  }

  return status;
}

bot_core::pose_t App::getPoseAsBotPose(Eigen::Isometry3d pose, int64_t utime){
  bot_core::pose_t pose_msg;
  pose_msg.utime =   utime;
  pose_msg.pos[0] = pose.translation().x();
  pose_msg.pos[1] = pose.translation().y();
  pose_msg.pos[2] = pose.translation().z();
  Eigen::Quaterniond r_x(pose.rotation());
  pose_msg.orientation[0] =  r_x.w();
  pose_msg.orientation[1] =  r_x.x();
  pose_msg.orientation[2] =  r_x.y();
  pose_msg.orientation[3] =  r_x.z();
  return pose_msg;
}

void App::lidarHandler(const lcm::ReceiveBuffer* rbuf,
     const std::string& channel, const  bot_core::planar_lidar_t* msg){
  if (!pose_initialized_){
    std::cout << "Estimate not initialised, exiting lidarHandler\n";
    return;
  }

  // 1. Update LIDAR Odometry
  std::vector<float> ranges_copy = msg->ranges;
  float* ranges = &ranges_copy[0];
  lidarOdom_->doOdometry(ranges, msg->nranges, msg->rad0, msg->radstep, msg->utime);

  // 2. Determine the body position using the LIDAR motion estimate:
  Eigen::Isometry3d lidar_init_to_lidar_now = lidarOdom_->getCurrentPose();
  Eigen::Isometry3d world_to_lidar_now = world_to_body_init_*body_to_lidar_*lidar_init_to_lidar_now;
  world_to_body_now_ = world_to_lidar_now * body_to_lidar_.inverse();

  //bot_core::pose_t pose_msg = getPoseAsBotPose( lidar_init_to_lidar_now , msg->utime);
  //lcm_->publish("POSE_BODY_ALT", &pose_msg );
  bot_core::pose_t pose_msg_body = getPoseAsBotPose( world_to_body_now_ , msg->utime);
  lcm_->publish(cl_cfg_.output_channel, &pose_msg_body );
}

void App::pointCloudHandler(const lcm::ReceiveBuffer* rbuf,
     const std::string& channel, const  bot_core::pointcloud_t* msg){
  if (!pose_initialized_){
    std::cout << "Estimate not initialised, exiting pointCloudHandler\n";
    return;
  }

  // 1. Update LIDAR Odometry
  std::vector<float> x;
  std::vector<float> y;
  for (int i=0;i<msg->n_points; i++){
    x.push_back( msg->points[i][0] );
    y.push_back( msg->points[i][1] );
  }

  lidarOdom_->doOdometry(x, y, msg->n_points, msg->utime);

  // 2. Determine the body position using the LIDAR motion estimate:
  Eigen::Isometry3d lidar_init_to_lidar_now = lidarOdom_->getCurrentPose();
  Eigen::Isometry3d world_to_lidar_now = world_to_body_init_*body_to_lidar_*lidar_init_to_lidar_now;
  world_to_body_now_ = world_to_lidar_now * body_to_lidar_.inverse();

  //bot_core::pose_t pose_msg = getPoseAsBotPose( world_to_lidar_now , msg->utime);
  //lcm_->publish("POSE_BODY_ALT", &pose_msg );
  bot_core::pose_t pose_msg_body = getPoseAsBotPose( world_to_body_now_ , msg->utime);
  lcm_->publish(cl_cfg_.output_channel, &pose_msg_body );
}

void App::initState(const double trans[3], const double quat[4]){
  if ( !cl_cfg_.init_with_message || pose_initialized_ ){
    return;
  }

  std::cout << "Init internal est using rigid transform or pose\n";

  world_to_body_init_.setIdentity();
  world_to_body_init_.translation()  << trans[0], trans[1] , trans[2];
  Eigen::Quaterniond quatE = Eigen::Quaterniond(quat[0], quat[1],
                                               quat[2], quat[3]);
  world_to_body_init_.rotate(quatE);
  pose_initialized_ = TRUE;
}

void App::rigidTransformInitHandler(const lcm::ReceiveBuffer* rbuf, const std::string& channel, const  bot_core::rigid_transform_t* msg){
  initState(msg->trans, msg->quat);
}

void App::poseInitHandler(const lcm::ReceiveBuffer* rbuf, const std::string& channel, const  bot_core::pose_t* msg){
  initState(msg->pos, msg->orientation);
}

int main(int argc, char **argv){
  CommandLineConfig cl_cfg;
  cl_cfg.use_velodyne = false;
  cl_cfg.init_with_message = TRUE;
  cl_cfg.input_channel = "HOKUYO_SCAN";
  cl_cfg.output_channel = "POSE_BODY";
  cl_cfg.init_channel = "POSE_VICON";

  ConciseArgs parser(argc, argv, "simple-fusion");
  parser.add(cl_cfg.init_with_message, "g", "init_with_message", "Bootstrap internal estimate using VICON or POSE_INIT");
  parser.add(cl_cfg.input_channel, "s", "input_channel", "Input LIDAR scan message");
  parser.add(cl_cfg.output_channel, "o", "output_channel", "Output message e.g POSE_BODY");
  parser.add(cl_cfg.use_velodyne, "v", "use_velodyne", "Use a velodyne instead of the LIDAR");
  parser.add(cl_cfg.init_channel, "i", "init_channel", "Read the init message from this channel, e.g., POSE_VICON");
  parser.parse();

  boost::shared_ptr<lcm::LCM> lcm(new lcm::LCM);
  if(!lcm->good()){
    std::cerr <<"ERROR: lcm is not good()" <<std::endl;
  }
  App app= App(lcm, cl_cfg);
  while(0 == lcm->handle());
}
<|endoftext|>


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

#include <assert.h>
#include "corgi/component_id_lookup.h"
#include "corgi/entity_manager.h"
#include "corgi/version.h"

namespace corgi {

// The reference to the version string is important because it ensures that
// the constant won't be stripped out by the compiler.
EntityManager::EntityManager()
    : entity_factory_(nullptr),
      max_component_id_(kInvalidComponent),
      version_(&Version()) {
  for (int i = 0; i < kMaxComponentCount; i++) {
    components_[i] = nullptr;
  }
}

// Allocates a new entity and returns it
EntityRef EntityManager::AllocateNewEntity() {
  EntityRef result = EntityRef(entities_.GetNewElement(kAddToBack));
  // Indexes are guaranteed to be unique and stable in vector pools.
  // May need to revisit this if we implement defragging though.
  result->set_entity_id(result.index());
  return result;
}

// Note: This function doesn't actually delete the entity immediately -
// it just marks it for deletion, and it gets cleaned out at the end of the
// next AdvanceFrame.
void EntityManager::DeleteEntity(EntityRef entity) {
  if (entity->marked_for_deletion()) {
    // already marked for deletion.
    return;
  }
  entity->set_marked_for_deletion(true);
  entities_to_delete_.push_back(entity);
}

// This deletes the entity instantly.  You should generally use the regular
// DeleteEntity unless you have a particuarly good reason to need it instantly.
void EntityManager::DeleteEntityImmediately(EntityRef entity) {
  RemoveAllComponents(entity);
  entities_.FreeElement(entity);
}

void EntityManager::DeleteMarkedEntities() {
  for (size_t i = 0; i < entities_to_delete_.size(); i++) {
    EntityRef entity = entities_to_delete_[i];
    RemoveAllComponents(entity);
    entities_.FreeElement(entity);
  }
  entities_to_delete_.resize(0);
}

void EntityManager::RemoveAllComponents(EntityRef entity) {
  for (ComponentId i = 0; i < kMaxComponentCount; i++) {
    if (components_[i] != nullptr && components_[i]->HasDataForEntity(entity)) {
      components_[i]->RemoveEntity(entity);
    }
  }
}

void EntityManager::AddEntityToComponent(EntityRef entity,
                                         ComponentId component_id) {
  ComponentInterface* component = GetComponent(component_id);
  assert(component != nullptr);
  component->AddEntityGenerically(entity);
}

void EntityManager::RegisterComponentHelper(ComponentInterface* new_component,
                                            ComponentId id) {
  assert(id < kMaxComponentCount);
  // Make sure this ID isn't already associated with a component.
  assert(components_[id] == nullptr);
  components_[id] = new_component;
  new_component->SetEntityManager(this);
  new_component->SetComponentIdOnDataType(id);
  new_component->Init();
}

void* EntityManager::GetComponentDataAsVoid(EntityRef entity,
                                            ComponentId component_id) {
  return components_[component_id]
             ? components_[component_id]->GetComponentDataAsVoid(entity)
             : nullptr;
}

const void* EntityManager::GetComponentDataAsVoid(
    EntityRef entity, ComponentId component_id) const {
  return components_[component_id]
             ? components_[component_id]->GetComponentDataAsVoid(entity)
             : nullptr;
}

void EntityManager::UpdateComponents(WorldTime delta_time) {
  // Update all the registered components.
  for (size_t i = 0; i < kMaxComponentCount; i++) {
    if (components_[i]) components_[i]->UpdateAllEntities(delta_time);
  }
  DeleteMarkedEntities();
}

void EntityManager::Clear() {
  for (size_t i = 0; i < kMaxComponentCount; i++) {
    if (components_[i]) {
      components_[i]->ClearComponentData();
      components_[i]->Cleanup();
    }
    components_[i] = nullptr;
  }
  entities_.Clear();
}

EntityRef EntityManager::CreateEntityFromData(const void* data) {
  assert(entity_factory_ != nullptr);
  return entity_factory_->CreateEntityFromData(data, this);
}

}  // corgi
<commit_msg>Fixed a bug where the max_component_id_ was not being reset.<commit_after>// Copyright 2015 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <assert.h>
#include "corgi/component_id_lookup.h"
#include "corgi/entity_manager.h"
#include "corgi/version.h"

namespace corgi {

// The reference to the version string is important because it ensures that
// the constant won't be stripped out by the compiler.
EntityManager::EntityManager()
    : entity_factory_(nullptr),
      max_component_id_(kInvalidComponent),
      version_(&Version()) {
  for (int i = 0; i < kMaxComponentCount; i++) {
    components_[i] = nullptr;
  }
}

// Allocates a new entity and returns it
EntityRef EntityManager::AllocateNewEntity() {
  EntityRef result = EntityRef(entities_.GetNewElement(kAddToBack));
  // Indexes are guaranteed to be unique and stable in vector pools.
  // May need to revisit this if we implement defragging though.
  result->set_entity_id(result.index());
  return result;
}

// Note: This function doesn't actually delete the entity immediately -
// it just marks it for deletion, and it gets cleaned out at the end of the
// next AdvanceFrame.
void EntityManager::DeleteEntity(EntityRef entity) {
  if (entity->marked_for_deletion()) {
    // already marked for deletion.
    return;
  }
  entity->set_marked_for_deletion(true);
  entities_to_delete_.push_back(entity);
}

// This deletes the entity instantly.  You should generally use the regular
// DeleteEntity unless you have a particuarly good reason to need it instantly.
void EntityManager::DeleteEntityImmediately(EntityRef entity) {
  RemoveAllComponents(entity);
  entities_.FreeElement(entity);
}

void EntityManager::DeleteMarkedEntities() {
  for (size_t i = 0; i < entities_to_delete_.size(); i++) {
    EntityRef entity = entities_to_delete_[i];
    RemoveAllComponents(entity);
    entities_.FreeElement(entity);
  }
  entities_to_delete_.resize(0);
}

void EntityManager::RemoveAllComponents(EntityRef entity) {
  for (ComponentId i = 0; i < kMaxComponentCount; i++) {
    if (components_[i] != nullptr && components_[i]->HasDataForEntity(entity)) {
      components_[i]->RemoveEntity(entity);
    }
  }
}

void EntityManager::AddEntityToComponent(EntityRef entity,
                                         ComponentId component_id) {
  ComponentInterface* component = GetComponent(component_id);
  assert(component != nullptr);
  component->AddEntityGenerically(entity);
}

void EntityManager::RegisterComponentHelper(ComponentInterface* new_component,
                                            ComponentId id) {
  assert(id < kMaxComponentCount);
  // Make sure this ID isn't already associated with a component.
  assert(components_[id] == nullptr);
  components_[id] = new_component;
  new_component->SetEntityManager(this);
  new_component->SetComponentIdOnDataType(id);
  new_component->Init();
}

void* EntityManager::GetComponentDataAsVoid(EntityRef entity,
                                            ComponentId component_id) {
  return components_[component_id]
             ? components_[component_id]->GetComponentDataAsVoid(entity)
             : nullptr;
}

const void* EntityManager::GetComponentDataAsVoid(
    EntityRef entity, ComponentId component_id) const {
  return components_[component_id]
             ? components_[component_id]->GetComponentDataAsVoid(entity)
             : nullptr;
}

void EntityManager::UpdateComponents(WorldTime delta_time) {
  // Update all the registered components.
  for (size_t i = 0; i < kMaxComponentCount; i++) {
    if (components_[i]) components_[i]->UpdateAllEntities(delta_time);
  }
  DeleteMarkedEntities();
}

void EntityManager::Clear() {
  for (size_t i = 0; i < kMaxComponentCount; i++) {
    if (components_[i]) {
      components_[i]->ClearComponentData();
      components_[i]->Cleanup();
    }
    components_[i] = nullptr;
  }
  entities_.Clear();
  max_component_id_ = 0;
}

EntityRef EntityManager::CreateEntityFromData(const void* data) {
  assert(entity_factory_ != nullptr);
  return entity_factory_->CreateEntityFromData(data, this);
}

}  // corgi
<|endoftext|>


<commit_before>#ifndef ENTT_META_NODE_HPP
#define ENTT_META_NODE_HPP

#include <cstddef>
#include <memory>
#include <type_traits>
#include <utility>
#include "../config/config.h"
#include "../container/dense_map.hpp"
#include "../core/attribute.h"
#include "../core/enum.hpp"
#include "../core/fwd.hpp"
#include "../core/type_info.hpp"
#include "../core/type_traits.hpp"
#include "../core/utility.hpp"
#include "../locator/locator.hpp" // TODO
#include "context.hpp"
#include "type_traits.hpp"

namespace entt {

class meta_any;
class meta_type;
struct meta_handle;

/**
 * @cond TURN_OFF_DOXYGEN
 * Internal details not to be documented.
 */

namespace internal {

enum class meta_traits : std::uint32_t {
    is_none = 0x0000,
    is_const = 0x0001,
    is_static = 0x0002,
    is_arithmetic = 0x0004,
    is_integral = 0x0008,
    is_signed = 0x0010,
    is_array = 0x0020,
    is_enum = 0x0040,
    is_class = 0x0080,
    is_meta_pointer_like = 0x0100,
    is_meta_sequence_container = 0x0200,
    is_meta_associative_container = 0x0400,
    _entt_enum_as_bitmask
};

struct meta_type_node;

struct meta_prop_node {
    meta_type_node (*type)(const meta_context &) noexcept {};
    std::shared_ptr<void> value{};
};

struct meta_base_node {
    meta_type_node (*type)(const meta_context &) noexcept {};
    const void *(*cast)(const void *) noexcept {};
};

struct meta_conv_node {
    meta_any (*conv)(const void *, const meta_ctx &){};
};

struct meta_ctor_node {
    using size_type = std::size_t;

    size_type arity{0u};
    meta_type (*arg)(const size_type, const meta_ctx &) noexcept {};
    meta_any (*invoke)(meta_any *const, const meta_ctx &){};
};

struct meta_dtor_node {
    void (*dtor)(void *){};
};

struct meta_data_node {
    using size_type = std::size_t;

    meta_traits traits{meta_traits::is_none};
    size_type arity{0u};
    meta_type_node (*type)(const meta_context &) noexcept {};
    meta_type (*arg)(const size_type, const meta_ctx &) noexcept {};
    bool (*set)(meta_handle, meta_any, const meta_ctx &){};
    meta_any (*get)(meta_handle, const meta_ctx &){};
    dense_map<id_type, meta_prop_node, identity> prop{};
};

struct meta_func_node {
    using size_type = std::size_t;

    meta_traits traits{meta_traits::is_none};
    size_type arity{0u};
    meta_type_node (*ret)(const meta_context &) noexcept {};
    meta_type (*arg)(const size_type, const meta_ctx &) noexcept {};
    meta_any (*invoke)(meta_handle, meta_any *const, const meta_ctx &){};
    std::shared_ptr<meta_func_node> next{};
    dense_map<id_type, meta_prop_node, identity> prop{};
};

struct meta_template_node {
    using size_type = std::size_t;

    size_type arity{0u};
    meta_type_node (*type)(const meta_context &) noexcept {};
    meta_type_node (*arg)(const size_type, const meta_context &) noexcept {};
};

struct meta_type_descriptor {
    dense_map<id_type, meta_ctor_node, identity> ctor{};
    dense_map<id_type, meta_base_node, identity> base{};
    dense_map<id_type, meta_conv_node, identity> conv{};
    dense_map<id_type, meta_data_node, identity> data{};
    dense_map<id_type, meta_func_node, identity> func{};
    dense_map<id_type, meta_prop_node, identity> prop{};
};

struct meta_type_node {
    using size_type = std::size_t;

    const type_info *info{};
    id_type id{};
    meta_traits traits{meta_traits::is_none};
    size_type size_of{0u};
    meta_type_node (*remove_pointer)(const meta_context &) noexcept {};
    meta_any (*default_constructor)(const meta_ctx &){};
    double (*conversion_helper)(void *, const void *){};
    meta_any (*from_void)(void *, const void *, const meta_ctx &){};
    meta_template_node templ{};
    meta_dtor_node dtor{};
    std::shared_ptr<meta_type_descriptor> details{};
};

template<typename Type>
meta_type_node resolve(const meta_context &) noexcept;

template<typename Type>
[[nodiscard]] meta_type_node resolve_TODO() noexcept {
    return resolve<Type>(meta_context::from(locator<meta_ctx>::value_or()));
}

template<typename... Args>
[[nodiscard]] auto meta_arg_node(type_list<Args...>, [[maybe_unused]] const std::size_t index, const meta_context &context) noexcept {
    std::size_t pos{};
    meta_type_node (*value)(const meta_context &) noexcept = nullptr;
    ((value = (pos++ == index ? &resolve<std::remove_cv_t<std::remove_reference_t<Args>>> : value)), ...);
    ENTT_ASSERT(value != nullptr, "Out of bounds");
    return value(context);
}

[[nodiscard]] inline const void *try_cast(const meta_type_node &from, const meta_type_node &to, const void *instance, const meta_context &context) noexcept {
    if(from.info && to.info && *from.info == *to.info) {
        return instance;
    }

    if(from.details) {
        for(auto &&curr: from.details->base) {
            if(const void *elem = try_cast(curr.second.type(context), to, curr.second.cast(instance), context); elem) {
                return elem;
            }
        }
    }

    return nullptr;
}

[[nodiscard]] inline const meta_type_node *try_resolve(const type_info &info, const meta_context &context) noexcept {
    const auto it = context.value.find(info.hash());
    return it != context.value.end() ? &it->second : nullptr;
}

template<typename Type>
[[nodiscard]] meta_type_node resolve(const meta_context &context) noexcept {
    static_assert(std::is_same_v<Type, std::remove_const_t<std::remove_reference_t<Type>>>, "Invalid type");

    if(auto *elem = try_resolve(type_id<Type>(), context); elem) {
        return *elem;
    }

    meta_type_node node{
        &type_id<Type>(),
        type_id<Type>().hash(),
        (std::is_arithmetic_v<Type> ? meta_traits::is_arithmetic : meta_traits::is_none)
            | (std::is_integral_v<Type> ? meta_traits::is_integral : meta_traits::is_none)
            | (std::is_signed_v<Type> ? meta_traits::is_signed : meta_traits::is_none)
            | (std::is_array_v<Type> ? meta_traits::is_array : meta_traits::is_none)
            | (std::is_enum_v<Type> ? meta_traits::is_enum : meta_traits::is_none)
            | (std::is_class_v<Type> ? meta_traits::is_class : meta_traits::is_none)
            | (is_meta_pointer_like_v<Type> ? meta_traits::is_meta_pointer_like : meta_traits::is_none)
            | (is_complete_v<meta_sequence_container_traits<Type>> ? meta_traits::is_meta_sequence_container : meta_traits::is_none)
            | (is_complete_v<meta_associative_container_traits<Type>> ? meta_traits::is_meta_associative_container : meta_traits::is_none),
        size_of_v<Type>,
        &resolve<std::remove_cv_t<std::remove_pointer_t<Type>>>};

    if constexpr(std::is_default_constructible_v<Type>) {
        node.default_constructor = +[](const meta_ctx &ctx) {
            // TODO it would be great if we had value and context construction support for meta_any
            meta_any elem{ctx};
            elem.emplace<Type>();
            return elem;
        };
    }

    if constexpr(std::is_arithmetic_v<Type>) {
        node.conversion_helper = +[](void *bin, const void *value) {
            return bin ? static_cast<double>(*static_cast<Type *>(bin) = static_cast<Type>(*static_cast<const double *>(value))) : static_cast<double>(*static_cast<const Type *>(value));
        };
    } else if constexpr(std::is_enum_v<Type>) {
        node.conversion_helper = +[](void *bin, const void *value) {
            return bin ? static_cast<double>(*static_cast<Type *>(bin) = static_cast<Type>(static_cast<std::underlying_type_t<Type>>(*static_cast<const double *>(value)))) : static_cast<double>(*static_cast<const Type *>(value));
        };
    }

    if constexpr(!std::is_same_v<Type, void> && !std::is_function_v<Type>) {
        node.from_void = +[](void *element, const void *as_const, const meta_ctx &ctx) {
            // TODO it would be great if we had value and context construction support for meta_any
            meta_any elem{ctx};
            element ? elem.emplace<std::decay_t<Type> &>(*static_cast<std::decay_t<Type> *>(element)) : elem.emplace<const std::decay_t<Type> &>(*static_cast<const std::decay_t<Type> *>(as_const));
            return elem;
        };
    }

    if constexpr(is_complete_v<meta_template_traits<Type>>) {
        node.templ = meta_template_node{
            meta_template_traits<Type>::args_type::size,
            &resolve<typename meta_template_traits<Type>::class_type>,
            +[](const std::size_t index, const meta_context &area) noexcept { return meta_arg_node(typename meta_template_traits<Type>::args_type{}, index, area); }};
    }

    return node;
}

} // namespace internal

/**
 * Internal details not to be documented.
 * @endcond
 */

} // namespace entt

#endif
<commit_msg>meta: try to get around invalid code that msvc accepts happily otherwise<commit_after>#ifndef ENTT_META_NODE_HPP
#define ENTT_META_NODE_HPP

#include <cstddef>
#include <memory>
#include <type_traits>
#include <utility>
#include "../config/config.h"
#include "../container/dense_map.hpp"
#include "../core/attribute.h"
#include "../core/enum.hpp"
#include "../core/fwd.hpp"
#include "../core/type_info.hpp"
#include "../core/type_traits.hpp"
#include "../core/utility.hpp"
#include "../locator/locator.hpp" // TODO
#include "context.hpp"
#include "type_traits.hpp"

namespace entt {

class meta_any;
class meta_type;
struct meta_handle;

/**
 * @cond TURN_OFF_DOXYGEN
 * Internal details not to be documented.
 */

namespace internal {

enum class meta_traits : std::uint32_t {
    is_none = 0x0000,
    is_const = 0x0001,
    is_static = 0x0002,
    is_arithmetic = 0x0004,
    is_integral = 0x0008,
    is_signed = 0x0010,
    is_array = 0x0020,
    is_enum = 0x0040,
    is_class = 0x0080,
    is_meta_pointer_like = 0x0100,
    is_meta_sequence_container = 0x0200,
    is_meta_associative_container = 0x0400,
    _entt_enum_as_bitmask
};

struct meta_type_node;

struct meta_prop_node {
    meta_type_node (*type)(const meta_context &) noexcept {};
    std::shared_ptr<void> value{};
};

struct meta_base_node {
    meta_type_node (*type)(const meta_context &) noexcept {};
    const void *(*cast)(const void *) noexcept {};
};

struct meta_conv_node {
    meta_any (*conv)(const void *, const meta_ctx &){};
};

struct meta_ctor_node {
    using size_type = std::size_t;

    size_type arity{0u};
    meta_type (*arg)(const size_type, const meta_ctx &) noexcept {};
    meta_any (*invoke)(meta_any *const, const meta_ctx &){};
};

struct meta_dtor_node {
    void (*dtor)(void *){};
};

struct meta_data_node {
    using size_type = std::size_t;

    meta_traits traits{meta_traits::is_none};
    size_type arity{0u};
    meta_type_node (*type)(const meta_context &) noexcept {};
    meta_type (*arg)(const size_type, const meta_ctx &) noexcept {};
    bool (*set)(meta_handle, meta_any, const meta_ctx &){};
    meta_any (*get)(meta_handle, const meta_ctx &){};
    dense_map<id_type, meta_prop_node, identity> prop{};
};

struct meta_func_node {
    using size_type = std::size_t;

    meta_traits traits{meta_traits::is_none};
    size_type arity{0u};
    meta_type_node (*ret)(const meta_context &) noexcept {};
    meta_type (*arg)(const size_type, const meta_ctx &) noexcept {};
    meta_any (*invoke)(meta_handle, meta_any *const, const meta_ctx &){};
    std::shared_ptr<meta_func_node> next{};
    dense_map<id_type, meta_prop_node, identity> prop{};
};

struct meta_template_node {
    using size_type = std::size_t;

    size_type arity{0u};
    meta_type_node (*type)(const meta_context &) noexcept {};
    meta_type_node (*arg)(const size_type, const meta_context &) noexcept {};
};

struct meta_type_descriptor {
    dense_map<id_type, meta_ctor_node, identity> ctor{};
    dense_map<id_type, meta_base_node, identity> base{};
    dense_map<id_type, meta_conv_node, identity> conv{};
    dense_map<id_type, meta_data_node, identity> data{};
    dense_map<id_type, meta_func_node, identity> func{};
    dense_map<id_type, meta_prop_node, identity> prop{};
};

struct meta_type_node {
    using size_type = std::size_t;

    const type_info *info{};
    id_type id{};
    meta_traits traits{meta_traits::is_none};
    size_type size_of{0u};
    meta_type_node (*remove_pointer)(const meta_context &) noexcept {};
    meta_any (*default_constructor)(const meta_ctx &){};
    double (*conversion_helper)(void *, const void *){};
    meta_any (*from_void)(void *, const void *, const meta_ctx &){};
    meta_template_node templ{};
    meta_dtor_node dtor{};
    std::shared_ptr<meta_type_descriptor> details{};
};

template<typename Type>
meta_type_node resolve(const meta_context &) noexcept;

template<typename Type>
[[nodiscard]] meta_type_node resolve_TODO() noexcept {
    return resolve<Type>(meta_context::from(locator<meta_ctx>::value_or()));
}

template<typename... Args>
[[nodiscard]] auto meta_arg_node(type_list<Args...>, [[maybe_unused]] const std::size_t index, const meta_context &context) noexcept {
    std::size_t pos{};
    meta_type_node (*value)(const meta_context &) noexcept = nullptr;
    ((value = (pos++ == index ? &resolve<std::remove_cv_t<std::remove_reference_t<Args>>> : value)), ...);
    ENTT_ASSERT(value != nullptr, "Out of bounds");
    return value(context);
}

[[nodiscard]] inline const void *try_cast(const meta_type_node &from, const meta_type_node &to, const void *instance, const meta_context &context) noexcept {
    if(from.info && to.info && *from.info == *to.info) {
        return instance;
    }

    if(from.details) {
        for(auto &&curr: from.details->base) {
            if(const void *elem = try_cast(curr.second.type(context), to, curr.second.cast(instance), context); elem) {
                return elem;
            }
        }
    }

    return nullptr;
}

[[nodiscard]] inline const meta_type_node *try_resolve(const type_info &info, const meta_context &context) noexcept {
    const auto it = context.value.find(info.hash());
    return it != context.value.end() ? &it->second : nullptr;
}

template<typename Type>
void meta_default_constructor([[maybe_unused]] meta_type_node &node) {
    if constexpr(std::is_default_constructible_v<Type>) {
        node.default_constructor = +[](const meta_ctx &ctx) {
            // TODO it would be great if we had value and context construction support for meta_any
            meta_any elem{ctx};
            elem.emplace<Type>();
            return elem;
        };
    }
}

template<typename Type>
void meta_conversion_helper([[maybe_unused]] meta_type_node &node) {
    if constexpr(std::is_arithmetic_v<Type>) {
        node.conversion_helper = +[](void *bin, const void *value) {
            return bin ? static_cast<double>(*static_cast<Type *>(bin) = static_cast<Type>(*static_cast<const double *>(value))) : static_cast<double>(*static_cast<const Type *>(value));
        };
    } else if constexpr(std::is_enum_v<Type>) {
        node.conversion_helper = +[](void *bin, const void *value) {
            return bin ? static_cast<double>(*static_cast<Type *>(bin) = static_cast<Type>(static_cast<std::underlying_type_t<Type>>(*static_cast<const double *>(value)))) : static_cast<double>(*static_cast<const Type *>(value));
        };
    }
}

template<typename Type>
void meta_from_void([[maybe_unused]] meta_type_node &node) {
    if constexpr(!std::is_same_v<Type, void> && !std::is_function_v<Type>) {
        node.from_void = +[](void *element, const void *as_const, const meta_ctx &ctx) {
            // TODO it would be great if we had value and context construction support for meta_any
            meta_any elem{ctx};
            element ? elem.emplace<std::decay_t<Type> &>(*static_cast<std::decay_t<Type> *>(element)) : elem.emplace<const std::decay_t<Type> &>(*static_cast<const std::decay_t<Type> *>(as_const));
            return elem;
        };
    }
}

template<typename Type>
[[nodiscard]] meta_type_node resolve(const meta_context &context) noexcept {
    static_assert(std::is_same_v<Type, std::remove_const_t<std::remove_reference_t<Type>>>, "Invalid type");

    if(auto *elem = try_resolve(type_id<Type>(), context); elem) {
        return *elem;
    }

    meta_type_node node{
        &type_id<Type>(),
        type_id<Type>().hash(),
        (std::is_arithmetic_v<Type> ? meta_traits::is_arithmetic : meta_traits::is_none)
            | (std::is_integral_v<Type> ? meta_traits::is_integral : meta_traits::is_none)
            | (std::is_signed_v<Type> ? meta_traits::is_signed : meta_traits::is_none)
            | (std::is_array_v<Type> ? meta_traits::is_array : meta_traits::is_none)
            | (std::is_enum_v<Type> ? meta_traits::is_enum : meta_traits::is_none)
            | (std::is_class_v<Type> ? meta_traits::is_class : meta_traits::is_none)
            | (is_meta_pointer_like_v<Type> ? meta_traits::is_meta_pointer_like : meta_traits::is_none)
            | (is_complete_v<meta_sequence_container_traits<Type>> ? meta_traits::is_meta_sequence_container : meta_traits::is_none)
            | (is_complete_v<meta_associative_container_traits<Type>> ? meta_traits::is_meta_associative_container : meta_traits::is_none),
        size_of_v<Type>,
        &resolve<std::remove_cv_t<std::remove_pointer_t<Type>>>};

    meta_default_constructor<Type>(node);
    meta_conversion_helper<Type>(node);
    meta_from_void<Type>(node);

    if constexpr(is_complete_v<meta_template_traits<Type>>) {
        node.templ = meta_template_node{
            meta_template_traits<Type>::args_type::size,
            &resolve<typename meta_template_traits<Type>::class_type>,
            +[](const std::size_t index, const meta_context &area) noexcept { return meta_arg_node(typename meta_template_traits<Type>::args_type{}, index, area); }};
    }

    return node;
}

} // namespace internal

/**
 * Internal details not to be documented.
 * @endcond
 */

} // namespace entt

#endif
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2013, Braden McDorman
 * All Rights Reserved. Distributed under the terms of the MIT License.
 */

#include <gab/environment_2d.hpp>

using namespace gab;

environment_2d::environment_2d(const environment_2d::size_type width, const environment_2d::size_type height)
  : _width(width)
  , _height(height)
  , _next(1)
  , _environment(new environment_2d::handle_type*[_width])
{
  for(environment_2d::size_type x = 0; x < _width; ++x) {
    _environment[x] = new environment_2d::handle_type[_height];
    memset(_environment[x], 0, _height * sizeof(environment_2d::handle_type));
  }
}

environment_2d::environment_2d(const environment_2d &rhs)
  : _width(rhs._width)
  , _height(rhs._height)
  , _next(1)
  , _environment(new environment_2d::handle_type*[_width])
{
  for(environment_2d::size_type x = 0; x < _width; ++x) {
    _environment[x] = new environment_2d::handle_type[_height];
    memcpy(_environment[x], rhs._environment[x], _height * sizeof(environment_2d::handle_type));
  }
}

environment_2d::~environment_2d()
{
  for(environment_2d::size_type x = 0; x < _width; ++x) delete[] _environment[x];
  delete[] _environment;
}

environment_2d::size_type environment_2d::width() const
{
  return _width;
}

environment_2d::size_type environment_2d::height() const
{
  return _height;
}

environment_2d::size_type environment_2d::size() const
{
  return _width * _height;
}

environment_2d::handle_type environment_2d::add_type(const environment_2d::name_type &name)
{
  _types[_next] = name;
  return _next++;
}

environment_2d::hash_type environment_2d::types_hash() const
{
  // This will in theory correctly identify changes to the type map.
  // 0 is also reserved for users as a "null" value.
  return (_next << 16) | (_types.size() << 0);
}

bool environment_2d::remove_type(const environment_2d::handle_type type)
{
  type_map_type::iterator it = _types.find(type);
  if(it == _types.end()) return false;
  _types.erase(it);
  return true;
}

const environment_2d::type_map_type &environment_2d::types() const
{
  return _types;
}

const environment_2d::handle_type *environment_2d::operator[](const environment_2d::size_type x) const
{
  if(x >= _width) throw std::out_of_range("x >= width");
  return _environment[x];
}<commit_msg>Copy types and next from rhs<commit_after>/*
 * Copyright (c) 2013, Braden McDorman
 * All Rights Reserved. Distributed under the terms of the MIT License.
 */

#include <gab/environment_2d.hpp>

using namespace gab;

environment_2d::environment_2d(const environment_2d::size_type width, const environment_2d::size_type height)
  : _width(width)
  , _height(height)
  , _next(1)
  , _environment(new environment_2d::handle_type*[_width])
{
  for(environment_2d::size_type x = 0; x < _width; ++x) {
    _environment[x] = new environment_2d::handle_type[_height];
    memset(_environment[x], 0, _height * sizeof(environment_2d::handle_type));
  }
}

environment_2d::environment_2d(const environment_2d &rhs)
  : _width(rhs._width)
  , _height(rhs._height)
  , _next(rhs._next)
  , _types(rhs._types)
  , _environment(new environment_2d::handle_type*[_width])
{
  for(environment_2d::size_type x = 0; x < _width; ++x) {
    _environment[x] = new environment_2d::handle_type[_height];
    memcpy(_environment[x], rhs._environment[x], _height * sizeof(environment_2d::handle_type));
  }
}

environment_2d::~environment_2d()
{
  for(environment_2d::size_type x = 0; x < _width; ++x) delete[] _environment[x];
  delete[] _environment;
}

environment_2d::size_type environment_2d::width() const
{
  return _width;
}

environment_2d::size_type environment_2d::height() const
{
  return _height;
}

environment_2d::size_type environment_2d::size() const
{
  return _width * _height;
}

environment_2d::handle_type environment_2d::add_type(const environment_2d::name_type &name)
{
  _types[_next] = name;
  return _next++;
}

environment_2d::hash_type environment_2d::types_hash() const
{
  // This will in theory correctly identify changes to the type map.
  // 0 is also reserved for users as a "null" value.
  return (_next << 16) | (_types.size() << 0);
}

bool environment_2d::remove_type(const environment_2d::handle_type type)
{
  type_map_type::iterator it = _types.find(type);
  if(it == _types.end()) return false;
  _types.erase(it);
  return true;
}

const environment_2d::type_map_type &environment_2d::types() const
{
  return _types;
}

const environment_2d::handle_type *environment_2d::operator[](const environment_2d::size_type x) const
{
  if(x >= _width) throw std::out_of_range("x >= width");
  return _environment[x];
}<|endoftext|>