<commit_before>// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include <vector>

#include "vm/closure_functions_cache.h"
#include "vm/compiler/backend/il_printer.h"
#include "vm/compiler/backend/il_test_helper.h"
#include "vm/compiler/call_specializer.h"
#include "vm/compiler/compiler_pass.h"
#include "vm/object.h"
#include "vm/unit_test.h"

namespace dart {

#if defined(DART_PRECOMPILER)

// This test asserts that we are inlining accesses to typed data interfaces
// (e.g. Uint8List) if there are no instantiated 3rd party classes.
ISOLATE_UNIT_TEST_CASE(IRTest_TypedDataAOT_Inlining) {
  const char* kScript =
      R"(
      import 'dart:typed_data';

      foo(Uint8List list, int from) {
        if (from >= list.length) {
          return list[from];
        }
      }
      )";

  const auto& root_library = Library::Handle(LoadTestScript(kScript));
  const auto& function = Function::Handle(GetFunction(root_library, "foo"));

  TestPipeline pipeline(function, CompilerPass::kAOT);
  FlowGraph* flow_graph = pipeline.RunPasses({});

  auto entry = flow_graph->graph_entry()->normal_entry();
  EXPECT(entry != nullptr);

  CheckNullInstr* check_null = nullptr;
  LoadFieldInstr* load_field = nullptr;
  GenericCheckBoundInstr* bounds_check = nullptr;
  Instruction* load_untagged = nullptr;
  LoadIndexedInstr* load_indexed = nullptr;

  ILMatcher cursor(flow_graph, entry);
  if (IsolateGroup::Current()->null_safety()) {
    RELEASE_ASSERT(cursor.TryMatch({
        kMoveGlob,
        {kMatchAndMoveLoadField, &load_field},
        kMoveGlob,
        kMatchAndMoveBranchTrue,
        kMoveGlob,
        {kMatchAndMoveGenericCheckBound, &bounds_check},
        {kMatchAndMoveLoadUntagged, &load_untagged},
        kMoveParallelMoves,
        {kMatchAndMoveLoadIndexed, &load_indexed},
        kMoveGlob,
        kMatchReturn,
    }));
  } else {
    RELEASE_ASSERT(cursor.TryMatch({
        kMoveGlob,
        {kMatchAndMoveCheckNull, &check_null},
        {kMatchAndMoveLoadField, &load_field},
        kMoveGlob,
        kMatchAndMoveBranchTrue,
        kMoveGlob,
        {kMatchAndMoveGenericCheckBound, &bounds_check},
        {kMatchAndMoveLoadUntagged, &load_untagged},
        kMoveParallelMoves,
        {kMatchAndMoveLoadIndexed, &load_indexed},
        kMoveGlob,
        kMatchReturn,
    }));
  }

  EXPECT(load_field->InputAt(0)->definition()->IsParameter());
  EXPECT(bounds_check->length()
             ->definition()
             ->OriginalDefinitionIgnoreBoxingAndConstraints() == load_field);
  EXPECT(load_untagged->InputAt(0)->definition()->IsParameter());
  EXPECT(load_indexed->InputAt(0)->definition() == load_untagged);
}

// This test asserts that we are inlining get:length, [] and []= for all typed
// data interfaces.  It also ensures that the asserted IR actually works by
// exercising it.
ISOLATE_UNIT_TEST_CASE(IRTest_TypedDataAOT_FunctionalGetSet) {
  const char* kTemplate =
      R"(
      import 'dart:typed_data';

      void reverse%s(%s list) {
        final length = list.length;
        final halfLength = length ~/ 2;
        for (int i = 0; i < halfLength; ++i) {
          final tmp = list[length-i-1];
          list[length-i-1] = list[i];
          list[i] = tmp;
        }
      }
      )";

  char script_buffer[1024];
  char uri_buffer[1024];
  char function_name[1024];
  auto& lib = Library::Handle();
  auto& function = Function::Handle();

  auto check_il = [&](const char* name) {
    // Fill in the template with the [name].
    Utils::SNPrint(script_buffer, sizeof(script_buffer), kTemplate, name, name);
    Utils::SNPrint(uri_buffer, sizeof(uri_buffer), "file:///reverse-%s.dart",
                   name);
    Utils::SNPrint(function_name, sizeof(function_name), "reverse%s", name);

    // Create a new library, load the function and compile it using our AOT
    // pipeline.
    lib = LoadTestScript(script_buffer, nullptr, uri_buffer);
    function = GetFunction(lib, function_name);
    TestPipeline pipeline(function, CompilerPass::kAOT);
    FlowGraph* flow_graph = pipeline.RunPasses({});
    auto entry = flow_graph->graph_entry()->normal_entry();

    // Ensure the IL matches what we expect.
    ILMatcher cursor(flow_graph, entry);
    if (IsolateGroup::Current()->null_safety()) {
      EXPECT(cursor.TryMatch({
          // Before loop
          kMoveGlob,
          kMatchAndMoveLoadField,
          kMoveGlob,
          kMatchAndMoveBranchTrue,

          // Loop
          kMoveGlob,
          // Load 1
          kMatchAndMoveGenericCheckBound,
          kMoveGlob,
          kMatchAndMoveLoadUntagged,
          kMoveParallelMoves,
          kMatchAndMoveLoadIndexed,
          kMoveGlob,
          // Load 2
          kMatchAndMoveGenericCheckBound,
          kMoveGlob,
          kMatchAndMoveLoadUntagged,
          kMoveParallelMoves,
          kMatchAndMoveLoadIndexed,
          kMoveGlob,
          // Store 1
          kMoveParallelMoves,
          kMatchAndMoveLoadUntagged,
          kMoveParallelMoves,
          kMatchAndMoveStoreIndexed,
          kMoveGlob,
          // Store 2
          kMoveParallelMoves,
          kMatchAndMoveLoadUntagged,
          kMoveParallelMoves,
          kMatchAndMoveStoreIndexed,
          kMoveGlob,

          // Exit the loop.
          kMatchAndMoveBranchFalse,
          kMoveGlob,
          kMatchReturn,
      }));
    } else {
      EXPECT(cursor.TryMatch({
          // Before loop
          kMoveGlob,
          kMatchAndMoveCheckNull,
          kMatchAndMoveLoadField,
          kMoveGlob,
          kMatchAndMoveBranchTrue,

          // Loop
          kMoveGlob,
          // Load 1
          kMatchAndMoveGenericCheckBound,
          kMoveGlob,
          kMatchAndMoveLoadUntagged,
          kMoveParallelMoves,
          kMatchAndMoveLoadIndexed,
          kMoveGlob,
          // Load 2
          kMatchAndMoveGenericCheckBound,
          kMoveGlob,
          kMatchAndMoveLoadUntagged,
          kMoveParallelMoves,
          kMatchAndMoveLoadIndexed,
          kMoveGlob,
          // Store 1
          kMoveParallelMoves,
          kMatchAndMoveLoadUntagged,
          kMoveParallelMoves,
          kMatchAndMoveStoreIndexed,
          kMoveGlob,
          // Store 2
          kMoveParallelMoves,
          kMatchAndMoveLoadUntagged,
          kMoveParallelMoves,
          kMatchAndMoveStoreIndexed,
          kMoveGlob,

          // Exit the loop.
          kMatchAndMoveBranchFalse,
          kMoveGlob,
          kMatchReturn,
      }));
    }
  };

  check_il("Uint8List");
  check_il("Int8List");
  check_il("Uint8ClampedList");
  check_il("Int16List");
  check_il("Uint16List");
  check_il("Int32List");
  check_il("Uint32List");
  check_il("Int64List");
  check_il("Uint64List");
  check_il("Float32List");
  check_il("Float64List");
}

// This test asserts that we get errors if receiver, index or value are null.
ISOLATE_UNIT_TEST_CASE(IRTest_TypedDataAOT_FunctionalIndexError) {
  const char* kTemplate =
      R"(
      import 'dart:typed_data';
      void set%s(%s list, int index, %s value) {
        list[index] = value;
      }
      )";

  char script_buffer[1024];
  char uri_buffer[1024];
  char function_name[1024];
  auto& lib = Library::Handle();
  auto& function = Function::Handle();
  auto& arguments = Array::Handle();
  auto& result = Object::Handle();

  const intptr_t kIndex = 1;
  const intptr_t kLastStage = 3;

  auto run_test = [&](const char* name, const char* type,
                      const TypedDataBase& data, const Object& value,
                      int stage) {
    // Fill in the template with the [name].
    Utils::SNPrint(script_buffer, sizeof(script_buffer), kTemplate, name, name,
                   type);
    Utils::SNPrint(uri_buffer, sizeof(uri_buffer), "file:///set-%s.dart", name);
    Utils::SNPrint(function_name, sizeof(function_name), "set%s", name);

    // Create a new library, load the function and compile it using our AOT
    // pipeline.
    lib = LoadTestScript(script_buffer, nullptr, uri_buffer);
    function = GetFunction(lib, function_name);
    TestPipeline pipeline(function, CompilerPass::kAOT);
    FlowGraph* flow_graph = pipeline.RunPasses({});
    auto entry = flow_graph->graph_entry()->normal_entry();

    // Ensure the IL matches what we expect.
    ILMatcher cursor(flow_graph, entry, /*trace=*/true);
    if (IsolateGroup::Current()->null_safety()) {
      EXPECT(cursor.TryMatch({
          // LoadField length
          kMoveGlob,
          kMatchAndMoveLoadField,

          // Bounds check
          kMoveGlob,
          kMatchAndMoveGenericCheckBound,

          // Store value.
          kMoveGlob,
          kMatchAndMoveLoadUntagged,
          kMoveParallelMoves,
          kMatchAndMoveOptionalUnbox,
          kMoveParallelMoves,
          kMatchAndMoveStoreIndexed,

          // Return
          kMoveGlob,
          kMatchReturn,
      }));
    } else {
      EXPECT(cursor.TryMatch({
          // Receiver null check
          kMoveGlob,
          kMatchAndMoveCheckNull,

          // Index null check
          kMoveGlob,
          kMatchAndMoveCheckNull,

          // Value null check
          kMoveGlob,
          kMatchAndMoveCheckNull,

          // LoadField length
          kMoveGlob,
          kMatchAndMoveLoadField,

          // Bounds check
          kMoveGlob,
          kMatchAndMoveGenericCheckBound,

          // Store value.
          kMoveGlob,
          kMatchAndMoveLoadUntagged,
          kMoveParallelMoves,
          kMatchAndMoveOptionalUnbox,
          kMoveParallelMoves,
          kMatchAndMoveStoreIndexed,

          // Return
          kMoveGlob,
          kMatchReturn,
      }));
    }

    // Compile the graph and attach the code.
    pipeline.CompileGraphAndAttachFunction();

    arguments = Array::New(3);
    arguments.SetAt(0, stage == 0 ? Object::null_object() : data);
    arguments.SetAt(
        1, stage == 1 ? Object::null_object() : Smi::Handle(Smi::New(kIndex)));
    arguments.SetAt(2, stage == 2 ? Object::null_object() : value);
    result = DartEntry::InvokeFunction(function, arguments);

    // Ensure we didn't deoptimize to unoptimized code.
    EXPECT(function.unoptimized_code() == Code::null());

    if (stage == kLastStage) {
      // The last stage must be successful
      EXPECT(result.IsNull());
    } else {
      // Ensure we get an error.
      EXPECT(result.IsUnhandledException());
      result = UnhandledException::Cast(result).exception();
    }
  };

  const auto& uint8_list =
      TypedData::Handle(TypedData::New(kTypedDataUint8ArrayCid, 16));
  const auto& uint8c_list =
      TypedData::Handle(TypedData::New(kTypedDataUint8ClampedArrayCid, 16));
  const auto& int16_list =
      TypedData::Handle(TypedData::New(kTypedDataInt16ArrayCid, 16));
  const auto& uint16_list =
      TypedData::Handle(TypedData::New(kTypedDataUint16ArrayCid, 16));
  const auto& int32_list =
      TypedData::Handle(TypedData::New(kTypedDataInt32ArrayCid, 16));
  const auto& uint32_list =
      TypedData::Handle(TypedData::New(kTypedDataUint32ArrayCid, 16));
  const auto& int64_list =
      TypedData::Handle(TypedData::New(kTypedDataInt64ArrayCid, 16));
  const auto& uint64_list =
      TypedData::Handle(TypedData::New(kTypedDataUint64ArrayCid, 16));
  const auto& float32_list =
      TypedData::Handle(TypedData::New(kTypedDataFloat32ArrayCid, 16));
  const auto& float64_list =
      TypedData::Handle(TypedData::New(kTypedDataFloat64ArrayCid, 16));
  const auto& int8_list =
      TypedData::Handle(TypedData::New(kTypedDataInt8ArrayCid, 16));
  const auto& int_value = Integer::Handle(Integer::New(42));
  const auto& float_value = Double::Handle(Double::New(4.2));
  // With null safety nulls cannot be passed as non-nullable arguments, so
  // skip all error stages and only run the last stage.
  const intptr_t first_stage =
      IsolateGroup::Current()->null_safety() ? kLastStage : 0;
  for (intptr_t stage = first_stage; stage <= kLastStage; ++stage) {
    run_test("Uint8List", "int", int8_list, int_value, stage);
    run_test("Int8List", "int", uint8_list, int_value, stage);
    run_test("Uint8ClampedList", "int", uint8c_list, int_value, stage);
    run_test("Int16List", "int", int16_list, int_value, stage);
    run_test("Uint16List", "int", uint16_list, int_value, stage);
    run_test("Int32List", "int", int32_list, int_value, stage);
    run_test("Uint32List", "int", uint32_list, int_value, stage);
    run_test("Int64List", "int", int64_list, int_value, stage);
    run_test("Uint64List", "int", uint64_list, int_value, stage);
    run_test("Float32List", "double", float32_list, float_value, stage);
    run_test("Float64List", "double", float64_list, float_value, stage);
  }
}

#endif  // defined(DART_PRECOMPILER)

}  // namespace dart
<commit_msg>[vm/test] Fix vm/cc/IRTest_TypedDataAOT_FunctionalGetSet on arm<commit_after>// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include <vector>

#include "vm/closure_functions_cache.h"
#include "vm/compiler/backend/il_printer.h"
#include "vm/compiler/backend/il_test_helper.h"
#include "vm/compiler/call_specializer.h"
#include "vm/compiler/compiler_pass.h"
#include "vm/object.h"
#include "vm/unit_test.h"

namespace dart {

#if defined(DART_PRECOMPILER)

// This test asserts that we are inlining accesses to typed data interfaces
// (e.g. Uint8List) if there are no instantiated 3rd party classes.
ISOLATE_UNIT_TEST_CASE(IRTest_TypedDataAOT_Inlining) {
  const char* kScript =
      R"(
      import 'dart:typed_data';

      foo(Uint8List list, int from) {
        if (from >= list.length) {
          return list[from];
        }
      }
      )";

  const auto& root_library = Library::Handle(LoadTestScript(kScript));
  const auto& function = Function::Handle(GetFunction(root_library, "foo"));

  TestPipeline pipeline(function, CompilerPass::kAOT);
  FlowGraph* flow_graph = pipeline.RunPasses({});

  auto entry = flow_graph->graph_entry()->normal_entry();
  EXPECT(entry != nullptr);

  CheckNullInstr* check_null = nullptr;
  LoadFieldInstr* load_field = nullptr;
  GenericCheckBoundInstr* bounds_check = nullptr;
  Instruction* load_untagged = nullptr;
  LoadIndexedInstr* load_indexed = nullptr;

  ILMatcher cursor(flow_graph, entry);
  if (IsolateGroup::Current()->null_safety()) {
    RELEASE_ASSERT(cursor.TryMatch({
        kMoveGlob,
        {kMatchAndMoveLoadField, &load_field},
        kMoveGlob,
        kMatchAndMoveBranchTrue,
        kMoveGlob,
        {kMatchAndMoveGenericCheckBound, &bounds_check},
        {kMatchAndMoveLoadUntagged, &load_untagged},
        kMoveParallelMoves,
        {kMatchAndMoveLoadIndexed, &load_indexed},
        kMoveGlob,
        kMatchReturn,
    }));
  } else {
    RELEASE_ASSERT(cursor.TryMatch({
        kMoveGlob,
        {kMatchAndMoveCheckNull, &check_null},
        {kMatchAndMoveLoadField, &load_field},
        kMoveGlob,
        kMatchAndMoveBranchTrue,
        kMoveGlob,
        {kMatchAndMoveGenericCheckBound, &bounds_check},
        {kMatchAndMoveLoadUntagged, &load_untagged},
        kMoveParallelMoves,
        {kMatchAndMoveLoadIndexed, &load_indexed},
        kMoveGlob,
        kMatchReturn,
    }));
  }

  EXPECT(load_field->InputAt(0)->definition()->IsParameter());
  EXPECT(bounds_check->length()
             ->definition()
             ->OriginalDefinitionIgnoreBoxingAndConstraints() == load_field);
  EXPECT(load_untagged->InputAt(0)->definition()->IsParameter());
  EXPECT(load_indexed->InputAt(0)->definition() == load_untagged);
}

// This test asserts that we are inlining get:length, [] and []= for all typed
// data interfaces.  It also ensures that the asserted IR actually works by
// exercising it.
ISOLATE_UNIT_TEST_CASE(IRTest_TypedDataAOT_FunctionalGetSet) {
  const char* kTemplate =
      R"(
      import 'dart:typed_data';

      void reverse%s(%s list) {
        final length = list.length;
        final halfLength = length >> 1;
        for (int i = 0; i < halfLength; ++i) {
          final tmp = list[length-i-1];
          list[length-i-1] = list[i];
          list[i] = tmp;
        }
      }
      )";

  char script_buffer[1024];
  char uri_buffer[1024];
  char function_name[1024];
  auto& lib = Library::Handle();
  auto& function = Function::Handle();

  auto check_il = [&](const char* name) {
    // Fill in the template with the [name].
    Utils::SNPrint(script_buffer, sizeof(script_buffer), kTemplate, name, name);
    Utils::SNPrint(uri_buffer, sizeof(uri_buffer), "file:///reverse-%s.dart",
                   name);
    Utils::SNPrint(function_name, sizeof(function_name), "reverse%s", name);

    // Create a new library, load the function and compile it using our AOT
    // pipeline.
    lib = LoadTestScript(script_buffer, nullptr, uri_buffer);
    function = GetFunction(lib, function_name);
    TestPipeline pipeline(function, CompilerPass::kAOT);
    FlowGraph* flow_graph = pipeline.RunPasses({});
    auto entry = flow_graph->graph_entry()->normal_entry();

    // Ensure the IL matches what we expect.
    ILMatcher cursor(flow_graph, entry);
    if (IsolateGroup::Current()->null_safety()) {
      EXPECT(cursor.TryMatch({
          // Before loop
          kMoveGlob,
          kMatchAndMoveLoadField,
          kMoveGlob,
          kMatchAndMoveBranchTrue,

          // Loop
          kMoveGlob,
          // Load 1
          kMatchAndMoveGenericCheckBound,
          kMoveGlob,
          kMatchAndMoveLoadUntagged,
          kMoveParallelMoves,
          kMatchAndMoveLoadIndexed,
          kMoveGlob,
          // Load 2
          kMatchAndMoveGenericCheckBound,
          kMoveGlob,
          kMatchAndMoveLoadUntagged,
          kMoveParallelMoves,
          kMatchAndMoveLoadIndexed,
          kMoveGlob,
          // Store 1
          kMoveParallelMoves,
          kMatchAndMoveLoadUntagged,
          kMoveParallelMoves,
          kMatchAndMoveStoreIndexed,
          kMoveGlob,
          // Store 2
          kMoveParallelMoves,
          kMatchAndMoveLoadUntagged,
          kMoveParallelMoves,
          kMatchAndMoveStoreIndexed,
          kMoveGlob,

          // Exit the loop.
          kMatchAndMoveBranchFalse,
          kMoveGlob,
          kMatchReturn,
      }));
    } else {
      EXPECT(cursor.TryMatch({
          // Before loop
          kMoveGlob,
          kMatchAndMoveCheckNull,
          kMatchAndMoveLoadField,
          kMoveGlob,
          kMatchAndMoveBranchTrue,

          // Loop
          kMoveGlob,
          // Load 1
          kMatchAndMoveGenericCheckBound,
          kMoveGlob,
          kMatchAndMoveLoadUntagged,
          kMoveParallelMoves,
          kMatchAndMoveLoadIndexed,
          kMoveGlob,
          // Load 2
          kMatchAndMoveGenericCheckBound,
          kMoveGlob,
          kMatchAndMoveLoadUntagged,
          kMoveParallelMoves,
          kMatchAndMoveLoadIndexed,
          kMoveGlob,
          // Store 1
          kMoveParallelMoves,
          kMatchAndMoveLoadUntagged,
          kMoveParallelMoves,
          kMatchAndMoveStoreIndexed,
          kMoveGlob,
          // Store 2
          kMoveParallelMoves,
          kMatchAndMoveLoadUntagged,
          kMoveParallelMoves,
          kMatchAndMoveStoreIndexed,
          kMoveGlob,

          // Exit the loop.
          kMatchAndMoveBranchFalse,
          kMoveGlob,
          kMatchReturn,
      }));
    }
  };

  check_il("Uint8List");
  check_il("Int8List");
  check_il("Uint8ClampedList");
  check_il("Int16List");
  check_il("Uint16List");
  check_il("Int32List");
  check_il("Uint32List");
  check_il("Int64List");
  check_il("Uint64List");
  check_il("Float32List");
  check_il("Float64List");
}

// This test asserts that we get errors if receiver, index or value are null.
ISOLATE_UNIT_TEST_CASE(IRTest_TypedDataAOT_FunctionalIndexError) {
  const char* kTemplate =
      R"(
      import 'dart:typed_data';
      void set%s(%s list, int index, %s value) {
        list[index] = value;
      }
      )";

  char script_buffer[1024];
  char uri_buffer[1024];
  char function_name[1024];
  auto& lib = Library::Handle();
  auto& function = Function::Handle();
  auto& arguments = Array::Handle();
  auto& result = Object::Handle();

  const intptr_t kIndex = 1;
  const intptr_t kLastStage = 3;

  auto run_test = [&](const char* name, const char* type,
                      const TypedDataBase& data, const Object& value,
                      int stage) {
    // Fill in the template with the [name].
    Utils::SNPrint(script_buffer, sizeof(script_buffer), kTemplate, name, name,
                   type);
    Utils::SNPrint(uri_buffer, sizeof(uri_buffer), "file:///set-%s.dart", name);
    Utils::SNPrint(function_name, sizeof(function_name), "set%s", name);

    // Create a new library, load the function and compile it using our AOT
    // pipeline.
    lib = LoadTestScript(script_buffer, nullptr, uri_buffer);
    function = GetFunction(lib, function_name);
    TestPipeline pipeline(function, CompilerPass::kAOT);
    FlowGraph* flow_graph = pipeline.RunPasses({});
    auto entry = flow_graph->graph_entry()->normal_entry();

    // Ensure the IL matches what we expect.
    ILMatcher cursor(flow_graph, entry, /*trace=*/true);
    if (IsolateGroup::Current()->null_safety()) {
      EXPECT(cursor.TryMatch({
          // LoadField length
          kMoveGlob,
          kMatchAndMoveLoadField,

          // Bounds check
          kMoveGlob,
          kMatchAndMoveGenericCheckBound,

          // Store value.
          kMoveGlob,
          kMatchAndMoveLoadUntagged,
          kMoveParallelMoves,
          kMatchAndMoveOptionalUnbox,
          kMoveParallelMoves,
          kMatchAndMoveStoreIndexed,

          // Return
          kMoveGlob,
          kMatchReturn,
      }));
    } else {
      EXPECT(cursor.TryMatch({
          // Receiver null check
          kMoveGlob,
          kMatchAndMoveCheckNull,

          // Index null check
          kMoveGlob,
          kMatchAndMoveCheckNull,

          // Value null check
          kMoveGlob,
          kMatchAndMoveCheckNull,

          // LoadField length
          kMoveGlob,
          kMatchAndMoveLoadField,

          // Bounds check
          kMoveGlob,
          kMatchAndMoveGenericCheckBound,

          // Store value.
          kMoveGlob,
          kMatchAndMoveLoadUntagged,
          kMoveParallelMoves,
          kMatchAndMoveOptionalUnbox,
          kMoveParallelMoves,
          kMatchAndMoveStoreIndexed,

          // Return
          kMoveGlob,
          kMatchReturn,
      }));
    }

    // Compile the graph and attach the code.
    pipeline.CompileGraphAndAttachFunction();

    arguments = Array::New(3);
    arguments.SetAt(0, stage == 0 ? Object::null_object() : data);
    arguments.SetAt(
        1, stage == 1 ? Object::null_object() : Smi::Handle(Smi::New(kIndex)));
    arguments.SetAt(2, stage == 2 ? Object::null_object() : value);
    result = DartEntry::InvokeFunction(function, arguments);

    // Ensure we didn't deoptimize to unoptimized code.
    EXPECT(function.unoptimized_code() == Code::null());

    if (stage == kLastStage) {
      // The last stage must be successful
      EXPECT(result.IsNull());
    } else {
      // Ensure we get an error.
      EXPECT(result.IsUnhandledException());
      result = UnhandledException::Cast(result).exception();
    }
  };

  const auto& uint8_list =
      TypedData::Handle(TypedData::New(kTypedDataUint8ArrayCid, 16));
  const auto& uint8c_list =
      TypedData::Handle(TypedData::New(kTypedDataUint8ClampedArrayCid, 16));
  const auto& int16_list =
      TypedData::Handle(TypedData::New(kTypedDataInt16ArrayCid, 16));
  const auto& uint16_list =
      TypedData::Handle(TypedData::New(kTypedDataUint16ArrayCid, 16));
  const auto& int32_list =
      TypedData::Handle(TypedData::New(kTypedDataInt32ArrayCid, 16));
  const auto& uint32_list =
      TypedData::Handle(TypedData::New(kTypedDataUint32ArrayCid, 16));
  const auto& int64_list =
      TypedData::Handle(TypedData::New(kTypedDataInt64ArrayCid, 16));
  const auto& uint64_list =
      TypedData::Handle(TypedData::New(kTypedDataUint64ArrayCid, 16));
  const auto& float32_list =
      TypedData::Handle(TypedData::New(kTypedDataFloat32ArrayCid, 16));
  const auto& float64_list =
      TypedData::Handle(TypedData::New(kTypedDataFloat64ArrayCid, 16));
  const auto& int8_list =
      TypedData::Handle(TypedData::New(kTypedDataInt8ArrayCid, 16));
  const auto& int_value = Integer::Handle(Integer::New(42));
  const auto& float_value = Double::Handle(Double::New(4.2));
  // With null safety nulls cannot be passed as non-nullable arguments, so
  // skip all error stages and only run the last stage.
  const intptr_t first_stage =
      IsolateGroup::Current()->null_safety() ? kLastStage : 0;
  for (intptr_t stage = first_stage; stage <= kLastStage; ++stage) {
    run_test("Uint8List", "int", int8_list, int_value, stage);
    run_test("Int8List", "int", uint8_list, int_value, stage);
    run_test("Uint8ClampedList", "int", uint8c_list, int_value, stage);
    run_test("Int16List", "int", int16_list, int_value, stage);
    run_test("Uint16List", "int", uint16_list, int_value, stage);
    run_test("Int32List", "int", int32_list, int_value, stage);
    run_test("Uint32List", "int", uint32_list, int_value, stage);
    run_test("Int64List", "int", int64_list, int_value, stage);
    run_test("Uint64List", "int", uint64_list, int_value, stage);
    run_test("Float32List", "double", float32_list, float_value, stage);
    run_test("Float64List", "double", float64_list, float_value, stage);
  }
}

#endif  // defined(DART_PRECOMPILER)

}  // namespace dart
<|endoftext|>


<commit_before>#include <iostream>

#include "../ptnk/bitvector.h"
#include "../ptnk/page.h"

namespace ptnk
{

typedef tx_id_t ver_t;

namespace stm
{

enum { TPIO_NHASH = 64 };

struct OvrEntry
{
	page_id_t pgidOrig;

	page_id_t pgidOvr;

	ver_t ver;

	OvrEntry* prev;
};

inline int pgidhash(page_id_t pgid)
{
	return pgid % TPIO_NHASH;
}

class __attribute__ ((aligned (8))) LocalOvr
{
public:
	page_id_t searchOvr(page_id_t pgid);
	void newOvr(page_id_t pgidOrig, page_id_t pgidOvr);

private:
	enum { TAG_TXVER_LOCAL = 0 };

	OvrEntry* m_ovrsLocal[TPIO_NHASH];

	//! tx ver id of read snapshot
	ver_t m_verRead;

	//! tx ver id of this tx
	ver_t m_verWrite;

	friend class ActiveOvr;
	bool checkConflict(LocalOvr* other);
	LocalOvr* m_prev;
	bool m_mergeOngoing;
	bool m_merged;
};

class ActiveOvr
{
public:
	bool tryCommit(LocalOvr* lovr);

private:
	void merge(LocalOvr* lovr);

	OvrEntry* m_ovrs[TPIO_NHASH];

	//! latest verified tx
	/*!
	 *	tx in this linked-list are ensured that they do not conflict each other
	 */
	LocalOvr* m_lovrVerifiedTip;
};

page_id_t
LocalOvr::searchOvr(page_id_t pgid)
{
	int h = pgidhash(pgid);
	OvrEntry* e = m_ovrsLocal[h];

	while(e)
	{
		if(e->ver > m_verRead)
		{
			continue;
		}

		if(e->pgidOrig == pgid)
		{
			return e->pgidOvr;
		}

		e = e->prev;
	}

	return pgid; // no actie ovr pg found
}

void
LocalOvr::newOvr(page_id_t pgidOrig, page_id_t pgidOvr)
{
	OvrEntry* e = new OvrEntry;
	e->pgidOrig = pgidOrig;
	e->pgidOvr = pgidOvr;
	e->ver = TAG_TXVER_LOCAL;

	int h = pgidhash(pgidOrig);
	e->prev = m_ovrsLocal[h];
	m_ovrsLocal[h] = e;
}

bool
ActiveOvr::tryCommit(LocalOvr* lovr)
{
	// step 1: validate _lovr_ that it does not conflict with other txs and add _lovr_ to validated ovrs list
	{
		LocalOvr* lovrVerified = NULL;

		for(;;)
		{
			LocalOvr* lovrPrev = m_lovrVerifiedTip;
			lovr->m_prev = lovrPrev;
			lovr->m_verWrite = lovr->m_prev->m_verWrite + 1;
			__sync_synchronize(); // lovr->m_prev must be set BEFORE tip ptr CAS swing below

			LocalOvr* lovrBefore = lovrPrev;
			while(lovrBefore && lovrBefore != lovrVerified)
			{
				if(! lovr->checkConflict(lovrBefore))
				{
					// abort commit
					delete lovr;
					return false;
				}

				lovrVerified = lovrBefore;
				lovrBefore = lovrBefore->m_prev;
			}

			if(__sync_bool_compare_and_swap(&m_lovrVerifiedTip, lovrPrev, lovr))
			{
				// CAS succeed and _lovr_ has been successfully added to list of verified txs...

				break; // step 1 done!
			}
			else
			{
				// some other unverified tx has been added to the list...

				// RETRY!
			}
		}
	}

	// step 2: merge _lovr_
	//         if there are any not yet merged txs, apply that first
	{
		// step 3.1: create vector of un-merged txs
		std::vector<LocalOvr*> lovrsUnmerged;
		for(LocalOvr* o = lovr; o && !o->m_merged; o = o->m_prev)
		{
			lovrsUnmerged.push_back(o);
		}

		// step 3.2: merge txs older one first
		typedef std::vector<LocalOvr*>::const_reverse_iterator it_t;
		for(it_t it = lovrsUnmerged.rbegin(); it != lovrsUnmerged.rend(); ++ it)
		{
			LocalOvr* o = *it;

			if(o->m_merged)	continue; // skip merged tx
			merge(o);
		}
	}

	return true;
}

void
ActiveOvr::merge(LocalOvr* lovr)
{
	// FIXME: really implement the concurrent merge
	if(! __sync_bool_compare_and_swap(&lovr->m_mergeOngoing, false, true))
	{
		// wait until merge complete
		while(! lovr->m_merged)
		{
			 asm volatile("": : :"memory"); // force re-read
		}

		return;
	}

	const ver_t verWrite = lovr->m_verWrite;

	// int off = rand();
	for(int i = 0; i < TPIO_NHASH; ++ i)
	{
		int roti = i; //(i + off) % TPIO_NHASH;

		// find the head entry of local ovrs and fill e->ver fields
		OvrEntry* e = lovr->m_ovrsLocal[roti];
		for(; e && e->ver == LocalOvr::TAG_TXVER_LOCAL; e = e->prev)
		{
			e->ver = lovr->m_verWrite;
		}

		// append the local ovrs list to the current list
		e->prev = m_ovrs[roti];
		__sync_synchronize();

		m_ovrs[roti] = e->prev;
	}

	__sync_synchronize(); // m_merged must be set after actual merge finishes
	lovr->m_merged = true;
}

} // end of namespace stm

} // end of namespace ptnk

using namespace ptnk;
using namespace ptnk::stm;

int
main(int argc, char* argv[])
{
	return 0;
}
<commit_msg>compiles<commit_after>#include <iostream>

#include "../ptnk/bitvector.h"
#include "../ptnk/page.h"

namespace ptnk
{

typedef tx_id_t ver_t;

namespace stm
{

enum { TPIO_NHASH = 64 };

struct OvrEntry
{
	page_id_t pgidOrig;

	page_id_t pgidOvr;

	ver_t ver;

	OvrEntry* prev;
};

inline int pgidhash(page_id_t pgid)
{
	return pgid % TPIO_NHASH;
}

class PgidBloomFilter
{
public:
	PgidBloomFilter()
	{
		::memset(m_bvBloomLocalOvrs, 0, sizeof(m_bvBloomLocalOvrs));
	}

	void add(page_id_t pgid) {}
	bool mayContain(page_id_t pgid) { return true; }
	bool mayContain(const PgidBloomFilter& o) { return true; }

private:
	char m_bvBloomLocalOvrs[16];
};

class __attribute__ ((aligned (8))) LocalOvr
{
public:
	page_id_t searchOvr(page_id_t pgid);
	void newOvr(page_id_t pgidOrig, page_id_t pgidOvr);

private:
	enum { TAG_TXVER_LOCAL = 0 };

	std::vector<OvrEntry> m_ovrsLocal;

	OvrEntry* m_hashOvrs[TPIO_NHASH];

	PgidBloomFilter m_bfOvrs;

	//! tx ver id of read snapshot
	ver_t m_verRead;

	//! tx ver id of this tx
	ver_t m_verWrite;

	friend class ActiveOvr;
	bool checkConflict(LocalOvr* other);
	LocalOvr* m_prev;
	bool m_mergeOngoing;
	bool m_merged;
};

class ActiveOvr
{
public:
	bool tryCommit(LocalOvr* lovr);

private:
	void merge(LocalOvr* lovr);

	OvrEntry* m_hashOvrs[TPIO_NHASH];

	//! latest verified tx
	/*!
	 *	tx in this linked-list are ensured that they do not conflict each other
	 */
	LocalOvr* m_lovrVerifiedTip;
};

page_id_t
LocalOvr::searchOvr(page_id_t pgid)
{
	int h = pgidhash(pgid);
	OvrEntry* e = m_hashOvrs[h];

	while(e)
	{
		if(e->ver > m_verRead)
		{
			continue;
		}

		if(e->pgidOrig == pgid)
		{
			return e->pgidOvr;
		}

		e = e->prev;
	}

	return pgid; // no actie ovr pg found
}

void
LocalOvr::newOvr(page_id_t pgidOrig, page_id_t pgidOvr)
{
	// add entry to m_ovrsLocal
	{
		OvrEntry e;
		e.pgidOrig = pgidOrig;
		e.pgidOvr = pgidOvr;
		e.ver = TAG_TXVER_LOCAL;
		m_ovrsLocal.push_back(e);
	}

	// set up hash
	{
		OvrEntry* e = &m_ovrsLocal.back();

		int h = pgidhash(pgidOrig);
		e->prev = m_hashOvrs[h];
		m_hashOvrs[h] = e;
	}

	// add entry to bloom filter
	m_bfOvrs.add(pgidOrig);
}

bool
LocalOvr::checkConflict(LocalOvr* other)
{
	if(! other->m_bfOvrs.mayContain(m_bfOvrs)) return false;

	const int iE = m_ovrsLocal.size();
	const int jE = other->m_ovrsLocal.size();
	for(int i = 0; i < iE; ++ i)
	{
		page_id_t pgid = m_ovrsLocal[i].pgidOrig;

		if(! other->m_bfOvrs.mayContain(pgid))
		{
			// bloom filter ensures that pgid does not conflict w/ other->m_ovrsLocal...

			// skip
		}
		else
		{
			for(int j = 0; j < jE; ++ j)
			{
				page_id_t pgidO = other->m_ovrsLocal[j].pgidOrig;

				if(pgid == pgidO) return true;
			}
		}
	}

	return false;
}

bool
ActiveOvr::tryCommit(LocalOvr* lovr)
{
	// step 1: validate _lovr_ that it does not conflict with other txs and add _lovr_ to validated ovrs list
	{
		LocalOvr* lovrVerified = NULL;

		for(;;)
		{
			LocalOvr* lovrPrev = m_lovrVerifiedTip;
			lovr->m_prev = lovrPrev;
			lovr->m_verWrite = lovr->m_prev->m_verWrite + 1;
			__sync_synchronize(); // lovr->m_prev must be set BEFORE tip ptr CAS swing below

			for(LocalOvr* lovrBefore = lovrPrev; lovrBefore && lovrBefore != lovrVerified; lovrBefore = lovrBefore->m_prev)
			{
				if(lovr->m_verRead >= lovrBefore->m_verWrite)
				{
					break;
				}

				if(! lovr->checkConflict(lovrBefore))
				{
					// abort commit
					delete lovr;
					return false;
				}
			}
			lovrVerified = lovr->m_prev;

			if(__sync_bool_compare_and_swap(&m_lovrVerifiedTip, lovrPrev, lovr))
			{
				// CAS succeed and _lovr_ has been successfully added to list of verified txs...

				break; // step 1 done!
			}
			else
			{
				// some other unverified tx has been added to the list...

				// RETRY!
			}
		}
	}

	// step 2: merge _lovr_
	//         if there are any not yet merged txs, apply that first
	{
		// step 2.1: create vector of un-merged txs
		std::vector<LocalOvr*> lovrsUnmerged;
		for(LocalOvr* o = lovr; o && !o->m_merged; o = o->m_prev)
		{
			lovrsUnmerged.push_back(o);
		}

		// step 2.2: merge txs older one first
		typedef std::vector<LocalOvr*>::const_reverse_iterator it_t;
		for(it_t it = lovrsUnmerged.rbegin(); it != lovrsUnmerged.rend(); ++ it)
		{
			LocalOvr* o = *it;

			if(o->m_merged)	continue; // skip merged tx
			merge(o);
		}
	}

	return true;
}

void
ActiveOvr::merge(LocalOvr* lovr)
{
	// FIXME: really implement the concurrent merge
	if(! __sync_bool_compare_and_swap(&lovr->m_mergeOngoing, false, true))
	{
		// wait until merge complete
		while(! lovr->m_merged)
		{
			 asm volatile("": : :"memory"); // force re-read
		}

		return;
	}

	const ver_t verWrite = lovr->m_verWrite;

	// int off = rand();
	for(int i = 0; i < TPIO_NHASH; ++ i)
	{
		int roti = i; //(i + off) % TPIO_NHASH;

		// find the head entry of local ovrs and fill e->ver fields
		OvrEntry* e = lovr->m_hashOvrs[roti];
		for(; e && e->ver == LocalOvr::TAG_TXVER_LOCAL; e = e->prev)
		{
			e->ver = lovr->m_verWrite;
		}

		// append the local ovrs list to the current list
		e->prev = m_hashOvrs[roti];
		__sync_synchronize();

		m_hashOvrs[roti] = e->prev;
	}

	__sync_synchronize(); // m_merged must be set after actual merge finishes
	lovr->m_merged = true;
}

} // end of namespace stm

} // end of namespace ptnk

using namespace ptnk;
using namespace ptnk::stm;

int
main(int argc, char* argv[])
{
	return 0;
}
<|endoftext|>


<commit_before>#include "camerasettings.hpp"

#include <QDebug>
#include <QJsonObject>

void rangeRestrictOne(double* d){
    if((*d) > 1){
        (*d) = 1;
    } else if ((*d) < 0){
        (*d) = 0;
    }
}

CameraSettings::CameraSettings(OpenCVCameraSource* s, Filter *f, Parser *p,
                               Recognizer *r, QObject* parent):
    QObject(parent),
    _camSource(s),
    _filter(f),
    _parser(p),
    _recognizer(r),
    _stage(0),
    settings("settings.set",false,false)
{
    if(settings.isNull()){
        settings.setObject(QJsonObject());
        qDebug() << "No settings file";
    } else {
        QJsonObject o = settings.object();
        QJsonValue c; QRgb r; cv::Scalar s;

        qDebug() << "Settings found.";

        c = o["lowColor"];
        r = (unsigned int)c.toInt();
        _filter->lh = qRed(r);
        _filter->ll = qGreen(r);
        _filter->ls = qBlue(r);

        c = o["lowColor"];
        r = (unsigned int)c.toInt();
        _filter->hh = qRed(r);
        _filter->hl = qGreen(r);
        _filter->hs = qBlue(r);

        _filter->updateScalars();
        _filter->printColors();
    }

    //Setup Camera
    //exposure(1,100);
}

CameraSettings::~CameraSettings()
{
    QJsonObject o = settings.object();
    cv::Scalar s = _filter->lowColor;
    QRgb r = qRgb(_filter->lh,_filter->ll,_filter->ls);

    o.insert("lowColor",QJsonValue((int)r));

    s = _filter->highColor;
    r = qRgb(_filter->hh,_filter->hl,_filter->hs);
    o.insert("highColor",QJsonValue((int)r));
    settings.setObject(o);
}

void CameraSettings::fps(double f)
{
    rangeRestrictOne(&f);
    _camSource->set(CV_CAP_PROP_FPS, f);
}

void CameraSettings::brightness(double b)
{
    rangeRestrictOne(&b);
    //Range 30->255
    _camSource->set(CV_CAP_PROP_BRIGHTNESS, b);
}

void CameraSettings::contrast(double c)
{
    rangeRestrictOne(&c);
    //Range 0->10
    _camSource->set(CV_CAP_PROP_CONTRAST, c);
}

void CameraSettings::saturation(double s)
{
    rangeRestrictOne(&s);
    //Range 0->200
    _camSource->set(CV_CAP_PROP_SATURATION, s);
}

void CameraSettings::hue(double h)
{
    rangeRestrictOne(&h);
    _camSource->set(CV_CAP_PROP_HUE, h);
}

void CameraSettings::gain(double g)
{
    rangeRestrictOne(&g);
    _camSource->set(CV_CAP_PROP_GAIN, g);
}

void CameraSettings::exposure(double a, double e)
{
    qDebug("Setting Exposure");
    rangeRestrictOne(&a);
    rangeRestrictOne(&e);
    // 0 - Auto, 1 - Manual
    _camSource->set(CV_CAP_PROP_AUTO_EXPOSURE, a);
    //Range: -11 -> 1
    _camSource->set(CV_CAP_PROP_EXPOSURE,e);
}

void CameraSettings::displayRes(int w, int h)
{
    Q_UNUSED(w)
    Q_UNUSED(h)
    //TODO
}

void CameraSettings::captureRes(int w, int h)
{
    Q_UNUSED(w)
    Q_UNUSED(h)
    //TODO
}

void CameraSettings::resetHandColors()
{
    _filter->resetColors();
}

void CameraSettings::addHandColor(QRgb color)
{
    _filter->addColor(color);
}

void CameraSettings::frameStage(int s)
{
    Q_UNUSED(s)
    _stage = s;
}

void CameraSettings::changeCam(unsigned int c)
{
    _camSource->switchCamera(c);
}

int CameraSettings::stage()
{
    return _stage;
}
<commit_msg>Temporarily removed setting for auto exposure (not working)<commit_after>#include "camerasettings.hpp"

#include <QDebug>
#include <QJsonObject>

void rangeRestrictOne(double* d){
    if((*d) > 1){
        (*d) = 1;
    } else if ((*d) < 0){
        (*d) = 0;
    }
}

CameraSettings::CameraSettings(OpenCVCameraSource* s, Filter *f, Parser *p,
                               Recognizer *r, QObject* parent):
    QObject(parent),
    _camSource(s),
    _filter(f),
    _parser(p),
    _recognizer(r),
    _stage(0),
    settings("settings.set",false,false)
{
    if(settings.isNull()){
        settings.setObject(QJsonObject());
        qDebug() << "No settings file";
    } else {
        QJsonObject o = settings.object();
        QJsonValue c; QRgb r; cv::Scalar s;

        qDebug() << "Settings found.";

        c = o["lowColor"];
        r = (unsigned int)c.toInt();
        _filter->lh = qRed(r);
        _filter->ll = qGreen(r);
        _filter->ls = qBlue(r);

        c = o["lowColor"];
        r = (unsigned int)c.toInt();
        _filter->hh = qRed(r);
        _filter->hl = qGreen(r);
        _filter->hs = qBlue(r);

        _filter->updateScalars();
        _filter->printColors();
    }

    //Setup Camera
    //exposure(1,100);
}

CameraSettings::~CameraSettings()
{
    QJsonObject o = settings.object();
    cv::Scalar s = _filter->lowColor;
    QRgb r = qRgb(_filter->lh,_filter->ll,_filter->ls);

    o.insert("lowColor",QJsonValue((int)r));

    s = _filter->highColor;
    r = qRgb(_filter->hh,_filter->hl,_filter->hs);
    o.insert("highColor",QJsonValue((int)r));
    settings.setObject(o);
}

void CameraSettings::fps(double f)
{
    rangeRestrictOne(&f);
    _camSource->set(CV_CAP_PROP_FPS, f);
}

void CameraSettings::brightness(double b)
{
    rangeRestrictOne(&b);
    //Range 30->255
    _camSource->set(CV_CAP_PROP_BRIGHTNESS, b);
}

void CameraSettings::contrast(double c)
{
    rangeRestrictOne(&c);
    //Range 0->10
    _camSource->set(CV_CAP_PROP_CONTRAST, c);
}

void CameraSettings::saturation(double s)
{
    rangeRestrictOne(&s);
    //Range 0->200
    _camSource->set(CV_CAP_PROP_SATURATION, s);
}

void CameraSettings::hue(double h)
{
    rangeRestrictOne(&h);
    _camSource->set(CV_CAP_PROP_HUE, h);
}

void CameraSettings::gain(double g)
{
    rangeRestrictOne(&g);
    _camSource->set(CV_CAP_PROP_GAIN, g);
}

void CameraSettings::exposure(double a, double e)
{
    qDebug("Setting Exposure");
    //rangeRestrictOne(&a);
    //rangeRestrictOne(&e);

    //Can't seem to get auto exposure to turn back on
    // 0 - Auto, 1 - Manual
    //_camSource->set(CV_CAP_PROP_AUTO_EXPOSURE, a);

    //Range: -11 -> 1
    _camSource->set(CV_CAP_PROP_EXPOSURE,e);
}

void CameraSettings::displayRes(int w, int h)
{
    Q_UNUSED(w)
    Q_UNUSED(h)
    //TODO
}

void CameraSettings::captureRes(int w, int h)
{
    Q_UNUSED(w)
    Q_UNUSED(h)
    //TODO
}

void CameraSettings::resetHandColors()
{
    _filter->resetColors();
}

void CameraSettings::addHandColor(QRgb color)
{
    _filter->addColor(color);
}

void CameraSettings::frameStage(int s)
{
    Q_UNUSED(s)
    _stage = s;
}

void CameraSettings::changeCam(unsigned int c)
{
    _camSource->switchCamera(c);
}

int CameraSettings::stage()
{
    return _stage;
}
<|endoftext|>


<commit_before>#include <QtGui>

#include "Qt5CodeEditor.h"

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

namespace prodbg
{

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

CodeEditor::CodeEditor(QWidget* parent) : QPlainTextEdit(parent)
{
    m_lineNumberArea = new LineNumberArea(this);

    connect(this, SIGNAL(blockCountChanged(int)), this, SLOT(updateLineNumberAreaWidth(int)));
    connect(this, SIGNAL(updateRequest(const QRect &, int)), this, SLOT(updateLineNumberArea(const QRect &, int)));
    connect(this, SIGNAL(cursorPositionChanged()), this, SLOT(highlightCurrentLine()));

    updateLineNumberAreaWidth(0);
    highlightCurrentLine();
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

int CodeEditor::lineNumberAreaWidth()
{
    int digits = 1;
    int max = qMax(1, blockCount());
    while (max >= 10) {
        max /= 10;
        ++digits;
    }

    int space = 3 + fontMetrics().width(QLatin1Char('9')) * digits;

    return space;
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void CodeEditor::updateLineNumberAreaWidth(int /* newBlockCount */)
{
    setViewportMargins(lineNumberAreaWidth(), 0, 0, 0);
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void CodeEditor::updateLineNumberArea(const QRect &rect, int dy)
{
    if (dy)
        m_lineNumberArea->scroll(0, dy);
    else
        m_lineNumberArea->update(0, rect.y(), m_lineNumberArea->width(), rect.height());

    if (rect.contains(viewport()->rect()))
        updateLineNumberAreaWidth(0);
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void CodeEditor::resizeEvent(QResizeEvent *e)
{
    QPlainTextEdit::resizeEvent(e);

    QRect cr = contentsRect();
    m_lineNumberArea->setGeometry(QRect(cr.left(), cr.top(), lineNumberAreaWidth(), cr.height()));
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void CodeEditor::highlightCurrentLine()
{
    QList<QTextEdit::ExtraSelection> extraSelections;

    if (!isReadOnly()) {
        QTextEdit::ExtraSelection selection;

        QColor lineColor = QColor(Qt::yellow).lighter(160);

        selection.format.setBackground(lineColor);
        selection.format.setProperty(QTextFormat::FullWidthSelection, true);
        selection.cursor = textCursor();
        selection.cursor.clearSelection();
        extraSelections.append(selection);
    }

    setExtraSelections(extraSelections);
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void CodeEditor::lineNumberAreaPaintEvent(QPaintEvent *event)
{
    QPainter painter(m_lineNumberArea);
    painter.fillRect(event->rect(), Qt::lightGray);

    QTextBlock block = firstVisibleBlock();
    int blockNumber = block.blockNumber();
    int top = (int) blockBoundingGeometry(block).translated(contentOffset()).top();
    int bottom = top + (int) blockBoundingRect(block).height();

    while (block.isValid() && top <= event->rect().bottom())
    {
        if (block.isVisible() && bottom >= event->rect().top())
        {
            QString number = QString::number(blockNumber + 1);
            painter.setPen(Qt::black);
            painter.drawText(0, top, m_lineNumberArea->width(), fontMetrics().height(),
                             Qt::AlignRight, number);
        }

        block = block.next();
        top = bottom;
        bottom = top + (int) blockBoundingRect(block).height();
        ++blockNumber;
    }
}

}

<commit_msg>Minor cleanup<commit_after>#include <QtGui>

#include "Qt5CodeEditor.h"

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

namespace prodbg
{

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

CodeEditor::CodeEditor(QWidget* parent) : QPlainTextEdit(parent)
{
    m_lineNumberArea = new LineNumberArea(this);

    connect(this, SIGNAL(blockCountChanged(int)), this, SLOT(updateLineNumberAreaWidth(int)));
    connect(this, SIGNAL(updateRequest(const QRect &, int)), this, SLOT(updateLineNumberArea(const QRect&, int)));
    connect(this, SIGNAL(cursorPositionChanged()), this, SLOT(highlightCurrentLine()));

    updateLineNumberAreaWidth(0);
    highlightCurrentLine();
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

int CodeEditor::lineNumberAreaWidth()
{
    int digits = 1;
    int max = qMax(1, blockCount());
    while (max >= 10) {
        max /= 10;
        ++digits;
    }

    int space = 3 + fontMetrics().width(QLatin1Char('9')) * digits;

    return space;
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void CodeEditor::updateLineNumberAreaWidth(int /* newBlockCount */)
{
    setViewportMargins(lineNumberAreaWidth(), 0, 0, 0);
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void CodeEditor::updateLineNumberArea(const QRect &rect, int dy)
{
    if (dy)
        m_lineNumberArea->scroll(0, dy);
    else
        m_lineNumberArea->update(0, rect.y(), m_lineNumberArea->width(), rect.height());

    if (rect.contains(viewport()->rect()))
        updateLineNumberAreaWidth(0);
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void CodeEditor::resizeEvent(QResizeEvent *e)
{
    QPlainTextEdit::resizeEvent(e);

    QRect cr = contentsRect();
    m_lineNumberArea->setGeometry(QRect(cr.left(), cr.top(), lineNumberAreaWidth(), cr.height()));
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void CodeEditor::highlightCurrentLine()
{
    QList<QTextEdit::ExtraSelection> extraSelections;

    if (!isReadOnly()) {
        QTextEdit::ExtraSelection selection;

        QColor lineColor = QColor(Qt::yellow).lighter(160);

        selection.format.setBackground(lineColor);
        selection.format.setProperty(QTextFormat::FullWidthSelection, true);
        selection.cursor = textCursor();
        selection.cursor.clearSelection();
        extraSelections.append(selection);
    }

    setExtraSelections(extraSelections);
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void CodeEditor::lineNumberAreaPaintEvent(QPaintEvent *event)
{
    QPainter painter(m_lineNumberArea);
    painter.fillRect(event->rect(), Qt::lightGray);

    QTextBlock block = firstVisibleBlock();
    int blockNumber = block.blockNumber();
    int top = (int) blockBoundingGeometry(block).translated(contentOffset()).top();
    int bottom = top + (int) blockBoundingRect(block).height();

    while (block.isValid() && top <= event->rect().bottom())
    {
        if (block.isVisible() && bottom >= event->rect().top())
        {
            QString number = QString::number(blockNumber + 1);
            painter.setPen(Qt::black);
            painter.drawText(0, top, m_lineNumberArea->width(), fontMetrics().height(),
                             Qt::AlignRight, number);
        }

        block = block.next();
        top = bottom;
        bottom = top + (int) blockBoundingRect(block).height();
        ++blockNumber;
    }
}

}

<|endoftext|>


<commit_before>/*
 * DepthSense SDK for Python and SimpleCV
 * -----------------------------------------------------------------------------
 * file:            depthsense.cxx
 * author:          Abdi Dahir
 * modified:        May 9 2014
 * vim:             set fenc=utf-8:ts=4:sw=4:expandtab:
 *
 * DepthSense hooks happen here. Initializes camera and buffers.
 * -----------------------------------------------------------------------------
 */

// MS completly untested
#ifdef _MSC_VER
#include <windows.h>
#endif

// C includes
#include <stdio.h>
#ifndef _MSC_VER
#include <stdint.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/mman.h>
#include <pthread.h>
#include <unistd.h>
#endif
#include <stdlib.h>
#include <string.h>

// C++ includes
#include <vector>
#include <exception>
#include <iostream>
#include <fstream>

// DepthSense SDK includes
#include <DepthSense.hxx>

// Application includes
#include "initdepthsense.h"

using namespace DepthSense;
using namespace std;

// depth sense node inits
static Context g_context;
static DepthNode g_dnode;
static ColorNode g_cnode;
static AudioNode g_anode;

static bool g_bDeviceFound = false;

// unecassary frame counters
static uint32_t g_aFrames = 0;
static uint32_t g_cFrames = 0;
static uint32_t g_dFrames = 0;

// shared mem
int16_t *depthMap;
int16_t *depthFullMap;

int16_t *vertexMap;
int16_t *vertexFullMap;

uint8_t *colourMap;
uint8_t *colourFullMap;

float *uvMap;
float *uvFullMap;

float *vertexFMap;
float *vertexFFullMap;

float *accelMap;
float *accelFullMap;

// proc mem
int16_t * depthCMap;
uint8_t * depthColouredMap;

// thread for running processing loop
#ifndef _MSC_VER
pthread_t looper;
#else
HANDLE looper;
#endif

// can't write atomic op but i can atleast do a swap
static void uptrSwap (uint8_t **pa, uint8_t **pb){
        uint8_t *temp = *pa;
        *pa = *pb;
        *pb = temp;
}

static void fptrSwap (float **pa, float **pb){
        float *temp = *pa;
        *pa = *pb;
        *pb = temp;
}

static void iptrSwap (int16_t **pa, int16_t **pb){
        int16_t *temp = *pa;
        *pa = *pb;
        *pb = temp;
}

/*----------------------------------------------------------------------------*/
// New audio sample event handler
static void onNewAudioSample(AudioNode node, AudioNode::NewSampleReceivedData data)
{
    //printf("A#%u: %d\n",g_aFrames,data.audioData.size());
    g_aFrames++;
}

/*----------------------------------------------------------------------------*/
// New color sample event handler
static void onNewColorSample(ColorNode node, ColorNode::NewSampleReceivedData data)
{
    //printf("C#%u: %d\n",g_cFrames,data.colorMap.size());
    memcpy(colourMap, data.colorMap, 3*cshmsz);
    uptrSwap(&colourMap, &colourFullMap);
    g_cFrames++;
}

/*----------------------------------------------------------------------------*/
// New depth sample event handler
static void onNewDepthSample(DepthNode node, DepthNode::NewSampleReceivedData data)
{
    // Depth
    memcpy(depthMap, data.depthMap, dshmsz);
    iptrSwap(&depthMap, &depthFullMap);

    // Verticies
    Vertex vertex;
    FPVertex fvertex;
    for(int i=0; i < dH; i++) {
        for(int j=0; j < dW; j++) {
            vertex = data.vertices[i*dW + j];
            fvertex = data.verticesFloatingPoint[i*dW + j];

            vertexMap[i*dW*3 + j*3 + 0] = vertex.x;
            vertexMap[i*dW*3 + j*3 + 1] = vertex.y;
            vertexMap[i*dW*3 + j*3 + 2] = vertex.z;

            vertexFMap[i*dW*3 + j*3 + 0] = fvertex.x;
            vertexFMap[i*dW*3 + j*3 + 1] = fvertex.y;
            vertexFMap[i*dW*3 + j*3 + 2] = fvertex.z;
            //cout << vertex.x << vertex.y << vertex.z << endl;
            //cout << fvertex.x << fvertex.y << fvertex.z << endl;

        }
    }

    iptrSwap(&vertexMap, &vertexFullMap);
    fptrSwap(&vertexFMap, &vertexFFullMap);

    // uv
    UV uv;
    for(int i=0; i < dH; i++) {
        for(int j=0; j < dW; j++) {
            uv = data.uvMap[i*dW + j];
            uvMap[i*dW*2 + j*2 + 0] = uv.u;
            uvMap[i*dW*2 + j*2 + 1] = uv.v;
            //cout << uv.u << uv.v << endl;

        }
    }

    fptrSwap(&uvMap, &uvFullMap);

    // Acceleration
    accelMap[0] = data.acceleration.x;
    accelMap[1] = data.acceleration.y;
    accelMap[2] = data.acceleration.z;

    fptrSwap(&accelMap, &accelFullMap);

    g_dFrames++;
}

/*----------------------------------------------------------------------------*/
static void configureAudioNode()
{
    g_anode.newSampleReceivedEvent().connect(&onNewAudioSample);

    AudioNode::Configuration config = g_anode.getConfiguration();
    config.sampleRate = 44100;

    try
    {
        g_context.requestControl(g_anode,0);

        g_anode.setConfiguration(config);

        g_anode.setInputMixerLevel(0.5f);
    }
    catch (ArgumentException& e)
    {
        printf("Argument Exception: %s\n",e.what());
    }
    catch (UnauthorizedAccessException& e)
    {
        printf("Unauthorized Access Exception: %s\n",e.what());
    }
    catch (ConfigurationException& e)
    {
        printf("Configuration Exception: %s\n",e.what());
    }
    catch (StreamingException& e)
    {
        printf("Streaming Exception: %s\n",e.what());
    }
    catch (TimeoutException&)
    {
        printf("TimeoutException\n");
    }
}

/*----------------------------------------------------------------------------*/
static void configureDepthNode()
{
    g_dnode.newSampleReceivedEvent().connect(&onNewDepthSample);

    DepthNode::Configuration config = g_dnode.getConfiguration();
    config.frameFormat = FRAME_FORMAT_QVGA;
    config.framerate = 30;
    config.mode = DepthNode::CAMERA_MODE_CLOSE_MODE;
    config.saturation = true;

    try
    {
        g_context.requestControl(g_dnode,0);
        g_dnode.setConfidenceThreshold(100);

        g_dnode.setEnableDepthMap(true);
        g_dnode.setEnableVertices(true);
        g_dnode.setEnableVerticesFloatingPoint(true);
        g_dnode.setEnableAccelerometer(true);
        g_dnode.setEnableUvMap(true);

        g_dnode.setConfiguration(config);

    }
    catch (ArgumentException& e)
    {
        printf("Argument Exception: %s\n",e.what());
    }
    catch (UnauthorizedAccessException& e)
    {
        printf("Unauthorized Access Exception: %s\n",e.what());
    }
    catch (IOException& e)
    {
        printf("IO Exception: %s\n",e.what());
    }
    catch (InvalidOperationException& e)
    {
        printf("Invalid Operation Exception: %s\n",e.what());
    }
    catch (ConfigurationException& e)
    {
        printf("Configuration Exception: %s\n",e.what());
    }
    catch (StreamingException& e)
    {
        printf("Streaming Exception: %s\n",e.what());
    }
    catch (TimeoutException&)
    {
        printf("TimeoutException\n");
    }

}

/*----------------------------------------------------------------------------*/
static void configureColorNode()
{

    // connect new color sample handler
    g_cnode.newSampleReceivedEvent().connect(&onNewColorSample);

    ColorNode::Configuration config = g_cnode.getConfiguration();
    config.frameFormat = FRAME_FORMAT_VGA;
    config.compression = COMPRESSION_TYPE_MJPEG;
    config.powerLineFrequency = POWER_LINE_FREQUENCY_50HZ;
    config.framerate = 30;

    g_cnode.setEnableColorMap(true);

    try
    {
        g_context.requestControl(g_cnode,0);

        g_cnode.setConfiguration(config);
        g_cnode.setBrightness(0);
        g_cnode.setContrast(5);
        g_cnode.setSaturation(5);
        g_cnode.setHue(0);
        g_cnode.setGamma(3);
        g_cnode.setWhiteBalance(4650);
        g_cnode.setSharpness(5);
        g_cnode.setWhiteBalanceAuto(true);

    }
    catch (ArgumentException& e)
    {
        printf("Argument Exception: %s\n",e.what());
    }
    catch (UnauthorizedAccessException& e)
    {
        printf("Unauthorized Access Exception: %s\n",e.what());
    }
    catch (IOException& e)
    {
        printf("IO Exception: %s\n",e.what());
    }
    catch (InvalidOperationException& e)
    {
        printf("Invalid Operation Exception: %s\n",e.what());
    }
    catch (ConfigurationException& e)
    {
        printf("Configuration Exception: %s\n",e.what());
    }
    catch (StreamingException& e)
    {
        printf("Streaming Exception: %s\n",e.what());
    }
    catch (TimeoutException&)
    {
        printf("TimeoutException\n");
    }

}

/*----------------------------------------------------------------------------*/
static void configureNode(Node node)
{
    if ((node.is<DepthNode>())&&(!g_dnode.isSet()))
    {
        g_dnode = node.as<DepthNode>();
        configureDepthNode();
        g_context.registerNode(node);
    }

    if ((node.is<ColorNode>())&&(!g_cnode.isSet()))
    {
        g_cnode = node.as<ColorNode>();
        configureColorNode();
        g_context.registerNode(node);
    }

    if ((node.is<AudioNode>())&&(!g_anode.isSet()))
    {
        g_anode = node.as<AudioNode>();
        configureAudioNode();
        // Audio seems to take up bandwith on usb3.0 devices ... we'll make this a param
        //g_context.registerNode(node);
    }
}

/*----------------------------------------------------------------------------*/
static void onNodeConnected(Device device, Device::NodeAddedData data)
{
    configureNode(data.node);
}

/*----------------------------------------------------------------------------*/
static void onNodeDisconnected(Device device, Device::NodeRemovedData data)
{
    if (data.node.is<AudioNode>() && (data.node.as<AudioNode>() == g_anode))
        g_anode.unset();
    if (data.node.is<ColorNode>() && (data.node.as<ColorNode>() == g_cnode))
        g_cnode.unset();
    if (data.node.is<DepthNode>() && (data.node.as<DepthNode>() == g_dnode))
        g_dnode.unset();
    printf("Node disconnected\n");
}

/*----------------------------------------------------------------------------*/
static void onDeviceConnected(Context context, Context::DeviceAddedData data)
{
    if (!g_bDeviceFound)
    {
        data.device.nodeAddedEvent().connect(&onNodeConnected);
        data.device.nodeRemovedEvent().connect(&onNodeDisconnected);
        g_bDeviceFound = true;
    }
}

/*----------------------------------------------------------------------------*/
static void onDeviceDisconnected(Context context, Context::DeviceRemovedData data)
{
    g_bDeviceFound = false;
    printf("Device disconnected\n");
}

static void * initblock(int sz)
{
    void * block;
    if ((block = malloc(sz)) == NULL) {
        perror("malloc: cannot alloc mem;");
        exit(1);
    }

    return block;
}

void killds()
{
    cout << "DEPTHSENSE SHUTDOWN IN PROGRESS ..." << endl;
    g_context.quit();
    #ifndef _MSC_VER
    pthread_join(looper, NULL);
    #else
    WaitForSingleObject(looper, NULL);
    #endif
    cout << "THREAD EXIT" << endl;
    free(depthMap);
    free(depthFullMap);
    free(colourMap);
    free(colourFullMap);
    free(vertexMap);
    free(vertexFullMap);
    free(vertexFMap);
    free(vertexFFullMap);
    free(uvMap);
    free(uvFullMap);
    free(depthCMap);
    free(depthColouredMap);

    cout << "DEPTHSENSE SHUTDOWN SUCCESSFUL" << endl;
}

#ifndef _MSC_VER
void* loopfunc(void *arg)
#else
DWORD WINAPI loopfunc(void *arg)
#endif
{
    cout << "EVENT LOOP RUNNING" << endl;
    g_context.run();
    cout << "EVENT LOOP FINISHED" << endl;
    return 0;
}

void initds()
{
    // shared mem double buffers
    depthMap = (int16_t *) initblock(dshmsz);
    depthFullMap = (int16_t *) initblock(dshmsz);

    accelMap = (float *) initblock(3*sizeof(float));
    accelFullMap = (float *) initblock(3*sizeof(float));

    colourMap = (uint8_t *) initblock(cshmsz*3);
    colourFullMap = (uint8_t *) initblock(cshmsz*3);

    vertexMap = (int16_t *) initblock(vshmsz*3);
    vertexFullMap = (int16_t *) initblock(vshmsz*3);

    uvMap = (float *) initblock(ushmsz*2);
    uvFullMap = (float *) initblock(ushmsz*2);

    vertexFMap = (float *) initblock(ushmsz*3);
    vertexFFullMap = (float *) initblock(ushmsz*3);

    // mem buffer blocks
    depthCMap = (int16_t *) initblock(dshmsz);
    depthColouredMap = (uint8_t *) initblock(hshmsz*3);

    // prepare the context
    g_context = Context::createStandalone();
    // TODO: Support multiple cameras ... standalone mode forces
    // a single session, can instead create a server once and join
    // to that server each time. Allow a list of devices
    //g_context = Context::create("localhost");
    g_context.deviceAddedEvent().connect(&onDeviceConnected);
    g_context.deviceRemovedEvent().connect(&onDeviceDisconnected);

    // Get the list of currently connected devices
    vector<Device> da = g_context.getDevices();

    // We are only interested in the first device
    if (da.size() >= 1)
    {
        g_bDeviceFound = true;

        da[0].nodeAddedEvent().connect(&onNodeConnected);
        da[0].nodeRemovedEvent().connect(&onNodeDisconnected);

        vector<Node> na = da[0].getNodes();

        for (int n = 0; n < (int)na.size();n++)
            configureNode(na[n]);
    }

    g_context.startNodes();

    // launch processing loop in a separate thread
    #ifndef _MSC_VER
    pthread_create(&looper, NULL, loopfunc, (void*)NULL);
    #else
    looper = CreateThread(NULL, 0, loopfunc, (void*)NULL, 0, NULL);
    #endif
}

<commit_msg>close thread handle on windows<commit_after>/*
 * DepthSense SDK for Python and SimpleCV
 * -----------------------------------------------------------------------------
 * file:            depthsense.cxx
 * author:          Abdi Dahir
 * modified:        May 9 2014
 * vim:             set fenc=utf-8:ts=4:sw=4:expandtab:
 *
 * DepthSense hooks happen here. Initializes camera and buffers.
 * -----------------------------------------------------------------------------
 */

// MS completly untested
#ifdef _MSC_VER
#include <windows.h>
#endif

// C includes
#include <stdio.h>
#ifndef _MSC_VER
#include <stdint.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/mman.h>
#include <pthread.h>
#include <unistd.h>
#endif
#include <stdlib.h>
#include <string.h>

// C++ includes
#include <vector>
#include <exception>
#include <iostream>
#include <fstream>

// DepthSense SDK includes
#include <DepthSense.hxx>

// Application includes
#include "initdepthsense.h"

using namespace DepthSense;
using namespace std;

// depth sense node inits
static Context g_context;
static DepthNode g_dnode;
static ColorNode g_cnode;
static AudioNode g_anode;

static bool g_bDeviceFound = false;

// unecassary frame counters
static uint32_t g_aFrames = 0;
static uint32_t g_cFrames = 0;
static uint32_t g_dFrames = 0;

// shared mem
int16_t *depthMap;
int16_t *depthFullMap;

int16_t *vertexMap;
int16_t *vertexFullMap;

uint8_t *colourMap;
uint8_t *colourFullMap;

float *uvMap;
float *uvFullMap;

float *vertexFMap;
float *vertexFFullMap;

float *accelMap;
float *accelFullMap;

// proc mem
int16_t * depthCMap;
uint8_t * depthColouredMap;

// thread for running processing loop
#ifndef _MSC_VER
pthread_t looper;
#else
HANDLE looper;
#endif

// can't write atomic op but i can atleast do a swap
static void uptrSwap (uint8_t **pa, uint8_t **pb){
        uint8_t *temp = *pa;
        *pa = *pb;
        *pb = temp;
}

static void fptrSwap (float **pa, float **pb){
        float *temp = *pa;
        *pa = *pb;
        *pb = temp;
}

static void iptrSwap (int16_t **pa, int16_t **pb){
        int16_t *temp = *pa;
        *pa = *pb;
        *pb = temp;
}

/*----------------------------------------------------------------------------*/
// New audio sample event handler
static void onNewAudioSample(AudioNode node, AudioNode::NewSampleReceivedData data)
{
    //printf("A#%u: %d\n",g_aFrames,data.audioData.size());
    g_aFrames++;
}

/*----------------------------------------------------------------------------*/
// New color sample event handler
static void onNewColorSample(ColorNode node, ColorNode::NewSampleReceivedData data)
{
    //printf("C#%u: %d\n",g_cFrames,data.colorMap.size());
    memcpy(colourMap, data.colorMap, 3*cshmsz);
    uptrSwap(&colourMap, &colourFullMap);
    g_cFrames++;
}

/*----------------------------------------------------------------------------*/
// New depth sample event handler
static void onNewDepthSample(DepthNode node, DepthNode::NewSampleReceivedData data)
{
    // Depth
    memcpy(depthMap, data.depthMap, dshmsz);
    iptrSwap(&depthMap, &depthFullMap);

    // Verticies
    Vertex vertex;
    FPVertex fvertex;
    for(int i=0; i < dH; i++) {
        for(int j=0; j < dW; j++) {
            vertex = data.vertices[i*dW + j];
            fvertex = data.verticesFloatingPoint[i*dW + j];

            vertexMap[i*dW*3 + j*3 + 0] = vertex.x;
            vertexMap[i*dW*3 + j*3 + 1] = vertex.y;
            vertexMap[i*dW*3 + j*3 + 2] = vertex.z;

            vertexFMap[i*dW*3 + j*3 + 0] = fvertex.x;
            vertexFMap[i*dW*3 + j*3 + 1] = fvertex.y;
            vertexFMap[i*dW*3 + j*3 + 2] = fvertex.z;
            //cout << vertex.x << vertex.y << vertex.z << endl;
            //cout << fvertex.x << fvertex.y << fvertex.z << endl;

        }
    }

    iptrSwap(&vertexMap, &vertexFullMap);
    fptrSwap(&vertexFMap, &vertexFFullMap);

    // uv
    UV uv;
    for(int i=0; i < dH; i++) {
        for(int j=0; j < dW; j++) {
            uv = data.uvMap[i*dW + j];
            uvMap[i*dW*2 + j*2 + 0] = uv.u;
            uvMap[i*dW*2 + j*2 + 1] = uv.v;
            //cout << uv.u << uv.v << endl;

        }
    }

    fptrSwap(&uvMap, &uvFullMap);

    // Acceleration
    accelMap[0] = data.acceleration.x;
    accelMap[1] = data.acceleration.y;
    accelMap[2] = data.acceleration.z;

    fptrSwap(&accelMap, &accelFullMap);

    g_dFrames++;
}

/*----------------------------------------------------------------------------*/
static void configureAudioNode()
{
    g_anode.newSampleReceivedEvent().connect(&onNewAudioSample);

    AudioNode::Configuration config = g_anode.getConfiguration();
    config.sampleRate = 44100;

    try
    {
        g_context.requestControl(g_anode,0);

        g_anode.setConfiguration(config);

        g_anode.setInputMixerLevel(0.5f);
    }
    catch (ArgumentException& e)
    {
        printf("Argument Exception: %s\n",e.what());
    }
    catch (UnauthorizedAccessException& e)
    {
        printf("Unauthorized Access Exception: %s\n",e.what());
    }
    catch (ConfigurationException& e)
    {
        printf("Configuration Exception: %s\n",e.what());
    }
    catch (StreamingException& e)
    {
        printf("Streaming Exception: %s\n",e.what());
    }
    catch (TimeoutException&)
    {
        printf("TimeoutException\n");
    }
}

/*----------------------------------------------------------------------------*/
static void configureDepthNode()
{
    g_dnode.newSampleReceivedEvent().connect(&onNewDepthSample);

    DepthNode::Configuration config = g_dnode.getConfiguration();
    config.frameFormat = FRAME_FORMAT_QVGA;
    config.framerate = 30;
    config.mode = DepthNode::CAMERA_MODE_CLOSE_MODE;
    config.saturation = true;

    try
    {
        g_context.requestControl(g_dnode,0);
        g_dnode.setConfidenceThreshold(100);

        g_dnode.setEnableDepthMap(true);
        g_dnode.setEnableVertices(true);
        g_dnode.setEnableVerticesFloatingPoint(true);
        g_dnode.setEnableAccelerometer(true);
        g_dnode.setEnableUvMap(true);

        g_dnode.setConfiguration(config);

    }
    catch (ArgumentException& e)
    {
        printf("Argument Exception: %s\n",e.what());
    }
    catch (UnauthorizedAccessException& e)
    {
        printf("Unauthorized Access Exception: %s\n",e.what());
    }
    catch (IOException& e)
    {
        printf("IO Exception: %s\n",e.what());
    }
    catch (InvalidOperationException& e)
    {
        printf("Invalid Operation Exception: %s\n",e.what());
    }
    catch (ConfigurationException& e)
    {
        printf("Configuration Exception: %s\n",e.what());
    }
    catch (StreamingException& e)
    {
        printf("Streaming Exception: %s\n",e.what());
    }
    catch (TimeoutException&)
    {
        printf("TimeoutException\n");
    }

}

/*----------------------------------------------------------------------------*/
static void configureColorNode()
{

    // connect new color sample handler
    g_cnode.newSampleReceivedEvent().connect(&onNewColorSample);

    ColorNode::Configuration config = g_cnode.getConfiguration();
    config.frameFormat = FRAME_FORMAT_VGA;
    config.compression = COMPRESSION_TYPE_MJPEG;
    config.powerLineFrequency = POWER_LINE_FREQUENCY_50HZ;
    config.framerate = 30;

    g_cnode.setEnableColorMap(true);

    try
    {
        g_context.requestControl(g_cnode,0);

        g_cnode.setConfiguration(config);
        g_cnode.setBrightness(0);
        g_cnode.setContrast(5);
        g_cnode.setSaturation(5);
        g_cnode.setHue(0);
        g_cnode.setGamma(3);
        g_cnode.setWhiteBalance(4650);
        g_cnode.setSharpness(5);
        g_cnode.setWhiteBalanceAuto(true);

    }
    catch (ArgumentException& e)
    {
        printf("Argument Exception: %s\n",e.what());
    }
    catch (UnauthorizedAccessException& e)
    {
        printf("Unauthorized Access Exception: %s\n",e.what());
    }
    catch (IOException& e)
    {
        printf("IO Exception: %s\n",e.what());
    }
    catch (InvalidOperationException& e)
    {
        printf("Invalid Operation Exception: %s\n",e.what());
    }
    catch (ConfigurationException& e)
    {
        printf("Configuration Exception: %s\n",e.what());
    }
    catch (StreamingException& e)
    {
        printf("Streaming Exception: %s\n",e.what());
    }
    catch (TimeoutException&)
    {
        printf("TimeoutException\n");
    }

}

/*----------------------------------------------------------------------------*/
static void configureNode(Node node)
{
    if ((node.is<DepthNode>())&&(!g_dnode.isSet()))
    {
        g_dnode = node.as<DepthNode>();
        configureDepthNode();
        g_context.registerNode(node);
    }

    if ((node.is<ColorNode>())&&(!g_cnode.isSet()))
    {
        g_cnode = node.as<ColorNode>();
        configureColorNode();
        g_context.registerNode(node);
    }

    if ((node.is<AudioNode>())&&(!g_anode.isSet()))
    {
        g_anode = node.as<AudioNode>();
        configureAudioNode();
        // Audio seems to take up bandwith on usb3.0 devices ... we'll make this a param
        //g_context.registerNode(node);
    }
}

/*----------------------------------------------------------------------------*/
static void onNodeConnected(Device device, Device::NodeAddedData data)
{
    configureNode(data.node);
}

/*----------------------------------------------------------------------------*/
static void onNodeDisconnected(Device device, Device::NodeRemovedData data)
{
    if (data.node.is<AudioNode>() && (data.node.as<AudioNode>() == g_anode))
        g_anode.unset();
    if (data.node.is<ColorNode>() && (data.node.as<ColorNode>() == g_cnode))
        g_cnode.unset();
    if (data.node.is<DepthNode>() && (data.node.as<DepthNode>() == g_dnode))
        g_dnode.unset();
    printf("Node disconnected\n");
}

/*----------------------------------------------------------------------------*/
static void onDeviceConnected(Context context, Context::DeviceAddedData data)
{
    if (!g_bDeviceFound)
    {
        data.device.nodeAddedEvent().connect(&onNodeConnected);
        data.device.nodeRemovedEvent().connect(&onNodeDisconnected);
        g_bDeviceFound = true;
    }
}

/*----------------------------------------------------------------------------*/
static void onDeviceDisconnected(Context context, Context::DeviceRemovedData data)
{
    g_bDeviceFound = false;
    printf("Device disconnected\n");
}

static void * initblock(int sz)
{
    void * block;
    if ((block = malloc(sz)) == NULL) {
        perror("malloc: cannot alloc mem;");
        exit(1);
    }

    return block;
}

void killds()
{
    cout << "DEPTHSENSE SHUTDOWN IN PROGRESS ..." << endl;
    g_context.quit();
    #ifndef _MSC_VER
    pthread_join(looper, NULL);
    #else
    WaitForSingleObject(looper, NULL);
    CloseHandle(looper);
    #endif
    cout << "THREAD EXIT" << endl;
    free(depthMap);
    free(depthFullMap);
    free(colourMap);
    free(colourFullMap);
    free(vertexMap);
    free(vertexFullMap);
    free(vertexFMap);
    free(vertexFFullMap);
    free(uvMap);
    free(uvFullMap);
    free(depthCMap);
    free(depthColouredMap);

    cout << "DEPTHSENSE SHUTDOWN SUCCESSFUL" << endl;
}

#ifndef _MSC_VER
void* loopfunc(void *arg)
#else
DWORD WINAPI loopfunc(void *arg)
#endif
{
    cout << "EVENT LOOP RUNNING" << endl;
    g_context.run();
    cout << "EVENT LOOP FINISHED" << endl;
    return 0;
}

void initds()
{
    // shared mem double buffers
    depthMap = (int16_t *) initblock(dshmsz);
    depthFullMap = (int16_t *) initblock(dshmsz);

    accelMap = (float *) initblock(3*sizeof(float));
    accelFullMap = (float *) initblock(3*sizeof(float));

    colourMap = (uint8_t *) initblock(cshmsz*3);
    colourFullMap = (uint8_t *) initblock(cshmsz*3);

    vertexMap = (int16_t *) initblock(vshmsz*3);
    vertexFullMap = (int16_t *) initblock(vshmsz*3);

    uvMap = (float *) initblock(ushmsz*2);
    uvFullMap = (float *) initblock(ushmsz*2);

    vertexFMap = (float *) initblock(ushmsz*3);
    vertexFFullMap = (float *) initblock(ushmsz*3);

    // mem buffer blocks
    depthCMap = (int16_t *) initblock(dshmsz);
    depthColouredMap = (uint8_t *) initblock(hshmsz*3);

    // prepare the context
    g_context = Context::createStandalone();
    // TODO: Support multiple cameras ... standalone mode forces
    // a single session, can instead create a server once and join
    // to that server each time. Allow a list of devices
    //g_context = Context::create("localhost");
    g_context.deviceAddedEvent().connect(&onDeviceConnected);
    g_context.deviceRemovedEvent().connect(&onDeviceDisconnected);

    // Get the list of currently connected devices
    vector<Device> da = g_context.getDevices();

    // We are only interested in the first device
    if (da.size() >= 1)
    {
        g_bDeviceFound = true;

        da[0].nodeAddedEvent().connect(&onNodeConnected);
        da[0].nodeRemovedEvent().connect(&onNodeDisconnected);

        vector<Node> na = da[0].getNodes();

        for (int n = 0; n < (int)na.size();n++)
            configureNode(na[n]);
    }

    g_context.startNodes();

    // launch processing loop in a separate thread
    #ifndef _MSC_VER
    pthread_create(&looper, NULL, loopfunc, (void*)NULL);
    #else
    looper = CreateThread(NULL, 0, loopfunc, (void*)NULL, 0, NULL);
    #endif
}

<|endoftext|>


<commit_before><commit_msg>Typo.<commit_after><|endoftext|>


<commit_before><commit_msg>Fix undefined behaviour<commit_after><|endoftext|>


<commit_before>// Copyright (c) 2014 GitHub, Inc. All rights reserved.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.

#include "atom/browser/ui/views/menu_bar.h"

#if defined(USE_X11)
#include "gtk/gtk.h"
#endif

#include "atom/browser/ui/views/menu_delegate.h"
#include "atom/browser/ui/views/submenu_button.h"
#include "ui/base/models/menu_model.h"
#include "ui/views/background.h"
#include "ui/views/layout/box_layout.h"

#if defined(OS_WIN)
#include "ui/gfx/color_utils.h"
#elif defined(USE_X11)
#include "chrome/browser/ui/libgtk2ui/owned_widget_gtk2.h"
#include "chrome/browser/ui/libgtk2ui/skia_utils_gtk2.h"
#endif

namespace atom {

namespace {

const char kViewClassName[] = "AtomMenuBar";

// Default color of the menu bar.
const SkColor kDefaultColor = SkColorSetARGB(255, 233, 233, 233);

#if defined(USE_X11)
void GetMenuBarColor(SkColor* enabled, SkColor* disabled, SkColor* highlight,
                     SkColor* hover, SkColor* background) {
  libgtk2ui::OwnedWidgetGtk fake_menu_bar;
  fake_menu_bar.Own(gtk_menu_bar_new());

  GtkStyle* style = gtk_rc_get_style(fake_menu_bar.get());
  *enabled = libgtk2ui::GdkColorToSkColor(style->fg[GTK_STATE_NORMAL]);
  *disabled = libgtk2ui::GdkColorToSkColor(style->fg[GTK_STATE_INSENSITIVE]);
  *highlight = libgtk2ui::GdkColorToSkColor(style->fg[GTK_STATE_SELECTED]);
  *hover = libgtk2ui::GdkColorToSkColor(style->fg[GTK_STATE_PRELIGHT]);
  *background = libgtk2ui::GdkColorToSkColor(style->bg[GTK_STATE_NORMAL]);
}
#endif

}  // namespace

MenuBar::MenuBar()
    : background_color_(kDefaultColor),
      menu_model_(NULL) {
#if defined(OS_WIN)
  background_color_ = color_utils::GetSysSkColor(COLOR_MENUBAR);
#elif defined(USE_X11)
  GetMenuBarColor(&enabled_color_, &disabled_color_, &highlight_color_,
                  &hover_color_, &background_color_);
#endif

  set_background(views::Background::CreateSolidBackground(background_color_));
  SetLayoutManager(new views::BoxLayout(
      views::BoxLayout::kHorizontal, 0, 0, 0));
}

MenuBar::~MenuBar() {
}

void MenuBar::SetMenu(ui::MenuModel* model) {
  menu_model_ = model;
  RemoveAllChildViews(true);

  for (int i = 0; i < model->GetItemCount(); ++i) {
    SubmenuButton* button = new SubmenuButton(this, model->GetLabelAt(i), this);
    button->set_tag(i);

#if defined(USE_X11)
    button->SetEnabledColor(enabled_color_);
    button->SetDisabledColor(disabled_color_);
    button->SetHighlightColor(highlight_color_);
    button->SetHoverColor(hover_color_);
    button->SetUnderlineColor(enabled_color_);
#endif

    AddChildView(button);
  }
}

void MenuBar::SetAcceleratorVisibility(bool visible) {
  for (int i = 0; i < child_count(); ++i)
    static_cast<SubmenuButton*>(child_at(i))->SetAcceleratorVisibility(visible);
}

int MenuBar::GetAcceleratorIndex(base::char16 key) {
  for (int i = 0; i < child_count(); ++i) {
    SubmenuButton* button = static_cast<SubmenuButton*>(child_at(i));
    if (button->accelerator() == key)
      return i;
  }
  return -1;
}

void MenuBar::ActivateAccelerator(base::char16 key) {
  int i = GetAcceleratorIndex(key);
  if (i != -1)
    static_cast<SubmenuButton*>(child_at(i))->Activate();
}

int MenuBar::GetItemCount() const {
  return menu_model_->GetItemCount();
}

bool MenuBar::GetMenuButtonFromScreenPoint(const gfx::Point& point,
                                           ui::MenuModel** menu_model,
                                           views::MenuButton** button) {
  gfx::Point location(point);
  views::View::ConvertPointFromScreen(this, &location);

  if (location.x() < 0 || location.x() >= width() || location.y() < 0 ||
      location.y() >= height())
    return false;

  for (int i = 0; i < child_count(); ++i) {
    views::View* view = child_at(i);
    if (view->bounds().Contains(location) &&
        (menu_model_->GetTypeAt(i) == ui::MenuModel::TYPE_SUBMENU)) {
      *menu_model = menu_model_->GetSubmenuModelAt(i);
      *button = static_cast<views::MenuButton*>(view);
      return true;
    }
  }

  return false;
}

const char* MenuBar::GetClassName() const {
  return kViewClassName;
}

void MenuBar::ButtonPressed(views::Button* sender, const ui::Event& event) {
}

void MenuBar::OnMenuButtonClicked(views::View* source,
                                  const gfx::Point& point) {
  // Hide the accelerator when a submenu is activated.
  SetAcceleratorVisibility(false);

  if (!menu_model_)
    return;

  views::MenuButton* button = static_cast<views::MenuButton*>(source);
  int id = button->tag();
  ui::MenuModel::ItemType type = menu_model_->GetTypeAt(id);
  if (type != ui::MenuModel::TYPE_SUBMENU)
    return;

  menu_delegate_.reset(new MenuDelegate(this));
  menu_delegate_->RunMenu(menu_model_->GetSubmenuModelAt(id), button);
}

}  // namespace atom
<commit_msg>win: Underline's color tends to be a little lighter.<commit_after>// Copyright (c) 2014 GitHub, Inc. All rights reserved.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.

#include "atom/browser/ui/views/menu_bar.h"

#if defined(USE_X11)
#include "gtk/gtk.h"
#endif

#include "atom/browser/ui/views/menu_delegate.h"
#include "atom/browser/ui/views/submenu_button.h"
#include "ui/base/models/menu_model.h"
#include "ui/views/background.h"
#include "ui/views/layout/box_layout.h"

#if defined(OS_WIN)
#include "ui/gfx/color_utils.h"
#elif defined(USE_X11)
#include "chrome/browser/ui/libgtk2ui/owned_widget_gtk2.h"
#include "chrome/browser/ui/libgtk2ui/skia_utils_gtk2.h"
#endif

namespace atom {

namespace {

const char kViewClassName[] = "AtomMenuBar";

// Default color of the menu bar.
const SkColor kDefaultColor = SkColorSetARGB(255, 233, 233, 233);

#if defined(USE_X11)
void GetMenuBarColor(SkColor* enabled, SkColor* disabled, SkColor* highlight,
                     SkColor* hover, SkColor* background) {
  libgtk2ui::OwnedWidgetGtk fake_menu_bar;
  fake_menu_bar.Own(gtk_menu_bar_new());

  GtkStyle* style = gtk_rc_get_style(fake_menu_bar.get());
  *enabled = libgtk2ui::GdkColorToSkColor(style->fg[GTK_STATE_NORMAL]);
  *disabled = libgtk2ui::GdkColorToSkColor(style->fg[GTK_STATE_INSENSITIVE]);
  *highlight = libgtk2ui::GdkColorToSkColor(style->fg[GTK_STATE_SELECTED]);
  *hover = libgtk2ui::GdkColorToSkColor(style->fg[GTK_STATE_PRELIGHT]);
  *background = libgtk2ui::GdkColorToSkColor(style->bg[GTK_STATE_NORMAL]);
}
#endif

}  // namespace

MenuBar::MenuBar()
    : background_color_(kDefaultColor),
      menu_model_(NULL) {
#if defined(OS_WIN)
  background_color_ = color_utils::GetSysSkColor(COLOR_MENUBAR);
#elif defined(USE_X11)
  GetMenuBarColor(&enabled_color_, &disabled_color_, &highlight_color_,
                  &hover_color_, &background_color_);
#endif

  set_background(views::Background::CreateSolidBackground(background_color_));
  SetLayoutManager(new views::BoxLayout(
      views::BoxLayout::kHorizontal, 0, 0, 0));
}

MenuBar::~MenuBar() {
}

void MenuBar::SetMenu(ui::MenuModel* model) {
  menu_model_ = model;
  RemoveAllChildViews(true);

  for (int i = 0; i < model->GetItemCount(); ++i) {
    SubmenuButton* button = new SubmenuButton(this, model->GetLabelAt(i), this);
    button->set_tag(i);

#if defined(USE_X11)
    button->SetEnabledColor(enabled_color_);
    button->SetDisabledColor(disabled_color_);
    button->SetHighlightColor(highlight_color_);
    button->SetHoverColor(hover_color_);
    button->SetUnderlineColor(enabled_color_);
#elif defined(OS_WIN)
    button->SetUnderlineColor(color_utils::GetSysSkColor(COLOR_GRAYTEXT));
#endif

    AddChildView(button);
  }
}

void MenuBar::SetAcceleratorVisibility(bool visible) {
  for (int i = 0; i < child_count(); ++i)
    static_cast<SubmenuButton*>(child_at(i))->SetAcceleratorVisibility(visible);
}

int MenuBar::GetAcceleratorIndex(base::char16 key) {
  for (int i = 0; i < child_count(); ++i) {
    SubmenuButton* button = static_cast<SubmenuButton*>(child_at(i));
    if (button->accelerator() == key)
      return i;
  }
  return -1;
}

void MenuBar::ActivateAccelerator(base::char16 key) {
  int i = GetAcceleratorIndex(key);
  if (i != -1)
    static_cast<SubmenuButton*>(child_at(i))->Activate();
}

int MenuBar::GetItemCount() const {
  return menu_model_->GetItemCount();
}

bool MenuBar::GetMenuButtonFromScreenPoint(const gfx::Point& point,
                                           ui::MenuModel** menu_model,
                                           views::MenuButton** button) {
  gfx::Point location(point);
  views::View::ConvertPointFromScreen(this, &location);

  if (location.x() < 0 || location.x() >= width() || location.y() < 0 ||
      location.y() >= height())
    return false;

  for (int i = 0; i < child_count(); ++i) {
    views::View* view = child_at(i);
    if (view->bounds().Contains(location) &&
        (menu_model_->GetTypeAt(i) == ui::MenuModel::TYPE_SUBMENU)) {
      *menu_model = menu_model_->GetSubmenuModelAt(i);
      *button = static_cast<views::MenuButton*>(view);
      return true;
    }
  }

  return false;
}

const char* MenuBar::GetClassName() const {
  return kViewClassName;
}

void MenuBar::ButtonPressed(views::Button* sender, const ui::Event& event) {
}

void MenuBar::OnMenuButtonClicked(views::View* source,
                                  const gfx::Point& point) {
  // Hide the accelerator when a submenu is activated.
  SetAcceleratorVisibility(false);

  if (!menu_model_)
    return;

  views::MenuButton* button = static_cast<views::MenuButton*>(source);
  int id = button->tag();
  ui::MenuModel::ItemType type = menu_model_->GetTypeAt(id);
  if (type != ui::MenuModel::TYPE_SUBMENU)
    return;

  menu_delegate_.reset(new MenuDelegate(this));
  menu_delegate_->RunMenu(menu_model_->GetSubmenuModelAt(id), button);
}

}  // namespace atom
<|endoftext|>


<commit_before>/****************************************************************************
 *
 * (c) 2009-2019 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
 *
 * QGroundControl is licensed according to the terms in the file
 * COPYING.md in the root of the source code directory.
 *
 * @file
 *   @brief Custom Firmware Plugin (PX4)
 *   @author Gus Grubba <gus@auterion.com>
 *
 */

#include "CustomFirmwarePlugin.h"
#include "CustomAutoPilotPlugin.h"

//-----------------------------------------------------------------------------
CustomFirmwarePlugin::CustomFirmwarePlugin()
{
    for (int i = 0; i < _flightModeInfoList.count(); i++) {
        FlightModeInfo_t& info = _flightModeInfoList[i];
        //-- Narrow the flight mode options to only these
        if (info.name != _holdFlightMode && info.name != _rtlFlightMode && info.name != _missionFlightMode) {
            // No other flight modes can be set
            info.canBeSet = false;
        }
    }
}

//-----------------------------------------------------------------------------
AutoPilotPlugin* CustomFirmwarePlugin::autopilotPlugin(Vehicle* vehicle)
{
    return new CustomAutoPilotPlugin(vehicle, vehicle);
}

const QVariantList& CustomFirmwarePlugin::toolIndicators(const Vehicle* vehicle)
{
    if (_toolIndicatorList.size() == 0) {
        // First call the base class to get the standard QGC list. This way we are guaranteed to always get
        // any new toolbar indicators which are added upstream in our custom build.
        _toolIndicatorList = FirmwarePlugin::toolIndicators(vehicle);
        // Then specifically remove the RC RSSI indicator.
        _toolIndicatorList.removeOne(QVariant::fromValue(QUrl::fromUserInput("qrc:/toolbar/RCRSSIIndicator.qml")));
    }
    return _toolIndicatorList;
}

// Tells QGC that your vehicle has a gimbal on it. This will in turn cause thing like gimbal commands to point
// the camera straight down for surveys to be automatically added to Plans.
bool CustomFirmwarePlugin::hasGimbal(Vehicle* /*vehicle*/, bool& rollSupported, bool& pitchSupported, bool& yawSupported)
{
    rollSupported = false;
    pitchSupported = true;
    yawSupported = true;
    return true;
}
<commit_msg>Update CustomFirmwarePlugin.cc<commit_after>/****************************************************************************
 *
 * (c) 2009-2019 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
 *
 * QGroundControl is licensed according to the terms in the file
 * COPYING.md in the root of the source code directory.
 *
 * @file
 *   @brief Custom Firmware Plugin (PX4)
 *   @author Gus Grubba <gus@auterion.com>
 *
 */

#include "CustomFirmwarePlugin.h"
#include "CustomAutoPilotPlugin.h"

//-----------------------------------------------------------------------------
CustomFirmwarePlugin::CustomFirmwarePlugin()
{
    for (int i = 0; i < _flightModeInfoList.count(); i++) {
        FlightModeInfo_t& info = _flightModeInfoList[i];
        //-- Narrow the flight mode options to only these
        if (info.name != _holdFlightMode && info.name != _rtlFlightMode && info.name != _missionFlightMode) {
            // No other flight modes can be set
            info.canBeSet = false;
        }
    }
}

//-----------------------------------------------------------------------------
AutoPilotPlugin* CustomFirmwarePlugin::autopilotPlugin(Vehicle* vehicle)
{
    return new CustomAutoPilotPlugin(vehicle, vehicle);
}

const QVariantList& CustomFirmwarePlugin::toolIndicators(const Vehicle* vehicle)
{
    if (_toolIndicatorList.size() == 0) {
        // First call the base class to get the standard QGC list. This way we are guaranteed to always get
        // any new toolbar indicators which are added upstream in our custom build.
        _toolIndicatorList = FirmwarePlugin::toolIndicators(vehicle);
        // Then specifically remove the RC RSSI indicator.
        _toolIndicatorList.removeOne(QVariant::fromValue(QUrl::fromUserInput("qrc:/toolbar/RCRSSIIndicator.qml")));
    }
    return _toolIndicatorList;
}

// Tells QGC that your vehicle has a gimbal on it. This will in turn cause thing like gimbal commands to point
// the camera straight down for surveys to be automatically added to Plans.
bool CustomFirmwarePlugin::hasGimbal(Vehicle* /*vehicle*/, bool& rollSupported, bool& pitchSupported, bool& yawSupported)
{
    rollSupported = false;
    pitchSupported = true;
    yawSupported = true;

    return true;
}
<|endoftext|>