<commit_before>//===- OpInterfacesGen.cpp - MLIR op interface utility generator ----------===//
//
// Copyright 2019 The MLIR Authors.
//
// 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.
// =============================================================================
//
// OpInterfacesGen generates definitions for operation interfaces.
//
//===----------------------------------------------------------------------===//

#include "mlir/Support/STLExtras.h"
#include "mlir/TableGen/GenInfo.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/TableGen/Error.h"
#include "llvm/TableGen/Record.h"
#include "llvm/TableGen/TableGenBackend.h"

using namespace llvm;
using namespace mlir;

namespace {
// This struct represents a single method argument.
struct MethodArgument {
  StringRef type, name;
};

// Wrapper class around a single interface method.
class OpInterfaceMethod {
public:
  explicit OpInterfaceMethod(const llvm::Record *def) : def(def) {
    llvm::DagInit *args = def->getValueAsDag("arguments");
    for (unsigned i = 0, e = args->getNumArgs(); i != e; ++i) {
      arguments.push_back(
          {llvm::cast<llvm::StringInit>(args->getArg(i))->getValue(),
           args->getArgNameStr(i)});
    }
  }

  // Return the return type of this method.
  StringRef getReturnType() const {
    return def->getValueAsString("returnType");
  }

  // Return the name of this method.
  StringRef getName() const { return def->getValueAsString("name"); }

  // Return if this method is static.
  bool isStatic() const { return def->isSubClassOf("StaticInterfaceMethod"); }

  // Return the body for this method if it has one.
  llvm::Optional<StringRef> getBody() const {
    auto value = def->getValueAsString("body");
    return value.empty() ? llvm::Optional<StringRef>() : value;
  }

  // Arguments.
  ArrayRef<MethodArgument> getArguments() const { return arguments; }
  bool arg_empty() const { return arguments.empty(); }

protected:
  // The TableGen definition of this method.
  const llvm::Record *def;

  // The arguments of this method.
  SmallVector<MethodArgument, 2> arguments;
};

// Wrapper class with helper methods for accessing OpInterfaces defined in
// TableGen.
class OpInterface {
public:
  explicit OpInterface(const llvm::Record *def) : def(def) {
    auto *listInit = dyn_cast<llvm::ListInit>(def->getValueInit("methods"));
    for (llvm::Init *init : listInit->getValues())
      methods.emplace_back(cast<llvm::DefInit>(init)->getDef());
  }

  // Return the name of this interface.
  StringRef getName() const { return def->getValueAsString("cppClassName"); }

  // Return the methods of this interface.
  ArrayRef<OpInterfaceMethod> getMethods() const { return methods; }

protected:
  // The TableGen definition of this interface.
  const llvm::Record *def;

  // The methods of this interface.
  SmallVector<OpInterfaceMethod, 8> methods;
};
} // end anonymous namespace

// Emit the method name and argument list for the given method. If
// 'addOperationArg' is true, then an Operation* argument is added to the
// beginning of the argument list.
static void emitMethodNameAndArgs(const OpInterfaceMethod &method,
                                  raw_ostream &os, bool addOperationArg) {
  os << method.getName() << '(';
  if (addOperationArg)
    os << "Operation *tablegen_opaque_op" << (method.arg_empty() ? "" : ", ");
  interleaveComma(method.getArguments(), os, [&](const MethodArgument &arg) {
    os << arg.type << " " << arg.name;
  });
  os << ')';
}

static void emitInterfaceDef(const Record &interfaceDef, raw_ostream &os) {
  OpInterface interface(&interfaceDef);
  StringRef interfaceName = interface.getName();

  // Insert the method definitions.
  auto *listInit = dyn_cast<ListInit>(interfaceDef.getValueInit("methods"));
  for (Init *init : listInit->getValues()) {
    OpInterfaceMethod method(cast<DefInit>(init)->getDef());
    os << method.getReturnType() << " " << interfaceName << "::";
    emitMethodNameAndArgs(method, os, /*addOperationArg=*/false);

    // Forward to the method on the concrete operation type.
    os << " {\n      return getImpl()->" << method.getName() << '(';
    if (!method.isStatic())
      os << "getOperation()" << (method.arg_empty() ? "" : ", ");
    interleaveComma(method.getArguments(), os,
                    [&](const MethodArgument &arg) { os << arg.name; });
    os << ");\n  }\n";
  }
}

static bool emitInterfaceDefs(const RecordKeeper &recordKeeper,
                              raw_ostream &os) {
  llvm::emitSourceFileHeader("Operation Interface Definitions", os);

  auto defs = recordKeeper.getAllDerivedDefinitions("OpInterface");
  for (const auto *def : defs)
    emitInterfaceDef(*def, os);
  return false;
}

static void emitConceptDecl(const Record &interfaceDef, raw_ostream &os) {
  os << "  class Concept {\n"
     << "  public:\n"
     << "    virtual ~Concept() = default;\n";

  // Insert each of the virtual methods.
  auto *listInit = dyn_cast<ListInit>(interfaceDef.getValueInit("methods"));
  for (Init *init : listInit->getValues()) {
    OpInterfaceMethod method(cast<DefInit>(init)->getDef());

    // In the concept, all methods are pure virtual.
    os << "    virtual " << method.getReturnType() << " ";
    emitMethodNameAndArgs(method, os, /*addOperationArg=*/!method.isStatic());
    os << " = 0;\n";
  }
  os << "  };\n";
}

static void emitModelDecl(const Record &interfaceDef, raw_ostream &os) {
  os << "  template<typename ConcreteOp>\n";
  os << "  class Model : public Concept {\npublic:\n";

  // Insert each of the virtual method overrides.
  auto *listInit = dyn_cast<ListInit>(interfaceDef.getValueInit("methods"));
  for (Init *init : listInit->getValues()) {
    OpInterfaceMethod method(cast<DefInit>(init)->getDef());
    os << "    " << method.getReturnType() << " ";
    emitMethodNameAndArgs(method, os, /*addOperationArg=*/!method.isStatic());
    os << " final {\n";

    // Provide a definition of the concrete op if this is non static.
    if (!method.isStatic()) {
      os << "      auto op = llvm::cast<ConcreteOp>(tablegen_opaque_op);\n"
         << "      (void)op;\n";
    }

    // Check for a provided body to the function.
    if (auto body = method.getBody()) {
      os << body << "\n    }\n";
      continue;
    }

    // Forward to the method on the concrete operation type.
    os << "      return " << (method.isStatic() ? "ConcreteOp::" : "op.");

    // Add the arguments to the call.
    os << method.getName() << '(';
    interleaveComma(method.getArguments(), os,
                    [&](const MethodArgument &arg) { os << arg.name; });
    os << ");\n    }\n";
  }
  os << "  };\n";
}

static void emitInterfaceDecl(const Record &interfaceDef, raw_ostream &os) {
  OpInterface interface(&interfaceDef);
  StringRef interfaceName = interface.getName();
  auto interfaceTraitsName = (interfaceName + "InterfaceTraits").str();

  // Emit the traits struct containing the concept and model declarations.
  os << "namespace detail {\n"
     << "struct " << interfaceTraitsName << " {\n";
  emitConceptDecl(interfaceDef, os);
  emitModelDecl(interfaceDef, os);
  os << "};\n} // end namespace detail\n";

  // Emit the main interface class declaration.
  os << llvm::formatv("class {0} : public OpInterface<{1}, detail::{2}> {\n"
                      "public:\n"
                      "  using OpInterface<{1}, detail::{2}>::OpInterface;\n",
                      interfaceName, interfaceName, interfaceTraitsName);

  // Insert the method declarations.
  for (auto &method : interface.getMethods()) {
    os << "  " << method.getReturnType() << " ";
    emitMethodNameAndArgs(method, os, /*addOperationArg=*/false);
    os << ";\n";
  }
  os << "};\n";
}

static bool emitInterfaceDecls(const RecordKeeper &recordKeeper,
                               raw_ostream &os) {
  llvm::emitSourceFileHeader("Operation Interface Declarations", os);

  auto defs = recordKeeper.getAllDerivedDefinitions("OpInterface");
  for (const auto *def : defs)
    emitInterfaceDecl(*def, os);
  return false;
}

// Registers the operation interface generator to mlir-tblgen.
static mlir::GenRegistration
    genInterfaceDecls("gen-op-interface-decls",
                      "Generate op interface declarations",
                      [](const RecordKeeper &records, raw_ostream &os) {
                        return emitInterfaceDecls(records, os);
                      });

// Registers the operation interface generator to mlir-tblgen.
static mlir::GenRegistration
    genInterfaceDefs("gen-op-interface-defs",
                     "Generate op interface definitions",
                     [](const RecordKeeper &records, raw_ostream &os) {
                       return emitInterfaceDefs(records, os);
                     });
<commit_msg>NFC: Avoid reconstructing the OpInterface methods. PiperOrigin-RevId: 264881293<commit_after>//===- OpInterfacesGen.cpp - MLIR op interface utility generator ----------===//
//
// Copyright 2019 The MLIR Authors.
//
// 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.
// =============================================================================
//
// OpInterfacesGen generates definitions for operation interfaces.
//
//===----------------------------------------------------------------------===//

#include "mlir/Support/STLExtras.h"
#include "mlir/TableGen/GenInfo.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/TableGen/Error.h"
#include "llvm/TableGen/Record.h"
#include "llvm/TableGen/TableGenBackend.h"

using namespace llvm;
using namespace mlir;

namespace {
// This struct represents a single method argument.
struct MethodArgument {
  StringRef type, name;
};

// Wrapper class around a single interface method.
class OpInterfaceMethod {
public:
  explicit OpInterfaceMethod(const llvm::Record *def) : def(def) {
    llvm::DagInit *args = def->getValueAsDag("arguments");
    for (unsigned i = 0, e = args->getNumArgs(); i != e; ++i) {
      arguments.push_back(
          {llvm::cast<llvm::StringInit>(args->getArg(i))->getValue(),
           args->getArgNameStr(i)});
    }
  }

  // Return the return type of this method.
  StringRef getReturnType() const {
    return def->getValueAsString("returnType");
  }

  // Return the name of this method.
  StringRef getName() const { return def->getValueAsString("name"); }

  // Return if this method is static.
  bool isStatic() const { return def->isSubClassOf("StaticInterfaceMethod"); }

  // Return the body for this method if it has one.
  llvm::Optional<StringRef> getBody() const {
    auto value = def->getValueAsString("body");
    return value.empty() ? llvm::Optional<StringRef>() : value;
  }

  // Arguments.
  ArrayRef<MethodArgument> getArguments() const { return arguments; }
  bool arg_empty() const { return arguments.empty(); }

protected:
  // The TableGen definition of this method.
  const llvm::Record *def;

  // The arguments of this method.
  SmallVector<MethodArgument, 2> arguments;
};

// Wrapper class with helper methods for accessing OpInterfaces defined in
// TableGen.
class OpInterface {
public:
  explicit OpInterface(const llvm::Record *def) : def(def) {
    auto *listInit = dyn_cast<llvm::ListInit>(def->getValueInit("methods"));
    for (llvm::Init *init : listInit->getValues())
      methods.emplace_back(cast<llvm::DefInit>(init)->getDef());
  }

  // Return the name of this interface.
  StringRef getName() const { return def->getValueAsString("cppClassName"); }

  // Return the methods of this interface.
  ArrayRef<OpInterfaceMethod> getMethods() const { return methods; }

protected:
  // The TableGen definition of this interface.
  const llvm::Record *def;

  // The methods of this interface.
  SmallVector<OpInterfaceMethod, 8> methods;
};
} // end anonymous namespace

// Emit the method name and argument list for the given method. If
// 'addOperationArg' is true, then an Operation* argument is added to the
// beginning of the argument list.
static void emitMethodNameAndArgs(const OpInterfaceMethod &method,
                                  raw_ostream &os, bool addOperationArg) {
  os << method.getName() << '(';
  if (addOperationArg)
    os << "Operation *tablegen_opaque_op" << (method.arg_empty() ? "" : ", ");
  interleaveComma(method.getArguments(), os, [&](const MethodArgument &arg) {
    os << arg.type << " " << arg.name;
  });
  os << ')';
}

static void emitInterfaceDef(const Record &interfaceDef, raw_ostream &os) {
  OpInterface interface(&interfaceDef);
  StringRef interfaceName = interface.getName();

  // Insert the method definitions.
  for (auto &method : interface.getMethods()) {
    os << method.getReturnType() << " " << interfaceName << "::";
    emitMethodNameAndArgs(method, os, /*addOperationArg=*/false);

    // Forward to the method on the concrete operation type.
    os << " {\n      return getImpl()->" << method.getName() << '(';
    if (!method.isStatic())
      os << "getOperation()" << (method.arg_empty() ? "" : ", ");
    interleaveComma(method.getArguments(), os,
                    [&](const MethodArgument &arg) { os << arg.name; });
    os << ");\n  }\n";
  }
}

static bool emitInterfaceDefs(const RecordKeeper &recordKeeper,
                              raw_ostream &os) {
  llvm::emitSourceFileHeader("Operation Interface Definitions", os);

  auto defs = recordKeeper.getAllDerivedDefinitions("OpInterface");
  for (const auto *def : defs)
    emitInterfaceDef(*def, os);
  return false;
}

static void emitConceptDecl(OpInterface &interface, raw_ostream &os) {
  os << "  class Concept {\n"
     << "  public:\n"
     << "    virtual ~Concept() = default;\n";

  // Insert each of the pure virtual concept methods.
  for (auto &method : interface.getMethods()) {
    os << "    virtual " << method.getReturnType() << " ";
    emitMethodNameAndArgs(method, os, /*addOperationArg=*/!method.isStatic());
    os << " = 0;\n";
  }
  os << "  };\n";
}

static void emitModelDecl(OpInterface &interface, raw_ostream &os) {
  os << "  template<typename ConcreteOp>\n";
  os << "  class Model : public Concept {\npublic:\n";

  // Insert each of the virtual method overrides.
  for (auto &method : interface.getMethods()) {
    os << "    " << method.getReturnType() << " ";
    emitMethodNameAndArgs(method, os, /*addOperationArg=*/!method.isStatic());
    os << " final {\n";

    // Provide a definition of the concrete op if this is non static.
    if (!method.isStatic()) {
      os << "      auto op = llvm::cast<ConcreteOp>(tablegen_opaque_op);\n"
         << "      (void)op;\n";
    }

    // Check for a provided body to the function.
    if (auto body = method.getBody()) {
      os << body << "\n    }\n";
      continue;
    }

    // Forward to the method on the concrete operation type.
    os << "      return " << (method.isStatic() ? "ConcreteOp::" : "op.");

    // Add the arguments to the call.
    os << method.getName() << '(';
    interleaveComma(method.getArguments(), os,
                    [&](const MethodArgument &arg) { os << arg.name; });
    os << ");\n    }\n";
  }
  os << "  };\n";
}

static void emitInterfaceDecl(const Record &interfaceDef, raw_ostream &os) {
  OpInterface interface(&interfaceDef);
  StringRef interfaceName = interface.getName();
  auto interfaceTraitsName = (interfaceName + "InterfaceTraits").str();

  // Emit the traits struct containing the concept and model declarations.
  os << "namespace detail {\n"
     << "struct " << interfaceTraitsName << " {\n";
  emitConceptDecl(interface, os);
  emitModelDecl(interface, os);
  os << "};\n} // end namespace detail\n";

  // Emit the main interface class declaration.
  os << llvm::formatv("class {0} : public OpInterface<{1}, detail::{2}> {\n"
                      "public:\n"
                      "  using OpInterface<{1}, detail::{2}>::OpInterface;\n",
                      interfaceName, interfaceName, interfaceTraitsName);

  // Insert the method declarations.
  for (auto &method : interface.getMethods()) {
    os << "  " << method.getReturnType() << " ";
    emitMethodNameAndArgs(method, os, /*addOperationArg=*/false);
    os << ";\n";
  }
  os << "};\n";
}

static bool emitInterfaceDecls(const RecordKeeper &recordKeeper,
                               raw_ostream &os) {
  llvm::emitSourceFileHeader("Operation Interface Declarations", os);

  auto defs = recordKeeper.getAllDerivedDefinitions("OpInterface");
  for (const auto *def : defs)
    emitInterfaceDecl(*def, os);
  return false;
}

// Registers the operation interface generator to mlir-tblgen.
static mlir::GenRegistration
    genInterfaceDecls("gen-op-interface-decls",
                      "Generate op interface declarations",
                      [](const RecordKeeper &records, raw_ostream &os) {
                        return emitInterfaceDecls(records, os);
                      });

// Registers the operation interface generator to mlir-tblgen.
static mlir::GenRegistration
    genInterfaceDefs("gen-op-interface-defs",
                     "Generate op interface definitions",
                     [](const RecordKeeper &records, raw_ostream &os) {
                       return emitInterfaceDefs(records, os);
                     });
<|endoftext|>


<commit_before>/**
 *  Ownership
 *  =========
 *
 *  Case study of ownership, mainly based on CppCoreGuidelines.
 *
 *  Note: Compile with -std=c++14.
 */

#include <iostream>
#include <type_traits>

// Annotate in the header that the return value of the function is probably
// a pointer that will not be deleted on the heap, passing the ownership to the
// caller.
template <class T, class =std::enable_if_t<std::is_pointer<T>::value>>
using owner = T;

class foo {
	foo()
	{
		std::cout << "foo ctor" << std::endl;
	}

	friend owner<foo*> get_foo();
};

owner<foo*>
get_foo()
{
	return new foo;
}

int
main()
{
	auto p = get_foo();
	delete p;
	return 0;
}
<commit_msg>updated ownership: make a singleton<commit_after>/**
 *  Ownership
 *  =========
 *
 *  Case study of ownership, mainly based on CppCoreGuidelines.
 *
 *  Note: Compile with -std=c++14.
 */

#include <iostream>
#include <type_traits>
#include <cassert>

// Annotate in the header that the return value of the function is probably
// a pointer that will not be deleted on the heap, passing the ownership to the
// caller.
template <class T, class = std::enable_if_t<std::is_pointer<T>::value>>
using owner = T;

class foo {
public:
	static owner<foo*>
	get()
	{
		if (!i_) i_ = new foo;
		return i_;
	}

	static void
	do_something()
	{
		assert(i_ != nullptr && "singleton is not alive");
	}
private:
	foo() = default;

	static foo* i_;
};

foo* foo::i_{};

int
main()
{
	auto p = foo::get();
	p->do_something();
	delete p;

	return 0;
}
<|endoftext|>


<commit_before>// Copyright 2004-present Facebook. All Rights Reserved.

#include <stdio.h>
#include <string.h>
#include <JavaScriptCore/JavaScript.h>
#include <JavaScriptCore/API/JSProfilerPrivate.h>
#include <jsc_legacy_profiler.h>
#include "JSCHelpers.h"
#include "JSCLegacyProfiler.h"

static JSValueRef nativeProfilerStart(
    JSContextRef ctx,
    JSObjectRef function,
    JSObjectRef thisObject,
    size_t argumentCount,
    const JSValueRef arguments[],
    JSValueRef* exception) {
  if (argumentCount < 1) {
    // Could raise an exception here.
    return JSValueMakeUndefined(ctx);
  }

  JSStringRef title = JSValueToStringCopy(ctx, arguments[0], NULL);
  JSStartProfiling(ctx, title);
  JSStringRelease(title);
  return JSValueMakeUndefined(ctx);
}

static JSValueRef nativeProfilerEnd(
    JSContextRef ctx,
    JSObjectRef function,
    JSObjectRef thisObject,
    size_t argumentCount,
    const JSValueRef arguments[],
    JSValueRef* exception) {
  if (argumentCount < 1) {
    // Could raise an exception here.
    return JSValueMakeUndefined(ctx);
  }

  JSStringRef title = JSValueToStringCopy(ctx, arguments[0], NULL);
  JSEndProfilingAndRender(ctx, title, "/sdcard/profile.json");
  JSStringRelease(title);
  return JSValueMakeUndefined(ctx);
}

namespace facebook {
namespace react {

void stopAndOutputProfilingFile(
  JSContextRef ctx,
  JSStringRef title,
  const char *filename) {
  JSEndProfilingAndRender(ctx, title, filename);
}

void addNativeProfilingHooks(JSGlobalContextRef ctx) {
  JSEnableByteCodeProfiling();
  installGlobalFunction(ctx, "nativeProfilerStart", nativeProfilerStart);
  installGlobalFunction(ctx, "nativeProfilerEnd", nativeProfilerEnd);
}

} }
<commit_msg>Allow the output of the JSC profile to be specified in JS<commit_after>// Copyright 2004-present Facebook. All Rights Reserved.

#include <stdio.h>
#include <string.h>
#include <JavaScriptCore/JavaScript.h>
#include <JavaScriptCore/API/JSProfilerPrivate.h>
#include <jsc_legacy_profiler.h>
#include "JSCHelpers.h"
#include "JSCLegacyProfiler.h"
#include "Value.h"

static JSValueRef nativeProfilerStart(
    JSContextRef ctx,
    JSObjectRef function,
    JSObjectRef thisObject,
    size_t argumentCount,
    const JSValueRef arguments[],
    JSValueRef* exception) {
  if (argumentCount < 1) {
    // Could raise an exception here.
    return JSValueMakeUndefined(ctx);
  }

  JSStringRef title = JSValueToStringCopy(ctx, arguments[0], exception);
  JSStartProfiling(ctx, title);
  JSStringRelease(title);
  return JSValueMakeUndefined(ctx);
}

static JSValueRef nativeProfilerEnd(
    JSContextRef ctx,
    JSObjectRef function,
    JSObjectRef thisObject,
    size_t argumentCount,
    const JSValueRef arguments[],
    JSValueRef* exception) {
  if (argumentCount < 1) {
    // Could raise an exception here.
    return JSValueMakeUndefined(ctx);
  }

  std::string writeLocation("/sdcard/");
  if (argumentCount > 1) {
    JSStringRef fileName = JSValueToStringCopy(ctx, arguments[1], exception);
    writeLocation += facebook::react::String::ref(fileName).str();
    JSStringRelease(fileName);
  } else {
    writeLocation += "profile.json";
  }
  JSStringRef title = JSValueToStringCopy(ctx, arguments[0], exception);
  JSEndProfilingAndRender(ctx, title, writeLocation.c_str());
  JSStringRelease(title);
  return JSValueMakeUndefined(ctx);
}

namespace facebook {
namespace react {

void stopAndOutputProfilingFile(
  JSContextRef ctx,
  JSStringRef title,
  const char *filename) {
  JSEndProfilingAndRender(ctx, title, filename);
}

void addNativeProfilingHooks(JSGlobalContextRef ctx) {
  JSEnableByteCodeProfiling();
  installGlobalFunction(ctx, "nativeProfilerStart", nativeProfilerStart);
  installGlobalFunction(ctx, "nativeProfilerEnd", nativeProfilerEnd);
}

} }
<|endoftext|>


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

#include <algorithm>
#include <memory>

#include <gtest/gtest.h>

#include <react/components/root/RootComponentDescriptor.h>
#include <react/components/scrollview/ScrollViewComponentDescriptor.h>
#include <react/components/view/ViewComponentDescriptor.h>
#include <react/element/ComponentBuilder.h>
#include <react/element/Element.h>
#include <react/element/testUtils.h>
#include <react/uimanager/ComponentDescriptorProviderRegistry.h>

using namespace facebook::react;

TEST(ElementTest, testYogaDirtyFlag) {
  auto builder = simpleComponentBuilder();

  auto rootShadowNode = std::shared_ptr<RootShadowNode>{};
  auto innerShadowNode = std::shared_ptr<ViewShadowNode>{};

  // clang-format off
  auto element =
      Element<RootShadowNode>()
        .reference(rootShadowNode)
        .tag(1)
        .children({
          Element<ViewShadowNode>()
            .tag(2),
          Element<ViewShadowNode>()
            .tag(3)
            .reference(innerShadowNode)
            .children({
              Element<ViewShadowNode>()
                .tag(4)
                .props([] {
                  /*
                   * Some non-default props.
                   */
                  auto mutableViewProps = std::make_shared<ViewProps>();
                  auto &props = *mutableViewProps;
                  props.nativeId = "native Id";
                  props.opacity = 0.5;
                  props.yogaStyle.alignContent() = YGAlignBaseline;
                  props.yogaStyle.flexDirection() = YGFlexDirectionRowReverse;
                  return mutableViewProps;
                }),
              Element<ViewShadowNode>()
                .tag(5),
              Element<ViewShadowNode>()
                .tag(6)
            }),
          Element<ScrollViewShadowNode>()
            .tag(9)
        });
  // clang-format on

  builder.build(element);

  /*
   * Yoga nodes are dirty right after creation.
   */
  EXPECT_TRUE(rootShadowNode->layoutIfNeeded());

  /*
   * Yoga nodes are clean (not dirty) right after layout pass.
   */
  EXPECT_FALSE(rootShadowNode->layoutIfNeeded());

  {
    /*
     * Cloning props without changing them must *not* dirty Yoga nodes.
     */
    auto newRootShadowNode =
        std::static_pointer_cast<RootShadowNode>(rootShadowNode->cloneTree(
            innerShadowNode->getFamily(), [](ShadowNode const &oldShadowNode) {
              auto &componentDescriptor =
                  oldShadowNode.getComponentDescriptor();
              auto props = componentDescriptor.cloneProps(
                  oldShadowNode.getProps(), RawProps());
              return oldShadowNode.clone(ShadowNodeFragment{props});
            }));

    EXPECT_FALSE(newRootShadowNode->layoutIfNeeded());
  }

  {
    /*
     * Changing *non-layout* sub-props must *not* dirty Yoga nodes.
     */
    auto newRootShadowNode =
        std::static_pointer_cast<RootShadowNode>(rootShadowNode->cloneTree(
            innerShadowNode->getFamily(), [](ShadowNode const &oldShadowNode) {
              auto viewProps = std::make_shared<ViewProps>();
              auto &props = *viewProps;

              props.nativeId = "some new native Id";
              props.foregroundColor = whiteColor();
              props.backgroundColor = blackColor();
              props.opacity = props.opacity + 0.042;
              props.zIndex = props.zIndex + 42;
              props.shouldRasterize = !props.shouldRasterize;
              props.collapsable = !props.collapsable;

              return oldShadowNode.clone(ShadowNodeFragment{viewProps});
            }));

    EXPECT_FALSE(newRootShadowNode->layoutIfNeeded());
  }

  {
    /*
     * Changing *layout* sub-props *must* dirty Yoga nodes.
     */
    auto newRootShadowNode =
        std::static_pointer_cast<RootShadowNode>(rootShadowNode->cloneTree(
            innerShadowNode->getFamily(), [](ShadowNode const &oldShadowNode) {
              auto viewProps = std::make_shared<ViewProps>();
              auto &props = *viewProps;

              props.yogaStyle.alignContent() = YGAlignBaseline;
              props.yogaStyle.display() = YGDisplayNone;

              return oldShadowNode.clone(ShadowNodeFragment{viewProps});
            }));

    EXPECT_TRUE(newRootShadowNode->layoutIfNeeded());
  }

  {
    /*
     * Removing all children *must* dirty Yoga nodes.
     */
    auto newRootShadowNode =
        std::static_pointer_cast<RootShadowNode>(rootShadowNode->cloneTree(
            innerShadowNode->getFamily(), [](ShadowNode const &oldShadowNode) {
              return oldShadowNode.clone(
                  {ShadowNodeFragment::propsPlaceholder(),
                   ShadowNode::emptySharedShadowNodeSharedList()});
            }));

    EXPECT_TRUE(newRootShadowNode->layoutIfNeeded());
  }

  {
    /*
     * Removing the last child *must* dirty Yoga nodes.
     */
    auto newRootShadowNode =
        std::static_pointer_cast<RootShadowNode>(rootShadowNode->cloneTree(
            innerShadowNode->getFamily(), [](ShadowNode const &oldShadowNode) {
              auto children = oldShadowNode.getChildren();
              children.pop_back();

              std::reverse(children.begin(), children.end());

              return oldShadowNode.clone(
                  {ShadowNodeFragment::propsPlaceholder(),
                   std::make_shared<ShadowNode::ListOfShared const>(children)});
            }));

    EXPECT_TRUE(newRootShadowNode->layoutIfNeeded());
  }

  {
    /*
     * Reversing a list of children *must* dirty Yoga nodes.
     */
    auto newRootShadowNode =
        std::static_pointer_cast<RootShadowNode>(rootShadowNode->cloneTree(
            innerShadowNode->getFamily(), [](ShadowNode const &oldShadowNode) {
              auto children = oldShadowNode.getChildren();

              std::reverse(children.begin(), children.end());

              return oldShadowNode.clone(
                  {ShadowNodeFragment::propsPlaceholder(),
                   std::make_shared<ShadowNode::ListOfShared const>(children)});
            }));

    EXPECT_TRUE(newRootShadowNode->layoutIfNeeded());
  }
}
<commit_msg>Fabric: Modernizing Yoga Dirty flag test.<commit_after>/*
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

#include <algorithm>
#include <memory>

#include <gtest/gtest.h>

#include <react/components/root/RootComponentDescriptor.h>
#include <react/components/scrollview/ScrollViewComponentDescriptor.h>
#include <react/components/view/ViewComponentDescriptor.h>
#include <react/element/ComponentBuilder.h>
#include <react/element/Element.h>
#include <react/element/testUtils.h>
#include <react/uimanager/ComponentDescriptorProviderRegistry.h>

using namespace facebook::react;

class YogaDirtyFlagTest : public ::testing::Test {
 protected:
  ComponentBuilder builder_;
  std::shared_ptr<RootShadowNode> rootShadowNode_;
  std::shared_ptr<ViewShadowNode> innerShadowNode_;
  std::shared_ptr<ScrollViewShadowNode> scrollViewShadowNode_;

  YogaDirtyFlagTest() : builder_(simpleComponentBuilder()) {
    // clang-format off
    auto element =
        Element<RootShadowNode>()
          .reference(rootShadowNode_)
          .tag(1)
          .children({
            Element<ViewShadowNode>()
              .tag(2),
            Element<ViewShadowNode>()
              .tag(3)
              .reference(innerShadowNode_)
              .children({
                Element<ViewShadowNode>()
                  .tag(4)
                  .props([] {
                    /*
                     * Some non-default props.
                     */
                    auto mutableViewProps = std::make_shared<ViewProps>();
                    auto &props = *mutableViewProps;
                    props.nativeId = "native Id";
                    props.opacity = 0.5;
                    props.yogaStyle.alignContent() = YGAlignBaseline;
                    props.yogaStyle.flexDirection() = YGFlexDirectionRowReverse;
                    return mutableViewProps;
                  }),
                Element<ViewShadowNode>()
                  .tag(5),
                Element<ViewShadowNode>()
                  .tag(6),
                Element<ScrollViewShadowNode>()
                  .reference(scrollViewShadowNode_)
                  .tag(7)
              })
          });
    // clang-format on

    builder_.build(element);

    /*
     * Yoga nodes are dirty right after creation.
     */
    EXPECT_TRUE(rootShadowNode_->layoutIfNeeded());

    /*
     * Yoga nodes are clean (not dirty) right after layout pass.
     */
    EXPECT_FALSE(rootShadowNode_->layoutIfNeeded());
  }
};

TEST_F(YogaDirtyFlagTest, cloningPropsWithoutChangingThem) {
  /*
   * Cloning props without changing them must *not* dirty a Yoga node.
   */
  auto newRootShadowNode = rootShadowNode_->cloneTree(
      innerShadowNode_->getFamily(), [](ShadowNode const &oldShadowNode) {
        auto &componentDescriptor = oldShadowNode.getComponentDescriptor();
        auto props = componentDescriptor.cloneProps(
            oldShadowNode.getProps(), RawProps());
        return oldShadowNode.clone(ShadowNodeFragment{props});
      });

  EXPECT_FALSE(
      static_cast<RootShadowNode &>(*newRootShadowNode).layoutIfNeeded());
}

TEST_F(YogaDirtyFlagTest, changingNonLayoutSubPropsMustNotDirtyYogaNode) {
  /*
   * Changing *non-layout* sub-props must *not* dirty a Yoga node.
   */
  auto newRootShadowNode = rootShadowNode_->cloneTree(
      innerShadowNode_->getFamily(), [](ShadowNode const &oldShadowNode) {
        auto viewProps = std::make_shared<ViewProps>();
        auto &props = *viewProps;

        props.nativeId = "some new native Id";
        props.foregroundColor = whiteColor();
        props.backgroundColor = blackColor();
        props.opacity = props.opacity + 0.042;
        props.zIndex = props.zIndex + 42;
        props.shouldRasterize = !props.shouldRasterize;
        props.collapsable = !props.collapsable;

        return oldShadowNode.clone(ShadowNodeFragment{viewProps});
      });

  EXPECT_FALSE(
      static_cast<RootShadowNode &>(*newRootShadowNode).layoutIfNeeded());
}

TEST_F(YogaDirtyFlagTest, changingLayoutSubPropsMustDirtyYogaNode) {
  /*
   * Changing *layout* sub-props *must* dirty a Yoga node.
   */
  auto newRootShadowNode = rootShadowNode_->cloneTree(
      innerShadowNode_->getFamily(), [](ShadowNode const &oldShadowNode) {
        auto viewProps = std::make_shared<ViewProps>();
        auto &props = *viewProps;

        props.yogaStyle.alignContent() = YGAlignBaseline;
        props.yogaStyle.display() = YGDisplayNone;

        return oldShadowNode.clone(ShadowNodeFragment{viewProps});
      });

  EXPECT_TRUE(
      static_cast<RootShadowNode &>(*newRootShadowNode).layoutIfNeeded());
}

TEST_F(YogaDirtyFlagTest, removingAllChildrenMustDirtyYogaNode) {
  /*
   * Removing all children *must* dirty a Yoga node.
   */
  auto newRootShadowNode = rootShadowNode_->cloneTree(
      innerShadowNode_->getFamily(), [](ShadowNode const &oldShadowNode) {
        return oldShadowNode.clone(
            {ShadowNodeFragment::propsPlaceholder(),
             ShadowNode::emptySharedShadowNodeSharedList()});
      });

  EXPECT_TRUE(
      static_cast<RootShadowNode &>(*newRootShadowNode).layoutIfNeeded());
}

TEST_F(YogaDirtyFlagTest, removingLastChildMustDirtyYogaNode) {
  /*
   * Removing the last child *must* dirty the Yoga node.
   */
  auto newRootShadowNode = rootShadowNode_->cloneTree(
      innerShadowNode_->getFamily(), [](ShadowNode const &oldShadowNode) {
        auto children = oldShadowNode.getChildren();
        children.pop_back();

        std::reverse(children.begin(), children.end());

        return oldShadowNode.clone(
            {ShadowNodeFragment::propsPlaceholder(),
             std::make_shared<ShadowNode::ListOfShared const>(children)});
      });

  EXPECT_TRUE(
      static_cast<RootShadowNode &>(*newRootShadowNode).layoutIfNeeded());
}

TEST_F(YogaDirtyFlagTest, reversingListOfChildrenMustDirtyYogaNode) {
  /*
   * Reversing a list of children *must* dirty a Yoga node.
   */
  auto newRootShadowNode = rootShadowNode_->cloneTree(
      innerShadowNode_->getFamily(), [](ShadowNode const &oldShadowNode) {
        auto children = oldShadowNode.getChildren();

        std::reverse(children.begin(), children.end());

        return oldShadowNode.clone(
            {ShadowNodeFragment::propsPlaceholder(),
             std::make_shared<ShadowNode::ListOfShared const>(children)});
      });

  EXPECT_TRUE(
      static_cast<RootShadowNode &>(*newRootShadowNode).layoutIfNeeded());
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: JoinDesignView.cxx,v $
 * $Revision: 1.22 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_dbaccess.hxx"
#ifndef DBAUI_JOINDESIGNVIEW_HXX
#include "JoinDesignView.hxx"
#endif
#ifndef DBAUI_JOINTABLEVIEW_HXX
#include "JoinTableView.hxx"
#endif
#ifndef DBAUI_JOINCONTROLLER_HXX
#include "JoinController.hxx"
#endif
#ifndef _UNDO_HXX
#include <svtools/undo.hxx>
#endif
#ifndef DBAUI_QYDLGTAB_HXX
#include "adtabdlg.hxx"
#endif
#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>
#endif
#ifndef _SV_MSGBOX_HXX
#include <vcl/msgbox.hxx>
#endif
#ifndef DBACCESS_UI_BROWSER_ID_HXX
#include "browserids.hxx"
#endif
#ifndef _DBU_QRY_HRC_
#include "dbu_qry.hrc"
#endif
#ifndef _COMPHELPER_TYPES_HXX_
#include <comphelper/types.hxx>
#endif
#ifndef _CONNECTIVITY_DBTOOLS_HXX_
#include <connectivity/dbtools.hxx>
#endif
#ifndef _COM_SUN_STAR_SDBC_DATATYPE_HPP_
#include <com/sun/star/sdbc/DataType.hpp>
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XNAMEACCESS_HPP_
#include <com/sun/star/container/XNameAccess.hpp>
#endif
#ifndef DBAUI_TABLECONNECTION_HXX
#include "TableConnection.hxx"
#endif
#ifndef DBAUI_CONNECTIONLINE_HXX
#include "ConnectionLine.hxx"
#endif
#ifndef DBAUI_CONNECTIONLINEDATA_HXX
#include "ConnectionLineData.hxx"
#endif
#ifndef DBAUI_TABLECONNECTIONDATA_HXX
#include "TableConnectionData.hxx"
#endif
#ifndef DBACCESS_SHARED_DBUSTRINGS_HRC
#include "dbustrings.hrc"
#endif
#ifndef _COMPHELPER_EXTRACT_HXX_
#include <comphelper/extract.hxx>
#endif
#ifndef DBAUI_TOOLS_HXX
#include "UITools.hxx"
#endif
#ifndef DBAUI_JOINTABLEVIEW_HXX
#include "JoinTableView.hxx"
#endif
//  #include <com/sun/star/util/URL.hdl>

using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::i18n;
using namespace ::com::sun::star::sdbc;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::util;

namespace dbaui
{

// =============================================================================
// = OJoinDesignView
// =============================================================================
// -----------------------------------------------------------------------------
OJoinDesignView::OJoinDesignView(Window* _pParent, OJoinController* _pController,const Reference< XMultiServiceFactory >& _rFactory)
    :ODataView(_pParent,_pController,_rFactory)
    ,m_pTableView(NULL)
    ,m_pController(_pController)
{
    m_pScrollWindow = new OScrollWindowHelper(this);
}
// -----------------------------------------------------------------------------
OJoinDesignView::~OJoinDesignView()
{
    ::std::auto_ptr<Window> aT3(m_pScrollWindow);
    m_pScrollWindow = NULL;
    ::std::auto_ptr<Window> aT2(m_pTableView);
    m_pTableView = NULL;
}
// -------------------------------------------------------------------------
void OJoinDesignView::Construct()
{
    m_pScrollWindow->setTableView(m_pTableView);
    m_pScrollWindow->Show();
    m_pTableView->Show();

    SetBackground( Wallpaper( Application::GetSettings().GetStyleSettings().GetFaceColor()) );

    ODataView::Construct();
}
// -----------------------------------------------------------------------------
void OJoinDesignView::initialize()
{
    //  getAddTableDialog()->Update();
}
// -------------------------------------------------------------------------
void OJoinDesignView::resizeDocumentView(Rectangle& _rPlayground)
{
    m_pScrollWindow->SetPosSizePixel( _rPlayground.TopLeft(), _rPlayground.GetSize() );

    // just for completeness: there is no space left, we occupied it all ...
    _rPlayground.SetPos( _rPlayground.BottomRight() );
    _rPlayground.SetSize( Size( 0, 0 ) );
}
// -----------------------------------------------------------------------------
void OJoinDesignView::setReadOnly(sal_Bool /*_bReadOnly*/)
{
}
// -----------------------------------------------------------------------------
void OJoinDesignView::SaveTabWinUIConfig(OTableWindow* pWin)
{
    getController()->SaveTabWinPosSize(pWin, m_pScrollWindow->GetHScrollBar()->GetThumbPos(), m_pScrollWindow->GetVScrollBar()->GetThumbPos());
}
// -----------------------------------------------------------------------------
void OJoinDesignView::KeyInput( const KeyEvent& rEvt )
{
    if ( m_pTableView && m_pTableView->IsVisible() )
        m_pTableView->KeyInput( rEvt );
    else
        ODataView::KeyInput(rEvt);
}
// -----------------------------------------------------------------------------

}   // namespace dbaui

<commit_msg>INTEGRATION: CWS dba30d (1.22.30); FILE MERGED 2008/05/29 11:30:21 fs 1.22.30.1: during #i80943#: refactoring: IController now passed around as reference, not as pointer<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: JoinDesignView.cxx,v $
 * $Revision: 1.23 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_dbaccess.hxx"
#ifndef DBAUI_JOINDESIGNVIEW_HXX
#include "JoinDesignView.hxx"
#endif
#ifndef DBAUI_JOINTABLEVIEW_HXX
#include "JoinTableView.hxx"
#endif
#ifndef DBAUI_JOINCONTROLLER_HXX
#include "JoinController.hxx"
#endif
#ifndef _UNDO_HXX
#include <svtools/undo.hxx>
#endif
#ifndef DBAUI_QYDLGTAB_HXX
#include "adtabdlg.hxx"
#endif
#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>
#endif
#ifndef _SV_MSGBOX_HXX
#include <vcl/msgbox.hxx>
#endif
#ifndef DBACCESS_UI_BROWSER_ID_HXX
#include "browserids.hxx"
#endif
#ifndef _DBU_QRY_HRC_
#include "dbu_qry.hrc"
#endif
#ifndef _COMPHELPER_TYPES_HXX_
#include <comphelper/types.hxx>
#endif
#ifndef _CONNECTIVITY_DBTOOLS_HXX_
#include <connectivity/dbtools.hxx>
#endif
#ifndef _COM_SUN_STAR_SDBC_DATATYPE_HPP_
#include <com/sun/star/sdbc/DataType.hpp>
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XNAMEACCESS_HPP_
#include <com/sun/star/container/XNameAccess.hpp>
#endif
#ifndef DBAUI_TABLECONNECTION_HXX
#include "TableConnection.hxx"
#endif
#ifndef DBAUI_CONNECTIONLINE_HXX
#include "ConnectionLine.hxx"
#endif
#ifndef DBAUI_CONNECTIONLINEDATA_HXX
#include "ConnectionLineData.hxx"
#endif
#ifndef DBAUI_TABLECONNECTIONDATA_HXX
#include "TableConnectionData.hxx"
#endif
#ifndef DBACCESS_SHARED_DBUSTRINGS_HRC
#include "dbustrings.hrc"
#endif
#ifndef _COMPHELPER_EXTRACT_HXX_
#include <comphelper/extract.hxx>
#endif
#ifndef DBAUI_TOOLS_HXX
#include "UITools.hxx"
#endif
#ifndef DBAUI_JOINTABLEVIEW_HXX
#include "JoinTableView.hxx"
#endif
//  #include <com/sun/star/util/URL.hdl>

using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::i18n;
using namespace ::com::sun::star::sdbc;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::util;

namespace dbaui
{

// =============================================================================
// = OJoinDesignView
// =============================================================================
// -----------------------------------------------------------------------------
OJoinDesignView::OJoinDesignView(Window* _pParent, OJoinController& _rController,const Reference< XMultiServiceFactory >& _rFactory)
    :ODataView( _pParent, _rController, _rFactory )
    ,m_pTableView(NULL)
    ,m_rController( _rController )
{
    m_pScrollWindow = new OScrollWindowHelper(this);
}
// -----------------------------------------------------------------------------
OJoinDesignView::~OJoinDesignView()
{
    ::std::auto_ptr<Window> aT3(m_pScrollWindow);
    m_pScrollWindow = NULL;
    ::std::auto_ptr<Window> aT2(m_pTableView);
    m_pTableView = NULL;
}
// -------------------------------------------------------------------------
void OJoinDesignView::Construct()
{
    m_pScrollWindow->setTableView(m_pTableView);
    m_pScrollWindow->Show();
    m_pTableView->Show();

    SetBackground( Wallpaper( Application::GetSettings().GetStyleSettings().GetFaceColor()) );

    ODataView::Construct();
}
// -----------------------------------------------------------------------------
void OJoinDesignView::initialize()
{
    //  getAddTableDialog()->Update();
}
// -------------------------------------------------------------------------
void OJoinDesignView::resizeDocumentView(Rectangle& _rPlayground)
{
    m_pScrollWindow->SetPosSizePixel( _rPlayground.TopLeft(), _rPlayground.GetSize() );

    // just for completeness: there is no space left, we occupied it all ...
    _rPlayground.SetPos( _rPlayground.BottomRight() );
    _rPlayground.SetSize( Size( 0, 0 ) );
}
// -----------------------------------------------------------------------------
void OJoinDesignView::setReadOnly(sal_Bool /*_bReadOnly*/)
{
}
// -----------------------------------------------------------------------------
void OJoinDesignView::SaveTabWinUIConfig(OTableWindow* pWin)
{
    getController().SaveTabWinPosSize(pWin, m_pScrollWindow->GetHScrollBar()->GetThumbPos(), m_pScrollWindow->GetVScrollBar()->GetThumbPos());
}
// -----------------------------------------------------------------------------
void OJoinDesignView::KeyInput( const KeyEvent& rEvt )
{
    if ( m_pTableView && m_pTableView->IsVisible() )
        m_pTableView->KeyInput( rEvt );
    else
        ODataView::KeyInput(rEvt);
}
// -----------------------------------------------------------------------------

}   // namespace dbaui

<|endoftext|>


<commit_before>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2017.  All rights reserved
 */
#ifndef _Stroika_Foundation_Execution_SpinLock_inl_
#define _Stroika_Foundation_Execution_SpinLock_inl_ 1

/*
 ********************************************************************************
 ***************************** Implementation Details ***************************
 ********************************************************************************
 */

namespace Stroika {
    namespace Foundation {
        namespace Execution {

            /*
             ********************************************************************************
             ******************************** Execution::SpinLock ***************************
             ********************************************************************************
             */
            inline SpinLock::SpinLock (BarrierFlag barrier)
                : fBarrierFlag_ (barrier)
#if !qCompilerAndStdLib_atomic_flag_atomic_flag_init_Buggy
                , fLock_ (ATOMIC_FLAG_INIT)
#endif
            {
#if qStroika_FeatureSupported_Valgrind
                Stroika_Foundation_Debug_ValgrindDisableCheck_stdatomic (fLock_);
                VALGRIND_HG_MUTEX_INIT_POST (&fLock_, true);
#endif
#if qCompilerAndStdLib_atomic_flag_atomic_flag_init_Buggy
                fLock_.clear (std::memory_order_release); // docs indicate no, but looking at MSFT impl, seems yes (to avoid issue with flag_init not working?
#endif
            }
#if qStroika_FeatureSupported_Valgrind
            inline SpinLock::~SpinLock ()
            {
                VALGRIND_HG_MUTEX_DESTROY_PRE (&fLock_);
                VALGRIND_HG_ENABLE_CHECKING (&fLock_, sizeof (fLock_));
            }
#endif
            inline bool SpinLock::try_lock ()
            {
// Atomically set fLock to true and examine the previous value. If it was false, we
// successfully gained the lock. If it was already true (someone else holds the lock),
// we did NOT gain the lock, but we changed nothing. The fact that we changed nothing in the case where
// we didn't gain the lock, is why this is not a race.
#if qStroika_FeatureSupported_Valgrind
                VALGRIND_HG_MUTEX_LOCK_PRE (&fLock_, true);
#endif
                bool result = not fLock_.test_and_set (std::memory_order_acquire);
#if qStroika_FeatureSupported_Valgrind
                if (result) {
                    VALGRIND_HG_MUTEX_LOCK_POST (&fLock_);
                }
#endif
                if (result) {
                    /*
                     *  https://stroika.atlassian.net/browse/STK-494
                     *
                     *  According to http://www.boost.org/doc/libs/1_54_0/doc/html/atomic/usage_examples.html#boost_atomic.usage_examples.example_spinlock
                     *  it makes sense to use memory_order_acquire, but that doesn't seem right, as the
                     *  lock could protect reading or writing another memory area.
                     */
                    switch (fBarrierFlag_) {
                        case BarrierFlag::eReleaseAcquire:
                            std::atomic_thread_fence (std::memory_order_acquire);
                            break;
                        case BarrierFlag::eMemoryTotalOrder:
                            std::atomic_thread_fence (std::memory_order_seq_cst);
                            break;
                        default:
                            break;
                    }
                }
                return result;
            }
            inline void SpinLock::lock ()
            {
                // Acquire lock. If / when fails, yield processor to avoid too much busy waiting.
                while (not try_lock ()) {
                    std::this_thread::yield (); // nb: until Stroika v2.0a209, this called Execution::Yield (), making this a cancelation point. That is principally bad because it makes SpinLock not interchangeable with mutex
                }
            }
            inline void SpinLock::unlock ()
            {
                switch (fBarrierFlag_) {
                    case BarrierFlag::eReleaseAcquire:
                        std::atomic_thread_fence (std::memory_order_release);
                        break;
                    case BarrierFlag::eMemoryTotalOrder:
                        std::atomic_thread_fence (std::memory_order_seq_cst);
                        break;
                    default:
                        break;
                }
// release lock
#if qStroika_FeatureSupported_Valgrind
                VALGRIND_HG_MUTEX_UNLOCK_PRE (&fLock_);
#endif
                fLock_.clear (std::memory_order_release);
#if qStroika_FeatureSupported_Valgrind
                VALGRIND_HG_MUTEX_UNLOCK_POST (&fLock_);
#endif
            }
        }
    }
}
#endif /*_Stroika_Foundation_Execution_SpinLock_inl_*/
<commit_msg>missing include<commit_after>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2017.  All rights reserved
 */
#ifndef _Stroika_Foundation_Execution_SpinLock_inl_
#define _Stroika_Foundation_Execution_SpinLock_inl_ 1

/*
 ********************************************************************************
 ***************************** Implementation Details ***************************
 ********************************************************************************
 */

#include <thread>

namespace Stroika {
    namespace Foundation {
        namespace Execution {

            /*
             ********************************************************************************
             ******************************** Execution::SpinLock ***************************
             ********************************************************************************
             */
            inline SpinLock::SpinLock (BarrierFlag barrier)
                : fBarrierFlag_ (barrier)
#if !qCompilerAndStdLib_atomic_flag_atomic_flag_init_Buggy
                , fLock_ (ATOMIC_FLAG_INIT)
#endif
            {
#if qStroika_FeatureSupported_Valgrind
                Stroika_Foundation_Debug_ValgrindDisableCheck_stdatomic (fLock_);
                VALGRIND_HG_MUTEX_INIT_POST (&fLock_, true);
#endif
#if qCompilerAndStdLib_atomic_flag_atomic_flag_init_Buggy
                fLock_.clear (std::memory_order_release); // docs indicate no, but looking at MSFT impl, seems yes (to avoid issue with flag_init not working?
#endif
            }
#if qStroika_FeatureSupported_Valgrind
            inline SpinLock::~SpinLock ()
            {
                VALGRIND_HG_MUTEX_DESTROY_PRE (&fLock_);
                VALGRIND_HG_ENABLE_CHECKING (&fLock_, sizeof (fLock_));
            }
#endif
            inline bool SpinLock::try_lock ()
            {
// Atomically set fLock to true and examine the previous value. If it was false, we
// successfully gained the lock. If it was already true (someone else holds the lock),
// we did NOT gain the lock, but we changed nothing. The fact that we changed nothing in the case where
// we didn't gain the lock, is why this is not a race.
#if qStroika_FeatureSupported_Valgrind
                VALGRIND_HG_MUTEX_LOCK_PRE (&fLock_, true);
#endif
                bool result = not fLock_.test_and_set (std::memory_order_acquire);
#if qStroika_FeatureSupported_Valgrind
                if (result) {
                    VALGRIND_HG_MUTEX_LOCK_POST (&fLock_);
                }
#endif
                if (result) {
                    /*
                     *  https://stroika.atlassian.net/browse/STK-494
                     *
                     *  According to http://www.boost.org/doc/libs/1_54_0/doc/html/atomic/usage_examples.html#boost_atomic.usage_examples.example_spinlock
                     *  it makes sense to use memory_order_acquire, but that doesn't seem right, as the
                     *  lock could protect reading or writing another memory area.
                     */
                    switch (fBarrierFlag_) {
                        case BarrierFlag::eReleaseAcquire:
                            std::atomic_thread_fence (std::memory_order_acquire);
                            break;
                        case BarrierFlag::eMemoryTotalOrder:
                            std::atomic_thread_fence (std::memory_order_seq_cst);
                            break;
                        default:
                            break;
                    }
                }
                return result;
            }
            inline void SpinLock::lock ()
            {
                // Acquire lock. If / when fails, yield processor to avoid too much busy waiting.
                while (not try_lock ()) {
                    std::this_thread::yield (); // nb: until Stroika v2.0a209, this called Execution::Yield (), making this a cancelation point. That is principally bad because it makes SpinLock not interchangeable with mutex
                }
            }
            inline void SpinLock::unlock ()
            {
                switch (fBarrierFlag_) {
                    case BarrierFlag::eReleaseAcquire:
                        std::atomic_thread_fence (std::memory_order_release);
                        break;
                    case BarrierFlag::eMemoryTotalOrder:
                        std::atomic_thread_fence (std::memory_order_seq_cst);
                        break;
                    default:
                        break;
                }
// release lock
#if qStroika_FeatureSupported_Valgrind
                VALGRIND_HG_MUTEX_UNLOCK_PRE (&fLock_);
#endif
                fLock_.clear (std::memory_order_release);
#if qStroika_FeatureSupported_Valgrind
                VALGRIND_HG_MUTEX_UNLOCK_POST (&fLock_);
#endif
            }
        }
    }
}
#endif /*_Stroika_Foundation_Execution_SpinLock_inl_*/
<|endoftext|>


<commit_before>#include "../../config.h"
#ifndef UNITTEST_NO_EXCEPTIONS

#include "../../unittestpp.h"
#include "../CurrentTest.h"
#include "RecordingReporter.h"
#include "ScopedCurrentTest.h"

#include <stdexcept>

using namespace std;

namespace {

int ThrowingFunction()
{
    throw "Doh";
}

int ThrowingStdExceptionFunction()
{
    throw std::logic_error("Doh");
}

struct CheckFixture
{
    CheckFixture()
      : reporter()
      , testResults(&reporter)
    {
    }

    void Throw()
    {
        ScopedCurrentTest scopedResults(testResults);
        CHECK(ThrowingFunction() == 1);
    }

    void StdThrow()
    {
        ScopedCurrentTest scopedResults(testResults);
        CHECK(ThrowingStdExceptionFunction() == 1);
    }

    RecordingReporter reporter;
    UnitTest::TestResults testResults;
};

TEST_FIXTURE(CheckFixture, CheckFailsOnException)
{
    Throw();
    CHECK(testResults.GetFailureCount() > 0);
}

TEST_FIXTURE(CheckFixture, CheckFailsOnStdException)
{
    StdThrow();
    CHECK(testResults.GetFailureCount() > 0);
}

TEST_FIXTURE(CheckFixture, CheckFailureBecauseOfExceptionIncludesCheckContents)
{
    Throw();
    CHECK(strstr(reporter.lastFailedMessage, "ThrowingFunction() == 1"));
}

TEST_FIXTURE(CheckFixture, CheckFailureBecauseOfStdExceptionIncludesCheckContents)
{
    StdThrow();
    CHECK(strstr(reporter.lastFailedMessage, "ThrowingStdExceptionFunction() == 1"));
}

TEST_FIXTURE(CheckFixture, CheckFailureBecauseOfStandardExceptionIncludesWhat)
{
    StdThrow();
    CHECK(strstr(reporter.lastFailedMessage, "exception (Doh)"));
}

TEST(CheckEqualFailsOnException)
{
    bool failure = false;
    {
        RecordingReporter reporter;
        UnitTest::TestResults testResults(&reporter);
		ScopedCurrentTest scopedResults(testResults);
        CHECK_EQUAL(ThrowingFunction(), 1);
        failure = (testResults.GetFailureCount() > 0);
    }

    CHECK(failure);
}

TEST(CheckEqualFailureBecauseOfExceptionContainsCorrectDetails)
{
    int line = 0;
    RecordingReporter reporter;
    {
        UnitTest::TestResults testResults(&reporter);
		UnitTest::TestDetails const testDetails("testName", "suiteName", "filename", -1);
		ScopedCurrentTest scopedResults(testResults, &testDetails);

		CHECK_EQUAL(ThrowingFunction(), 123);    line = __LINE__;
    }

    CHECK_EQUAL("testName", reporter.lastFailedTest);
    CHECK_EQUAL("suiteName", reporter.lastFailedSuite);
    CHECK_EQUAL("filename", reporter.lastFailedFile);
    CHECK_EQUAL(line, reporter.lastFailedLine);
}

TEST(CheckEqualFailureBecauseOfExceptionIncludesCheckContents)
{
    RecordingReporter reporter;
    {
        UnitTest::TestResults testResults(&reporter);
		ScopedCurrentTest scopedResults(testResults);
        CHECK_EQUAL(ThrowingFunction(), 123);
    }

    CHECK(strstr(reporter.lastFailedMessage, "ThrowingFunction()"));
    CHECK(strstr(reporter.lastFailedMessage, "123"));
}

TEST(CheckEqualFailureBecauseOfStandardExceptionIncludesWhat)
{
    RecordingReporter reporter;
    {
        UnitTest::TestResults testResults(&reporter);
        ScopedCurrentTest scopedResults(testResults);
        CHECK_EQUAL(ThrowingStdExceptionFunction(), 123);
    }

    CHECK(strstr(reporter.lastFailedMessage, "exception (Doh)"));
}

TEST(CheckCloseFailsOnException)
{
    bool failure = false;
    {
        RecordingReporter reporter;
        UnitTest::TestResults testResults(&reporter);
		ScopedCurrentTest scopedResults(testResults);
        CHECK_CLOSE((float)ThrowingFunction(), 1.0001f, 0.1f);
        failure = (testResults.GetFailureCount() > 0);
    }

    CHECK(failure);
}

TEST(CheckCloseFailureBecauseOfExceptionContainsCorrectDetails)
{
    int line = 0;
    RecordingReporter reporter;
    {
        UnitTest::TestResults testResults(&reporter);
		UnitTest::TestDetails testDetails("closeTest", "closeSuite", "filename", -1);
		ScopedCurrentTest scopedResults(testResults, &testDetails);
        CHECK_CLOSE((float)ThrowingFunction(), 1.0001f, 0.1f);    line = __LINE__;
    }

    CHECK_EQUAL("closeTest", reporter.lastFailedTest);
    CHECK_EQUAL("closeSuite", reporter.lastFailedSuite);
    CHECK_EQUAL("filename", reporter.lastFailedFile);
    CHECK_EQUAL(line, reporter.lastFailedLine);
}

TEST(CheckCloseFailureBecauseOfExceptionIncludesCheckContents)
{
    RecordingReporter reporter;
    {
        UnitTest::TestResults testResults(&reporter);
		ScopedCurrentTest scopedResults(testResults);
        CHECK_CLOSE((float)ThrowingFunction(), 1.0001f, 0.1f);
    }

    CHECK(strstr(reporter.lastFailedMessage, "(float)ThrowingFunction()"));
    CHECK(strstr(reporter.lastFailedMessage, "1.0001f"));
}

TEST(CheckCloseFailureBecauseOfStandardExceptionIncludesWhat)
{
    RecordingReporter reporter;
    {
        UnitTest::TestResults testResults(&reporter);
        ScopedCurrentTest scopedResults(testResults);
        CHECK_CLOSE((float)ThrowingStdExceptionFunction(), 1.0001f, 0.1f);
    }

    CHECK(strstr(reporter.lastFailedMessage, "exception (Doh)"));
}

class ThrowingObject
{
public:
    float operator[](int) const
    {
        throw "Test throw";
    }
};

TEST(CheckArrayCloseFailureBecauseOfExceptionContainsCorrectDetails)
{
    int line = 0;
    RecordingReporter reporter;
    {
        UnitTest::TestResults testResults(&reporter);
		UnitTest::TestDetails testDetails("arrayCloseTest", "arrayCloseSuite", "filename", -1);
		ScopedCurrentTest scopedResults(testResults, &testDetails);

		int const data[4] = { 0, 1, 2, 3 };
        CHECK_ARRAY_CLOSE(data, ThrowingObject(), 4, 0.01f);     line = __LINE__;
    }

    CHECK_EQUAL("arrayCloseTest", reporter.lastFailedTest);
    CHECK_EQUAL("arrayCloseSuite", reporter.lastFailedSuite);
    CHECK_EQUAL("filename", reporter.lastFailedFile);
    CHECK_EQUAL(line, reporter.lastFailedLine);
}

TEST(CheckArrayCloseFailsOnException)
{
    bool failure = false;
    {
        RecordingReporter reporter;
        UnitTest::TestResults testResults(&reporter);
		ScopedCurrentTest scopedResults(testResults);

		const float data[4] = { 0, 1, 2, 3 };
        ThrowingObject obj;
        CHECK_ARRAY_CLOSE(data, obj, 3, 0.01f);

		failure = (testResults.GetFailureCount() > 0);
    }

    CHECK(failure);
}

TEST(CheckArrayCloseFailureOnExceptionIncludesCheckContents)
{
    RecordingReporter reporter;
    {
        UnitTest::TestResults testResults(&reporter);
		ScopedCurrentTest scopedResults(testResults);

		const float data[4] = { 0, 1, 2, 3 };
        ThrowingObject obj;
        CHECK_ARRAY_CLOSE(data, obj, 3, 0.01f);
    }

    CHECK(strstr(reporter.lastFailedMessage, "data"));
    CHECK(strstr(reporter.lastFailedMessage, "obj"));
}

TEST(CheckArrayEqualFailsOnException)
{
    bool failure = false;
    {
        RecordingReporter reporter;
        UnitTest::TestResults testResults(&reporter);
		ScopedCurrentTest scopedResults(testResults);

		const float data[4] = { 0, 1, 2, 3 };
        ThrowingObject obj;
        CHECK_ARRAY_EQUAL (data, obj, 3);

		failure = (testResults.GetFailureCount() > 0);
    }

    CHECK(failure);
}

TEST(CheckArrayEqualFailureOnExceptionIncludesCheckContents)
{
    RecordingReporter reporter;
    {
        UnitTest::TestResults testResults(&reporter);
		ScopedCurrentTest scopedResults(testResults);

		const float data[4] = { 0, 1, 2, 3 };
        ThrowingObject obj;
        CHECK_ARRAY_EQUAL (data, obj, 3);
    }

    CHECK(strstr(reporter.lastFailedMessage, "data"));
    CHECK(strstr(reporter.lastFailedMessage, "obj"));
}

class ThrowingObject2D
{
public:
    float* operator[](int) const
    {
        throw "Test throw";
    }
};

TEST(CheckArray2DCloseFailureBecauseOfExceptionContainsCorrectDetails)
{
    int line = 0;
    RecordingReporter reporter;
    {
        UnitTest::TestResults testResults(&reporter);
		UnitTest::TestDetails testDetails("array2DCloseTest", "array2DCloseSuite", "filename", -1);
		ScopedCurrentTest scopedResults(testResults, &testDetails);

		const float data[2][2] = { {0, 1}, {2, 3} };
        CHECK_ARRAY2D_CLOSE(data, ThrowingObject2D(), 2, 2, 0.01f);   line = __LINE__;
    }

    CHECK_EQUAL("array2DCloseTest", reporter.lastFailedTest);
    CHECK_EQUAL("array2DCloseSuite", reporter.lastFailedSuite);
    CHECK_EQUAL("filename", reporter.lastFailedFile);
    CHECK_EQUAL(line, reporter.lastFailedLine);
}

TEST(CheckArray2DCloseFailsOnException)
{
    bool failure = false;
    {
        RecordingReporter reporter;
        UnitTest::TestResults testResults(&reporter);
		ScopedCurrentTest scopedResults(testResults);

		const float data[2][2] = { {0, 1}, {2, 3} };
        ThrowingObject2D obj;
        CHECK_ARRAY2D_CLOSE(data, obj, 2, 2, 0.01f);

		failure = (testResults.GetFailureCount() > 0);
    }

    CHECK(failure);
}

TEST(CheckArray2DCloseFailureOnExceptionIncludesCheckContents)
{
    RecordingReporter reporter;
    {
        UnitTest::TestResults testResults(&reporter);
		ScopedCurrentTest scopedResults(testResults);

		const float data[2][2] = { {0, 1}, {2, 3} };
        ThrowingObject2D obj;
        CHECK_ARRAY2D_CLOSE(data, obj, 2, 2, 0.01f);
    }

    CHECK(strstr(reporter.lastFailedMessage, "data"));
    CHECK(strstr(reporter.lastFailedMessage, "obj"));
}

}

#endif
<commit_msg>Improve CheckFixture method names.<commit_after>#include "../../config.h"
#ifndef UNITTEST_NO_EXCEPTIONS

#include "../../unittestpp.h"
#include "../CurrentTest.h"
#include "RecordingReporter.h"
#include "ScopedCurrentTest.h"

#include <stdexcept>

using namespace std;

namespace {

int ThrowingFunction()
{
    throw "Doh";
}

int ThrowingStdExceptionFunction()
{
    throw std::logic_error("Doh");
}

struct CheckFixture
{
    CheckFixture()
      : reporter()
      , testResults(&reporter)
    {
    }

    void PerformCheckWithNonStdThrow()
    {
        ScopedCurrentTest scopedResults(testResults);
        CHECK(ThrowingFunction() == 1);
    }

    void PerformCheckWithStdThrow()
    {
        ScopedCurrentTest scopedResults(testResults);
        CHECK(ThrowingStdExceptionFunction() == 1);
    }

    RecordingReporter reporter;
    UnitTest::TestResults testResults;
};

TEST_FIXTURE(CheckFixture, CheckFailsOnException)
{
    PerformCheckWithNonStdThrow();
    CHECK(testResults.GetFailureCount() > 0);
}

TEST_FIXTURE(CheckFixture, CheckFailsOnStdException)
{
    PerformCheckWithStdThrow();
    CHECK(testResults.GetFailureCount() > 0);
}

TEST_FIXTURE(CheckFixture, CheckFailureBecauseOfExceptionIncludesCheckContents)
{
    PerformCheckWithNonStdThrow();
    CHECK(strstr(reporter.lastFailedMessage, "ThrowingFunction() == 1"));
}

TEST_FIXTURE(CheckFixture, CheckFailureBecauseOfStdExceptionIncludesCheckContents)
{
    PerformCheckWithStdThrow();
    CHECK(strstr(reporter.lastFailedMessage, "ThrowingStdExceptionFunction() == 1"));
}

TEST_FIXTURE(CheckFixture, CheckFailureBecauseOfStandardExceptionIncludesWhat)
{
    PerformCheckWithStdThrow();
    CHECK(strstr(reporter.lastFailedMessage, "exception (Doh)"));
}

TEST(CheckEqualFailsOnException)
{
    bool failure = false;
    {
        RecordingReporter reporter;
        UnitTest::TestResults testResults(&reporter);
		ScopedCurrentTest scopedResults(testResults);
        CHECK_EQUAL(ThrowingFunction(), 1);
        failure = (testResults.GetFailureCount() > 0);
    }

    CHECK(failure);
}

TEST(CheckEqualFailureBecauseOfExceptionContainsCorrectDetails)
{
    int line = 0;
    RecordingReporter reporter;
    {
        UnitTest::TestResults testResults(&reporter);
		UnitTest::TestDetails const testDetails("testName", "suiteName", "filename", -1);
		ScopedCurrentTest scopedResults(testResults, &testDetails);

		CHECK_EQUAL(ThrowingFunction(), 123);    line = __LINE__;
    }

    CHECK_EQUAL("testName", reporter.lastFailedTest);
    CHECK_EQUAL("suiteName", reporter.lastFailedSuite);
    CHECK_EQUAL("filename", reporter.lastFailedFile);
    CHECK_EQUAL(line, reporter.lastFailedLine);
}

TEST(CheckEqualFailureBecauseOfExceptionIncludesCheckContents)
{
    RecordingReporter reporter;
    {
        UnitTest::TestResults testResults(&reporter);
		ScopedCurrentTest scopedResults(testResults);
        CHECK_EQUAL(ThrowingFunction(), 123);
    }

    CHECK(strstr(reporter.lastFailedMessage, "ThrowingFunction()"));
    CHECK(strstr(reporter.lastFailedMessage, "123"));
}

TEST(CheckEqualFailureBecauseOfStandardExceptionIncludesWhat)
{
    RecordingReporter reporter;
    {
        UnitTest::TestResults testResults(&reporter);
        ScopedCurrentTest scopedResults(testResults);
        CHECK_EQUAL(ThrowingStdExceptionFunction(), 123);
    }

    CHECK(strstr(reporter.lastFailedMessage, "exception (Doh)"));
}

TEST(CheckCloseFailsOnException)
{
    bool failure = false;
    {
        RecordingReporter reporter;
        UnitTest::TestResults testResults(&reporter);
		ScopedCurrentTest scopedResults(testResults);
        CHECK_CLOSE((float)ThrowingFunction(), 1.0001f, 0.1f);
        failure = (testResults.GetFailureCount() > 0);
    }

    CHECK(failure);
}

TEST(CheckCloseFailureBecauseOfExceptionContainsCorrectDetails)
{
    int line = 0;
    RecordingReporter reporter;
    {
        UnitTest::TestResults testResults(&reporter);
		UnitTest::TestDetails testDetails("closeTest", "closeSuite", "filename", -1);
		ScopedCurrentTest scopedResults(testResults, &testDetails);
        CHECK_CLOSE((float)ThrowingFunction(), 1.0001f, 0.1f);    line = __LINE__;
    }

    CHECK_EQUAL("closeTest", reporter.lastFailedTest);
    CHECK_EQUAL("closeSuite", reporter.lastFailedSuite);
    CHECK_EQUAL("filename", reporter.lastFailedFile);
    CHECK_EQUAL(line, reporter.lastFailedLine);
}

TEST(CheckCloseFailureBecauseOfExceptionIncludesCheckContents)
{
    RecordingReporter reporter;
    {
        UnitTest::TestResults testResults(&reporter);
		ScopedCurrentTest scopedResults(testResults);
        CHECK_CLOSE((float)ThrowingFunction(), 1.0001f, 0.1f);
    }

    CHECK(strstr(reporter.lastFailedMessage, "(float)ThrowingFunction()"));
    CHECK(strstr(reporter.lastFailedMessage, "1.0001f"));
}

TEST(CheckCloseFailureBecauseOfStandardExceptionIncludesWhat)
{
    RecordingReporter reporter;
    {
        UnitTest::TestResults testResults(&reporter);
        ScopedCurrentTest scopedResults(testResults);
        CHECK_CLOSE((float)ThrowingStdExceptionFunction(), 1.0001f, 0.1f);
    }

    CHECK(strstr(reporter.lastFailedMessage, "exception (Doh)"));
}

class ThrowingObject
{
public:
    float operator[](int) const
    {
        throw "Test throw";
    }
};

TEST(CheckArrayCloseFailureBecauseOfExceptionContainsCorrectDetails)
{
    int line = 0;
    RecordingReporter reporter;
    {
        UnitTest::TestResults testResults(&reporter);
		UnitTest::TestDetails testDetails("arrayCloseTest", "arrayCloseSuite", "filename", -1);
		ScopedCurrentTest scopedResults(testResults, &testDetails);

		int const data[4] = { 0, 1, 2, 3 };
        CHECK_ARRAY_CLOSE(data, ThrowingObject(), 4, 0.01f);     line = __LINE__;
    }

    CHECK_EQUAL("arrayCloseTest", reporter.lastFailedTest);
    CHECK_EQUAL("arrayCloseSuite", reporter.lastFailedSuite);
    CHECK_EQUAL("filename", reporter.lastFailedFile);
    CHECK_EQUAL(line, reporter.lastFailedLine);
}

TEST(CheckArrayCloseFailsOnException)
{
    bool failure = false;
    {
        RecordingReporter reporter;
        UnitTest::TestResults testResults(&reporter);
		ScopedCurrentTest scopedResults(testResults);

		const float data[4] = { 0, 1, 2, 3 };
        ThrowingObject obj;
        CHECK_ARRAY_CLOSE(data, obj, 3, 0.01f);

		failure = (testResults.GetFailureCount() > 0);
    }

    CHECK(failure);
}

TEST(CheckArrayCloseFailureOnExceptionIncludesCheckContents)
{
    RecordingReporter reporter;
    {
        UnitTest::TestResults testResults(&reporter);
		ScopedCurrentTest scopedResults(testResults);

		const float data[4] = { 0, 1, 2, 3 };
        ThrowingObject obj;
        CHECK_ARRAY_CLOSE(data, obj, 3, 0.01f);
    }

    CHECK(strstr(reporter.lastFailedMessage, "data"));
    CHECK(strstr(reporter.lastFailedMessage, "obj"));
}

TEST(CheckArrayEqualFailsOnException)
{
    bool failure = false;
    {
        RecordingReporter reporter;
        UnitTest::TestResults testResults(&reporter);
		ScopedCurrentTest scopedResults(testResults);

		const float data[4] = { 0, 1, 2, 3 };
        ThrowingObject obj;
        CHECK_ARRAY_EQUAL (data, obj, 3);

		failure = (testResults.GetFailureCount() > 0);
    }

    CHECK(failure);
}

TEST(CheckArrayEqualFailureOnExceptionIncludesCheckContents)
{
    RecordingReporter reporter;
    {
        UnitTest::TestResults testResults(&reporter);
		ScopedCurrentTest scopedResults(testResults);

		const float data[4] = { 0, 1, 2, 3 };
        ThrowingObject obj;
        CHECK_ARRAY_EQUAL (data, obj, 3);
    }

    CHECK(strstr(reporter.lastFailedMessage, "data"));
    CHECK(strstr(reporter.lastFailedMessage, "obj"));
}

class ThrowingObject2D
{
public:
    float* operator[](int) const
    {
        throw "Test throw";
    }
};

TEST(CheckArray2DCloseFailureBecauseOfExceptionContainsCorrectDetails)
{
    int line = 0;
    RecordingReporter reporter;
    {
        UnitTest::TestResults testResults(&reporter);
		UnitTest::TestDetails testDetails("array2DCloseTest", "array2DCloseSuite", "filename", -1);
		ScopedCurrentTest scopedResults(testResults, &testDetails);

		const float data[2][2] = { {0, 1}, {2, 3} };
        CHECK_ARRAY2D_CLOSE(data, ThrowingObject2D(), 2, 2, 0.01f);   line = __LINE__;
    }

    CHECK_EQUAL("array2DCloseTest", reporter.lastFailedTest);
    CHECK_EQUAL("array2DCloseSuite", reporter.lastFailedSuite);
    CHECK_EQUAL("filename", reporter.lastFailedFile);
    CHECK_EQUAL(line, reporter.lastFailedLine);
}

TEST(CheckArray2DCloseFailsOnException)
{
    bool failure = false;
    {
        RecordingReporter reporter;
        UnitTest::TestResults testResults(&reporter);
		ScopedCurrentTest scopedResults(testResults);

		const float data[2][2] = { {0, 1}, {2, 3} };
        ThrowingObject2D obj;
        CHECK_ARRAY2D_CLOSE(data, obj, 2, 2, 0.01f);

		failure = (testResults.GetFailureCount() > 0);
    }

    CHECK(failure);
}

TEST(CheckArray2DCloseFailureOnExceptionIncludesCheckContents)
{
    RecordingReporter reporter;
    {
        UnitTest::TestResults testResults(&reporter);
		ScopedCurrentTest scopedResults(testResults);

		const float data[2][2] = { {0, 1}, {2, 3} };
        ThrowingObject2D obj;
        CHECK_ARRAY2D_CLOSE(data, obj, 2, 2, 0.01f);
    }

    CHECK(strstr(reporter.lastFailedMessage, "data"));
    CHECK(strstr(reporter.lastFailedMessage, "obj"));
}

}

#endif
<|endoftext|>


<commit_before>/*
    Persons Model
    Copyright (C) 2012  Aleix Pol Gonzalez <aleixpol@blue-systems.com>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
*/

#include "duplicatestest.h"
#include <duplicatesfinder.h>
#include <persons-model.h>

#include <qtest_kde.h>
#include <QStandardItemModel>

QTEST_KDEMAIN_CORE( DuplicatesTest )

DuplicatesTest::DuplicatesTest(QObject* parent): QObject(parent)
{}

void DuplicatesTest::testDuplicates()
{
    PersonsModel m;
//     m.appendRow();

    DuplicatesFinder f(&m);
    f.start();
    QTest::kWaitForSignal(&f, SIGNAL(finished(KJob*)));
}
<commit_msg>fix the test...<commit_after>/*
    Persons Model
    Copyright (C) 2012  Aleix Pol Gonzalez <aleixpol@blue-systems.com>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
*/

#include "duplicatestest.h"
#include <duplicatesfinder.h>
#include <persons-model.h>

#include <qtest_kde.h>
#include <QStandardItemModel>

QTEST_KDEMAIN_CORE( DuplicatesTest )

DuplicatesTest::DuplicatesTest(QObject* parent): QObject(parent)
{}

void DuplicatesTest::testDuplicates()
{
    PersonsModel m;
//     m.appendRow();

    QScopedPointer<DuplicatesFinder> f(new DuplicatesFinder(&m));
    f->start();
    QTest::kWaitForSignal(f.data(), SIGNAL(finished(KJob*)));
}
<|endoftext|>


<commit_before>/*
 *  Plot2D.cpp
 *  hog2
 *
 *  Created by Nathan Sturtevant on 4/18/07.
 *  Copyright 2007 Nathan Sturtevant, University of Alberta. All rights reserved.
 *
 */

#include "Plot2D.h"
#include <math.h>
#include <cstring>

namespace Plotting {

	Line::Line(char *label, tPlotType ptype)
	:plotType(ptype)
	{
		ClearColor();
		strncpy(name,label,1024);
		xMin = DBL_MAX;
		xMax = DBL_MIN;
		yMin = DBL_MAX;
		yMax = DBL_MIN;
		hidden = false;
		changedLine = false;
	}

	void Line::AddPoint(double _y)
	{
		changedLine = true;
		if (x.size() == 0)
			AddPoint(0, _y);
		else
			AddPoint(x.back()+1, _y);
	}

	void Line::AddPoint(double _x, double _y)
	{
		changedLine = true;
		if (_x < xMin)
			xMin = _x;
		if (_x > xMax)
			xMax = _x;
		if (_y < yMin)
			yMin = _y;
		if (_y > yMax)
			yMax = _y;
		x.push_back(_x);
		y.push_back(_y);

		//printf("New %s bounds (%1.2f, %1.2f, %1.2f, %1.2f)\n", name, xMin, yMax, xMax, yMin);

	}

	double Line::DistanceToLine(double xp, double yp)
	{
		double bestDist = (y[0]-yp)*(y[0]-yp)+(x[0]-xp)*(x[0]-xp);
		int bestIndex = 0;
		// Linear search? - can be sped up with binary search if needed
		for (unsigned int m = 1; m < x.size()-1; m++)
		{
			if (fless((y[m]-yp)*(y[m]-yp)+(x[m]-xp)*(x[m]-xp), bestDist))
			{
				bestDist = (y[m]-yp)*(y[m]-yp)+(x[m]-xp)*(x[m]-xp);
				bestIndex = m;
			}
		}
		return sqrt(bestDist);
	}

	double Line::VerticalDistanceToLine(double xp, double yp)
	{
		double horizDist = fabs(y[0]-yp);
		int horizIndex = 0;
		// Linear search? - can be sped up with binary search if needed
		for (unsigned int m = 1; m < x.size()-1; m++)
		{
			if (fabs(y[m]-yp) < horizDist)
			{
				horizDist = fabs(y[m]-yp);
				horizIndex = m;
			}
		}
		return fabs(x[horizIndex]-xp);
	}

	void Line::Smooth(unsigned int windowSize)
	{
		double sum=0;
		// setup initial window
		for (unsigned int m = 0; (m < x.size()) && (m < windowSize); m++)
		{
			sum += y[m];
			y[m/2] = sum/(double)(m+1);
		}
		for (unsigned int m = windowSize/2; m < x.size()-windowSize/2-1; m++)
		{
			y[m] = sum/(double)windowSize;
			sum-=y[m-windowSize/2];
			sum+=y[m+windowSize/2];
		}
		for (unsigned int m = x.size()-windowSize/2-1; m < x.size(); m++)
		{
			y[m] = sum/(double)(windowSize/2+x.size()-1-m);
			sum-=y[m-windowSize/2];
		}
	}

	void Line::ClearColor()
	{
		r = -1;
	}

	void Line::SetColor(double _r, double _g, double _b)
	{
		r = _r; g = _g; b = _b;
	}

	void Line::OpenGLDraw() const
	{
		if (hidden)
			return;
		switch (plotType)
		{
			case kLinePlot:
			{
				glBegin(GL_LINE_STRIP);
				if (r != -1)
				{
					glColor3f(r, g, b);
				}
				for (unsigned int t = 0; t < x.size(); t++)
					glVertex2d(x[t], y[t]);
				glEnd();
			}
			break;
			case kImpulsePlot:
			{
				glBegin(GL_LINES);
				if (r != -1)
				{
					glColor3f(r, g, b);
				}
				for (unsigned int t = 0; t < x.size(); t++)
				{
					glVertex2d(x[t], 0);
					glVertex2d(x[t], y[t]);
				}
				glEnd();
			}
			break;
		}
	}

	Plot2D::Plot2D()
	{
		ResetAxis();
		drawMouse = true;
		lastSelectedLine = -1;
		recomputeBorders = true;
	}

	void Plot2D::AddLine(Line *l)
	{
		lines.push_back(l);

		if (l->GetMaxX() > xMax)
			xMax = l->GetMaxX();
		if (l->GetMaxY() > yMax)
			yMax = l->GetMaxY();
		if (l->GetMinX() < xMin)
			xMin = l->GetMinX();
		if (l->GetMinY() < yMin)
			yMin = l->GetMinY();

		if (!forceAxis)
			ResetAxis();
	}

	void Plot2D::Zoom(double amt)
	{
		printf("Got amt %1.2f\n", amt);
		double cx, cy;
		amt = 1-0.01*amt;
		cx = xMin+(xMax-xMin)/2;
		cy = yMin+(yMax-yMin)/2;
		double width = (xMax-xMin)*amt;
		double height = (yMax-yMin)*amt;

		xMin = cx - width/2;
		xMax = cx + width/2;
		yMin = cy - height/2;
		yMax = cy + height/2;

		dLeft = xMin;
		dRight = xMax;
		dTop = yMax;
		dBottom = yMin;
	}

	void Plot2D::SetAxis(double minx, double miny, double maxx, double maxy)
	{
		forceAxis = true;
		xMax = maxx;
		xMin = minx;
		yMax = maxy;
		yMin = miny;
	}

	void Plot2D::ResetAxis()
	{
		forceAxis = false;
		recomputeBorders = false;
		xMin = DBL_MAX;
		xMax = DBL_MIN;
		yMin = DBL_MAX;
		yMax = DBL_MIN;

		// recompute max/min stuff
		for (unsigned int x = 0; x < lines.size(); x++)
		{
			Line *l = lines[x];

			if (l->GetMaxX() > xMax)
				xMax = l->GetMaxX();
			if (l->GetMaxY() > yMax)
				yMax = l->GetMaxY();
			if (l->GetMinX() < xMin)
				xMin = l->GetMinX();
			if (l->GetMinY() < yMin)
				yMin = l->GetMinY();
		}

		dLeft = xMin;
		dRight = xMax;
		dTop = yMax;
		dBottom = yMin;
	}

	void Plot2D::OffsetCurrMouse(double deltaX, double deltaY)
	{
		mouseXLoc += deltaX;
		mouseYLoc += deltaY;

		if (lines.size() == 0)
			return;

		double minDist = lines[0]->DistanceToLine(mouseXLoc, mouseYLoc);
		int minIndex = 0;
		for (unsigned int x = 1; x < lines.size(); x++)
		{
			if (lines[x]->IsHidden())
				continue;

			if (fless(lines[x]->DistanceToLine(mouseXLoc, mouseYLoc), minDist))
			{
				minIndex = x;
				minDist = lines[x]->DistanceToLine(mouseXLoc, mouseYLoc);
			}
			//		if (lines[x]->pointOnLine(mouseXLoc, mouseYLoc))
			//			printf("Near: %s\n", lines[x]->getLabel());
		}
		if (minIndex != lastSelectedLine)
		{
			// set colors here instead
//			if (lastSelectedLine != -1)
//				lines[lastSelectedLine]->unselect();
//			lines[minIndex]->select();
			lastSelectedLine = minIndex;
//			printf("Near: %s\n", lines[minIndex]->getLabel());
//			submitMessage(lines[minIndex]->getLabel());
		}
	}

//	void Plot2D::SetCurrMouse(double lastX, double lastY, Rect &winRect)
//	{
//		double tpW = (dRight-dLeft)*.05;
//		double tpH = (dTop-dBottom)*.05;
//		mouseXLoc = dLeft-tpW+(dRight+2*tpW - dLeft)*(lastX/winRect.right);
//		mouseYLoc = dBottom-tpH+(dTop+2*tpH - dBottom)*(1-(lastY/winRect.bottom));
//
//		if (lines.size() == 0)
//			return;
//
//		double minDist = lines[0]->DistanceToLine(mouseXLoc, mouseYLoc);
//		int minIndex = 0;
//		for (unsigned int x = 1; x < lines.size(); x++)
//		{
//			if (fless(lines[x]->DistanceToLine(mouseXLoc, mouseYLoc), minDist))
//			{
//				minIndex = x;
//				minDist = lines[x]->DistanceToLine(mouseXLoc, mouseYLoc);
//			}
//	//		if (lines[x]->pointOnLine(mouseXLoc, mouseYLoc))
//	//			printf("Near: %s\n", lines[x]->getLabel());
//		}
//		if (minIndex != lastSelectedLine)
//		{
////			if (lastSelectedLine != -1)
////				lines[lastSelectedLine]->unselect();
////			lines[minIndex]->select();
//			lastSelectedLine = minIndex;
//			//printf("Near: %s\n", lines[minIndex]->getLabel());
//			//submitMessage(lines[minIndex]->getLabel());
//		}
//	}
//
//	void Plot2D::Recenter(double lastX, double lastY, Rect &winRect)
//	{
//		double tpW = (dRight-dLeft)*.05;
//		double tpH = (dTop-dBottom)*.05;
//		double XLoc = dLeft-tpW+(dRight+2*tpW - dLeft)*(lastX/winRect.right);
//		double YLoc = dBottom-tpH+(dTop+2*tpH - dBottom)*(1-(lastY/winRect.bottom));
//
//		xMin = XLoc - (dRight-dLeft)/2;
//		xMax = XLoc + (dRight-dLeft)/2;
//		yMin = YLoc - (dTop-dBottom)/2;
//		yMax = YLoc + (dTop-dBottom)/2;
//
//		dLeft = xMin;
//		dRight = xMax;
//		dTop = yMax;
//		dBottom = yMin;
//
//	}

	void Plot2D::SmoothLines()
	{
		for (unsigned int x = 0; x < lines.size(); x++)
			lines[x]->Smooth(50);
		ResetAxis();
	}

	void Plot2D::OpenGLDraw() const
	{
		GLint matrixMode;

		if (recomputeBorders)
			assert(false);
//			ResetAxis();

		glGetIntegerv(GL_MATRIX_MODE, &matrixMode);

		glEnable(GL_BLEND); // for text fading
		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // ditto

		// set orthograhic 1:1  pixel transform in local view coords
		glDisable(GL_DEPTH_TEST);

		glMatrixMode(GL_PROJECTION);
		glPushMatrix();
		glLoadIdentity();
		glMatrixMode(GL_MODELVIEW);
		glPushMatrix();
		glLoadIdentity();
		glColor3f(0, 1, 0);

		// left, right, bottom, top, near, far
		double tpW = (dRight-dLeft)*.05;
		double tpH = (dTop-dBottom)*.05;
		glOrtho(dLeft-tpW, dRight+tpW, dBottom-tpH, dTop+tpH, -1, 1);
		//printf("Drawing axis (%1.2f, %1.2f, %1.2f, %1.2f)\n", dLeft, dTop, dRight, dBottom);

		glColor3f(1, 1, 1); // draw axis
		glBegin(GL_LINES);
		glVertex2d(dLeft-tpW, 0); glVertex2d(dRight+tpW, 0);
		glVertex2d(0, dBottom-tpH); glVertex2d(0, dTop+tpH);
		glEnd();

		for (unsigned int x = 0; x < lines.size(); x++)
		{
			if (lines[x]->GetChanged())
				assert(false);
			//recomputeBorders = true;
			lines[x]->OpenGLDraw();
		}

		glLineWidth(3.0);
		if (lastSelectedLine != -1)
			lines[lastSelectedLine]->OpenGLDraw();
		glLineWidth(1.0);

		// draw mouse - temporary hack
		if (drawMouse)
		{
			glColor4f(0, 1, 0, .5); // draw axis
			glBegin(GL_LINES);
			glVertex2d(mouseXLoc, dBottom-tpH); glVertex2d(mouseXLoc, dTop+tpH);
			glVertex2d(dLeft-tpW, mouseYLoc); glVertex2d(dRight+tpW, mouseYLoc);
			glEnd();
		}

		glPopMatrix(); // GL_MODELVIEW
		glMatrixMode(GL_PROJECTION);
		glPopMatrix();
		glMatrixMode(matrixMode);

		glEnable(GL_DEPTH_TEST);
	}
}
<commit_msg>added assert include<commit_after>/*
 *  Plot2D.cpp
 *  hog2
 *
 *  Created by Nathan Sturtevant on 4/18/07.
 *  Copyright 2007 Nathan Sturtevant, University of Alberta. All rights reserved.
 *
 */

#include "Plot2D.h"
#include <math.h>
#include <cstring>
#include <assert.h>

namespace Plotting {

	Line::Line(char *label, tPlotType ptype)
	:plotType(ptype)
	{
		ClearColor();
		strncpy(name,label,1024);
		xMin = DBL_MAX;
		xMax = DBL_MIN;
		yMin = DBL_MAX;
		yMax = DBL_MIN;
		hidden = false;
		changedLine = false;
	}

	void Line::AddPoint(double _y)
	{
		changedLine = true;
		if (x.size() == 0)
			AddPoint(0, _y);
		else
			AddPoint(x.back()+1, _y);
	}

	void Line::AddPoint(double _x, double _y)
	{
		changedLine = true;
		if (_x < xMin)
			xMin = _x;
		if (_x > xMax)
			xMax = _x;
		if (_y < yMin)
			yMin = _y;
		if (_y > yMax)
			yMax = _y;
		x.push_back(_x);
		y.push_back(_y);

		//printf("New %s bounds (%1.2f, %1.2f, %1.2f, %1.2f)\n", name, xMin, yMax, xMax, yMin);

	}

	double Line::DistanceToLine(double xp, double yp)
	{
		double bestDist = (y[0]-yp)*(y[0]-yp)+(x[0]-xp)*(x[0]-xp);
		int bestIndex = 0;
		// Linear search? - can be sped up with binary search if needed
		for (unsigned int m = 1; m < x.size()-1; m++)
		{
			if (fless((y[m]-yp)*(y[m]-yp)+(x[m]-xp)*(x[m]-xp), bestDist))
			{
				bestDist = (y[m]-yp)*(y[m]-yp)+(x[m]-xp)*(x[m]-xp);
				bestIndex = m;
			}
		}
		return sqrt(bestDist);
	}

	double Line::VerticalDistanceToLine(double xp, double yp)
	{
		double horizDist = fabs(y[0]-yp);
		int horizIndex = 0;
		// Linear search? - can be sped up with binary search if needed
		for (unsigned int m = 1; m < x.size()-1; m++)
		{
			if (fabs(y[m]-yp) < horizDist)
			{
				horizDist = fabs(y[m]-yp);
				horizIndex = m;
			}
		}
		return fabs(x[horizIndex]-xp);
	}

	void Line::Smooth(unsigned int windowSize)
	{
		double sum=0;
		// setup initial window
		for (unsigned int m = 0; (m < x.size()) && (m < windowSize); m++)
		{
			sum += y[m];
			y[m/2] = sum/(double)(m+1);
		}
		for (unsigned int m = windowSize/2; m < x.size()-windowSize/2-1; m++)
		{
			y[m] = sum/(double)windowSize;
			sum-=y[m-windowSize/2];
			sum+=y[m+windowSize/2];
		}
		for (unsigned int m = x.size()-windowSize/2-1; m < x.size(); m++)
		{
			y[m] = sum/(double)(windowSize/2+x.size()-1-m);
			sum-=y[m-windowSize/2];
		}
	}

	void Line::ClearColor()
	{
		r = -1;
	}

	void Line::SetColor(double _r, double _g, double _b)
	{
		r = _r; g = _g; b = _b;
	}

	void Line::OpenGLDraw() const
	{
		if (hidden)
			return;
		switch (plotType)
		{
			case kLinePlot:
			{
				glBegin(GL_LINE_STRIP);
				if (r != -1)
				{
					glColor3f(r, g, b);
				}
				for (unsigned int t = 0; t < x.size(); t++)
					glVertex2d(x[t], y[t]);
				glEnd();
			}
			break;
			case kImpulsePlot:
			{
				glBegin(GL_LINES);
				if (r != -1)
				{
					glColor3f(r, g, b);
				}
				for (unsigned int t = 0; t < x.size(); t++)
				{
					glVertex2d(x[t], 0);
					glVertex2d(x[t], y[t]);
				}
				glEnd();
			}
			break;
		}
	}

	Plot2D::Plot2D()
	{
		ResetAxis();
		drawMouse = true;
		lastSelectedLine = -1;
		recomputeBorders = true;
	}

	void Plot2D::AddLine(Line *l)
	{
		lines.push_back(l);

		if (l->GetMaxX() > xMax)
			xMax = l->GetMaxX();
		if (l->GetMaxY() > yMax)
			yMax = l->GetMaxY();
		if (l->GetMinX() < xMin)
			xMin = l->GetMinX();
		if (l->GetMinY() < yMin)
			yMin = l->GetMinY();

		if (!forceAxis)
			ResetAxis();
	}

	void Plot2D::Zoom(double amt)
	{
		printf("Got amt %1.2f\n", amt);
		double cx, cy;
		amt = 1-0.01*amt;
		cx = xMin+(xMax-xMin)/2;
		cy = yMin+(yMax-yMin)/2;
		double width = (xMax-xMin)*amt;
		double height = (yMax-yMin)*amt;

		xMin = cx - width/2;
		xMax = cx + width/2;
		yMin = cy - height/2;
		yMax = cy + height/2;

		dLeft = xMin;
		dRight = xMax;
		dTop = yMax;
		dBottom = yMin;
	}

	void Plot2D::SetAxis(double minx, double miny, double maxx, double maxy)
	{
		forceAxis = true;
		xMax = maxx;
		xMin = minx;
		yMax = maxy;
		yMin = miny;
	}

	void Plot2D::ResetAxis()
	{
		forceAxis = false;
		recomputeBorders = false;
		xMin = DBL_MAX;
		xMax = DBL_MIN;
		yMin = DBL_MAX;
		yMax = DBL_MIN;

		// recompute max/min stuff
		for (unsigned int x = 0; x < lines.size(); x++)
		{
			Line *l = lines[x];

			if (l->GetMaxX() > xMax)
				xMax = l->GetMaxX();
			if (l->GetMaxY() > yMax)
				yMax = l->GetMaxY();
			if (l->GetMinX() < xMin)
				xMin = l->GetMinX();
			if (l->GetMinY() < yMin)
				yMin = l->GetMinY();
		}

		dLeft = xMin;
		dRight = xMax;
		dTop = yMax;
		dBottom = yMin;
	}

	void Plot2D::OffsetCurrMouse(double deltaX, double deltaY)
	{
		mouseXLoc += deltaX;
		mouseYLoc += deltaY;

		if (lines.size() == 0)
			return;

		double minDist = lines[0]->DistanceToLine(mouseXLoc, mouseYLoc);
		int minIndex = 0;
		for (unsigned int x = 1; x < lines.size(); x++)
		{
			if (lines[x]->IsHidden())
				continue;

			if (fless(lines[x]->DistanceToLine(mouseXLoc, mouseYLoc), minDist))
			{
				minIndex = x;
				minDist = lines[x]->DistanceToLine(mouseXLoc, mouseYLoc);
			}
			//		if (lines[x]->pointOnLine(mouseXLoc, mouseYLoc))
			//			printf("Near: %s\n", lines[x]->getLabel());
		}
		if (minIndex != lastSelectedLine)
		{
			// set colors here instead
//			if (lastSelectedLine != -1)
//				lines[lastSelectedLine]->unselect();
//			lines[minIndex]->select();
			lastSelectedLine = minIndex;
//			printf("Near: %s\n", lines[minIndex]->getLabel());
//			submitMessage(lines[minIndex]->getLabel());
		}
	}

//	void Plot2D::SetCurrMouse(double lastX, double lastY, Rect &winRect)
//	{
//		double tpW = (dRight-dLeft)*.05;
//		double tpH = (dTop-dBottom)*.05;
//		mouseXLoc = dLeft-tpW+(dRight+2*tpW - dLeft)*(lastX/winRect.right);
//		mouseYLoc = dBottom-tpH+(dTop+2*tpH - dBottom)*(1-(lastY/winRect.bottom));
//
//		if (lines.size() == 0)
//			return;
//
//		double minDist = lines[0]->DistanceToLine(mouseXLoc, mouseYLoc);
//		int minIndex = 0;
//		for (unsigned int x = 1; x < lines.size(); x++)
//		{
//			if (fless(lines[x]->DistanceToLine(mouseXLoc, mouseYLoc), minDist))
//			{
//				minIndex = x;
//				minDist = lines[x]->DistanceToLine(mouseXLoc, mouseYLoc);
//			}
//	//		if (lines[x]->pointOnLine(mouseXLoc, mouseYLoc))
//	//			printf("Near: %s\n", lines[x]->getLabel());
//		}
//		if (minIndex != lastSelectedLine)
//		{
////			if (lastSelectedLine != -1)
////				lines[lastSelectedLine]->unselect();
////			lines[minIndex]->select();
//			lastSelectedLine = minIndex;
//			//printf("Near: %s\n", lines[minIndex]->getLabel());
//			//submitMessage(lines[minIndex]->getLabel());
//		}
//	}
//
//	void Plot2D::Recenter(double lastX, double lastY, Rect &winRect)
//	{
//		double tpW = (dRight-dLeft)*.05;
//		double tpH = (dTop-dBottom)*.05;
//		double XLoc = dLeft-tpW+(dRight+2*tpW - dLeft)*(lastX/winRect.right);
//		double YLoc = dBottom-tpH+(dTop+2*tpH - dBottom)*(1-(lastY/winRect.bottom));
//
//		xMin = XLoc - (dRight-dLeft)/2;
//		xMax = XLoc + (dRight-dLeft)/2;
//		yMin = YLoc - (dTop-dBottom)/2;
//		yMax = YLoc + (dTop-dBottom)/2;
//
//		dLeft = xMin;
//		dRight = xMax;
//		dTop = yMax;
//		dBottom = yMin;
//
//	}

	void Plot2D::SmoothLines()
	{
		for (unsigned int x = 0; x < lines.size(); x++)
			lines[x]->Smooth(50);
		ResetAxis();
	}

	void Plot2D::OpenGLDraw() const
	{
		GLint matrixMode;

		if (recomputeBorders)
			assert(false);
//			ResetAxis();

		glGetIntegerv(GL_MATRIX_MODE, &matrixMode);

		glEnable(GL_BLEND); // for text fading
		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // ditto

		// set orthograhic 1:1  pixel transform in local view coords
		glDisable(GL_DEPTH_TEST);

		glMatrixMode(GL_PROJECTION);
		glPushMatrix();
		glLoadIdentity();
		glMatrixMode(GL_MODELVIEW);
		glPushMatrix();
		glLoadIdentity();
		glColor3f(0, 1, 0);

		// left, right, bottom, top, near, far
		double tpW = (dRight-dLeft)*.05;
		double tpH = (dTop-dBottom)*.05;
		glOrtho(dLeft-tpW, dRight+tpW, dBottom-tpH, dTop+tpH, -1, 1);
		//printf("Drawing axis (%1.2f, %1.2f, %1.2f, %1.2f)\n", dLeft, dTop, dRight, dBottom);

		glColor3f(1, 1, 1); // draw axis
		glBegin(GL_LINES);
		glVertex2d(dLeft-tpW, 0); glVertex2d(dRight+tpW, 0);
		glVertex2d(0, dBottom-tpH); glVertex2d(0, dTop+tpH);
		glEnd();

		for (unsigned int x = 0; x < lines.size(); x++)
		{
			if (lines[x]->GetChanged())
				assert(false);
			//recomputeBorders = true;
			lines[x]->OpenGLDraw();
		}

		glLineWidth(3.0);
		if (lastSelectedLine != -1)
			lines[lastSelectedLine]->OpenGLDraw();
		glLineWidth(1.0);

		// draw mouse - temporary hack
		if (drawMouse)
		{
			glColor4f(0, 1, 0, .5); // draw axis
			glBegin(GL_LINES);
			glVertex2d(mouseXLoc, dBottom-tpH); glVertex2d(mouseXLoc, dTop+tpH);
			glVertex2d(dLeft-tpW, mouseYLoc); glVertex2d(dRight+tpW, mouseYLoc);
			glEnd();
		}

		glPopMatrix(); // GL_MODELVIEW
		glMatrixMode(GL_PROJECTION);
		glPopMatrix();
		glMatrixMode(matrixMode);

		glEnable(GL_DEPTH_TEST);
	}
}
<|endoftext|>


<commit_before><commit_msg>Care for the entire height of the hbox when intersecting with obstacles, not just the baseline.<commit_after><|endoftext|>