<commit_before>/* bzflag
 * Copyright (c) 1993 - 2004 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

/* interface header */
#include "ComposeDefaultKey.h"

/* common implementation headers */
#include "RemotePlayer.h"
#include "KeyManager.h"

/* local implementation headers */
#include "LocalPlayer.h"
#include "World.h"
#include "HUDRenderer.h"
#include "Roster.h"

/* FIXME -- pulled from player.h */
void addMessage(const Player* player, const std::string& msg, bool highlight=false, const char* oldColor=NULL);
extern char messageMessage[PlayerIdPLen + MessageLen];
#define MAX_MESSAGE_HISTORY (20)
extern HUDRenderer *hud;
extern ServerLink*	serverLink;
void selectNextRecipient (bool forward, bool robotIn);

MessageQueue	messageHistory;
unsigned int	messageHistoryIndex = 0;

void printout(const std::string& name, void*)
{
  std::cout << name << " = " << BZDB.get(name) << std::endl;
}

void listSetVars(const std::string& name, void*)
{
  char message[MessageLen];

  if (BZDB.getPermission(name) == StateDatabase::Locked) {
    sprintf(message, "/set %s %f", name.c_str(), BZDB.eval(name));
    addMessage(LocalPlayer::getMyTank(), message, false, NULL);
  }
}

bool			ComposeDefaultKey::keyPress(const BzfKeyEvent& key)
{
  bool sendIt;
  LocalPlayer *myTank = LocalPlayer::getMyTank();
  if (KEYMGR.get(key, true) == "jump") {
    // jump while typing
    myTank->jump();
  }

  if (myTank->getInputMethod() != LocalPlayer::Keyboard) {
    if ((key.button == BzfKeyEvent::Up) ||
	(key.button == BzfKeyEvent::Down))
      return true;
  }

  switch (key.ascii) {
  case 3:	// ^C
  case 27:	// escape
    //    case 127:	// delete
    sendIt = false;			// finished composing -- don't send
    break;

  case 4:	// ^D
  case 13:	// return
    sendIt = true;
    break;

  default:
    return false;
  }

  if (sendIt) {
    std::string message = hud->getComposeString();

    if (message.length() > 0) {
      const char* silence = message.c_str();
      if (strncmp(silence, "SILENCE", 7) == 0) {
	Player *loudmouth = getPlayerByName(silence + 8);
	if (loudmouth) {
	  silencePlayers.push_back(silence + 8);
	  std::string message = "Silenced ";
	  message += (silence + 8);
	  addMessage(NULL, message);
	}
      } else if (strncmp(silence, "DUMP", 4) == 0) {
	BZDB.iterate(printout, NULL);
      } else if (strncmp(silence, "UNSILENCE", 9) == 0) {
	Player *loudmouth = getPlayerByName(silence + 10);
	if (loudmouth) {
	  std::vector<std::string>::iterator it = silencePlayers.begin();
	  for (; it != silencePlayers.end(); it++) {
	    if (*it == silence + 10) {
	      silencePlayers.erase(it);
	      std::string message = "Unsilenced ";
	      message += (silence + 10);
	      addMessage(NULL, message);
	      break;
	    }
	  }
	}
      } else if (strncmp(silence, "SAVEWORLD", 9) == 0) {
	std::string path = silence + 10;
	if (World::getWorld()->writeWorld(path)) {
	  addMessage(NULL, "World Saved");
	} else {
	  addMessage(NULL, "Invalid file name specified");
	}
      } else if (message == "/set") {
	BZDB.iterate(listSetVars, NULL);
      } else {
	int i, mhLen = messageHistory.size();
	for (i = 0; i < mhLen; i++) {
	  if (messageHistory[i] == message) {
	    messageHistory.erase(messageHistory.begin() + i);
	    messageHistory.push_front(message);
	    break;
	  }
	}
	if (i == mhLen) {
	  if (mhLen >= MAX_MESSAGE_HISTORY) {
	    messageHistory.pop_back();
	  }
	  messageHistory.push_front(message);
	}

	char messageBuffer[MessageLen];
	memset(messageBuffer, 0, MessageLen);
	strncpy(messageBuffer, message.c_str(), MessageLen);
	nboPackString(messageMessage + PlayerIdPLen, messageBuffer, MessageLen);
	serverLink->send(MsgMessage, sizeof(messageMessage), messageMessage);
      }
    }
  }

  messageHistoryIndex = 0;
  hud->setComposing(std::string());
  HUDui::setDefaultKey(NULL);
  return true;
}

bool			ComposeDefaultKey::keyRelease(const BzfKeyEvent& key)
{
  LocalPlayer *myTank = LocalPlayer::getMyTank();
  if (myTank->getInputMethod() != LocalPlayer::Keyboard) {
    if (key.button == BzfKeyEvent::Up) {
      if (messageHistoryIndex < messageHistory.size()) {
	hud->setComposeString(messageHistory[messageHistoryIndex]);
	messageHistoryIndex++;
      }
      else
	hud->setComposeString(std::string());
      return true;
    }
    else if (key.button == BzfKeyEvent::Down) {
      if (messageHistoryIndex > 0){
	messageHistoryIndex--;
	hud->setComposeString(messageHistory[messageHistoryIndex]);
      }
      else
	hud->setComposeString(std::string());
      return true;
    }
    else if ((key.shift == BzfKeyEvent::ShiftKey || (hud->getComposeString().length() == 0)) &&
	     (key.button == BzfKeyEvent::Left || key.button == BzfKeyEvent::Right)) {
      // exclude robot from private message recipient.
      // No point sending messages to robot (now)
      selectNextRecipient(key.button != BzfKeyEvent::Left, false);
      const Player *recipient = myTank->getRecipient();
      if (recipient) {
	void* buf = messageMessage;
	buf = nboPackUByte(buf, recipient->getId());
	std::string composePrompt = "Send to ";
	composePrompt += recipient->getCallSign();
	composePrompt += ": ";
	hud->setComposing(composePrompt);
      }
      return false;
    }
  }
  return keyPress(key);
}

// Local Variables: ***
// mode: C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8
<commit_msg>Include win32.h to quell C4786<commit_after>/* bzflag
 * Copyright (c) 1993 - 2004 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

/* interface header */
#include "ComposeDefaultKey.h"

/* common implementation headers */
#include "win32.h"
#include "RemotePlayer.h"
#include "KeyManager.h"

/* local implementation headers */
#include "LocalPlayer.h"
#include "World.h"
#include "HUDRenderer.h"
#include "Roster.h"

/* FIXME -- pulled from player.h */
void addMessage(const Player* player, const std::string& msg, bool highlight=false, const char* oldColor=NULL);
extern char messageMessage[PlayerIdPLen + MessageLen];
#define MAX_MESSAGE_HISTORY (20)
extern HUDRenderer *hud;
extern ServerLink*	serverLink;
void selectNextRecipient (bool forward, bool robotIn);

MessageQueue	messageHistory;
unsigned int	messageHistoryIndex = 0;

void printout(const std::string& name, void*)
{
  std::cout << name << " = " << BZDB.get(name) << std::endl;
}

void listSetVars(const std::string& name, void*)
{
  char message[MessageLen];

  if (BZDB.getPermission(name) == StateDatabase::Locked) {
    sprintf(message, "/set %s %f", name.c_str(), BZDB.eval(name));
    addMessage(LocalPlayer::getMyTank(), message, false, NULL);
  }
}

bool			ComposeDefaultKey::keyPress(const BzfKeyEvent& key)
{
  bool sendIt;
  LocalPlayer *myTank = LocalPlayer::getMyTank();
  if (KEYMGR.get(key, true) == "jump") {
    // jump while typing
    myTank->jump();
  }

  if (myTank->getInputMethod() != LocalPlayer::Keyboard) {
    if ((key.button == BzfKeyEvent::Up) ||
	(key.button == BzfKeyEvent::Down))
      return true;
  }

  switch (key.ascii) {
  case 3:	// ^C
  case 27:	// escape
    //    case 127:	// delete
    sendIt = false;			// finished composing -- don't send
    break;

  case 4:	// ^D
  case 13:	// return
    sendIt = true;
    break;

  default:
    return false;
  }

  if (sendIt) {
    std::string message = hud->getComposeString();

    if (message.length() > 0) {
      const char* silence = message.c_str();
      if (strncmp(silence, "SILENCE", 7) == 0) {
	Player *loudmouth = getPlayerByName(silence + 8);
	if (loudmouth) {
	  silencePlayers.push_back(silence + 8);
	  std::string message = "Silenced ";
	  message += (silence + 8);
	  addMessage(NULL, message);
	}
      } else if (strncmp(silence, "DUMP", 4) == 0) {
	BZDB.iterate(printout, NULL);
      } else if (strncmp(silence, "UNSILENCE", 9) == 0) {
	Player *loudmouth = getPlayerByName(silence + 10);
	if (loudmouth) {
	  std::vector<std::string>::iterator it = silencePlayers.begin();
	  for (; it != silencePlayers.end(); it++) {
	    if (*it == silence + 10) {
	      silencePlayers.erase(it);
	      std::string message = "Unsilenced ";
	      message += (silence + 10);
	      addMessage(NULL, message);
	      break;
	    }
	  }
	}
      } else if (strncmp(silence, "SAVEWORLD", 9) == 0) {
	std::string path = silence + 10;
	if (World::getWorld()->writeWorld(path)) {
	  addMessage(NULL, "World Saved");
	} else {
	  addMessage(NULL, "Invalid file name specified");
	}
      } else if (message == "/set") {
	BZDB.iterate(listSetVars, NULL);
      } else {
	int i, mhLen = messageHistory.size();
	for (i = 0; i < mhLen; i++) {
	  if (messageHistory[i] == message) {
	    messageHistory.erase(messageHistory.begin() + i);
	    messageHistory.push_front(message);
	    break;
	  }
	}
	if (i == mhLen) {
	  if (mhLen >= MAX_MESSAGE_HISTORY) {
	    messageHistory.pop_back();
	  }
	  messageHistory.push_front(message);
	}

	char messageBuffer[MessageLen];
	memset(messageBuffer, 0, MessageLen);
	strncpy(messageBuffer, message.c_str(), MessageLen);
	nboPackString(messageMessage + PlayerIdPLen, messageBuffer, MessageLen);
	serverLink->send(MsgMessage, sizeof(messageMessage), messageMessage);
      }
    }
  }

  messageHistoryIndex = 0;
  hud->setComposing(std::string());
  HUDui::setDefaultKey(NULL);
  return true;
}

bool			ComposeDefaultKey::keyRelease(const BzfKeyEvent& key)
{
  LocalPlayer *myTank = LocalPlayer::getMyTank();
  if (myTank->getInputMethod() != LocalPlayer::Keyboard) {
    if (key.button == BzfKeyEvent::Up) {
      if (messageHistoryIndex < messageHistory.size()) {
	hud->setComposeString(messageHistory[messageHistoryIndex]);
	messageHistoryIndex++;
      }
      else
	hud->setComposeString(std::string());
      return true;
    }
    else if (key.button == BzfKeyEvent::Down) {
      if (messageHistoryIndex > 0){
	messageHistoryIndex--;
	hud->setComposeString(messageHistory[messageHistoryIndex]);
      }
      else
	hud->setComposeString(std::string());
      return true;
    }
    else if ((key.shift == BzfKeyEvent::ShiftKey || (hud->getComposeString().length() == 0)) &&
	     (key.button == BzfKeyEvent::Left || key.button == BzfKeyEvent::Right)) {
      // exclude robot from private message recipient.
      // No point sending messages to robot (now)
      selectNextRecipient(key.button != BzfKeyEvent::Left, false);
      const Player *recipient = myTank->getRecipient();
      if (recipient) {
	void* buf = messageMessage;
	buf = nboPackUByte(buf, recipient->getId());
	std::string composePrompt = "Send to ";
	composePrompt += recipient->getCallSign();
	composePrompt += ": ";
	hud->setComposing(composePrompt);
      }
      return false;
    }
  }
  return keyPress(key);
}

// Local Variables: ***
// mode: C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8
<|endoftext|>


<commit_before>/*
 * Smithsonian Astrophysical Observatory, Cambridge, MA, USA
 * This code has been modified under the terms listed below and is made
 * available under the same terms.
 */

/*
 *	Copyright 1991-2004 George A Howlett.
 *
 *	Permission is hereby granted, free of charge, to any person obtaining
 *	a copy of this software and associated documentation files (the
 *	"Software"), to deal in the Software without restriction, including
 *	without limitation the rights to use, copy, modify, merge, publish,
 *	distribute, sublicense, and/or sell copies of the Software, and to
 *	permit persons to whom the Software is furnished to do so, subject to
 *	the following conditions:
 *
 *	The above copyright notice and this permission notice shall be
 *	included in all copies or substantial portions of the Software.
 *
 *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 *	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 *	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 *	NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 *	LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 *	OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 *	WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#include <tk.h>
#include <iostream>
using namespace std;

extern "C" {
Tcl_AppInitProc Tkblt_Init;
Tcl_AppInitProc Tkblt_SafeInit;
};

Tcl_AppInitProc Blt_VectorCmdInitProc;
Tcl_AppInitProc Blt_GraphCmdInitProc;

#include "tkbltStubInit.c"

int Tkblt_Init(Tcl_Interp* interp)
{
  Tcl_Namespace *nsPtr;

  if (Tcl_InitStubs(interp, TCL_PATCH_LEVEL, 0) == NULL)
    return TCL_ERROR;
  if (Tk_InitStubs(interp, TK_PATCH_LEVEL, 0) == NULL)
    return TCL_ERROR;

  nsPtr = Tcl_FindNamespace(interp, "::blt", (Tcl_Namespace *)NULL, 0);
  if (nsPtr == NULL) {
    nsPtr = Tcl_CreateNamespace(interp, "::blt", NULL, NULL);
    if (nsPtr == NULL)
      return TCL_ERROR;
  }

  if (Blt_VectorCmdInitProc(interp) != TCL_OK)
    return TCL_ERROR;
  if (Blt_GraphCmdInitProc(interp) != TCL_OK)
    return TCL_ERROR;

  if (Tcl_PkgProvideEx(interp, PACKAGE_NAME, PACKAGE_VERSION, (ClientData)&tkbltStubs) != TCL_OK)
    return TCL_ERROR;

  return TCL_OK;
}

int Tkblt_SafeInit(Tcl_Interp* interp)
{
  return Tkblt_Init(interp);
}
<commit_msg>Export Tkblt_Init and Tkblt_SafeInit symbols<commit_after>/*
 * Smithsonian Astrophysical Observatory, Cambridge, MA, USA
 * This code has been modified under the terms listed below and is made
 * available under the same terms.
 */

/*
 *	Copyright 1991-2004 George A Howlett.
 *
 *	Permission is hereby granted, free of charge, to any person obtaining
 *	a copy of this software and associated documentation files (the
 *	"Software"), to deal in the Software without restriction, including
 *	without limitation the rights to use, copy, modify, merge, publish,
 *	distribute, sublicense, and/or sell copies of the Software, and to
 *	permit persons to whom the Software is furnished to do so, subject to
 *	the following conditions:
 *
 *	The above copyright notice and this permission notice shall be
 *	included in all copies or substantial portions of the Software.
 *
 *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 *	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 *	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 *	NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 *	LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 *	OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 *	WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#include <tk.h>
#include <iostream>
using namespace std;

extern "C" {
DLLEXPORT Tcl_AppInitProc Tkblt_Init;
DLLEXPORT Tcl_AppInitProc Tkblt_SafeInit;
};

Tcl_AppInitProc Blt_VectorCmdInitProc;
Tcl_AppInitProc Blt_GraphCmdInitProc;

#include "tkbltStubInit.c"

DLLEXPORT int Tkblt_Init(Tcl_Interp* interp)
{
  Tcl_Namespace *nsPtr;

  if (Tcl_InitStubs(interp, TCL_PATCH_LEVEL, 0) == NULL)
    return TCL_ERROR;
  if (Tk_InitStubs(interp, TK_PATCH_LEVEL, 0) == NULL)
    return TCL_ERROR;

  nsPtr = Tcl_FindNamespace(interp, "::blt", (Tcl_Namespace *)NULL, 0);
  if (nsPtr == NULL) {
    nsPtr = Tcl_CreateNamespace(interp, "::blt", NULL, NULL);
    if (nsPtr == NULL)
      return TCL_ERROR;
  }

  if (Blt_VectorCmdInitProc(interp) != TCL_OK)
    return TCL_ERROR;
  if (Blt_GraphCmdInitProc(interp) != TCL_OK)
    return TCL_ERROR;

  if (Tcl_PkgProvideEx(interp, PACKAGE_NAME, PACKAGE_VERSION, (ClientData)&tkbltStubs) != TCL_OK)
    return TCL_ERROR;

  return TCL_OK;
}

DLLEXPORT int Tkblt_SafeInit(Tcl_Interp* interp)
{
  return Tkblt_Init(interp);
}
<|endoftext|>


<commit_before>/*
Première version du programme de controle des Yi
*/
#include <Arduino.h>
#include <Wire.h>

//const int shutter_pin = 2;
//const int power_pin = 4;
const int powerup_button_pin = 5;
const int powerdown_button_pin = 6;
const int tmlapse_start_pin = 7;
const int tmlapse_stop_pin = 8;
//const int shutter_led_pin = A0;
const int shutter_led_pin = 3;
const int shutter_button_pin = 9;

int pic_count = 0; // picture counter
int after_pic_delay = 800;
volatile int shutter_led_counter = 0;
long old_timestamp = 0;
long current_timestamp = 0;
const byte cam_range = 0b00000001;

// MCP23017 registers (everything except direction defaults to 0)

#define IODIRA   0x00   // IO direction  (0 = output, 1 = input (Default))
#define IODIRB   0x01
#define IOPOLA   0x02   // IO polarity   (0 = normal, 1 = inverse)
#define IOPOLB   0x03
#define GPINTENA 0x04   // Interrupt on change (0 = disable, 1 = enable)
#define GPINTENB 0x05
#define DEFVALA  0x06   // Default comparison for interrupt on change (interrupts on opposite)
#define DEFVALB  0x07
#define INTCONA  0x08   // Interrupt control (0 = interrupt on change from previous, 1 = interrupt on change from DEFVAL)
#define INTCONB  0x09
#define IOCON    0x0A   // IO Configuration: bank/mirror/seqop/disslw/haen/odr/intpol/notimp
//#define IOCON 0x0B  // same as 0x0A
#define GPPUA    0x0C   // Pull-up resistor (0 = disabled, 1 = enabled)
#define GPPUB    0x0D
#define INFTFA   0x0E   // Interrupt flag (read only) : (0 = no interrupt, 1 = pin caused interrupt)
#define INFTFB   0x0F
#define INTCAPA  0x10   // Interrupt capture (read only) : value of GPIO at time of last interrupt
#define INTCAPB  0x11
#define GPIOA    0x12   // Port value. Write to change, read to obtain value
#define GPIOB    0x13
#define OLLATA   0x14   // Output latch. Write to latch output.
#define OLLATB   0x15

#define mcp1 0x20  // MCP23017 n°1 (shutter and power) is on I2C port 0x20
#define mcp2 0x21  // MCP23017 n°2 (shutter led input) is on I2C port 0x21

#define ISR_INDICATOR 12  // pin 12
#define ONBOARD_LED 13    // pin 13
volatile bool sht_led_activity;
int sht_LedToggle_array[8];
unsigned long time = 0;

void expanderWrite (const byte port, const byte reg, const byte data ){
  Wire.beginTransmission (port);
  Wire.write (reg);
  Wire.write (data);
  Wire.endTransmission ();
} // end of expanderWrite

// read a byte from the expander
unsigned int expanderRead (const byte port, const byte reg){
  Wire.beginTransmission (port);
  Wire.write (reg);
  Wire.endTransmission ();
  Wire.requestFrom (port, 1);
  return Wire.read();
} // end of expanderRead

// interrupt service routine, called when pin D2 goes from 0 to 1
void mcp2_interrupt ()
{
  digitalWrite (ISR_INDICATOR, HIGH);  // debugging
  sht_led_activity = true;   // set flag so main loop knows
}  // end of mcp2_interrupt

void myISR() {
  shutter_led_counter++;
}

void setup() {
  pinMode (ISR_INDICATOR, OUTPUT);  // for testing (ISR indicator)
  pinMode (ONBOARD_LED, OUTPUT);  // for onboard LED
  Serial.begin(9600);
  Serial.println("Starting program");
  Wire.begin ();
  // Set expander n°1 I/O as output
  expanderWrite(mcp1, IODIRA, 0x00);
  expanderWrite(mcp1, IODIRB, 0x00);

  // Set expander n°2 I/O as output. We will set inputs later
  expanderWrite(mcp2, IODIRA, 0x00);
  expanderWrite(mcp2, IODIRB, 0x00);

  // TODO set dynamically the pins as output
  // enable GPIOA pins as input
  expanderWrite(mcp2, IODIRA, 0xFF);
  // enable pull-up on switches
  expanderWrite(mcp2, GPPUA, 0xFF);
  // expander configuration register
  expanderWrite(mcp2, IOCON, 0b01100010); // no mirror interrupts, disable sequential mode, active HIGH

  // invert polarity
  //expanderWrite(mcp2, IOPOLA, 0xFF);  // invert polarity of signal - both ports

  // enable interrupts
  expanderWrite (mcp2, GPINTENA, cam_range); // enable interrupts

  //expanderWriteBoth(DEFVALA, 0b00000000); // defini la valeur par défaut à 0
  expanderWrite(mcp2, INTCONA, 0b00000000);// Active le mode "on change"
  // FIN MES TESTS
  // no interrupt yet
  sht_led_activity = false;

  // read from interrupt capture ports to clear them
  expanderRead (mcp2, INTCAPA);
  expanderRead (mcp2, INTCAPB);

  // pin 19 of MCP23017 is plugged into D2 of the Arduino which is interrupt 0
  attachInterrupt(0, mcp2_interrupt, RISING);
  //attachInterrupt(digitalPinToInterrupt(shutter_led_pin), mcp2_interrupt, CHANGE);

  // pinMode(shutter_pin, OUTPUT);
  // pinMode(power_pin, OUTPUT);
  pinMode(powerup_button_pin, INPUT_PULLUP);
  pinMode(powerdown_button_pin, INPUT_PULLUP);
  pinMode(tmlapse_start_pin, INPUT_PULLUP);
  pinMode(tmlapse_stop_pin, INPUT_PULLUP);
  pinMode(shutter_button_pin, INPUT_PULLUP);
  pinMode(shutter_led_pin, INPUT);
  //pinMode(A5, INPUT);
  //attachInterrupt(digitalPinToInterrupt(shutter_led_pin), myISR, RISING);

}

void power_up_Yi(const byte cam_range) {
  Serial.println("Starting the Yi");
  //Set expander n°1 GPIOA to HIGH
  expanderWrite(mcp1, GPIOA, cam_range);

  delay(500);
  //Set expander n°1 GPIOA to LOW
  expanderWrite(mcp1, GPIOA, 0b00000000);

  Serial.println("Pause during the boot");
  delay(10000); //attente mise en route
  Serial.println("The cams should be ready");
}

void power_down_Yi(const byte cam_range) {
  Serial.println("Shutting down the Yi");
  //Set expander n°1 GPIOA to HIGH
  expanderWrite(mcp1, GPIOA, cam_range);

  delay(2500);
  //Set expander n°1 GPIOA to LOW
  expanderWrite(mcp1, GPIOA, 0b00000000);
}

void handle_Sht_led_activity ()
{
  unsigned int sht_LedValue = 0;
  unsigned int sht_LedLastValue = 0;
  //Serial.println("Inside handle_Sht_led_activity function");
  sht_led_activity = false;  // ready for next time through the interrupt service routine
  digitalWrite (ISR_INDICATOR, LOW);  // debugging

  // Read port values, as required. Note that this re-arms the interrupts.

  if (expanderRead (mcp2, INFTFA))
    {

    sht_LedValue |= expanderRead (mcp2, INTCAPA);        // port B is in low-order byte
    }

    Serial.print("sht_LedValue : ");
    Serial.println(sht_LedValue, BIN);
    Serial.print("last State : ");
    Serial.println(sht_LedLastValue, BIN);
    Serial.print("Ou exclusif : ");
    Serial.println(sht_LedLastValue ^ sht_LedValue, BIN);
    Serial.println("");
  Serial.println ("Shutter Led toggles");
  //Serial.println ("0                   1");
  Serial.println ("0 1 2 3 4 5 6 7");

  // display which buttons were down at the time of the interrupt
  for (byte sht_Led = 0; sht_Led < 8; sht_Led++)
    {
    if ((sht_LedLastValue ^ sht_LedValue) & (1 << sht_Led)){
      //Serial.print ("01 ");
      sht_LedToggle_array[sht_Led]+=1;
      Serial.print(sht_LedToggle_array[sht_Led]);
      Serial.print(" ");
      }
    else {
      //Serial.print ("00 ");
      Serial.print(sht_LedToggle_array[sht_Led]);
      Serial.print(" ");
      }

    }
  sht_LedLastValue = sht_LedValue;
  Serial.println ();

  // if a switch is now pressed, turn LED on  (key down event)
  if (sht_LedValue)
    {
    time = millis ();  // remember when
    digitalWrite (ONBOARD_LED, HIGH);  // on-board LED
    }  // end if

}  // end of handle_Sht_led_activity

//Take a picture
long take_picture(const byte cam_range) {
  Serial.println("Taking picture...");
  long pic_start_time = millis();
  byte shutter_led_check = 0b00000000;
  memset(sht_LedToggle_array,0,sizeof(sht_LedToggle_array
  )); //Reset the array

  //Set expander n°1 GPIOB to HIGH to "press" the shutter button
  expanderWrite(mcp1, GPIOB, cam_range);
  delay(100);
  //Set expander n°1 GPIOB to LOW to "release" the shutter button
  expanderWrite(mcp1, GPIOB, 0b00000000);

  while (shutter_led_check != cam_range) { // Wait for the shutter led return
    if (sht_led_activity) {
      handle_Sht_led_activity();

      for (byte sht_Led = 0; sht_Led < 8; sht_Led++)
      {
        if ((sht_LedToggle_array[sht_Led] == 1) & (cam_range & (1 << sht_Led)))
          {
          shutter_led_check = shutter_led_check ^ (1 << sht_Led);
          Serial.print("1 << sht_Led : ");
          Serial.println(1 << sht_Led, BIN);
          Serial.print("shutter_led_check : ");
          Serial.println(shutter_led_check, BIN);
        }
        }
      }
    if (millis()-pic_start_time > 2500) {
      Serial.println("No response");
      return 0;
    }
  }
  Serial.println("Shutter leds detected");

  Serial.println("Pause");
  unsigned long delay_Start_Time = millis();
  // Wait for the cams to be ready, and check interrupt in case of a failure
  while (millis() < (delay_Start_Time + after_pic_delay)) {
    if (sht_led_activity) {
      handle_Sht_led_activity();
      for (byte sht_Led = 0; sht_Led < 8; sht_Led++)
      {
        if ((sht_LedToggle_array[sht_Led] > 1) & (cam_range & (1 << sht_Led)))
        {
          Serial.print("Error on cam n°");
          Serial.println(sht_Led);
          return -1;
        }
      }

    }

    }
  Serial.println("End of pause");
  return pic_start_time;
}

void timelapse(const byte cam_range) {
  Serial.println("Starting timelapse");
  int pic_shutter_request = 0;
  int pic_shutter_taken = 0;
  while (true) {
    current_timestamp = take_picture(cam_range);
    pic_shutter_request++;
    Serial.print("Interval : ");
    Serial.print(current_timestamp - old_timestamp);
    Serial.println("ms");
    if (current_timestamp != 0) {
      old_timestamp = current_timestamp;
      pic_shutter_taken++;
      Serial.print("Successful pictures : ");
      Serial.print(pic_shutter_taken);
      Serial.print(" of ");
      Serial.println(pic_shutter_request);
      Serial.print("Missing pictures : ");
      Serial.println(pic_shutter_request - pic_shutter_taken);
    }

    if (digitalRead(tmlapse_stop_pin) == LOW) {
      Serial.println("Timelapse stopped");
      break;
    }
  }
}

void loop() {

  if (digitalRead(powerup_button_pin) == LOW) {
    power_up_Yi(cam_range);
  }

  if (digitalRead(powerdown_button_pin) == LOW) {
    power_down_Yi(cam_range);
  }

  if (digitalRead(shutter_button_pin) == LOW) {
    Serial.println(take_picture(cam_range));
  }

  if (digitalRead(tmlapse_start_pin) == LOW) {
    timelapse(cam_range);
  }

  // turn LED off after 500 ms
  if (millis () > (time + 200) && time != 0)
   {
    digitalWrite (ONBOARD_LED, LOW);
    time = 0;
   }  // end if time up

}
<commit_msg>xor to or and various serial debug msg commented<commit_after>/*
Première version du programme de controle des Yi
*/
#include <Arduino.h>
#include <Wire.h>

//const int shutter_pin = 2;
//const int power_pin = 4;
const int powerup_button_pin = 5;
const int powerdown_button_pin = 6;
const int tmlapse_start_pin = 7;
const int tmlapse_stop_pin = 8;
//const int shutter_led_pin = A0;
const int shutter_led_pin = 3;
const int shutter_button_pin = 9;

int pic_count = 0; // picture counter
int after_pic_delay = 800;
volatile int shutter_led_counter = 0;
long old_timestamp = 0;
long current_timestamp = 0;
const byte cam_range = 0b00000001;

// MCP23017 registers (everything except direction defaults to 0)

#define IODIRA   0x00   // IO direction  (0 = output, 1 = input (Default))
#define IODIRB   0x01
#define IOPOLA   0x02   // IO polarity   (0 = normal, 1 = inverse)
#define IOPOLB   0x03
#define GPINTENA 0x04   // Interrupt on change (0 = disable, 1 = enable)
#define GPINTENB 0x05
#define DEFVALA  0x06   // Default comparison for interrupt on change (interrupts on opposite)
#define DEFVALB  0x07
#define INTCONA  0x08   // Interrupt control (0 = interrupt on change from previous, 1 = interrupt on change from DEFVAL)
#define INTCONB  0x09
#define IOCON    0x0A   // IO Configuration: bank/mirror/seqop/disslw/haen/odr/intpol/notimp
//#define IOCON 0x0B  // same as 0x0A
#define GPPUA    0x0C   // Pull-up resistor (0 = disabled, 1 = enabled)
#define GPPUB    0x0D
#define INFTFA   0x0E   // Interrupt flag (read only) : (0 = no interrupt, 1 = pin caused interrupt)
#define INFTFB   0x0F
#define INTCAPA  0x10   // Interrupt capture (read only) : value of GPIO at time of last interrupt
#define INTCAPB  0x11
#define GPIOA    0x12   // Port value. Write to change, read to obtain value
#define GPIOB    0x13
#define OLLATA   0x14   // Output latch. Write to latch output.
#define OLLATB   0x15

#define mcp1 0x20  // MCP23017 n°1 (shutter and power) is on I2C port 0x20
#define mcp2 0x21  // MCP23017 n°2 (shutter led input) is on I2C port 0x21

#define ISR_INDICATOR 12  // pin 12
#define ONBOARD_LED 13    // pin 13
volatile bool sht_led_activity;
int sht_LedToggle_array[8];
unsigned long time = 0;

void expanderWrite (const byte port, const byte reg, const byte data ){
  Wire.beginTransmission (port);
  Wire.write (reg);
  Wire.write (data);
  Wire.endTransmission ();
} // end of expanderWrite

// read a byte from the expander
unsigned int expanderRead (const byte port, const byte reg){
  Wire.beginTransmission (port);
  Wire.write (reg);
  Wire.endTransmission ();
  Wire.requestFrom (port, 1);
  return Wire.read();
} // end of expanderRead

// interrupt service routine, called when pin D2 goes from 0 to 1
void mcp2_interrupt ()
{
  digitalWrite (ISR_INDICATOR, HIGH);  // debugging
  sht_led_activity = true;   // set flag so main loop knows
}  // end of mcp2_interrupt

void myISR() {
  shutter_led_counter++;
}

void setup() {
  pinMode (ISR_INDICATOR, OUTPUT);  // for testing (ISR indicator)
  pinMode (ONBOARD_LED, OUTPUT);  // for onboard LED
  Serial.begin(9600);
  Serial.println("Starting program");
  Wire.begin ();
  // Set expander n°1 I/O as output
  expanderWrite(mcp1, IODIRA, 0x00);
  expanderWrite(mcp1, IODIRB, 0x00);

  // Set expander n°2 I/O as output. We will set inputs later
  expanderWrite(mcp2, IODIRA, 0x00);
  expanderWrite(mcp2, IODIRB, 0x00);

  // TODO set dynamically the pins as output
  // enable GPIOA pins as input
  expanderWrite(mcp2, IODIRA, 0xFF);
  // enable pull-up on switches
  expanderWrite(mcp2, GPPUA, 0xFF);
  // expander configuration register
  expanderWrite(mcp2, IOCON, 0b01100010); // no mirror interrupts, disable sequential mode, active HIGH

  // invert polarity
  //expanderWrite(mcp2, IOPOLA, 0xFF);  // invert polarity of signal - both ports

  // enable interrupts
  expanderWrite (mcp2, GPINTENA, cam_range); // enable interrupts

  //expanderWriteBoth(DEFVALA, 0b00000000); // defini la valeur par défaut à 0
  expanderWrite(mcp2, INTCONA, 0b00000000);// Active le mode "on change"
  // FIN MES TESTS
  // no interrupt yet
  sht_led_activity = false;

  // read from interrupt capture ports to clear them
  expanderRead (mcp2, INTCAPA);
  expanderRead (mcp2, INTCAPB);

  // pin 19 of MCP23017 is plugged into D2 of the Arduino which is interrupt 0
  attachInterrupt(0, mcp2_interrupt, RISING);
  //attachInterrupt(digitalPinToInterrupt(shutter_led_pin), mcp2_interrupt, CHANGE);

  // pinMode(shutter_pin, OUTPUT);
  // pinMode(power_pin, OUTPUT);
  pinMode(powerup_button_pin, INPUT_PULLUP);
  pinMode(powerdown_button_pin, INPUT_PULLUP);
  pinMode(tmlapse_start_pin, INPUT_PULLUP);
  pinMode(tmlapse_stop_pin, INPUT_PULLUP);
  pinMode(shutter_button_pin, INPUT_PULLUP);
  pinMode(shutter_led_pin, INPUT);
  //pinMode(A5, INPUT);
  //attachInterrupt(digitalPinToInterrupt(shutter_led_pin), myISR, RISING);

}

void power_up_Yi(const byte cam_range) {
  Serial.println("Starting the Yi");
  //Set expander n°1 GPIOA to HIGH
  expanderWrite(mcp1, GPIOA, cam_range);

  delay(500);
  //Set expander n°1 GPIOA to LOW
  expanderWrite(mcp1, GPIOA, 0b00000000);

  Serial.println("Pause during the boot");
  delay(10000); //attente mise en route
  Serial.println("The cams should be ready");
}

void power_down_Yi(const byte cam_range) {
  Serial.println("Shutting down the Yi");
  //Set expander n°1 GPIOA to HIGH
  expanderWrite(mcp1, GPIOA, cam_range);

  delay(2500);
  //Set expander n°1 GPIOA to LOW
  expanderWrite(mcp1, GPIOA, 0b00000000);
}

void handle_Sht_led_activity ()
{
  unsigned int sht_LedValue = 0;
  unsigned int sht_LedLastValue = 0;
  //Serial.println("Inside handle_Sht_led_activity function");
  sht_led_activity = false;  // ready for next time through the interrupt service routine
  digitalWrite (ISR_INDICATOR, LOW);  // debugging

  // Read port values, as required. Note that this re-arms the interrupts.

  if (expanderRead (mcp2, INFTFA))
    {

    sht_LedValue |= expanderRead (mcp2, INTCAPA);        // port B is in low-order byte
    }

    /*Serial.print("sht_LedValue : ");
    Serial.println(sht_LedValue, BIN);
    Serial.print("last State : ");
    Serial.println(sht_LedLastValue, BIN);
    Serial.print("Ou exclusif : ");
    Serial.println(sht_LedLastValue ^ sht_LedValue, BIN);
    Serial.println("");
  Serial.println ("Shutter Led toggles");
  //Serial.println ("0                   1");
  Serial.println ("0 1 2 3 4 5 6 7");*/

  // display which buttons were down at the time of the interrupt
  for (byte sht_Led = 0; sht_Led < 8; sht_Led++)
    {
    if ((sht_LedLastValue ^ sht_LedValue) & (1 << sht_Led)){
      //Serial.print ("01 ");
      sht_LedToggle_array[sht_Led]+=1;
      /*Serial.print(sht_LedToggle_array[sht_Led]);
      Serial.print(" ");*/
      }
    else {
      //Serial.print ("00 ");
      /*Serial.print(sht_LedToggle_array[sht_Led]);
      Serial.print(" ");*/
      }

    }
  sht_LedLastValue = sht_LedValue;

  // if a switch is now pressed, turn LED on  (key down event)
  if (sht_LedValue)
    {
    time = millis ();  // remember when
    digitalWrite (ONBOARD_LED, HIGH);  // on-board LED
    }  // end if

}  // end of handle_Sht_led_activity

//Take a picture
long take_picture(const byte cam_range) {
  Serial.println("Taking picture...");
  long pic_start_time = millis();
  byte shutter_led_check = 0b00000000;
  memset(sht_LedToggle_array,0,sizeof(sht_LedToggle_array
  )); //Reset the array

  //Set expander n°1 GPIOB to HIGH to "press" the shutter button
  expanderWrite(mcp1, GPIOB, cam_range);
  delay(100);
  //Set expander n°1 GPIOB to LOW to "release" the shutter button
  expanderWrite(mcp1, GPIOB, 0b00000000);

  while (shutter_led_check != cam_range) { // Wait for the shutter led return
    if (sht_led_activity) {
      handle_Sht_led_activity();

      for (byte sht_Led = 0; sht_Led < 8; sht_Led++)
      {
        if ((sht_LedToggle_array[sht_Led] == 1) & (cam_range & (1 << sht_Led)))
          {
          shutter_led_check = shutter_led_check | (1 << sht_Led);
          /*Serial.print("1 << sht_Led : ");
          Serial.println(1 << sht_Led, BIN);
          Serial.print("shutter_led_check : ");
          Serial.println(shutter_led_check, BIN);*/
        }
        }
      }
    if (millis()-pic_start_time > 2500) {
      Serial.println("No response");
      return 0;
    }
  }
  Serial.println("Shutter leds detected");

  Serial.println("Pause");
  unsigned long delay_Start_Time = millis();
  // Wait for the cams to be ready, and check interrupt in case of a failure
  while (millis() < (delay_Start_Time + after_pic_delay)) {
    if (sht_led_activity) {
      handle_Sht_led_activity();
      for (byte sht_Led = 0; sht_Led < 8; sht_Led++)
      {
        if ((sht_LedToggle_array[sht_Led] > 1) & (cam_range & (1 << sht_Led)))
        {
          Serial.print("Error on cam n°");
          Serial.println(sht_Led);
          return -1;
        }
      }

    }

    }
  Serial.println("End of pause");
  return pic_start_time;
}

void timelapse(const byte cam_range) {
  Serial.println("Starting timelapse");
  int pic_shutter_request = 0;
  int pic_shutter_taken = 0;
  while (true) {
    current_timestamp = take_picture(cam_range);
    pic_shutter_request++;
    Serial.print("Interval : ");
    Serial.print(current_timestamp - old_timestamp);
    Serial.println("ms");
    if (current_timestamp != 0) {
      old_timestamp = current_timestamp;
      pic_shutter_taken++;
      Serial.print("Successful pictures : ");
      Serial.print(pic_shutter_taken);
      Serial.print(" of ");
      Serial.println(pic_shutter_request);
      Serial.print("Missing pictures : ");
      Serial.println(pic_shutter_request - pic_shutter_taken);
    }

    if (digitalRead(tmlapse_stop_pin) == LOW) {
      Serial.println("Timelapse stopped");
      break;
    }
  }
}

void loop() {

  if (digitalRead(powerup_button_pin) == LOW) {
    power_up_Yi(cam_range);
  }

  if (digitalRead(powerdown_button_pin) == LOW) {
    power_down_Yi(cam_range);
  }

  if (digitalRead(shutter_button_pin) == LOW) {
    Serial.println(take_picture(cam_range));
  }

  if (digitalRead(tmlapse_start_pin) == LOW) {
    timelapse(cam_range);
  }

  // turn LED off after 500 ms
  if (millis () > (time + 200) && time != 0)
   {
    digitalWrite (ONBOARD_LED, LOW);
    time = 0;
   }  // end if time up

}
<|endoftext|>


<commit_before>#include <QCoreApplication>
#include <QtCore/QCommandLineParser>
#include <QtCore/QCommandLineOption>
#include "w3cserver.h"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    // check if we are running the server in secure mode (wss)
    bool sec = false;
    if (argc > 0){
        QString str(argv[1]);
        if (str == "-secure")
            sec = true;
    }

    W3CServer *server = new W3CServer(8080,sec,true);
    QObject::connect(server, &W3CServer::closed, &a, &QCoreApplication::quit);

    return a.exec(); // start exec loop

}
<commit_msg>Delete main.cpp<commit_after><|endoftext|>


<commit_before>//
//  WindowSettings.cpp
//  Hume
//
//  Created by Marshall Clyburn on 7/11/14.
//  Copyright (c) 2014 Marshall Clyburn. All rights reserved.
//

#include "WindowSettings.h"

namespace hm
{
	/*
	 Default to a fullscreen window at the maximum
	 resolution supported by the attached screen.
	 */
	WindowSettings::WindowSettings() : fullscreen(true), title("Hume Window")
	{
		setBestFullscreenMode();
	}

	WindowSettings::~WindowSettings()
	{

	}

	/*
	 Set the window to fullscreen at the best possible
	 resolution attainable.
	*/
	void WindowSettings::setBestFullscreenMode()
	{
		fullscreen = true;
		int display_mode_count = SDL_GetNumDisplayModes(0);
		if(display_mode_count < 1)
		{
			Logger::getLogger()->log("No available display modes.", ERROR);
			exit(0);
		}
		else
		{
			SDL_DisplayMode mode;
			int success;
			do
			{
				success = SDL_GetDisplayMode(0, 0, &mode);
			}
			while(success != 0);

			if(Logger::getLogger()->getLogLevel() >= LogLevel::INFO)
			{
				std::string msg = "Using resolution of ";
				msg += mode.w;
				msg += "x";
				msg += mode.h;
				msg += ".";
				Logger::getLogger()->log(msg);
			}
		}
	}
}
<commit_msg>Fix logging resolution as chars.<commit_after>//
//  WindowSettings.cpp
//  Hume
//
//  Created by Marshall Clyburn on 7/11/14.
//  Copyright (c) 2014 Marshall Clyburn. All rights reserved.
//

#include "WindowSettings.h"

namespace hm
{
	/*
	 Default to a fullscreen window at the maximum
	 resolution supported by the attached screen.
	 */
	WindowSettings::WindowSettings() : fullscreen(true), title("Hume Window")
	{
		setBestFullscreenMode();
	}

	WindowSettings::~WindowSettings()
	{

	}

	/*
	 Set the window to fullscreen at the best possible
	 resolution attainable.
	*/
	void WindowSettings::setBestFullscreenMode()
	{
		fullscreen = true;
		int display_mode_count = SDL_GetNumDisplayModes(0);
		if(display_mode_count < 1)
		{
			Logger::getLogger()->log("No available display modes.", ERROR);
			exit(0);
		}
		else
		{
			SDL_DisplayMode mode;
			int success;
			do
			{
				success = SDL_GetDisplayMode(0, 0, &mode);
			}
			while(success != 0);

			if(Logger::getLogger()->getLogLevel() >= LogLevel::INFO)
			{
				std::string msg = "Using resolution of " +
				std::to_string(mode.w) + "x" +
				std::to_string(mode.h) + ".";
				Logger::getLogger()->log(msg);
			}
		}
	}
}
<|endoftext|>


<commit_before>/*
 *  OpenExternBrowser.cpp
 *  OpenLieroX
 *
 *  Created by Albert Zeyer on 29.09.08.
 *  code under LGPL
 *
 */

#include <string>
#include <iostream>
#include <list>

#ifdef __APPLE__
#include <Carbon/Carbon.h>
#include <CoreFoundation/CoreFoundation.h>
#include <CoreServices/CoreServices.h>
#endif

#ifdef WIN32
#include <windows.h>
#include <shellapi.h>
#endif

// declared in AuxLib.h; we are not including this to avoid problems with Rect
void OpenLinkInExternBrowser(const std::string& url) {
	std::cout << "open in extern browser: " << url << std::endl;

#if defined(__APPLE__)
	// Thanks to Jooleem project (http://jooleem.sourceforge.net) for the code

	// Create a string ref of the URL:
	CFStringRef cfurlStr = CFStringCreateWithCString( NULL, url.c_str(), kCFStringEncodingASCII);

	// Create a URL object:
	CFURLRef cfurl = CFURLCreateWithString (NULL, cfurlStr, NULL);

	// Open the URL:
	LSOpenCFURLRef(cfurl, NULL);

	// Release the created resources:
	CFRelease(cfurl);
	CFRelease(cfurlStr);

#elif defined(WIN32)
	ShellExecute(NULL, "open", url.c_str(), NULL, NULL, SW_MAXIMIZE);

#else
	std::string browser = "";

	if (getenv("BROWSER") != NULL) {
		browser = getenv("BROWSER");
	}

	if(browser == "") {
		// test some browsers and take the first found
		std::list<std::string> browsers;
		browsers.push_back("gnome-open");
		browsers.push_back("sensible-browser");
		browsers.push_back("firefox");
		browsers.push_back("mozilla-firefox");
		browsers.push_back("konqueror");
		browsers.push_back("mozilla");
		browsers.push_back("opera");
		browsers.push_back("epiphany");
		browsers.push_back("galeon");
		browsers.push_back("netscape");

		for (std::list<std::string>::const_iterator it = browsers.begin(); it != browsers.end(); ++it) {
			if (::system(("test -x /usr/bin/" + *it + " -o -x /usr/bin/X11/" + *it + " -o -x /usr/local/bin/" + *it).c_str()) == 0) {
				browser = *it;
				break;
			}
		}
	}

	if(browser == "") {
		std::cout << "WARNING: no browser found" << std::endl;
		return;
	} else
		std::cout << "Using " << browser << " as your default browser" << std::endl;

	::system((browser + " " + url + " &").c_str());

#endif
}

<commit_msg>small fix: missing include<commit_after>/*
 *  OpenExternBrowser.cpp
 *  OpenLieroX
 *
 *  Created by Albert Zeyer on 29.09.08.
 *  code under LGPL
 *
 */

#include <string>
#include <iostream>
#include <list>
#include <cstdlib>

#ifdef __APPLE__
#include <Carbon/Carbon.h>
#include <CoreFoundation/CoreFoundation.h>
#include <CoreServices/CoreServices.h>
#endif

#ifdef WIN32
#include <windows.h>
#include <shellapi.h>
#endif

// declared in AuxLib.h; we are not including this to avoid problems with Rect
void OpenLinkInExternBrowser(const std::string& url) {
	std::cout << "open in extern browser: " << url << std::endl;

#if defined(__APPLE__)
	// Thanks to Jooleem project (http://jooleem.sourceforge.net) for the code

	// Create a string ref of the URL:
	CFStringRef cfurlStr = CFStringCreateWithCString( NULL, url.c_str(), kCFStringEncodingASCII);

	// Create a URL object:
	CFURLRef cfurl = CFURLCreateWithString (NULL, cfurlStr, NULL);

	// Open the URL:
	LSOpenCFURLRef(cfurl, NULL);

	// Release the created resources:
	CFRelease(cfurl);
	CFRelease(cfurlStr);

#elif defined(WIN32)
	ShellExecute(NULL, "open", url.c_str(), NULL, NULL, SW_MAXIMIZE);

#else
	std::string browser = "";

	if (getenv("BROWSER") != NULL) {
		browser = getenv("BROWSER");
	}

	if(browser == "") {
		// test some browsers and take the first found
		std::list<std::string> browsers;
		browsers.push_back("gnome-open");
		browsers.push_back("sensible-browser");
		browsers.push_back("firefox");
		browsers.push_back("mozilla-firefox");
		browsers.push_back("konqueror");
		browsers.push_back("mozilla");
		browsers.push_back("opera");
		browsers.push_back("epiphany");
		browsers.push_back("galeon");
		browsers.push_back("netscape");

		for (std::list<std::string>::const_iterator it = browsers.begin(); it != browsers.end(); ++it) {
			if (::system(("test -x /usr/bin/" + *it + " -o -x /usr/bin/X11/" + *it + " -o -x /usr/local/bin/" + *it).c_str()) == 0) {
				browser = *it;
				break;
			}
		}
	}

	if(browser == "") {
		std::cout << "WARNING: no browser found" << std::endl;
		return;
	} else
		std::cout << "Using " << browser << " as your default browser" << std::endl;

	::system((browser + " " + url + " &").c_str());

#endif
}

<|endoftext|>


<commit_before>/* vim: set sw=4 sts=4 et foldmethod=syntax : */

#include <max_clique/dbmcsa_max_clique.hh>
#include <max_clique/colourise.hh>
#include <max_clique/print_incumbent.hh>
#include <threads/atomic_incumbent.hh>
#include <threads/queue.hh>
#include <graph/degree_sort.hh>
#include <graph/min_width_sort.hh>

#include <algorithm>
#include <list>
#include <functional>
#include <vector>
#include <thread>

using namespace parasols;

namespace
{
    template <unsigned size_>
    struct QueueItem
    {
        FixedBitSet<size_> c;
        FixedBitSet<size_> p;
        unsigned cn;
        std::vector<int> position;
    };

    template <unsigned size_>
    struct StealPoint
    {
        std::mutex mutex;
        std::condition_variable cv;
        bool ready = false;
        FixedBitSet<size_> c;
        FixedBitSet<size_> p;
        std::vector<int> position;
        int skip = 0;
        bool was_stolen = false;
    };

    template <unsigned size_>
    auto found_possible_new_best(const FixedBitGraph<size_> & graph, const std::vector<int> & o,
            const FixedBitSet<size_> & c, int c_popcount,
            const MaxCliqueParams & params, MaxCliqueResult & result, AtomicIncumbent & best_anywhere,
            const std::vector<int> & position) -> void
    {
        if (best_anywhere.update(c_popcount)) {
            result.size = c_popcount;
            result.members.clear();
            for (int i = 0 ; i < graph.size() ; ++i)
                if (c.test(i))
                    result.members.insert(o[i]);
            print_incumbent(params, result.size, position);
        }
    }

    auto bound(unsigned c_popcount, unsigned cn, const MaxCliqueParams & params, AtomicIncumbent & best_anywhere) -> bool
    {
        unsigned best_anywhere_value = best_anywhere.get();
        return (c_popcount + cn <= best_anywhere_value || best_anywhere_value >= params.stop_after_finding);
    }

    template <MaxCliqueOrder order_, unsigned size_>
    auto expand(
            const FixedBitGraph<size_> & graph,
            const std::vector<int> & o,                      // vertex ordering
            Queue<QueueItem<size_> > * const maybe_queue,    // not null if we're populating: enqueue here
            bool blocking_enqueue,
            StealPoint<size_> * const steal_point,
            FixedBitSet<size_> & c,                          // current candidate clique
            FixedBitSet<size_> & p,                          // potential additions
            int skip,
            MaxCliqueResult & result,
            const MaxCliqueParams & params,
            AtomicIncumbent & best_anywhere,
            std::vector<int> & position) -> void
    {
        ++result.nodes;

        auto c_popcount = c.popcount();

        // get our coloured vertices
        std::array<unsigned, size_ * bits_per_word> p_order, colours;
        colourise<size_>(graph, p, p_order, colours);

        // for each v in p... (v comes later)
        for (int n = p.popcount() - 1 ; n >= 0 ; --n) {
            ++position.back();

            // bound, timeout or early exit?
            if (bound(c_popcount, colours[n], params, best_anywhere) || params.abort.load())
                return;

            auto v = p_order[n];

            // consider taking v
            c.set(v);
            ++c_popcount;

            if (skip > 0) {
                --skip;
            }
            else {
                // export stealable?
                if (steal_point) {
                    std::unique_lock<std::mutex> guard(steal_point->mutex);
                    if (steal_point->was_stolen)
                        return;

                    if (! steal_point->ready) {
                        steal_point->c = c;
                        steal_point->p = p;
                        steal_point->position = position;
                        steal_point->skip = 0;
                        steal_point->was_stolen = false;
                        steal_point->ready = true;
                        steal_point->cv.notify_all();
                    }

                    ++steal_point->skip;
                }

                // filter p to contain vertices adjacent to v
                FixedBitSet<size_> new_p = p;
                new_p = p;
                graph.intersect_with_row(v, new_p);

                if (new_p.empty())
                    found_possible_new_best(graph, o, c, c_popcount, params, result, best_anywhere, position);
                else
                {
                    if (maybe_queue) {
                        auto new_position = position;
                        new_position.push_back(0);
                        if (blocking_enqueue)
                            maybe_queue->enqueue_blocking(QueueItem<size_>{ c, std::move(new_p), c_popcount + colours[n], std::move(new_position) }, params.n_threads);
                        else
                            maybe_queue->enqueue(QueueItem<size_>{ c, std::move(new_p), c_popcount + colours[n], std::move(new_position) });
                    }
                    else {
                        position.push_back(0);
                        expand<order_, size_>(graph, o, maybe_queue, false,
                                nullptr, c, new_p, 0, result, params, best_anywhere, position);
                        position.pop_back();
                    }
                }
            }

            // now consider not taking v
            c.unset(v);
            p.unset(v);
            --c_popcount;
        }
    }

    template <MaxCliqueOrder order_, unsigned size_>
    auto max_clique(const FixedBitGraph<size_> & graph, const std::vector<int> & o, const MaxCliqueParams & params) -> MaxCliqueResult
    {
        Queue<QueueItem<size_> > queue{ params.n_threads, false, false }; // work queue
        Queue<QueueItem<size_> > queue_2{ params.n_threads, false, false }; // work queue, depth 2

        MaxCliqueResult result; // global result
        std::mutex result_mutex;

        AtomicIncumbent best_anywhere; // global incumbent
        best_anywhere.update(params.initial_bound);

        std::list<std::thread> threads; // populating thread, and workers

        /* populate */
        threads.push_back(std::thread([&] {
                    MaxCliqueResult tr; // local result

                    FixedBitSet<size_> tc; // local candidate clique
                    tc.resize(graph.size());

                    FixedBitSet<size_> tp; // local potential additions
                    tp.resize(graph.size());
                    tp.set_all();

                    std::vector<int> position;
                    position.reserve(graph.size());
                    position.push_back(0);

                    // populate!
                    expand<order_, size_>(graph, o, &queue, true, nullptr, tc, tp, 0, result, params, best_anywhere, position);

                    // merge results
                    queue.initial_producer_done();
                    std::unique_lock<std::mutex> guard(result_mutex);
                    result.merge(tr);
                    }));

        /* steal points */
        std::vector<StealPoint<size_> > steal_points((params.n_threads));

        /* workers */
        for (unsigned i = 0 ; i < params.n_threads ; ++i) {
            threads.push_back(std::thread([&, i] {
                        auto start_time = std::chrono::steady_clock::now(); // local start time

                        MaxCliqueResult tr; // local result

                        auto * current_queue = &queue;
                        auto * next_queue = &queue_2;
                        while (true) {
                            while (true) {
                                // clear steal point
                                {
                                    std::unique_lock<std::mutex> guard(steal_points[i].mutex);
                                    steal_points[i].ready = true;
                                    steal_points[i].p = FixedBitSet<size_>();
                                    steal_points[i].cv.notify_all();
                                }

                                // get some work to do
                                QueueItem<size_> args;
                                if (! current_queue->dequeue_blocking(args))
                                    break;

                                // re-evaluate the bound against our new best
                                if (args.cn <= best_anywhere.get())
                                    continue;

                                // not ready to be stolen from yet
                                {
                                    std::unique_lock<std::mutex> guard(steal_points[i].mutex);
                                    steal_points[i].ready = false;
                                }

                                // do some work
                                expand<order_, size_>(graph, o, nullptr, false, &steal_points[i],
                                        args.c, args.p, 0, tr, params, best_anywhere, args.position);
                            }

                            if (! next_queue)
                                break;

                            if (next_queue->want_producer()) {
                                for (auto & s : steal_points) {
                                    std::unique_lock<std::mutex> guard(s.mutex);
                                    while (! s.ready)
                                        s.cv.wait(guard);

                                    s.was_stolen = true;
                                    auto c = s.c;
                                    auto p = s.p;
                                    auto skip = s.skip;
                                    auto position = s.position;
                                    guard.unlock();

                                    expand<order_, size_>(graph, o, next_queue, false, nullptr, c, p, skip, tr, params, best_anywhere, position);
                                }

                                next_queue->initial_producer_done();
                            }

                            current_queue = next_queue;
                            next_queue = nullptr;
                        }

                        auto overall_time = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start_time);

                        // merge results
                        {
                            std::unique_lock<std::mutex> guard(result_mutex);
                            result.merge(tr);
                            result.times.push_back(overall_time);
                        }
                        }));
        }

        // wait until they're done, and clean up threads
        for (auto & t : threads)
            t.join();

        return result;
    }

    template <MaxCliqueOrder order_, unsigned size_>
    auto dbmcsa(const Graph & graph, const MaxCliqueParams & params) -> MaxCliqueResult
    {
        std::vector<int> o(graph.size()); // vertex ordering
        std::iota(o.begin(), o.end(), 0);

        switch (order_) {
            case MaxCliqueOrder::Degree:
                degree_sort(graph, o, false);
                break;
            case MaxCliqueOrder::MinWidth:
                min_width_sort(graph, o, false);
                break;
            case MaxCliqueOrder::ExDegree:
                exdegree_sort(graph, o, false);
                break;
            case MaxCliqueOrder::DynExDegree:
                dynexdegree_sort(graph, o, false);
                break;
        }

        // re-encode graph as a bit graph
        FixedBitGraph<size_> bit_graph;
        bit_graph.resize(graph.size());

        for (int i = 0 ; i < graph.size() ; ++i)
            for (int j = 0 ; j < graph.size() ; ++j)
                if (graph.adjacent(o[i], o[j]))
                    bit_graph.add_edge(i, j);

        // go!
        return max_clique<order_>(bit_graph, o, params);
    }
}

template <MaxCliqueOrder order_>
auto parasols::dbmcsa_max_clique(const Graph & graph, const MaxCliqueParams & params) -> MaxCliqueResult
{
    /* This is pretty horrible: in order to avoid dynamic allocation, select
     * the appropriate specialisation for our graph's size. */
    static_assert(max_graph_words == 1024, "Need to update here if max_graph_size is changed.");
    if (graph.size() < bits_per_word)
        return dbmcsa<order_, 1>(graph, params);
    else if (graph.size() < 2 * bits_per_word)
        return dbmcsa<order_, 2>(graph, params);
    else if (graph.size() < 4 * bits_per_word)
        return dbmcsa<order_, 4>(graph, params);
    else if (graph.size() < 8 * bits_per_word)
        return dbmcsa<order_, 8>(graph, params);
    else if (graph.size() < 16 * bits_per_word)
        return dbmcsa<order_, 16>(graph, params);
    else if (graph.size() < 32 * bits_per_word)
        return dbmcsa<order_, 32>(graph, params);
    else if (graph.size() < 64 * bits_per_word)
        return dbmcsa<order_, 64>(graph, params);
    else if (graph.size() < 128 * bits_per_word)
        return dbmcsa<order_, 128>(graph, params);
    else if (graph.size() < 256 * bits_per_word)
        return dbmcsa<order_, 256>(graph, params);
    else if (graph.size() < 512 * bits_per_word)
        return dbmcsa<order_, 512>(graph, params);
    else if (graph.size() < 1024 * bits_per_word)
        return dbmcsa<order_, 1024>(graph, params);
    else
        throw GraphTooBig();
}

template auto parasols::dbmcsa_max_clique<MaxCliqueOrder::Degree>(const Graph &, const MaxCliqueParams &) -> MaxCliqueResult;
template auto parasols::dbmcsa_max_clique<MaxCliqueOrder::MinWidth>(const Graph &, const MaxCliqueParams &) -> MaxCliqueResult;
template auto parasols::dbmcsa_max_clique<MaxCliqueOrder::ExDegree>(const Graph &, const MaxCliqueParams &) -> MaxCliqueResult;
template auto parasols::dbmcsa_max_clique<MaxCliqueOrder::DynExDegree>(const Graph &, const MaxCliqueParams &) -> MaxCliqueResult;

<commit_msg>Cleaner steal points<commit_after>/* vim: set sw=4 sts=4 et foldmethod=syntax : */

#include <max_clique/dbmcsa_max_clique.hh>
#include <max_clique/colourise.hh>
#include <max_clique/print_incumbent.hh>
#include <threads/atomic_incumbent.hh>
#include <threads/queue.hh>
#include <graph/degree_sort.hh>
#include <graph/min_width_sort.hh>

#include <algorithm>
#include <list>
#include <functional>
#include <vector>
#include <thread>

using namespace parasols;

namespace
{
    template <unsigned size_>
    struct QueueItem
    {
        FixedBitSet<size_> c;
        FixedBitSet<size_> p;
        unsigned cn;
        std::vector<int> position;
    };

    template <unsigned size_>
    struct StealPoint
    {
        std::mutex mutex;
        std::condition_variable cv;
        bool ready = false;
        FixedBitSet<size_> c;
        FixedBitSet<size_> p;
        std::vector<int> position;
        int skip = 0;
        bool was_stolen = false;

        void not_ready()
        {
            std::unique_lock<std::mutex> guard(mutex);
            ready = false;
            was_stolen = false;
            skip = 0;
        }

        void finished()
        {
            std::unique_lock<std::mutex> guard(mutex);
            ready = true;
            was_stolen = false;
            skip = 0;
            p = FixedBitSet<size_>();
            cv.notify_all();
        }
    };

    template <unsigned size_>
    auto found_possible_new_best(const FixedBitGraph<size_> & graph, const std::vector<int> & o,
            const FixedBitSet<size_> & c, int c_popcount,
            const MaxCliqueParams & params, MaxCliqueResult & result, AtomicIncumbent & best_anywhere,
            const std::vector<int> & position) -> void
    {
        if (best_anywhere.update(c_popcount)) {
            result.size = c_popcount;
            result.members.clear();
            for (int i = 0 ; i < graph.size() ; ++i)
                if (c.test(i))
                    result.members.insert(o[i]);
            print_incumbent(params, result.size, position);
        }
    }

    auto bound(unsigned c_popcount, unsigned cn, const MaxCliqueParams & params, AtomicIncumbent & best_anywhere) -> bool
    {
        unsigned best_anywhere_value = best_anywhere.get();
        return (c_popcount + cn <= best_anywhere_value || best_anywhere_value >= params.stop_after_finding);
    }

    template <MaxCliqueOrder order_, unsigned size_>
    auto expand(
            const FixedBitGraph<size_> & graph,
            const std::vector<int> & o,                      // vertex ordering
            Queue<QueueItem<size_> > * const maybe_queue,    // not null if we're populating: enqueue here
            bool blocking_enqueue,
            StealPoint<size_> * const steal_point,
            FixedBitSet<size_> & c,                          // current candidate clique
            FixedBitSet<size_> & p,                          // potential additions
            int skip,
            MaxCliqueResult & result,
            const MaxCliqueParams & params,
            AtomicIncumbent & best_anywhere,
            std::vector<int> & position) -> void
    {
        ++result.nodes;

        auto c_popcount = c.popcount();

        // get our coloured vertices
        std::array<unsigned, size_ * bits_per_word> p_order, colours;
        colourise<size_>(graph, p, p_order, colours);

        // for each v in p... (v comes later)
        for (int n = p.popcount() - 1 ; n >= 0 ; --n) {
            ++position.back();

            // bound, timeout or early exit?
            if (bound(c_popcount, colours[n], params, best_anywhere) || params.abort.load())
                return;

            auto v = p_order[n];

            // consider taking v
            c.set(v);
            ++c_popcount;

            if (skip > 0) {
                --skip;
            }
            else {
                // export stealable?
                if (steal_point) {
                    std::unique_lock<std::mutex> guard(steal_point->mutex);
                    if (steal_point->was_stolen)
                        return;

                    if (! steal_point->ready) {
                        steal_point->c = c;
                        steal_point->p = p;
                        steal_point->position = position;
                        steal_point->skip = 0;
                        steal_point->was_stolen = false;
                        steal_point->ready = true;
                        steal_point->cv.notify_all();
                    }

                    ++steal_point->skip;
                }

                // filter p to contain vertices adjacent to v
                FixedBitSet<size_> new_p = p;
                new_p = p;
                graph.intersect_with_row(v, new_p);

                if (new_p.empty())
                    found_possible_new_best(graph, o, c, c_popcount, params, result, best_anywhere, position);
                else
                {
                    if (maybe_queue) {
                        auto new_position = position;
                        new_position.push_back(0);
                        if (blocking_enqueue)
                            maybe_queue->enqueue_blocking(QueueItem<size_>{ c, std::move(new_p), c_popcount + colours[n], std::move(new_position) }, params.n_threads);
                        else
                            maybe_queue->enqueue(QueueItem<size_>{ c, std::move(new_p), c_popcount + colours[n], std::move(new_position) });
                    }
                    else {
                        position.push_back(0);
                        expand<order_, size_>(graph, o, maybe_queue, false,
                                nullptr, c, new_p, 0, result, params, best_anywhere, position);
                        position.pop_back();
                    }
                }
            }

            // now consider not taking v
            c.unset(v);
            p.unset(v);
            --c_popcount;
        }
    }

    template <MaxCliqueOrder order_, unsigned size_>
    auto max_clique(const FixedBitGraph<size_> & graph, const std::vector<int> & o, const MaxCliqueParams & params) -> MaxCliqueResult
    {
        Queue<QueueItem<size_> > queue{ params.n_threads, false, false }; // work queue
        Queue<QueueItem<size_> > queue_2{ params.n_threads, false, false }; // work queue, depth 2

        MaxCliqueResult result; // global result
        std::mutex result_mutex;

        AtomicIncumbent best_anywhere; // global incumbent
        best_anywhere.update(params.initial_bound);

        std::list<std::thread> threads; // populating thread, and workers

        /* populate */
        threads.push_back(std::thread([&] {
                    MaxCliqueResult tr; // local result

                    FixedBitSet<size_> tc; // local candidate clique
                    tc.resize(graph.size());

                    FixedBitSet<size_> tp; // local potential additions
                    tp.resize(graph.size());
                    tp.set_all();

                    std::vector<int> position;
                    position.reserve(graph.size());
                    position.push_back(0);

                    // populate!
                    expand<order_, size_>(graph, o, &queue, true, nullptr, tc, tp, 0, result, params, best_anywhere, position);

                    // merge results
                    queue.initial_producer_done();
                    std::unique_lock<std::mutex> guard(result_mutex);
                    result.merge(tr);
                    }));

        /* steal points */
        std::vector<StealPoint<size_> > steal_points((params.n_threads));

        /* workers */
        for (unsigned i = 0 ; i < params.n_threads ; ++i) {
            threads.push_back(std::thread([&, i] {
                        auto start_time = std::chrono::steady_clock::now(); // local start time

                        MaxCliqueResult tr; // local result

                        auto * current_queue = &queue;
                        auto * next_queue = &queue_2;
                        while (true) {
                            while (true) {
                                // get some work to do
                                QueueItem<size_> args;
                                if (! current_queue->dequeue_blocking(args))
                                    break;

                                // re-evaluate the bound against our new best
                                if (args.cn <= best_anywhere.get())
                                    continue;

                                steal_points[i].not_ready();

                                // do some work
                                expand<order_, size_>(graph, o, nullptr, false, &steal_points[i],
                                        args.c, args.p, 0, tr, params, best_anywhere, args.position);

                                steal_points[i].not_ready();
                            }

                            steal_points[i].finished();

                            if (! next_queue)
                                break;

                            if (next_queue->want_producer()) {
                                for (auto & s : steal_points) {
                                    std::unique_lock<std::mutex> guard(s.mutex);
                                    while (! s.ready)
                                        s.cv.wait(guard);

                                    s.was_stolen = true;
                                    auto c = s.c;
                                    auto p = s.p;
                                    auto skip = s.skip;
                                    auto position = s.position;
                                    guard.unlock();

                                    expand<order_, size_>(graph, o, next_queue, false, nullptr, c, p, skip, tr, params, best_anywhere, position);
                                }

                                next_queue->initial_producer_done();
                            }

                            current_queue = next_queue;
                            next_queue = nullptr;
                        }

                        auto overall_time = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start_time);

                        // merge results
                        {
                            std::unique_lock<std::mutex> guard(result_mutex);
                            result.merge(tr);
                            result.times.push_back(overall_time);
                        }
                        }));
        }

        // wait until they're done, and clean up threads
        for (auto & t : threads)
            t.join();

        return result;
    }

    template <MaxCliqueOrder order_, unsigned size_>
    auto dbmcsa(const Graph & graph, const MaxCliqueParams & params) -> MaxCliqueResult
    {
        std::vector<int> o(graph.size()); // vertex ordering
        std::iota(o.begin(), o.end(), 0);

        switch (order_) {
            case MaxCliqueOrder::Degree:
                degree_sort(graph, o, false);
                break;
            case MaxCliqueOrder::MinWidth:
                min_width_sort(graph, o, false);
                break;
            case MaxCliqueOrder::ExDegree:
                exdegree_sort(graph, o, false);
                break;
            case MaxCliqueOrder::DynExDegree:
                dynexdegree_sort(graph, o, false);
                break;
        }

        // re-encode graph as a bit graph
        FixedBitGraph<size_> bit_graph;
        bit_graph.resize(graph.size());

        for (int i = 0 ; i < graph.size() ; ++i)
            for (int j = 0 ; j < graph.size() ; ++j)
                if (graph.adjacent(o[i], o[j]))
                    bit_graph.add_edge(i, j);

        // go!
        return max_clique<order_>(bit_graph, o, params);
    }
}

template <MaxCliqueOrder order_>
auto parasols::dbmcsa_max_clique(const Graph & graph, const MaxCliqueParams & params) -> MaxCliqueResult
{
    /* This is pretty horrible: in order to avoid dynamic allocation, select
     * the appropriate specialisation for our graph's size. */
    static_assert(max_graph_words == 1024, "Need to update here if max_graph_size is changed.");
    if (graph.size() < bits_per_word)
        return dbmcsa<order_, 1>(graph, params);
    else if (graph.size() < 2 * bits_per_word)
        return dbmcsa<order_, 2>(graph, params);
    else if (graph.size() < 4 * bits_per_word)
        return dbmcsa<order_, 4>(graph, params);
    else if (graph.size() < 8 * bits_per_word)
        return dbmcsa<order_, 8>(graph, params);
    else if (graph.size() < 16 * bits_per_word)
        return dbmcsa<order_, 16>(graph, params);
    else if (graph.size() < 32 * bits_per_word)
        return dbmcsa<order_, 32>(graph, params);
    else if (graph.size() < 64 * bits_per_word)
        return dbmcsa<order_, 64>(graph, params);
    else if (graph.size() < 128 * bits_per_word)
        return dbmcsa<order_, 128>(graph, params);
    else if (graph.size() < 256 * bits_per_word)
        return dbmcsa<order_, 256>(graph, params);
    else if (graph.size() < 512 * bits_per_word)
        return dbmcsa<order_, 512>(graph, params);
    else if (graph.size() < 1024 * bits_per_word)
        return dbmcsa<order_, 1024>(graph, params);
    else
        throw GraphTooBig();
}

template auto parasols::dbmcsa_max_clique<MaxCliqueOrder::Degree>(const Graph &, const MaxCliqueParams &) -> MaxCliqueResult;
template auto parasols::dbmcsa_max_clique<MaxCliqueOrder::MinWidth>(const Graph &, const MaxCliqueParams &) -> MaxCliqueResult;
template auto parasols::dbmcsa_max_clique<MaxCliqueOrder::ExDegree>(const Graph &, const MaxCliqueParams &) -> MaxCliqueResult;
template auto parasols::dbmcsa_max_clique<MaxCliqueOrder::DynExDegree>(const Graph &, const MaxCliqueParams &) -> MaxCliqueResult;

<|endoftext|>


<commit_before>#include "ingamescene.h"
#include <QPixmap>
#include <QtGlobal>
#include "../dice.h"
#include <QTimeLine>
#include <QEasingCurve>
#include "block.h"

IngameScene::IngameScene(qreal x, qreal y,
                         qreal width, qreal height,
                         QObject *parent)
    : QGraphicsScene(x,y,width,height,parent), window(dynamic_cast<MainWindow*>(parent))
{
    Q_CHECK_PTR(window);

    setBackgroundPixmap(":/images/ingame/background_test.jpg");

    board = new Board(this,window);
    board->setPos(200,10);

    player = new Player(board,1);
    player->setImage(":/images/ingame/pieces/blue.png");
    player->setPos(BlockCoords::corner_coord[0]);
    player->setZValue(3);

    //주사위 그래픽
    dice_graphic = new DiceGraphicItem(this,window);
    dice_graphic->setPos(800,400);
    dice_graphic->setZValue(2);

    //주사위 패널 첫번째
    first_dice_panel = new DiceValuePanel(this,window);
    first_dice_panel->setPos(400,400);
    first_dice_panel->setZValue(2);
    //주사위 패널 두번째
    second_dice_panel = new DiceValuePanel(this,window);
    second_dice_panel->setPos(500,400);
    second_dice_panel->setZValue(2);

    //Signal / Slots connection
    Dice * dice = Dice::getInst();
    connect(dice,SIGNAL(diceRolled(int)),player,SLOT(walkBy(int)));
    connect(dice,SIGNAL(firstDiceRolled(int)),first_dice_panel,SLOT(setValue(int)));
    connect(dice,SIGNAL(secondDiceRolled(int)),second_dice_panel,SLOT(setValue(int)));
}

IngameScene::~IngameScene(){
    delete first_dice_panel;
    delete second_dice_panel;
    delete dice_graphic;
    delete background;
}

QGraphicsPixmapItem* IngameScene::setBackgroundPixmap(const char * filename){
    background = this->addPixmap(QPixmap(filename));
    return background;
}

QGraphicsPixmapItem* IngameScene::backgroundPixmap(){
    return background;
}

DiceGraphicItem::DiceGraphicItem(QGraphicsScene *scene, MainWindow *window)
    : QGameItem(scene,window){
    //버튼 초기상태 이미지
    this->setImage(":/images/ingame/button.png");
}

void DiceGraphicItem::mousePressEvent(QGraphicsSceneMouseEvent *event){
    //버튼이 눌렸을 때의 이미지로 바꿈
    this->setImage(":/images/ingame/button2_pushed.png");
    //QGameItem::mousePressEvent(event);

}

void DiceGraphicItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event){
    //마우스에서 땠을 경우 다시 초기상태 이미지로 바꿈
    this->setImage(":/images/ingame/button.png");
    //여기에 게임 스테이트 머신을 추가해서 롤할지 안할지 결정하게 해야함
    Dice * dice = Dice::getInst();
    dice->roll();

}

DiceValuePanel::DiceValuePanel(QGraphicsScene *scene, MainWindow *window)
    : QGameItem(scene,window)
{
    setImage(":/images/ingame/dice/dice3.png"); //default image
    timeline = new QTimeLine(1500); //spin for 1.5 second
    timeline->setFrameRange(0,50); // 50 spins
    timeline->setEasingCurve(QEasingCurve::InOutCirc);
    connect(this->timeline,SIGNAL(frameChanged(int)),this,SLOT(spinValue(int)));
    connect(timeline,SIGNAL(finished()),this,SLOT(endSpin()));
}

void DiceValuePanel::endSpin(){
    //finally fix dice image to diceValue
    switch(diceValue){
    case 1:
        this->setImage(":/images/ingame/dice/dice1.png");
        break;
    case 2:
        this->setImage(":/images/ingame/dice/dice2.png");
        break;
    case 3:
        this->setImage(":/images/ingame/dice/dice3.png");
        break;
    case 4:
        this->setImage(":/images/ingame/dice/dice4.png");
        break;
    case 5:
        this->setImage(":/images/ingame/dice/dice5.png");
        break;
    case 6:
        this->setImage(":/images/ingame/dice/dice6.png");
        break;
    }
}

void DiceValuePanel::setValue(int value){
    diceValue = value;
    timeline->start();
}

void DiceValuePanel::spinValue(int frame){
    int value = rand() % 6 + 1;
    switch(value){
    case 1:
        this->setImage(":/images/ingame/dice/dice1.png");
        break;
    case 2:
        this->setImage(":/images/ingame/dice/dice2.png");
        break;
    case 3:
        this->setImage(":/images/ingame/dice/dice3.png");
        break;
    case 4:
        this->setImage(":/images/ingame/dice/dice4.png");
        break;
    case 5:
        this->setImage(":/images/ingame/dice/dice5.png");
        break;
    case 6:
        this->setImage(":/images/ingame/dice/dice6.png");
        break;
    }
}

void DiceValuePanel::mousePressEvent(QGraphicsSceneMouseEvent *event){

}

void DiceValuePanel::mouseReleaseEvent(QGraphicsSceneMouseEvent *event){

}
<commit_msg>Ingamescene: managed by localgame instance<commit_after>#include "ingamescene.h"
#include <QPixmap>
#include <QtGlobal>
#include "../dice.h"
#include <QTimeLine>
#include <QEasingCurve>
#include "block.h"
#include "localgame.h"

IngameScene::IngameScene(qreal x, qreal y,
                         qreal width, qreal height,
                         QObject *parent)
    : QGraphicsScene(x,y,width,height,parent), window(dynamic_cast<MainWindow*>(parent))
{
    Q_CHECK_PTR(window);

    setBackgroundPixmap(":/images/ingame/background_test.jpg");

    board = new Board(this,window);
    board->setPos(200,720-board->boundingRect().size().height());

    player = new Player(board,1);
    player->setImage(":/images/ingame/pieces/blue.png");
    player->setPos(BlockCoords::corner_coord[0]);
    player->setZValue(3);

    LocalGame * game = LocalGame::getInst();
    game->addPlayer(player);
    game->init(board,Dice::getInst());

    //주사위 그래픽
    dice_graphic = new DiceGraphicItem(this,window);
    dice_graphic->setPos(800,400);
    dice_graphic->setZValue(2);

    //주사위 패널 첫번째
    first_dice_panel = new DiceValuePanel(this,window);
    first_dice_panel->setPos(400,400);
    first_dice_panel->setZValue(2);
    //주사위 패널 두번째
    second_dice_panel = new DiceValuePanel(this,window);
    second_dice_panel->setPos(500,400);
    second_dice_panel->setZValue(2);

    //Signal / Slots connection
    Dice * dice = Dice::getInst();
    connect(dice,SIGNAL(firstDiceRolled(int)),first_dice_panel,SLOT(setValue(int)));
    connect(dice,SIGNAL(secondDiceRolled(int)),second_dice_panel,SLOT(setValue(int)));
}

IngameScene::~IngameScene(){
    delete first_dice_panel;
    delete second_dice_panel;
    delete dice_graphic;
    delete background;
}

QGraphicsPixmapItem* IngameScene::setBackgroundPixmap(const char * filename){
    background = this->addPixmap(QPixmap(filename));
    return background;
}

QGraphicsPixmapItem* IngameScene::backgroundPixmap(){
    return background;
}

DiceGraphicItem::DiceGraphicItem(QGraphicsScene *scene, MainWindow *window)
    : QGameItem(scene,window){
    //버튼 초기상태 이미지
    this->setImage(":/images/ingame/button.png");
}

void DiceGraphicItem::mousePressEvent(QGraphicsSceneMouseEvent *event){
    //버튼이 눌렸을 때의 이미지로 바꿈
    this->setImage(":/images/ingame/button2_pushed.png");
    //QGameItem::mousePressEvent(event);

}

void DiceGraphicItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event){
    //마우스에서 땠을 경우 다시 초기상태 이미지로 바꿈
    this->setImage(":/images/ingame/button.png");
    //여기에 게임 스테이트 머신을 추가해서 롤할지 안할지 결정하게 해야함
    Dice * dice = Dice::getInst();
    dice->roll();

}

DiceValuePanel::DiceValuePanel(QGraphicsScene *scene, MainWindow *window)
    : QGameItem(scene,window)
{
    setImage(":/images/ingame/dice/dice3.png"); //default image
    timeline = new QTimeLine(1500); //spin for 1.5 second
    timeline->setFrameRange(0,50); // 50 spins
    timeline->setEasingCurve(QEasingCurve::InOutCirc);
    connect(this->timeline,SIGNAL(frameChanged(int)),this,SLOT(spinValue(int)));
    connect(timeline,SIGNAL(finished()),this,SLOT(endSpin()));
}

void DiceValuePanel::endSpin(){
    //finally fix dice image to diceValue
    switch(diceValue){
    case 1:
        this->setImage(":/images/ingame/dice/dice1.png");
        break;
    case 2:
        this->setImage(":/images/ingame/dice/dice2.png");
        break;
    case 3:
        this->setImage(":/images/ingame/dice/dice3.png");
        break;
    case 4:
        this->setImage(":/images/ingame/dice/dice4.png");
        break;
    case 5:
        this->setImage(":/images/ingame/dice/dice5.png");
        break;
    case 6:
        this->setImage(":/images/ingame/dice/dice6.png");
        break;
    }
}

void DiceValuePanel::setValue(int value){
    diceValue = value;
    timeline->start();
}

void DiceValuePanel::spinValue(int frame){
    int value = rand() % 6 + 1;
    switch(value){
    case 1:
        this->setImage(":/images/ingame/dice/dice1.png");
        break;
    case 2:
        this->setImage(":/images/ingame/dice/dice2.png");
        break;
    case 3:
        this->setImage(":/images/ingame/dice/dice3.png");
        break;
    case 4:
        this->setImage(":/images/ingame/dice/dice4.png");
        break;
    case 5:
        this->setImage(":/images/ingame/dice/dice5.png");
        break;
    case 6:
        this->setImage(":/images/ingame/dice/dice6.png");
        break;
    }
}

void DiceValuePanel::mousePressEvent(QGraphicsSceneMouseEvent *event){

}

void DiceValuePanel::mouseReleaseEvent(QGraphicsSceneMouseEvent *event){

}
<|endoftext|>