<commit_before>/** @file
    @brief Implementation

    @date 2014

    @author
    Sensics, Inc.
    <http://sensics.com/osvr>
*/

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

// Internal Includes
#include "DevicesWithParameters.h"
#include "GetSerialPortState.h"
#include <osvr/VRPNServer/VRPNDeviceRegistration.h>
#include <osvr/USBSerial/USBSerialEnum.h>

// Library/third-party includes
#include <json/reader.h>
#include <json/value.h>

#include <vrpn_YEI_3Space.h>

// Standard includes
#include <vector>
#include <memory>
#include <string>
#include <string.h>

namespace {
/// @brief Manage an array of dynamically allocated c-strings, terminated with a
/// null entry.
class CStringArray : boost::noncopyable {
  public:
    typedef std::unique_ptr<char[]> UniqueCharArray;
    void push_back(std::string const &str) {
        // Remove null terminator from array
        if (m_arrayHasNullTerminator()) {
            m_data.pop_back();
        }
        {
            const size_t stringLength = str.size() + 1;
            UniqueCharArray copy(new char[stringLength]);
            memcpy(copy.get(), str.c_str(), stringLength);
            m_dataOwnership.push_back(std::move(copy));
        }
        m_data.push_back(m_dataOwnership.back().get());
    }
    const char **get_array() {
        // Ensure null terminator on array
        if (!m_arrayHasNullTerminator()) {
            m_data.push_back(nullptr);
        }
        return m_data.data();
    }

  private:
    bool m_arrayHasNullTerminator() const {
        return !m_data.empty() && nullptr == m_data.back();
    }
    std::vector<const char *> m_data;
    std::vector<UniqueCharArray> m_dataOwnership;
};
} // namespace

void createYEI(VRPNMultiserverData &data, OSVR_PluginRegContext ctx,
               const char *params) {
    Json::Reader reader;
    Json::Value root;
    if (!reader.parse(params, root)) {
        throw std::runtime_error("Could not parse configuration: " +
                                 reader.getFormattedErrorMessages());
    }
    uint16_t vID = 0x9AC;
    uint16_t pID = 0x3F2;
    for (auto dev : osvr::usbserial::Enumerator(vID, pID)) {

        std::string port = normalizeAndVerifySerialPort(dev->getPort());

        bool calibrate_gyros_on_setup =
            root.get("calibrateGyrosOnSetup", false).asBool();
        bool tare_on_setup = root.get("tareOnSetup", false).asBool();
        double frames_per_second = root.get("framesPerSecond", 250).asFloat();

        Json::Value commands = root.get("resetCommands", Json::arrayValue);
        CStringArray reset_commands;

        for (Json::ArrayIndex i = 0, e = commands.size(); i < e; ++i) {
            reset_commands.push_back(commands[i].asString());
        }

        osvr::vrpnserver::VRPNDeviceRegistration reg(ctx);

        reg.registerDevice(new vrpn_YEI_3Space_Sensor(
            reg.useDecoratedName(data.getName("YEI_3Space_Sensor")).c_str(),
            reg.getVRPNConnection(), port.c_str(), 115200,
            calibrate_gyros_on_setup, tare_on_setup, frames_per_second, 0, 0, 1,
            0, reset_commands.get_array()));
    }
}
<commit_msg>Make constants const.<commit_after>/** @file
    @brief Implementation

    @date 2014

    @author
    Sensics, Inc.
    <http://sensics.com/osvr>
*/

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

// Internal Includes
#include "DevicesWithParameters.h"
#include "GetSerialPortState.h"
#include <osvr/VRPNServer/VRPNDeviceRegistration.h>
#include <osvr/USBSerial/USBSerialEnum.h>

// Library/third-party includes
#include <json/reader.h>
#include <json/value.h>

#include <vrpn_YEI_3Space.h>

// Standard includes
#include <vector>
#include <memory>
#include <string>
#include <string.h>

namespace {
/// @brief Manage an array of dynamically allocated c-strings, terminated with a
/// null entry.
class CStringArray : boost::noncopyable {
  public:
    typedef std::unique_ptr<char[]> UniqueCharArray;
    void push_back(std::string const &str) {
        // Remove null terminator from array
        if (m_arrayHasNullTerminator()) {
            m_data.pop_back();
        }
        {
            const size_t stringLength = str.size() + 1;
            UniqueCharArray copy(new char[stringLength]);
            memcpy(copy.get(), str.c_str(), stringLength);
            m_dataOwnership.push_back(std::move(copy));
        }
        m_data.push_back(m_dataOwnership.back().get());
    }
    const char **get_array() {
        // Ensure null terminator on array
        if (!m_arrayHasNullTerminator()) {
            m_data.push_back(nullptr);
        }
        return m_data.data();
    }

  private:
    bool m_arrayHasNullTerminator() const {
        return !m_data.empty() && nullptr == m_data.back();
    }
    std::vector<const char *> m_data;
    std::vector<UniqueCharArray> m_dataOwnership;
};
} // namespace

void createYEI(VRPNMultiserverData &data, OSVR_PluginRegContext ctx,
               const char *params) {
    Json::Reader reader;
    Json::Value root;
    if (!reader.parse(params, root)) {
        throw std::runtime_error("Could not parse configuration: " +
                                 reader.getFormattedErrorMessages());
    }
    static const uint16_t vID = 0x9AC;
    static const uint16_t pID = 0x3F2;
    for (auto dev : osvr::usbserial::Enumerator(vID, pID)) {

        std::string port = normalizeAndVerifySerialPort(dev->getPort());

        bool calibrate_gyros_on_setup =
            root.get("calibrateGyrosOnSetup", false).asBool();
        bool tare_on_setup = root.get("tareOnSetup", false).asBool();
        double frames_per_second = root.get("framesPerSecond", 250).asFloat();

        Json::Value commands = root.get("resetCommands", Json::arrayValue);
        CStringArray reset_commands;

        for (Json::ArrayIndex i = 0, e = commands.size(); i < e; ++i) {
            reset_commands.push_back(commands[i].asString());
        }

        osvr::vrpnserver::VRPNDeviceRegistration reg(ctx);

        reg.registerDevice(new vrpn_YEI_3Space_Sensor(
            reg.useDecoratedName(data.getName("YEI_3Space_Sensor")).c_str(),
            reg.getVRPNConnection(), port.c_str(), 115200,
            calibrate_gyros_on_setup, tare_on_setup, frames_per_second, 0, 0, 1,
            0, reset_commands.get_array()));
    }
}
<|endoftext|>


<commit_before>//===- IndexBody.cpp - Indexing statements --------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "IndexingContext.h"
#include "clang/AST/RecursiveASTVisitor.h"

using namespace clang;
using namespace clang::index;

namespace {

class BodyIndexer : public RecursiveASTVisitor<BodyIndexer> {
  IndexingContext &IndexCtx;
  const NamedDecl *Parent;
  const DeclContext *ParentDC;
  SmallVector<Stmt*, 16> StmtStack;

  typedef RecursiveASTVisitor<BodyIndexer> base;
public:
  BodyIndexer(IndexingContext &indexCtx,
              const NamedDecl *Parent, const DeclContext *DC)
    : IndexCtx(indexCtx), Parent(Parent), ParentDC(DC) { }

  bool shouldWalkTypesOfTypeLocs() const { return false; }

  bool dataTraverseStmtPre(Stmt *S) {
    StmtStack.push_back(S);
    return true;
  }

  bool dataTraverseStmtPost(Stmt *S) {
    assert(StmtStack.back() == S);
    StmtStack.pop_back();
    return true;
  }

  bool TraverseTypeLoc(TypeLoc TL) {
    IndexCtx.indexTypeLoc(TL, Parent, ParentDC);
    return true;
  }

  bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) {
    IndexCtx.indexNestedNameSpecifierLoc(NNS, Parent, ParentDC);
    return true;
  }

  SymbolRoleSet getRolesForRef(const Expr *E,
                               SmallVectorImpl<SymbolRelation> &Relations) {
    SymbolRoleSet Roles{};
    assert(!StmtStack.empty() && E == StmtStack.back());
    if (StmtStack.size() == 1)
      return Roles;
    auto It = StmtStack.end()-2;
    while (isa<CastExpr>(*It) || isa<ParenExpr>(*It)) {
      if (auto ICE = dyn_cast<ImplicitCastExpr>(*It)) {
        if (ICE->getCastKind() == CK_LValueToRValue)
          Roles |= (unsigned)(unsigned)SymbolRole::Read;
      }
      if (It == StmtStack.begin())
        break;
      --It;
    }
    const Stmt *Parent = *It;

    if (auto BO = dyn_cast<BinaryOperator>(Parent)) {
      if (BO->getOpcode() == BO_Assign && BO->getLHS()->IgnoreParenCasts() == E)
        Roles |= (unsigned)SymbolRole::Write;

    } else if (auto UO = dyn_cast<UnaryOperator>(Parent)) {
      if (UO->isIncrementDecrementOp()) {
        Roles |= (unsigned)SymbolRole::Read;
        Roles |= (unsigned)SymbolRole::Write;
      } else if (UO->getOpcode() == UO_AddrOf) {
        Roles |= (unsigned)SymbolRole::AddressOf;
      }

    } else if (auto CA = dyn_cast<CompoundAssignOperator>(Parent)) {
      if (CA->getLHS()->IgnoreParenCasts() == E) {
        Roles |= (unsigned)SymbolRole::Read;
        Roles |= (unsigned)SymbolRole::Write;
      }

    } else if (auto CE = dyn_cast<CallExpr>(Parent)) {
      if (CE->getCallee()->IgnoreParenCasts() == E) {
        addCallRole(Roles, Relations);
        if (auto *ME = dyn_cast<MemberExpr>(E)) {
          if (auto *CXXMD = dyn_cast_or_null<CXXMethodDecl>(ME->getMemberDecl()))
            if (CXXMD->isVirtual() && !ME->hasQualifier()) {
              Roles |= (unsigned)SymbolRole::Dynamic;
              auto BaseTy = ME->getBase()->IgnoreImpCasts()->getType();
              if (!BaseTy.isNull())
                if (auto *CXXRD = BaseTy->getPointeeCXXRecordDecl())
                  Relations.emplace_back((unsigned)SymbolRole::RelationReceivedBy,
                                         CXXRD);
            }
        }
      } else if (auto CXXOp = dyn_cast<CXXOperatorCallExpr>(CE)) {
        if (CXXOp->getNumArgs() > 0 && CXXOp->getArg(0)->IgnoreParenCasts() == E) {
          OverloadedOperatorKind Op = CXXOp->getOperator();
          if (Op == OO_Equal) {
            Roles |= (unsigned)SymbolRole::Write;
          } else if ((Op >= OO_PlusEqual && Op <= OO_PipeEqual) ||
                     Op == OO_LessLessEqual || Op == OO_GreaterGreaterEqual ||
                     Op == OO_PlusPlus || Op == OO_MinusMinus) {
            Roles |= (unsigned)SymbolRole::Read;
            Roles |= (unsigned)SymbolRole::Write;
          } else if (Op == OO_Amp) {
            Roles |= (unsigned)SymbolRole::AddressOf;
          }
        }
      }
    }

    return Roles;
  }

  void addCallRole(SymbolRoleSet &Roles,
                   SmallVectorImpl<SymbolRelation> &Relations) {
    Roles |= (unsigned)SymbolRole::Call;
    if (auto *FD = dyn_cast<FunctionDecl>(ParentDC))
      Relations.emplace_back((unsigned)SymbolRole::RelationCalledBy, FD);
    else if (auto *MD = dyn_cast<ObjCMethodDecl>(ParentDC))
      Relations.emplace_back((unsigned)SymbolRole::RelationCalledBy, MD);
  }

  bool VisitDeclRefExpr(DeclRefExpr *E) {
    SmallVector<SymbolRelation, 4> Relations;
    SymbolRoleSet Roles = getRolesForRef(E, Relations);
    return IndexCtx.handleReference(E->getDecl(), E->getLocation(),
                                    Parent, ParentDC, Roles, Relations, E);
  }

  bool VisitMemberExpr(MemberExpr *E) {
    SourceLocation Loc = E->getMemberLoc();
    if (Loc.isInvalid())
      Loc = E->getLocStart();
    SmallVector<SymbolRelation, 4> Relations;
    SymbolRoleSet Roles = getRolesForRef(E, Relations);
    return IndexCtx.handleReference(E->getMemberDecl(), Loc,
                                    Parent, ParentDC, Roles, Relations, E);
  }

  bool VisitDesignatedInitExpr(DesignatedInitExpr *E) {
    for (DesignatedInitExpr::Designator &D : llvm::reverse(E->designators())) {
      if (D.isFieldDesignator() && D.getField())
        return IndexCtx.handleReference(D.getField(), D.getFieldLoc(), Parent,
                                        ParentDC, SymbolRoleSet(), {}, E);
    }
    return true;
  }

  bool VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
    SmallVector<SymbolRelation, 4> Relations;
    SymbolRoleSet Roles = getRolesForRef(E, Relations);
    return IndexCtx.handleReference(E->getDecl(), E->getLocation(),
                                    Parent, ParentDC, Roles, Relations, E);
  }

  bool VisitObjCMessageExpr(ObjCMessageExpr *E) {
    auto isDynamic = [](const ObjCMessageExpr *MsgE)->bool {
      if (MsgE->getReceiverKind() != ObjCMessageExpr::Instance)
        return false;
      if (auto *RecE = dyn_cast<ObjCMessageExpr>(
              MsgE->getInstanceReceiver()->IgnoreParenCasts())) {
        if (RecE->getMethodFamily() == OMF_alloc)
          return false;
      }
      return true;
    };

    if (ObjCMethodDecl *MD = E->getMethodDecl()) {
      SymbolRoleSet Roles{};
      SmallVector<SymbolRelation, 2> Relations;
      addCallRole(Roles, Relations);
      if (E->isImplicit())
        Roles |= (unsigned)SymbolRole::Implicit;

      if (isDynamic(E)) {
        Roles |= (unsigned)SymbolRole::Dynamic;
        if (auto *RecD = E->getReceiverInterface())
          Relations.emplace_back((unsigned)SymbolRole::RelationReceivedBy, RecD);
      }

      return IndexCtx.handleReference(MD, E->getSelectorStartLoc(),
                                      Parent, ParentDC, Roles, Relations, E);
    }
    return true;
  }

  bool VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
    if (E->isExplicitProperty())
      return IndexCtx.handleReference(E->getExplicitProperty(), E->getLocation(),
                                      Parent, ParentDC, SymbolRoleSet(), {}, E);

    // No need to do a handleReference for the objc method, because there will
    // be a message expr as part of PseudoObjectExpr.
    return true;
  }

  bool VisitMSPropertyRefExpr(MSPropertyRefExpr *E) {
    return IndexCtx.handleReference(E->getPropertyDecl(), E->getMemberLoc(),
                                    Parent, ParentDC, SymbolRoleSet(), {}, E);
  }

  bool VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
    return IndexCtx.handleReference(E->getProtocol(), E->getProtocolIdLoc(),
                                    Parent, ParentDC, SymbolRoleSet(), {}, E);
  }

  bool passObjCLiteralMethodCall(const ObjCMethodDecl *MD, const Expr *E) {
    SymbolRoleSet Roles{};
    SmallVector<SymbolRelation, 2> Relations;
    addCallRole(Roles, Relations);
    Roles |= (unsigned)SymbolRole::Implicit;
    return IndexCtx.handleReference(MD, E->getLocStart(),
                                    Parent, ParentDC, Roles, Relations, E);
  }

  bool VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
    if (ObjCMethodDecl *MD = E->getBoxingMethod()) {
      return passObjCLiteralMethodCall(MD, E);
    }
    return true;
  }

  bool VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
    if (ObjCMethodDecl *MD = E->getDictWithObjectsMethod()) {
      return passObjCLiteralMethodCall(MD, E);
    }
    return true;
  }

  bool VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
    if (ObjCMethodDecl *MD = E->getArrayWithObjectsMethod()) {
      return passObjCLiteralMethodCall(MD, E);
    }
    return true;
  }

  bool VisitCXXConstructExpr(CXXConstructExpr *E) {
    SymbolRoleSet Roles{};
    SmallVector<SymbolRelation, 2> Relations;
    addCallRole(Roles, Relations);
    return IndexCtx.handleReference(E->getConstructor(), E->getLocation(),
                                    Parent, ParentDC, Roles, Relations, E);
  }

  bool TraverseCXXOperatorCallExpr(CXXOperatorCallExpr *E,
                                   DataRecursionQueue *Q = nullptr) {
    if (E->getOperatorLoc().isInvalid())
      return true; // implicit.
    return base::TraverseCXXOperatorCallExpr(E, Q);
  }

  bool VisitDeclStmt(DeclStmt *S) {
    if (IndexCtx.shouldIndexFunctionLocalSymbols()) {
      IndexCtx.indexDeclGroupRef(S->getDeclGroup());
      return true;
    }

    DeclGroupRef DG = S->getDeclGroup();
    for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I) {
      const Decl *D = *I;
      if (!D)
        continue;
      if (!IndexCtx.isFunctionLocalDecl(D))
        IndexCtx.indexTopLevelDecl(D);
    }

    return true;
  }

  bool TraverseLambdaCapture(LambdaExpr *LE, const LambdaCapture *C) {
    if (C->capturesThis() || C->capturesVLAType())
      return true;

    if (C->capturesVariable() && IndexCtx.shouldIndexFunctionLocalSymbols())
      return IndexCtx.handleReference(C->getCapturedVar(), C->getLocation(),
                                      Parent, ParentDC, SymbolRoleSet());

    // FIXME: Lambda init-captures.
    return true;
  }

  // RecursiveASTVisitor visits both syntactic and semantic forms, duplicating
  // the things that we visit. Make sure to only visit the semantic form.
  // Also visit things that are in the syntactic form but not the semantic one,
  // for example the indices in DesignatedInitExprs.
  bool TraverseInitListExpr(InitListExpr *S, DataRecursionQueue *Q = nullptr) {

    class SyntacticFormIndexer :
              public RecursiveASTVisitor<SyntacticFormIndexer> {
      IndexingContext &IndexCtx;
      const NamedDecl *Parent;
      const DeclContext *ParentDC;
      bool Visited = false;

    public:
      SyntacticFormIndexer(IndexingContext &indexCtx,
                            const NamedDecl *Parent, const DeclContext *DC)
        : IndexCtx(indexCtx), Parent(Parent), ParentDC(DC) { }

      bool shouldWalkTypesOfTypeLocs() const { return false; }

      bool TraverseInitListExpr(InitListExpr *S, DataRecursionQueue *Q = nullptr) {
        // Don't visit nested InitListExprs, this visitor will be called again
        // later on for the nested ones.
        if (Visited)
          return true;
        Visited = true;
        InitListExpr *SyntaxForm = S->isSemanticForm() ? S->getSyntacticForm() : S;
        if (SyntaxForm) {
          for (Stmt *SubStmt : SyntaxForm->children()) {
            if (!TraverseStmt(SubStmt, Q))
              return false;
          }
        }
        return true;
      }

      bool VisitDesignatedInitExpr(DesignatedInitExpr *E) {
        for (DesignatedInitExpr::Designator &D : llvm::reverse(E->designators())) {
          if (D.isFieldDesignator())
            return IndexCtx.handleReference(D.getField(), D.getFieldLoc(),
                                            Parent, ParentDC, SymbolRoleSet(),
                                            {}, E);
        }
        return true;
      }
    };

    auto visitForm = [&](InitListExpr *Form) {
      for (Stmt *SubStmt : Form->children()) {
        if (!TraverseStmt(SubStmt, Q))
          return false;
      }
      return true;
    };

    InitListExpr *SemaForm = S->isSemanticForm() ? S : S->getSemanticForm();
    InitListExpr *SyntaxForm = S->isSemanticForm() ? S->getSyntacticForm() : S;

    if (SemaForm) {
      // Visit things present in syntactic form but not the semantic form.
      if (SyntaxForm) {
        SyntacticFormIndexer(IndexCtx, Parent, ParentDC).TraverseStmt(SyntaxForm);
      }
      return visitForm(SemaForm);
    }

    // No semantic, try the syntactic.
    if (SyntaxForm) {
      return visitForm(SyntaxForm);
    }

    return true;
  }
};

} // anonymous namespace

void IndexingContext::indexBody(const Stmt *S, const NamedDecl *Parent,
                                const DeclContext *DC) {
  if (!S)
    return;

  if (!DC)
    DC = Parent->getLexicalDeclContext();
  BodyIndexer(*this, Parent, DC).TraverseStmt(const_cast<Stmt*>(S));
}
<commit_msg>[index] Avoid using a RecursiveASTVisitor for SyntacticFormIndexer and iterate the DesignatedInitExprs of the InitListExpr directly.<commit_after>//===- IndexBody.cpp - Indexing statements --------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "IndexingContext.h"
#include "clang/AST/RecursiveASTVisitor.h"

using namespace clang;
using namespace clang::index;

namespace {

class BodyIndexer : public RecursiveASTVisitor<BodyIndexer> {
  IndexingContext &IndexCtx;
  const NamedDecl *Parent;
  const DeclContext *ParentDC;
  SmallVector<Stmt*, 16> StmtStack;

  typedef RecursiveASTVisitor<BodyIndexer> base;
public:
  BodyIndexer(IndexingContext &indexCtx,
              const NamedDecl *Parent, const DeclContext *DC)
    : IndexCtx(indexCtx), Parent(Parent), ParentDC(DC) { }

  bool shouldWalkTypesOfTypeLocs() const { return false; }

  bool dataTraverseStmtPre(Stmt *S) {
    StmtStack.push_back(S);
    return true;
  }

  bool dataTraverseStmtPost(Stmt *S) {
    assert(StmtStack.back() == S);
    StmtStack.pop_back();
    return true;
  }

  bool TraverseTypeLoc(TypeLoc TL) {
    IndexCtx.indexTypeLoc(TL, Parent, ParentDC);
    return true;
  }

  bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) {
    IndexCtx.indexNestedNameSpecifierLoc(NNS, Parent, ParentDC);
    return true;
  }

  SymbolRoleSet getRolesForRef(const Expr *E,
                               SmallVectorImpl<SymbolRelation> &Relations) {
    SymbolRoleSet Roles{};
    assert(!StmtStack.empty() && E == StmtStack.back());
    if (StmtStack.size() == 1)
      return Roles;
    auto It = StmtStack.end()-2;
    while (isa<CastExpr>(*It) || isa<ParenExpr>(*It)) {
      if (auto ICE = dyn_cast<ImplicitCastExpr>(*It)) {
        if (ICE->getCastKind() == CK_LValueToRValue)
          Roles |= (unsigned)(unsigned)SymbolRole::Read;
      }
      if (It == StmtStack.begin())
        break;
      --It;
    }
    const Stmt *Parent = *It;

    if (auto BO = dyn_cast<BinaryOperator>(Parent)) {
      if (BO->getOpcode() == BO_Assign && BO->getLHS()->IgnoreParenCasts() == E)
        Roles |= (unsigned)SymbolRole::Write;

    } else if (auto UO = dyn_cast<UnaryOperator>(Parent)) {
      if (UO->isIncrementDecrementOp()) {
        Roles |= (unsigned)SymbolRole::Read;
        Roles |= (unsigned)SymbolRole::Write;
      } else if (UO->getOpcode() == UO_AddrOf) {
        Roles |= (unsigned)SymbolRole::AddressOf;
      }

    } else if (auto CA = dyn_cast<CompoundAssignOperator>(Parent)) {
      if (CA->getLHS()->IgnoreParenCasts() == E) {
        Roles |= (unsigned)SymbolRole::Read;
        Roles |= (unsigned)SymbolRole::Write;
      }

    } else if (auto CE = dyn_cast<CallExpr>(Parent)) {
      if (CE->getCallee()->IgnoreParenCasts() == E) {
        addCallRole(Roles, Relations);
        if (auto *ME = dyn_cast<MemberExpr>(E)) {
          if (auto *CXXMD = dyn_cast_or_null<CXXMethodDecl>(ME->getMemberDecl()))
            if (CXXMD->isVirtual() && !ME->hasQualifier()) {
              Roles |= (unsigned)SymbolRole::Dynamic;
              auto BaseTy = ME->getBase()->IgnoreImpCasts()->getType();
              if (!BaseTy.isNull())
                if (auto *CXXRD = BaseTy->getPointeeCXXRecordDecl())
                  Relations.emplace_back((unsigned)SymbolRole::RelationReceivedBy,
                                         CXXRD);
            }
        }
      } else if (auto CXXOp = dyn_cast<CXXOperatorCallExpr>(CE)) {
        if (CXXOp->getNumArgs() > 0 && CXXOp->getArg(0)->IgnoreParenCasts() == E) {
          OverloadedOperatorKind Op = CXXOp->getOperator();
          if (Op == OO_Equal) {
            Roles |= (unsigned)SymbolRole::Write;
          } else if ((Op >= OO_PlusEqual && Op <= OO_PipeEqual) ||
                     Op == OO_LessLessEqual || Op == OO_GreaterGreaterEqual ||
                     Op == OO_PlusPlus || Op == OO_MinusMinus) {
            Roles |= (unsigned)SymbolRole::Read;
            Roles |= (unsigned)SymbolRole::Write;
          } else if (Op == OO_Amp) {
            Roles |= (unsigned)SymbolRole::AddressOf;
          }
        }
      }
    }

    return Roles;
  }

  void addCallRole(SymbolRoleSet &Roles,
                   SmallVectorImpl<SymbolRelation> &Relations) {
    Roles |= (unsigned)SymbolRole::Call;
    if (auto *FD = dyn_cast<FunctionDecl>(ParentDC))
      Relations.emplace_back((unsigned)SymbolRole::RelationCalledBy, FD);
    else if (auto *MD = dyn_cast<ObjCMethodDecl>(ParentDC))
      Relations.emplace_back((unsigned)SymbolRole::RelationCalledBy, MD);
  }

  bool VisitDeclRefExpr(DeclRefExpr *E) {
    SmallVector<SymbolRelation, 4> Relations;
    SymbolRoleSet Roles = getRolesForRef(E, Relations);
    return IndexCtx.handleReference(E->getDecl(), E->getLocation(),
                                    Parent, ParentDC, Roles, Relations, E);
  }

  bool VisitMemberExpr(MemberExpr *E) {
    SourceLocation Loc = E->getMemberLoc();
    if (Loc.isInvalid())
      Loc = E->getLocStart();
    SmallVector<SymbolRelation, 4> Relations;
    SymbolRoleSet Roles = getRolesForRef(E, Relations);
    return IndexCtx.handleReference(E->getMemberDecl(), Loc,
                                    Parent, ParentDC, Roles, Relations, E);
  }

  bool VisitDesignatedInitExpr(DesignatedInitExpr *E) {
    for (DesignatedInitExpr::Designator &D : llvm::reverse(E->designators())) {
      if (D.isFieldDesignator() && D.getField())
        return IndexCtx.handleReference(D.getField(), D.getFieldLoc(), Parent,
                                        ParentDC, SymbolRoleSet(), {}, E);
    }
    return true;
  }

  bool VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
    SmallVector<SymbolRelation, 4> Relations;
    SymbolRoleSet Roles = getRolesForRef(E, Relations);
    return IndexCtx.handleReference(E->getDecl(), E->getLocation(),
                                    Parent, ParentDC, Roles, Relations, E);
  }

  bool VisitObjCMessageExpr(ObjCMessageExpr *E) {
    auto isDynamic = [](const ObjCMessageExpr *MsgE)->bool {
      if (MsgE->getReceiverKind() != ObjCMessageExpr::Instance)
        return false;
      if (auto *RecE = dyn_cast<ObjCMessageExpr>(
              MsgE->getInstanceReceiver()->IgnoreParenCasts())) {
        if (RecE->getMethodFamily() == OMF_alloc)
          return false;
      }
      return true;
    };

    if (ObjCMethodDecl *MD = E->getMethodDecl()) {
      SymbolRoleSet Roles{};
      SmallVector<SymbolRelation, 2> Relations;
      addCallRole(Roles, Relations);
      if (E->isImplicit())
        Roles |= (unsigned)SymbolRole::Implicit;

      if (isDynamic(E)) {
        Roles |= (unsigned)SymbolRole::Dynamic;
        if (auto *RecD = E->getReceiverInterface())
          Relations.emplace_back((unsigned)SymbolRole::RelationReceivedBy, RecD);
      }

      return IndexCtx.handleReference(MD, E->getSelectorStartLoc(),
                                      Parent, ParentDC, Roles, Relations, E);
    }
    return true;
  }

  bool VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
    if (E->isExplicitProperty())
      return IndexCtx.handleReference(E->getExplicitProperty(), E->getLocation(),
                                      Parent, ParentDC, SymbolRoleSet(), {}, E);

    // No need to do a handleReference for the objc method, because there will
    // be a message expr as part of PseudoObjectExpr.
    return true;
  }

  bool VisitMSPropertyRefExpr(MSPropertyRefExpr *E) {
    return IndexCtx.handleReference(E->getPropertyDecl(), E->getMemberLoc(),
                                    Parent, ParentDC, SymbolRoleSet(), {}, E);
  }

  bool VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
    return IndexCtx.handleReference(E->getProtocol(), E->getProtocolIdLoc(),
                                    Parent, ParentDC, SymbolRoleSet(), {}, E);
  }

  bool passObjCLiteralMethodCall(const ObjCMethodDecl *MD, const Expr *E) {
    SymbolRoleSet Roles{};
    SmallVector<SymbolRelation, 2> Relations;
    addCallRole(Roles, Relations);
    Roles |= (unsigned)SymbolRole::Implicit;
    return IndexCtx.handleReference(MD, E->getLocStart(),
                                    Parent, ParentDC, Roles, Relations, E);
  }

  bool VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
    if (ObjCMethodDecl *MD = E->getBoxingMethod()) {
      return passObjCLiteralMethodCall(MD, E);
    }
    return true;
  }

  bool VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
    if (ObjCMethodDecl *MD = E->getDictWithObjectsMethod()) {
      return passObjCLiteralMethodCall(MD, E);
    }
    return true;
  }

  bool VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
    if (ObjCMethodDecl *MD = E->getArrayWithObjectsMethod()) {
      return passObjCLiteralMethodCall(MD, E);
    }
    return true;
  }

  bool VisitCXXConstructExpr(CXXConstructExpr *E) {
    SymbolRoleSet Roles{};
    SmallVector<SymbolRelation, 2> Relations;
    addCallRole(Roles, Relations);
    return IndexCtx.handleReference(E->getConstructor(), E->getLocation(),
                                    Parent, ParentDC, Roles, Relations, E);
  }

  bool TraverseCXXOperatorCallExpr(CXXOperatorCallExpr *E,
                                   DataRecursionQueue *Q = nullptr) {
    if (E->getOperatorLoc().isInvalid())
      return true; // implicit.
    return base::TraverseCXXOperatorCallExpr(E, Q);
  }

  bool VisitDeclStmt(DeclStmt *S) {
    if (IndexCtx.shouldIndexFunctionLocalSymbols()) {
      IndexCtx.indexDeclGroupRef(S->getDeclGroup());
      return true;
    }

    DeclGroupRef DG = S->getDeclGroup();
    for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I) {
      const Decl *D = *I;
      if (!D)
        continue;
      if (!IndexCtx.isFunctionLocalDecl(D))
        IndexCtx.indexTopLevelDecl(D);
    }

    return true;
  }

  bool TraverseLambdaCapture(LambdaExpr *LE, const LambdaCapture *C) {
    if (C->capturesThis() || C->capturesVLAType())
      return true;

    if (C->capturesVariable() && IndexCtx.shouldIndexFunctionLocalSymbols())
      return IndexCtx.handleReference(C->getCapturedVar(), C->getLocation(),
                                      Parent, ParentDC, SymbolRoleSet());

    // FIXME: Lambda init-captures.
    return true;
  }

  // RecursiveASTVisitor visits both syntactic and semantic forms, duplicating
  // the things that we visit. Make sure to only visit the semantic form.
  // Also visit things that are in the syntactic form but not the semantic one,
  // for example the indices in DesignatedInitExprs.
  bool TraverseInitListExpr(InitListExpr *S, DataRecursionQueue *Q = nullptr) {
    auto visitForm = [&](InitListExpr *Form) {
      for (Stmt *SubStmt : Form->children()) {
        if (!TraverseStmt(SubStmt, Q))
          return false;
      }
      return true;
    };

    auto visitSyntacticDesignatedInitExpr = [&](DesignatedInitExpr *E) -> bool {
      for (DesignatedInitExpr::Designator &D : llvm::reverse(E->designators())) {
        if (D.isFieldDesignator())
          return IndexCtx.handleReference(D.getField(), D.getFieldLoc(),
                                          Parent, ParentDC, SymbolRoleSet(),
                                          {}, E);
      }
      return true;
    };

    InitListExpr *SemaForm = S->isSemanticForm() ? S : S->getSemanticForm();
    InitListExpr *SyntaxForm = S->isSemanticForm() ? S->getSyntacticForm() : S;

    if (SemaForm) {
      // Visit things present in syntactic form but not the semantic form.
      if (SyntaxForm) {
        for (Expr *init : SyntaxForm->inits()) {
          if (auto *DIE = dyn_cast<DesignatedInitExpr>(init))
            visitSyntacticDesignatedInitExpr(DIE);
        }
      }
      return visitForm(SemaForm);
    }

    // No semantic, try the syntactic.
    if (SyntaxForm) {
      return visitForm(SyntaxForm);
    }

    return true;
  }
};

} // anonymous namespace

void IndexingContext::indexBody(const Stmt *S, const NamedDecl *Parent,
                                const DeclContext *DC) {
  if (!S)
    return;

  if (!DC)
    DC = Parent->getLexicalDeclContext();
  BodyIndexer(*this, Parent, DC).TraverseStmt(const_cast<Stmt*>(S));
}
<|endoftext|>


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

#include "SurgSim/Devices/ReplayPoseDevice/ReplayPoseDevice.h"

#include "SurgSim/Devices/ReplayPoseDevice/ReplayPoseScaffold.h"
#include "SurgSim/Framework/Assert.h"

namespace SurgSim
{
namespace Devices
{

SURGSIM_REGISTER(SurgSim::Input::DeviceInterface, SurgSim::Devices::ReplayPoseDevice, ReplayPoseDevice);

ReplayPoseDevice::ReplayPoseDevice(const std::string& uniqueName) :
	SurgSim::Input::CommonDevice(uniqueName, ReplayPoseScaffold::buildDeviceInputData()),
	m_fileName("ReplayPoseDevice.txt")
{
}

ReplayPoseDevice::~ReplayPoseDevice()
{
	if (isInitialized())
	{
		finalize();
	}
}

const std::string ReplayPoseDevice::getFileName() const
{
	return m_fileName;
}

void ReplayPoseDevice::setFileName(const std::string& fileName)
{
	SURGSIM_ASSERT(!isInitialized()) << "The filename can only be set before initialization";
	m_fileName = fileName;
}

double ReplayPoseDevice::getRate() const
{
	return m_rate;
}

void ReplayPoseDevice::setRate(double rate)
{
	SURGSIM_ASSERT(!isInitialized()) << "The rate can only be set before initialization";
	m_rate = rate;
}

bool ReplayPoseDevice::initialize()
{
	SURGSIM_ASSERT(!isInitialized()) << getName() << " already initialized.";
	std::shared_ptr<ReplayPoseScaffold> scaffold = ReplayPoseScaffold::getOrCreateSharedInstance();
	SURGSIM_ASSERT(scaffold);

	scaffold->setRate(m_rate);

	if (!scaffold->registerDevice(this))
	{
		return false;
	}
	m_scaffold = std::move(scaffold);

	return true;
}

bool ReplayPoseDevice::finalize()
{
	SURGSIM_ASSERT(isInitialized()) << getName() << " is not initialized, cannot finalize.";
	bool ok = m_scaffold->unregisterDevice();
	m_scaffold.reset();
	return ok;
}

bool ReplayPoseDevice::isInitialized() const
{
	return (m_scaffold != nullptr);
}

};  // namespace Devices
};  // namespace SurgSim
<commit_msg>Make ReplayPoseDevice rate 1KHz by default<commit_after>// This file is a part of the OpenSurgSim project.
// Copyright 2013-2015, SimQuest Solutions Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "SurgSim/Devices/ReplayPoseDevice/ReplayPoseDevice.h"

#include "SurgSim/Devices/ReplayPoseDevice/ReplayPoseScaffold.h"
#include "SurgSim/Framework/Assert.h"

namespace SurgSim
{
namespace Devices
{

SURGSIM_REGISTER(SurgSim::Input::DeviceInterface, SurgSim::Devices::ReplayPoseDevice, ReplayPoseDevice);

ReplayPoseDevice::ReplayPoseDevice(const std::string& uniqueName) :
	SurgSim::Input::CommonDevice(uniqueName, ReplayPoseScaffold::buildDeviceInputData()),
	m_fileName("ReplayPoseDevice.txt"),
	m_rate(1000.0)
{
}

ReplayPoseDevice::~ReplayPoseDevice()
{
	if (isInitialized())
	{
		finalize();
	}
}

const std::string ReplayPoseDevice::getFileName() const
{
	return m_fileName;
}

void ReplayPoseDevice::setFileName(const std::string& fileName)
{
	SURGSIM_ASSERT(!isInitialized()) << "The filename can only be set before initialization";
	m_fileName = fileName;
}

double ReplayPoseDevice::getRate() const
{
	return m_rate;
}

void ReplayPoseDevice::setRate(double rate)
{
	SURGSIM_ASSERT(!isInitialized()) << "The rate can only be set before initialization";
	m_rate = rate;
}

bool ReplayPoseDevice::initialize()
{
	SURGSIM_ASSERT(!isInitialized()) << getName() << " already initialized.";
	std::shared_ptr<ReplayPoseScaffold> scaffold = ReplayPoseScaffold::getOrCreateSharedInstance();
	SURGSIM_ASSERT(scaffold);

	scaffold->setRate(m_rate);

	if (!scaffold->registerDevice(this))
	{
		return false;
	}
	m_scaffold = std::move(scaffold);

	return true;
}

bool ReplayPoseDevice::finalize()
{
	SURGSIM_ASSERT(isInitialized()) << getName() << " is not initialized, cannot finalize.";
	bool ok = m_scaffold->unregisterDevice();
	m_scaffold.reset();
	return ok;
}

bool ReplayPoseDevice::isInitialized() const
{
	return (m_scaffold != nullptr);
}

};  // namespace Devices
};  // namespace SurgSim
<|endoftext|>


<commit_before>// Copyright (C) 1999-2018
// Smithsonian Astrophysical Observatory, Cambridge, MA, USA
// For conditions of distribution and use, see copyright notice in "copyright"

#include <tk.h>

#include "basepolygon.h"
#include "fitsimage.h"

BasePolygon::BasePolygon(Base* p, const Vector& ctr,
			 const Vector& b)
  : Marker(p, ctr, 0)
{
}

BasePolygon::BasePolygon(Base* p, const Vector& ctr,
		 const Vector& b,
		 const char* clr, int* dsh,
		 int wth, const char* fnt, const char* txt,
		 unsigned short prop, const char* cmt,
		 const List<Tag>& tg, const List<CallBack>& cb)
  : Marker(p, ctr, 0, clr, dsh, wth, fnt, txt, prop, cmt, tg, cb)
{
}

BasePolygon::BasePolygon(Base* p, const List<Vertex>& v,
		 const char* clr, int* dsh,
		 int wth, const char* fnt, const char* txt,
		 unsigned short prop, const char* cmt,
		 const List<Tag>& tg, const List<CallBack>& cb)
  : Marker(p, Vector(0,0), 0, clr, dsh, wth, fnt, txt, prop, cmt, tg, cb)
{
  // Vertex list is in ref coords
  angle = 0;
  vertex = v;

  // find center
  center = Vector(0,0);
  vertex.head();
  do
    center += vertex.current()->vector;
  while (vertex.next());
  center /= vertex.count();

  // vertices are relative
  vertex.head();
  do
    vertex.current()->vector *= Translate(-center) * FlipY(); // no rotation
  while (vertex.next());

  updateBBox();
}

BasePolygon::BasePolygon(const BasePolygon& a) : Marker(a)
{
  vertex = a.vertex;
}

void BasePolygon::createVertex(int which, const Vector& v)
{
  // which segment (1 to n)
  // v is in ref coords
  Matrix mm = bckMatrix();

  int seg = which-1;
  if (seg>=0 && seg<vertex.count()) {
    Vertex* n = new Vertex(v * mm);
    vertex.insert(seg,n);

    recalcCenter();

    updateBBox();
    doCallBack(CallBack::EDITCB);
    doCallBack(CallBack::MOVECB); // center can change
  }
}

void BasePolygon::deleteVertex(int h)
{
  if (h>4) {
    int hh = h-4-1;

    if (vertex.count() > 3) {
      Vertex* v = vertex[hh];
      if (v) {
	vertex.extractNext(v);
	delete v;

	recalcCenter();

	updateBBox();
	doCallBack(CallBack::EDITCB);
	doCallBack(CallBack::MOVECB); // center can change
      }
    }
  }
}

void BasePolygon::edit(const Vector& v, int h)
{
  if (h < 5) {
    Vector s1 = v * bckMatrix();
    Vector s2 = bckMap(handle[h-1],Coord::CANVAS);

    if (s1[0] != 0 && s1[1] != 0 && s2[0] != 0 && s2[1] != 0) {
      double a = fabs(s1[0]/s2[0]);
      double b = fabs(s1[1]/s2[1]);
      double s = a > b ? a : b;

      vertex.head();
      do
	vertex.current()->vector *= Scale(s);
      while (vertex.next());
    }

    updateBBox();
    doCallBack(CallBack::EDITCB);
  }
  else {
    moveVertex(v,h);

    updateBBox();
    doCallBack(CallBack::EDITCB);
    doCallBack(CallBack::MOVECB); // center can change
  }
}

void BasePolygon::moveVertex(const Vector& v, int h)
{
  Matrix mm = bckMatrix();

  if (vertex[h-5])
    vertex.current()->vector = v * mm;

  recalcCenter();
}

void BasePolygon::recalcCenter()
{
  // recalculate center

  Vector nc;
  vertex.head();
  do
    nc += vertex.current()->vector * Rotate(angle) * FlipY();
  while (vertex.next());
  nc /= vertex.count();

  center += nc;

  // update all vertices

  vertex.head();
  do
    vertex.current()->vector -= nc * FlipY() * Rotate(-angle);
  while (vertex.next());
}

void BasePolygon::rotate(const Vector& v, int h)
{
  if (h < 5)
    Marker::rotate(v,h);
  else {
    // we need to check this here, because we are really rotating
    if (canEdit()) {
      moveVertex(v,h);

      updateBBox();
      doCallBack(CallBack::EDITCB);
      doCallBack(CallBack::MOVECB); // center can change
    }
  }
}

void BasePolygon::updateHandles()
{
  // generate handles
  numHandle = 4 + vertex.count();
  if (handle)
    delete [] handle;
  handle = new Vector[numHandle];

  // the first four are our control handles
  BBox bb;
  vertex.head();
  do
    bb.bound(vertex.current()->vector);
  while (vertex.next());

  Vector zz = parent->zoom();
  float r = 10/zz.length();
  bb.expand(r); // give us more room

  handle[0] = fwdMap(bb.ll,Coord::CANVAS);
  handle[1] = fwdMap(bb.lr(),Coord::CANVAS);
  handle[2] = fwdMap(bb.ur,Coord::CANVAS);
  handle[3] = fwdMap(bb.ul(),Coord::CANVAS);

  // and the rest are vertices
  int i=4;
  vertex.head();
  do
    handle[i++] = fwdMap(vertex.current()->vector,Coord::CANVAS);
  while (vertex.next());
}

void BasePolygon::updateCoords(const Matrix& mx)
{
  Scale s(mx);
  vertex.head();
  do
    vertex.current()->vector *= s;
  while (vertex.next());

  Marker::updateCoords(mx);
}

void BasePolygon::listBase(FitsImage* ptr, ostream& str,
			   Coord::CoordSystem sys, Coord::SkyFrame sky,
			   Coord::SkyFormat format)
{
  Matrix mm = fwdMatrix();
  switch (sys) {
  case Coord::IMAGE:
  case Coord::PHYSICAL:
  case Coord::DETECTOR:
  case Coord::AMPLIFIER:
    {
      str << type_ << '(';
      int first=1;
      vertex.head();
      do {
	if (!first)
	  str << ',';
	first=0;

	Vector vv = ptr->mapFromRef(vertex.current()->vector*mm,sys);
	str << setprecision(parent->precLinear_) << vv;
      }
      while (vertex.next());
      str << ')';
    }
    break;
  default:
    {
      str << type_ << '(';
      int first=1;
      vertex.head();
      do {
	if (!first)
	  str << ',';
	first=0;

	listWCS(ptr,vertex.current()->vector*mm,sys,sky,format);
	str << ra << ',' << dec;
      }
      while (vertex.next());
      str << ')';
    }
  }
}

<commit_msg>simplify marker code<commit_after>// Copyright (C) 1999-2018
// Smithsonian Astrophysical Observatory, Cambridge, MA, USA
// For conditions of distribution and use, see copyright notice in "copyright"

#include <tk.h>

#include "basepolygon.h"
#include "fitsimage.h"

BasePolygon::BasePolygon(Base* p, const Vector& ctr,
			 const Vector& b)
  : Marker(p, ctr, 0)
{
}

BasePolygon::BasePolygon(Base* p, const Vector& ctr,
		 const Vector& b,
		 const char* clr, int* dsh,
		 int wth, const char* fnt, const char* txt,
		 unsigned short prop, const char* cmt,
		 const List<Tag>& tg, const List<CallBack>& cb)
  : Marker(p, ctr, 0, clr, dsh, wth, fnt, txt, prop, cmt, tg, cb)
{
}

BasePolygon::BasePolygon(Base* p, const List<Vertex>& v,
		 const char* clr, int* dsh,
		 int wth, const char* fnt, const char* txt,
		 unsigned short prop, const char* cmt,
		 const List<Tag>& tg, const List<CallBack>& cb)
  : Marker(p, Vector(0,0), 0, clr, dsh, wth, fnt, txt, prop, cmt, tg, cb)
{
  // Vertex list is in ref coords
  angle = 0;
  vertex = v;

  // find center
  center = Vector(0,0);
  vertex.head();
  do
    center += vertex.current()->vector;
  while (vertex.next());
  center /= vertex.count();

  // vertices are relative
  vertex.head();
  do
    vertex.current()->vector *= Translate(-center) * FlipY(); // no rotation
  while (vertex.next());

  updateBBox();
}

BasePolygon::BasePolygon(const BasePolygon& a) : Marker(a)
{
  vertex = a.vertex;
}

void BasePolygon::createVertex(int which, const Vector& v)
{
  // which segment (1 to n)
  // v is in ref coords
  Matrix mm = bckMatrix();

  int seg = which-1;
  if (seg>=0 && seg<vertex.count()) {
    Vertex* n = new Vertex(v * mm);
    vertex.insert(seg,n);

    recalcCenter();

    updateBBox();
    doCallBack(CallBack::EDITCB);
    doCallBack(CallBack::MOVECB); // center can change
  }
}

void BasePolygon::deleteVertex(int h)
{
  if (h>4) {
    int hh = h-4-1;

    if (vertex.count() > 3) {
      Vertex* v = vertex[hh];
      if (v) {
	vertex.extractNext(v);
	delete v;

	recalcCenter();

	updateBBox();
	doCallBack(CallBack::EDITCB);
	doCallBack(CallBack::MOVECB); // center can change
      }
    }
  }
}

void BasePolygon::edit(const Vector& v, int h)
{
  if (h < 5) {
    Vector s1 = v * bckMatrix();
    Vector s2 = bckMap(handle[h-1],Coord::CANVAS);

    if (s1[0] != 0 && s1[1] != 0 && s2[0] != 0 && s2[1] != 0) {
      double a = fabs(s1[0]/s2[0]);
      double b = fabs(s1[1]/s2[1]);
      double s = a > b ? a : b;

      vertex.head();
      do
	vertex.current()->vector *= Scale(s);
      while (vertex.next());
    }

    updateBBox();
    doCallBack(CallBack::EDITCB);
  }
  else {
    moveVertex(v,h);

    updateBBox();
    doCallBack(CallBack::EDITCB);
    doCallBack(CallBack::MOVECB); // center can change
  }
}

void BasePolygon::moveVertex(const Vector& v, int h)
{
  Matrix mm = bckMatrix();

  if (vertex[h-5])
    vertex.current()->vector = v * mm;

  recalcCenter();
}

void BasePolygon::recalcCenter()
{
  // recalculate center

  Vector nc;
  vertex.head();
  do
    nc += vertex.current()->vector * Rotate(angle) * FlipY();
  while (vertex.next());
  nc /= vertex.count();

  center += nc;

  // update all vertices

  vertex.head();
  do
    vertex.current()->vector -= nc * FlipY() * Rotate(-angle);
  while (vertex.next());
}

void BasePolygon::rotate(const Vector& v, int h)
{
  if (h < 5)
    Marker::rotate(v,h);
  else {
    // we need to check this here, because we are really rotating
    if (canEdit()) {
      moveVertex(v,h);

      updateBBox();
      doCallBack(CallBack::EDITCB);
      doCallBack(CallBack::MOVECB); // center can change
    }
  }
}

void BasePolygon::updateHandles()
{
  // generate handles
  numHandle = 4 + vertex.count();
  if (handle)
    delete [] handle;
  handle = new Vector[numHandle];

  // the first four are our control handles
  BBox bb;
  vertex.head();
  do
    bb.bound(vertex.current()->vector);
  while (vertex.next());

  Vector zz = parent->zoom();
  float r = 10/zz.length();
  bb.expand(r); // give us more room

  handle[0] = fwdMap(bb.ll,Coord::CANVAS);
  handle[1] = fwdMap(bb.lr(),Coord::CANVAS);
  handle[2] = fwdMap(bb.ur,Coord::CANVAS);
  handle[3] = fwdMap(bb.ul(),Coord::CANVAS);

  // and the rest are vertices
  int i=4;
  vertex.head();
  do
    handle[i++] = fwdMap(vertex.current()->vector,Coord::CANVAS);
  while (vertex.next());
}

void BasePolygon::updateCoords(const Matrix& mx)
{
  Scale s(mx);
  vertex.head();
  do
    vertex.current()->vector *= s;
  while (vertex.next());

  Marker::updateCoords(mx);
}

void BasePolygon::listBase(FitsImage* ptr, ostream& str,
			   Coord::CoordSystem sys, Coord::SkyFrame sky,
			   Coord::SkyFormat format)
{
  Matrix mm = fwdMatrix();

  str << type_ << '(';
  int first=1;
  vertex.head();
  do {
    if (!first)
      str << ',';
    first=0;

    Vector vv = vertex.current()->vector*mm;
    switch (sys) {
    case Coord::IMAGE:
    case Coord::PHYSICAL:
    case Coord::DETECTOR:
    case Coord::AMPLIFIER:
      str << setprecision(parent->precLinear_) << ptr->mapFromRef(vv,sys);
      break;
    default:
      listWCS(ptr,vv,sys,sky,format);
      str << ra << ',' << dec;
      break;
    }
  } while (vertex.next());
  str << ')';
}

<|endoftext|>


<commit_before>#include "musicsoundkmicrowidget.h"
#include "ui_musicsoundkmicrowidget.h"
#include "musicsoundkmicrosearchwidget.h"
#include "musicfunctionuiobject.h"
#include "musiccoremplayer.h"
#include "musicsettingmanager.h"
#include "musiclrcanalysis.h"
#include "musiclrcmanagerforinline.h"
#include "musicstringutils.h"
#include "musicdownloadsourcethread.h"
#include "musicvideouiobject.h"
#include "musictinyuiobject.h"
#include "musicuiobject.h"
#include "musictoolsetsuiobject.h"
#include "musicmessagebox.h"
#include "musicaudiorecordercore.h"
#include "musiccoreutils.h"
#include "musicotherdefine.h"
#include "musictime.h"

#include <QFileDialog>

#ifdef Q_CC_GNU
    #pragma GCC diagnostic ignored "-Wparentheses"
#endif

MusicSoundKMicroWidget::MusicSoundKMicroWidget(QWidget *parent)
    : MusicAbstractMoveWidget(parent),
    m_ui(new Ui::MusicSoundKMicroWidget)
{
    m_ui->setupUi(this);

#if defined MUSIC_GREATER_NEW
    setAttribute(Qt::WA_TranslucentBackground, false);
#endif
    setAttribute(Qt::WA_DeleteOnClose, true);
    setAttribute(Qt::WA_QuitOnClose, true);

    m_ui->topTitleCloseButton->setIcon(QIcon(":/functions/btn_close_hover"));
    m_ui->topTitleCloseButton->setStyleSheet(MusicUIObject::MToolButtonStyle04);
    m_ui->topTitleCloseButton->setCursor(QCursor(Qt::PointingHandCursor));
    m_ui->topTitleCloseButton->setToolTip(tr("Close"));
    connect(m_ui->topTitleCloseButton, SIGNAL(clicked()), SLOT(close()));

    m_ui->stackedWidget->setStyleSheet(MusicUIObject::MBackgroundStyle02);
    m_ui->topWidget->setStyleSheet(MusicUIObject::MBackgroundStyle06);
    m_ui->controlWidget->setStyleSheet(MusicUIObject::MBackgroundStyle06);
    m_ui->timeLabel->setStyleSheet(MusicUIObject::MColorStyle03);
    m_ui->timeSlider->setStyleSheet(MusicUIObject::MSliderStyle01);
    m_ui->transferButton->setStyleSheet(MusicUIObject::MKGRecordTransfer);

    m_queryMv = true;
    m_stateButtonOn = true;
    m_intervalTime = 0;
    m_recordCore = nullptr;

    recordStateChanged(false);
    setButtonStyle(true);
    setStateButtonStyle(true);

    m_ui->gifLabel->setType(MusicGifLabelWidget::Gif_Record_red);
//    m_ui->gifLabel->start();
    m_ui->loadingLabel->setType(MusicGifLabelWidget::Gif_Cicle_Blue);
    m_ui->loadingLabel->hide();

    m_ui->volumeButton->setValue(100);
    m_ui->volumeButton->setCursor(QCursor(Qt::PointingHandCursor));
    m_mediaPlayer = new MusicCoreMPlayer(this);
    m_searchWidget = new MusicSoundKMicroSearchWidget;
    m_searchWidget->connectTo(this);
    m_searchWidget->show();

    m_ui->winTipsButton->setStyleSheet(MusicUIObject::MKGTinyBtnWintopOff);

    m_analysis = new MusicLrcAnalysis(this);
    m_analysis->setLineMax(5);
    m_ui->musicPage->connectTo(this);
    for(int i=0; i<m_analysis->getLineMax(); ++i)
    {
        MusicLRCManagerForInline *w = new MusicLRCManagerForInline(this);
        w->setLrcPerWidth(-10);
        m_ui->musicPage->addWidget(w);
        m_musicLrcContainer.append(w);
    }

    m_recordCore = new MusicAudioRecorderCore(this);
    m_ui->transferButton->setAudioCore(m_recordCore);

#ifdef Q_OS_UNIX
    m_ui->stateButton->setFocusPolicy(Qt::NoFocus);
    m_ui->playButton->setFocusPolicy(Qt::NoFocus);
    m_ui->winTipsButton->setFocusPolicy(Qt::NoFocus);
#endif

    connect(m_ui->winTipsButton, SIGNAL(clicked()), SLOT(tipsButtonChanged()));
    connect(m_ui->stateButton, SIGNAL(clicked()), SLOT(stateButtonChanged()));
    connect(m_ui->playButton, SIGNAL(clicked()), SLOT(playButtonChanged()));
    connect(m_mediaPlayer, SIGNAL(finished()), SLOT(playFinished()));
    connect(m_mediaPlayer, SIGNAL(positionChanged(qint64)), SLOT(positionChanged(qint64)));
    connect(m_mediaPlayer, SIGNAL(durationChanged(qint64)), SLOT(durationChanged(qint64)));
    connect(m_ui->timeSlider, SIGNAL(sliderReleasedAt(int)), SLOT(setPosition(int)));
    connect(m_ui->volumeButton, SIGNAL(musicVolumeChanged(int)), SLOT(volumeChanged(int)));
    connect(m_ui->recordButton, SIGNAL(clicked()), SLOT(recordButtonClicked()));
}

MusicSoundKMicroWidget::~MusicSoundKMicroWidget()
{
    delete m_ui;
}

QString MusicSoundKMicroWidget::getClassName()
{
    return staticMetaObject.className();
}

void MusicSoundKMicroWidget::setButtonStyle(bool style) const
{
    m_ui->playButton->setStyleSheet(style ? MusicUIObject::MKGVideoBtnPlay :
                                            MusicUIObject::MKGVideoBtnPause);
}

void MusicSoundKMicroWidget::setStateButtonStyle(bool style)  const
{
    m_ui->stateButton->setStyleSheet(style ? MusicUIObject::MKGVideoBtnOrigin :
                                             MusicUIObject::MKGVideoBtnOriginOff);
}

void MusicSoundKMicroWidget::startSeachKMicro(const QString &name)
{
    m_searchWidget->startSeachKMicro(name);
}

void MusicSoundKMicroWidget::volumeChanged(int volume)
{
    m_mediaPlayer->setVolume(volume);
}

void MusicSoundKMicroWidget::positionChanged(qint64 position)
{
    m_ui->timeSlider->setValue(position*MT_S2MS);
    m_ui->timeLabel->setText(QString("%1/%2").arg(MusicTime::msecTime2LabelJustified(position*MT_S2MS))
                                             .arg(MusicTime::msecTime2LabelJustified(m_ui->timeSlider->maximum())));

    if(!m_queryMv && !m_analysis->isEmpty())
    {
        QString currentLrc, laterLrc;
        if(m_analysis->findText(m_ui->timeSlider->value(), m_ui->timeSlider->maximum(), currentLrc, laterLrc, m_intervalTime))
        {
            if(currentLrc != m_musicLrcContainer[m_analysis->getMiddle()]->text())
            {
                if(m_analysis->isValid())
                {
                    m_ui->musicPage->start();
                }
            }
        }
    }
}

void MusicSoundKMicroWidget::durationChanged(qint64 duration)
{
    m_ui->loadingLabel->stop();
    m_ui->loadingLabel->hide();
    m_ui->timeSlider->setRange(0, duration*MT_S2MS);
    m_ui->timeLabel->setText(QString("00:00/%1").arg(MusicTime::msecTime2LabelJustified(duration*MT_S2MS)));

    multiMediaChanged();
}

void MusicSoundKMicroWidget::playFinished()
{
    m_mediaPlayer->stop();
    if(m_ui->gifLabel->isRunning())
    {
        MusicMessageBox message;
        message.setText(tr("Record Finished"));
        message.exec();

        recordStateChanged(false);

        QString filename = QFileDialog::getSaveFileName( this,
            tr("choose a filename to save under"), QDir::currentPath(), "Wav(*.wav)");
        if(!filename.isEmpty())
        {
            m_recordCore->addWavHeader(MusicUtils::Core::toLocal8Bit(filename));
        }
    }
}

void MusicSoundKMicroWidget::setPosition(int position)
{
    m_mediaPlayer->setPosition(position/MT_S2MS);
    m_analysis->setSongSpeedAndSlow(position);
}

void MusicSoundKMicroWidget::playButtonChanged()
{
    m_mediaPlayer->play();
    switch(m_mediaPlayer->state())
    {
        case MusicObject::PS_PlayingState:
            setButtonStyle(false);
            break;
        case MusicObject::PS_PausedState:
            setButtonStyle(true);
            break;
        default: break;
    }

    if(!m_queryMv)
    {
        if(m_mediaPlayer->state() == MusicObject::PS_PlayingState)
        {
            m_musicLrcContainer[m_analysis->getMiddle()]->startLrcMask(m_intervalTime);
        }
        else
        {
            m_musicLrcContainer[m_analysis->getMiddle()]->stopLrcMask();
            m_ui->musicPage->stop();
        }
    }
}

void MusicSoundKMicroWidget::stateButtonChanged()
{
    m_stateButtonOn = !m_stateButtonOn;
    setStateButtonStyle(m_stateButtonOn);

    multiMediaChanged();
}

void MusicSoundKMicroWidget::tipsButtonChanged()
{
    if(m_ui->winTipsButton->styleSheet().contains(MusicUIObject::MKGTinyBtnWintopOff))
    {
        m_ui->winTipsButton->setStyleSheet(MusicUIObject::MKGTinyBtnWintopOn);
        m_searchWidget->hide();
    }
    else
    {
        m_ui->winTipsButton->setStyleSheet(MusicUIObject::MKGTinyBtnWintopOff);
        m_searchWidget->show();
    }
}

void MusicSoundKMicroWidget::mvURLChanged(bool mv, const QString &url, const QString &lrcUrl)
{
    setButtonStyle(false);

    m_ui->loadingLabel->show();
    m_ui->loadingLabel->start();

    if(m_queryMv = mv)
    {
        m_ui->stackedWidget->setCurrentIndex(SOUND_KMICRO_INDEX_0);
        m_mediaPlayer->setMedia(MusicCoreMPlayer::VideoCategory, url, (int)m_ui->videoPage->winId());
        m_mediaPlayer->play();
    }
    else
    {
        m_ui->stackedWidget->setCurrentIndex(SOUND_KMICRO_INDEX_1);
        m_mediaPlayer->setMedia(MusicCoreMPlayer::MusicCategory, url);
        m_mediaPlayer->play();

        ////////////////////////////////////////////////////////////////
        MusicDownloadSourceThread *download = new MusicDownloadSourceThread(this);
        connect(download, SIGNAL(downLoadByteDataChanged(QByteArray)), SLOT(downLoadFinished(QByteArray)));
        download->startToDownload(lrcUrl);
    }
}

void MusicSoundKMicroWidget::downLoadFinished(const QByteArray &data)
{
    m_analysis->setLrcData(data);

    for(int i=0; i<m_analysis->getLineMax(); ++i)
    {
        m_musicLrcContainer[i]->setText( QString() );
    }
    setItemStyleSheet(0, -3, 90);
    setItemStyleSheet(1, -6, 35);
    setItemStyleSheet(2, -10, 0);
    setItemStyleSheet(3, -6, 35);
    setItemStyleSheet(4, -3, 90);
}

void MusicSoundKMicroWidget::updateAnimationLrc()
{
    for(int i=0; i<m_analysis->getLineMax(); ++i)
    {
        m_musicLrcContainer[i]->setText(m_analysis->getText(i));
    }
    m_analysis->setCurrentIndex(m_analysis->getCurrentIndex() + 1);
    m_musicLrcContainer[m_analysis->getMiddle()]->startLrcMask(m_intervalTime);
}

void MusicSoundKMicroWidget::recordButtonClicked()
{
    if(m_ui->gifLabel->isRunning())
    {
        MusicMessageBox message;
        message.setText(tr("Recording Now, Stop It?"));
        if(message.exec() == 0)
        {
            recordStateChanged(false);
        }
    }
    else
    {
        int index = m_ui->transferButton->audioInputIndex();
        if(index != -1)
        {
            recordStateChanged(true);
        }
        else
        {
            MusicMessageBox message;
            message.setText(tr("Input Error"));
            message.exec();
        }
    }
}

void MusicSoundKMicroWidget::closeEvent(QCloseEvent *event)
{
    MusicAbstractMoveWidget::closeEvent(event);
    emit resetFlag(MusicObject::TT_SoundKMicro);

    qDeleteAll(m_musicLrcContainer);
    delete m_analysis;
    delete m_mediaPlayer;
    delete m_searchWidget;
    delete m_recordCore;
}

void MusicSoundKMicroWidget::paintEvent(QPaintEvent *event)
{
    MusicAbstractMoveWidget::paintEvent(event);
    m_searchWidget->move( geometry().topRight() + QPoint(5, -4) );
}

void MusicSoundKMicroWidget::mouseMoveEvent(QMouseEvent *event)
{
    MusicAbstractMoveWidget::mouseMoveEvent(event);
    m_searchWidget->move( geometry().topRight() + QPoint(5, -4) );
}

void MusicSoundKMicroWidget::multiMediaChanged()
{
    if(m_queryMv)
    {
        m_mediaPlayer->setMultiVoice(m_stateButtonOn ? 0 : 1);
    }
    else
    {
        m_stateButtonOn ? m_mediaPlayer->setRightVolume() : m_mediaPlayer->setLeftVolume();
    }

    volumeChanged(m_ui->volumeButton->value());
}

void MusicSoundKMicroWidget::setItemStyleSheet(int index, int size, int transparent)
{
    MusicLRCManagerForInline *w = m_musicLrcContainer[index];
    w->setCenterOnLrc(false);
    w->setFontSize(size);

    int value = 100 - transparent;
    value = (value < 0) ? 0 : value;
    value = (value > 100) ? 100 : value;
    w->setFontTransparent(value);
    w->setTransparent(value);

    if(M_SETTING_PTR->value("LrcColorChoiced").toInt() != -1)
    {
        MusicLRCColor::LrcColorType index = MStatic_cast(MusicLRCColor::LrcColorType, M_SETTING_PTR->value("LrcColorChoiced").toInt());
        MusicLRCColor cl = MusicLRCColor::mapIndexToColor(index);
        w->setLinearGradientColor(cl);
    }
    else
    {
        MusicLRCColor cl(MusicUtils::String::readColorConfig(M_SETTING_PTR->value("LrcFgColorChoiced").toString()),
                         MusicUtils::String::readColorConfig(M_SETTING_PTR->value("LrcBgColorChoiced").toString()));
        w->setLinearGradientColor(cl);
    }
}

void MusicSoundKMicroWidget::recordStateChanged(bool state)
{
    if(state && m_mediaPlayer->state() != MusicObject::PS_StoppedState)
    {
        m_ui->gifLabel->start();
        m_ui->recordButton->setStyleSheet(MusicUIObject::MKGRerecord);
        if(m_recordCore)
        {
            m_recordCore->onRecordStart();
            if(m_recordCore->error())
            {
                return;
            }
        }
    }
    else
    {
        m_ui->gifLabel->stop();
        m_ui->recordButton->setStyleSheet(MusicUIObject::MKGRecord);
        if(m_recordCore)
        {
            m_recordCore->onRecordStop();
        }
    }
}
<commit_msg>Fix kmicro deleted twice[548321]<commit_after>#include "musicsoundkmicrowidget.h"
#include "ui_musicsoundkmicrowidget.h"
#include "musicsoundkmicrosearchwidget.h"
#include "musicfunctionuiobject.h"
#include "musiccoremplayer.h"
#include "musicsettingmanager.h"
#include "musiclrcanalysis.h"
#include "musiclrcmanagerforinline.h"
#include "musicstringutils.h"
#include "musicdownloadsourcethread.h"
#include "musicvideouiobject.h"
#include "musictinyuiobject.h"
#include "musicuiobject.h"
#include "musictoolsetsuiobject.h"
#include "musicmessagebox.h"
#include "musicaudiorecordercore.h"
#include "musiccoreutils.h"
#include "musicotherdefine.h"
#include "musictime.h"

#include <QFileDialog>

#ifdef Q_CC_GNU
    #pragma GCC diagnostic ignored "-Wparentheses"
#endif

MusicSoundKMicroWidget::MusicSoundKMicroWidget(QWidget *parent)
    : MusicAbstractMoveWidget(parent),
    m_ui(new Ui::MusicSoundKMicroWidget)
{
    m_ui->setupUi(this);

#if defined MUSIC_GREATER_NEW
    setAttribute(Qt::WA_TranslucentBackground, false);
#endif
//    setAttribute(Qt::WA_DeleteOnClose, true);
//    setAttribute(Qt::WA_QuitOnClose, true);

    m_ui->topTitleCloseButton->setIcon(QIcon(":/functions/btn_close_hover"));
    m_ui->topTitleCloseButton->setStyleSheet(MusicUIObject::MToolButtonStyle04);
    m_ui->topTitleCloseButton->setCursor(QCursor(Qt::PointingHandCursor));
    m_ui->topTitleCloseButton->setToolTip(tr("Close"));
    connect(m_ui->topTitleCloseButton, SIGNAL(clicked()), SLOT(close()));

    m_ui->stackedWidget->setStyleSheet(MusicUIObject::MBackgroundStyle02);
    m_ui->topWidget->setStyleSheet(MusicUIObject::MBackgroundStyle06);
    m_ui->controlWidget->setStyleSheet(MusicUIObject::MBackgroundStyle06);
    m_ui->timeLabel->setStyleSheet(MusicUIObject::MColorStyle03);
    m_ui->timeSlider->setStyleSheet(MusicUIObject::MSliderStyle01);
    m_ui->transferButton->setStyleSheet(MusicUIObject::MKGRecordTransfer);

    m_queryMv = true;
    m_stateButtonOn = true;
    m_intervalTime = 0;
    m_recordCore = nullptr;

    recordStateChanged(false);
    setButtonStyle(true);
    setStateButtonStyle(true);

    m_ui->gifLabel->setType(MusicGifLabelWidget::Gif_Record_red);
//    m_ui->gifLabel->start();
    m_ui->loadingLabel->setType(MusicGifLabelWidget::Gif_Cicle_Blue);
    m_ui->loadingLabel->hide();

    m_ui->volumeButton->setValue(100);
    m_ui->volumeButton->setCursor(QCursor(Qt::PointingHandCursor));
    m_mediaPlayer = new MusicCoreMPlayer(this);
    m_searchWidget = new MusicSoundKMicroSearchWidget;
    m_searchWidget->connectTo(this);
    m_searchWidget->show();

    m_ui->winTipsButton->setStyleSheet(MusicUIObject::MKGTinyBtnWintopOff);

    m_analysis = new MusicLrcAnalysis(this);
    m_analysis->setLineMax(5);
    m_ui->musicPage->connectTo(this);
    for(int i=0; i<m_analysis->getLineMax(); ++i)
    {
        MusicLRCManagerForInline *w = new MusicLRCManagerForInline(this);
        w->setLrcPerWidth(-10);
        m_ui->musicPage->addWidget(w);
        m_musicLrcContainer.append(w);
    }

    m_recordCore = new MusicAudioRecorderCore(this);
    m_ui->transferButton->setAudioCore(m_recordCore);

#ifdef Q_OS_UNIX
    m_ui->stateButton->setFocusPolicy(Qt::NoFocus);
    m_ui->playButton->setFocusPolicy(Qt::NoFocus);
    m_ui->winTipsButton->setFocusPolicy(Qt::NoFocus);
#endif

    connect(m_ui->winTipsButton, SIGNAL(clicked()), SLOT(tipsButtonChanged()));
    connect(m_ui->stateButton, SIGNAL(clicked()), SLOT(stateButtonChanged()));
    connect(m_ui->playButton, SIGNAL(clicked()), SLOT(playButtonChanged()));
    connect(m_mediaPlayer, SIGNAL(finished()), SLOT(playFinished()));
    connect(m_mediaPlayer, SIGNAL(positionChanged(qint64)), SLOT(positionChanged(qint64)));
    connect(m_mediaPlayer, SIGNAL(durationChanged(qint64)), SLOT(durationChanged(qint64)));
    connect(m_ui->timeSlider, SIGNAL(sliderReleasedAt(int)), SLOT(setPosition(int)));
    connect(m_ui->volumeButton, SIGNAL(musicVolumeChanged(int)), SLOT(volumeChanged(int)));
    connect(m_ui->recordButton, SIGNAL(clicked()), SLOT(recordButtonClicked()));
}

MusicSoundKMicroWidget::~MusicSoundKMicroWidget()
{
    delete m_ui;
}

QString MusicSoundKMicroWidget::getClassName()
{
    return staticMetaObject.className();
}

void MusicSoundKMicroWidget::setButtonStyle(bool style) const
{
    m_ui->playButton->setStyleSheet(style ? MusicUIObject::MKGVideoBtnPlay :
                                            MusicUIObject::MKGVideoBtnPause);
}

void MusicSoundKMicroWidget::setStateButtonStyle(bool style)  const
{
    m_ui->stateButton->setStyleSheet(style ? MusicUIObject::MKGVideoBtnOrigin :
                                             MusicUIObject::MKGVideoBtnOriginOff);
}

void MusicSoundKMicroWidget::startSeachKMicro(const QString &name)
{
    m_searchWidget->startSeachKMicro(name);
}

void MusicSoundKMicroWidget::volumeChanged(int volume)
{
    m_mediaPlayer->setVolume(volume);
}

void MusicSoundKMicroWidget::positionChanged(qint64 position)
{
    m_ui->timeSlider->setValue(position*MT_S2MS);
    m_ui->timeLabel->setText(QString("%1/%2").arg(MusicTime::msecTime2LabelJustified(position*MT_S2MS))
                                             .arg(MusicTime::msecTime2LabelJustified(m_ui->timeSlider->maximum())));

    if(!m_queryMv && !m_analysis->isEmpty())
    {
        QString currentLrc, laterLrc;
        if(m_analysis->findText(m_ui->timeSlider->value(), m_ui->timeSlider->maximum(), currentLrc, laterLrc, m_intervalTime))
        {
            if(currentLrc != m_musicLrcContainer[m_analysis->getMiddle()]->text())
            {
                if(m_analysis->isValid())
                {
                    m_ui->musicPage->start();
                }
            }
        }
    }
}

void MusicSoundKMicroWidget::durationChanged(qint64 duration)
{
    m_ui->loadingLabel->stop();
    m_ui->loadingLabel->hide();
    m_ui->timeSlider->setRange(0, duration*MT_S2MS);
    m_ui->timeLabel->setText(QString("00:00/%1").arg(MusicTime::msecTime2LabelJustified(duration*MT_S2MS)));

    multiMediaChanged();
}

void MusicSoundKMicroWidget::playFinished()
{
    m_mediaPlayer->stop();
    if(m_ui->gifLabel->isRunning())
    {
        MusicMessageBox message;
        message.setText(tr("Record Finished"));
        message.exec();

        recordStateChanged(false);

        QString filename = QFileDialog::getSaveFileName( this,
            tr("choose a filename to save under"), QDir::currentPath(), "Wav(*.wav)");
        if(!filename.isEmpty())
        {
            m_recordCore->addWavHeader(MusicUtils::Core::toLocal8Bit(filename));
        }
    }
}

void MusicSoundKMicroWidget::setPosition(int position)
{
    m_mediaPlayer->setPosition(position/MT_S2MS);
    m_analysis->setSongSpeedAndSlow(position);
}

void MusicSoundKMicroWidget::playButtonChanged()
{
    m_mediaPlayer->play();
    switch(m_mediaPlayer->state())
    {
        case MusicObject::PS_PlayingState:
            setButtonStyle(false);
            break;
        case MusicObject::PS_PausedState:
            setButtonStyle(true);
            break;
        default: break;
    }

    if(!m_queryMv)
    {
        if(m_mediaPlayer->state() == MusicObject::PS_PlayingState)
        {
            m_musicLrcContainer[m_analysis->getMiddle()]->startLrcMask(m_intervalTime);
        }
        else
        {
            m_musicLrcContainer[m_analysis->getMiddle()]->stopLrcMask();
            m_ui->musicPage->stop();
        }
    }
}

void MusicSoundKMicroWidget::stateButtonChanged()
{
    m_stateButtonOn = !m_stateButtonOn;
    setStateButtonStyle(m_stateButtonOn);

    multiMediaChanged();
}

void MusicSoundKMicroWidget::tipsButtonChanged()
{
    if(m_ui->winTipsButton->styleSheet().contains(MusicUIObject::MKGTinyBtnWintopOff))
    {
        m_ui->winTipsButton->setStyleSheet(MusicUIObject::MKGTinyBtnWintopOn);
        m_searchWidget->hide();
    }
    else
    {
        m_ui->winTipsButton->setStyleSheet(MusicUIObject::MKGTinyBtnWintopOff);
        m_searchWidget->show();
    }
}

void MusicSoundKMicroWidget::mvURLChanged(bool mv, const QString &url, const QString &lrcUrl)
{
    setButtonStyle(false);

    m_ui->loadingLabel->show();
    m_ui->loadingLabel->start();

    if(m_queryMv = mv)
    {
        m_ui->stackedWidget->setCurrentIndex(SOUND_KMICRO_INDEX_0);
        m_mediaPlayer->setMedia(MusicCoreMPlayer::VideoCategory, url, (int)m_ui->videoPage->winId());
        m_mediaPlayer->play();
    }
    else
    {
        m_ui->stackedWidget->setCurrentIndex(SOUND_KMICRO_INDEX_1);
        m_mediaPlayer->setMedia(MusicCoreMPlayer::MusicCategory, url);
        m_mediaPlayer->play();

        ////////////////////////////////////////////////////////////////
        MusicDownloadSourceThread *download = new MusicDownloadSourceThread(this);
        connect(download, SIGNAL(downLoadByteDataChanged(QByteArray)), SLOT(downLoadFinished(QByteArray)));
        download->startToDownload(lrcUrl);
    }
}

void MusicSoundKMicroWidget::downLoadFinished(const QByteArray &data)
{
    m_analysis->setLrcData(data);

    for(int i=0; i<m_analysis->getLineMax(); ++i)
    {
        m_musicLrcContainer[i]->setText( QString() );
    }
    setItemStyleSheet(0, -3, 90);
    setItemStyleSheet(1, -6, 35);
    setItemStyleSheet(2, -10, 0);
    setItemStyleSheet(3, -6, 35);
    setItemStyleSheet(4, -3, 90);
}

void MusicSoundKMicroWidget::updateAnimationLrc()
{
    for(int i=0; i<m_analysis->getLineMax(); ++i)
    {
        m_musicLrcContainer[i]->setText(m_analysis->getText(i));
    }
    m_analysis->setCurrentIndex(m_analysis->getCurrentIndex() + 1);
    m_musicLrcContainer[m_analysis->getMiddle()]->startLrcMask(m_intervalTime);
}

void MusicSoundKMicroWidget::recordButtonClicked()
{
    if(m_ui->gifLabel->isRunning())
    {
        MusicMessageBox message;
        message.setText(tr("Recording Now, Stop It?"));
        if(message.exec() == 0)
        {
            recordStateChanged(false);
        }
    }
    else
    {
        int index = m_ui->transferButton->audioInputIndex();
        if(index != -1)
        {
            recordStateChanged(true);
        }
        else
        {
            MusicMessageBox message;
            message.setText(tr("Input Error"));
            message.exec();
        }
    }
}

void MusicSoundKMicroWidget::closeEvent(QCloseEvent *event)
{
    MusicAbstractMoveWidget::closeEvent(event);
    emit resetFlag(MusicObject::TT_SoundKMicro);

    qDeleteAll(m_musicLrcContainer);
    delete m_analysis;
    delete m_mediaPlayer;
    delete m_searchWidget;
    delete m_recordCore;
}

void MusicSoundKMicroWidget::paintEvent(QPaintEvent *event)
{
    MusicAbstractMoveWidget::paintEvent(event);
    m_searchWidget->move( geometry().topRight() + QPoint(5, -4) );
}

void MusicSoundKMicroWidget::mouseMoveEvent(QMouseEvent *event)
{
    MusicAbstractMoveWidget::mouseMoveEvent(event);
    m_searchWidget->move( geometry().topRight() + QPoint(5, -4) );
}

void MusicSoundKMicroWidget::multiMediaChanged()
{
    if(m_queryMv)
    {
        m_mediaPlayer->setMultiVoice(m_stateButtonOn ? 0 : 1);
    }
    else
    {
        m_stateButtonOn ? m_mediaPlayer->setRightVolume() : m_mediaPlayer->setLeftVolume();
    }

    volumeChanged(m_ui->volumeButton->value());
}

void MusicSoundKMicroWidget::setItemStyleSheet(int index, int size, int transparent)
{
    MusicLRCManagerForInline *w = m_musicLrcContainer[index];
    w->setCenterOnLrc(false);
    w->setFontSize(size);

    int value = 100 - transparent;
    value = (value < 0) ? 0 : value;
    value = (value > 100) ? 100 : value;
    w->setFontTransparent(value);
    w->setTransparent(value);

    if(M_SETTING_PTR->value("LrcColorChoiced").toInt() != -1)
    {
        MusicLRCColor::LrcColorType index = MStatic_cast(MusicLRCColor::LrcColorType, M_SETTING_PTR->value("LrcColorChoiced").toInt());
        MusicLRCColor cl = MusicLRCColor::mapIndexToColor(index);
        w->setLinearGradientColor(cl);
    }
    else
    {
        MusicLRCColor cl(MusicUtils::String::readColorConfig(M_SETTING_PTR->value("LrcFgColorChoiced").toString()),
                         MusicUtils::String::readColorConfig(M_SETTING_PTR->value("LrcBgColorChoiced").toString()));
        w->setLinearGradientColor(cl);
    }
}

void MusicSoundKMicroWidget::recordStateChanged(bool state)
{
    if(state && m_mediaPlayer->state() != MusicObject::PS_StoppedState)
    {
        m_ui->gifLabel->start();
        m_ui->recordButton->setStyleSheet(MusicUIObject::MKGRerecord);
        if(m_recordCore)
        {
            m_recordCore->onRecordStart();
            if(m_recordCore->error())
            {
                return;
            }
        }
    }
    else
    {
        m_ui->gifLabel->stop();
        m_ui->recordButton->setStyleSheet(MusicUIObject::MKGRecord);
        if(m_recordCore)
        {
            m_recordCore->onRecordStop();
        }
    }
}
<|endoftext|>


<commit_before>/**
 * Copyright 2008 Matthew Graham
 * 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 "request_parser.h"
#include <sstream>

void request_parser_c::add_input( const std::string &input )
{
	m_input.append( input );
}

std::string request_parser_c::readline()
{
	if ( m_input.find( "\n" ) == std::string::npos ) {
		return std::string();
	}
	std::istringstream str( m_input );
	std::string line;
	std::getline( str, line );
	m_input = str.str();

	return line;
}

<commit_msg>made some minor mods to the request_parser readline method<commit_after>/**
 * Copyright 2008 Matthew Graham
 * 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 "request_parser.h"
#include <sstream>
#include <iostream>
#include <list>

void request_parser_c::add_input( const std::string &input )
{
	m_input.append( input );
}

std::string request_parser_c::readline()
{
	if ( m_input.find( "\n" ) == std::string::npos ) {
		return std::string();
	}
	std::istringstream str( m_input );
	std::list< std::string > lines;
	std::string line;
	do {
		std::getline( str, line );
		lines.push_back( line );
		std::cerr << "line: " << line;
	} while ( ! str.eof() );

	// m_input = remainder;
	m_input = std::string();

	return line;
}

<|endoftext|>


<commit_before>#include "stel.h"
#include "log.h"

namespace steg
{

lua_State* L = NULL;

static int cLuaLoadLibs(lua_State* L)
{
	luaL_openlibs(L);

	return 0;
}

DBG_Status LuaInit()
{
    DBG_Status status = DBG_OK;

    ENG_LogInfo("Lua module initializing...");

	L = luaL_newstate();
	if(L == NULL)
	{
		ENG_LogError("Lua module initialization failure! Game cannot run!");
		//shut down log module
		LogQuit();
		exit(EXIT_FAILURE);
	}
	else
	{
		if(lua_cpcall(L, cLuaLoadLibs, NULL))
		{
			//handle error
			const char* errorStr = lua_tostring(L, -1);
			ENG_LogErrors("Lua module cannot open libs: ", errorStr);
			lua_pop(L, 1);
			//shut down log module
            LogQuit();
			lua_close(L);
			exit(EXIT_FAILURE);
		}
		else
		{
			ENG_LogInfo("Lua module initialize successfully!");
		}
	}

    //load lua interface
	status |= PLuaDoScript("./scripts/interface.lua");

    return status;
}

void LuaQuit()
{
    ENG_LogInfo("Lua module shutting down...");
	lua_close(L);
	L = NULL;
	ENG_LogInfo("Lua module shut down successfully!");
}

static const char* (luaLoadErrors[3]) =
{
	[0] = "syntax error during pre-compilation",	//LUA_ERRSYNTAX
	[1] = "memory allocation error",				//LUA_ERRMEM
	[2] = "cannot open/read the script file",		//LUA_ERRFILE
};

static int cLuaDoFile(lua_State* L)
{
	luaL_checktype(L, 1, LUA_TLIGHTUSERDATA);
	//const char* scriptFile = (char*)lua_topointer(L, 1);  //lua_topointer() "Typically this function is used only for debug information."
	const char* scriptFile = (char*)lua_touserdata(L, 1);
	int err = luaL_loadfile(L, scriptFile);
	if(err)
	{
		//handle errors
		const char* errStr = NULL;
		switch(err)
		{
		case LUA_ERRSYNTAX:
			errStr = luaLoadErrors[0];
			break;
		case LUA_ERRMEM:
			errStr = luaLoadErrors[1];
			break;
		case LUA_ERRFILE:
			errStr = luaLoadErrors[2];
			break;
		default:
			errStr = "Unknown error!";
			break;
		}

		luaL_error(L, "Cannot load script file: %s", errStr);
	}
	else
	{
		//do script
		lua_call(L, 0, 0);
	}

	return 0;	//return values are discarded in cpcall
}

DBG_Status PLuaDoScript(const char* scriptFile)
{
	DBG_Status status = DBG_OK;

	if(scriptFile == NULL)
	{
		return DBG_ARG_ERR;
	}
	else
	{
		if(lua_cpcall(L, cLuaDoFile, (void*)scriptFile))
		{
			//handle error
			const char* errorStr = lua_tostring(L, -1);
			LUA_LogErrors("Lua module cannot do script: ", errorStr);
			lua_pop(L, 1);

			status |= DBG_LUA_ERR;
		}
	}

	return status;
}

struct typePtrPair
{
	const char* name;
	void* ptr;
	enum luaType
	{
		typeInt,
		typeDouble,
		typeBool,
		typeString,
		typeCFunction,
	} type;
};

static int cLuaGetGlobal(lua_State* L)
{
	luaL_checktype(L, 1, LUA_TLIGHTUSERDATA);
	typePtrPair* p = (typePtrPair*)lua_touserdata(L, 1);

	lua_getglobal(L, p->name);
	if(lua_isnil(L, -1))
    {
        luaL_error(L, "\"%s\" is not defined yet as a global value!", p->name);
        return 0;
    }
	switch(p->type)
	{
	case typePtrPair::typeInt:		//temp
	case typePtrPair::typeDouble:
		//if(lua_type(L, -1) == LUA_TNUMBER)
		if(lua_isnumber(L, -1))
		{
			double v = lua_tonumber(L, -1);
			if(p->type == typePtrPair::typeInt)
			{
				*((int*)(p->ptr)) = (int)v;
			}
			else	// double
			{
				*((double*)(p->ptr)) = (double)v;
			}
		}
		else
		{
			luaL_error(L, "Global \"%s\" is not a number!", p->name);
		}
		break;
	//case typePtrPair::typeDouble:
	//	break;
	case typePtrPair::typeBool:
		if(lua_isboolean(L, -1))
		{
			*((bool*)(p->ptr)) = lua_toboolean(L, -1);
		}
		else
		{
			luaL_error(L, "Global \"%s\" is not a bool!", p->name);
		}
		break;
	case typePtrPair::typeString:
		if(lua_isstring(L, -1))
		{
			*((std::string*)(p->ptr)) = lua_tostring(L, -1);	//The sequence is copied as the new value for the string.
																//"http://www.cplusplus.com/reference/string/string/operator=/"
		}
		else
		{
			luaL_error(L, "Global \"%s\" is not a string!", p->name);
		}
		break;
	case typePtrPair::typeCFunction:
		if(lua_iscfunction(L, -1))
		{
			*((lua_CFunction*)(p->ptr)) = lua_tocfunction(L, -1);
		}
		else
		{
			luaL_error(L, "Global \"%s\" is not a lua_CFunction!", p->name);
		}
		break;
	default:
		luaL_error(L, "Wrong type!");
		break;
	}
	lua_pop(L, 1);

	return 0;
}

static DBG_Status _pGetGlobal(const char* name, void* value, typePtrPair::luaType t)
{
	DBG_Status status = DBG_OK;

	if(value == NULL || name == NULL)
		return DBG_ARG_ERR | DBG_NULL_PTR;

	typePtrPair* p = new typePtrPair;
	if(p)
	{
		p->name = name;
		p->ptr = value;
		p->type = t;

		if(lua_cpcall(L, cLuaGetGlobal, (void*)p))
		{
			//handle error
			const char* errorStr = lua_tostring(L, -1);
			LUA_LogErrors("Error in lua getglobal: ", errorStr);
			lua_pop(L, 1);

			status |= DBG_LUA_ERR;
		}

		delete p;
	}
	else
	{
		LUA_LogError("Cannot alloc new typePtrPair struct!");
		status |= DBG_MEM_ERR;
	}

	return status;
}

DBG_Status PLuaGetGlobal(const char* name, double* value)
{
	DBG_Status status = DBG_OK;

	status |= _pGetGlobal(name, value, typePtrPair::typeDouble);

	return status;
}

DBG_Status PLuaGetGlobal(const char* name, float* value)
{
	DBG_Status status = DBG_OK;

	double tmp;
	status |= PLuaGetGlobal(name, &tmp);
	*value = (float)tmp;

	return status;
}

DBG_Status PLuaGetGlobal(const char* name, int* value)
{
	DBG_Status status = DBG_OK;

	status |= _pGetGlobal(name, value, typePtrPair::typeInt);

	return status;
}

DBG_Status PLuaGetGlobal(const char* name, bool* value)
{
	DBG_Status status = DBG_OK;

	status |= _pGetGlobal(name, value, typePtrPair::typeBool);

	return status;
}

DBG_Status PLuaGetGlobal(const char* name, std::string* value)
{
	DBG_Status status = DBG_OK;

	status |= _pGetGlobal(name, value, typePtrPair::typeString);

	return status;
}

DBG_Status PLuaGetGlobal(const char* name, lua_CFunction* value)
{
	DBG_Status status = DBG_OK;

	status |= _pGetGlobal(name, value, typePtrPair::typeCFunction);

	return status;
}

}
<commit_msg>Update stel.cpp<commit_after>#include "stel.h"
#include "log.h"

namespace steg
{
jmp_buf StelJmp;
lua_State* L = NULL;

static int cLuaLoadLibs(lua_State* L)
{
	luaL_openlibs(L);

	return 0;
}

DBG_Status LuaInit()
{
    DBG_Status status = DBG_OK;

    ENG_LogInfo("Lua module initializing...");

	L = luaL_newstate();
	if(L == NULL)
	{
		ENG_LogError("Lua module initialization failure! Game cannot run!");
		//shut down log module
		LogQuit();
		exit(EXIT_FAILURE);
	}
	else
	{
		if(lua_cpcall(L, cLuaLoadLibs, NULL))
		{
			//handle error
			const char* errorStr = lua_tostring(L, -1);
			ENG_LogErrors("Lua module cannot open libs: ", errorStr);
			lua_pop(L, 1);
			//shut down log module
            LogQuit();
			lua_close(L);
			exit(EXIT_FAILURE);
		}
		else
		{
			ENG_LogInfo("Lua module initialize successfully!");
		}
	}

    //load lua interface
	status |= PLuaDoScript("./scripts/interface.lua");

    return status;
}

void LuaQuit()
{
    ENG_LogInfo("Lua module shutting down...");
	lua_close(L);
	L = NULL;
	ENG_LogInfo("Lua module shut down successfully!");
}

static const char* (luaLoadErrors[3]) =
{
	[0] = "syntax error during pre-compilation",	//LUA_ERRSYNTAX
	[1] = "memory allocation error",				//LUA_ERRMEM
	[2] = "cannot open/read the script file",		//LUA_ERRFILE
};

static int cLuaDoFile(lua_State* L)
{
	luaL_checktype(L, 1, LUA_TLIGHTUSERDATA);
	//const char* scriptFile = (char*)lua_topointer(L, 1);  //lua_topointer() "Typically this function is used only for debug information."
	const char* scriptFile = (char*)lua_touserdata(L, 1);
	int err = luaL_loadfile(L, scriptFile);
	if(err)
	{
		//handle errors
		const char* errStr = NULL;
		switch(err)
		{
		case LUA_ERRSYNTAX:
			errStr = luaLoadErrors[0];
			break;
		case LUA_ERRMEM:
			errStr = luaLoadErrors[1];
			break;
		case LUA_ERRFILE:
			errStr = luaLoadErrors[2];
			break;
		default:
			errStr = "Unknown error!";
			break;
		}

		luaL_error(L, "Cannot load script file: %s", errStr);
	}
	else
	{
		//do script
		lua_call(L, 0, 0);
	}

	return 0;	//return values are discarded in cpcall
}

DBG_Status PLuaDoScript(const char* scriptFile)
{
	DBG_Status status = DBG_OK;

	if(scriptFile == NULL)
	{
		return DBG_ARG_ERR;
	}
	else
	{
		if(lua_cpcall(L, cLuaDoFile, (void*)scriptFile))
		{
			//handle error
			const char* errorStr = lua_tostring(L, -1);
			LUA_LogErrors("Lua module cannot do script: ", errorStr);
			lua_pop(L, 1);

			status |= DBG_LUA_ERR;
		}
	}

	return status;
}

struct typePtrPair
{
	const char* name;
	void* ptr;
	enum luaType
	{
		typeInt,
		typeDouble,
		typeBool,
		typeString,
		typeCFunction,
	} type;
};

static int cLuaGetGlobal(lua_State* L)
{
	luaL_checktype(L, 1, LUA_TLIGHTUSERDATA);
	typePtrPair* p = (typePtrPair*)lua_touserdata(L, 1);

	lua_getglobal(L, p->name);
	if(lua_isnil(L, -1))
    {
        luaL_error(L, "\"%s\" is not defined yet as a global value!", p->name);
        return 0;
    }
	switch(p->type)
	{
	case typePtrPair::typeInt:		//temp
	case typePtrPair::typeDouble:
		//if(lua_type(L, -1) == LUA_TNUMBER)
		if(lua_isnumber(L, -1))
		{
			double v = lua_tonumber(L, -1);
			if(p->type == typePtrPair::typeInt)
			{
				*((int*)(p->ptr)) = (int)v;
			}
			else	// double
			{
				*((double*)(p->ptr)) = (double)v;
			}
		}
		else
		{
			luaL_error(L, "Global \"%s\" is not a number!", p->name);
		}
		break;
	//case typePtrPair::typeDouble:
	//	break;
	case typePtrPair::typeBool:
		if(lua_isboolean(L, -1))
		{
			*((bool*)(p->ptr)) = lua_toboolean(L, -1);
		}
		else
		{
			luaL_error(L, "Global \"%s\" is not a bool!", p->name);
		}
		break;
	case typePtrPair::typeString:
		if(lua_isstring(L, -1))
		{
			*((std::string*)(p->ptr)) = lua_tostring(L, -1);	//The sequence is copied as the new value for the string.
																//"http://www.cplusplus.com/reference/string/string/operator=/"
		}
		else
		{
			luaL_error(L, "Global \"%s\" is not a string!", p->name);
		}
		break;
	case typePtrPair::typeCFunction:
		if(lua_iscfunction(L, -1))
		{
			*((lua_CFunction*)(p->ptr)) = lua_tocfunction(L, -1);
		}
		else
		{
			luaL_error(L, "Global \"%s\" is not a lua_CFunction!", p->name);
		}
		break;
	default:
		luaL_error(L, "Wrong type!");
		break;
	}
	lua_pop(L, 1);

	return 0;
}

static DBG_Status _pGetGlobal(const char* name, void* value, typePtrPair::luaType t)
{
	DBG_Status status = DBG_OK;

	if(value == NULL || name == NULL)
		return DBG_ARG_ERR | DBG_NULL_PTR;

	typePtrPair* p = new typePtrPair;
	if(p)
	{
		p->name = name;
		p->ptr = value;
		p->type = t;

		if(lua_cpcall(L, cLuaGetGlobal, (void*)p))
		{
			//handle error
			const char* errorStr = lua_tostring(L, -1);
			LUA_LogErrors("Error in lua getglobal: ", errorStr);
			lua_pop(L, 1);

			status |= DBG_LUA_ERR;
		}

		delete p;
	}
	else
	{
		LUA_LogError("Cannot alloc new typePtrPair struct!");
		status |= DBG_MEM_ERR;
	}

	return status;
}

DBG_Status PLuaGetGlobal(const char* name, double* value)
{
	DBG_Status status = DBG_OK;

	status |= _pGetGlobal(name, value, typePtrPair::typeDouble);

	return status;
}

DBG_Status PLuaGetGlobal(const char* name, float* value)
{
	DBG_Status status = DBG_OK;

	double tmp;
	status |= PLuaGetGlobal(name, &tmp);
	*value = (float)tmp;

	return status;
}

DBG_Status PLuaGetGlobal(const char* name, int* value)
{
	DBG_Status status = DBG_OK;

	status |= _pGetGlobal(name, value, typePtrPair::typeInt);

	return status;
}

DBG_Status PLuaGetGlobal(const char* name, bool* value)
{
	DBG_Status status = DBG_OK;

	status |= _pGetGlobal(name, value, typePtrPair::typeBool);

	return status;
}

DBG_Status PLuaGetGlobal(const char* name, std::string* value)
{
	DBG_Status status = DBG_OK;

	status |= _pGetGlobal(name, value, typePtrPair::typeString);

	return status;
}

DBG_Status PLuaGetGlobal(const char* name, lua_CFunction* value)
{
	DBG_Status status = DBG_OK;

	status |= _pGetGlobal(name, value, typePtrPair::typeCFunction);

	return status;
}

DBG_Status JLuaCallRegisteredFunction(const char* file, const char* functionPath, const char* argTypes, const char* retTypes, ...)
{
}

}
<|endoftext|>