<commit_before>#include "client.hh"
#include "output_formatter.hh"
#include "utils.hh"
#include <gtest/gtest.h>
#include <fstream>
#include <functional>
#include <thread>
#include <list>

namespace {

  using namespace prometheus;

  class BenchmarkTest : public ::testing::Test {};

  SetGauge<2> test_runtime("test_runtime_last_s",
			   ("Runtime of the last run of tests, by test name"
			    " and thread count."),
			   {"test", "threads"});

  void run(std::function<void()> f, std::string const& name, int threads) {
    std::list<std::thread> l;
    prometheus::IntervalReporter<> reporter(test_runtime.labels({name, std::to_string(threads)}));
    for (int i = 0; i < threads; ++i) {
      l.push_back(std::thread(f));
    }
    for (auto& t : l) {
      t.join();
    }
  }

  Counter<0> counter0("counter0", "");
  void incCounter1000000() {
    for (int i = 0; i < 1000000; ++i) {
      counter0.inc();
    }
  }
  TEST_F(BenchmarkTest, IncCounter) {
    run(incCounter1000000, "incCounter1000000", 1);
    EXPECT_EQ(1000000, counter0.value());
    run(incCounter1000000, "incCounter1000000", 10);
    EXPECT_EQ(11000000, counter0.value());
    run(incCounter1000000, "incCounter1000000", 100);
    EXPECT_EQ(111000000, counter0.value());
  }

  IncDecGauge<0> gauge0("gauge0", "");
  void incGauge1000000() {
    for (int i = 0; i < 1000000; ++i) {
      gauge0.inc();
    }
  }
  TEST_F(BenchmarkTest, IncGauge) {
    run(incGauge1000000, "incGauge1000000", 1);
    EXPECT_EQ(1000000, gauge0.value());
    run(incGauge1000000, "incGauge1000000", 10);
    EXPECT_EQ(11000000, gauge0.value());
    run(incGauge1000000, "incGauge1000000", 100);
    EXPECT_EQ(111000000, gauge0.value());
  }

}

SetGauge<0> run_time("run_timestamp", "Timestamp at which this test was run.");

int main(int argc, char**argv) {
  ::testing::InitGoogleTest(&argc, argv);
  prometheus::set_to_current_time(run_time);
  int retval = RUN_ALL_TESTS();
  {
    std::fstream bin_output(std::string(getenv("TEST_TMPDIR")) + "/benchmark_report.pb", std::ios::out | std::ios::binary);
    auto v = prometheus::impl::global_registry.collect();
    for (auto m : v) {
      prometheus::metricfamily_proto_to_ostream(std::cout, m);
      prometheus::delete_metricfamily(m);
    }
  }
  return retval;
};
<commit_msg>Add more benchmarks: - creating labels; - observing values in histograms; - setting gauges.<commit_after>#include "client.hh"
#include "output_formatter.hh"
#include "utils.hh"
#include <gtest/gtest.h>
#include <fstream>
#include <functional>
#include <thread>
#include <list>
#include <random>

namespace {

  using namespace prometheus;
  using namespace std::placeholders;

  class BenchmarkTest : public ::testing::Test {};

  SetGauge<2> test_runtime("test_runtime_last_s",
			   ("Runtime of the last run of tests, by test name"
			    " and thread count."),
			   {"test", "threads"});

  // This is the harness that runs the actual benchmarks. It spawns
  // `threads` threads and makes them run the benchmark function, then
  // joins them all. It uses an IntervalReporter to measure the total
  // time spent.
  void run(std::function<void(int, int)> f, std::string const& name, int threads) {
    std::list<std::thread> l;
    prometheus::IntervalReporter<> reporter(test_runtime.labels({name, std::to_string(threads)}));
    for (int i = 0; i < threads; ++i) {
      l.push_back(std::thread(f, i, threads));
    }
    for (auto& t : l) {
      t.join();
    }
  }

  // Test incrementing a counter many times.
  Counter<0> counter0("counter0", "");
  void incCounter1000000(int threadid, int threadcount) {
    for (int i = 0; i < 1000000; ++i) {
      counter0.inc();
    }
  }
  TEST_F(BenchmarkTest, IncCounter) {
    run(incCounter1000000, "incCounter1000000", 1);
    EXPECT_EQ(1000000, counter0.value());
    run(incCounter1000000, "incCounter1000000", 10);
    EXPECT_EQ(11000000, counter0.value());
    run(incCounter1000000, "incCounter1000000", 100);
    EXPECT_EQ(111000000, counter0.value());
  }

  // Test incrementing a gauge many times.
  IncDecGauge<0> gauge0("gauge0", "");
  void incGauge1000000(int threadid, int threadcount) {
    for (int i = 0; i < 1000000; ++i) {
      gauge0.inc();
    }
  }
  TEST_F(BenchmarkTest, IncGauge) {
    run(incGauge1000000, "incGauge1000000", 1);
    EXPECT_EQ(1000000, gauge0.value());
    run(incGauge1000000, "incGauge1000000", 10);
    EXPECT_EQ(11000000, gauge0.value());
    run(incGauge1000000, "incGauge1000000", 100);
    EXPECT_EQ(111000000, gauge0.value());
  }

  // Test setting a gauge many times.
  SetGauge<0> gauge1("gauge1", "");
  void setGauge1000000(int threadid, int threadcount) {
    for (int i = 0; i < 1000000; ++i) {
      gauge1.set(i);
    }
  }
  TEST_F(BenchmarkTest, SetGauge) {
    run(setGauge1000000, "setGauge1000000", 1);
    EXPECT_EQ(1000000-1, gauge1.value());
    run(setGauge1000000, "setGauge1000000", 10);
    EXPECT_EQ(1000000-1, gauge1.value());
    run(setGauge1000000, "setGauge1000000", 100);
    EXPECT_EQ(1000000-1, gauge1.value());
  }

  // Test creating new valuetypes (counters, here) and performing an
  // operation on them.
  Counter<3> labelled_counter0("labelled_counter0", "", {
      "threadid", "threadcount", "iteration"});
  void createLabelsAndInc10000(int threadid, int threadcount) {
    std::string threadid_str = std::to_string(threadid);
    std::string threadcount_str = std::to_string(threadcount);
    for (int i = 0; i < 10000; ++i) {
      labelled_counter0.labels({threadid_str, threadcount_str, std::to_string(i)}).inc();
    }
  }
  TEST_F(BenchmarkTest, CreateLabelsAndInc) {
    run(createLabelsAndInc10000, "createLabelsAndInc10000", 1);
    EXPECT_EQ(1, labelled_counter0.labels({"0", "1", "50"}).value());

    run(createLabelsAndInc10000, "createLabelsAndInc10000", 10);
    EXPECT_EQ(1, labelled_counter0.labels({"0", "10", "960"}).value());
    EXPECT_EQ(1, labelled_counter0.labels({"5", "10", "5324"}).value());

    run(createLabelsAndInc10000, "createLabelsAndInc10000", 100);
    EXPECT_EQ(1, labelled_counter0.labels({"0", "100", "0"}).value());
    EXPECT_EQ(1, labelled_counter0.labels({"99", "100", "9999"}).value());
  }

  // Test observing pseudorandom values (with a fixed seed for
  // reproducibility). The distribution is passed as an argument, to
  // compare uniform distribution (cheaper) vs exponential
  // distribution (more realistic).
  Histogram<0> histogram0("histogram0", "");
  template<typename distribution>
  void observePseudoRandom100000(distribution& dis, int threadid, int threadcount) {
    std::mt19937 prng(42);
    for (int i = 0; i < 100000; ++i) {
      double d = dis(prng);
      histogram0.observe(d);
    }
  }
  TEST_F(BenchmarkTest, Histogram) {
    std::uniform_real_distribution<double> uniform(0.0, 1024.0);
    run(std::bind(observePseudoRandom100000<std::uniform_real_distribution<double>>, uniform, _1, _2),
        "observepseudorandom100000<uniform>", 1);
    EXPECT_EQ(100000, histogram0.value());
    run(std::bind(observePseudoRandom100000<std::uniform_real_distribution<double>>, uniform, _1, _2),
        "observepseudorandom100000<uniform>", 10);
    EXPECT_EQ(11*100000, histogram0.value());
    run(std::bind(observePseudoRandom100000<std::uniform_real_distribution<double>>, uniform, _1, _2),
        "observepseudorandom100000<uniform>", 100);
    EXPECT_EQ(111*100000, histogram0.value());

    std::exponential_distribution<double> exponential(1.0);
    run(std::bind(observePseudoRandom100000<std::exponential_distribution<double>>, exponential, _1, _2),
        "observepseudorandom100000<exponential>", 1);
    EXPECT_EQ(112*100000, histogram0.value());
    run(std::bind(observePseudoRandom100000<std::exponential_distribution<double>>, exponential, _1, _2),
        "observepseudorandom100000<exponential>", 10);
    EXPECT_EQ(122*100000, histogram0.value());
    run(std::bind(observePseudoRandom100000<std::exponential_distribution<double>>, exponential, _1, _2),
        "observepseudorandom100000<exponential>", 100);
    EXPECT_EQ(222*100000, histogram0.value());
  }

}

SetGauge<0> run_time("run_timestamp", "Timestamp at which this test was run.");

int main(int argc, char**argv) {
  ::testing::InitGoogleTest(&argc, argv);
  prometheus::set_to_current_time(run_time);
  int retval = RUN_ALL_TESTS();
  {
    auto v = prometheus::impl::global_registry.collect();
    for (auto m : v) {
      if (m->name() == "test_runtime_last_s") {
        prometheus::metricfamily_proto_to_ostream(std::cout, m);
      }
      prometheus::delete_metricfamily(m);
    }
  }
  return retval;
};
<|endoftext|>


<commit_before>#include "socket.hpp"

int main(int argc, char* argv[])
{
  try
  {
    if (argc != 4)
    {
      std::cerr << "Usage: blocking_tcp <host> <port> <message>\n";
      return 1;
    }

    Socket c;
    c.connect(argv[1], argv[2], 10);

    for (int i=0; i < 3; ++i) {
      boost::posix_time::ptime time_sent =
        boost::posix_time::microsec_clock::universal_time();

      c.write(argv[3], 10);

      //for (;;)
      //{
        char test[300];
	c.read(test, 1000, 10);
	//std::string line = c.read_line(boost::posix_time::seconds(10));

        // Keep going until we get back the line that was sent.
	std::string line = test;
	std::cout << "received string = " << test << std::endl;

	/*
	if (line == argv[3]) {
          break;
	} else {

	}
	*/
      //}

      boost::posix_time::ptime time_received =
        boost::posix_time::microsec_clock::universal_time();

      std::cout << "Round trip time: ";
      std::cout << (time_received - time_sent).total_microseconds();
      std::cout << " microseconds\n";
    }
  }
  catch (std::exception& e)
  {
    std::cerr << "Exception: " << e.what() << "\n";
  }

  return 0;
}
<commit_msg>remove example tcp client<commit_after><|endoftext|>


<commit_before>#include "./video_recorder.h"
#include <QTimer>
#include <QLoggingCategory>
#include "./graphics/gl.h"

QLoggingCategory videoRecorderChan("VideoRecorder");

VideoRecorder::VideoRecorder(double fps) : fps(fps)
{
}

VideoRecorder::~VideoRecorder()
{
  qCInfo(videoRecorderChan) << "Destructor";
  if (isRecording)
    stopRecording();

  if (videoTimer.get())
    disconnect(videoTimer.get(), &QTimer::timeout, this,
               &VideoRecorder::updateVideoTimer);
}

void VideoRecorder::initialize(Graphics::Gl *gl)
{
  this->gl = gl;
}

void VideoRecorder::resize(int width, int height)
{
  stopRecording();

  // mpeg supports even frame sizes only!
  videoWidth = (width % 2 == 0) ? width : width - 1;
  videoHeight = (height % 2 == 0) ? height : height - 1;
}

void VideoRecorder::createNewVideo(std::string filename)
{
  qCInfo(videoRecorderChan) << "Create recorder" << filename.c_str();
  if (videoRecorder.get())
  {
    videoRecorder->stopRecording();
  }

  pixelBuffer.resize(videoWidth * videoHeight * 3);
  videoRecorder = std::make_unique<FFMPEGRecorder>(videoWidth, videoHeight, 1,
                                                   true, filename, fps);

  videoRecorder->startRecording();
  videoTimer = std::make_unique<QTimer>(this);
  connect(videoTimer.get(), &QTimer::timeout, this,
          &VideoRecorder::updateVideoTimer);
}

void VideoRecorder::startRecording()
{
  isRecording = true;
  videoTimer->start(40);
}

void VideoRecorder::stopRecording()
{
  if (!isRecording)
    return;

  isRecording = false;
  videoTimer->stop();
}

void VideoRecorder::updateVideoTimer()
{
  videoRecorder->queueFrame(pixelBuffer.data());
}

void VideoRecorder::captureVideoFrame()
{
  if (videoRecorder && isRecording)
  {
    gl->glReadPixels(0, 0, videoWidth, videoHeight, GL_RGB, GL_UNSIGNED_BYTE,
                     pixelBuffer.data());
  }
}

bool VideoRecorder::getIsRecording()
{
  return isRecording;
}

bool VideoRecorder::getHasActiveRecording()
{
  return videoRecorder.get() != nullptr;
}

<commit_msg>Disconnect old timer before creating a new video.<commit_after>#include "./video_recorder.h"
#include <QTimer>
#include <QLoggingCategory>
#include "./graphics/gl.h"

QLoggingCategory videoRecorderChan("VideoRecorder");

VideoRecorder::VideoRecorder(double fps) : fps(fps)
{
}

VideoRecorder::~VideoRecorder()
{
  qCInfo(videoRecorderChan) << "Destructor";
  if (isRecording)
    stopRecording();

  if (videoTimer.get())
    disconnect(videoTimer.get(), &QTimer::timeout, this,
               &VideoRecorder::updateVideoTimer);
}

void VideoRecorder::initialize(Graphics::Gl *gl)
{
  this->gl = gl;
}

void VideoRecorder::resize(int width, int height)
{
  stopRecording();

  // mpeg supports even frame sizes only!
  videoWidth = (width % 2 == 0) ? width : width - 1;
  videoHeight = (height % 2 == 0) ? height : height - 1;
}

void VideoRecorder::createNewVideo(std::string filename)
{
  qCInfo(videoRecorderChan) << "Create recorder" << filename.c_str();
  if (videoRecorder.get())
  {
    videoRecorder->stopRecording();
    disconnect(videoTimer.get(), &QTimer::timeout, this,
               &VideoRecorder::updateVideoTimer);
  }

  pixelBuffer.resize(videoWidth * videoHeight * 3);
  videoRecorder = std::make_unique<FFMPEGRecorder>(videoWidth, videoHeight, 1,
                                                   true, filename, fps);

  videoRecorder->startRecording();
  videoTimer = std::make_unique<QTimer>(this);
  connect(videoTimer.get(), &QTimer::timeout, this,
          &VideoRecorder::updateVideoTimer);
}

void VideoRecorder::startRecording()
{
  isRecording = true;
  videoTimer->start(40);
}

void VideoRecorder::stopRecording()
{
  if (!isRecording)
    return;

  isRecording = false;
  videoTimer->stop();
}

void VideoRecorder::updateVideoTimer()
{
  videoRecorder->queueFrame(pixelBuffer.data());
}

void VideoRecorder::captureVideoFrame()
{
  if (videoRecorder && isRecording)
  {
    gl->glReadPixels(0, 0, videoWidth, videoHeight, GL_RGB, GL_UNSIGNED_BYTE,
                     pixelBuffer.data());
  }
}

bool VideoRecorder::getIsRecording()
{
  return isRecording;
}

bool VideoRecorder::getHasActiveRecording()
{
  return videoRecorder.get() != nullptr;
}

<|endoftext|>


<commit_before>#include "view/SceneView.h"

#include "util/DotSceneLoader.h"

#include "util/BulletDebugDrawer.h"

#include <OgreRoot.h>
#include <OgreViewport.h>
#include <OgreConfigFile.h>
#include <OgreEntity.h>
#include <OgreCompositorManager.h>
#include <OgreWindowEventUtilities.h>

#include <sstream>
#include <string>

#include <btBulletDynamicsCommon.h>

SceneView::SceneView(Rally::Model::World& world) :
        world(world),
        camera(NULL),
        viewport(NULL),
        sceneManager(NULL),
        renderWindow(NULL),
        postProcessingEnabled(false) {
    debugDrawEnabled = false;
}

SceneView::~SceneView() {
    //delete bulletDebugDrawer;
    tunnelPortalView.detach();

    playerCarView.detach();

    bloomView.detach();
    ssaoView.detach();
    gbufferView.detach();

	lensflare->end();
	delete lensflare;
	lensflare = NULL;

    Ogre::Root* root = Ogre::Root::getSingletonPtr();
    delete root;
}

void SceneView::initialize(std::string resourceConfigPath, std::string pluginConfigPath) {
    Ogre::Root* root = new Ogre::Root(pluginConfigPath);

    this->loadResourceConfig(resourceConfigPath);
    // (The actual precaching is done below, once there is a render context)

    if(!root->restoreConfig() && !root->showConfigDialog()) {
        throw std::runtime_error("Could neither restore Ogre config, nor read it from the user.");
    }

    renderWindow = root->initialise(
        true, // auto-create the render window now
        "Rally Sport Racing Game");

    sceneManager = root->createSceneManager("OctreeSceneManager"); // Todo: Research a good scene manager

    // This should be done after creating a scene manager, so that there is a render context (GL/D3D)
    Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();

    sceneManager->setSkyDome(true, "Rally/CloudySky", 5, 8);

    camera = this->addCamera("MainCamera");
    viewport = this->addViewport(camera);
    camera->setAspectRatio(Ogre::Real(viewport->getActualWidth()) / Ogre::Real(viewport->getActualHeight()));

    Ogre::SceneNode* sceneNode = sceneManager->getRootSceneNode()->createChildSceneNode();
    sceneNode->setPosition(Ogre::Vector3(0, 0, 0));

    // Load the scene.
    DotSceneLoader loader;
    loader.parseDotScene("world.scene", "General", sceneManager, sceneNode);

    // shadows
   	sceneManager->getEntity("mark")->setCastShadows(false);
    sceneManager->getEntity("horisont")->setCastShadows(false);
    sceneManager->getEntity("fysikgrans")->setCastShadows(false);
    sceneManager->getEntity("maskin")->setCastShadows(false);
    sceneManager->getEntity("plank")->setCastShadows(false);
    sceneManager->setShadowTechnique(Ogre::SHADOWTYPE_TEXTURE_MODULATIVE);
    sceneManager->setAmbientLight(Ogre::ColourValue(1, 1, 1));
    sceneManager->setShadowFarDistance(250);
    sceneManager->setShadowColour(Ogre::ColourValue(0.80f, 0.80f, 0.80f));
    sceneManager->setShadowTextureSize( 2048 );
    sceneManager->setShadowTextureCount( 1 );

	// lights
    Ogre::Light* sunLight = sceneManager->createLight("sunLight");
    sunLight->setType(Ogre::Light::LT_DIRECTIONAL);
    sunLight->setCastShadows(true);
    sunLight->setDirection(Ogre::Vector3( 1, -3, 1 ));
    sunLight->setDiffuseColour(Ogre::ColourValue(1, 1, 1));
    sunLight->setSpecularColour(Ogre::ColourValue(1, 1, 1));
    sceneNode->attachObject(sunLight);

    Ogre::Light* skyLight1 = sceneManager->createLight("skyLight1");
    skyLight1->setType(Ogre::Light::LT_POINT);
    skyLight1->setCastShadows(false);
    skyLight1->setPosition(Ogre::Vector3(0, 300, 0));
    skyLight1->setDiffuseColour(Ogre::ColourValue(0.8f, 0.8f, 1.0f));
    skyLight1->setSpecularColour(Ogre::ColourValue(1, 1, 1));
    sceneNode->attachObject(skyLight1);

	playerCarView.attachTo(sceneManager, world.getPlayerCar());

	//goalView.attachTo(sceneManager, "Finish", "car.mesh", world.getFinish());
	goalView.attachTo(sceneManager, "Start", "car.mesh", world.getStart());

    // Debug draw Bullet
    bulletDebugDrawer = new Rally::Util::BulletDebugDrawer(sceneManager);
    world.getPhysicsWorld().getDynamicsWorld()->setDebugDrawer(bulletDebugDrawer);

    sceneManager->setSkyDome(true, "Rally/CloudySky", 5, 8);

	// Place the magic surface at the end of the tunnel.
	tunnelPortalView.attachTo(sceneManager, "TunnelPortal");
	tunnelPortalView.setScale(15.0f, 5.0f, true);
    tunnelPortalView.setPosition(Rally::Vector3(86.0f, 5.0f, -134.0f));
    tunnelPortalView.setOrientation(Rally::Quaternion(Ogre::Math::Sqrt(0.5f), 0, -Ogre::Math::Sqrt(0.5f), 0));

    // Snap a picture for the magic surface at Kopparbunken.
	tunnelPortalView.moveCamera(
        Rally::Vector3(255.0f, 12.0f, 240.0f), // position
        Rally::Vector3(255.0f, 12.0f, 239.0f)); // look at
    tunnelPortalView.takeSnapshot();

	lensflare = new Rally::View::LensFlareView();
	lensflare->init(sceneManager, camera, viewport->getWidth(), viewport->getHeight(), 800, 30, "LensFlareHalo", "LensFlareCircle", "LensFlareBurst");
	lensflare->setPosition(Ogre::Vector3(-800, 500, -800));
}

Ogre::Viewport* SceneView::addViewport(Ogre::Camera* followedCamera) {
    Ogre::Viewport* viewport = renderWindow->addViewport(camera);
    viewport->setBackgroundColour(Ogre::ColourValue(0, 0, 0));

    return viewport;
}

Ogre::Camera* SceneView::addCamera(Ogre::String cameraName) {
    // Setup camera to match viewport
    Ogre::Camera* camera = sceneManager->createCamera(cameraName);
	camera->setNearClipDistance(Ogre::Real(0.1));

    return camera;
}

void SceneView::loadResourceConfig(Ogre::String resourceConfigPath) {
    Ogre::ResourceGroupManager& resourceGroupManager = Ogre::ResourceGroupManager::getSingleton();

    Ogre::ConfigFile resourceConfig;
    resourceConfig.load(resourceConfigPath);

    for(Ogre::ConfigFile::SectionIterator sectionIterator = resourceConfig.getSectionIterator();
            sectionIterator.hasMoreElements();
            sectionIterator.moveNext()) {
        Ogre::ConfigFile::SettingsMultiMap* settings = sectionIterator.peekNextValue();

        // Now load all the resources for this resource group
        for(Ogre::ConfigFile::SettingsMultiMap::iterator resource = settings->begin();
                resource != settings->end();
                ++resource) {
            resourceGroupManager.addResourceLocation(
                resource->second, // filename of directory
                resource->first, // resource type
                sectionIterator.peekNextKey()); // resource group
        }
    }
}

void SceneView::addLogicListener(Rally::View::SceneView_LogicListener& logicListener) {
    Ogre::Root::getSingleton().addFrameListener(&logicListener);
}

bool SceneView::renderFrame(float deltaTime) {
    Ogre::WindowEventUtilities::messagePump();

    if(renderWindow->isClosed())  {
        return false;
    } else {
        updatePlayerCar(deltaTime);
        updateRemoteCars();
		//updateCheckPoints();
		updateParticles();
		lensflare->update();

    if(debugDrawEnabled){
        world.getPhysicsWorld().getDynamicsWorld()->debugDrawWorld();
    }

        Ogre::Root& root = Ogre::Root::getSingleton();
        if(!root.renderOneFrame()) {
            return false;
        }
    }
    return true;
}

void SceneView::updatePlayerCar(float deltaTime) {
    // Todo: Move to separate view
    Rally::Model::Car& playerCar = world.getPlayerCar();
    Rally::Vector3 position = playerCar.getPosition();
    playerCarView.setEffectFactor(playerCar.getEffectFactor());
    playerCarView.updateBody(playerCar.getPosition(), playerCar.getOrientation());
    playerCarView.updateWheels(
        playerCar.getRightFrontWheelOrientation(),
        playerCar.getLeftFrontWheelOrientation(),
        playerCar.getRightBackWheelOrientation(),
        playerCar.getLeftBackWheelOrientation());

	Rally::Vector3 currentCameraPosition = camera->getPosition();

	Rally::Vector3 displacementBase = playerCar.getOrientation() * Ogre::Vector3::UNIT_Z;
	displacementBase *= -1;

	float xzdisplacement = 7.0f;
	float ydisplacement = 3.0f;

	Rally::Vector3 displacement(
		xzdisplacement * displacementBase.x,
		ydisplacement,
		xzdisplacement * displacementBase.z);

    Rally::Vector3 endPosition = position + displacement;

	float velocityAdjust = playerCar.getVelocity().length()/8;
	float lerpAdjust = Ogre::Math::Clamp(velocityAdjust*deltaTime, 0.01f, 0.9f);

	// Lerp towards the new camera position to get a smoother pan
	float lerpX = Ogre::Math::lerp(currentCameraPosition.x, endPosition.x, lerpAdjust);
	float lerpY = Ogre::Math::lerp(currentCameraPosition.y, endPosition.y, lerpAdjust);
	float lerpZ = Ogre::Math::lerp(currentCameraPosition.z, endPosition.z, lerpAdjust);

	Rally::Vector3 newPos(lerpX, lerpY, lerpZ);
	Rally::Vector3 cameraPosition = newPos;

	/*
	Shoot a ray from the car (with an offset to prevent collision with itself) to the camera.
	If anyting is intersected the camera is adjusted to prevent that the camera is blocked.
	*/
	btVector3 start(position.x, position.y + 1.1f, position.z);
	btVector3 end(newPos.x, newPos.y, newPos.z);

	btCollisionWorld::ClosestRayResultCallback ClosestRayResultCallBack(start, end);

	// Perform raycast
	world.getPhysicsWorld().getDynamicsWorld()->getCollisionWorld()->rayTest(start, end, ClosestRayResultCallBack);

	if(ClosestRayResultCallBack.hasHit() &&
		ClosestRayResultCallBack.m_collisionObject->getInternalType() != btCollisionObject::CO_GHOST_OBJECT) {

		btVector3 hitLoc = ClosestRayResultCallBack.m_hitPointWorld;

		//If the camera is blocked, the new camera is set to where the collison
		//happened with a tiny offset.
		cameraPosition = Rally::Vector3(hitLoc.getX(), hitLoc.getY(), hitLoc.getZ());

		float camOffset = 0.5f;

		//Adjust for X
		if(hitLoc.getX() > cameraPosition.x)
			cameraPosition += Rally::Vector3(-camOffset, 0.0f, 0.0f);
		else if(hitLoc.getX() < cameraPosition.x)
			cameraPosition += Rally::Vector3(camOffset, 0.0f, 0.0f);

		//Adjust for Y
		if(hitLoc.getY() > cameraPosition.y)
			cameraPosition += Rally::Vector3(0.0f, -camOffset, 0.0f);

		//Adjust for Z
		if(hitLoc.getZ() > cameraPosition.z)
			cameraPosition += Rally::Vector3(0.0f, 0.0f, -camOffset);
		else if(hitLoc.getZ() < cameraPosition.z)
			cameraPosition += Rally::Vector3(0.0f, 0.0f, camOffset);

	}

    camera->setPosition(cameraPosition);
	camera->lookAt(position);

    // This is a bit of a temporary hack... It is laggy though...
    /*Rally::Vector3 lookVector = (Rally::Vector3(255.0f, 12.0f, 240.0f) - Rally::Vector3(255.0f, 12.0f, 239.0f))*
        (cameraPosition - Rally::Vector3(86.0f, 12.0f, -134.0f)).length();
	tunnelPortalView.moveCamera(
        Rally::Vector3(255.0f, 12.0f, 240.0f) + lookVector, // position
        Rally::Vector3(255.0f, 12.0f, 239.0f) + lookVector); // look at
    tunnelPortalView.takeSnapshot();*/
}

void SceneView::updateRemoteCars() {
    for(std::map<int, Rally::View::RemoteCarView>::iterator carViewIterator = remoteCarViews.begin();
            carViewIterator != remoteCarViews.end();
            ++carViewIterator) {
        carViewIterator->second.updateWithRemoteCar();
    }
}

void SceneView::updateCheckPoints() {
	//goalView.update();
}

void SceneView::remoteCarUpdated(int carId, const Rally::Model::RemoteCar& remoteCar, bool carTypeChanged) {
    std::map<int, Rally::View::RemoteCarView>::iterator found = remoteCarViews.find(carId);

    // Lazily construct if not found
    if(found == remoteCarViews.end()) {
        found = remoteCarViews.insert(std::map<int, Rally::View::RemoteCarView>::value_type(carId,
            Rally::View::RemoteCarView(remoteCar))).first;
        std::ostringstream carNameStream;
        carNameStream << "RemoteCar_" << carId;
        std::string carName = carNameStream.str();

        found->second.attachTo(sceneManager, carName);
    }

    // We don't really update the car here, as it has to be done every frame for the interpolation.

    found->second.changeCar(remoteCar.getCarType());
}

void SceneView::remoteCarRemoved(int carId, const Rally::Model::RemoteCar& remoteCar) {
    remoteCarViews.erase(carId);
}

void SceneView::toggleDebugDraw() {
    debugDrawEnabled = !debugDrawEnabled;
}

void SceneView::toggleReflections() {
    playerCarView.setReflectionsOn(!playerCarView.isReflectionsOn());
}

void SceneView::togglePostProcessing() {
    postProcessingEnabled = !postProcessingEnabled;

    if(postProcessingEnabled) {
        // TODO: Fix so that setEnabled works, can't be that hard...
        /*gbufferView.setEnabled(true);
        ssaoView.setEnabled(true);
        bloomView.setEnabled(true);*/
        gbufferView.attachTo(viewport);
        gbufferView.setEnabled(true);

        ssaoView.attachTo(viewport, &world.getPlayerCar());
        ssaoView.setEnabled(true);

        bloomView.attachTo(viewport, &world.getPlayerCar());
        bloomView.setEnabled(true);

        motionBlurView.attachTo(viewport, &world.getPlayerCar());
        motionBlurView.setEnabled(true);
    } else {
        motionBlurView.detach();
        bloomView.detach();
        ssaoView.detach();
        gbufferView.detach();
        /*bloomView.setEnabled(false);
        ssaoView.setEnabled(false);
        gbufferView.setEnabled(false);*/
    }
}

void SceneView::updateParticles(){
	bool enabled[4] = {false, false, false, false};
	Rally::Vector3 positions[4];

	if(world.getPlayerCar().getPhysicsCar().getRightBackWheelTraction() < 0.2){
		positions[0] = world.getPlayerCar().getPhysicsCar().getRightBackWheelOrigin();
		enabled[0] = true;
	}

	if(world.getPlayerCar().getPhysicsCar().getRightFrontWheelTraction() < 0.2){
		positions[1] = world.getPlayerCar().getPhysicsCar().getRightFrontWheelOrigin();
		enabled[1] = true;
	}

	if(world.getPlayerCar().getPhysicsCar().getLeftBackWheelTraction() < 0.2){
		positions[2] = world.getPlayerCar().getPhysicsCar().getLeftBackWheelOrigin();
		enabled[2] = true;
	}

	if(world.getPlayerCar().getPhysicsCar().getLeftFrontWheelTraction() < 0.2){
		positions[3] = world.getPlayerCar().getPhysicsCar().getLeftFrontWheelOrigin();
		enabled[3] = true;
	}

	playerCarView.enableWheelParticles(enabled, positions);

}
<commit_msg>The camera no longer collides with the car<commit_after>#include "view/SceneView.h"

#include "util/DotSceneLoader.h"

#include "util/BulletDebugDrawer.h"

#include <OgreRoot.h>
#include <OgreViewport.h>
#include <OgreConfigFile.h>
#include <OgreEntity.h>
#include <OgreCompositorManager.h>
#include <OgreWindowEventUtilities.h>

#include <sstream>
#include <string>

#include <btBulletDynamicsCommon.h>

SceneView::SceneView(Rally::Model::World& world) :
        world(world),
        camera(NULL),
        viewport(NULL),
        sceneManager(NULL),
        renderWindow(NULL),
        postProcessingEnabled(false) {
    debugDrawEnabled = false;
}

SceneView::~SceneView() {
    //delete bulletDebugDrawer;
    tunnelPortalView.detach();

    playerCarView.detach();

    bloomView.detach();
    ssaoView.detach();
    gbufferView.detach();

	lensflare->end();
	delete lensflare;
	lensflare = NULL;

    Ogre::Root* root = Ogre::Root::getSingletonPtr();
    delete root;
}

void SceneView::initialize(std::string resourceConfigPath, std::string pluginConfigPath) {
    Ogre::Root* root = new Ogre::Root(pluginConfigPath);

    this->loadResourceConfig(resourceConfigPath);
    // (The actual precaching is done below, once there is a render context)

    if(!root->restoreConfig() && !root->showConfigDialog()) {
        throw std::runtime_error("Could neither restore Ogre config, nor read it from the user.");
    }

    renderWindow = root->initialise(
        true, // auto-create the render window now
        "Rally Sport Racing Game");

    sceneManager = root->createSceneManager("OctreeSceneManager"); // Todo: Research a good scene manager

    // This should be done after creating a scene manager, so that there is a render context (GL/D3D)
    Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();

    sceneManager->setSkyDome(true, "Rally/CloudySky", 5, 8);

    camera = this->addCamera("MainCamera");
    viewport = this->addViewport(camera);
    camera->setAspectRatio(Ogre::Real(viewport->getActualWidth()) / Ogre::Real(viewport->getActualHeight()));

    Ogre::SceneNode* sceneNode = sceneManager->getRootSceneNode()->createChildSceneNode();
    sceneNode->setPosition(Ogre::Vector3(0, 0, 0));

    // Load the scene.
    DotSceneLoader loader;
    loader.parseDotScene("world.scene", "General", sceneManager, sceneNode);

    // shadows
   	sceneManager->getEntity("mark")->setCastShadows(false);
    sceneManager->getEntity("horisont")->setCastShadows(false);
    sceneManager->getEntity("fysikgrans")->setCastShadows(false);
    sceneManager->getEntity("maskin")->setCastShadows(false);
    sceneManager->getEntity("plank")->setCastShadows(false);
    sceneManager->setShadowTechnique(Ogre::SHADOWTYPE_TEXTURE_MODULATIVE);
    sceneManager->setAmbientLight(Ogre::ColourValue(1, 1, 1));
    sceneManager->setShadowFarDistance(250);
    sceneManager->setShadowColour(Ogre::ColourValue(0.80f, 0.80f, 0.80f));
    sceneManager->setShadowTextureSize( 2048 );
    sceneManager->setShadowTextureCount( 1 );

	// lights
    Ogre::Light* sunLight = sceneManager->createLight("sunLight");
    sunLight->setType(Ogre::Light::LT_DIRECTIONAL);
    sunLight->setCastShadows(true);
    sunLight->setDirection(Ogre::Vector3( 1, -3, 1 ));
    sunLight->setDiffuseColour(Ogre::ColourValue(1, 1, 1));
    sunLight->setSpecularColour(Ogre::ColourValue(1, 1, 1));
    sceneNode->attachObject(sunLight);

    Ogre::Light* skyLight1 = sceneManager->createLight("skyLight1");
    skyLight1->setType(Ogre::Light::LT_POINT);
    skyLight1->setCastShadows(false);
    skyLight1->setPosition(Ogre::Vector3(0, 300, 0));
    skyLight1->setDiffuseColour(Ogre::ColourValue(0.8f, 0.8f, 1.0f));
    skyLight1->setSpecularColour(Ogre::ColourValue(1, 1, 1));
    sceneNode->attachObject(skyLight1);

	playerCarView.attachTo(sceneManager, world.getPlayerCar());

	//goalView.attachTo(sceneManager, "Finish", "car.mesh", world.getFinish());
	goalView.attachTo(sceneManager, "Start", "car.mesh", world.getStart());

    // Debug draw Bullet
    bulletDebugDrawer = new Rally::Util::BulletDebugDrawer(sceneManager);
    world.getPhysicsWorld().getDynamicsWorld()->setDebugDrawer(bulletDebugDrawer);

    sceneManager->setSkyDome(true, "Rally/CloudySky", 5, 8);

	// Place the magic surface at the end of the tunnel.
	tunnelPortalView.attachTo(sceneManager, "TunnelPortal");
	tunnelPortalView.setScale(15.0f, 5.0f, true);
    tunnelPortalView.setPosition(Rally::Vector3(86.0f, 5.0f, -134.0f));
    tunnelPortalView.setOrientation(Rally::Quaternion(Ogre::Math::Sqrt(0.5f), 0, -Ogre::Math::Sqrt(0.5f), 0));

    // Snap a picture for the magic surface at Kopparbunken.
	tunnelPortalView.moveCamera(
        Rally::Vector3(255.0f, 12.0f, 240.0f), // position
        Rally::Vector3(255.0f, 12.0f, 239.0f)); // look at
    tunnelPortalView.takeSnapshot();

	lensflare = new Rally::View::LensFlareView();
	lensflare->init(sceneManager, camera, viewport->getWidth(), viewport->getHeight(), 800, 30, "LensFlareHalo", "LensFlareCircle", "LensFlareBurst");
	lensflare->setPosition(Ogre::Vector3(-800, 500, -800));
}

Ogre::Viewport* SceneView::addViewport(Ogre::Camera* followedCamera) {
    Ogre::Viewport* viewport = renderWindow->addViewport(camera);
    viewport->setBackgroundColour(Ogre::ColourValue(0, 0, 0));

    return viewport;
}

Ogre::Camera* SceneView::addCamera(Ogre::String cameraName) {
    // Setup camera to match viewport
    Ogre::Camera* camera = sceneManager->createCamera(cameraName);
	camera->setNearClipDistance(Ogre::Real(0.1));

    return camera;
}

void SceneView::loadResourceConfig(Ogre::String resourceConfigPath) {
    Ogre::ResourceGroupManager& resourceGroupManager = Ogre::ResourceGroupManager::getSingleton();

    Ogre::ConfigFile resourceConfig;
    resourceConfig.load(resourceConfigPath);

    for(Ogre::ConfigFile::SectionIterator sectionIterator = resourceConfig.getSectionIterator();
            sectionIterator.hasMoreElements();
            sectionIterator.moveNext()) {
        Ogre::ConfigFile::SettingsMultiMap* settings = sectionIterator.peekNextValue();

        // Now load all the resources for this resource group
        for(Ogre::ConfigFile::SettingsMultiMap::iterator resource = settings->begin();
                resource != settings->end();
                ++resource) {
            resourceGroupManager.addResourceLocation(
                resource->second, // filename of directory
                resource->first, // resource type
                sectionIterator.peekNextKey()); // resource group
        }
    }
}

void SceneView::addLogicListener(Rally::View::SceneView_LogicListener& logicListener) {
    Ogre::Root::getSingleton().addFrameListener(&logicListener);
}

bool SceneView::renderFrame(float deltaTime) {
    Ogre::WindowEventUtilities::messagePump();

    if(renderWindow->isClosed())  {
        return false;
    } else {
        updatePlayerCar(deltaTime);
        updateRemoteCars();
		//updateCheckPoints();
		updateParticles();
		lensflare->update();

    if(debugDrawEnabled){
        world.getPhysicsWorld().getDynamicsWorld()->debugDrawWorld();
    }

        Ogre::Root& root = Ogre::Root::getSingleton();
        if(!root.renderOneFrame()) {
            return false;
        }
    }
    return true;
}

void SceneView::updatePlayerCar(float deltaTime) {
    // Todo: Move to separate view
    Rally::Model::Car& playerCar = world.getPlayerCar();
    Rally::Vector3 position = playerCar.getPosition();
    playerCarView.setEffectFactor(playerCar.getEffectFactor());
    playerCarView.updateBody(playerCar.getPosition(), playerCar.getOrientation());
    playerCarView.updateWheels(
        playerCar.getRightFrontWheelOrientation(),
        playerCar.getLeftFrontWheelOrientation(),
        playerCar.getRightBackWheelOrientation(),
        playerCar.getLeftBackWheelOrientation());

	Rally::Vector3 currentCameraPosition = camera->getPosition();

	Rally::Vector3 displacementBase = playerCar.getOrientation() * Ogre::Vector3::UNIT_Z;
	displacementBase *= -1;

	float xzdisplacement = 6.0f;
	float ydisplacement = 3.0f;

	Rally::Vector3 displacement(
		xzdisplacement * displacementBase.x,
		ydisplacement,
		xzdisplacement * displacementBase.z);

    Rally::Vector3 endPosition = position + displacement;

	float velocityAdjust = playerCar.getVelocity().length()/8;
	float lerpAdjust = Ogre::Math::Clamp(velocityAdjust*deltaTime, 0.025f, 0.9f);

	// Lerp towards the new camera position to get a smoother pan
	float lerpX = Ogre::Math::lerp(currentCameraPosition.x, endPosition.x, lerpAdjust);
	float lerpY = Ogre::Math::lerp(currentCameraPosition.y, endPosition.y, lerpAdjust);
	float lerpZ = Ogre::Math::lerp(currentCameraPosition.z, endPosition.z, lerpAdjust);

	Rally::Vector3 newPos(lerpX, lerpY, lerpZ);
	Rally::Vector3 cameraPosition = newPos;

	/*
	Shoot a ray from the car to the camera.
	If anything is intersected the camera is adjusted to prevent that the camera is blocked.
	*/
	btVector3 start(position.x, position.y + 0.5f, position.z);
	btVector3 end(newPos.x, newPos.y, newPos.z);

	btCollisionWorld::ClosestRayResultCallback ClosestRayResultCallBack(start, end);

	// Perform raycast
	world.getPhysicsWorld().getDynamicsWorld()->getCollisionWorld()->rayTest(start, end, ClosestRayResultCallBack);

	if(ClosestRayResultCallBack.hasHit() &&
		ClosestRayResultCallBack.m_collisionObject->getInternalType() != btCollisionObject::CO_GHOST_OBJECT
        && ClosestRayResultCallBack.m_collisionObject->getActivationState() != 4) {

		btVector3 hitLoc = ClosestRayResultCallBack.m_hitPointWorld;

		//If the camera is blocked, the new camera is set to where the collison happened.
		cameraPosition = Rally::Vector3(hitLoc.getX(), hitLoc.getY(), hitLoc.getZ());
	}

    camera->setPosition(cameraPosition);
	camera->lookAt(position);

    // This is a bit of a temporary hack... It is laggy though...
    /*Rally::Vector3 lookVector = (Rally::Vector3(255.0f, 12.0f, 240.0f) - Rally::Vector3(255.0f, 12.0f, 239.0f))*
        (cameraPosition - Rally::Vector3(86.0f, 12.0f, -134.0f)).length();
	tunnelPortalView.moveCamera(
        Rally::Vector3(255.0f, 12.0f, 240.0f) + lookVector, // position
        Rally::Vector3(255.0f, 12.0f, 239.0f) + lookVector); // look at
    tunnelPortalView.takeSnapshot();*/
}

void SceneView::updateRemoteCars() {
    for(std::map<int, Rally::View::RemoteCarView>::iterator carViewIterator = remoteCarViews.begin();
            carViewIterator != remoteCarViews.end();
            ++carViewIterator) {
        carViewIterator->second.updateWithRemoteCar();
    }
}

void SceneView::updateCheckPoints() {
	//goalView.update();
}

void SceneView::remoteCarUpdated(int carId, const Rally::Model::RemoteCar& remoteCar, bool carTypeChanged) {
    std::map<int, Rally::View::RemoteCarView>::iterator found = remoteCarViews.find(carId);

    // Lazily construct if not found
    if(found == remoteCarViews.end()) {
        found = remoteCarViews.insert(std::map<int, Rally::View::RemoteCarView>::value_type(carId,
            Rally::View::RemoteCarView(remoteCar))).first;
        std::ostringstream carNameStream;
        carNameStream << "RemoteCar_" << carId;
        std::string carName = carNameStream.str();

        found->second.attachTo(sceneManager, carName);
    }

    // We don't really update the car here, as it has to be done every frame for the interpolation.

    found->second.changeCar(remoteCar.getCarType());
}

void SceneView::remoteCarRemoved(int carId, const Rally::Model::RemoteCar& remoteCar) {
    remoteCarViews.erase(carId);
}

void SceneView::toggleDebugDraw() {
    debugDrawEnabled = !debugDrawEnabled;
}

void SceneView::toggleReflections() {
    playerCarView.setReflectionsOn(!playerCarView.isReflectionsOn());
}

void SceneView::togglePostProcessing() {
    postProcessingEnabled = !postProcessingEnabled;

    if(postProcessingEnabled) {
        // TODO: Fix so that setEnabled works, can't be that hard...
        /*gbufferView.setEnabled(true);
        ssaoView.setEnabled(true);
        bloomView.setEnabled(true);*/
        gbufferView.attachTo(viewport);
        gbufferView.setEnabled(true);

        ssaoView.attachTo(viewport, &world.getPlayerCar());
        ssaoView.setEnabled(true);

        bloomView.attachTo(viewport, &world.getPlayerCar());
        bloomView.setEnabled(true);

        motionBlurView.attachTo(viewport, &world.getPlayerCar());
        motionBlurView.setEnabled(true);
    } else {
        motionBlurView.detach();
        bloomView.detach();
        ssaoView.detach();
        gbufferView.detach();
        /*bloomView.setEnabled(false);
        ssaoView.setEnabled(false);
        gbufferView.setEnabled(false);*/
    }
}

void SceneView::updateParticles(){
	bool enabled[4] = {false, false, false, false};
	Rally::Vector3 positions[4];

	if(world.getPlayerCar().getPhysicsCar().getRightBackWheelTraction() < 0.2){
		positions[0] = world.getPlayerCar().getPhysicsCar().getRightBackWheelOrigin();
		enabled[0] = true;
	}

	if(world.getPlayerCar().getPhysicsCar().getRightFrontWheelTraction() < 0.2){
		positions[1] = world.getPlayerCar().getPhysicsCar().getRightFrontWheelOrigin();
		enabled[1] = true;
	}

	if(world.getPlayerCar().getPhysicsCar().getLeftBackWheelTraction() < 0.2){
		positions[2] = world.getPlayerCar().getPhysicsCar().getLeftBackWheelOrigin();
		enabled[2] = true;
	}

	if(world.getPlayerCar().getPhysicsCar().getLeftFrontWheelTraction() < 0.2){
		positions[3] = world.getPlayerCar().getPhysicsCar().getLeftFrontWheelOrigin();
		enabled[3] = true;
	}

	playerCarView.enableWheelParticles(enabled, positions);

}
<|endoftext|>


<commit_before>/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#include <stdarg.h>
#include "SkOSMenu.h"
#include "SkThread.h"

static int gOSMenuCmd = 7000;

SkOSMenu::SkOSMenu(const char title[]) {
	fTitle.set(title);
}

SkOSMenu::~SkOSMenu() {
    this->reset();
}

void SkOSMenu::reset() {
    fItems.deleteAll();
    fTitle.reset();
}

void SkOSMenu::assignKeyEquivalentToItem(int itemID, SkUnichar key) {
    for (int i = 0; i < fItems.count(); ++i) {
        if (itemID == fItems[i]->getID())
            fItems[i]->setKeyEquivalent(key);
    }
}

bool SkOSMenu::handleKeyEquivalent(SkUnichar key) {
    int value = 0, size = 0;
    bool state;
    SkOSMenu::TriState tristate;
    for (int i = 0; i < fItems.count(); ++i) {
        Item* item = fItems[i];
        if (item->getKeyEquivalent()== key) {
            SkString list;
            switch (item->getType()) {
                case kList_Type:
                    SkOSMenu::FindListItemCount(item->getEvent(), &size);
                    SkOSMenu::FindListIndex(item->getEvent(), item->getSlotName(), &value);
                    value = (value + 1) % size;
                    item->postEventWithInt(value);
                    break;
                case kSwitch_Type:
                    SkOSMenu::FindSwitchState(item->getEvent(), item->getSlotName(), &state);
                    item->postEventWithBool(!state);
                    break;
                case kTriState_Type:
                    SkOSMenu::FindTriState(item->getEvent(), item->getSlotName(), &tristate);
                    if (kOnState == tristate)
                        tristate = kMixedState;
                    else
                        tristate = (SkOSMenu::TriState)((int)tristate + 1);
                    item->postEventWithInt(tristate);
                    break;
                case kAction_Type:
                case kCustom_Type:
                case kSlider_Type:
                case kTextField_Type:
                default:
                    item->postEvent();
                    break;
            }
            return true;
        }
    }
    return false;
}

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

SkOSMenu::Item::Item(const char label[], SkOSMenu::Type type,
                     const char slotName[], SkEvent* evt) {
    fLabel.set(label);
    fSlotName.set(slotName);
    fType = type;
    fEvent = evt;
    fKey = 0;
    fID = sk_atomic_inc(&gOSMenuCmd);
}

void SkOSMenu::Item::postEventWithBool(bool value) const {
    SkASSERT(SkOSMenu::kSwitch_Type == fType);
    fEvent->setBool(fSlotName.c_str(), value);
    this->postEvent();
}

void SkOSMenu::Item::postEventWithScalar(SkScalar value) const {
    SkASSERT(SkOSMenu::kSlider_Type == fType);
    fEvent->setScalar(fSlotName.c_str(), value);
    this->postEvent();
}

void SkOSMenu::Item::postEventWithInt(int value) const {
    SkASSERT(SkOSMenu::kList_Type == fType || SkOSMenu::kTriState_Type == fType);
    fEvent->setS32(fSlotName.c_str(), value);
    this->postEvent();
}

void SkOSMenu::Item::postEventWithString(const char value[]) const {
    SkASSERT(SkOSMenu::kTextField_Type == fType);
    fEvent->setString(fSlotName.c_str(), value);
    this->postEvent();
}

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

static const char* gMenuEventType = "SkOSMenuEventType";
static const char* gSlider_Min_Scalar = "SkOSMenuSlider_Min";
static const char* gSlider_Max_Scalar = "SkOSMenuSlider_Max";
static const char* gDelimiter = "|";
static const char* gList_Items_Str = "SkOSMenuList_Items";
static const char* gList_ItemCount_S32 = "SkOSMenuList_ItemCount";

int SkOSMenu::appendItem(const char label[], Type type, const char slotName[],
                         SkEvent* evt) {
    SkOSMenu::Item* item = new Item(label, type, slotName, evt);
    fItems.append(1, &item);
    return item->getID();
}

int SkOSMenu::appendAction(const char label[], SkEventSinkID target) {
    SkEvent* evt = new SkEvent(gMenuEventType, target);
    //Store label in event so it can be used to identify the action later
    evt->setString(label, label);
    return appendItem(label, SkOSMenu::kAction_Type, "", evt);
}

int SkOSMenu::appendList(const char label[], const char slotName[],
                         SkEventSinkID target, int index, const char option[], ...) {
    SkEvent* evt = new SkEvent(gMenuEventType, target);
    va_list args;
    if (option) {
        SkString str(option);
        va_start(args, option);
        int count = 1;
        for (const char* arg = va_arg(args, const char*); arg != NULL; arg = va_arg(args, const char*)) {
            str += gDelimiter;
            str += arg;
            ++count;
        }
        va_end(args);
        evt->setString(gList_Items_Str, str);
        evt->setS32(gList_ItemCount_S32, count);
        evt->setS32(slotName, index);
    }
    return appendItem(label, SkOSMenu::kList_Type, slotName, evt);
}

int SkOSMenu::appendSlider(const char label[], const char slotName[],
                           SkEventSinkID target, SkScalar min, SkScalar max,
                           SkScalar defaultValue) {
    SkEvent* evt = new SkEvent(gMenuEventType, target);
    evt->setScalar(gSlider_Min_Scalar, min);
    evt->setScalar(gSlider_Max_Scalar, max);
    evt->setScalar(slotName, defaultValue);
    return appendItem(label, SkOSMenu::kSlider_Type, slotName, evt);
}

int SkOSMenu::appendSwitch(const char label[], const char slotName[],
                           SkEventSinkID target, bool defaultState) {
    SkEvent* evt = new SkEvent(gMenuEventType, target);
    evt->setBool(slotName, defaultState);
    return appendItem(label, SkOSMenu::kSwitch_Type, slotName, evt);
}

int SkOSMenu::appendTriState(const char label[], const char slotName[],
                             SkEventSinkID target, SkOSMenu::TriState defaultState) {
    SkEvent* evt = new SkEvent(gMenuEventType, target);
    evt->setS32(slotName, defaultState);
    return appendItem(label, SkOSMenu::kTriState_Type, slotName, evt);
}

int SkOSMenu::appendTextField(const char label[], const char slotName[],
                              SkEventSinkID target, const char placeholder[]) {
    SkEvent* evt = new SkEvent(gMenuEventType, target);
    evt->setString(slotName, placeholder);
    return appendItem(label, SkOSMenu::kTextField_Type, slotName, evt);
}

bool SkOSMenu::FindListItemCount(const SkEvent* evt, int* count) {
    return evt->isType(gMenuEventType) && evt->findS32(gList_ItemCount_S32, count);
}

bool SkOSMenu::FindListItems(const SkEvent* evt, SkString items[]) {
    if (evt->isType(gMenuEventType) && NULL != items) {
        const char* text = evt->findString(gList_Items_Str);
        char temp[strlen(text)];
        memcpy(temp, text, strlen(text) + 1); //make sure to copy the null terminator
        char* token = strtok(temp, gDelimiter);
        int index = 0;
        while (token != NULL) {
            items[index].set(token, strlen(token));
            token = strtok (NULL, gDelimiter);
            ++index;
        }
        return true;
    }
    return false;
}

bool SkOSMenu::FindSliderMin(const SkEvent* evt, SkScalar* min) {
    return evt->isType(gMenuEventType) && evt->findScalar(gSlider_Min_Scalar, min);
}

bool SkOSMenu::FindSliderMax(const SkEvent* evt, SkScalar* max) {
    return evt->isType(gMenuEventType) && evt->findScalar(gSlider_Max_Scalar, max);
}

bool SkOSMenu::FindAction(const SkEvent* evt, const char label[]) {
    return evt->isType(gMenuEventType) && evt->findString(label);
}

bool SkOSMenu::FindListIndex(const SkEvent* evt, const char slotName[], int* value) {
    return evt->isType(gMenuEventType) && evt->findS32(slotName, value);
}

bool SkOSMenu::FindSliderValue(const SkEvent* evt, const char slotName[], SkScalar* value) {
    return evt->isType(gMenuEventType) && evt->findScalar(slotName, value);
}

bool SkOSMenu::FindSwitchState(const SkEvent* evt, const char slotName[], bool* value) {
    return evt->isType(gMenuEventType) && evt->findBool(slotName, value);
}

bool SkOSMenu::FindTriState(const SkEvent* evt, const char slotName[], SkOSMenu::TriState* value) {
    return evt->isType(gMenuEventType) && evt->findS32(slotName, (int*)value);
}

bool SkOSMenu::FindText(const SkEvent* evt, const char slotName[], SkString* value) {
    if (evt->isType(gMenuEventType)) {
        const char* text = evt->findString(slotName);
        if (!text || !*text)
            return false;
        else {
            value->set(text);
            return true;
        }
    }
    return false;
}
<commit_msg>Fixed error in SkOSMenu<commit_after>/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#include <stdarg.h>
#include "SkOSMenu.h"
#include "SkThread.h"

static int gOSMenuCmd = 7000;

SkOSMenu::SkOSMenu(const char title[]) {
	fTitle.set(title);
}

SkOSMenu::~SkOSMenu() {
    this->reset();
}

void SkOSMenu::reset() {
    fItems.deleteAll();
    fTitle.reset();
}

void SkOSMenu::assignKeyEquivalentToItem(int itemID, SkUnichar key) {
    for (int i = 0; i < fItems.count(); ++i) {
        if (itemID == fItems[i]->getID())
            fItems[i]->setKeyEquivalent(key);
    }
}

bool SkOSMenu::handleKeyEquivalent(SkUnichar key) {
    int value = 0, size = 0;
    bool state;
    SkOSMenu::TriState tristate;
    for (int i = 0; i < fItems.count(); ++i) {
        Item* item = fItems[i];
        if (item->getKeyEquivalent()== key) {
            SkString list;
            switch (item->getType()) {
                case kList_Type:
                    SkOSMenu::FindListItemCount(item->getEvent(), &size);
                    SkOSMenu::FindListIndex(item->getEvent(), item->getSlotName(), &value);
                    value = (value + 1) % size;
                    item->postEventWithInt(value);
                    break;
                case kSwitch_Type:
                    SkOSMenu::FindSwitchState(item->getEvent(), item->getSlotName(), &state);
                    item->postEventWithBool(!state);
                    break;
                case kTriState_Type:
                    SkOSMenu::FindTriState(item->getEvent(), item->getSlotName(), &tristate);
                    if (kOnState == tristate)
                        tristate = kMixedState;
                    else
                        tristate = (SkOSMenu::TriState)((int)tristate + 1);
                    item->postEventWithInt(tristate);
                    break;
                case kAction_Type:
                case kCustom_Type:
                case kSlider_Type:
                case kTextField_Type:
                default:
                    item->postEvent();
                    break;
            }
            return true;
        }
    }
    return false;
}

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

SkOSMenu::Item::Item(const char label[], SkOSMenu::Type type,
                     const char slotName[], SkEvent* evt) {
    fLabel.set(label);
    fSlotName.set(slotName);
    fType = type;
    fEvent = evt;
    fKey = 0;
    fID = sk_atomic_inc(&gOSMenuCmd);
}

void SkOSMenu::Item::postEventWithBool(bool value) const {
    SkASSERT(SkOSMenu::kSwitch_Type == fType);
    fEvent->setBool(fSlotName.c_str(), value);
    this->postEvent();
}

void SkOSMenu::Item::postEventWithScalar(SkScalar value) const {
    SkASSERT(SkOSMenu::kSlider_Type == fType);
    fEvent->setScalar(fSlotName.c_str(), value);
    this->postEvent();
}

void SkOSMenu::Item::postEventWithInt(int value) const {
    SkASSERT(SkOSMenu::kList_Type == fType || SkOSMenu::kTriState_Type == fType);
    fEvent->setS32(fSlotName.c_str(), value);
    this->postEvent();
}

void SkOSMenu::Item::postEventWithString(const char value[]) const {
    SkASSERT(SkOSMenu::kTextField_Type == fType);
    fEvent->setString(fSlotName.c_str(), value);
    this->postEvent();
}

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

static const char* gMenuEventType = "SkOSMenuEventType";
static const char* gSlider_Min_Scalar = "SkOSMenuSlider_Min";
static const char* gSlider_Max_Scalar = "SkOSMenuSlider_Max";
static const char* gDelimiter = "|";
static const char* gList_Items_Str = "SkOSMenuList_Items";
static const char* gList_ItemCount_S32 = "SkOSMenuList_ItemCount";

int SkOSMenu::appendItem(const char label[], Type type, const char slotName[],
                         SkEvent* evt) {
    SkOSMenu::Item* item = new Item(label, type, slotName, evt);
    fItems.append(1, &item);
    return item->getID();
}

int SkOSMenu::appendAction(const char label[], SkEventSinkID target) {
    SkEvent* evt = new SkEvent(gMenuEventType, target);
    //Store label in event so it can be used to identify the action later
    evt->setString(label, label);
    return appendItem(label, SkOSMenu::kAction_Type, "", evt);
}

int SkOSMenu::appendList(const char label[], const char slotName[],
                         SkEventSinkID target, int index, const char option[], ...) {
    SkEvent* evt = new SkEvent(gMenuEventType, target);
    va_list args;
    if (option) {
        SkString str(option);
        va_start(args, option);
        int count = 1;
        for (const char* arg = va_arg(args, const char*); arg != NULL; arg = va_arg(args, const char*)) {
            str += gDelimiter;
            str += arg;
            ++count;
        }
        va_end(args);
        evt->setString(gList_Items_Str, str);
        evt->setS32(gList_ItemCount_S32, count);
        evt->setS32(slotName, index);
    }
    return appendItem(label, SkOSMenu::kList_Type, slotName, evt);
}

int SkOSMenu::appendSlider(const char label[], const char slotName[],
                           SkEventSinkID target, SkScalar min, SkScalar max,
                           SkScalar defaultValue) {
    SkEvent* evt = new SkEvent(gMenuEventType, target);
    evt->setScalar(gSlider_Min_Scalar, min);
    evt->setScalar(gSlider_Max_Scalar, max);
    evt->setScalar(slotName, defaultValue);
    return appendItem(label, SkOSMenu::kSlider_Type, slotName, evt);
}

int SkOSMenu::appendSwitch(const char label[], const char slotName[],
                           SkEventSinkID target, bool defaultState) {
    SkEvent* evt = new SkEvent(gMenuEventType, target);
    evt->setBool(slotName, defaultState);
    return appendItem(label, SkOSMenu::kSwitch_Type, slotName, evt);
}

int SkOSMenu::appendTriState(const char label[], const char slotName[],
                             SkEventSinkID target, SkOSMenu::TriState defaultState) {
    SkEvent* evt = new SkEvent(gMenuEventType, target);
    evt->setS32(slotName, defaultState);
    return appendItem(label, SkOSMenu::kTriState_Type, slotName, evt);
}

int SkOSMenu::appendTextField(const char label[], const char slotName[],
                              SkEventSinkID target, const char placeholder[]) {
    SkEvent* evt = new SkEvent(gMenuEventType, target);
    evt->setString(slotName, placeholder);
    return appendItem(label, SkOSMenu::kTextField_Type, slotName, evt);
}

bool SkOSMenu::FindListItemCount(const SkEvent* evt, int* count) {
    return evt->isType(gMenuEventType) && evt->findS32(gList_ItemCount_S32, count);
}

bool SkOSMenu::FindListItems(const SkEvent* evt, SkString items[]) {
    if (evt->isType(gMenuEventType) && NULL != items) {
        const char* text = evt->findString(gList_Items_Str);
        if (text != NULL) {
            SkString temp(text);
            char* token = strtok((char*)temp.c_str(), gDelimiter);
            int index = 0;
            while (token != NULL) {
                items[index].set(token, strlen(token));
                token = strtok (NULL, gDelimiter);
                ++index;
            }
        }
        return true;
    }
    return false;
}

bool SkOSMenu::FindSliderMin(const SkEvent* evt, SkScalar* min) {
    return evt->isType(gMenuEventType) && evt->findScalar(gSlider_Min_Scalar, min);
}

bool SkOSMenu::FindSliderMax(const SkEvent* evt, SkScalar* max) {
    return evt->isType(gMenuEventType) && evt->findScalar(gSlider_Max_Scalar, max);
}

bool SkOSMenu::FindAction(const SkEvent* evt, const char label[]) {
    return evt->isType(gMenuEventType) && evt->findString(label);
}

bool SkOSMenu::FindListIndex(const SkEvent* evt, const char slotName[], int* value) {
    return evt->isType(gMenuEventType) && evt->findS32(slotName, value);
}

bool SkOSMenu::FindSliderValue(const SkEvent* evt, const char slotName[], SkScalar* value) {
    return evt->isType(gMenuEventType) && evt->findScalar(slotName, value);
}

bool SkOSMenu::FindSwitchState(const SkEvent* evt, const char slotName[], bool* value) {
    return evt->isType(gMenuEventType) && evt->findBool(slotName, value);
}

bool SkOSMenu::FindTriState(const SkEvent* evt, const char slotName[], SkOSMenu::TriState* value) {
    return evt->isType(gMenuEventType) && evt->findS32(slotName, (int*)value);
}

bool SkOSMenu::FindText(const SkEvent* evt, const char slotName[], SkString* value) {
    if (evt->isType(gMenuEventType)) {
        const char* text = evt->findString(slotName);
        if (!text || !*text)
            return false;
        else {
            value->set(text);
            return true;
        }
    }
    return false;
}
<|endoftext|>


<commit_before>/*
 * libaps.cpp
 *
 * A thin wrapper around APSRack to allow calling from Matlab without name-mangling.
 *  Created on: Jun 25, 2012
 *      Author: qlab
 */

#include "headings.h"
#include "libaps.h"

APSRack APSRack_;

#ifdef __cplusplus
extern "C" {
#endif

int init(){

	APSRack_.init();

	return APS_OK;
}

int get_numDevices(){
	return APSRack_.get_num_devices();
}

void get_deviceSerial(int deviceID, char* deviceSerial){
	//Assumes sufficient memory has been allocated
	string serialStr = APSRack_.get_deviceSerial(deviceID);
	size_t strLen = serialStr.copy(deviceSerial, serialStr.size());
	deviceSerial[strLen] = '\0';
}

//Connect to a device specified by ID
int connect_by_ID(int deviceID){
	return APSRack_.connect(deviceID);
}

//Connect to a device specified by serial number string
//Assumes null-terminated deviceSerial
int connect_by_serial(char * deviceSerial){
	return APSRack_.connect(string(deviceSerial));
}

int disconnect_by_ID(int deviceID){
	return APSRack_.disconnect(deviceID);
}

//Assumes a null-terminated deviceSerial
int disconnect_by_serial(char * deviceSerial){
	return APSRack_.disconnect(string(deviceSerial));
}

int serial2ID(char * deviceSerial){
	return APSRack_.serial2dev[string(deviceSerial)];
}

//Initialize an APS unit
//Assumes null-terminated bitFile
int initAPS(int deviceID, char * bitFile, int forceReload){
	try {
		return APSRack_.initAPS(deviceID, string(bitFile), forceReload);
	} catch (std::exception& e) {
		string error = e.what();
		if (error.compare("Unable to open bitfile.") == 0) {
			return APS_FILE_ERROR;
		} else {
			return APS_UNKNOWN_ERROR;
		}
	}

}

int read_bitfile_version(int deviceID) {
	return APSRack_.read_bitfile_version(deviceID);
}

int set_sampleRate(int deviceID, int freq){
	return APSRack_.set_sampleRate(deviceID, freq);
}

int get_sampleRate(int deviceID){
	return APSRack_.get_sampleRate(deviceID);
}

//Load the waveform library as floats
int set_waveform_float(int deviceID, int channelNum, float* data, int numPts){
	return APSRack_.set_waveform(deviceID, channelNum, vector<float>(data, data+numPts));
}

//Load the waveform library as int16
int set_waveform_int(int deviceID, int channelNum, short* data, int numPts){
	return APSRack_.set_waveform(deviceID, channelNum, vector<short>(data, data+numPts));
}

int load_sequence_file(int deviceID, const char * seqFile){
	try {
		return APSRack_.load_sequence_file(deviceID, string(seqFile));
	} catch (...) {
		return APS_UNKNOWN_ERROR;
	}
	// should not reach this point
	return APS_UNKNOWN_ERROR;
}

int clear_channel_data(int deviceID) {
	return APSRack_.clear_channel_data(deviceID);
}

int run(int deviceID) {
	return APSRack_.run(deviceID);
}

int stop(int deviceID) {
	return APSRack_.stop(deviceID);
}

int get_running(int deviceID){
	return APSRack_.get_running(deviceID);
}

//Expects a null-terminated character array
int set_log(char * fileNameArr) {

	string fileName(fileNameArr);
	if (fileName.compare("stdout") == 0){
		return APSRack_.set_log(stdout);
	}
	else if (fileName.compare("stderr") == 0){
		return APSRack_.set_log(stderr);
	}
	else{

		FILE* pFile = fopen(fileName.c_str(), "a");
		if (!pFile) {
			return APS_FILE_ERROR;
		}

		return APSRack_.set_log(pFile);
	}
}

int set_logging_level(int logLevel){
	return APSRack_.set_logging_level(logLevel);
}

int set_trigger_source(int deviceID, int triggerSource) {
	return APSRack_.set_trigger_source(deviceID, TRIGGERSOURCE(triggerSource));
}

int get_trigger_source(int deviceID) {
	return int(APSRack_.get_trigger_source(deviceID));
}

int set_trigger_interval(int deviceID, double interval){
	return APSRack_.set_trigger_interval(deviceID, interval);
}

double get_trigger_interval(int deviceID){
	return APSRack_.get_trigger_interval(deviceID);
}

int set_miniLL_repeat(int deviceID, unsigned short repeat){
	return APSRack_.set_miniLL_repeat(deviceID, repeat);
}

int set_channel_offset(int deviceID, int channelNum, float offset){
	return APSRack_.set_channel_offset(deviceID, channelNum, offset);
}
int set_channel_scale(int deviceID, int channelNum, float scale){
	return APSRack_.set_channel_scale(deviceID, channelNum, scale);
}
int set_channel_enabled(int deviceID, int channelNum, int enable){
	return APSRack_.set_channel_enabled(deviceID, channelNum, enable);
}

float get_channel_offset(int deviceID, int channelNum){
	return APSRack_.get_channel_offset(deviceID, channelNum);
}
float get_channel_scale(int deviceID, int channelNum){
	return APSRack_.get_channel_scale(deviceID, channelNum);
}
int get_channel_enabled(int deviceID, int channelNum){
	return APSRack_.get_channel_enabled(deviceID, channelNum);
}

int set_LL_data_IQ(int deviceID, int channelNum, int length, unsigned short* addr, unsigned short* count,
					unsigned short* trigger1, unsigned short * trigger2, unsigned short* repeat){
	//Convert data pointers to vectors and passed through
	return APSRack_.set_LL_data(deviceID, channelNum, WordVec(addr, addr+length), WordVec(count, count+length),
			WordVec(trigger1, trigger1+length), WordVec(trigger2, trigger2+length), WordVec(repeat, repeat+length));
}

int set_run_mode(int deviceID, int channelNum, int mode) {
	return APSRack_.set_run_mode(deviceID, channelNum, RUN_MODE(mode));
}

int set_repeat_mode(int deviceID, int channelNum, int mode) {
	return APSRack_.set_repeat_mode(deviceID, channelNum, mode);
}

int save_state_files() {
	return APSRack_.save_state_files();
}

int read_state_files() {
	return APSRack_.read_state_files();
}

int save_bulk_state_file() {
	string fileName = "";
	return APSRack_.save_bulk_state_file(fileName);
}
int read_bulk_state_file() {
	string fileName = "";
	return APSRack_.read_bulk_state_file(fileName);
}

int raw_write(int deviceID, int numBytes, UCHAR* data){
	return APSRack_.raw_write(deviceID, numBytes, data);
}

int raw_read(int deviceID, int fpga){
	return APSRack_.raw_read(deviceID, FPGASELECT(fpga));
}

int read_register(int deviceID, int fpga, int addr){
	return APSRack_.read_register(deviceID, FPGASELECT(fpga), addr);
}

int program_FPGA(int deviceID, char* bitFile, int chipSelect, int expectedVersion) {
	return APSRack_.program_FPGA(deviceID, string(bitFile), FPGASELECT(chipSelect), expectedVersion);
}

#ifdef __cplusplus
}
#endif

<commit_msg>Fix for bug where calling the matlab openBySerialNum method with a non-existant serial would open device 0 rather than reporting that the serial could not be found.<commit_after>/*
 * libaps.cpp
 *
 * A thin wrapper around APSRack to allow calling from Matlab without name-mangling.
 *  Created on: Jun 25, 2012
 *      Author: qlab
 */

#include "headings.h"
#include "libaps.h"

APSRack APSRack_;

#ifdef __cplusplus
extern "C" {
#endif

int init(){

	APSRack_.init();

	return APS_OK;
}

int get_numDevices(){
	return APSRack_.get_num_devices();
}

void get_deviceSerial(int deviceID, char* deviceSerial){
	//Assumes sufficient memory has been allocated
	string serialStr = APSRack_.get_deviceSerial(deviceID);
	size_t strLen = serialStr.copy(deviceSerial, serialStr.size());
	deviceSerial[strLen] = '\0';
}

//Connect to a device specified by ID
int connect_by_ID(int deviceID){
	return APSRack_.connect(deviceID);
}

//Connect to a device specified by serial number string
//Assumes null-terminated deviceSerial
int connect_by_serial(char * deviceSerial){
	return APSRack_.connect(string(deviceSerial));
}

int disconnect_by_ID(int deviceID){
	return APSRack_.disconnect(deviceID);
}

//Assumes a null-terminated deviceSerial
int disconnect_by_serial(char * deviceSerial){
	return APSRack_.disconnect(string(deviceSerial));
}

int serial2ID(char * deviceSerial){
	if ( !APSRack_.serial2dev.count(deviceSerial)) {
		// serial number not in map of known devices
		return -1;
	}

	return APSRack_.serial2dev[string(deviceSerial)];
}

//Initialize an APS unit
//Assumes null-terminated bitFile
int initAPS(int deviceID, char * bitFile, int forceReload){
	try {
		return APSRack_.initAPS(deviceID, string(bitFile), forceReload);
	} catch (std::exception& e) {
		string error = e.what();
		if (error.compare("Unable to open bitfile.") == 0) {
			return APS_FILE_ERROR;
		} else {
			return APS_UNKNOWN_ERROR;
		}
	}

}

int read_bitfile_version(int deviceID) {
	return APSRack_.read_bitfile_version(deviceID);
}

int set_sampleRate(int deviceID, int freq){
	return APSRack_.set_sampleRate(deviceID, freq);
}

int get_sampleRate(int deviceID){
	return APSRack_.get_sampleRate(deviceID);
}

//Load the waveform library as floats
int set_waveform_float(int deviceID, int channelNum, float* data, int numPts){
	return APSRack_.set_waveform(deviceID, channelNum, vector<float>(data, data+numPts));
}

//Load the waveform library as int16
int set_waveform_int(int deviceID, int channelNum, short* data, int numPts){
	return APSRack_.set_waveform(deviceID, channelNum, vector<short>(data, data+numPts));
}

int load_sequence_file(int deviceID, const char * seqFile){
	try {
		return APSRack_.load_sequence_file(deviceID, string(seqFile));
	} catch (...) {
		return APS_UNKNOWN_ERROR;
	}
	// should not reach this point
	return APS_UNKNOWN_ERROR;
}

int clear_channel_data(int deviceID) {
	return APSRack_.clear_channel_data(deviceID);
}

int run(int deviceID) {
	return APSRack_.run(deviceID);
}

int stop(int deviceID) {
	return APSRack_.stop(deviceID);
}

int get_running(int deviceID){
	return APSRack_.get_running(deviceID);
}

//Expects a null-terminated character array
int set_log(char * fileNameArr) {

	string fileName(fileNameArr);
	if (fileName.compare("stdout") == 0){
		return APSRack_.set_log(stdout);
	}
	else if (fileName.compare("stderr") == 0){
		return APSRack_.set_log(stderr);
	}
	else{

		FILE* pFile = fopen(fileName.c_str(), "a");
		if (!pFile) {
			return APS_FILE_ERROR;
		}

		return APSRack_.set_log(pFile);
	}
}

int set_logging_level(int logLevel){
	return APSRack_.set_logging_level(logLevel);
}

int set_trigger_source(int deviceID, int triggerSource) {
	return APSRack_.set_trigger_source(deviceID, TRIGGERSOURCE(triggerSource));
}

int get_trigger_source(int deviceID) {
	return int(APSRack_.get_trigger_source(deviceID));
}

int set_trigger_interval(int deviceID, double interval){
	return APSRack_.set_trigger_interval(deviceID, interval);
}

double get_trigger_interval(int deviceID){
	return APSRack_.get_trigger_interval(deviceID);
}

int set_miniLL_repeat(int deviceID, unsigned short repeat){
	return APSRack_.set_miniLL_repeat(deviceID, repeat);
}

int set_channel_offset(int deviceID, int channelNum, float offset){
	return APSRack_.set_channel_offset(deviceID, channelNum, offset);
}
int set_channel_scale(int deviceID, int channelNum, float scale){
	return APSRack_.set_channel_scale(deviceID, channelNum, scale);
}
int set_channel_enabled(int deviceID, int channelNum, int enable){
	return APSRack_.set_channel_enabled(deviceID, channelNum, enable);
}

float get_channel_offset(int deviceID, int channelNum){
	return APSRack_.get_channel_offset(deviceID, channelNum);
}
float get_channel_scale(int deviceID, int channelNum){
	return APSRack_.get_channel_scale(deviceID, channelNum);
}
int get_channel_enabled(int deviceID, int channelNum){
	return APSRack_.get_channel_enabled(deviceID, channelNum);
}

int set_LL_data_IQ(int deviceID, int channelNum, int length, unsigned short* addr, unsigned short* count,
					unsigned short* trigger1, unsigned short * trigger2, unsigned short* repeat){
	//Convert data pointers to vectors and passed through
	return APSRack_.set_LL_data(deviceID, channelNum, WordVec(addr, addr+length), WordVec(count, count+length),
			WordVec(trigger1, trigger1+length), WordVec(trigger2, trigger2+length), WordVec(repeat, repeat+length));
}

int set_run_mode(int deviceID, int channelNum, int mode) {
	return APSRack_.set_run_mode(deviceID, channelNum, RUN_MODE(mode));
}

int set_repeat_mode(int deviceID, int channelNum, int mode) {
	return APSRack_.set_repeat_mode(deviceID, channelNum, mode);
}

int save_state_files() {
	return APSRack_.save_state_files();
}

int read_state_files() {
	return APSRack_.read_state_files();
}

int save_bulk_state_file() {
	string fileName = "";
	return APSRack_.save_bulk_state_file(fileName);
}
int read_bulk_state_file() {
	string fileName = "";
	return APSRack_.read_bulk_state_file(fileName);
}

int raw_write(int deviceID, int numBytes, UCHAR* data){
	return APSRack_.raw_write(deviceID, numBytes, data);
}

int raw_read(int deviceID, int fpga){
	return APSRack_.raw_read(deviceID, FPGASELECT(fpga));
}

int read_register(int deviceID, int fpga, int addr){
	return APSRack_.read_register(deviceID, FPGASELECT(fpga), addr);
}

int program_FPGA(int deviceID, char* bitFile, int chipSelect, int expectedVersion) {
	return APSRack_.program_FPGA(deviceID, string(bitFile), FPGASELECT(chipSelect), expectedVersion);
}

#ifdef __cplusplus
}
#endif

<|endoftext|>


<commit_before>/***************************************************************************
                          irccontact.cpp  -  description
                             -------------------
    begin                : Wed Mar 6 2002
    copyright            : (C) 2002 by nbetcher
    email                : nbetcher@usinternet.com
 ***************************************************************************/

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

#include "irccontact.h"

#include "irc_channel_tabwidget.h"
#include "ircchatview.h"
#include "ircchatwindow.h"
#include "ircprotocol.h"
#include "ircqueryview.h"
#include "ircservercontact.h"
#include "kirc.h"
#include "kopete.h"
#include "kopetecontactlist.h"
#include "kopetemetacontact.h"
#include "tabcompleter.h"

#include <kaction.h>
#include <kconfig.h>
#include <kdebug.h>
#include <kglobal.h>
#include <kiconloader.h>
#include <klocale.h>
#include <kmessagebox.h>
#include <ksimpleconfig.h>

#include <qiconset.h>
#include <qlayout.h>
#include <qtextedit.h>
#include <qvbox.h>

IRCContact::IRCContact(const QString &server, const QString &target, unsigned int port, bool joinOnConnect, IRCServerContact *contact, KopeteMetaContact *parent, QString &protocolID)
	: KopeteContact(protocolID, parent),
	  m_pActionCollection(new KActionCollection(this, "IRCActionCollection"))
{
	contactOnList = false;

	if (!init(server, port,target,contact,joinOnConnect))
	{
		delete this;
		return;
	}

}

IRCContact::IRCContact(const QString &server, const QString &target, unsigned int port,
		       IRCServerContact *contact, const QStringList /*pendingMessage*/,
		       KopeteMetaContact *parent, QString &protocolID)
	: KopeteContact(protocolID, parent),
	  m_pActionCollection(new KActionCollection(this, "IRCActionCollection"))
{
	contactOnList = false;

	if (!init(server,  port,target,contact,true))
	{
		delete this;
		return;
	}

	//TODO: show pending messages
}

bool IRCContact::init(const QString &server, unsigned int port,const QString &target, IRCServerContact *contact,bool joinOnConnect)
{
	m_engine = contact->engine();
	m_requestedQuit = false;
	added = false;

	KGlobal::config()->setGroup("IRC");
	QString newServer;

	if (server.isEmpty() == true)
	{
		newServer = KGlobal::config()->readEntry("Server", "");
		m_serverName = newServer;
	}
	else
	{
		m_serverName = server;
	}
	if (port == 0)
	{
		port = KGlobal::config()->readEntry("Port", "6667").toUInt();
	}
	QString user = "kopeteuser";
	QString nick = KGlobal::config()->readEntry("Nickname", "KopeteUser");

	m_serverContact = contact;
	m_targetName = target;
	m_port = port;
	m_username = user;
	m_nickname = nick;
	mJoinOnConnect = joinOnConnect;

	// Just to be safe!
	mTabPage = 0L;
	queryView = 0L;
	chatView = 0L;

//	parent->setDisplayName(m_serverName, false);
//	parent->addContact( this, QStringList() );
	setDisplayName(target);

	if (m_serverContact->activeContacts().contains(m_targetName.lower()) > 0)
	{
		return false;
	}
	m_serverContact->activeContacts().append(m_targetName.lower());
	added = true;
	connect(m_serverContact->engine(), SIGNAL(successfulQuit()), this, SLOT(unloading()));
	connect(m_serverContact->engine(), SIGNAL(incomingPartedChannel(const QString &, const QString &, const QString &)), this, SLOT(slotPartedChannel(const QString &, const QString &, const QString &)));
	connect(m_serverContact->engine(), SIGNAL(incomingKick(const QString &, const QString &, const QString &, const QString &)), this, SLOT(slotUserKicked(const QString &, const QString &, const QString &, const QString &)));
	connect(m_engine, SIGNAL(incomingPrivMessage(const QString &, const QString &, const QString &)), this, SLOT(incomingPrivMessage(const QString &, const QString &, const QString &)));
	connect(m_engine, SIGNAL(incomingPrivAction(const QString &, const QString &, const QString &)), this, SLOT(incomingPrivAction(const QString &, const QString &, const QString &)));

	connect(m_serverContact->engine(), SIGNAL(connectionClosed()), this, SLOT(unloading()));
	if (mJoinOnConnect == true)
	{
		if (m_serverContact->engine()->isLoggedIn() == true)
		{
			joinNow();
		}
		else
		{
			QObject::connect(m_serverContact->engine(), SIGNAL(connectedToServer()), this, SLOT(joinNow()));
		}
	}

	return true;
}

bool IRCContact::isChannel() const
{
	static QString const sChannelChars(QString::fromLatin1("#!&+"));

	return ((m_targetName.isEmpty() == false)
		&& (sChannelChars.contains(m_targetName[0]) > 0));
}

KopeteContact::ContactStatus IRCContact::status() const
{
	if (m_serverContact->engine()->isLoggedIn())
	{
		return KopeteContact::Online;
	}
	return KopeteContact::Offline;
}

QString IRCContact::statusIcon() const
{
	if (m_serverContact->engine()->isLoggedIn())
	{
		return "connect_established";
	} else {
		return "connect_no";
	}
}

void IRCContact::incomingPrivMessage(const QString &originating, const QString &/*target_dest*/, const QString &/*message*/)
{
	//kdDebug()<< "IRCContact::incomingPrivMessage :"<<target <<endl;
	QString target= originating.section('!', 0, 0);

	if (m_targetName.lower() == target.lower())
	{
		if (mTabPage == 0)
		{
			joinNow();
		}
		if(m_targetName!=target)
		{
			//update case of the displayName
			m_targetName=target;
			setDisplayName(target);
		}
	}
}

void IRCContact::incomingPrivAction(const QString &originating, const QString &/*target_dest*/, const QString &/*message*/)
{
	QString target= originating.section('!', 0, 0);

	if (m_targetName.lower() == target.lower())
	{
		if (mTabPage == 0)
		{
			joinNow();
		}
	}
}

void IRCContact::slotOpen()
{
	if (!m_serverContact->engine()->isLoggedIn())
	{
		slotOpenConnect();
	} else {
		if (m_serverContact->chatWindow() != 0)
		{
			m_serverContact->chatWindow()->show();
		}
		joinNow();
	}
}

void IRCContact::slotOpenConnect()
{
	if (!m_serverContact->engine()->isLoggedIn())
	{
		QObject::disconnect(m_serverContact->engine(), SIGNAL(connectedToServer()), this, SLOT(joinNow()));
		QObject::connect(m_serverContact->engine(), SIGNAL(connectedToServer()), this, SLOT(joinNow()));
		m_serverContact->slotConnectNow();
		m_serverContact->chatWindow()->show();
	} else {
		slotOpen();
	}
}

KActionCollection* IRCContact::customContextMenuActions()
{
	m_pActionCollection->clear();

	if (isChannel())
	{
		if (mTabPage)
		{
			new KAction(i18n("Part"), KShortcut(),
				    this, SLOT(slotPart()),
				    m_pActionCollection, "part");
		}
// TODO:	popup->insertItem("Hop (Part and Re-join)", this, SLOT(slotHop()));
	}
	else
	{
		if (mTabPage)
		{
			new KAction(i18n("Close"), KShortcut(),
				    this, SLOT(unloading()),
				    m_pActionCollection, "close");
		}
	}
	if (!mTabPage)
	{
		if (m_serverContact->engine()->isLoggedIn())
		{
			QString const sLabel(isChannel()
					     ? i18n("Join")
					     : i18n("Open"));
			new KAction(sLabel, KShortcut(),
				    this, SLOT(slotOpen()),
				    m_pActionCollection, "open");
		}
		else
		{
			QString const sLabel(isChannel()
					     ? i18n("Connect && Join")
					     : i18n("Connect && Open"));
			new KAction(sLabel, KShortcut(),
				    this, SLOT(slotOpen()),
				    m_pActionCollection, "open_connect");
		}
	}

	return m_pActionCollection;
}

void IRCContact::execute()
{
	if (m_serverContact->chatWindow() != 0)
	{
		m_serverContact->chatWindow()->raise();
		if (mTabPage !=0)
		{
			m_serverContact->chatWindow()->mTabWidget->showPage(mTabPage);
		}
	}
	if (chatView !=0)
	{
		chatView->messageEdit()->setFocus();
		return;
	}
	if (queryView !=0)
	{
		queryView->messageEdit()->setFocus();
		return;
	}
}

void IRCContact::slotDeleteContact()
{
	if (KMessageBox::warningYesNo(qApp->mainWidget(),
				      i18n("<qt>Are you sure you want to remove %1 from your contact list?</qt>").arg(displayName()),
				      i18n("Confirmation")) == KMessageBox::Yes)
	{
		if (isChannel())
		{
			slotPart();
		}
		if (mTabPage !=0)
		{
			m_serverContact->chatWindow()->mTabWidget->removePage(mTabPage);
			delete mTabPage;
			mTabPage = 0L;
			queryView = 0L;
			chatView = 0L;
		}
		delete this;
	}
}

void IRCContact::slotPart()
{
	if (chatView != 0)
	{
		QColor color(175, 8, 8);
		QString partWarning = "Attempting to part channel. If this takes an unusual amount of time, please click the close button on this window again, or right click on the contact in the Kopete window and click \"Part\" again.
");
		if (isChannel())
		{
			if (chatView !=0)
			{
				chatView->messageView()->append(partWarning);
				chatView->messageView()->scrollToBottom();
			}
			m_waitingPart = true;
			m_serverContact->engine()->partChannel(m_targetName ,QString("Using Kopete IRC Plugin"));
		}
	}
}

void IRCContact::slotPartedChannel(const QString &originating, const QString &channel, const QString &)
{
	if (m_targetName.lower() == channel.lower() && originating.section('!', 0, 0).lower() == m_engine->nickName().lower())
	{
		unloading();
	}
}

void IRCContact::slotUserKicked(const QString &user, const QString &channel,
				const QString &/*by*/, const QString &/*reason*/)
{
	if (m_targetName.lower() == channel.lower() && user.lower() == m_engine->nickName().lower())
	{
		unloading();
	}
}

IRCContact::~IRCContact()
{
	if (added && !contactOnList)
	{
		m_serverContact->activeContacts().remove(m_targetName.lower());
	}
}

void IRCContact::unloading()
{
	if (mTabPage !=0)
	{
		kdDebug()<< "IRCContact::unloading()" <<endl;
		if (m_serverContact->closing() == false)
		{
			delete mTabPage;
		}
		mTabPage = 0L;
		chatView = 0L;
		queryView = 0L;
		/*if (!contactOnList)
		{
			delete this;
		} */
	}
	emit statusChanged();
	emit statusChanged(this, Offline);
}

void IRCContact::joinNow()
{
	kdDebug() << "IRC Plugin: IRCContact::joinNow() creating mTabPage!" << endl;
	mTabPage = new QVBox(m_serverContact->chatWindow()->mTabWidget);
	if (isChannel())
	{
		chatView = new IRCChatView(m_serverName, m_targetName, this, mTabPage);
		m_serverContact->chatWindow()->mTabWidget->addTab(mTabPage, SmallIconSet("irc_privmsg"), m_targetName);
	} else {
		queryView = new IRCQueryView(m_serverName, m_targetName, m_serverContact, mTabPage, this);
		m_serverContact->chatWindow()->mTabWidget->addTab(mTabPage, SmallIconSet("irc_querymsg"), m_targetName);
	}

	m_serverContact->chatWindow()->show();

	KGlobal::config()->setGroup("IRC");
	bool minimize = KGlobal::config()->readBoolEntry("MinimizeNewQueries", false);
	if (isChannel())
	{
		m_serverContact->chatWindow()->mTabWidget->showPage(mTabPage);
	} else {
		if (!minimize)
		{
			m_serverContact->chatWindow()->mTabWidget->showPage(mTabPage);
		}
	}
	emit statusChanged();
	emit statusChanged(this, Online);

}

QString IRCContact::id() const
{
	return QString(m_targetName+"@"+m_serverName).lower();
}

#include "irccontact.moc"
/*
 * Local variables:
 * c-indentation-style: k&r
 * c-basic-offset: 8
 * indent-tabs-mode: t
 * End:
 */
// vim: set noet ts=4 sts=4 sw=4:

<commit_msg>Click on a irc contact start a chat<commit_after>/***************************************************************************
                          irccontact.cpp  -  description
                             -------------------
    begin                : Wed Mar 6 2002
    copyright            : (C) 2002 by nbetcher
    email                : nbetcher@usinternet.com
 ***************************************************************************/

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

#include "irccontact.h"

#include "irc_channel_tabwidget.h"
#include "ircchatview.h"
#include "ircchatwindow.h"
#include "ircprotocol.h"
#include "ircqueryview.h"
#include "ircservercontact.h"
#include "kirc.h"
#include "kopete.h"
#include "kopetecontactlist.h"
#include "kopetemetacontact.h"
#include "tabcompleter.h"

#include <kaction.h>
#include <kconfig.h>
#include <kdebug.h>
#include <kglobal.h>
#include <kiconloader.h>
#include <klocale.h>
#include <kmessagebox.h>
#include <ksimpleconfig.h>

#include <qiconset.h>
#include <qlayout.h>
#include <qtextedit.h>
#include <qvbox.h>

IRCContact::IRCContact(const QString &server, const QString &target, unsigned int port, bool joinOnConnect, IRCServerContact *contact, KopeteMetaContact *parent, QString &protocolID)
	: KopeteContact(protocolID, parent),
	  m_pActionCollection(new KActionCollection(this, "IRCActionCollection"))
{
	contactOnList = false;

	if (!init(server, port,target,contact,joinOnConnect))
	{
		delete this;
		return;
	}

}

IRCContact::IRCContact(const QString &server, const QString &target, unsigned int port,
		       IRCServerContact *contact, const QStringList /*pendingMessage*/,
		       KopeteMetaContact *parent, QString &protocolID)
	: KopeteContact(protocolID, parent),
	  m_pActionCollection(new KActionCollection(this, "IRCActionCollection"))
{
	contactOnList = false;

	if (!init(server,  port,target,contact,true))
	{
		delete this;
		return;
	}

	//TODO: show pending messages
}

bool IRCContact::init(const QString &server, unsigned int port,const QString &target, IRCServerContact *contact,bool joinOnConnect)
{
	m_engine = contact->engine();
	m_requestedQuit = false;
	added = false;

	KGlobal::config()->setGroup("IRC");
	QString newServer;

	if (server.isEmpty() == true)
	{
		newServer = KGlobal::config()->readEntry("Server", "");
		m_serverName = newServer;
	}
	else
	{
		m_serverName = server;
	}
	if (port == 0)
	{
		port = KGlobal::config()->readEntry("Port", "6667").toUInt();
	}
	QString user = "kopeteuser";
	QString nick = KGlobal::config()->readEntry("Nickname", "KopeteUser");

	m_serverContact = contact;
	m_targetName = target;
	m_port = port;
	m_username = user;
	m_nickname = nick;
	mJoinOnConnect = joinOnConnect;

	// Just to be safe!
	mTabPage = 0L;
	queryView = 0L;
	chatView = 0L;

//	parent->setDisplayName(m_serverName, false);
//	parent->addContact( this, QStringList() );
	setDisplayName(target);

	if (m_serverContact->activeContacts().contains(m_targetName.lower()) > 0)
	{
		return false;
	}
	m_serverContact->activeContacts().append(m_targetName.lower());
	added = true;
	connect(m_serverContact->engine(), SIGNAL(successfulQuit()), this, SLOT(unloading()));
	connect(m_serverContact->engine(), SIGNAL(incomingPartedChannel(const QString &, const QString &, const QString &)), this, SLOT(slotPartedChannel(const QString &, const QString &, const QString &)));
	connect(m_serverContact->engine(), SIGNAL(incomingKick(const QString &, const QString &, const QString &, const QString &)), this, SLOT(slotUserKicked(const QString &, const QString &, const QString &, const QString &)));
	connect(m_engine, SIGNAL(incomingPrivMessage(const QString &, const QString &, const QString &)), this, SLOT(incomingPrivMessage(const QString &, const QString &, const QString &)));
	connect(m_engine, SIGNAL(incomingPrivAction(const QString &, const QString &, const QString &)), this, SLOT(incomingPrivAction(const QString &, const QString &, const QString &)));

	connect(m_serverContact->engine(), SIGNAL(connectionClosed()), this, SLOT(unloading()));
	if (mJoinOnConnect == true)
	{
		if (m_serverContact->engine()->isLoggedIn() == true)
		{
			joinNow();
		}
		else
		{
			QObject::connect(m_serverContact->engine(), SIGNAL(connectedToServer()), this, SLOT(joinNow()));
		}
	}

	return true;
}

bool IRCContact::isChannel() const
{
	static QString const sChannelChars(QString::fromLatin1("#!&+"));

	return ((m_targetName.isEmpty() == false)
		&& (sChannelChars.contains(m_targetName[0]) > 0));
}

KopeteContact::ContactStatus IRCContact::status() const
{
	if (m_serverContact->engine()->isLoggedIn())
	{
		return KopeteContact::Online;
	}
	return KopeteContact::Offline;
}

QString IRCContact::statusIcon() const
{
	if (m_serverContact->engine()->isLoggedIn())
	{
		return "connect_established";
	} else {
		return "connect_no";
	}
}

void IRCContact::incomingPrivMessage(const QString &originating, const QString &/*target_dest*/, const QString &/*message*/)
{
	//kdDebug()<< "IRCContact::incomingPrivMessage :"<<target <<endl;
	QString target= originating.section('!', 0, 0);

	if (m_targetName.lower() == target.lower())
	{
		if (mTabPage == 0)
		{
			joinNow();
		}
		if(m_targetName!=target)
		{
			//update case of the displayName
			m_targetName=target;
			setDisplayName(target);
		}
	}
}

void IRCContact::incomingPrivAction(const QString &originating, const QString &/*target_dest*/, const QString &/*message*/)
{
	QString target= originating.section('!', 0, 0);

	if (m_targetName.lower() == target.lower())
	{
		if (mTabPage == 0)
		{
			joinNow();
		}
	}
}

void IRCContact::slotOpen()
{
	if (!m_serverContact->engine()->isLoggedIn())
	{
		slotOpenConnect();
	} else {
		if (m_serverContact->chatWindow() != 0)
		{
			m_serverContact->chatWindow()->show();
		}
		joinNow();
	}
}

void IRCContact::slotOpenConnect()
{
	if (!m_serverContact->engine()->isLoggedIn())
	{
		QObject::disconnect(m_serverContact->engine(), SIGNAL(connectedToServer()), this, SLOT(joinNow()));
		QObject::connect(m_serverContact->engine(), SIGNAL(connectedToServer()), this, SLOT(joinNow()));
		m_serverContact->slotConnectNow();
		m_serverContact->chatWindow()->show();
	} else {
		slotOpen();
	}
}

KActionCollection* IRCContact::customContextMenuActions()
{
	m_pActionCollection->clear();

	if (isChannel())
	{
		if (mTabPage)
		{
			new KAction(i18n("Part"), KShortcut(),
				    this, SLOT(slotPart()),
				    m_pActionCollection, "part");
		}
// TODO:	popup->insertItem("Hop (Part and Re-join)", this, SLOT(slotHop()));
	}
	else
	{
		if (mTabPage)
		{
			new KAction(i18n("Close"), KShortcut(),
				    this, SLOT(unloading()),
				    m_pActionCollection, "close");
		}
	}
	if (!mTabPage)
	{
		if (m_serverContact->engine()->isLoggedIn())
		{
			QString const sLabel(isChannel()
					     ? i18n("Join")
					     : i18n("Open"));
			new KAction(sLabel, KShortcut(),
				    this, SLOT(slotOpen()),
				    m_pActionCollection, "open");
		}
		else
		{
			QString const sLabel(isChannel()
					     ? i18n("Connect && Join")
					     : i18n("Connect && Open"));
			new KAction(sLabel, KShortcut(),
				    this, SLOT(slotOpen()),
				    m_pActionCollection, "open_connect");
		}
	}

	return m_pActionCollection;
}

void IRCContact::execute()
{
	if (!mTabPage)
	{
		slotOpen();
	}

	if (m_serverContact->chatWindow() != 0)
	{
		m_serverContact->chatWindow()->raise();
		if (mTabPage !=0)
		{
			m_serverContact->chatWindow()->mTabWidget->showPage(mTabPage);
		}
	}
	if (chatView !=0)
	{
		chatView->messageEdit()->setFocus();
		return;
	}
	if (queryView !=0)
	{
		queryView->messageEdit()->setFocus();
		return;
	}
}

void IRCContact::slotDeleteContact()
{
	if (KMessageBox::warningYesNo(qApp->mainWidget(),
				      i18n("<qt>Are you sure you want to remove %1 from your contact list?</qt>").arg(displayName()),
				      i18n("Confirmation")) == KMessageBox::Yes)
	{
		if (isChannel())
		{
			slotPart();
		}
		if (mTabPage !=0)
		{
			m_serverContact->chatWindow()->mTabWidget->removePage(mTabPage);
			delete mTabPage;
			mTabPage = 0L;
			queryView = 0L;
			chatView = 0L;
		}
		delete this;
	}
}

void IRCContact::slotPart()
{
	if (chatView != 0)
	{
		QColor color(175, 8, 8);
		QString partWarning = "Attempting to part channel. If this takes an unusual amount of time, please click the close button on this window again, or right click on the contact in the Kopete window and click \"Part\" again.
");
		if (isChannel())
		{
			if (chatView !=0)
			{
				chatView->messageView()->append(partWarning);
				chatView->messageView()->scrollToBottom();
			}
			m_waitingPart = true;
			m_serverContact->engine()->partChannel(m_targetName ,QString("Using Kopete IRC Plugin"));
		}
	}
}

void IRCContact::slotPartedChannel(const QString &originating, const QString &channel, const QString &)
{
	if (m_targetName.lower() == channel.lower() && originating.section('!', 0, 0).lower() == m_engine->nickName().lower())
	{
		unloading();
	}
}

void IRCContact::slotUserKicked(const QString &user, const QString &channel,
				const QString &/*by*/, const QString &/*reason*/)
{
	if (m_targetName.lower() == channel.lower() && user.lower() == m_engine->nickName().lower())
	{
		unloading();
	}
}

IRCContact::~IRCContact()
{
	if (added && !contactOnList)
	{
		m_serverContact->activeContacts().remove(m_targetName.lower());
	}
}

void IRCContact::unloading()
{
	if (mTabPage !=0)
	{
		kdDebug()<< "IRCContact::unloading()" <<endl;
		if (m_serverContact->closing() == false)
		{
			delete mTabPage;
		}
		mTabPage = 0L;
		chatView = 0L;
		queryView = 0L;
		/*if (!contactOnList)
		{
			delete this;
		} */
	}
	emit statusChanged();
	emit statusChanged(this, Offline);
}

void IRCContact::joinNow()
{
	kdDebug() << "IRC Plugin: IRCContact::joinNow() creating mTabPage!" << endl;
	mTabPage = new QVBox(m_serverContact->chatWindow()->mTabWidget);
	if (isChannel())
	{
		chatView = new IRCChatView(m_serverName, m_targetName, this, mTabPage);
		m_serverContact->chatWindow()->mTabWidget->addTab(mTabPage, SmallIconSet("irc_privmsg"), m_targetName);
	} else {
		queryView = new IRCQueryView(m_serverName, m_targetName, m_serverContact, mTabPage, this);
		m_serverContact->chatWindow()->mTabWidget->addTab(mTabPage, SmallIconSet("irc_querymsg"), m_targetName);
	}

	m_serverContact->chatWindow()->show();

	KGlobal::config()->setGroup("IRC");
	bool minimize = KGlobal::config()->readBoolEntry("MinimizeNewQueries", false);
	if (isChannel())
	{
		m_serverContact->chatWindow()->mTabWidget->showPage(mTabPage);
	} else {
		if (!minimize)
		{
			m_serverContact->chatWindow()->mTabWidget->showPage(mTabPage);
		}
	}
	emit statusChanged();
	emit statusChanged(this, Online);

}

QString IRCContact::id() const
{
	return QString(m_targetName+"@"+m_serverName).lower();
}

#include "irccontact.moc"
/*
 * Local variables:
 * c-indentation-style: k&r
 * c-basic-offset: 8
 * indent-tabs-mode: t
 * End:
 */
// vim: set noet ts=4 sts=4 sw=4:

<|endoftext|>