no message

no message

--- DesktopEditor/doctrenderer/test_builder/docbuilder/doctrendererwrapper/doctrendererwrapper.cpp
+++ DesktopEditor/doctrenderer/test_builder/docbuilder/doctrendererwrapper/doctrendererwrapper.cpp
@@ -6,9 +6,9 @@
 #include "../../../docbuilder.h"

 #ifdef _WIN64
-#pragma comment(lib, "../../../../../SDK/lib/win_64/doctrenderer.lib")
+#pragma comment(lib, "../../../../../build/lib/win_64/doctrenderer.lib")
 #else
-#pragma comment(lib, "../../../../../SDK/lib/win_32/doctrenderer.lib")
+#pragma comment(lib, "../../../../../build/lib/win_32/doctrenderer.lib")
 #endif

 namespace doctrendererwrapper {


battery power first draft

battery power first draft

--- PowerMeter.cpp
+++ PowerMeter.cpp
@@ -1,6 +1,8 @@
 // Do not remove the include below
 #include "Arduino.h"
 #include <avr/pgmspace.h>
+#include <avr/sleep.h>
+#include <avr/interrupt.h>
 #include <avr/power.h>
 #include <EEPROM.h>

@@ -161,6 +163,7 @@
     movingAverage::clear();

     calibrate::SetCalibrationConstantsFromEEPROM();
+    digitalWrite(PanelLampsPinOut,	HIGH); // turn on front panel lights on boot

 #if defined(DEBUG_SERIAL)
     Serial.begin(9600);
@@ -177,10 +180,14 @@
 	void doAloSetup();
 }

+namespace sleep {
+	void SleepNow();
+}
+
 namespace {
 	void sample();
 	uint8_t DisplaySwr();
-	void FrontPanelLamps();
+	bool FrontPanelLamps();
 	enum SetupMode_t {METER_NORMAL, ALO_SETUP, CALIBRATE_SETUP};
 	enum EEPROM_ASSIGNMENTS {EEPROM_SWR_LOCK, EEPROM_PWR_LOCK, EEPROM_FWD_CALIBRATION, EEPROM_REFL_CALIBRATION};

@@ -353,7 +360,6 @@
 	  }
 #endif
 	  SwrUpdateTime = now;
-	  FrontPanelLamps();
 	  uint8_t swr = DisplaySwr();
 	  DisplayPower_t pwr;
 	  if (digitalRead(PeakSwitchPinIn) == LOW)
@@ -367,6 +373,8 @@
 		  Alo::CheckAloSwr(swr);
 	  else
 		  Alo::CheckAloPwr();
+	  if (!FrontPanelLamps())
+		  sleep::SleepNow();
   }

   unsigned long nowusec = micros();
@@ -966,14 +974,17 @@
 	return (uint8_t)v;
 }

-void FrontPanelLamps()
+bool FrontPanelLamps()
 {
 	if (digitalRead(PanelLampsPinOut) == HIGH)
 	{
 		unsigned long timeOn = millis() - coupler7dot5LastHeardMillis;
 		if ( timeOn > FrontPanelLampsOnMsec)
 			digitalWrite(PanelLampsPinOut,	LOW);
-	}
+		return true;
+	}
+	else
+		return false;
 }

 DisplayPower_t SquareToWatts(DisplayPower_t s)
@@ -1590,3 +1601,30 @@

 }
 }
+
+namespace sleep {
+	void Coupler7dot5Interrupt()
+	{
+		detachInterrupt(digitalPinToInterrupt(coupler7dot5VPinIn));
+	}
+
+	void AloRevInterrupt()
+	{
+		detachInterrupt(digitalPinToInterrupt(ALOtripSwitchPinIn));
+	}
+
+	void SleepNow()
+	{
+		set_sleep_mode(SLEEP_MODE_PWR_DOWN);
+		cli();
+		attachInterrupt(digitalPinToInterrupt(coupler7dot5VPinIn), Coupler7dot5Interrupt, LOW);
+		attachInterrupt(digitalPinToInterrupt(ALOtripSwitchPinIn), AloRevInterrupt, LOW);
+		sleep_enable();
+		sleep_bod_disable();
+		sei();
+		sleep_cpu();
+		sleep_disable();
+		sei();
+	}
+}
+


EDA221/Assignment2: Disable culling by default + add culling modes

--- src/EDA221/assignment2.cpp
+++ src/EDA221/assignment2.cpp
@@ -121,7 +121,9 @@
 	glEnable(GL_DEPTH_TEST);

 	// Enable face culling to improve performance
-	glEnable(GL_CULL_FACE);
+	//glEnable(GL_CULL_FACE);
+	//glCullFace(GL_FRONT);
+	//glCullFace(GL_BACK);

 	f64 ddeltatime;


GL_SHADER_COMPILER returns GL_FALSE for ANGLE_PLATFORM_WP8

--- src/libGLESv2/Context.cpp
+++ src/libGLESv2/Context.cpp
@@ -1185,7 +1185,11 @@
 {
     switch (pname)
     {
+#if defined(ANGLE_PLATFORM_WP8)
+      case GL_SHADER_COMPILER:           *params = GL_FALSE;                            break;
+#else
       case GL_SHADER_COMPILER:           *params = GL_TRUE;                             break;
+#endif
       case GL_SAMPLE_COVERAGE_INVERT:    *params = mState.sampleCoverageInvert;         break;
       case GL_DEPTH_WRITEMASK:           *params = mState.depthStencil.depthMask;       break;
       case GL_COLOR_WRITEMASK:


Implemented variable assignment.

Implemented variable assignment.

--- bf/compiler.cpp
+++ bf/compiler.cpp
@@ -322,7 +322,7 @@

     void operator()(const expression::unary_operation_t<expression::operator_t::not_> &e) {
         boost::apply_visitor(*this, e.expression);
-        m_var_stack.back()->bool_not(*m_var_stack.back()); // TODO: Implement 'self' case in generator.
+        m_var_stack.back()->bool_not(*m_var_stack.back());
     }

     void operator()(const expression::binary_operation_t<expression::operator_t::plus> &e) {
@@ -431,13 +431,15 @@
         else {
             auto var_ptr = m_bfg.new_var(i.variable_name);
             m_scope.back().emplace(i.variable_name, var_ptr);
-            boost::apply_visitor(expression_visitor(m_bfg, m_scope, var_ptr), i.expression);
+            auto visitor = expression_visitor(m_bfg, m_scope, var_ptr);
+            boost::apply_visitor(visitor, i.expression);
         }
     }

     // ----- Variable assignment ----------------------------------------------
     void operator()(const instruction::variable_assignment_t &i) {
-        // TODO: Assign expression value
+        auto visitor = expression_visitor(m_bfg, m_scope, get_var(i.variable_name));
+        boost::apply_visitor(visitor, i.expression);
     }

     // ----- Print variable ---------------------------------------------------


Drop ':' if the source file name is empty

A large number of tests compile contracts while passing in an empty
string for the source name.  This leads to it being keyed by the name
":<contract>", while the tests try to look it up under the name
"<contract>".  This change resolves that issue by dropping the ':' in
cases where there is, effectively, no source file to prepend anyway.

--- libsolidity/ast/AST.cpp
+++ libsolidity/ast/AST.cpp
@@ -192,7 +192,8 @@

 std::string ContractDefinition::fullyQualifiedName() const
 {
-	std::string qualifiedName = *(location().sourceName) + ":" + name();
+	std::string sourceString = *(location().sourceName);
+	std::string qualifiedName = (sourceString.empty() ? ("") : (sourceString + ":")) + name();
 	return qualifiedName;
 }


Fix format by changing to LLVM style (#3008)

The file implements compiler code and should roughly follow LLVM style.

--- iree/compiler/Conversion/HLOToLinalg/HLOToLinalgOnTensors.cpp
+++ iree/compiler/Conversion/HLOToLinalg/HLOToLinalgOnTensors.cpp
@@ -56,13 +56,13 @@
     // Don't convert the body of reduction ops.
     target.addDynamicallyLegalDialect<mhlo::MhloDialect>(
         Optional<ConversionTarget::DynamicLegalityCallbackFn>(
-            [](Operation* op) {
+            [](Operation *op) {
               auto parentOp = op->getParentRegion()->getParentOp();
               return isa<mhlo::ReduceOp>(parentOp) ||
                      isa<mhlo::ReduceWindowOp>(parentOp);
             }));
     // Let the rest fall through.
-    target.markUnknownOpDynamicallyLegal([](Operation*) { return true; });
+    target.markUnknownOpDynamicallyLegal([](Operation *) { return true; });

     if (failed(applyPartialConversion(getFunction(), target, patterns))) {
       signalPassFailure();
@@ -73,7 +73,7 @@
 }  // namespace

 void populateHLOToLinalgOnTensorsConversionPatterns(
-    MLIRContext* context, OwningRewritePatternList& patterns) {
+    MLIRContext *context, OwningRewritePatternList &patterns) {
   mhlo::populateHLOToLinalgConversionPattern(context, &patterns);
 }


Install new program binary when current program is successfully relinked or reloaded

Trac #21270
Bug=351
Signed-off-by: Nicolas Capens

git-svn-id: 947ae547afacb859f3991e003b9d6feb04be57d7@1240 736b8ea6-26fd-11df-bfd4-992fa37f6226

--- src/libGLESv2/Context.cpp
+++ src/libGLESv2/Context.cpp
@@ -1167,14 +1167,31 @@
 {
     Program *programObject = mResourceManager->getProgram(program);

-    programObject->link();
+    bool linked = programObject->link();
+
+    // if the current program was relinked successfully we
+    // need to install the new executables
+    if (linked && program == mState.currentProgram)
+    {
+        mCurrentProgramBinary = programObject->getProgramBinary();
+        mDxUniformsDirty = true;
+    }
 }

 void Context::setProgramBinary(GLuint program, const void *binary, GLint length)
 {
     Program *programObject = mResourceManager->getProgram(program);

-    programObject->setProgramBinary(binary, length);
+    bool loaded = programObject->setProgramBinary(binary, length);
+
+    // if the current program was reloaded successfully we
+    // need to install the new executables
+    if (loaded && program == mState.currentProgram)
+    {
+        mCurrentProgramBinary = programObject->getProgramBinary();
+        mDxUniformsDirty = true;
+    }
+
 }

 void Context::beginQuery(GLenum target, GLuint query)


Rename the configuration property

Rename the configuration property

--- src/driver.cpp
+++ src/driver.cpp
@@ -97,14 +97,14 @@
     wiringPiSetup();

     rc_switch = RCSwitch();
-    rc_switch.enableReceive(asgard::get_int_value(config, "rf_gpio_pin"));
+    rc_switch.enableReceive(asgard::get_int_value(config, "rf_gpio_in_pin"));

     //Drop root privileges and run as pi:pi again
     if(!asgard::revoke_root()){
        std::cout << "asgard:rf: unable to revoke root privileges, exiting..." << std::endl;
        return 1;
     }
-
+
     // Load the configuration file
     asgard::load_config(config);


INTEGRATION: CWS impress31 (1.48.16); FILE MERGED 2005/01/28 09:06:56 cl 1.48.16.1: #i32920# added SdPage::getPresentationStyle()

--- sd/source/core/sdpage.cxx
+++ sd/source/core/sdpage.cxx
@@ -2,9 +2,9 @@
  *
  *  $RCSfile: sdpage.cxx,v $
  *
- *  $Revision: 1.48 $
+ *  $Revision: 1.49 $
  *
- *  last change: $Author: kz $ $Date: 2005-01-13 17:25:42 $
+ *  last change: $Author: vg $ $Date: 2005-02-17 09:40:54 $
  *
  *  The Contents of this file are made available subject to the terms of
  *  either of the following licenses
@@ -166,6 +166,7 @@
 #include "stlsheet.hxx"
 #include "glob.hrc"
 #include "glob.hxx"
+#include "helpids.h"

 #ifndef _SDR_CONTACT_DISPLAYINFO_HXX
 #include <svx/sdr/contact/displayinfo.hxx>
@@ -719,6 +720,48 @@
     SfxStyleSheetBasePool* pStShPool = pModel->GetStyleSheetPool();
     SfxStyleSheetBase*     pResult   = pStShPool->Find(aName, eFamily);
     return (SfxStyleSheet*)pResult;
+}
+
+/** returns the presentation style with the given helpid from this masterpage or this
+    slides masterpage */
+SdStyleSheet* SdPage::getPresentationStyle( sal_uInt32 nHelpId ) const
+{
+    String aStyleName( pPage->GetLayoutName() );
+    const String aSep( RTL_CONSTASCII_USTRINGPARAM( SD_LT_SEPARATOR ));
+    aStyleName.Erase(aStyleName.Search(aSep) + aSep.Len());
+
+    sal_uInt16 nNameId;
+    switch( nHelpId )
+    {
+    case HID_PSEUDOSHEET_TITLE:             nNameId = STR_LAYOUT_TITLE;             break;
+    case HID_PSEUDOSHEET_SUBTITLE:          nNameId = STR_LAYOUT_SUBTITLE;          break;
+    case HID_PSEUDOSHEET_OUTLINE1:
+    case HID_PSEUDOSHEET_OUTLINE2:
+    case HID_PSEUDOSHEET_OUTLINE3:
+    case HID_PSEUDOSHEET_OUTLINE4:
+    case HID_PSEUDOSHEET_OUTLINE5:
+    case HID_PSEUDOSHEET_OUTLINE6:
+    case HID_PSEUDOSHEET_OUTLINE7:
+    case HID_PSEUDOSHEET_OUTLINE8:
+    case HID_PSEUDOSHEET_OUTLINE9:          nNameId = STR_LAYOUT_OUTLINE;           break;
+    case HID_PSEUDOSHEET_BACKGROUNDOBJECTS: nNameId = STR_LAYOUT_BACKGROUNDOBJECTS; break;
+    case HID_PSEUDOSHEET_BACKGROUND:        nNameId = STR_LAYOUT_BACKGROUND;        break;
+    case HID_PSEUDOSHEET_NOTES:             nNameId = STR_LAYOUT_NOTES;             break;
+
+    default:
+        DBG_ERROR( "SdPage::getPresentationStyle(), illegal argument!" );
+        return 0;
+    }
+    aStyleName.Append( String( SdResId( nNameId ) ) );
+    if( nNameId == STR_LAYOUT_OUTLINE )
+    {
+        aStyleName.Append( sal_Unicode( ' ' ));
+        aStyleName.Append( String::CreateFromInt32( sal_Int32( nHelpId - HID_PSEUDOSHEET_OUTLINE )));
+    }
+
+    SfxStyleSheetBasePool* pStShPool = pModel->GetStyleSheetPool();
+    SfxStyleSheetBase*     pResult   = pStShPool->Find(aStyleName, SD_LT_FAMILY);
+    return dynamic_cast<SdStyleSheet*>(pResult);
 }

 /*************************************************************************
@@ -3466,9 +3509,3 @@
            (maDateTimeText == rSettings.maDateTimeText);
 }

-// stl functions to use with the presentation object list
-
-void sd::removePresObj_func::operator() (PresentationObjectDescriptor x)
-{
-    delete mpPage->RemoveObject(x.mpObject->GetOrdNum());
-}


Append [0] to active array uniform names
TRAC #11796
Singed-off-by: Andrew Lewycky
Signed-off-by: Daniel Koch

Author:    Nicolas Capens

git-svn-id: 947ae547afacb859f3991e003b9d6feb04be57d7@210 736b8ea6-26fd-11df-bfd4-992fa37f6226

--- src/libGLESv2/Program.cpp
+++ src/libGLESv2/Program.cpp
@@ -2142,6 +2142,11 @@
     {
         std::string string = undecorate(mUniforms[uniform]->name);

+        if (mUniforms[uniform]->arraySize != 1)
+        {
+            string += "[0]";
+        }
+
         strncpy(name, string.c_str(), bufsize);
         name[bufsize - 1] = '\0';


Use the new protocol

Use the new protocol

--- src/driver.cpp
+++ src/driver.cpp
@@ -20,26 +20,85 @@

 const std::size_t UNIX_PATH_MAX = 108;
 const std::size_t gpio_pin = 2;
+const std::size_t buffer_size = 4096;
+
+// Configuration (this should be in a configuration file)
+const char* server_socket_path = "/tmp/asgard_socket";
+const char* client_socket_path = "/tmp/asgard_rf_socket";

 //Buffers
-char write_buffer[4096];
-char receive_buffer[4096];
+char write_buffer[buffer_size + 1];
+char receive_buffer[buffer_size + 1];
+
+// The socket file descriptor
+int socket_fd;
+
+// The socket addresses
+struct sockaddr_un client_address;
+struct sockaddr_un server_address;
+
+// The remote IDs
+int source_id = -1;
+int temperature_sensor_id = -1;
+int humidity_sensor_id = -1;
+int button_actuator_id = -1;
+
+void stop(){
+    std::cout << "asgard:rf: stop the driver" << std::endl;
+
+    // Unregister the temperature sensor, if necessary
+    if(temperature_sensor_id >= 0){
+        auto nbytes = snprintf(write_buffer, buffer_size, "UNREG_SENSOR %d %d", source_id, temperature_sensor_id);
+        sendto(socket_fd, write_buffer, nbytes, 0, (struct sockaddr *) &server_address, sizeof(struct sockaddr_un));
+    }
+
+    // Unregister the humidity sensor, if necessary
+    if(temperature_sensor_id >= 0){
+        auto nbytes = snprintf(write_buffer, buffer_size, "UNREG_SENSOR %d %d", source_id, humidity_sensor_id);
+        sendto(socket_fd, write_buffer, nbytes, 0, (struct sockaddr *) &server_address, sizeof(struct sockaddr_un));
+    }
+
+    // Unregister the button actuator, if necessary
+    if(temperature_sensor_id >= 0){
+        auto nbytes = snprintf(write_buffer, buffer_size, "UNREG_ACTUATOR %d %d", source_id, button_actuator_id);
+        sendto(socket_fd, write_buffer, nbytes, 0, (struct sockaddr *) &server_address, sizeof(struct sockaddr_un));
+    }
+
+    // Unregister the source, if necessary
+    if(source_id >= 0){
+        auto nbytes = snprintf(write_buffer, buffer_size, "UNREG_SOURCE %d", source_id);
+        sendto(socket_fd, write_buffer, nbytes, 0, (struct sockaddr *) &server_address, sizeof(struct sockaddr_un));
+    }
+
+    // Unlink the client socket
+    unlink(client_socket_path);
+
+    // Close the socket
+    close(socket_fd);
+}
+
+void terminate(int){
+    stop();
+
+    std::exit(0);
+}
+

 bool revoke_root(){
     if (getuid() == 0) {
         if (setgid(1000) != 0){
-            std::cout << "asgard:dht11: setgid: Unable to drop group privileges: " << strerror(errno) << std::endl;
+            std::cout << "asgard:rf: setgid: Unable to drop group privileges: " << strerror(errno) << std::endl;
             return false;
         }

         if (setuid(1000) != 0){
-            std::cout << "asgard:dht11: setgid: Unable to drop user privileges: " << strerror(errno) << std::endl;
+            std::cout << "asgard:rf: setgid: Unable to drop user privileges: " << strerror(errno) << std::endl;
             return false;
         }
     }

     if (setuid(0) != -1){
-        std::cout << "asgard:dht11: managed to regain root privileges, exiting..." << std::endl;
+        std::cout << "asgard:rf: managed to regain root privileges, exiting..." << std::endl;
         return false;
     }

@@ -64,23 +123,23 @@
     (void) station;

     //Send the humidity to the server
-    auto nbytes = snprintf(write_buffer, 4096, "DATA %d %d", humidity_sensor, humidity);
-    write(socket_fd, write_buffer, nbytes);
+    auto nbytes = snprintf(write_buffer, buffer_size, "DATA %d %d %d", source_id, humidity_sensor_id, humidity);
+    sendto(socket_fd, write_buffer, nbytes, 0, (struct sockaddr *) &server_address, sizeof(struct sockaddr_un));

     //Send the temperature to the server
-    nbytes = snprintf(write_buffer, 4096, "DATA %d %f", temperature_sensor, temperature);
-    write(socket_fd, write_buffer, nbytes);
-}
-
-void read_data(RCSwitch& rc_switch, int socket_fd, int rf_button_1, int temperature_sensor, int humidity_sensor){
+    nbytes = snprintf(write_buffer, buffer_size, "DATA %d %d %f", source_id, temperature_sensor_id, temperature);
+    sendto(socket_fd, write_buffer, nbytes, 0, (struct sockaddr *) &server_address, sizeof(struct sockaddr_un));
+}
+
+void read_data(RCSwitch& rc_switch){
     if (rc_switch.available()) {
         int value = rc_switch.getReceivedValue();

         if (value) {
             if((rc_switch.getReceivedProtocol() == 1 || rc_switch.getReceivedProtocol() == 2) && rc_switch.getReceivedValue() == 1135920){
                 //Send the event to the server
-                auto nbytes = snprintf(write_buffer, 4096, "EVENT %d 1", rf_button_1);
-                write(socket_fd, write_buffer, nbytes);
+                auto nbytes = snprintf(write_buffer, buffer_size, "EVENT %d %d %d", source_id, button_actuator_id, 1);
+                sendto(socket_fd, write_buffer, nbytes, 0, (struct sockaddr *) &server_address, sizeof(struct sockaddr_un));
             } else if(rc_switch.getReceivedProtocol() == 5){
                 unsigned long value = rc_switch.getReceivedValue();
                 decode_wt450(value, socket_fd, temperature_sensor, humidity_sensor);
@@ -113,78 +172,85 @@
        return 1;
     }

-    //Open the socket
-    auto socket_fd = socket(PF_UNIX, SOCK_STREAM, 0);
+    // Open the socket
+    socket_fd = socket(AF_UNIX, SOCK_DGRAM, 0);
     if(socket_fd < 0){
-        std::cout << "asgard:rf: socket() failed" << std::endl;
+        std::cerr << "asgard:rf: socket() failed" << std::endl;
         return 1;
     }

-    //Init the address
-    struct sockaddr_un address;
-    memset(&address, 0, sizeof(struct sockaddr_un));
-    address.sun_family = AF_UNIX;
-    snprintf(address.sun_path, UNIX_PATH_MAX, "/tmp/asgard_socket");
-
-    //Connect to the server
-    if(connect(socket_fd, (struct sockaddr *) &address, sizeof(struct sockaddr_un)) != 0){
-        std::cout << "asgard:rf: connect() failed" << std::endl;
+    // Init the client address
+    memset(&client_address, 0, sizeof(struct sockaddr_un));
+    client_address.sun_family = AF_UNIX;
+    snprintf(client_address.sun_path, UNIX_PATH_MAX, client_socket_path);
+
+    // Unlink the client socket
+    unlink(client_socket_path);
+
+    // Bind to client socket
+    if(bind(socket_fd, (const struct sockaddr *) &client_address, sizeof(struct sockaddr_un)) < 0){
+        std::cerr << "asgard:rf: bind() failed" << std::endl;
         return 1;
     }

-    //Register the actuator
-    auto nbytes = snprintf(write_buffer, 4096, "REG_ACTUATOR rf_button_1");
-    write(socket_fd, write_buffer, nbytes);
-
-    //Get the response from the server
-    nbytes = read(socket_fd, receive_buffer, 4096);
-
-    if(!nbytes){
-        std::cout << "asgard:ir: failed to register actuator" << std::endl;
-        return 1;
-    }
-
-    receive_buffer[nbytes] = 0;
-
-    //Parse the actuator id
-    int rf_button_1 = atoi(receive_buffer);
-    std::cout << "remote actuator: " << rf_button_1 << std::endl;
-
-    nbytes = snprintf(write_buffer, 4096, "REG_SENSOR TEMPERATURE rf_weather_1");
-    write(socket_fd, write_buffer, nbytes);
-
-    nbytes = read(socket_fd, receive_buffer, 4096);
-
-    if(!nbytes){
-        std::cout << "asgard:dht11: failed to register temperature sensor" << std::endl;
-        return 1;
-    }
-
-    receive_buffer[nbytes] = 0;
-
-    int temperature_sensor = atoi(receive_buffer);
-
-    std::cout << "Temperature sensor: " << temperature_sensor << std::endl;
-
-    nbytes = snprintf(write_buffer, 4096, "REG_SENSOR HUMIDITY rf_weather_1");
-    write(socket_fd, write_buffer, nbytes);
-
-    nbytes = read(socket_fd, receive_buffer, 4096);
-
-    if(!nbytes){
-        std::cout << "asgard:dht11: failed to register humidity sensor" << std::endl;
-        return 1;
-    }
-
-    receive_buffer[nbytes] = 0;
-
-    int humidity_sensor = atoi(receive_buffer);
-
-    std::cout << "Humidity sensor: " << humidity_sensor << std::endl;
+    //Register signals for "proper" shutdown
+    signal(SIGTERM, terminate);
+    signal(SIGINT, terminate);
+
+    // Init the server address
+    memset(&server_address, 0, sizeof(struct sockaddr_un));
+    server_address.sun_family = AF_UNIX;
+    snprintf(server_address.sun_path, UNIX_PATH_MAX, server_socket_path);
+
+    socklen_t address_length = sizeof(struct sockaddr_un);
+
+    // Register the source
+    auto nbytes = snprintf(write_buffer, buffer_size, "REG_SOURCE rf");
+    sendto(socket_fd, write_buffer, nbytes, 0, (struct sockaddr *) &server_address, sizeof(struct sockaddr_un));
+
+    auto bytes_received = recvfrom(socket_fd, receive_buffer, buffer_size, 0, (struct sockaddr *) &(server_address), &address_length);
+    receive_buffer[bytes_received] = '\0';
+
+    source_id = atoi(receive_buffer);
+
+    std::cout << "asgard:rf: remote source: " << source_id << std::endl;
+
+    // Register the temperature sensor
+    nbytes = snprintf(write_buffer, buffer_size, "REG_SENSOR %d %s %s", source_id, "TEMPERATURE", "local");
+    sendto(socket_fd, write_buffer, nbytes, 0, (struct sockaddr *) &server_address, sizeof(struct sockaddr_un));
+
+    bytes_received = recvfrom(socket_fd, receive_buffer, buffer_size, 0, (struct sockaddr *) &(server_address), &address_length);
+    receive_buffer[bytes_received] = '\0';
+
+    temperature_sensor_id = atoi(receive_buffer);
+
+    std::cout << "asgard:rf: remote temperature sensor: " << temperature_sensor_id << std::endl;
+
+    // Register the humidity sensor
+    nbytes = snprintf(write_buffer, buffer_size, "REG_SENSOR %d %s %s", source_id, "HUMIDITY", "local");
+    sendto(socket_fd, write_buffer, nbytes, 0, (struct sockaddr *) &server_address, sizeof(struct sockaddr_un));
+
+    bytes_received = recvfrom(socket_fd, receive_buffer, buffer_size, 0, (struct sockaddr *) &(server_address), &address_length);
+    receive_buffer[bytes_received] = '\0';
+
+    humidity_sensor_id = atoi(receive_buffer);
+
+    std::cout << "asgard:rf: remote humidity sensor: " << temperature_sensor_id << std::endl;
+
+    // Register the button actuator
+    nbytes = snprintf(write_buffer, buffer_size, "REG_ACTUATOR %d %s", source_id, "rf_button_1");
+    sendto(socket_fd, write_buffer, nbytes, 0, (struct sockaddr *) &server_address, sizeof(struct sockaddr_un));
+
+    bytes_received = recvfrom(socket_fd, receive_buffer, buffer_size, 0, (struct sockaddr *) &(server_address), &address_length);
+    receive_buffer[bytes_received] = '\0';
+
+    button_actuator_id = atoi(receive_buffer);
+
+    std::cout << "asgard:rf: remote button actuator: " << button_actuator_id << std::endl;

     //wait for events
     while(true) {
-        read_data(rc_switch, socket_fd, rf_button_1, temperature_sensor, humidity_sensor);
+        read_data(rc_switch);

         //wait for 10 time units
         delay(10);


Output of given function

Output of given function

--- Modules/Classification/CLUtilities/test/mitkGIFNeighbourhoodGreyToneDifferenceFeaturesTest.cpp
+++ Modules/Classification/CLUtilities/test/mitkGIFNeighbourhoodGreyToneDifferenceFeaturesTest.cpp
@@ -19,7 +19,7 @@
 #include "mitkIOUtil.h"
 #include <cmath>

-#include <mitkGIFCurvatureStatistic.h>
+#include <mitkGIFNeighbourhoodGreyToneDifferenceFeatures.h>

 class mitkGIFNeighbourhoodGreyToneDifferenceFeaturesTestSuite : public mitk::TestFixture
 {
@@ -47,7 +47,7 @@

   void ImageDescription_PhantomTest()
   {
-    mitk::GIFCurvatureStatistic::Pointer featureCalculator = mitk::GIFCurvatureStatistic::New();
+    mitk::GIFNeighbourhoodGreyToneDifferenceFeatures::Pointer featureCalculator = mitk::GIFNeighbourhoodGreyToneDifferenceFeatures::New();

     featureCalculator->SetUseBinsize(true);
     featureCalculator->SetBinsize(1.0);


s/std::io_errc::stream/std::errc::io_error/

--- c++11/src/propagation.cpp
+++ c++11/src/propagation.cpp
@@ -69,7 +69,7 @@
   }
   if (!binary_carrier.SerializeToOstream(&carrier)) {
     return opentracing::make_unexpected(
-        std::make_error_code(std::io_errc::stream));
+        std::make_error_code(std::errc::io_error));
   }

   // Flush so that when we call carrier.good, we'll get an accurate view of the
@@ -77,7 +77,7 @@
   carrier.flush();
   if (!carrier.good()) {
     return opentracing::make_unexpected(
-        std::make_error_code(std::io_errc::stream));
+        std::make_error_code(std::errc::io_error));
   }

   return {};
@@ -149,7 +149,7 @@
   // state first before checking for an empty stream.
   if (!carrier.good()) {
     return opentracing::make_unexpected(
-        std::make_error_code(std::io_errc::stream));
+        std::make_error_code(std::errc::io_error));
   }

   // Check for the case when no span is encoded.


Fixed bug.

Fixed bug.

--- src/ExternalPropagator.cpp
+++ src/ExternalPropagator.cpp
@@ -419,7 +419,7 @@
     Literal conflictLiteral )
 {
     assert( solver.isFalse( conflictLiteral ) );
-    Clause* clause = getReason( solver, Literal::null );
+    Clause* clause = getReason( solver, check_getReasonForLiteral ? conflictLiteral : Literal::null );
     if( clause == NULL )
     {
         clause = new Clause();


Updated RBEIMConstruction::enrich_eim_approximation()

--- src/reduced_basis/rb_eim_construction.C
+++ src/reduced_basis/rb_eim_construction.C
@@ -1019,10 +1019,10 @@

                                 Point xi_eta =
                                   FEMap::inverse_map(elem_side->dim(),
-                                                    elem_side.get(),
-                                                    xyz_qp,
-                                                    /*Newton iteration tolerance*/ TOLERANCE,
-                                                    /*secure*/ true);
+                                                     elem_side.get(),
+                                                     xyz_qp,
+                                                     /*Newton iteration tolerance*/ TOLERANCE,
+                                                     /*secure*/ true);

                                 // Inverse map should map back to a 2D reference domain
                                 libmesh_assert(std::abs(xi_eta(2)) < TOLERANCE);
@@ -1032,15 +1032,15 @@
                                 xi_eta_perturb(0) += fd_delta;
                                 Point xyz_perturb_0 =
                                   FEMap::map(elem_side->dim(),
-                                            elem_side.get(),
-                                            xi_eta_perturb);
+                                             elem_side.get(),
+                                             xi_eta_perturb);
                                 xi_eta_perturb(0) -= fd_delta;

                                 xi_eta_perturb(1) += fd_delta;
                                 Point xyz_perturb_1 =
                                   FEMap::map(elem_side->dim(),
-                                            elem_side.get(),
-                                            xi_eta_perturb);
+                                             elem_side.get(),
+                                             xi_eta_perturb);
                                 xi_eta_perturb(1) -= fd_delta;

                                 // Finally, we rescale xyz_perturb_0 and xyz_perturb_1 so that
@@ -1284,173 +1284,332 @@

   set_params_from_training_set(training_index);

-  // Make a copy of the parametrized function for training index, since we
-  // will modify this below to give us a new basis function.
-  auto local_pf = _local_parametrized_functions_for_training[training_index];
-
-  bool has_obs_vals = (eim_eval.get_n_observation_points() > 0);
-
-  std::vector<std::vector<Number>> new_bf_obs_vals;
-  if (has_obs_vals)
-    new_bf_obs_vals = _parametrized_functions_for_training_obs_values[training_index];
-
-  // If we have at least one basis function, then we need to use
-  // rb_eim_solve() to find the EIM interpolation error. Otherwise,
-  // just use solution as is.
-  if (eim_eval.get_n_basis_functions() > 0)
-    {
-      // Get the right-hand side vector for the EIM approximation
-      // by sampling the parametrized function (stored in solution)
-      // at the interpolation points.
-      unsigned int RB_size = eim_eval.get_n_basis_functions();
-      DenseVector<Number> EIM_rhs(RB_size);
-      for (unsigned int i=0; i<RB_size; i++)
-        {
-          EIM_rhs(i) =
-            RBEIMEvaluation::get_parametrized_function_value(comm(),
-                                                             local_pf,
-                                                             eim_eval.get_interpolation_points_elem_id(i),
-                                                             eim_eval.get_interpolation_points_comp(i),
-                                                             eim_eval.get_interpolation_points_qp(i));
-        }
-
-      eim_eval.set_parameters( get_parameters() );
-      DenseVector<Number> rb_eim_solution = eim_eval.rb_eim_solve(EIM_rhs);
-
-      // Load the "EIM residual" into solution by subtracting
-      // the EIM approximation
-      eim_eval.decrement_vector(local_pf, rb_eim_solution);
-
-      if(has_obs_vals)
-        {
+  if (eim_eval.get_parametrized_function().on_mesh_sides())
+    {
+      // Make a copy of the parametrized function for training index, since we
+      // will modify this below to give us a new basis function.
+      auto local_pf = _local_side_parametrized_functions_for_training[training_index];
+
+      // If we have at least one basis function, then we need to use
+      // rb_eim_solve() to find the EIM interpolation error. Otherwise,
+      // just use solution as is.
+      if (eim_eval.get_n_basis_functions() > 0)
+        {
+          // Get the right-hand side vector for the EIM approximation
+          // by sampling the parametrized function (stored in solution)
+          // at the interpolation points.
+          unsigned int RB_size = eim_eval.get_n_basis_functions();
+          DenseVector<Number> EIM_rhs(RB_size);
           for (unsigned int i=0; i<RB_size; i++)
-            for (unsigned int j=0; j<eim_eval.get_n_observation_points(); j++)
-              for (unsigned int k=0; k<new_bf_obs_vals[j].size(); k++)
-                new_bf_obs_vals[j][k] -= rb_eim_solution(i) * eim_eval.get_observation_values(i,j)[k];
-        }
-    }
-
-  // Find the quadrature point at which local_pf (which now stores
-  // the "EIM residual") has maximum absolute value
-  Number optimal_value = 0.;
-  Point optimal_point;
-  unsigned int optimal_comp = 0;
-  dof_id_type optimal_elem_id = DofObject::invalid_id;
-  subdomain_id_type optimal_subdomain_id = 0;
-  unsigned int optimal_qp = 0;
-  std::vector<Point> optimal_point_perturbs;
-  std::vector<Real> optimal_point_phi_i_qp;
-
-  // Initialize largest_abs_value to be negative so that it definitely gets updated.
-  Real largest_abs_value = -1.;
-
-  // In order to compute phi_i_qp, we initialize a FEMContext
-  FEMContext con(*this);
-  for (auto dim : con.elem_dimensions())
-    {
-      auto fe = con.get_element_fe(/*var=*/0, dim);
-      fe->get_phi();
-    }
-
-  for (const auto & pr : local_pf)
-    {
-      dof_id_type elem_id = pr.first;
-      const auto & comp_and_qp = pr.second;
-
-      // Also initialize phi in order to compute phi_i_qp
-      const Elem & elem_ref = get_mesh().elem_ref(elem_id);
-      con.pre_fe_reinit(*this, &elem_ref);
-
-      auto elem_fe = con.get_element_fe(/*var=*/0, elem_ref.dim());
-      const std::vector<std::vector<Real>> & phi = elem_fe->get_phi();
-
-      elem_fe->reinit(&elem_ref);
-
-      for (const auto & comp : index_range(comp_and_qp))
-        {
-          const std::vector<Number> & qp_values = comp_and_qp[comp];
-
-          for (auto qp : index_range(qp_values))
             {
-              Number value = qp_values[qp];
-              Real abs_value = std::abs(value);
-
-              if (abs_value > largest_abs_value)
+              EIM_rhs(i) =
+                RBEIMEvaluation::get_parametrized_function_side_value(comm(),
+                                                                      local_pf,
+                                                                      eim_eval.get_interpolation_points_elem_id(i),
+                                                                      eim_eval.get_interpolation_points_side_index(i),
+                                                                      eim_eval.get_interpolation_points_comp(i),
+                                                                      eim_eval.get_interpolation_points_qp(i));
+            }
+
+          eim_eval.set_parameters( get_parameters() );
+          DenseVector<Number> rb_eim_solution = eim_eval.rb_eim_solve(EIM_rhs);
+
+          // Load the "EIM residual" into solution by subtracting
+          // the EIM approximation
+          eim_eval.side_decrement_vector(local_pf, rb_eim_solution);
+        }
+
+      // Find the quadrature point at which local_pf (which now stores
+      // the "EIM residual") has maximum absolute value
+      Number optimal_value = 0.;
+      Point optimal_point;
+      unsigned int optimal_comp = 0;
+      dof_id_type optimal_elem_id = DofObject::invalid_id;
+      unsigned int optimal_side_index = 0;
+      subdomain_id_type optimal_subdomain_id = 0;
+      boundary_id_type optimal_boundary_id = 0;
+      unsigned int optimal_qp = 0;
+      std::vector<Point> optimal_point_perturbs;
+      std::vector<Real> optimal_point_phi_i_qp;
+
+      // Initialize largest_abs_value to be negative so that it definitely gets updated.
+      Real largest_abs_value = -1.;
+
+      // In order to compute phi_i_qp, we initialize a FEMContext
+      FEMContext con(*this);
+      init_context(con);
+
+      FEBase* side_fe = nullptr;
+      con.get_side_fe( 0, side_fe );
+
+      const std::vector<std::vector<Real>> & phi_side = side_fe->get_phi();
+
+      for (const auto & pr : local_pf)
+        {
+          auto elem_and_side = pr.first;
+          dof_id_type elem_id = elem_and_side.first;
+          unsigned int side_index = elem_and_side.second;
+          const auto & comp_and_qp = pr.second;
+
+          // Also initialize phi in order to compute phi_i_qp
+          const Elem & elem_ref = get_mesh().elem_ref(elem_id);
+          con.pre_fe_reinit(*this, &elem_ref);
+
+          side_fe->reinit(&elem_ref, side_index);
+
+          for (const auto & comp : index_range(comp_and_qp))
+            {
+              const std::vector<Number> & qp_values = comp_and_qp[comp];
+
+              for (auto qp : index_range(qp_values))
                 {
-                  largest_abs_value = abs_value;
-                  optimal_value = value;
-                  optimal_comp = comp;
-                  optimal_elem_id = elem_id;
-                  optimal_qp = qp;
-
-                  optimal_point_phi_i_qp.resize(phi.size());
-                  for(auto i : index_range(phi))
-                    optimal_point_phi_i_qp[i] = phi[i][qp];
-
-                  const auto & point_list =
-                    libmesh_map_find(_local_quad_point_locations, elem_id);
-
-                  libmesh_error_msg_if(qp >= point_list.size(), "Error: Invalid qp");
-
-                  optimal_point = point_list[qp];
-
-                  optimal_subdomain_id = libmesh_map_find(_local_quad_point_subdomain_ids, elem_id);
-
-                  if (get_rb_eim_evaluation().get_parametrized_function().requires_xyz_perturbations)
+                  Number value = qp_values[qp];
+                  Real abs_value = std::abs(value);
+
+                  if (abs_value > largest_abs_value)
                     {
-                      const auto & perturb_list =
-                        libmesh_map_find(_local_quad_point_locations_perturbations, elem_id);
-
-                      libmesh_error_msg_if(qp >= perturb_list.size(), "Error: Invalid qp");
-
-                      optimal_point_perturbs = perturb_list[qp];
+                      largest_abs_value = abs_value;
+                      optimal_value = value;
+                      optimal_comp = comp;
+                      optimal_elem_id = elem_id;
+                      optimal_side_index = side_index;
+                      optimal_qp = qp;
+
+                      // TODO: We only want the "dofs on side" entries
+                      // from phi_side. Could do this by initing an FE object
+                      // on the side itself, rather than using get_side_fe().
+                      optimal_point_phi_i_qp.resize(phi_side.size());
+                      for(auto i : index_range(phi_side))
+                        optimal_point_phi_i_qp[i] = phi_side[i][qp];
+
+                      const auto & point_list =
+                        libmesh_map_find(_local_quad_point_locations, elem_id);
+
+                      libmesh_error_msg_if(qp >= point_list.size(), "Error: Invalid qp");
+
+                      optimal_point = point_list[qp];
+
+                      optimal_subdomain_id = libmesh_map_find(_local_side_quad_point_subdomain_ids, elem_and_side);
+                      optimal_boundary_id = libmesh_map_find(_local_side_quad_point_boundary_ids, elem_and_side);
+
+                      if (get_rb_eim_evaluation().get_parametrized_function().requires_xyz_perturbations)
+                        {
+                          const auto & perturb_list =
+                            libmesh_map_find(_local_quad_point_locations_perturbations, elem_id);
+
+                          libmesh_error_msg_if(qp >= perturb_list.size(), "Error: Invalid qp");
+
+                          optimal_point_perturbs = perturb_list[qp];
+                        }
                     }
                 }
             }
         }
-    }
-
-  // Find out which processor has the largest of the abs values
-  // and broadcast from that processor.
-  unsigned int proc_ID_index;
-  this->comm().maxloc(largest_abs_value, proc_ID_index);
-
-  this->comm().broadcast(optimal_value, proc_ID_index);
-  this->comm().broadcast(optimal_point, proc_ID_index);
-  this->comm().broadcast(optimal_comp, proc_ID_index);
-  this->comm().broadcast(optimal_elem_id, proc_ID_index);
-  this->comm().broadcast(optimal_subdomain_id, proc_ID_index);
-  this->comm().broadcast(optimal_qp, proc_ID_index);
-  this->comm().broadcast(optimal_point_perturbs, proc_ID_index);
-  this->comm().broadcast(optimal_point_phi_i_qp, proc_ID_index);
-
-  libmesh_error_msg_if(optimal_elem_id == DofObject::invalid_id, "Error: Invalid element ID");
-
-  libmesh_error_msg_if(optimal_value == 0., "New EIM basis function should not be zero");
-
-  // Scale local_pf so that its largest value is 1.0
-  scale_parametrized_function(local_pf, 1./optimal_value);
-
-  // Add local_pf as the new basis function and store data
-  // associated with the interpolation point.
-  eim_eval.add_basis_function_and_interpolation_data(local_pf,
-                                                     optimal_point,
-                                                     optimal_comp,
-                                                     optimal_elem_id,
-                                                     optimal_subdomain_id,
-                                                     optimal_qp,
-                                                     optimal_point_perturbs,
-                                                     optimal_point_phi_i_qp);
-
-  if (has_obs_vals)
-    {
-      // Apply the scame scaling to new_bf_obs_vals as we did to
-      // the new basis function itself
-      for (unsigned int i=0; i<new_bf_obs_vals.size(); i++)
-        for (unsigned int j=0; j<new_bf_obs_vals[i].size(); j++)
-          new_bf_obs_vals[i][j] *= 1./optimal_value;
-
-      eim_eval.add_observation_values_for_basis_function(new_bf_obs_vals);
+
+      // Find out which processor has the largest of the abs values
+      // and broadcast from that processor.
+      unsigned int proc_ID_index;
+      this->comm().maxloc(largest_abs_value, proc_ID_index);
+
+      this->comm().broadcast(optimal_value, proc_ID_index);
+      this->comm().broadcast(optimal_point, proc_ID_index);
+      this->comm().broadcast(optimal_comp, proc_ID_index);
+      this->comm().broadcast(optimal_elem_id, proc_ID_index);
+      this->comm().broadcast(optimal_subdomain_id, proc_ID_index);
+      this->comm().broadcast(optimal_qp, proc_ID_index);
+      this->comm().broadcast(optimal_point_perturbs, proc_ID_index);
+      this->comm().broadcast(optimal_point_phi_i_qp, proc_ID_index);
+
+      libmesh_error_msg_if(optimal_elem_id == DofObject::invalid_id, "Error: Invalid element ID");
+
+      libmesh_error_msg_if(optimal_value == 0., "New EIM basis function should not be zero");
+
+      // Scale local_pf so that its largest value is 1.0
+      scale_parametrized_function(local_pf, 1./optimal_value);
+
+      // Add local_pf as the new basis function and store data
+      // associated with the interpolation point.
+      eim_eval.add_side_basis_function_and_interpolation_data(local_pf,
+                                                              optimal_point,
+                                                              optimal_comp,
+                                                              optimal_elem_id,
+                                                              optimal_side_index,
+                                                              optimal_subdomain_id,
+                                                              optimal_boundary_id,
+                                                              optimal_qp,
+                                                              optimal_point_perturbs,
+                                                              optimal_point_phi_i_qp);
+    }
+  else
+    {
+      // Make a copy of the parametrized function for training index, since we
+      // will modify this below to give us a new basis function.
+      auto local_pf = _local_parametrized_functions_for_training[training_index];
+
+      bool has_obs_vals = (eim_eval.get_n_observation_points() > 0);
+
+      std::vector<std::vector<Number>> new_bf_obs_vals;
+      if (has_obs_vals)
+        new_bf_obs_vals = _parametrized_functions_for_training_obs_values[training_index];
+
+      // If we have at least one basis function, then we need to use
+      // rb_eim_solve() to find the EIM interpolation error. Otherwise,
+      // just use solution as is.
+      if (eim_eval.get_n_basis_functions() > 0)
+        {
+          // Get the right-hand side vector for the EIM approximation
+          // by sampling the parametrized function (stored in solution)
+          // at the interpolation points.
+          unsigned int RB_size = eim_eval.get_n_basis_functions();
+          DenseVector<Number> EIM_rhs(RB_size);
+          for (unsigned int i=0; i<RB_size; i++)
+            {
+              EIM_rhs(i) =
+                RBEIMEvaluation::get_parametrized_function_value(comm(),
+                                                                local_pf,
+                                                                eim_eval.get_interpolation_points_elem_id(i),
+                                                                eim_eval.get_interpolation_points_comp(i),
+                                                                eim_eval.get_interpolation_points_qp(i));
+            }
+
+          eim_eval.set_parameters( get_parameters() );
+          DenseVector<Number> rb_eim_solution = eim_eval.rb_eim_solve(EIM_rhs);
+
+          // Load the "EIM residual" into solution by subtracting
+          // the EIM approximation
+          eim_eval.decrement_vector(local_pf, rb_eim_solution);
+
+          if(has_obs_vals)
+            {
+              for (unsigned int i=0; i<RB_size; i++)
+                for (unsigned int j=0; j<eim_eval.get_n_observation_points(); j++)
+                  for (unsigned int k=0; k<new_bf_obs_vals[j].size(); k++)
+                    new_bf_obs_vals[j][k] -= rb_eim_solution(i) * eim_eval.get_observation_values(i,j)[k];
+            }
+        }
+
+      // Find the quadrature point at which local_pf (which now stores
+      // the "EIM residual") has maximum absolute value
+      Number optimal_value = 0.;
+      Point optimal_point;
+      unsigned int optimal_comp = 0;
+      dof_id_type optimal_elem_id = DofObject::invalid_id;
+      subdomain_id_type optimal_subdomain_id = 0;
+      unsigned int optimal_qp = 0;
+      std::vector<Point> optimal_point_perturbs;
+      std::vector<Real> optimal_point_phi_i_qp;
+
+      // Initialize largest_abs_value to be negative so that it definitely gets updated.
+      Real largest_abs_value = -1.;
+
+      // In order to compute phi_i_qp, we initialize a FEMContext
+      FEMContext con(*this);
+      for (auto dim : con.elem_dimensions())
+        {
+          auto fe = con.get_element_fe(/*var=*/0, dim);
+          fe->get_phi();
+        }
+
+      for (const auto & pr : local_pf)
+        {
+          dof_id_type elem_id = pr.first;
+          const auto & comp_and_qp = pr.second;
+
+          // Also initialize phi in order to compute phi_i_qp
+          const Elem & elem_ref = get_mesh().elem_ref(elem_id);
+          con.pre_fe_reinit(*this, &elem_ref);
+
+          auto elem_fe = con.get_element_fe(/*var=*/0, elem_ref.dim());
+          const std::vector<std::vector<Real>> & phi = elem_fe->get_phi();
+
+          elem_fe->reinit(&elem_ref);
+
+          for (const auto & comp : index_range(comp_and_qp))
+            {
+              const std::vector<Number> & qp_values = comp_and_qp[comp];
+
+              for (auto qp : index_range(qp_values))
+                {
+                  Number value = qp_values[qp];
+                  Real abs_value = std::abs(value);
+
+                  if (abs_value > largest_abs_value)
+                    {
+                      largest_abs_value = abs_value;
+                      optimal_value = value;
+                      optimal_comp = comp;
+                      optimal_elem_id = elem_id;
+                      optimal_qp = qp;
+
+                      optimal_point_phi_i_qp.resize(phi.size());
+                      for(auto i : index_range(phi))
+                        optimal_point_phi_i_qp[i] = phi[i][qp];
+
+                      const auto & point_list =
+                        libmesh_map_find(_local_quad_point_locations, elem_id);
+
+                      libmesh_error_msg_if(qp >= point_list.size(), "Error: Invalid qp");
+
+                      optimal_point = point_list[qp];
+
+                      optimal_subdomain_id = libmesh_map_find(_local_quad_point_subdomain_ids, elem_id);
+
+                      if (get_rb_eim_evaluation().get_parametrized_function().requires_xyz_perturbations)
+                        {
+                          const auto & perturb_list =
+                            libmesh_map_find(_local_quad_point_locations_perturbations, elem_id);
+
+                          libmesh_error_msg_if(qp >= perturb_list.size(), "Error: Invalid qp");
+
+                          optimal_point_perturbs = perturb_list[qp];
+                        }
+                    }
+                }
+            }
+        }
+
+      // Find out which processor has the largest of the abs values
+      // and broadcast from that processor.
+      unsigned int proc_ID_index;
+      this->comm().maxloc(largest_abs_value, proc_ID_index);
+
+      this->comm().broadcast(optimal_value, proc_ID_index);
+      this->comm().broadcast(optimal_point, proc_ID_index);
+      this->comm().broadcast(optimal_comp, proc_ID_index);
+      this->comm().broadcast(optimal_elem_id, proc_ID_index);
+      this->comm().broadcast(optimal_subdomain_id, proc_ID_index);
+      this->comm().broadcast(optimal_qp, proc_ID_index);
+      this->comm().broadcast(optimal_point_perturbs, proc_ID_index);
+      this->comm().broadcast(optimal_point_phi_i_qp, proc_ID_index);
+
+      libmesh_error_msg_if(optimal_elem_id == DofObject::invalid_id, "Error: Invalid element ID");
+
+      libmesh_error_msg_if(optimal_value == 0., "New EIM basis function should not be zero");
+
+      // Scale local_pf so that its largest value is 1.0
+      scale_parametrized_function(local_pf, 1./optimal_value);
+
+      // Add local_pf as the new basis function and store data
+      // associated with the interpolation point.
+      eim_eval.add_basis_function_and_interpolation_data(local_pf,
+                                                        optimal_point,
+                                                        optimal_comp,
+                                                        optimal_elem_id,
+                                                        optimal_subdomain_id,
+                                                        optimal_qp,
+                                                        optimal_point_perturbs,
+                                                        optimal_point_phi_i_qp);
+
+      if (has_obs_vals)
+        {
+          // Apply the scame scaling to new_bf_obs_vals as we did to
+          // the new basis function itself
+          for (unsigned int i=0; i<new_bf_obs_vals.size(); i++)
+            for (unsigned int j=0; j<new_bf_obs_vals[i].size(); j++)
+              new_bf_obs_vals[i][j] *= 1./optimal_value;
+
+          eim_eval.add_observation_values_for_basis_function(new_bf_obs_vals);
+        }
     }
 }


kwm: move UpdateSpaceOfScreen in space change cond

--- kwm/space.cpp
+++ kwm/space.cpp
@@ -287,6 +287,10 @@

         Space = GetActiveSpaceOfScreen(KWMScreen.Current);
         UpdateActiveWindowList(KWMScreen.Current);
+
+        if (Space->NeedsUpdate)
+            UpdateSpaceOfScreen(Space, KWMScreen.Current);
+
         if(Space->FocusedWindowID != 0)
         {
             FocusWindowByID(Space->FocusedWindowID);
@@ -326,10 +330,6 @@
         ClearMarkedWindow();
         DestroyApplicationNotifications();
     }
-    else if (Space->NeedsUpdate)
-    {
-        UpdateSpaceOfScreen(Space, KWMScreen.Current);
-    }

     KWMScreen.Transitioning = false;
     pthread_mutex_unlock(&KWMThread.Lock);


fixed ZoomStep for View3DInventor

fixed ZoomStep for View3DInventor

--- src/Gui/View3DInventor.cpp
+++ src/Gui/View3DInventor.cpp
@@ -292,8 +292,8 @@
         bool on = rGrp.GetBool("ZoomAtCursor", false);
         _viewer->navigationStyle()->setZoomAtCursor(on);
     }
-    else if (strcmp(Reason,"ZoomSetp") == 0) {
-        float val = rGrp.GetFloat("ZoomSetp", 0.0f);
+    else if (strcmp(Reason,"ZoomStep") == 0) {
+        float val = rGrp.GetFloat("ZoomStep", 0.0f);
         _viewer->navigationStyle()->setZoomStep(val);
     }
     else if (strcmp(Reason,"EyeDistance") == 0) {


duplex: move code to CloseRead(), CloseWrite(), CloseSocket()

--- src/duplex.cxx
+++ src/duplex.cxx
@@ -58,6 +58,38 @@
         event2_set(&sock_event, EV_READ);
     }

+    void CloseRead() {
+        assert(read_fd >= 0);
+
+        event2_set(&read_event, 0);
+
+        if (read_fd > 2)
+            close(read_fd);
+
+        read_fd = -1;
+    }
+
+    void CloseWrite() {
+        assert(write_fd >= 0);
+
+        event2_set(&write_event, 0);
+
+        if (write_fd > 2)
+            close(write_fd);
+
+        write_fd = -1;
+    }
+
+    void CloseSocket() {
+        assert(sock_fd >= 0);
+
+        event2_set(&sock_event, 0);
+        event2_commit(&sock_event);
+
+        close(sock_fd);
+        sock_fd = -1;
+    }
+
     void Destroy();
     bool CheckDestroy();

@@ -69,31 +101,14 @@
 void
 Duplex::Destroy()
 {
-    if (read_fd >= 0) {
-        event2_set(&read_event, 0);
-
-        if (read_fd > 2)
-            close(read_fd);
-
-        read_fd = -1;
-    }
-
-    if (write_fd >= 0) {
-        event2_set(&write_event, 0);
-
-        if (write_fd > 2)
-            close(write_fd);
-
-        write_fd = -1;
-    }
-
-    if (sock_fd >= 0) {
-        event2_set(&sock_event, 0);
-        event2_commit(&sock_event);
-
-        close(sock_fd);
-        sock_fd = -1;
-    }
+    if (read_fd >= 0)
+        CloseRead();
+
+    if (write_fd >= 0)
+        CloseWrite();
+
+    if (sock_fd >= 0)
+        CloseSocket();

     from_read.Free(fb_pool_get());
     to_write.Free(fb_pool_get());
@@ -122,8 +137,7 @@
     }

     if (nbytes == 0) {
-        close(read_fd);
-        read_fd = -1;
+        CloseRead();
         if (CheckDestroy())
             return;
     }


add more opengl info on startup to pc ui

--- selfdrive/ui/qt/window.cc
+++ selfdrive/ui/qt/window.cc
@@ -63,6 +63,9 @@
 void GLWindow::initializeGL() {
   initializeOpenGLFunctions();
   std::cout << "OpenGL version: " << glGetString(GL_VERSION) << std::endl;
+  std::cout << "OpenGL vendor: " << glGetString(GL_VENDOR) << std::endl;
+  std::cout << "OpenGL renderer: " << glGetString(GL_RENDERER) << std::endl;
+  std::cout << "OpenGL language version: " << glGetString(GL_SHADING_LANGUAGE_VERSION) << std::endl;

   ui_state = new UIState();
   ui_init(ui_state);


fixed Block error when reading last sectors

--- src/llamaos/xen/Block.cpp
+++ src/llamaos/xen/Block.cpp
@@ -134,7 +134,7 @@
       request->operation = BLKIF_OP_READ;
       request->handle = vdev;
       request->id = 0;
-      request->nr_segments = 8;
+      request->nr_segments = 1;
       request->sector_number = i;
       request->seg [0].gref = shared_buffer_ref;
       request->seg [0].first_sect = 0;


Fixes syscall intrinsic on macOS they use a slightly different section + register for the id

--- src/llvm_backend_proc.cpp
+++ src/llvm_backend_proc.cpp
@@ -2058,26 +2058,47 @@
 				break;
 			case TargetArch_arm64:
 				{
-					GB_ASSERT(arg_count <= 7);
-
-					char asm_string[] = "svc #0";
-					gbString constraints = gb_string_make(heap_allocator(), "={x0}");
-					for (unsigned i = 0; i < arg_count; i++) {
-						constraints = gb_string_appendc(constraints, ",{");
-						static char const *regs[] = {
-							"x8",
-							"x0",
-							"x1",
-							"x2",
-							"x3",
-							"x4",
-							"x5",
-						};
-						constraints = gb_string_appendc(constraints, regs[i]);
-						constraints = gb_string_appendc(constraints, "}");
-					}
-
-					inline_asm = llvm_get_inline_asm(func_type, make_string_c(asm_string), make_string_c(constraints));
+                    GB_ASSERT(arg_count <= 7);
+
+                    if(build_context.metrics.os == TargetOs_darwin) {
+                        char asm_string[] = "svc #0x80";
+                        gbString constraints = gb_string_make(heap_allocator(), "={x0}");
+                        for (unsigned i = 0; i < arg_count; i++) {
+                            constraints = gb_string_appendc(constraints, ",{");
+                            static char const *regs[] = {
+                                "x16",
+                                "x0",
+                                "x1",
+                                "x2",
+                                "x3",
+                                "x4",
+                                "x5",
+                            };
+                            constraints = gb_string_appendc(constraints, regs[i]);
+                            constraints = gb_string_appendc(constraints, "}");
+                        }
+
+                        inline_asm = llvm_get_inline_asm(func_type, make_string_c(asm_string), make_string_c(constraints));
+                    } else {
+                        char asm_string[] = "svc #0";
+                        gbString constraints = gb_string_make(heap_allocator(), "={x0}");
+                        for (unsigned i = 0; i < arg_count; i++) {
+                            constraints = gb_string_appendc(constraints, ",{");
+                            static char const *regs[] = {
+                                "x8",
+                                "x0",
+                                "x1",
+                                "x2",
+                                "x3",
+                                "x4",
+                                "x5",
+                            };
+                            constraints = gb_string_appendc(constraints, regs[i]);
+                            constraints = gb_string_appendc(constraints, "}");
+                        }
+
+                        inline_asm = llvm_get_inline_asm(func_type, make_string_c(asm_string), make_string_c(constraints));
+                    }
 				}
 				break;
 			default:


Font texture are now created with both luminance and alpha

--- src/loader/FontLoader.cpp
+++ src/loader/FontLoader.cpp
@@ -24,18 +24,26 @@
     if (fileContent(path, &data, length))
     {
       font = new Font();
-      unsigned char * image = new unsigned char[textureWidth * textureHeight];
+      unsigned char * alpha = new unsigned char[textureWidth * textureHeight];

       stbtt_bakedchar charDef[96];
-      stbtt_BakeFontBitmap(data, 0, fontSize, image, textureWidth, textureHeight, 32, 96, charDef);
+      stbtt_BakeFontBitmap(data, 0, fontSize, alpha, textureWidth, textureHeight, 32, 96, charDef);
       delete[] data;
+
+      // Construct an luminance-alpha texture
+      unsigned char * image = new unsigned char[textureWidth * textureHeight * 2];
+      for (int i = 0, len = textureWidth * textureHeight; i < len; ++i)
+      {
+        image[i * 2 + 0] = 255;
+        image[i * 2 + 1] = alpha[i];
+      }

       // Create the texture
       Texture * texture = new Texture();
       texture->images[0] = image;
       texture->width = textureWidth;
       texture->height = textureHeight;
-      texture->format = AlphaFormat;
+      texture->format = LuminanceAlphaFormat;
       texture->imageDataType = UnsignedByteType;
       texture->type = Texture2D;
       font->texture = texture;


Added implementation of hypre_CSRMatrixAbsMatvec

--- linalg/hypre_parcsr.cpp
+++ linalg/hypre_parcsr.cpp
@@ -984,7 +984,126 @@
                               HYPRE_Real beta,
                               HYPRE_Real *y)
 {
-   // TODO: implement
+   HYPRE_Int        *A_i      = hypre_CSRMatrixI(A);
+   HYPRE_Int        *A_j      = hypre_CSRMatrixJ(A);
+   HYPRE_Int         num_rows = hypre_CSRMatrixNumRows(A);
+
+   HYPRE_Int        *A_rownnz = hypre_CSRMatrixRownnz(A);
+   HYPRE_Int         num_rownnz = hypre_CSRMatrixNumRownnz(A);
+
+   HYPRE_Real       *A_data  = hypre_CSRMatrixData(A);
+   HYPRE_Real       *x_data = x;
+   HYPRE_Real       *y_data = y;
+
+   HYPRE_Real        temp, tempx;
+
+   HYPRE_Int         i, jj;
+
+   HYPRE_Int         m;
+
+   HYPRE_Real        xpar=0.7;
+
+   /*-----------------------------------------------------------------------
+    * Do (alpha == 0.0) computation - RDF: USE MACHINE EPS
+    *-----------------------------------------------------------------------*/
+
+   if (alpha == 0.0)
+   {
+#ifdef HYPRE_USING_OPENMP
+      #pragma omp parallel for private(i) HYPRE_SMP_SCHEDULE
+#endif
+      for (i = 0; i < num_rows; i++)
+      {
+         y_data[i] = beta*y_data[i];
+      }
+      return;
+   }
+
+   /*-----------------------------------------------------------------------
+    * y = (beta/alpha)*y
+    *-----------------------------------------------------------------------*/
+
+   temp = beta / alpha;
+
+   if (temp != 1.0)
+   {
+      if (temp == 0.0)
+      {
+#ifdef HYPRE_USING_OPENMP
+         #pragma omp parallel for private(i) HYPRE_SMP_SCHEDULE
+#endif
+         for (i = 0; i < num_rows; i++)
+         {
+            y_data[i] = 0.0;
+         }
+      }
+      else
+      {
+#ifdef HYPRE_USING_OPENMP
+         #pragma omp parallel for private(i) HYPRE_SMP_SCHEDULE
+#endif
+         for (i = 0; i < num_rows; i++)
+         {
+            y_data[i] *= temp;
+         }
+      }
+   }
+
+   /*-----------------------------------------------------------------
+    * y += A*x
+    *-----------------------------------------------------------------*/
+
+   /* use rownnz pointer to do the A*x multiplication
+      when num_rownnz is smaller than num_rows */
+
+   if (num_rownnz < xpar*(num_rows))
+   {
+#ifdef HYPRE_USING_OPENMP
+      #pragma omp parallel for private(i,jj,m,tempx) HYPRE_SMP_SCHEDULE
+#endif
+      for (i = 0; i < num_rownnz; i++)
+      {
+         m = A_rownnz[i];
+
+         tempx = 0;
+         for (jj = A_i[m]; jj < A_i[m+1]; jj++)
+         {
+            tempx += fabs(A_data[jj])*x_data[A_j[jj]];
+         }
+         y_data[m] += tempx;
+      }
+   }
+   else
+   {
+#ifdef HYPRE_USING_OPENMP
+      #pragma omp parallel for private(i,jj,temp) HYPRE_SMP_SCHEDULE
+#endif
+      for (i = 0; i < num_rows; i++)
+      {
+         tempx = 0;
+         for (jj = A_i[i]; jj < A_i[i+1]; jj++)
+         {
+            tempx += fabs(A_data[jj])*x_data[A_j[jj]];
+         }
+         y_data[i] += tempx;
+      }
+   }
+
+   /*-----------------------------------------------------------------
+    * y = alpha*y
+    *-----------------------------------------------------------------*/
+
+   if (alpha != 1.0)
+   {
+#ifdef HYPRE_USING_OPENMP
+      #pragma omp parallel for private(i) HYPRE_SMP_SCHEDULE
+#endif
+      for (i = 0; i < num_rows; i++)
+      {
+         y_data[i] *= alpha;
+      }
+   }
+
 }

 /* Based on hypre_CSRMatrixMatvecT in hypre's csr_matvec.c */


videonode: Do not finish if material is different

Fix bluerobotics/qgroundcontrol#164

Signed-off-by: Patrick J.P <c2b7559029b4032a4ce95718d7d3bc36c8a1d7c1@gmail.com>

--- src/VideoStreaming/gstqtvideosink/painters/videonode.cpp
+++ src/VideoStreaming/gstqtvideosink/painters/videonode.cpp
@@ -52,14 +52,18 @@

 void VideoNode::setCurrentFrame(GstBuffer* buffer)
 {
-    Q_ASSERT (m_materialType == MaterialTypeVideo);
+    if (m_materialType != MaterialTypeVideo) {
+        return;
+    }
     static_cast<VideoMaterial*>(material())->setCurrentFrame(buffer);
     markDirty(DirtyMaterial);
 }

 void VideoNode::updateColors(int brightness, int contrast, int hue, int saturation)
 {
-    Q_ASSERT (m_materialType == MaterialTypeVideo);
+    if (m_materialType != MaterialTypeVideo) {
+        return;
+    }
     static_cast<VideoMaterial*>(material())->updateColors(brightness, contrast, hue, saturation);
     markDirty(DirtyMaterial);
 }


Agrego algunas validaciones

Agrego algunas validaciones

--- src/main/model/entity.cpp
+++ src/main/model/entity.cpp
@@ -665,7 +665,7 @@
 }

 std::shared_ptr<Command> Unit::giveDefaultCommand(Unit& r) {
-	if (owner.getActive() && owner.name != r.owner.name)
+	if (owner.getActive() && (owner.name != r.owner.name))
 		return std::make_shared<AttackCommand>(r.getId(), getId());
 	else
 		return giveDefaultCommand((Entity&)r);
@@ -676,14 +676,14 @@
 }

 std::shared_ptr<Command> Building::giveDefaultCommand(Unit& r) {
-	if (owner.getActive() && owner.name != r.owner.name)
+	if (owner.getActive() && (owner.name != r.owner.name))
 		return std::make_shared<AttackCommand>(r.getId(), getId());
 	else
 		return giveDefaultCommand((Entity&)r);
 }

 std::shared_ptr<Command> Building::giveDefaultCommand(Worker& r) {
-	if (owner.getActive() && owner.name != r.owner.name)
+	if (owner.getActive() && (owner.name != r.owner.name))
 		return giveDefaultCommand((Unit&)r);
 	else
 		return std::make_shared<RepairCommand>(r.getId(), getId());
@@ -694,7 +694,7 @@
 }

 std::shared_ptr<Command> Flag::giveDefaultCommand(Unit& r) {
-	if (owner.getActive() && owner.name != r.owner.name)
+	if (owner.getActive() && (owner.name != r.owner.name))
 		return std::make_shared<AttackCommand>(r.getId(), getId());
 	else
 		return giveDefaultCommand((Entity&)r);


Fix a bug in network telemetry manager

Fix a bug in network telemetry manager

-- Allow telemetry stats to be gathered and uploaded only when
   device is network and service provisioned.

--- src/adaptations/device-layer/NetworkTelemetryManager.cpp
+++ src/adaptations/device-layer/NetworkTelemetryManager.cpp
@@ -46,6 +46,7 @@

 WeaveTelemetryBase::WeaveTelemetryBase()
 {
+    mEnabled = false;
 }

 void WeaveTelemetryBase::Init(uint32_t aIntervalMsec)
@@ -91,7 +92,7 @@
 {
     WEAVE_ERROR err = WEAVE_NO_ERROR;

-    WeaveLogProgress(DeviceLayer, "Initiating Network Telemetry & Topology\n");
+    WeaveLogProgress(DeviceLayer, "Initiating Network Telemetry & Topology");

 #if WEAVE_DEVICE_CONFIG_ENABLE_WIFI_TELEMETRY
     mWiFiTelemetry.Init(WEAVE_DEVICE_CONFIG_DEFAULT_TELEMETRY_INTERVAL_MS);
@@ -109,14 +110,18 @@
     return err;
 }

-
 #if WEAVE_DEVICE_CONFIG_ENABLE_WIFI_TELEMETRY
 void WiFiTelemetry::GetTelemetryStatsAndLogEvent(void)
 {
     WEAVE_ERROR err;

-    err = ConnectivityMgr().GetAndLogWifiStatsCounters();
-    SuccessOrExit(err);
+    if (ConnectivityMgr().IsWiFiStationProvisioned() &&
+        ConnectivityMgr().IsWiFiStationEnabled() &&
+        ConfigurationMgr().IsPairedToAccount())
+    {
+        err = ConnectivityMgr().GetAndLogWifiStatsCounters();
+        SuccessOrExit(err);
+    }

 exit:
     return;
@@ -129,8 +134,13 @@
 {
     WEAVE_ERROR err;

-    err = ThreadStackMgr().GetAndLogThreadStatsCounters();
-    SuccessOrExit(err);
+    if (ConnectivityMgr().IsThreadProvisioned() &&
+        ConnectivityMgr().IsThreadEnabled() &&
+        ConfigurationMgr().IsPairedToAccount())
+    {
+        err = ThreadStackMgr().GetAndLogThreadStatsCounters();
+        SuccessOrExit(err);
+    }

 exit:
     return;
@@ -140,13 +150,18 @@
 {
     WEAVE_ERROR err;

+    if (ConnectivityMgr().IsThreadProvisioned() &&
+        ConnectivityMgr().IsThreadEnabled() &&
+        ConfigurationMgr().IsPairedToAccount())
+    {
 #if WEAVE_DEVICE_CONFIG_ENABLE_THREAD_TELEMETRY_FULL
-    err = ThreadStackMgr().GetAndLogThreadTopologyFull();
-    SuccessOrExit(err);
+        err = ThreadStackMgr().GetAndLogThreadTopologyFull();
+        SuccessOrExit(err);
 #else
-    err = ThreadStackMgr().GetAndLogThreadTopologyMinimal();
-    SuccessOrExit(err);
-#endif
+        err = ThreadStackMgr().GetAndLogThreadTopologyMinimal();
+        SuccessOrExit(err);
+#endif
+    }

 exit:
     return;
@@ -157,81 +172,85 @@
 #if WEAVE_DEVICE_CONFIG_ENABLE_TUNNEL_TELEMETRY
 void TunnelTelemetry::GetTelemetryStatsAndLogEvent(void)
 {
-    nl::Weave::Profiles::DataManagement_Current::event_id_t eventId;
-    nl::Weave::Profiles::WeaveTunnel::WeaveTunnelStatistics tunnelStats;
-    Schema::Weave::Trait::Telemetry::Tunnel::TelemetryTunnelTrait::TelemetryTunnelStatsEvent statsEvent;
-
-    ServiceTunnelAgent.GetWeaveTunnelStatistics(tunnelStats);
-
-    statsEvent.txBytesToService       = tunnelStats.mPrimaryStats.mTxBytesToService;
-    statsEvent.rxBytesFromService     = tunnelStats.mPrimaryStats.mRxBytesFromService;
-    statsEvent.txMessagesToService    = tunnelStats.mPrimaryStats.mTxMessagesToService;
-    statsEvent.rxMessagesFromService  = tunnelStats.mPrimaryStats.mRxMessagesFromService;
-    statsEvent.tunnelDownCount        = tunnelStats.mPrimaryStats.mTunnelDownCount;
-    statsEvent.tunnelConnAttemptCount = tunnelStats.mPrimaryStats.mTunnelConnAttemptCount;
-
-    statsEvent.lastTimeTunnelWentDown    = tunnelStats.mPrimaryStats.mLastTimeTunnelWentDown;
-    statsEvent.lastTimeTunnelEstablished = tunnelStats.mPrimaryStats.mLastTimeTunnelEstablished;
-
-    statsEvent.droppedMessagesCount = tunnelStats.mDroppedMessagesCount;
-
-    switch (ServiceTunnelAgent.GetWeaveTunnelAgentState())
-    {
-    case nl::Weave::Profiles::WeaveTunnel::WeaveTunnelAgent::kState_Initialized_NoTunnel:
-        statsEvent.currentTunnelState = Schema::Weave::Trait::Telemetry::Tunnel::TelemetryTunnelTrait::TUNNEL_STATE_NO_TUNNEL;
-        break;
-    case nl::Weave::Profiles::WeaveTunnel::WeaveTunnelAgent::kState_PrimaryTunModeEstablished:
-        statsEvent.currentTunnelState = Schema::Weave::Trait::Telemetry::Tunnel::TelemetryTunnelTrait::TUNNEL_STATE_PRIMARY_ESTABLISHED;
-        break;
-    case nl::Weave::Profiles::WeaveTunnel::WeaveTunnelAgent::kState_BkupOnlyTunModeEstablished:
-        statsEvent.currentTunnelState =
-            Schema::Weave::Trait::Telemetry::Tunnel::TelemetryTunnelTrait::TUNNEL_STATE_BACKUP_ONLY_ESTABLISHED;
-        break;
-    case nl::Weave::Profiles::WeaveTunnel::WeaveTunnelAgent::kState_PrimaryAndBkupTunModeEstablished:
-        statsEvent.currentTunnelState =
-            Schema::Weave::Trait::Telemetry::Tunnel::TelemetryTunnelTrait::TUNNEL_STATE_PRIMARY_AND_BACKUP_ESTABLISHED;
-        break;
-    default:
-        break;
-    }
-
-    switch (tunnelStats.mCurrentActiveTunnel)
-    {
-    case nl::Weave::Profiles::WeaveTunnel::kType_TunnelUnknown:
-        statsEvent.currentActiveTunnel = Schema::Weave::Trait::Telemetry::Tunnel::TelemetryTunnelTrait::TUNNEL_TYPE_NONE;
-        break;
-    case nl::Weave::Profiles::WeaveTunnel::kType_TunnelPrimary:
-        statsEvent.currentActiveTunnel = Schema::Weave::Trait::Telemetry::Tunnel::TelemetryTunnelTrait::TUNNEL_TYPE_PRIMARY;
-        break;
-    case nl::Weave::Profiles::WeaveTunnel::kType_TunnelBackup:
-        statsEvent.currentActiveTunnel = Schema::Weave::Trait::Telemetry::Tunnel::TelemetryTunnelTrait::TUNNEL_TYPE_BACKUP;
-        break;
-    case nl::Weave::Profiles::WeaveTunnel::kType_TunnelShortcut:
-        statsEvent.currentActiveTunnel = Schema::Weave::Trait::Telemetry::Tunnel::TelemetryTunnelTrait::TUNNEL_TYPE_SHORTCUT;
-        break;
-    default:
-        break;
-    }
-
-    WeaveLogProgress(DeviceLayer,
-                     "Weave Tunnel Counters\n"
-                     "Tx Messages:                   %d\n"
-                     "Rx Messages:                   %d\n"
-                     "Tunnel Down Count:             %d\n"
-                     "Tunnel Conn Attempt Count:     %d\n"
-                     "Tunnel State:                  %d\n"
-                     "CurrentActiveTunnel:           %d\n",
-                     statsEvent.txMessagesToService, statsEvent.rxMessagesFromService, statsEvent.tunnelDownCount, statsEvent.tunnelConnAttemptCount,
-                     statsEvent.currentTunnelState, statsEvent.currentActiveTunnel);
-
-    WeaveLogProgress(DeviceLayer,
-                     "Weave Tunnel Time Stamps\n"
-                     "LastTime TunnelWentDown:       %" PRIu64 "\n"
-                     "LastTime TunnelEstablished:    %" PRIu64 "\n",
-                     statsEvent.lastTimeTunnelWentDown, statsEvent.lastTimeTunnelEstablished);
-
-    eventId = nl::LogEvent(&statsEvent);
-    WeaveLogProgress(DeviceLayer, "Weave Tunnel Tolopoly Stats Event Id: %u\n", eventId);
+    if (ConnectivityMgr().GetServiceTunnelMode() == ConnectivityManager::kServiceTunnelMode_Enabled &&
+        ConfigurationMgr().IsPairedToAccount())
+    {
+        nl::Weave::Profiles::DataManagement_Current::event_id_t eventId;
+        nl::Weave::Profiles::WeaveTunnel::WeaveTunnelStatistics tunnelStats;
+        Schema::Weave::Trait::Telemetry::Tunnel::TelemetryTunnelTrait::TelemetryTunnelStatsEvent statsEvent;
+
+        ServiceTunnelAgent.GetWeaveTunnelStatistics(tunnelStats);
+
+        statsEvent.txBytesToService       = tunnelStats.mPrimaryStats.mTxBytesToService;
+        statsEvent.rxBytesFromService     = tunnelStats.mPrimaryStats.mRxBytesFromService;
+        statsEvent.txMessagesToService    = tunnelStats.mPrimaryStats.mTxMessagesToService;
+        statsEvent.rxMessagesFromService  = tunnelStats.mPrimaryStats.mRxMessagesFromService;
+        statsEvent.tunnelDownCount        = tunnelStats.mPrimaryStats.mTunnelDownCount;
+        statsEvent.tunnelConnAttemptCount = tunnelStats.mPrimaryStats.mTunnelConnAttemptCount;
+
+        statsEvent.lastTimeTunnelWentDown    = tunnelStats.mPrimaryStats.mLastTimeTunnelWentDown;
+        statsEvent.lastTimeTunnelEstablished = tunnelStats.mPrimaryStats.mLastTimeTunnelEstablished;
+
+        statsEvent.droppedMessagesCount = tunnelStats.mDroppedMessagesCount;
+
+        switch (ServiceTunnelAgent.GetWeaveTunnelAgentState())
+        {
+        case nl::Weave::Profiles::WeaveTunnel::WeaveTunnelAgent::kState_Initialized_NoTunnel:
+            statsEvent.currentTunnelState = Schema::Weave::Trait::Telemetry::Tunnel::TelemetryTunnelTrait::TUNNEL_STATE_NO_TUNNEL;
+            break;
+        case nl::Weave::Profiles::WeaveTunnel::WeaveTunnelAgent::kState_PrimaryTunModeEstablished:
+            statsEvent.currentTunnelState = Schema::Weave::Trait::Telemetry::Tunnel::TelemetryTunnelTrait::TUNNEL_STATE_PRIMARY_ESTABLISHED;
+            break;
+        case nl::Weave::Profiles::WeaveTunnel::WeaveTunnelAgent::kState_BkupOnlyTunModeEstablished:
+            statsEvent.currentTunnelState =
+                Schema::Weave::Trait::Telemetry::Tunnel::TelemetryTunnelTrait::TUNNEL_STATE_BACKUP_ONLY_ESTABLISHED;
+            break;
+        case nl::Weave::Profiles::WeaveTunnel::WeaveTunnelAgent::kState_PrimaryAndBkupTunModeEstablished:
+            statsEvent.currentTunnelState =
+                Schema::Weave::Trait::Telemetry::Tunnel::TelemetryTunnelTrait::TUNNEL_STATE_PRIMARY_AND_BACKUP_ESTABLISHED;
+            break;
+        default:
+            break;
+        }
+
+        switch (tunnelStats.mCurrentActiveTunnel)
+        {
+        case nl::Weave::Profiles::WeaveTunnel::kType_TunnelUnknown:
+            statsEvent.currentActiveTunnel = Schema::Weave::Trait::Telemetry::Tunnel::TelemetryTunnelTrait::TUNNEL_TYPE_NONE;
+            break;
+        case nl::Weave::Profiles::WeaveTunnel::kType_TunnelPrimary:
+            statsEvent.currentActiveTunnel = Schema::Weave::Trait::Telemetry::Tunnel::TelemetryTunnelTrait::TUNNEL_TYPE_PRIMARY;
+            break;
+        case nl::Weave::Profiles::WeaveTunnel::kType_TunnelBackup:
+            statsEvent.currentActiveTunnel = Schema::Weave::Trait::Telemetry::Tunnel::TelemetryTunnelTrait::TUNNEL_TYPE_BACKUP;
+            break;
+        case nl::Weave::Profiles::WeaveTunnel::kType_TunnelShortcut:
+            statsEvent.currentActiveTunnel = Schema::Weave::Trait::Telemetry::Tunnel::TelemetryTunnelTrait::TUNNEL_TYPE_SHORTCUT;
+            break;
+        default:
+            break;
+        }
+
+        WeaveLogProgress(DeviceLayer,
+                         "Weave Tunnel Counters\n"
+                         "Tx Messages:                   %d\n"
+                         "Rx Messages:                   %d\n"
+                         "Tunnel Down Count:             %d\n"
+                         "Tunnel Conn Attempt Count:     %d\n"
+                         "Tunnel State:                  %d\n"
+                         "CurrentActiveTunnel:           %d\n",
+                         statsEvent.txMessagesToService, statsEvent.rxMessagesFromService, statsEvent.tunnelDownCount, statsEvent.tunnelConnAttemptCount,
+                         statsEvent.currentTunnelState, statsEvent.currentActiveTunnel);
+
+        WeaveLogProgress(DeviceLayer,
+                         "Weave Tunnel Time Stamps\n"
+                         "LastTime TunnelWentDown:       %" PRIu64 "\n"
+                         "LastTime TunnelEstablished:    %" PRIu64 "\n",
+                         statsEvent.lastTimeTunnelWentDown, statsEvent.lastTimeTunnelEstablished);
+
+        eventId = nl::LogEvent(&statsEvent);
+        WeaveLogProgress(DeviceLayer, "Weave Tunnel Tolopoly Stats Event Id: %u\n", eventId);
+    }

     return;
 }


testing

testing

--- src/Micro/MicroManager.cpp
+++ src/Micro/MicroManager.cpp
@@ -197,7 +197,7 @@

 void MicroManager::checkDefense(){
 	//Run through all our bases. Set defense in the main OR in the natural expo, and some defenses in all bases
-
+

 }


Delete entity.hpp

Delete entity.hpp

--- src/entity.hpp
+++ src/entity.hpp
@@ -1,12 +0,0 @@
-#pragma once
-
-#include "vector.hpp"
-
-struct entity_t{
-	typedef vector3_t<float> position_t, velocity_t;
-	position_t position;
-	velocity_t velocity;
-	void move(position_t offset);
-	void accelerate(velocity_t ammount);
-	void update(); //std::chrono?
-};


Added method getDefaultEphemeris().

Added method getDefaultEphemeris().

git-svn-id: 6625e4d6743179724b113c04fbf297d122273a36@535 108fab2b-820f-0410-9f2c-e5cc2c41d7be

--- src/ModeledReferencePR.hpp
+++ src/ModeledReferencePR.hpp
@@ -258,6 +258,14 @@
         };

+        /** Method to get a pointer to the default EphemerisStore to be used with GNSS data structures.
+         */
+        virtual EphemerisStore* getDefaultEphemeris()
+        {
+           return pDefaultEphemeris;
+        };
+
+
         /// Destructor.
         virtual ~ModeledReferencePR() throw() {};


Revert bug in overwriting Content-Type headers

--- RestClient.cpp
+++ RestClient.cpp
@@ -14,7 +14,7 @@
     ssl = 0;
     fingerprint = NULL;
     num_headers = 0;
-        if (contentType != NULL) {
+        if (contentType == NULL) {
             contentType = "application/x-www-form-urlencoded";  // default
 	}
 }
@@ -25,7 +25,7 @@
     ssl = 0;
     fingerprint = NULL;
     num_headers = 0;
-        if (contentType != NULL) {
+        if (contentType == NULL) {
             contentType = "application/x-www-form-urlencoded";  // default
         }
 }
@@ -48,7 +48,7 @@
     ssl = 1;
     fingerprint = _fingerprint;
     num_headers = 0;
-        if (contentType != NULL) {
+        if (contentType == NULL) {
             contentType = "application/x-www-form-urlencoded";  // default
         }
 }
@@ -59,7 +59,7 @@
     ssl = (_ssl) ? 1 : 0;
     fingerprint = NULL;
     num_headers = 0;
-        if (contentType != NULL) {
+        if (contentType == NULL) {
             contentType = "application/x-www-form-urlencoded";  // default
         }
 }


Handle foreign results null pointers as non-errors (#15)

* Handle foreign results null pointers as non-errors if the
foreign function returns no results.

Signed-off-by: John Plevyak <21e8c5cc24c747cac934fcbef39d1b757b61996c@gmail.com>

--- src/exports.cc
+++ src/exports.cc
@@ -231,16 +231,24 @@
   uint64_t address = 0;
   void *result = nullptr;
   size_t result_size = 0;
-  auto res = f(wasm, args, [&wasm, &address, &result, &result_size](size_t s) -> void * {
-    result = wasm.allocMemory(s, &address);
+  auto res = f(wasm, args, [&wasm, &address, &result, &result_size, results](size_t s) -> void * {
+    if (results) {
+      result = wasm.allocMemory(s, &address);
+    } else {
+      // If the caller does not want the results, allocate a temporary buffer for them.
+      result = ::malloc(s);
+    }
     result_size = s;
     return result;
   });
-  if (!context->wasmVm()->setWord(results, Word(address))) {
-    return WasmResult::InvalidMemoryAccess;
-  }
-  if (!context->wasmVm()->setWord(results_size, Word(result_size))) {
-    return WasmResult::InvalidMemoryAccess;
+  if (results && !context->wasmVm()->setWord(results, Word(address))) {
+    return WasmResult::InvalidMemoryAccess;
+  }
+  if (results_size && !context->wasmVm()->setWord(results_size, Word(result_size))) {
+    return WasmResult::InvalidMemoryAccess;
+  }
+  if (!results) {
+    ::free(result);
   }
   return res;
 }


Added new constructor, members and methods to ModeledReferencePR in order to adapt it to GNSS data structures.

git-svn-id: 6625e4d6743179724b113c04fbf297d122273a36@532 108fab2b-820f-0410-9f2c-e5cc2c41d7be

--- src/ModeledReferencePR.hpp
+++ src/ModeledReferencePR.hpp
@@ -94,6 +94,19 @@
         };

+        /** Explicit constructor, taking as input a Position object containing reference
+         * station coordinates.
+         * @param dIonoModel    Ionospheric model to be used by default.
+         * @param dTropoModel   Tropospheric model to be used by default.
+         */
+        ModeledReferencePR(Position RxCoordinates, IonoModelStore& dIonoModel, TropModel& dTropoModel) throw(Exception) {
+            InitializeValues();
+            setInitialRxPosition(RxCoordinates);
+            setDefaultIonoModel(dIonoModel);
+            setDefaultTropoModel(dTropoModel);
+        };
+
+
         /** Compute the modeled pseudoranges, given satellite ID's, pseudoranges and other data
          * @param Tr            Measured time of reception of the data.
          * @param Satellite     Vector of satellites; on successful return, satellites that
@@ -170,6 +183,12 @@

     protected:
+
+        /// Pointer to default ionospheric model
+        IonoModelStore *pDefaultIonoModel;
+
+        /// Pointer to default tropospheric model
+        TropModel *pDefaultTropoModel;

         /// Initialization method
         void InitializeValues() throw(Exception) {
@@ -188,6 +207,8 @@
             rejectedSV(0);
             useTGD = true;
             minElev = 10.0;  // By default, cut-off elevation is set to 10 degrees
+            pDefaultIonoModel = NULL;
+            pDefaultTropoModel = NULL;
         };

@@ -297,6 +318,33 @@
         };

+        /** Method to set the default ionospheric model.
+         * @param dIonoModel    Ionospheric model to be used by default.
+         */
+        void setDefaultIonoModel(IonoModelStore& dIonoModel)
+        {
+           pDefaultIonoModel = &dIonoModel;
+        };
+
+
+        /** Method to set the default tropospheric model.
+         * @param dTropoModel    Tropospheric model to be used by default.
+         */
+        void setDefaultTropoModel(TropModel& dTropoModel)
+        {
+           pDefaultTropoModel = &dTropoModel;
+        };
+
+
+        /** Method to set the default extra biases.
+         * @param eBiases    Vector with the default extra biases
+         */
+        void setDefaultExtraBiases(Vector<double>& eBiases)
+        {
+           extraBiases = eBiases;
+        };
+
+
    }; // class ModeledReferencePR

    //@}


Add check in weave to avoid segfault

Add check in weave to avoid segfault

--- src/extend.cpp
+++ src/extend.cpp
@@ -1463,6 +1463,7 @@
       Node current = afters.collection()->front().clone(ctx);
       afters.collection()->pop_front();
       DEBUG_PRINTLN(WEAVE, "CURRENT: " << current)
+      if (current.collection()->size() == 0) continue;

       Node last_current = Node::createCollection();
       last_current.collection()->push_back(current.collection()->back());


fuzzing bugs gone too

fuzzing bugs gone too

--- src/extend.cpp
+++ src/extend.cpp
@@ -49,13 +49,10 @@
       last = lit;
     }
     if (satisfied) continue;
-    flipped++;
     assert (last);
     LOG ("flipping blocking literal %d", last);
-    const int idx = vidx (last);
-    const int tmp = sign (last);
-    vals[idx] = tmp;
-    vals[-idx] = -tmp;
+    vals[vidx (last)] = sign (last);
+    flipped++;
   }
   VRB ("extend", "flipped %ld literals during extension", flipped);
   STOP (extend);


remove Creatures 3 from the window title

--- SDLBackend.cpp
+++ SDLBackend.cpp
@@ -71,7 +71,7 @@

 	resizeNotify(800, 600);

-	SDL_WM_SetCaption("openc2e - Creatures 3 (development build)", "openc2e");
+	SDL_WM_SetCaption("openc2e (development build " __DATE__ ")", "openc2e");
 	SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
 	SDL_ShowCursor(false);
 }


fcache: use DeleteUnrefTrashPool() to destroy FilterCacheRequest

Eliminate the now-obsolete workaround.

--- src/fcache.cxx
+++ src/fcache.cxx
@@ -288,14 +288,7 @@

     request->timeout_event.Cancel();

-    /* DeleteUnrefTrashPool() poisons the object and trashes the pool,
-       which breaks the istream_read() call in
-       filter_cache_response_response() and causes an assertion
-       failure when the sink_rubber closes the stream */
-    //DeleteUnrefTrashPool(*request->pool, request);
-    request->~FilterCacheRequest();
-    pool_unref(&request->pool);
-    /* TODO: eliminate the above workaround */
+    DeleteUnrefTrashPool(request->pool, request);
 }

 /**


Improved the behavior of pivot reports

Improved the behavior of pivot reports

--- src/filters.cc
+++ src/filters.cc
@@ -793,18 +793,25 @@
     break;

   case SET_ACCOUNT: {
-    account_t * prev_account = temp.account;
-    temp.account->remove_post(&temp);
-
-    std::list<string> account_names;
-    split_string(substitute.to_string(), ':', account_names);
-    temp.account = create_temp_account_from_path(account_names, temps,
-						 xact.journal->master);
-    temp.account->add_post(&temp);
-
-    temp.account->add_flags(prev_account->flags());
-    if (prev_account->has_xdata())
-      temp.account->xdata().add_flags(prev_account->xdata().flags());
+    string account_name = substitute.to_string();
+    if (! account_name.empty() &&
+	account_name[account_name.length() - 1] != ':') {
+      account_t * prev_account = temp.account;
+      temp.account->remove_post(&temp);
+
+      account_name += ':';
+      account_name += prev_account->fullname();
+
+      std::list<string> account_names;
+      split_string(account_name, ':', account_names);
+      temp.account = create_temp_account_from_path(account_names, temps,
+						   xact.journal->master);
+      temp.account->add_post(&temp);
+
+      temp.account->add_flags(prev_account->flags());
+      if (prev_account->has_xdata())
+	temp.account->xdata().add_flags(prev_account->xdata().flags());
+    }
     break;
   }


superbubbles update, WIP

superbubbles update, WIP

--- src/repeat_graph/haplotype_resolver.cpp
+++ src/repeat_graph/haplotype_resolver.cpp
@@ -126,6 +126,7 @@
 int HaplotypeResolver::findHeterozygousLoops()
 {
 	const float COV_MULT = 1.5;
+	const int MAX_LOOP_LEN = Config::get("max_bubble_length");

 	GraphProcessor proc(_graph, _asmSeqs);
 	auto unbranchingPaths = proc.getUnbranchingPaths();
@@ -138,6 +139,7 @@
 		if (!loop.id.strand()) continue;
 		if (!loop.isLooped()) continue;
 		if (loop.path.front()->selfComplement) continue;
+		if (loop.length > MAX_LOOP_LEN) continue;

 		GraphNode* node = loop.nodeLeft();
 		if (node->inEdges.size() != 2 ||
@@ -175,6 +177,9 @@
 		GraphEdge* inEdge = entrancePath->path.back();
 		GraphEdge* outEdge = exitPath->path.front();
 		if (inEdge->rightLink || outEdge->leftLink) continue;
+
+		Logger::get().debug() << "Bubble-loop: " << inEdge->edgeId.signedId()
+			<< " " << outEdge->edgeId.signedId();

 		//links
 		_graph.linkEdges(inEdge, outEdge);
@@ -405,7 +410,7 @@
 	}
 	if (bubbleBranches.size() < 2) return VariantPaths();

-	for (auto& aln : bubbleBranches)
+	/*for (auto& aln : bubbleBranches)
 	{
 		std::string pathStr;
 		for (size_t i = 0; i < aln.path.size(); ++i)
@@ -413,7 +418,7 @@
 			pathStr += std::to_string(aln.path[i].edge->edgeId.signedId()) + " -> ";
 		}
 		Logger::get().debug() << "\tBranch: " << pathStr << aln.score;
-	}
+	}*/

 	VariantPaths vp;
 	vp.startEdge = refPath.path[bubbleStartId].edge;
@@ -693,40 +698,86 @@
 		return deadEnds[maxId].path;
 	};

+	//helper structures for dijkstra
+	struct DijkstraResult
+	{
+		DijkstraResult(): failure(false) {}
+		std::unordered_map<GraphEdge*, int> dist;
+		std::unordered_map<GraphEdge*, GraphEdge*> prev;
+		bool failure;
+	};
+	struct EdgeWithPriority
+	{
+		GraphEdge* edge;
+		int priority;
+	};
+	auto lowestPri = [](EdgeWithPriority& e1, EdgeWithPriority& e2)
+		{return e1.priority > e2.priority;};
+
+	//returns all discoverable edges within maxBubble
+	/*auto getDiscoverable = [](GraphEdge* source, int maxBubble)
+	{
+		std::priority_queue<EdgeWithPriority,
+							std::vector<EdgeWithPriority>,
+							decltype(lowestPri)> queue(lowestPri);
+		DijkstraResult res;
+		res.dist[source] = 0;
+		res.prev[source] = nullptr;
+		queue.push({source, 0});
+		std::unordered_set<GraphEdge*> closed;
+
+		while (!queue.empty())
+		{
+			auto curEdge = queue.top();
+			queue.pop();
+			if (closed.count(curEdge.edge)) continue;	//instead of doing "update_priority"
+			closed.insert(curEdge.edge);
+
+			if (curEdge.priority > maxBubble) continue;	//gone too far
+
+			for (auto& nextEdge : curEdge.edge->nodeRight->outEdges)
+			{
+				int newDist = curEdge.priority + nextEdge->length() + 1;
+				if (!res.dist.count(nextEdge) || newDist < res.dist[nextEdge])
+				{
+					res.dist[nextEdge] = newDist;
+					res.prev[nextEdge] = curEdge.edge;
+					queue.push({nextEdge, newDist});
+				}
+			}
+		}
+
+		res.dist.erase(source);
+		return res;
+	};*/
+
 	//runs dijskstra algorithm and returns shortest paths
 	//lengths from source to all edges. terminates
 	//with failure if the distance start to exceed maxBubble
-		struct DijkstraResult
-	{
-		DijkstraResult(): failure(false) {}
-		std::unordered_map<GraphEdge*, int> dist;
-		bool failure;
-	};
-
 	auto getShortestPathsLen = [](GraphEdge* source, GraphEdge* sink,
 								  int maxBubble)
 	{
 		DijkstraResult res;
-		struct EdgeWithPriority
-		{
-			GraphEdge* edge;
-			int priority;
-		};
-		auto lowestPri = [](EdgeWithPriority& e1, EdgeWithPriority& e2)
-			{return e1.priority > e2.priority;};
 		std::priority_queue<EdgeWithPriority,
 							std::vector<EdgeWithPriority>,
 							decltype(lowestPri)> queue(lowestPri);
-
 		res.dist[source] = 0;
 		queue.push({source, 0});
 		std::unordered_set<GraphEdge*> closed;
+
 		while (!queue.empty())
 		{
 			auto curEdge = queue.top();
 			queue.pop();
 			if (closed.count(curEdge.edge)) continue;
 			closed.insert(curEdge.edge);
+
+			//dead end
+			if (curEdge.edge->nodeRight->outEdges.empty())
+			{
+				res.failure = true;
+				return res;
+			}

 			for (auto& nextEdge : curEdge.edge->nodeRight->outEdges)
 			{
@@ -751,6 +802,43 @@
 		return res;
 	};

+	//checks if there is a path between two nodes of length
+	//at most maxBubble
+	/*auto hasPath = [](GraphEdge* source, GraphEdge* sink,
+					  int maxBubble)
+	{
+		DijkstraResult res;
+		std::priority_queue<EdgeWithPriority,
+							std::vector<EdgeWithPriority>,
+							decltype(lowestPri)> queue(lowestPri);
+		res.dist[source] = 0;
+		queue.push({source, 0});
+		std::unordered_set<GraphEdge*> closed;
+
+		while (!queue.empty())
+		{
+			auto curEdge = queue.top();
+			queue.pop();
+			if (closed.count(curEdge.edge)) continue;
+			closed.insert(curEdge.edge);
+			if (curEdge.priority > maxBubble) continue;
+
+			for (auto& nextEdge : curEdge.edge->nodeRight->outEdges)
+			{
+				if (nextEdge == sink) return true;
+
+				int newDist = curEdge.priority + nextEdge->length() + 1;
+				if (!res.dist.count(nextEdge) || newDist < res.dist[nextEdge])
+				{
+					res.dist[nextEdge] = newDist;
+					queue.push({nextEdge, newDist});
+				}
+			}
+		}
+
+		return false;
+	};*/
+
 	struct Superbubble
 	{
 		Superbubble(): start(nullptr), end(nullptr) {}
@@ -761,25 +849,51 @@
 	};

 	Superbubble isRightSuperbubble(GraphEdge* startEdge, int maxBubbleLen,
-								  const RepeatGraph& graph)
-	{
-		//Logger::get().debug() << "From: " << startEdge->edgeId.signedId();
-
-		//arbitrary "reference path". If all paths converge, then
-		//this one does as well.
+								   const RepeatGraph& graph,
+								   const std::unordered_set<GraphEdge*> loopedEdges)
+	{
+		Logger::get().debug() << "From: " << startEdge->edgeId.signedId();
+
 		auto refPath = anyPath(startEdge, maxBubbleLen);
 		if (refPath.empty()) return Superbubble();

-		/*std::string pathStr;
+		std::string pathStr;
 		for (size_t i = 0; i < refPath.size(); ++i)
 		{
 			pathStr += std::to_string(refPath[i]->edgeId.signedId()) + " -> ";
 		}
-		Logger::get().debug() << "\tReference path: " << pathStr;*/
-
+		Logger::get().debug() << "\tReference path: " << pathStr;
+
+		/*auto discoverableEdges = getDiscoverable(startEdge, maxBubbleLen);
+		if (discoverableEdges.dist.empty()) return Superbubble();
+		std::vector<GraphEdge*> endCandidates;
+		for (auto& discovIter : discoverableEdges.dist)
+		{
+			endCandidates.push_back(discovIter.first);
+		}
+		std::sort(endCandidates.begin(), endCandidates.end(),
+				  [&discoverableEdges](GraphEdge* e1, GraphEdge* e2)
+				  	{return discoverableEdges.dist[e1] < discoverableEdges.dist[e2];});*/
+
+		//for (GraphEdge* endCand : endCandidates)
 		for (GraphEdge* endCand : refPath)
 		{
 			if (endCand == startEdge) continue;
+			if (loopedEdges.count(endCand)) continue;
+
+			int numIn = 0;
+			int numOut = 0;
+			for (auto& edge : endCand->nodeLeft->inEdges)
+			{
+				if (!loopedEdges.count(edge)) ++numIn;
+			}
+			for (auto& edge : endCand->nodeLeft->outEdges)
+			{
+				if (!loopedEdges.count(edge)) ++numOut;
+			}
+			if (numOut > 1 || numIn < 2) continue;
+			//if (endCand->nodeLeft->outEdges.size() > 1 ||
+			//	endCand->nodeLeft->inEdges.size() < 2) continue;

 			//Logger::get().debug() << "\t\tEnd check: " << endCand->edgeId.signedId();

@@ -790,11 +904,7 @@
 									graph.complementEdge(startEdge),
 									maxBubbleLen);
 			if (distancesFromSource.failure ||
-				distancesFromSink.failure)
-			{
-				//Logger::get().debug() << "\t\tDiverged!";
-				continue;
-			}
+				distancesFromSink.failure) continue;

 			/*for (auto& edgeDist : distancesFromSource.dist)
 			{
@@ -807,6 +917,9 @@
 					<< " " << edgeDist.second;
 			}*/

+			//check that set of reachable (internal) edges consistent
+			//and each internal edge is connected to source and sink
+			//by a path < maxBubble.
 			bool goodBubble = true;
 			for (auto& edgeDist : distancesFromSource.dist)
 			{
@@ -824,8 +937,33 @@
 					break;
 				}
 			}
+			for (auto& edgeDist : distancesFromSink.dist)
+			{
+				GraphEdge* complEdge = graph.complementEdge(edgeDist.first);
+				if (!distancesFromSource.dist.count(complEdge))
+				{
+					goodBubble = false;
+					break;
+				}
+			}
+
+			//check if one cannot reach source from sink (fwd direction)
+			//if (hasPath(endCand, startEdge, maxBubbleLen)) goodBubble = false;
+
 			if (goodBubble)
 			{
+				//trace back reference path
+				/*GraphPath refPath;
+				GraphEdge* curEdge = endCand;
+				refPath.push_back(curEdge);
+				do
+				{
+					curEdge = discoverableEdges.prev[curEdge];
+					refPath.push_back(curEdge);
+				}
+				while (curEdge != startEdge);
+				std::reverse(refPath.begin(), refPath.end());*/
+
 				Superbubble sb;
 				sb.start = startEdge;
 				sb.end = endCand;
@@ -835,6 +973,7 @@
 					if (edgeDist.first != sb.start &&
 						edgeDist.first != sb.end) sb.internalEdges.insert(edgeDist.first);
 				}
+				Logger::get().debug() << "Good end: " << sb.end->edgeId.signedId();
 				return sb;
 			}
 		}
@@ -864,19 +1003,40 @@
 	{
 		if (loopedEdges.count(startEdge)) continue;
 		if (usedEdges.count(startEdge)) continue;
-		if (startEdge->nodeRight->inEdges.size() > 1 ||
-			startEdge->nodeRight->outEdges.size() < 2) continue;
+		//if (!startEdge->nodeRight->isBifurcation()) continue;
+
+		int numIn = 0;
+		int numOut = 0;
+		for (auto& edge : startEdge->nodeRight->inEdges)
+		{
+			if (!loopedEdges.count(edge)) ++numIn;
+		}
+		for (auto& edge : startEdge->nodeRight->outEdges)
+		{
+			if (!loopedEdges.count(edge)) ++numOut;
+		}
+		if (numOut < 2 || numIn > 1) continue;
+
+		//if (startEdge->nodeRight->inEdges.size() > 1 ||
+		//	startEdge->nodeRight->outEdges.size() < 2) continue;

 		//finding superbubble in one direction
-		auto fwdBubble = isRightSuperbubble(startEdge, MAX_BUBBLE_LEN, _graph);
+		auto fwdBubble = isRightSuperbubble(startEdge, MAX_BUBBLE_LEN,
+											_graph, loopedEdges);
 		if (!fwdBubble.end || startEdge == fwdBubble.end ||
 			startEdge == _graph.complementEdge(fwdBubble.end)) continue;

-		//in the opposit direction, both directions must agree
-		auto revBubble = isRightSuperbubble(_graph.complementEdge(fwdBubble.end),
-											MAX_BUBBLE_LEN, _graph);
+		//in the opposite direction, both directions must agree
+		/*auto revBubble = isRightSuperbubble(_graph.complementEdge(fwdBubble.end),
+											MAX_BUBBLE_LEN, _graph, loopedEdges);
 		if (!revBubble.end ||
-			startEdge != _graph.complementEdge(revBubble.end)) continue;
+			startEdge != _graph.complementEdge(revBubble.end))
+		{
+			Logger::get().warning() << "Direction inconsistency! "
+				<< startEdge->edgeId.signedId() << " "
+				<< fwdBubble.end->edgeId.signedId();
+			continue;
+		}*/

 		//superbubble found!
 		usedEdges.insert(_graph.complementEdge(fwdBubble.end));
@@ -921,6 +1081,13 @@
 			pathStr += std::to_string(edge->edgeId.signedId()) + " ";
 		}
 		Logger::get().debug() << "\t\tInternal: " << pathStr;
+
+		/*if (startEdge->nodeRight->inEdges.size() > 1 ||
+			fwdBubble.end->nodeLeft->outEdges.size() > 1)
+		if (numIn > 1)
+		{
+			Logger::get().debug() << " Interesting!";
+		}*/
 		//
 	}