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

#include <algorithm>
#include <vector>

#include "base/file_path.h"
#include "base/file_util.h"
#include "base/message_loop.h"
#include "base/path_service.h"
#include "base/string_util.h"
#include "chrome/browser/extensions/extension.h"
#include "chrome/browser/extensions/extensions_service.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/json_value_serializer.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/platform_test.h"

namespace {

struct ExtensionsOrder {
  bool operator()(const Extension* a, const Extension* b) {
    return a->name() < b->name();
  }
};

}  // namespace

// A mock implementation of ExtensionsServiceFrontendInterface for testing the
// backend.
class ExtensionsServiceTestFrontend
    : public ExtensionsServiceFrontendInterface {
 public:
  ~ExtensionsServiceTestFrontend() {
    for (ExtensionList::iterator iter = extensions_.begin();
         iter != extensions_.end(); ++iter) {
      delete *iter;
    }
  }

  std::vector<std::string>* errors() {
    return &errors_;
  }

  ExtensionList* extensions() {
    return &extensions_;
  }

  // ExtensionsServiceFrontendInterface
  virtual MessageLoop* GetMessageLoop() {
    return &message_loop_;
  }

  virtual void OnExtensionLoadError(const std::string& message) {
    errors_.push_back(message);
  }

  virtual void OnExtensionsLoadedFromDirectory(ExtensionList* new_extensions) {
    extensions_.insert(extensions_.end(), new_extensions->begin(),
                       new_extensions->end());
    delete new_extensions;
    // In the tests we rely on extensions being in particular order,
    // which is not always the case (and is not guaranteed by used APIs).
    std::stable_sort(extensions_.begin(), extensions_.end(), ExtensionsOrder());
  }

 private:
  MessageLoop message_loop_;
  ExtensionList extensions_;
  std::vector<std::string> errors_;
};

// make the test a PlatformTest to setup autorelease pools properly on mac
typedef PlatformTest ExtensionsServiceTest;

// Test loading extensions from the profile directory.
TEST_F(ExtensionsServiceTest, LoadAllExtensionsFromDirectory) {
  std::wstring extensions_dir;
  ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_dir));
  FilePath manifest_path = FilePath::FromWStringHack(extensions_dir).Append(
      FILE_PATH_LITERAL("extensions"));

  scoped_refptr<ExtensionsServiceBackend> backend(new ExtensionsServiceBackend);
  scoped_refptr<ExtensionsServiceTestFrontend> frontend(
      new ExtensionsServiceTestFrontend);

  std::vector<Extension*> extensions;
  EXPECT_TRUE(backend->LoadExtensionsFromDirectory(manifest_path,
      scoped_refptr<ExtensionsServiceFrontendInterface>(frontend.get())));
  frontend->GetMessageLoop()->RunAllPending();

  // Note: There can be more errors if there are extra directories, like .svn
  // directories.
  EXPECT_TRUE(frontend->errors()->size() >= 2u);
  ASSERT_EQ(2u, frontend->extensions()->size());

  EXPECT_EQ(std::wstring(L"com.google.myextension1"),
            frontend->extensions()->at(0)->id());
  EXPECT_EQ(std::wstring(L"My extension 1"),
            frontend->extensions()->at(0)->name());
  EXPECT_EQ(std::wstring(L"The first extension that I made."),
            frontend->extensions()->at(0)->description());
  ASSERT_EQ(2u, frontend->extensions()->at(0)->content_scripts().size());
  EXPECT_EQ(std::wstring(L"script1.user.js"),
            frontend->extensions()->at(0)->content_scripts().at(0));
  EXPECT_EQ(std::wstring(L"script2.user.js"),
            frontend->extensions()->at(0)->content_scripts().at(1));

  EXPECT_EQ(std::wstring(L"com.google.myextension2"),
            frontend->extensions()->at(1)->id());
  EXPECT_EQ(std::wstring(L"My extension 2"),
            frontend->extensions()->at(1)->name());
  EXPECT_EQ(std::wstring(L""),
            frontend->extensions()->at(1)->description());
  ASSERT_EQ(0u, frontend->extensions()->at(1)->content_scripts().size());
};
<commit_msg>Reverting 6787. inteded to commit other changelist. Review URL: http://codereview.chromium.org/13387<commit_after>// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <vector>

#include "base/file_path.h"
#include "base/file_util.h"
#include "base/message_loop.h"
#include "base/path_service.h"
#include "base/string_util.h"
#include "chrome/browser/extensions/extensions_service.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/json_value_serializer.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/platform_test.h"

// A mock implementation of ExtensionsServiceFrontendInterface for testing the
// backend.
class ExtensionsServiceTestFrontend
    : public ExtensionsServiceFrontendInterface {
 public:
  ~ExtensionsServiceTestFrontend() {
    for (ExtensionList::iterator iter = extensions_.begin();
         iter != extensions_.end(); ++iter) {
      delete *iter;
    }
  }

  std::vector<std::string>* errors() {
    return &errors_;
  }

  ExtensionList* extensions() {
    return &extensions_;
  }

  // ExtensionsServiceFrontendInterface
  virtual MessageLoop* GetMessageLoop() {
    return &message_loop_;
  }

  virtual void OnExtensionLoadError(const std::string& message) {
    errors_.push_back(message);
  }

  virtual void OnExtensionsLoadedFromDirectory(ExtensionList* new_extensions) {
    extensions_.insert(extensions_.end(), new_extensions->begin(),
                       new_extensions->end());
    delete new_extensions;
  }

 private:
  MessageLoop message_loop_;
  ExtensionList extensions_;
  std::vector<std::string> errors_;
};

// make the test a PlatformTest to setup autorelease pools properly on mac
typedef PlatformTest ExtensionsServiceTest;

// Test loading extensions from the profile directory.
TEST_F(ExtensionsServiceTest, LoadAllExtensionsFromDirectory) {
  std::wstring extensions_dir;
  ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_dir));
  FilePath manifest_path = FilePath::FromWStringHack(extensions_dir).Append(
      FILE_PATH_LITERAL("extensions"));

  scoped_refptr<ExtensionsServiceBackend> backend(new ExtensionsServiceBackend);
  scoped_refptr<ExtensionsServiceTestFrontend> frontend(
      new ExtensionsServiceTestFrontend);

  std::vector<Extension*> extensions;
  EXPECT_TRUE(backend->LoadExtensionsFromDirectory(manifest_path,
      scoped_refptr<ExtensionsServiceFrontendInterface>(frontend.get())));
  frontend->GetMessageLoop()->RunAllPending();

  // Note: There can be more errors if there are extra directories, like .svn
  // directories.
  EXPECT_TRUE(frontend->errors()->size() >= 2u);
  EXPECT_EQ(2u, frontend->extensions()->size());

  EXPECT_EQ(std::wstring(L"com.google.myextension1"),
            frontend->extensions()->at(0)->id());
  EXPECT_EQ(std::wstring(L"My extension 1"),
            frontend->extensions()->at(0)->name());
  EXPECT_EQ(std::wstring(L"The first extension that I made."),
            frontend->extensions()->at(0)->description());
  EXPECT_EQ(2u, frontend->extensions()->at(0)->content_scripts().size());
  EXPECT_EQ(std::wstring(L"script1.user.js"),
            frontend->extensions()->at(0)->content_scripts().at(0));
  EXPECT_EQ(std::wstring(L"script2.user.js"),
            frontend->extensions()->at(0)->content_scripts().at(1));

  EXPECT_EQ(std::wstring(L"com.google.myextension2"),
            frontend->extensions()->at(1)->id());
  EXPECT_EQ(std::wstring(L"My extension 2"),
            frontend->extensions()->at(1)->name());
  EXPECT_EQ(std::wstring(L""),
            frontend->extensions()->at(1)->description());
  EXPECT_EQ(0u, frontend->extensions()->at(1)->content_scripts().size());
};
<|endoftext|>


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

#include "chrome/browser/net/pref_proxy_config_service.h"

#include "base/command_line.h"
#include "base/file_path.h"
#include "chrome/browser/net/chrome_url_request_context.h"
#include "chrome/browser/prefs/pref_service_mock_builder.h"
#include "chrome/browser/prefs/proxy_config_dictionary.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/testing_pref_service.h"
#include "net/proxy/proxy_config_service_common_unittest.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using testing::_;
using testing::Mock;

namespace {

const char kFixedPacUrl[] = "http://chromium.org/fixed_pac_url";

// Testing proxy config service that allows us to fire notifications at will.
class TestProxyConfigService : public net::ProxyConfigService {
 public:
  TestProxyConfigService(const net::ProxyConfig& config,
                         ConfigAvailability availability)
      : config_(config),
        availability_(availability) {}

  void SetProxyConfig(const net::ProxyConfig config,
                      ConfigAvailability availability) {
    config_ = config;
    availability_ = availability;
    FOR_EACH_OBSERVER(net::ProxyConfigService::Observer, observers_,
                      OnProxyConfigChanged(config, availability));
  }

 private:
  virtual void AddObserver(net::ProxyConfigService::Observer* observer) {
    observers_.AddObserver(observer);
  }

  virtual void RemoveObserver(net::ProxyConfigService::Observer* observer) {
    observers_.RemoveObserver(observer);
  }

  virtual net::ProxyConfigService::ConfigAvailability GetLatestProxyConfig(
      net::ProxyConfig* config) {
    *config = config_;
    return availability_;
  }

  net::ProxyConfig config_;
  ConfigAvailability availability_;
  ObserverList<net::ProxyConfigService::Observer, true> observers_;
};

// A mock observer for capturing callbacks.
class MockObserver : public net::ProxyConfigService::Observer {
 public:
  MOCK_METHOD2(OnProxyConfigChanged,
               void(const net::ProxyConfig&,
                    net::ProxyConfigService::ConfigAvailability));
};

template<typename TESTBASE>
class PrefProxyConfigServiceTestBase : public TESTBASE {
 protected:
  PrefProxyConfigServiceTestBase()
      : ui_thread_(BrowserThread::UI, &loop_),
        io_thread_(BrowserThread::IO, &loop_) {}

  virtual void Init(PrefService* pref_service) {
    ASSERT_TRUE(pref_service);
    PrefProxyConfigService::RegisterPrefs(pref_service);
    fixed_config_.set_pac_url(GURL(kFixedPacUrl));
    delegate_service_ =
        new TestProxyConfigService(fixed_config_,
                                   net::ProxyConfigService::CONFIG_VALID);
    proxy_config_tracker_ = new PrefProxyConfigTracker(pref_service);
    proxy_config_service_.reset(
        new PrefProxyConfigService(proxy_config_tracker_.get(),
                                   delegate_service_));
  }

  virtual void TearDown() {
    proxy_config_tracker_->DetachFromPrefService();
    loop_.RunAllPending();
    proxy_config_service_.reset();
  }

  MessageLoop loop_;
  TestProxyConfigService* delegate_service_; // weak
  scoped_ptr<PrefProxyConfigService> proxy_config_service_;
  net::ProxyConfig fixed_config_;

 private:
  scoped_refptr<PrefProxyConfigTracker> proxy_config_tracker_;
  BrowserThread ui_thread_;
  BrowserThread io_thread_;
};

class PrefProxyConfigServiceTest
    : public PrefProxyConfigServiceTestBase<testing::Test> {
 protected:
  virtual void SetUp() {
    pref_service_.reset(new TestingPrefService());
    Init(pref_service_.get());
  }

  scoped_ptr<TestingPrefService> pref_service_;
};

TEST_F(PrefProxyConfigServiceTest, BaseConfiguration) {
  net::ProxyConfig actual_config;
  EXPECT_EQ(net::ProxyConfigService::CONFIG_VALID,
            proxy_config_service_->GetLatestProxyConfig(&actual_config));
  EXPECT_EQ(GURL(kFixedPacUrl), actual_config.pac_url());
}

TEST_F(PrefProxyConfigServiceTest, DynamicPrefOverrides) {
  pref_service_->SetManagedPref(
      prefs::kProxy,
      ProxyConfigDictionary::CreateFixedServers("http://example.com:3128", ""));
  loop_.RunAllPending();

  net::ProxyConfig actual_config;
  EXPECT_EQ(net::ProxyConfigService::CONFIG_VALID,
            proxy_config_service_->GetLatestProxyConfig(&actual_config));
  EXPECT_FALSE(actual_config.auto_detect());
  EXPECT_EQ(net::ProxyConfig::ProxyRules::TYPE_SINGLE_PROXY,
            actual_config.proxy_rules().type);
  EXPECT_EQ(actual_config.proxy_rules().single_proxy,
            net::ProxyServer::FromURI("http://example.com:3128",
                                      net::ProxyServer::SCHEME_HTTP));

  pref_service_->SetManagedPref(prefs::kProxy,
                                ProxyConfigDictionary::CreateAutoDetect());
  loop_.RunAllPending();

  EXPECT_EQ(net::ProxyConfigService::CONFIG_VALID,
            proxy_config_service_->GetLatestProxyConfig(&actual_config));
  EXPECT_TRUE(actual_config.auto_detect());
}

// Compares proxy configurations, but allows different identifiers.
MATCHER_P(ProxyConfigMatches, config, "") {
  net::ProxyConfig reference(config);
  reference.set_id(arg.id());
  return reference.Equals(arg);
}

TEST_F(PrefProxyConfigServiceTest, Observers) {
  const net::ProxyConfigService::ConfigAvailability CONFIG_VALID =
      net::ProxyConfigService::CONFIG_VALID;
  MockObserver observer;
  proxy_config_service_->AddObserver(&observer);

  // Firing the observers in the delegate should trigger a notification.
  net::ProxyConfig config2;
  config2.set_auto_detect(true);
  EXPECT_CALL(observer, OnProxyConfigChanged(ProxyConfigMatches(config2),
                                             CONFIG_VALID)).Times(1);
  delegate_service_->SetProxyConfig(config2, CONFIG_VALID);
  loop_.RunAllPending();
  Mock::VerifyAndClearExpectations(&observer);

  // Override configuration, this should trigger a notification.
  net::ProxyConfig pref_config;
  pref_config.set_pac_url(GURL(kFixedPacUrl));

  EXPECT_CALL(observer, OnProxyConfigChanged(ProxyConfigMatches(pref_config),
                                             CONFIG_VALID)).Times(1);
  pref_service_->SetManagedPref(
      prefs::kProxy,
      ProxyConfigDictionary::CreatePacScript(kFixedPacUrl));
  loop_.RunAllPending();
  Mock::VerifyAndClearExpectations(&observer);

  // Since there are pref overrides, delegate changes should be ignored.
  net::ProxyConfig config3;
  config3.proxy_rules().ParseFromString("http=config3:80");
  EXPECT_CALL(observer, OnProxyConfigChanged(_, _)).Times(0);
  fixed_config_.set_auto_detect(true);
  delegate_service_->SetProxyConfig(config3, CONFIG_VALID);
  loop_.RunAllPending();
  Mock::VerifyAndClearExpectations(&observer);

  // Clear the override should switch back to the fixed configuration.
  EXPECT_CALL(observer, OnProxyConfigChanged(ProxyConfigMatches(config3),
                                             CONFIG_VALID)).Times(1);
  pref_service_->RemoveManagedPref(prefs::kProxy);
  loop_.RunAllPending();
  Mock::VerifyAndClearExpectations(&observer);

  // Delegate service notifications should show up again.
  net::ProxyConfig config4;
  config4.proxy_rules().ParseFromString("socks:config4");
  EXPECT_CALL(observer, OnProxyConfigChanged(ProxyConfigMatches(config4),
                                             CONFIG_VALID)).Times(1);
  delegate_service_->SetProxyConfig(config4, CONFIG_VALID);
  loop_.RunAllPending();
  Mock::VerifyAndClearExpectations(&observer);

  proxy_config_service_->RemoveObserver(&observer);
}

TEST_F(PrefProxyConfigServiceTest, Fallback) {
  const net::ProxyConfigService::ConfigAvailability CONFIG_VALID =
      net::ProxyConfigService::CONFIG_VALID;
  MockObserver observer;
  net::ProxyConfig actual_config;
  delegate_service_->SetProxyConfig(net::ProxyConfig::CreateDirect(),
                                    net::ProxyConfigService::CONFIG_UNSET);
  proxy_config_service_->AddObserver(&observer);

  // Prepare test data.
  net::ProxyConfig recommended_config = net::ProxyConfig::CreateAutoDetect();
  net::ProxyConfig user_config =
      net::ProxyConfig::CreateFromCustomPacURL(GURL(kFixedPacUrl));

  // Set a recommended pref.
  EXPECT_CALL(observer,
              OnProxyConfigChanged(ProxyConfigMatches(recommended_config),
                                   CONFIG_VALID)).Times(1);
  pref_service_->SetRecommendedPref(
      prefs::kProxy,
      ProxyConfigDictionary::CreateAutoDetect());
  loop_.RunAllPending();
  Mock::VerifyAndClearExpectations(&observer);
  EXPECT_EQ(CONFIG_VALID,
            proxy_config_service_->GetLatestProxyConfig(&actual_config));
  EXPECT_THAT(actual_config, ProxyConfigMatches(recommended_config));

  // Override in user prefs.
  EXPECT_CALL(observer,
              OnProxyConfigChanged(ProxyConfigMatches(user_config),
                                   CONFIG_VALID)).Times(1);
  pref_service_->SetManagedPref(
      prefs::kProxy,
      ProxyConfigDictionary::CreatePacScript(kFixedPacUrl));
  loop_.RunAllPending();
  Mock::VerifyAndClearExpectations(&observer);
  EXPECT_EQ(CONFIG_VALID,
            proxy_config_service_->GetLatestProxyConfig(&actual_config));
  EXPECT_THAT(actual_config, ProxyConfigMatches(user_config));

  // Go back to recommended pref.
  EXPECT_CALL(observer,
              OnProxyConfigChanged(ProxyConfigMatches(recommended_config),
                                   CONFIG_VALID)).Times(1);
  pref_service_->RemoveManagedPref(prefs::kProxy);
  loop_.RunAllPending();
  Mock::VerifyAndClearExpectations(&observer);
  EXPECT_EQ(CONFIG_VALID,
            proxy_config_service_->GetLatestProxyConfig(&actual_config));
  EXPECT_THAT(actual_config, ProxyConfigMatches(recommended_config));

  proxy_config_service_->RemoveObserver(&observer);
}

// Test parameter object for testing command line proxy configuration.
struct CommandLineTestParams {
  // Explicit assignment operator, so testing::TestWithParam works with MSVC.
  CommandLineTestParams& operator=(const CommandLineTestParams& other) {
    description = other.description;
    for (unsigned int i = 0; i < arraysize(switches); i++)
      switches[i] = other.switches[i];
    is_null = other.is_null;
    auto_detect = other.auto_detect;
    pac_url = other.pac_url;
    proxy_rules = other.proxy_rules;
    return *this;
  }

  // Short description to identify the test.
  const char* description;

  // The command line to build a ProxyConfig from.
  struct SwitchValue {
    const char* name;
    const char* value;
  } switches[2];

  // Expected outputs (fields of the ProxyConfig).
  bool is_null;
  bool auto_detect;
  GURL pac_url;
  net::ProxyRulesExpectation proxy_rules;
};

void PrintTo(const CommandLineTestParams& params, std::ostream* os) {
  *os << params.description;
}

class PrefProxyConfigServiceCommandLineTest
    : public PrefProxyConfigServiceTestBase<
          testing::TestWithParam<CommandLineTestParams> > {
 protected:
  PrefProxyConfigServiceCommandLineTest()
      : command_line_(CommandLine::NO_PROGRAM) {}

  virtual void SetUp() {
    for (size_t i = 0; i < arraysize(GetParam().switches); i++) {
      const char* name = GetParam().switches[i].name;
      const char* value = GetParam().switches[i].value;
      if (name && value)
        command_line_.AppendSwitchASCII(name, value);
      else if (name)
        command_line_.AppendSwitch(name);
    }
    pref_service_.reset(
        PrefServiceMockBuilder().WithCommandLine(&command_line_).Create());
    Init(pref_service_.get());
  }

 private:
  CommandLine command_line_;
  scoped_ptr<PrefService> pref_service_;
};

TEST_P(PrefProxyConfigServiceCommandLineTest, CommandLine) {
  net::ProxyConfig config;
  EXPECT_EQ(net::ProxyConfigService::CONFIG_VALID,
            proxy_config_service_->GetLatestProxyConfig(&config));

  if (GetParam().is_null) {
    EXPECT_EQ(GURL(kFixedPacUrl), config.pac_url());
  } else {
    EXPECT_NE(GURL(kFixedPacUrl), config.pac_url());
    EXPECT_EQ(GetParam().auto_detect, config.auto_detect());
    EXPECT_EQ(GetParam().pac_url, config.pac_url());
    EXPECT_TRUE(GetParam().proxy_rules.Matches(config.proxy_rules()));
  }
}

static const CommandLineTestParams kCommandLineTestParams[] = {
  {
    "Empty command line",
    // Input
    { },
    // Expected result
    true,                                               // is_null
    false,                                              // auto_detect
    GURL(),                                             // pac_url
    net::ProxyRulesExpectation::Empty(),
  },
  {
    "No proxy",
    // Input
    {
      { switches::kNoProxyServer, NULL },
    },
    // Expected result
    false,                                              // is_null
    false,                                              // auto_detect
    GURL(),                                             // pac_url
    net::ProxyRulesExpectation::Empty(),
  },
  {
    "No proxy with extra parameters.",
    // Input
    {
      { switches::kNoProxyServer, NULL },
      { switches::kProxyServer, "http://proxy:8888" },
    },
    // Expected result
    false,                                              // is_null
    false,                                              // auto_detect
    GURL(),                                             // pac_url
    net::ProxyRulesExpectation::Empty(),
  },
  {
    "Single proxy.",
    // Input
    {
      { switches::kProxyServer, "http://proxy:8888" },
    },
    // Expected result
    false,                                              // is_null
    false,                                              // auto_detect
    GURL(),                                             // pac_url
    net::ProxyRulesExpectation::Single(
        "proxy:8888",  // single proxy
        ""),           // bypass rules
  },
  {
    "Per scheme proxy.",
    // Input
    {
      { switches::kProxyServer, "http=httpproxy:8888;ftp=ftpproxy:8889" },
    },
    // Expected result
    false,                                              // is_null
    false,                                              // auto_detect
    GURL(),                                             // pac_url
    net::ProxyRulesExpectation::PerScheme(
        "httpproxy:8888",  // http
        "",                // https
        "ftpproxy:8889",   // ftp
        ""),               // bypass rules
  },
  {
    "Per scheme proxy with bypass URLs.",
    // Input
    {
      { switches::kProxyServer, "http=httpproxy:8888;ftp=ftpproxy:8889" },
      { switches::kProxyBypassList,
        ".google.com, foo.com:99, 1.2.3.4:22, 127.0.0.1/8" },
    },
    // Expected result
    false,                                              // is_null
    false,                                              // auto_detect
    GURL(),                                             // pac_url
    net::ProxyRulesExpectation::PerScheme(
        "httpproxy:8888",  // http
        "",                // https
        "ftpproxy:8889",   // ftp
        "*.google.com,foo.com:99,1.2.3.4:22,127.0.0.1/8"),
  },
  {
    "Pac URL",
    // Input
    {
      { switches::kProxyPacUrl, "http://wpad/wpad.dat" },
    },
    // Expected result
    false,                                              // is_null
    false,                                              // auto_detect
    GURL("http://wpad/wpad.dat"),                       // pac_url
    net::ProxyRulesExpectation::Empty(),
  },
  {
    "Autodetect",
    // Input
    {
      { switches::kProxyAutoDetect, NULL },
    },
    // Expected result
    false,                                              // is_null
    true,                                               // auto_detect
    GURL(),                                             // pac_url
    net::ProxyRulesExpectation::Empty(),
  },
};

INSTANTIATE_TEST_CASE_P(
    PrefProxyConfigServiceCommandLineTestInstance,
    PrefProxyConfigServiceCommandLineTest,
    testing::ValuesIn(kCommandLineTestParams));

}  // namespace
<commit_msg>Replace gmock's EXPECT_THAT by an explicit check when comparing proxy config in PrefProxyConfigServiceTest.Fallback. This should avoid having gtest print the objects, which results in uninitialized memory accesses.<commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/net/pref_proxy_config_service.h"

#include "base/command_line.h"
#include "base/file_path.h"
#include "chrome/browser/net/chrome_url_request_context.h"
#include "chrome/browser/prefs/pref_service_mock_builder.h"
#include "chrome/browser/prefs/proxy_config_dictionary.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/testing_pref_service.h"
#include "net/proxy/proxy_config_service_common_unittest.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using testing::_;
using testing::Mock;

namespace {

const char kFixedPacUrl[] = "http://chromium.org/fixed_pac_url";

// Testing proxy config service that allows us to fire notifications at will.
class TestProxyConfigService : public net::ProxyConfigService {
 public:
  TestProxyConfigService(const net::ProxyConfig& config,
                         ConfigAvailability availability)
      : config_(config),
        availability_(availability) {}

  void SetProxyConfig(const net::ProxyConfig config,
                      ConfigAvailability availability) {
    config_ = config;
    availability_ = availability;
    FOR_EACH_OBSERVER(net::ProxyConfigService::Observer, observers_,
                      OnProxyConfigChanged(config, availability));
  }

 private:
  virtual void AddObserver(net::ProxyConfigService::Observer* observer) {
    observers_.AddObserver(observer);
  }

  virtual void RemoveObserver(net::ProxyConfigService::Observer* observer) {
    observers_.RemoveObserver(observer);
  }

  virtual net::ProxyConfigService::ConfigAvailability GetLatestProxyConfig(
      net::ProxyConfig* config) {
    *config = config_;
    return availability_;
  }

  net::ProxyConfig config_;
  ConfigAvailability availability_;
  ObserverList<net::ProxyConfigService::Observer, true> observers_;
};

// A mock observer for capturing callbacks.
class MockObserver : public net::ProxyConfigService::Observer {
 public:
  MOCK_METHOD2(OnProxyConfigChanged,
               void(const net::ProxyConfig&,
                    net::ProxyConfigService::ConfigAvailability));
};

template<typename TESTBASE>
class PrefProxyConfigServiceTestBase : public TESTBASE {
 protected:
  PrefProxyConfigServiceTestBase()
      : ui_thread_(BrowserThread::UI, &loop_),
        io_thread_(BrowserThread::IO, &loop_) {}

  virtual void Init(PrefService* pref_service) {
    ASSERT_TRUE(pref_service);
    PrefProxyConfigService::RegisterPrefs(pref_service);
    fixed_config_.set_pac_url(GURL(kFixedPacUrl));
    delegate_service_ =
        new TestProxyConfigService(fixed_config_,
                                   net::ProxyConfigService::CONFIG_VALID);
    proxy_config_tracker_ = new PrefProxyConfigTracker(pref_service);
    proxy_config_service_.reset(
        new PrefProxyConfigService(proxy_config_tracker_.get(),
                                   delegate_service_));
  }

  virtual void TearDown() {
    proxy_config_tracker_->DetachFromPrefService();
    loop_.RunAllPending();
    proxy_config_service_.reset();
  }

  MessageLoop loop_;
  TestProxyConfigService* delegate_service_; // weak
  scoped_ptr<PrefProxyConfigService> proxy_config_service_;
  net::ProxyConfig fixed_config_;

 private:
  scoped_refptr<PrefProxyConfigTracker> proxy_config_tracker_;
  BrowserThread ui_thread_;
  BrowserThread io_thread_;
};

class PrefProxyConfigServiceTest
    : public PrefProxyConfigServiceTestBase<testing::Test> {
 protected:
  virtual void SetUp() {
    pref_service_.reset(new TestingPrefService());
    Init(pref_service_.get());
  }

  scoped_ptr<TestingPrefService> pref_service_;
};

TEST_F(PrefProxyConfigServiceTest, BaseConfiguration) {
  net::ProxyConfig actual_config;
  EXPECT_EQ(net::ProxyConfigService::CONFIG_VALID,
            proxy_config_service_->GetLatestProxyConfig(&actual_config));
  EXPECT_EQ(GURL(kFixedPacUrl), actual_config.pac_url());
}

TEST_F(PrefProxyConfigServiceTest, DynamicPrefOverrides) {
  pref_service_->SetManagedPref(
      prefs::kProxy,
      ProxyConfigDictionary::CreateFixedServers("http://example.com:3128", ""));
  loop_.RunAllPending();

  net::ProxyConfig actual_config;
  EXPECT_EQ(net::ProxyConfigService::CONFIG_VALID,
            proxy_config_service_->GetLatestProxyConfig(&actual_config));
  EXPECT_FALSE(actual_config.auto_detect());
  EXPECT_EQ(net::ProxyConfig::ProxyRules::TYPE_SINGLE_PROXY,
            actual_config.proxy_rules().type);
  EXPECT_EQ(actual_config.proxy_rules().single_proxy,
            net::ProxyServer::FromURI("http://example.com:3128",
                                      net::ProxyServer::SCHEME_HTTP));

  pref_service_->SetManagedPref(prefs::kProxy,
                                ProxyConfigDictionary::CreateAutoDetect());
  loop_.RunAllPending();

  EXPECT_EQ(net::ProxyConfigService::CONFIG_VALID,
            proxy_config_service_->GetLatestProxyConfig(&actual_config));
  EXPECT_TRUE(actual_config.auto_detect());
}

// Compares proxy configurations, but allows different identifiers.
MATCHER_P(ProxyConfigMatches, config, "") {
  net::ProxyConfig reference(config);
  reference.set_id(arg.id());
  return reference.Equals(arg);
}

TEST_F(PrefProxyConfigServiceTest, Observers) {
  const net::ProxyConfigService::ConfigAvailability CONFIG_VALID =
      net::ProxyConfigService::CONFIG_VALID;
  MockObserver observer;
  proxy_config_service_->AddObserver(&observer);

  // Firing the observers in the delegate should trigger a notification.
  net::ProxyConfig config2;
  config2.set_auto_detect(true);
  EXPECT_CALL(observer, OnProxyConfigChanged(ProxyConfigMatches(config2),
                                             CONFIG_VALID)).Times(1);
  delegate_service_->SetProxyConfig(config2, CONFIG_VALID);
  loop_.RunAllPending();
  Mock::VerifyAndClearExpectations(&observer);

  // Override configuration, this should trigger a notification.
  net::ProxyConfig pref_config;
  pref_config.set_pac_url(GURL(kFixedPacUrl));

  EXPECT_CALL(observer, OnProxyConfigChanged(ProxyConfigMatches(pref_config),
                                             CONFIG_VALID)).Times(1);
  pref_service_->SetManagedPref(
      prefs::kProxy,
      ProxyConfigDictionary::CreatePacScript(kFixedPacUrl));
  loop_.RunAllPending();
  Mock::VerifyAndClearExpectations(&observer);

  // Since there are pref overrides, delegate changes should be ignored.
  net::ProxyConfig config3;
  config3.proxy_rules().ParseFromString("http=config3:80");
  EXPECT_CALL(observer, OnProxyConfigChanged(_, _)).Times(0);
  fixed_config_.set_auto_detect(true);
  delegate_service_->SetProxyConfig(config3, CONFIG_VALID);
  loop_.RunAllPending();
  Mock::VerifyAndClearExpectations(&observer);

  // Clear the override should switch back to the fixed configuration.
  EXPECT_CALL(observer, OnProxyConfigChanged(ProxyConfigMatches(config3),
                                             CONFIG_VALID)).Times(1);
  pref_service_->RemoveManagedPref(prefs::kProxy);
  loop_.RunAllPending();
  Mock::VerifyAndClearExpectations(&observer);

  // Delegate service notifications should show up again.
  net::ProxyConfig config4;
  config4.proxy_rules().ParseFromString("socks:config4");
  EXPECT_CALL(observer, OnProxyConfigChanged(ProxyConfigMatches(config4),
                                             CONFIG_VALID)).Times(1);
  delegate_service_->SetProxyConfig(config4, CONFIG_VALID);
  loop_.RunAllPending();
  Mock::VerifyAndClearExpectations(&observer);

  proxy_config_service_->RemoveObserver(&observer);
}

TEST_F(PrefProxyConfigServiceTest, Fallback) {
  const net::ProxyConfigService::ConfigAvailability CONFIG_VALID =
      net::ProxyConfigService::CONFIG_VALID;
  MockObserver observer;
  net::ProxyConfig actual_config;
  delegate_service_->SetProxyConfig(net::ProxyConfig::CreateDirect(),
                                    net::ProxyConfigService::CONFIG_UNSET);
  proxy_config_service_->AddObserver(&observer);

  // Prepare test data.
  net::ProxyConfig recommended_config = net::ProxyConfig::CreateAutoDetect();
  net::ProxyConfig user_config =
      net::ProxyConfig::CreateFromCustomPacURL(GURL(kFixedPacUrl));

  // Set a recommended pref.
  EXPECT_CALL(observer,
              OnProxyConfigChanged(ProxyConfigMatches(recommended_config),
                                   CONFIG_VALID)).Times(1);
  pref_service_->SetRecommendedPref(
      prefs::kProxy,
      ProxyConfigDictionary::CreateAutoDetect());
  loop_.RunAllPending();
  Mock::VerifyAndClearExpectations(&observer);
  EXPECT_EQ(CONFIG_VALID,
            proxy_config_service_->GetLatestProxyConfig(&actual_config));
  EXPECT_TRUE(actual_config.Equals(recommended_config));

  // Override in user prefs.
  EXPECT_CALL(observer,
              OnProxyConfigChanged(ProxyConfigMatches(user_config),
                                   CONFIG_VALID)).Times(1);
  pref_service_->SetManagedPref(
      prefs::kProxy,
      ProxyConfigDictionary::CreatePacScript(kFixedPacUrl));
  loop_.RunAllPending();
  Mock::VerifyAndClearExpectations(&observer);
  EXPECT_EQ(CONFIG_VALID,
            proxy_config_service_->GetLatestProxyConfig(&actual_config));
  EXPECT_TRUE(actual_config.Equals(user_config));

  // Go back to recommended pref.
  EXPECT_CALL(observer,
              OnProxyConfigChanged(ProxyConfigMatches(recommended_config),
                                   CONFIG_VALID)).Times(1);
  pref_service_->RemoveManagedPref(prefs::kProxy);
  loop_.RunAllPending();
  Mock::VerifyAndClearExpectations(&observer);
  EXPECT_EQ(CONFIG_VALID,
            proxy_config_service_->GetLatestProxyConfig(&actual_config));
  EXPECT_TRUE(actual_config.Equals(recommended_config));

  proxy_config_service_->RemoveObserver(&observer);
}

// Test parameter object for testing command line proxy configuration.
struct CommandLineTestParams {
  // Explicit assignment operator, so testing::TestWithParam works with MSVC.
  CommandLineTestParams& operator=(const CommandLineTestParams& other) {
    description = other.description;
    for (unsigned int i = 0; i < arraysize(switches); i++)
      switches[i] = other.switches[i];
    is_null = other.is_null;
    auto_detect = other.auto_detect;
    pac_url = other.pac_url;
    proxy_rules = other.proxy_rules;
    return *this;
  }

  // Short description to identify the test.
  const char* description;

  // The command line to build a ProxyConfig from.
  struct SwitchValue {
    const char* name;
    const char* value;
  } switches[2];

  // Expected outputs (fields of the ProxyConfig).
  bool is_null;
  bool auto_detect;
  GURL pac_url;
  net::ProxyRulesExpectation proxy_rules;
};

void PrintTo(const CommandLineTestParams& params, std::ostream* os) {
  *os << params.description;
}

class PrefProxyConfigServiceCommandLineTest
    : public PrefProxyConfigServiceTestBase<
          testing::TestWithParam<CommandLineTestParams> > {
 protected:
  PrefProxyConfigServiceCommandLineTest()
      : command_line_(CommandLine::NO_PROGRAM) {}

  virtual void SetUp() {
    for (size_t i = 0; i < arraysize(GetParam().switches); i++) {
      const char* name = GetParam().switches[i].name;
      const char* value = GetParam().switches[i].value;
      if (name && value)
        command_line_.AppendSwitchASCII(name, value);
      else if (name)
        command_line_.AppendSwitch(name);
    }
    pref_service_.reset(
        PrefServiceMockBuilder().WithCommandLine(&command_line_).Create());
    Init(pref_service_.get());
  }

 private:
  CommandLine command_line_;
  scoped_ptr<PrefService> pref_service_;
};

TEST_P(PrefProxyConfigServiceCommandLineTest, CommandLine) {
  net::ProxyConfig config;
  EXPECT_EQ(net::ProxyConfigService::CONFIG_VALID,
            proxy_config_service_->GetLatestProxyConfig(&config));

  if (GetParam().is_null) {
    EXPECT_EQ(GURL(kFixedPacUrl), config.pac_url());
  } else {
    EXPECT_NE(GURL(kFixedPacUrl), config.pac_url());
    EXPECT_EQ(GetParam().auto_detect, config.auto_detect());
    EXPECT_EQ(GetParam().pac_url, config.pac_url());
    EXPECT_TRUE(GetParam().proxy_rules.Matches(config.proxy_rules()));
  }
}

static const CommandLineTestParams kCommandLineTestParams[] = {
  {
    "Empty command line",
    // Input
    { },
    // Expected result
    true,                                               // is_null
    false,                                              // auto_detect
    GURL(),                                             // pac_url
    net::ProxyRulesExpectation::Empty(),
  },
  {
    "No proxy",
    // Input
    {
      { switches::kNoProxyServer, NULL },
    },
    // Expected result
    false,                                              // is_null
    false,                                              // auto_detect
    GURL(),                                             // pac_url
    net::ProxyRulesExpectation::Empty(),
  },
  {
    "No proxy with extra parameters.",
    // Input
    {
      { switches::kNoProxyServer, NULL },
      { switches::kProxyServer, "http://proxy:8888" },
    },
    // Expected result
    false,                                              // is_null
    false,                                              // auto_detect
    GURL(),                                             // pac_url
    net::ProxyRulesExpectation::Empty(),
  },
  {
    "Single proxy.",
    // Input
    {
      { switches::kProxyServer, "http://proxy:8888" },
    },
    // Expected result
    false,                                              // is_null
    false,                                              // auto_detect
    GURL(),                                             // pac_url
    net::ProxyRulesExpectation::Single(
        "proxy:8888",  // single proxy
        ""),           // bypass rules
  },
  {
    "Per scheme proxy.",
    // Input
    {
      { switches::kProxyServer, "http=httpproxy:8888;ftp=ftpproxy:8889" },
    },
    // Expected result
    false,                                              // is_null
    false,                                              // auto_detect
    GURL(),                                             // pac_url
    net::ProxyRulesExpectation::PerScheme(
        "httpproxy:8888",  // http
        "",                // https
        "ftpproxy:8889",   // ftp
        ""),               // bypass rules
  },
  {
    "Per scheme proxy with bypass URLs.",
    // Input
    {
      { switches::kProxyServer, "http=httpproxy:8888;ftp=ftpproxy:8889" },
      { switches::kProxyBypassList,
        ".google.com, foo.com:99, 1.2.3.4:22, 127.0.0.1/8" },
    },
    // Expected result
    false,                                              // is_null
    false,                                              // auto_detect
    GURL(),                                             // pac_url
    net::ProxyRulesExpectation::PerScheme(
        "httpproxy:8888",  // http
        "",                // https
        "ftpproxy:8889",   // ftp
        "*.google.com,foo.com:99,1.2.3.4:22,127.0.0.1/8"),
  },
  {
    "Pac URL",
    // Input
    {
      { switches::kProxyPacUrl, "http://wpad/wpad.dat" },
    },
    // Expected result
    false,                                              // is_null
    false,                                              // auto_detect
    GURL("http://wpad/wpad.dat"),                       // pac_url
    net::ProxyRulesExpectation::Empty(),
  },
  {
    "Autodetect",
    // Input
    {
      { switches::kProxyAutoDetect, NULL },
    },
    // Expected result
    false,                                              // is_null
    true,                                               // auto_detect
    GURL(),                                             // pac_url
    net::ProxyRulesExpectation::Empty(),
  },
};

INSTANTIATE_TEST_CASE_P(
    PrefProxyConfigServiceCommandLineTestInstance,
    PrefProxyConfigServiceCommandLineTest,
    testing::ValuesIn(kCommandLineTestParams));

}  // namespace
<|endoftext|>


<commit_before>#include "vtkAbstractArray.h"
#include "vtkExodusIIReader.h"
#include "vtkDataObject.h"
#include "vtkDataSet.h"
#include "vtkDataSetAttributes.h"
#include "vtkIdTypeArray.h"
#include "vtkMultiBlockDataSet.h"
#include "vtkPExodusIIReader.h"
#include "vtkSmartPointer.h"

#include <vtkTestUtilities.h>
#include <vtkTesting.h>

#define VTK_CREATE(type, name) \
  vtkSmartPointer<type> name = vtkSmartPointer<type>::New ();

int TestExodusImplicitArrays(int argc, char *argv[])
{
  const char* fname = vtkTestUtilities::ExpandDataFileName(argc, argv, "Data/disk_out_ref.ex2");
  VTK_CREATE (vtkExodusIIReader, reader);
  reader->SetFileName (fname);
  reader->GenerateImplicitElementIdArrayOn ();
  reader->GenerateImplicitNodeIdArrayOn ();
  reader->Update ();

  vtkMultiBlockDataSet *mb = reader->GetOutput ();

  if (!mb)
    {
    return 1;
    }
  vtkMultiBlockDataSet *elems = vtkMultiBlockDataSet::SafeDownCast (mb->GetBlock (0));

  if (!elems)
    {
    return 1;
    }
  vtkDataObject *obj = elems->GetBlock (0);

  if (!obj)
    {
    return 1;
    }
  vtkIdTypeArray *ie = vtkIdTypeArray::SafeDownCast (
                  obj->GetAttributes (vtkDataSet::CELL)->GetAbstractArray ("ImplicitElementId"));
  vtkIdTypeArray *in = vtkIdTypeArray::SafeDownCast (
                  obj->GetAttributes (vtkDataSet::POINT)->GetAbstractArray ("ImplicitNodeId"));
  if (!ie || !in)
    {
    return 1;
    }

  for (int id = 0; id < ie->GetNumberOfTuples (); id ++)
    {
    if (ie->GetValue (id) != (id + 1))
      {
      return 1;
      }
    }

  if (in->GetValue (0) != 143 || in->GetValue (1) != 706 || in->GetValue (2) != 3173)
    {
    return 1;
    }

  return 0;
}
<commit_msg>BUG: Fixed a memory leak<commit_after>#include "vtkAbstractArray.h"
#include "vtkExodusIIReader.h"
#include "vtkDataObject.h"
#include "vtkDataSet.h"
#include "vtkDataSetAttributes.h"
#include "vtkIdTypeArray.h"
#include "vtkMultiBlockDataSet.h"
#include "vtkPExodusIIReader.h"
#include "vtkSmartPointer.h"

#include <vtkTestUtilities.h>
#include <vtkTesting.h>

#define VTK_CREATE(type, name) \
  vtkSmartPointer<type> name = vtkSmartPointer<type>::New ();

int TestExodusImplicitArrays(int argc, char *argv[])
{
  const char* fname = vtkTestUtilities::ExpandDataFileName(argc, argv, "Data/disk_out_ref.ex2");
  VTK_CREATE (vtkExodusIIReader, reader);
  reader->SetFileName (fname);
  reader->GenerateImplicitElementIdArrayOn ();
  reader->GenerateImplicitNodeIdArrayOn ();
  reader->Update ();

  delete [] fname;

  vtkMultiBlockDataSet *mb = reader->GetOutput ();

  if (!mb)
    {
    return 1;
    }
  vtkMultiBlockDataSet *elems = vtkMultiBlockDataSet::SafeDownCast (mb->GetBlock (0));

  if (!elems)
    {
    return 1;
    }
  vtkDataObject *obj = elems->GetBlock (0);

  if (!obj)
    {
    return 1;
    }
  vtkIdTypeArray *ie = vtkIdTypeArray::SafeDownCast (
                  obj->GetAttributes (vtkDataSet::CELL)->GetAbstractArray ("ImplicitElementId"));
  vtkIdTypeArray *in = vtkIdTypeArray::SafeDownCast (
                  obj->GetAttributes (vtkDataSet::POINT)->GetAbstractArray ("ImplicitNodeId"));
  if (!ie || !in)
    {
    return 1;
    }

  for (int id = 0; id < ie->GetNumberOfTuples (); id ++)
    {
    if (ie->GetValue (id) != (id + 1))
      {
      return 1;
      }
    }

  if (in->GetValue (0) != 143 || in->GetValue (1) != 706 || in->GetValue (2) != 3173)
    {
    return 1;
    }

  return 0;
}
<|endoftext|>


<commit_before>#include <boost/program_options.hpp>
#include <iostream>
#include <iterator>
#include <string>
#include <vector>
#include <algorithm>

namespace po = boost::program_options;
using namespace std;

// A helper function to simplify the main part.
template<class T>
ostream& operator<<(ostream& os, const vector<T>& v)
{
  copy(v.begin(), v.end(), ostream_iterator<T>(cout, " "));
  return os;
}

int main(int ac, char* av[]) {
  try {

    int opt;
    po::options_description desc("Allowed options");
    desc.add_options()
    ("help", "produce help message")
    ("optimization", po::value<int>(&opt)->default_value(10),
     "optimization level")
    ("include-path,I", po::value< vector<string> >(),
     "include path")
    ("input-file", po::value< vector<string> >(), "input file");

    po::variables_map vm;
    po::positional_options_description p;
    p.add("input-file", -1);

    po::store(po::command_line_parser(ac, av).
              options(desc).positional(p).run(), vm);
    po::notify(vm);

    if (vm.count("help")) {
      cout << desc << "\n";
      return 1;
    }

    if (vm.count("include-path"))
    {
      cout << "Include paths are: "
      << vm["include-path"].as< vector<string> >() << "\n";
    }

    if (vm.count("input-file"))
    {
      cout << "Input files are: "
      << vm["input-file"].as< vector<string> >() << "\n";
    }

    cout << "Optimization level is " << opt << "\n";
  }
  catch(exception& e) {
    cerr << "error: " << e.what() << "\n";
    return 1;
  }
  catch(...) {
    cerr << "Exception of unknown type!\n";
  }

  return 0;
}
<commit_msg>Sucessfully tested the usage of passing further unrecognizes arguments.<commit_after>#include <boost/program_options.hpp>
#include <iostream>
#include <iterator>
#include <string>
#include <vector>
#include <algorithm>

namespace po = boost::program_options;
using namespace std;

// A helper function to simplify the main part.
template<class T>
ostream& operator<<(ostream& os, const vector<T>& v)
{
  copy(v.begin(), v.end(), ostream_iterator<T>(cout, " "));
  return os;
}

int main(int ac, char* av[]) {
  try {

      po::options_description desc("Allowed options");
      desc.add_options()
          ("help", "produce help message")
          ("compression", po::value<int>(), "set compression level")
      ;

      po::options_description desc2("Allowed options 2");
      desc2.add_options()
          ("pleh2", "produce pleh2 message")
          ("compressione", po::value<int>(), "set compressione level")
      ;

      po::variables_map vm;
      po::parsed_options parsed = po::command_line_parser(ac, av).options(desc).allow_unregistered().run();

      po::store(parsed, vm);
      po::notify(vm);

      vector<string> to_pass_further = po::collect_unrecognized(parsed.options, po::exclude_positional);

      for (int i=0; i<to_pass_further.size(); ++i){
        cout << to_pass_further[i] << endl;
      }

      po::variables_map vm2;
      po::parsed_options parsed2 = po::command_line_parser(to_pass_further).options(desc2).allow_unregistered().run();

      po::store(parsed2, vm2);
      po::notify(vm2);

      if (vm.count("help")) {
          cout << desc << "\n";
      }

      if (vm.count("compression")) {
          cout << "Compression level was set to "
               << vm["compression"].as<int>() << ".\n";
      } else {
          cout << "Compression level was not set.\n";
      }

      if (vm2.count("pleh2")) {
          cout << desc2 << "\n";
      }

      if (vm2.count("compressione")) {
          cout << "Compressione level was set to "
               << vm2["compressione"].as<int>() << ".\n";
      } else {
          cout << "Compressione level was not set.\n";
      }

  }
  catch(exception& e) {
      cerr << "error: " << e.what() << "\n";
      return 1;
  }
  catch(...) {
      cerr << "Exception of unknown type!\n";
  }

  return 0;
}
<|endoftext|>


<commit_before>// Time:  O(1), per move.
// Space: O(n^2)

class TicTacToe {
public:
    /** Initialize your data structure here. */
    TicTacToe(int n) : rows_(n, {0, 0}), cols_(n, {0, 0}),
                       diagonal_(2, 0), anti_diagonal_(2, 0) {
    }

    /** Player {player} makes a move at ({row}, {col}).
        @param row The row of the board.
        @param col The column of the board.
        @param player The player, can be either 1 or 2.
        @return The current winning condition, can be either:
                0: No one wins.
                1: Player 1 wins.
                2: Player 2 wins. */
    int move(int row, int col, int player) {
        const int i = player - 1;
        ++rows_[row][i], ++cols_[col][i];
        if (row == col) {
            ++diagonal_[i];
        }
        if (col == rows_.size() - row - 1) {
            ++anti_diagonal_[i];
        }
        if (rows_[row][i] == rows_.size() ||
            cols_[col][i] == cols_.size() ||
            diagonal_[i] == rows_.size() ||
            anti_diagonal_[i] == cols_.size()) {
            return player;
        }
        return 0;
    }

private:
    vector<vector<int>> rows_, cols_;
    vector<int> diagonal_, anti_diagonal_;
};

/**
 * Your TicTacToe object will be instantiated and called as such:
 * TicTacToe obj = new TicTacToe(n);
 * int param_1 = obj.move(row,col,player);
 */
<commit_msg>Update design-tic-tac-toe.cpp<commit_after>// Time:  O(1), per move.
// Space: O(n^2)

class TicTacToe {
public:
    /** Initialize your data structure here. */
    TicTacToe(int n) : rows_(n, {0, 0}), cols_(n, {0, 0}),
                       diagonal_(2, 0), anti_diagonal_(2, 0) {
    }

    /** Player {player} makes a move at ({row}, {col}).
        @param row The row of the board.
        @param col The column of the board.
        @param player The player, can be either 1 or 2.
        @return The current winning condition, can be either:
                0: No one wins.
                1: Player 1 wins.
                2: Player 2 wins. */
    int move(int row, int col, int player) {
        const auto i = player - 1;
        ++rows_[row][i], ++cols_[col][i];
        if (row == col) {
            ++diagonal_[i];
        }
        if (col == rows_.size() - row - 1) {
            ++anti_diagonal_[i];
        }
        if (rows_[row][i] == rows_.size() ||
            cols_[col][i] == cols_.size() ||
            diagonal_[i] == rows_.size() ||
            anti_diagonal_[i] == cols_.size()) {
            return player;
        }
        return 0;
    }

private:
    vector<vector<int>> rows_, cols_;
    vector<int> diagonal_, anti_diagonal_;
};

/**
 * Your TicTacToe object will be instantiated and called as such:
 * TicTacToe obj = new TicTacToe(n);
 * int param_1 = obj.move(row,col,player);
 */
<|endoftext|>


<commit_before>#include <iostream>
#include <string>
#include <dlfcn.h>

using namespace std;

int main(int argc, char* argv[]) {
    if (argc <= 1) {
        exit(0);
    }
    string filename = argv[1];
    cerr << "file = " << filename << endl;
    void* mylib = dlopen(filename.c_str(), RTLD_GLOBAL|RTLD_LAZY);
    if (mylib==NULL)
    {
    	cerr << "Problem opening library: " << filename << " Reason: " << dlerror() << endl;
    	return -1;
    }

    cerr << "Calling dlclose " << endl;
    int eret = dlclose(mylib);
    cerr << dlerror() << endl;
    cerr << "eret = " << eret << endl;
}
<commit_msg>Added stdlib.h to the include list to fix a compilation error.<commit_after>#include <iostream>
#include <string>
#include <stdlib.h>
#include <dlfcn.h>

using namespace std;

int main(int argc, char* argv[]) {
    if (argc <= 1) {
        exit(0);
    }
    string filename = argv[1];
    cerr << "file = " << filename << endl;
    void* mylib = dlopen(filename.c_str(), RTLD_GLOBAL|RTLD_LAZY);
    if (mylib==NULL)
    {
    	cerr << "Problem opening library: " << filename << " Reason: " << dlerror() << endl;
    	return -1;
    }

    cerr << "Calling dlclose " << endl;
    int eret = dlclose(mylib);
    cerr << dlerror() << endl;
    cerr << "eret = " << eret << endl;
}
<|endoftext|>


<commit_before>/*!
 * @file FgAircraftsModel.cpp
 *
 * @brief Aircrafts model
 *
 * @author Andrey Shelest
 * @author Oleksii Aliakin (alex@nls.la)
 * @date Created Feb 08, 2015
 * @date Modified Jul 21, 2015
 */

#include "FgAircraftsModel.h"
#include "FgTransport.h"

#include <QFile>
#include <QJsonArray>
#include <QJsonDocument>
#include <QCoreApplication>

FgAircraftsModel::FgAircraftsModel(QObject *parent) :
    QAbstractListModel(parent)
{
    init();

    m_Roles[Name] = "name";
    m_Roles[Connected] = "connected";
    m_Roles[Aircraft] = "aircraft";
}

FgAircraftsModel::~FgAircraftsModel()
{
//    saveConfig("./config/fgapConfig.json");
}

bool FgAircraftsModel::init()
{
    QString configFileName("%1/%2/%3");
    configFileName = configFileName.arg(QCoreApplication::applicationDirPath(),
                                        CONFIG_PATH,
                                        "multiplayWithoutServer.json");
    QFile configFile(configFileName);
    if (!configFile.open(QIODevice::ReadOnly))
    {
        qWarning("Couldn't open config file: %s",  configFileName.toStdString().c_str());
        return false;
    }
    QJsonDocument configData(QJsonDocument::fromJson(configFile.readAll()));
    QJsonObject configObj = configData.object();
    QJsonArray aircrafts = configObj["aircrafts"].toArray();

    for (auto const &parameter : aircrafts)
    {
        auto aircraft = std::make_shared<FgControlledAircraft>(parameter.toObject());
        emit beginInsertRows(QModelIndex(), m_OurAircrafts.count(), m_OurAircrafts.count());
        m_OurAircrafts.append(aircraft);
        connect(aircraft.get(), &FgControlledAircraft::onConnected, this, &FgAircraftsModel::onAircraftConnected);
        emit endInsertRows();
    }

    m_Transport = m_OurAircrafts[0]->transport();
    connect(m_Transport.get(), &FgTransport::fgDataReceived, this, &FgAircraftsModel::onDataReceived);

//    m_OurAircrafts["Travis"]->follow(m_OurAircrafts["Rover"].get());
//    m_OurAircrafts["Rover"]->autopilot()->engage();

//    m_OurAircrafts[0]->runFlightGear();
//    m_OurAircrafts[0]->autopilot()->engage();
//    m_OurAircrafts["Rover"]->runFlightGear();
    return true;
}

bool FgAircraftsModel::saveConfig(const QString &filename)
{
    QFile saveFile(filename);

    if (!saveFile.open(QIODevice::WriteOnly))
    {
        qWarning("Couldn't open save file.");
        return false;
    }

    QJsonArray aircrafts;
    for (auto &aircraft : m_OurAircrafts)
        aircrafts.append(aircraft->configurationAsJson());

    QJsonObject config;
    config["aircrafts"] = aircrafts;
    QJsonDocument saveDoc(config);
    saveFile.write(saveDoc.toJson());

    return true;
}

int FgAircraftsModel::rowCount(const QModelIndex &parent) const
{
    Q_UNUSED(parent);
    qDebug("Row count");
    return m_OurAircrafts.count();
}

QVariant FgAircraftsModel::data(const QModelIndex &index, int role) const
{
    qDebug("FgController::data. row = %d, role = %d", index.row(), role);
    if (!index.isValid())
        return QVariant();

    if (index.row() >= m_OurAircrafts.size())
        return QVariant();

    switch (role)
    {
    case Name:
    case Qt::DisplayRole:
        return m_OurAircrafts[index.row()]->callsign();
        break;
    case Connected:
        return m_OurAircrafts[index.row()]->connected();
        break;
     case Aircraft:
        return QVariant::fromValue(m_OurAircrafts[index.row()].get());
    default:
        return QVariant();
        break;
    }

    return QVariant();
}

QString FgAircraftsModel::get(int index) const
{
    return m_OurAircrafts.at(index)->callsign();
}

void FgAircraftsModel::runFlightgear(int index) const
{
    m_OurAircrafts[index]->runFlightGear();
}

QHash<int, QByteArray> FgAircraftsModel::roleNames() const
{
    return m_Roles;
}

void FgAircraftsModel::updateAircraft(const QString & /* aircraftId */)
{
}

void FgAircraftsModel::onDataReceived()
{
    updateOtherAircraftsCount();

    emit fdmDataChanged(m_Transport);

    //eleron
    //elevator

    if (m_OurAircrafts.isEmpty())
    {
        qDebug() << "Our aircraft is empty!";
        return;
    }
}

void FgAircraftsModel::onAircraftConnected()
{
    FgAircraft *aircraft = static_cast<FgAircraft*>(sender());

    int row = 0;
    for (auto &a : m_OurAircrafts)
        if (a->callsign() != aircraft->callsign())
            ++row;
        else
            break;

    // FIXME: fix fix fix
    emit beginRemoveRows(QModelIndex(), 0, m_OurAircrafts.size()-1);
    emit endRemoveRows();

    emit beginInsertRows(QModelIndex(), 0, m_OurAircrafts.size()-1);
    emit endInsertRows();

    qDebug() << "aircraft " << m_OurAircrafts[row]->callsign() << " connected";
}

void FgAircraftsModel::updateOtherAircraftsCount()
{
    qint32 count = m_Transport->getInt("/ai/models/num-players");

    if (m_AircraftsCount == count)
    {
        // assume that aircrafts remain the same
        return;
    }

    m_AircraftsCount = count;

    // get all aircrafts and add new ones to the list
    QList<QString> callsigns;
    for (int i = 0; i < count; ++i)
    {
        QString callsign = m_Transport->getString("/ai/models/multiplayer[" + QString::number(i) + "]/callsign");
        qDebug() << "callsign = " << callsign;
        callsigns.push_back(callsign);
        if (m_OtherAircrafts.end() !=
                std::find_if(m_OtherAircrafts.begin(), m_OtherAircrafts.end(),
                             [&callsign](std::shared_ptr<FgAircraft> a){ return a->callsign() == callsign;}))
        {
            continue;
        }

        auto aircraft = std::make_shared<FgAircraft>(callsign);
        aircraft->setConnected(true);
        //! @todo  aircraft->setIndex();
        m_OtherAircrafts.append(aircraft);
        emit aircraftAdded(aircraft.get());
        qDebug() << "otherAircraftAdded";
    }

    // remove disconnected aircrafts from the list
    auto it = m_OtherAircrafts.begin();
    while (it != m_OtherAircrafts.end())
    {
        if (!callsigns.contains((*it)->callsign()))
        {
            emit aircraftDisconnected((*it).get());
            qDebug() << "aircraftDisconnected";

            it = m_OtherAircrafts.erase(it);
        }
        else
        {
            ++it;
        }
    }
}
<commit_msg>fixed model updating<commit_after>/*!
 * @file FgAircraftsModel.cpp
 *
 * @brief Aircrafts model
 *
 * @author Andrey Shelest
 * @author Oleksii Aliakin (alex@nls.la)
 * @date Created Feb 08, 2015
 * @date Modified Jul 21, 2015
 */

#include "FgAircraftsModel.h"
#include "FgTransport.h"

#include <QFile>
#include <QJsonArray>
#include <QJsonDocument>
#include <QCoreApplication>

FgAircraftsModel::FgAircraftsModel(QObject *parent) :
    QAbstractListModel(parent)
{
    init();

    m_Roles[Name] = "name";
    m_Roles[Connected] = "connected";
    m_Roles[Aircraft] = "aircraft";
}

FgAircraftsModel::~FgAircraftsModel()
{
//    saveConfig("./config/fgapConfig.json");
}

bool FgAircraftsModel::init()
{
    QString configFileName("%1/%2/%3");
    configFileName = configFileName.arg(QCoreApplication::applicationDirPath(),
                                        CONFIG_PATH,
                                        "multiplayWithoutServer.json");
    QFile configFile(configFileName);
    if (!configFile.open(QIODevice::ReadOnly))
    {
        qWarning("Couldn't open config file: %s",  configFileName.toStdString().c_str());
        return false;
    }
    QJsonDocument configData(QJsonDocument::fromJson(configFile.readAll()));
    QJsonObject configObj = configData.object();
    QJsonArray aircrafts = configObj["aircrafts"].toArray();

    for (auto const &parameter : aircrafts)
    {
        auto aircraft = std::make_shared<FgControlledAircraft>(parameter.toObject());
        emit beginInsertRows(QModelIndex(), m_OurAircrafts.count(), m_OurAircrafts.count());
        m_OurAircrafts.append(aircraft);
        connect(aircraft.get(), &FgControlledAircraft::onConnected, this, &FgAircraftsModel::onAircraftConnected);
        emit endInsertRows();
    }

    m_Transport = m_OurAircrafts[0]->transport();
    connect(m_Transport.get(), &FgTransport::fgDataReceived, this, &FgAircraftsModel::onDataReceived);

//    m_OurAircrafts["Travis"]->follow(m_OurAircrafts["Rover"].get());
//    m_OurAircrafts["Rover"]->autopilot()->engage();

//    m_OurAircrafts[0]->runFlightGear();
//    m_OurAircrafts[0]->autopilot()->engage();
//    m_OurAircrafts["Rover"]->runFlightGear();
    return true;
}

bool FgAircraftsModel::saveConfig(const QString &filename)
{
    QFile saveFile(filename);

    if (!saveFile.open(QIODevice::WriteOnly))
    {
        qWarning("Couldn't open save file.");
        return false;
    }

    QJsonArray aircrafts;
    for (auto &aircraft : m_OurAircrafts)
        aircrafts.append(aircraft->configurationAsJson());

    QJsonObject config;
    config["aircrafts"] = aircrafts;
    QJsonDocument saveDoc(config);
    saveFile.write(saveDoc.toJson());

    return true;
}

int FgAircraftsModel::rowCount(const QModelIndex &parent) const
{
    Q_UNUSED(parent);
    qDebug("Row count");
    return m_OurAircrafts.count();
}

QVariant FgAircraftsModel::data(const QModelIndex &index, int role) const
{
    qDebug("FgController::data. row = %d, role = %d", index.row(), role);
    if (!index.isValid())
        return QVariant();

    if (index.row() >= m_OurAircrafts.size())
        return QVariant();

    switch (role)
    {
    case Name:
    case Qt::DisplayRole:
        return m_OurAircrafts[index.row()]->callsign();
        break;
    case Connected:
        return m_OurAircrafts[index.row()]->connected();
        break;
     case Aircraft:
        return QVariant::fromValue(m_OurAircrafts[index.row()].get());
    default:
        return QVariant();
        break;
    }

    return QVariant();
}

QString FgAircraftsModel::get(int index) const
{
    return m_OurAircrafts.at(index)->callsign();
}

void FgAircraftsModel::runFlightgear(int index) const
{
    m_OurAircrafts[index]->runFlightGear();
}

QHash<int, QByteArray> FgAircraftsModel::roleNames() const
{
    return m_Roles;
}

void FgAircraftsModel::updateAircraft(const QString & /* aircraftId */)
{
}

void FgAircraftsModel::onDataReceived()
{
    updateOtherAircraftsCount();

    emit fdmDataChanged(m_Transport);

    //eleron
    //elevator

    if (m_OurAircrafts.isEmpty())
    {
        qDebug() << "Our aircraft is empty!";
        return;
    }
}

void FgAircraftsModel::onAircraftConnected()
{
    FgAircraft *aircraft = static_cast<FgAircraft*>(sender());

    emit dataChanged(QModelIndex(), index(m_OurAircrafts.size()-1), {Connected});
    qDebug() << "aircraft " << aircraft->callsign() << " connected";
}

void FgAircraftsModel::updateOtherAircraftsCount()
{
    qint32 count = m_Transport->getInt("/ai/models/num-players");

    if (m_AircraftsCount == count)
    {
        // assume that aircrafts remain the same
        return;
    }

    m_AircraftsCount = count;

    // get all aircrafts and add new ones to the list
    QList<QString> callsigns;
    for (int i = 0; i < count; ++i)
    {
        QString callsign = m_Transport->getString("/ai/models/multiplayer[" + QString::number(i) + "]/callsign");
        qDebug() << "callsign = " << callsign;
        callsigns.push_back(callsign);
        if (m_OtherAircrafts.end() !=
                std::find_if(m_OtherAircrafts.begin(), m_OtherAircrafts.end(),
                             [&callsign](std::shared_ptr<FgAircraft> a){ return a->callsign() == callsign;}))
        {
            continue;
        }

        auto aircraft = std::make_shared<FgAircraft>(callsign);
        aircraft->setConnected(true);
        //! @todo  aircraft->setIndex();
        m_OtherAircrafts.append(aircraft);
        emit aircraftAdded(aircraft.get());
        qDebug() << "otherAircraftAdded";
    }

    // remove disconnected aircrafts from the list
    auto it = m_OtherAircrafts.begin();
    while (it != m_OtherAircrafts.end())
    {
        if (!callsigns.contains((*it)->callsign()))
        {
            emit aircraftDisconnected((*it).get());
            qDebug() << "aircraftDisconnected";

            it = m_OtherAircrafts.erase(it);
        }
        else
        {
            ++it;
        }
    }
}
<|endoftext|>


<commit_before>/*
   For more information, please see: http://software.sci.utah.edu

   The MIT License

   Copyright (c) 2012 Scientific Computing and Imaging Institute,
   University of Utah.

   License for the specific language governing rights and limitations under
   Permission is hereby granted, free of charge, to any person obtaining a
   copy of this software and associated documentation files (the "Software"),
   to deal in the Software without restriction, including without limitation
   the rights to use, copy, modify, merge, publish, distribute, sublicense,
   and/or sell copies of the Software, and to permit persons to whom the
   Software is furnished to do so, subject to the following conditions:

   The above copyright notice and this permission notice shall be included
   in all copies or substantial portions of the Software.

   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
   THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
   DEALINGS IN THE SOFTWARE.
*/

#include <Interface/Modules/Render/ViewScene.h>
#include <Dataflow/Network/ModuleStateInterface.h>
#include <Core/Datatypes/Geometry.h>
#include <QFileDialog>
#include "QtGLContext.h"

using namespace SCIRun::Gui;
using namespace SCIRun::Dataflow::Networks;
using namespace SCIRun::Core::Datatypes;

//------------------------------------------------------------------------------
ViewSceneDialog::ViewSceneDialog(const std::string& name, ModuleStateHandle state,
  QWidget* parent /* = 0 */)
  : ModuleDialogGeneric(state, parent)
{
  setupUi(this);
  setWindowTitle(QString::fromStdString(name));

  // Setup Qt OpenGL widget.
  QGLFormat fmt;
  fmt.setAlpha(true);
  fmt.setRgba(true);
  mGLWidget = new GLWidget(new QtGLContext(fmt));

  if (mGLWidget->isValid())
  {
    // Hook up the GLWidget
    glLayout->addWidget(mGLWidget);
    glLayout->update();

    // Set spire transient value (should no longer be used).
    mSpire = std::weak_ptr<Spire::SCIRun::SRInterface>(mGLWidget->getSpire());
  }
  else
  {
    /// \todo Display dialog.
    delete mGLWidget;
  }
}

//------------------------------------------------------------------------------
ViewSceneDialog::~ViewSceneDialog()
{
}

//------------------------------------------------------------------------------
void ViewSceneDialog::closeEvent(QCloseEvent *evt)
{
}

//------------------------------------------------------------------------------
void ViewSceneDialog::moduleExecuted()
{
  // Grab the geomData transient value.
  boost::any geomDataTransient = state_->getTransientValue("geomData");
  if (!geomDataTransient.empty())
  {
    boost::shared_ptr<std::list<boost::shared_ptr<Core::Datatypes::GeometryObject>>> geomData; // Whoa...
    try
    {
      geomData = boost::any_cast<boost::shared_ptr<std::list<boost::shared_ptr<Core::Datatypes::GeometryObject>>>>(geomDataTransient);
    }
    catch (const boost::bad_any_cast&)
    {
      //error("Unable to cast boost::any transient value to spire pointer.");
      return;
    }
    std::shared_ptr<Spire::SCIRun::SRInterface> spire = mSpire.lock();
    if (spire == nullptr)
      return;

    // Grab objects (to be regenerated with supplied data)
    std::shared_ptr<Spire::StuInterface> stuPipe = spire->getStuPipe();

    // Remove ALL prior objects.
    stuPipe->removeAllObjects();

    for (auto it = geomData->begin(); it != geomData->end(); ++it)
    {
      boost::shared_ptr<Core::Datatypes::GeometryObject> obj = *it;

      // Try/catch is for single-threaded cases. Exceptions are handled on the
      // spire thread when spire is threaded.
      try
      {
        // Will remove all traces of old VBO's / IBO's not in use.
        // (remember, we remove the VBOs/IBOs we added at the end of this loop,
        //  this is to ensure there is only 1 shared_ptr reference to the IBOs
        //  and VBOs in Spire).
        stuPipe->removeObject(obj->objectName);
      }
      catch (std::out_of_range& e)
      {
        // Ignore
      }

      stuPipe->addObject(obj->objectName);

      // Add vertex buffer objects.
      for (auto it = obj->mVBOs.cbegin(); it != obj->mVBOs.cend(); ++it)
      {
        const GeometryObject::SpireVBO& vbo = *it;
        stuPipe->addVBO(vbo.name, vbo.data, vbo.attributeNames);
      }

      // Add index buffer objects.
      for (auto it = obj->mIBOs.cbegin(); it != obj->mIBOs.cend(); ++it)
      {
        const GeometryObject::SpireIBO& ibo = *it;
        Spire::StuInterface::IBO_TYPE type;
        switch (ibo.indexSize)
        {
          case 1: // 8-bit
            type = Spire::StuInterface::IBO_8BIT;
            break;

          case 2: // 16-bit
            type = Spire::StuInterface::IBO_16BIT;
            break;

          case 4: // 32-bit
            type = Spire::StuInterface::IBO_32BIT;
            break;

          default:
            type = Spire::StuInterface::IBO_32BIT;
            throw std::invalid_argument("Unable to determine index buffer depth.");
            break;
        }
        stuPipe->addIBO(ibo.name, ibo.data, type);
      }

      // Add passes
      for (auto it = obj->mPasses.cbegin(); it != obj->mPasses.cend(); ++it)
      {
        const GeometryObject::SpirePass& pass = *it;
        stuPipe->addPassToObject(obj->objectName, pass.passName, pass.programName,
                                 pass.vboName, pass.iboName, pass.type);

        // Add uniforms associated with the pass
        for (auto it = pass.uniforms.begin(); it != pass.uniforms.end(); ++it)
        {
          std::string uniformName = std::get<0>(*it);
          std::shared_ptr<Spire::AbstractUniformStateItem> uniform(std::get<1>(*it));
          stuPipe->addPassUniformConcrete(obj->objectName, pass.passName,
                                          uniformName, uniform);
        }

        // Add gpu state if it has been set.
        if (pass.hasGPUState == true)
          stuPipe->addPassGPUState(obj->objectName, pass.passName, pass.gpuState);
      }

      // Now that we have created all of the appropriate passes, get rid of the
      // VBOs and IBOs.
      for (auto it = obj->mVBOs.cbegin(); it != obj->mVBOs.cend(); ++it)
      {
        const GeometryObject::SpireVBO& vbo = *it;
        stuPipe->removeVBO(vbo.name);
      }

      for (auto it = obj->mIBOs.cbegin(); it != obj->mIBOs.cend(); ++it)
      {
        const GeometryObject::SpireIBO& ibo = *it;
        stuPipe->removeIBO(ibo.name);
      }
    }
  }
}
<commit_msg>Commented out old remove object code.<commit_after>/*
   For more information, please see: http://software.sci.utah.edu

   The MIT License

   Copyright (c) 2012 Scientific Computing and Imaging Institute,
   University of Utah.

   License for the specific language governing rights and limitations under
   Permission is hereby granted, free of charge, to any person obtaining a
   copy of this software and associated documentation files (the "Software"),
   to deal in the Software without restriction, including without limitation
   the rights to use, copy, modify, merge, publish, distribute, sublicense,
   and/or sell copies of the Software, and to permit persons to whom the
   Software is furnished to do so, subject to the following conditions:

   The above copyright notice and this permission notice shall be included
   in all copies or substantial portions of the Software.

   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
   THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
   DEALINGS IN THE SOFTWARE.
*/

#include <Interface/Modules/Render/ViewScene.h>
#include <Dataflow/Network/ModuleStateInterface.h>
#include <Core/Datatypes/Geometry.h>
#include <QFileDialog>
#include "QtGLContext.h"

using namespace SCIRun::Gui;
using namespace SCIRun::Dataflow::Networks;
using namespace SCIRun::Core::Datatypes;

//------------------------------------------------------------------------------
ViewSceneDialog::ViewSceneDialog(const std::string& name, ModuleStateHandle state,
  QWidget* parent /* = 0 */)
  : ModuleDialogGeneric(state, parent)
{
  setupUi(this);
  setWindowTitle(QString::fromStdString(name));

  // Setup Qt OpenGL widget.
  QGLFormat fmt;
  fmt.setAlpha(true);
  fmt.setRgba(true);
  mGLWidget = new GLWidget(new QtGLContext(fmt));

  if (mGLWidget->isValid())
  {
    // Hook up the GLWidget
    glLayout->addWidget(mGLWidget);
    glLayout->update();

    // Set spire transient value (should no longer be used).
    mSpire = std::weak_ptr<Spire::SCIRun::SRInterface>(mGLWidget->getSpire());
  }
  else
  {
    /// \todo Display dialog.
    delete mGLWidget;
  }
}

//------------------------------------------------------------------------------
ViewSceneDialog::~ViewSceneDialog()
{
}

//------------------------------------------------------------------------------
void ViewSceneDialog::closeEvent(QCloseEvent *evt)
{
}

//------------------------------------------------------------------------------
void ViewSceneDialog::moduleExecuted()
{
  // Grab the geomData transient value.
  boost::any geomDataTransient = state_->getTransientValue("geomData");
  if (!geomDataTransient.empty())
  {
    boost::shared_ptr<std::list<boost::shared_ptr<Core::Datatypes::GeometryObject>>> geomData; // Whoa...
    try
    {
      geomData = boost::any_cast<boost::shared_ptr<std::list<boost::shared_ptr<Core::Datatypes::GeometryObject>>>>(geomDataTransient);
    }
    catch (const boost::bad_any_cast&)
    {
      //error("Unable to cast boost::any transient value to spire pointer.");
      return;
    }
    std::shared_ptr<Spire::SCIRun::SRInterface> spire = mSpire.lock();
    if (spire == nullptr)
      return;

    // Grab objects (to be regenerated with supplied data)
    std::shared_ptr<Spire::StuInterface> stuPipe = spire->getStuPipe();

    // Remove ALL prior objects.
    stuPipe->removeAllObjects();

    for (auto it = geomData->begin(); it != geomData->end(); ++it)
    {
      boost::shared_ptr<Core::Datatypes::GeometryObject> obj = *it;

      // Since we simply remove all objects from the scene everyframe (that
      // needs to change) we don't need to remove the objects one-by-one.
      //// Try/catch is for single-threaded cases. Exceptions are handled on the
      //// spire thread when spire is threaded.
      //try
      //{
      //  // Will remove all traces of old VBO's / IBO's not in use.
      //  // (remember, we remove the VBOs/IBOs we added at the end of this loop,
      //  //  this is to ensure there is only 1 shared_ptr reference to the IBOs
      //  //  and VBOs in Spire).
      //  stuPipe->removeObject(obj->objectName);
      //}
      //catch (std::out_of_range&)
      //{
      //  // Ignore
      //}

      stuPipe->addObject(obj->objectName);

      // Add vertex buffer objects.
      for (auto it = obj->mVBOs.cbegin(); it != obj->mVBOs.cend(); ++it)
      {
        const GeometryObject::SpireVBO& vbo = *it;
        stuPipe->addVBO(vbo.name, vbo.data, vbo.attributeNames);
      }

      // Add index buffer objects.
      for (auto it = obj->mIBOs.cbegin(); it != obj->mIBOs.cend(); ++it)
      {
        const GeometryObject::SpireIBO& ibo = *it;
        Spire::StuInterface::IBO_TYPE type;
        switch (ibo.indexSize)
        {
          case 1: // 8-bit
            type = Spire::StuInterface::IBO_8BIT;
            break;

          case 2: // 16-bit
            type = Spire::StuInterface::IBO_16BIT;
            break;

          case 4: // 32-bit
            type = Spire::StuInterface::IBO_32BIT;
            break;

          default:
            type = Spire::StuInterface::IBO_32BIT;
            throw std::invalid_argument("Unable to determine index buffer depth.");
            break;
        }
        stuPipe->addIBO(ibo.name, ibo.data, type);
      }

      // Add passes
      for (auto it = obj->mPasses.cbegin(); it != obj->mPasses.cend(); ++it)
      {
        const GeometryObject::SpirePass& pass = *it;
        stuPipe->addPassToObject(obj->objectName, pass.passName, pass.programName,
                                 pass.vboName, pass.iboName, pass.type);

        // Add uniforms associated with the pass
        for (auto it = pass.uniforms.begin(); it != pass.uniforms.end(); ++it)
        {
          std::string uniformName = std::get<0>(*it);
          std::shared_ptr<Spire::AbstractUniformStateItem> uniform(std::get<1>(*it));
          stuPipe->addPassUniformConcrete(obj->objectName, pass.passName,
                                          uniformName, uniform);
        }

        // Add gpu state if it has been set.
        if (pass.hasGPUState == true)
          stuPipe->addPassGPUState(obj->objectName, pass.passName, pass.gpuState);
      }

      // Now that we have created all of the appropriate passes, get rid of the
      // VBOs and IBOs.
      for (auto it = obj->mVBOs.cbegin(); it != obj->mVBOs.cend(); ++it)
      {
        const GeometryObject::SpireVBO& vbo = *it;
        stuPipe->removeVBO(vbo.name);
      }

      for (auto it = obj->mIBOs.cbegin(); it != obj->mIBOs.cend(); ++it)
      {
        const GeometryObject::SpireIBO& ibo = *it;
        stuPipe->removeIBO(ibo.name);
      }
    }
  }
}
<|endoftext|>


<commit_before>/*     Copyright 2015-2019 Egor Yusov
 *
 *  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
 *
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS.
 *
 *  In no event and under no legal theory, whether in tort (including neVkigence),
 *  contract, or otherwise, unless required by applicable law (such as deliberate
 *  and grossly neVkigent acts) or agreed to in writing, shall any Contributor be
 *  liable for any damages, including any direct, indirect, special, incidental,
 *  or consequential damages of any character arising as a result of this License or
 *  out of the use or inability to use the software (including but not limited to damages
 *  for loss of goodwill, work stoppage, computer failure or malfunction, or any and
 *  all other commercial damages or losses), even if such Contributor has been advised
 *  of the possibility of such damages.
 */

#include "pch.h"

#include "FenceVkImpl.h"
#include "EngineMemory.h"
#include "RenderDeviceVkImpl.h"

namespace Diligent
{

FenceVkImpl :: FenceVkImpl(IReferenceCounters* pRefCounters,
                           RenderDeviceVkImpl* pRendeDeviceVkImpl,
                           const FenceDesc&    Desc,
                           bool                IsDeviceInternal) :
    TFenceBase(pRefCounters, pRendeDeviceVkImpl, Desc, IsDeviceInternal),
    m_FencePool(pRendeDeviceVkImpl->GetLogicalDevice().GetSharedPtr())
{
}

FenceVkImpl :: ~FenceVkImpl()
{
    // Do not dispose pending fences as the pool checks that the fence
    // is signalled, while pending fences may not be.
    // The pool will be destroyed next anyway, so it makes no difference.
    m_PendingFences.clear();
}

Uint64 FenceVkImpl :: GetCompletedValue()
{
    const auto& LogicalDevice = m_pDevice->GetLogicalDevice();
    while (!m_PendingFences.empty())
    {
        auto& Value_Fence = m_PendingFences.front();
        auto status = LogicalDevice.GetFenceStatus(Value_Fence.second);
        if(status == VK_SUCCESS)
        {
            if (Value_Fence.first > m_LastCompletedFenceValue)
                m_LastCompletedFenceValue = Value_Fence.first;
            m_FencePool.DisposeFence(std::move(Value_Fence.second));
            m_PendingFences.pop_front();
        }
        else
        {
            break;
        }
    }

    return m_LastCompletedFenceValue;
}

void FenceVkImpl :: Reset(Uint64 Value)
{
    DEV_CHECK_ERR(Value >= m_LastCompletedFenceValue, "Resetting fence '", m_Desc.Name, "' to the value (", Value, ") that is smaller than the last completed value (", m_LastCompletedFenceValue, ")");
    if (Value > m_LastCompletedFenceValue)
        m_LastCompletedFenceValue = Value;
}

void FenceVkImpl :: Wait()
{
    const auto& LogicalDevice = m_pDevice->GetLogicalDevice();
    for (auto& val_fence : m_PendingFences)
    {
        while (LogicalDevice.GetFenceStatus(val_fence.second) == VK_NOT_READY)
        {
            VkFence FenceToWait = val_fence.second;
            auto res = LogicalDevice.WaitForFences(1, &FenceToWait, VK_TRUE, UINT64_MAX);
            VERIFY_EXPR(res == VK_SUCCESS); (void)res;
        }

        auto status = LogicalDevice.GetFenceStatus(val_fence.second);
        DEV_CHECK_ERR(status == VK_SUCCESS, "All pending fences must now be complete!"); (void)status;
        if (val_fence.first > m_LastCompletedFenceValue)
            m_LastCompletedFenceValue = val_fence.first;
        m_FencePool.DisposeFence(std::move(val_fence.second));
    }
    m_PendingFences.clear();
}

}
<commit_msg>Another minor fix for fence waiting<commit_after>/*     Copyright 2015-2019 Egor Yusov
 *
 *  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
 *
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS.
 *
 *  In no event and under no legal theory, whether in tort (including neVkigence),
 *  contract, or otherwise, unless required by applicable law (such as deliberate
 *  and grossly neVkigent acts) or agreed to in writing, shall any Contributor be
 *  liable for any damages, including any direct, indirect, special, incidental,
 *  or consequential damages of any character arising as a result of this License or
 *  out of the use or inability to use the software (including but not limited to damages
 *  for loss of goodwill, work stoppage, computer failure or malfunction, or any and
 *  all other commercial damages or losses), even if such Contributor has been advised
 *  of the possibility of such damages.
 */

#include "pch.h"

#include "FenceVkImpl.h"
#include "EngineMemory.h"
#include "RenderDeviceVkImpl.h"

namespace Diligent
{

FenceVkImpl :: FenceVkImpl(IReferenceCounters* pRefCounters,
                           RenderDeviceVkImpl* pRendeDeviceVkImpl,
                           const FenceDesc&    Desc,
                           bool                IsDeviceInternal) :
    TFenceBase(pRefCounters, pRendeDeviceVkImpl, Desc, IsDeviceInternal),
    m_FencePool(pRendeDeviceVkImpl->GetLogicalDevice().GetSharedPtr())
{
}

FenceVkImpl :: ~FenceVkImpl()
{
    // Do not dispose pending fences as the pool checks that the fence
    // is signalled, while pending fences may not be.
    // The pool will be destroyed next anyway, so it makes no difference.
    m_PendingFences.clear();
}

Uint64 FenceVkImpl :: GetCompletedValue()
{
    const auto& LogicalDevice = m_pDevice->GetLogicalDevice();
    while (!m_PendingFences.empty())
    {
        auto& Value_Fence = m_PendingFences.front();
        auto status = LogicalDevice.GetFenceStatus(Value_Fence.second);
        if(status == VK_SUCCESS)
        {
            if (Value_Fence.first > m_LastCompletedFenceValue)
                m_LastCompletedFenceValue = Value_Fence.first;
            m_FencePool.DisposeFence(std::move(Value_Fence.second));
            m_PendingFences.pop_front();
        }
        else
        {
            break;
        }
    }

    return m_LastCompletedFenceValue;
}

void FenceVkImpl :: Reset(Uint64 Value)
{
    DEV_CHECK_ERR(Value >= m_LastCompletedFenceValue, "Resetting fence '", m_Desc.Name, "' to the value (", Value, ") that is smaller than the last completed value (", m_LastCompletedFenceValue, ")");
    if (Value > m_LastCompletedFenceValue)
        m_LastCompletedFenceValue = Value;
}

void FenceVkImpl :: Wait()
{
    const auto& LogicalDevice = m_pDevice->GetLogicalDevice();
    for (auto& val_fence : m_PendingFences)
    {
        auto status = LogicalDevice.GetFenceStatus(val_fence.second);
        if (status == VK_NOT_READY)
        {
            VkFence FenceToWait = val_fence.second;
            status = LogicalDevice.WaitForFences(1, &FenceToWait, VK_TRUE, UINT64_MAX);
        }

        DEV_CHECK_ERR(status == VK_SUCCESS, "All pending fences must now be complete!"); (void)status;
        if (val_fence.first > m_LastCompletedFenceValue)
            m_LastCompletedFenceValue = val_fence.first;
        m_FencePool.DisposeFence(std::move(val_fence.second));
    }
    m_PendingFences.clear();
}

}
<|endoftext|>


<commit_before>#include <math.h>
#include <memory.h>
#include <random>
#include <stdlib.h>

#include "Neural_Networks.h"

Connection::Connection(Layer *layer, Layer *parent_layer, double scale) {
	this->layer = layer;
	this->parent_layer = parent_layer;
	this->number_weights = layer->number_nodes * parent_layer->number_nodes;

	weight = new float[number_weights];

	for (int i = 0; i < number_weights; i++) {
		weight[i] = scale * (2.0 * rand() / RAND_MAX - 1);
	}
}
Connection::~Connection() {
	delete[] weight;
}

Layer::Layer(int number_nodes, int activation) {
	this->activation = activation;
	this->batch_size = 1;
	this->number_nodes = number_nodes;

	memset(bias = new float[number_nodes], 0, sizeof(float) * number_nodes);
	error = new float[number_nodes];
	neuron = new float[number_nodes];
}
Layer::~Layer() {
	for (int i = 0; i < connection.size(); i++) {
		delete connection[i];
	}
	delete[] bias;
	delete[] error;
	delete[] neuron;
}

void Layer::Activation() {
	#pragma omp parallel for
	for (int h = 0; h < batch_size; h++) {
		float *neuron = &this->neuron[h * number_nodes];

		for (int j = 0; j < number_nodes; j++) {
			neuron[j] += bias[j];
		}

		if (activation == Activation::softmax) {
			double max;
			double sum = 0;

			for (int j = 0; j < number_nodes; j++) {
				if (j == 0 || max < neuron[j]) {
					max = neuron[j];
				}
			}
			for (int j = 0; j < number_nodes; j++) {
				sum += (neuron[j] = exp(neuron[j] - max));
			}
			for (int j = 0; j < number_nodes; j++) {
				neuron[j] /= sum;
			}
		}
		else {
			if (activation == Activation::linear) {
				// neuron[j] = neuron[j];
			}
			else if (activation == Activation::sigmoid) {
				for (int j = 0; j < number_nodes; j++) {
					neuron[j] = 1 / (1 + exp(-neuron[j]));
				}
			}
		}
	}
}
void Layer::Backward() {
	#pragma omp parallel for
	for (int h = 0; h < batch_size; h++) {
		float *error = &this->error[h * number_nodes];
		float *neuron = &this->neuron[h * number_nodes];

		for (int j = 0; j < number_nodes; j++) {
			for (int k = 0; k < connection.size(); k++) {
				Connection *connection = this->connection[k];

				Layer *parent_layer = connection->parent_layer;

				float *next_error = &parent_layer->error[h * parent_layer->number_nodes];
				float *weight = &connection->weight[j * parent_layer->number_nodes];

				for (int l = 0; l < parent_layer->number_nodes; l++) {
					next_error[l] += error[j] * weight[l];
				}
			}
		}
	}
}
void Layer::Derivative(int loss, float **y_batch) {
	if (y_batch) {
		#pragma omp parallel for
		for (int h = 0; h < batch_size; h++) {
			float *error = &this->error[h * number_nodes];
			float *neuron = &this->neuron[h * number_nodes];

			if (loss == Loss::cross_entropy) {
				if (activation == Activation::sigmoid) {
					for (int j = 0; j < number_nodes; j++) {
						error[j] = (neuron[j] - y_batch[h][j]) / (number_nodes * batch_size);
					}
				}
				else if (activation == Activation::softmax) {
					for (int j = 0; j < number_nodes; j++) {
						error[j] = (neuron[j] - y_batch[h][j]) / batch_size;
					}
				}
			}
			else if (loss == Loss::mean_squared_error) {
				for (int j = 0; j < number_nodes; j++) {
					error[j] = 2 * (neuron[j] - y_batch[h][j]) / (number_nodes * batch_size);
				}
			}
		}
		Derivative(loss);
	}
	else {
		#pragma omp parallel for
		for (int h = 0; h < batch_size; h++) {
			float *error = &this->error[h * number_nodes];
			float *neuron = &this->neuron[h * number_nodes];

			if (activation == Activation::linear) {
				// error[j] *= 1;
			}
			else if (activation == Activation::sigmoid && loss != Loss::cross_entropy){
				for (int j = 0; j < number_nodes; j++) {
					error[j] *= (1 - neuron[j]) * neuron[j];
				}
			}
		}
	}
}
void Layer::Forward() {
	#pragma omp parallel for
	for (int h = 0; h < batch_size; h++) {
		float *neuron = &this->neuron[h * number_nodes];

		for (int j = 0; j < number_nodes; j++) {
			double sum = 0;

			for (int k = 0; k < connection.size(); k++) {
				Connection *connection = this->connection[k];

				Layer *parent_layer = connection->parent_layer;

				float *prev_neuron = &parent_layer->neuron[h * parent_layer->number_nodes];
				float *weight = &connection->weight[j * parent_layer->number_nodes];

				for (int l = 0; l < parent_layer->number_nodes; l++) {
					sum += prev_neuron[l] * weight[l];
				}
			}
			neuron[j] = sum;
		}
	}
}
void Layer::Resize_Memory(int batch_size) {
	this->batch_size = batch_size;

	error = (float*)realloc(error, sizeof(float) * batch_size * number_nodes);
	neuron = (float*)realloc(neuron, sizeof(float) * batch_size * number_nodes);
}

void Neural_Networks::Resize_Memory(int batch_size) {
	if (this->batch_size != batch_size) {
		for (int i = 0; i < layer.size(); i++) {
			layer[i]->Resize_Memory(batch_size);
		}
		this->batch_size = batch_size;
	}
}

double Neural_Networks::Calculate_Loss(Layer *layer, float **y_batch) {
	double sum = 0, *batch_sum = new double[batch_size];

	memset(batch_sum, 0, sizeof(double) * batch_size);

	#pragma omp parallel for
	for (int h = 0; h < batch_size; h++) {
		float *neuron = &layer->neuron[h * layer->number_nodes];

		if (loss == Loss::cross_entropy) {
			if (layer->activation == Activation::sigmoid) {
				for (int j = 0; j < layer->number_nodes; j++) {
					batch_sum[h] -= (y_batch[h][j] * log(static_cast<double>(neuron[j])) + (1 - y_batch[h][j]) * log(1.0 - neuron[j])) / layer->number_nodes;
				}
			}
			else if (layer->activation == Activation::softmax) {
				for (int j = 0; j < layer->number_nodes; j++) {
					batch_sum[h] -= y_batch[h][j] * log(static_cast<double>(neuron[j]));
				}
			}
		}
		else if (loss == Loss::mean_squared_error) {
			for (int j = 0; j < layer->number_nodes; j++) {
				batch_sum[h] += (neuron[j] - y_batch[h][j]) * (neuron[j] - y_batch[h][j]) / layer->number_nodes;
			}
		}
	}
	for (int h = 0; h < batch_size; h++) {
		sum += batch_sum[h];
	}
	return sum;
}

Neural_Networks::Neural_Networks() {
	batch_size = 1;
}
Neural_Networks::~Neural_Networks() {
	for (int i = 0; i < layer.size(); i++) {
		delete layer[i];
	}
}

void Neural_Networks::Add(int number_nodes, int activation) {
	this->layer.push_back(new Layer(number_nodes, activation));
}
void Neural_Networks::Compile(int loss, double learning_rate) {
	this->loss = loss;
	this->learning_rate = learning_rate;
}
void Neural_Networks::Connect(int from, int to, double scale) {
	Connection *connection = new Connection(layer[from], layer[to], scale);

	this->connection.push_back(connection);
	layer[from]->connection.push_back(connection);
}
void Neural_Networks::Predict(float input[], float output[]) {
	Predict(&input, &output);
}
void Neural_Networks::Predict(float **input, float **output, int batch_size) {
	Resize_Memory(batch_size);

	for (int h = 0, i = 0; h < batch_size; h++) {
		memcpy(&layer[i]->neuron[h * layer[i]->number_nodes], input[h], sizeof(float) * layer[i]->number_nodes);
	}
	for (int i = 1; i < layer.size(); i++) {
		layer[i]->Forward();
		layer[i]->Activation();
	}
	for (int h = 0, i = layer.size() - 1; h < batch_size; h++) {
		memcpy(output[h], &layer[i]->neuron[h * layer[i]->number_nodes], sizeof(float) * layer[i]->number_nodes);
	}
}

double Neural_Networks::Evaluate(float **x_test, float **y_test, int test_size, int batch_size) {
	float **x_batch = new float*[batch_size];
	float **y_batch = new float*[batch_size];

	double loss = 0;

	for (int g = 0, h = 0; g < test_size; g++) {
		x_batch[h] = x_test[g];
		y_batch[h] = y_test[g];

		if (++h == batch_size || g == test_size - 1) {
			Resize_Memory(h);

			// copy x_test to neuron
			while (--h >= 0) {
				memcpy(&layer[0]->neuron[h * layer[0]->number_nodes], x_batch[h], sizeof(float) * layer[0]->number_nodes);
			}
			h = 0;

			// forward propagation
			for (int i = 1; i < layer.size(); i++) {
				layer[i]->Forward();
				layer[i]->Activation();
			}

			// calculate loss
			loss += Calculate_Loss(layer.back(), y_batch);
		}
	}
	delete[] x_batch;
	delete[] y_batch;

	return loss / test_size;
}
double Neural_Networks::Fit(float **x_train, float **y_train, int train_size, int batch_size) {
	float **x_batch = new float*[batch_size];
	float **y_batch = new float*[batch_size];

	double loss = 0;

	for (int g = 0, h = 0; g < train_size; g++) {
		x_batch[h] = x_train[g];
		y_batch[h] = y_train[g];

		if (++h == batch_size || g == train_size - 1) {
			Resize_Memory(h);

			// copy x_train to neuron
			while (--h >= 0) {
				memcpy(&layer[0]->neuron[h * layer[0]->number_nodes], x_batch[h], sizeof(float) * layer[0]->number_nodes);
			}
			h = 0;

			// initialize error to zero
			for (int i = 0; i < layer.size(); i++) {
				memset(layer[i]->error, 0, sizeof(float) * this->batch_size * layer[i]->number_nodes);
			}

			// forward propagation
			for (int i = 1; i < layer.size(); i++) {
				layer[i]->Forward();
				layer[i]->Activation();
			}

			// calculate loss
			loss += Calculate_Loss(layer.back(), y_batch);

			// calculate error
			layer.back()->Derivative(this->loss, y_batch);

			// error backpropagation
			layer.back()->Backward();

			for (int i = layer.size() - 2; i > 0; i--) {
				layer[i]->Derivative();
				layer[i]->Backward();
			}

			// adjust bias
			for (int i = 0; i < layer.size(); i++) {
				Layer *layer = this->layer[i];

				#pragma omp parallel for
				for (int j = 0; j < layer->number_nodes; j++) {
					double sum = 0;

					for (int h = 0; h < this->batch_size; h++) {
						sum += layer->error[h * layer->number_nodes + j];
					}
					layer->bias[j] -= learning_rate * sum;
				}
			}

			// adjust weight
			for (int i = 0; i < connection.size(); i++) {
				Connection *connection = this->connection[i];

				Layer *layer = connection->layer;
				Layer *parent_layer = connection->parent_layer;

				#pragma omp parallel for
				for (int j = 0; j < connection->number_weights; j++) {
					int k = j / parent_layer->number_nodes;
					int l = j % parent_layer->number_nodes;

					double sum = 0;

					for (int h = 0; h < this->batch_size; h++) {
						sum += layer->error[h * layer->number_nodes + k] * parent_layer->neuron[h * parent_layer->number_nodes + l];
					}
					connection->weight[j] -= learning_rate * sum;
				}
			}
		}
	}
	delete[] x_batch;
	delete[] y_batch;

	return loss / train_size;
}<commit_msg>Delete Neural_Networks.cpp<commit_after><|endoftext|>