<commit_before>// Copyright (C) 2012-2015 Leap Motion, Inc. All rights reserved.
#include "stdafx.h"
#include "BasicThread.h"
#include "Autowired.h"
#include "BasicThreadStateBlock.h"
#include "ContextEnumerator.h"
#include "fast_pointer_cast.h"
#include ATOMIC_HEADER

BasicThread::BasicThread(const char* pName):
  ContextMember(pName),
  m_state(std::make_shared<BasicThreadStateBlock>()),
  m_wasStarted(false),
  m_stop(false),
  m_running(false),
  m_priority(ThreadPriority::Default)
{}

BasicThread::~BasicThread(void){}

std::mutex& BasicThread::GetLock(void) {
  return m_state->m_lock;
}

void BasicThread::DoRun(std::shared_ptr<CoreObject>&& refTracker) {
  assert(m_running);
  m_wasStarted = true;

  // Make our own session current before we do anything else:
  CurrentContextPusher pusher(GetContext());

  // Set the thread name no matter what:
  if(GetName())
    SetCurrentThreadName();

  // Now we wait for the thread to be good to go:
  try {
    Run();
  }
  catch(dispatch_aborted_exception&) {
    // Okay, this is fine, a dispatcher is terminating--this is a normal way to
    // end a dispatcher loop.
  }
  catch(...) {
    try {
      // Ask that the enclosing context filter this exception, if possible:
      GetContext()->FilterException();
    }
    catch(...) {
      // Generic exception, unhandled, we can't do anything about this
    }

    // Signal shutdown on the enclosing context--cannot wait, if we wait we WILL deadlock
    GetContext()->SignalShutdown(false);
  }

  // Run loop is over, time to clean up
  DoRunLoopCleanup(pusher.Pop(), std::move(refTracker));
}

void BasicThread::DoRunLoopCleanup(std::shared_ptr<CoreContext>&& ctxt, std::shared_ptr<CoreObject>&& refTracker) {
  // Take a copy of our state condition shared pointer while we still hold a reference to
  // ourselves.  This is the only member out of our collection of members that we actually
  // need to hold a reference to.
  auto state = m_state;

  // Perform a manual notification of teardown listeners
  NotifyTeardownListeners();

  // Transition to stopped state.  Synchronization not required, transitions are all one-way
  m_stop = true;
  m_running = false;

  // Tell our CoreRunnable parent that we're done to ensure that our reference count will be cleared.
  Stop(false);

  // Release our hold on the context.  After this point, we have to be VERY CAREFUL that we
  // don't try to refer to any of our own member variables, because our own object may have
  // already gone out of scope.  [this] is potentially dangling.
  ctxt.reset();

  // Clear our reference tracker, which will notify anyone who is asleep and also maybe
  // will destroy the entire underlying context.
  refTracker.reset();

  // MUST detach here.  By this point in the application, it's possible that `this` has already been
  // deleted.  If that's the case, `state.unique()` is true, and when we go out of scope, the destructor
  // for m_thisThread will be invoked.  If that happens, the destructor will block for the held thread
  // to quit--and, in this case, the thread which is being held is actually us.  Blocking on it, in that
  // case, would be a trivial deadlock.  So, because we're about to quit anyway, we simply detach the
  // thread and prepare for final teardown operations.
  state->m_thisThread.detach();

  // Notify other threads that we are done.  At this point, any held references that might still exist
  // notification must happen from a synchronized level in order to ensure proper ordering.
  std::lock_guard<std::mutex> lk(state->m_lock);
  state->m_completed = true;
  state->m_stateCondition.notify_all();
}

void BasicThread::WaitForStateUpdate(const std::function<bool()>& fn) {
  std::unique_lock<std::mutex> lk(m_state->m_lock);
  m_state->m_stateCondition.wait(
    lk,
    [&fn, this] {
      return fn() || ShouldStop();
    }
  );
  if(ShouldStop())
    throw dispatch_aborted_exception();
}

void BasicThread::PerformStatusUpdate(const std::function<void()>& fn) {
  std::unique_lock<std::mutex> lk(m_state->m_lock);
  fn();
  m_state->m_stateCondition.notify_all();
}

bool BasicThread::ThreadSleep(std::chrono::nanoseconds timeout) {
  std::unique_lock<std::mutex> lk(m_state->m_lock);
  return m_state->m_stateCondition.wait_for(lk, timeout, [this] { return ShouldStop(); });
}

bool BasicThread::OnStart(void) {
  std::shared_ptr<CoreContext> context = m_context.lock();
  if(!context)
    return false;

  // Currently running:
  m_running = true;

  // Place the new thread entity directly in the space where it goes to avoid
  // any kind of races arising from asynchronous access to this space
  auto outstanding = GetOutstanding();
  m_state->m_thisThread.~thread();
  new (&m_state->m_thisThread) std::thread(
    [this, outstanding] () mutable {
      this->DoRun(std::move(outstanding));
    }
  );
  return true;
}

void BasicThread::OnStop(bool graceful) {
  // If we were never started, we need to set our completed flag to true
  if (!m_wasStarted)
    m_state->m_completed = true;

  // Always invoke stop handler:
  OnStop();
}

void BasicThread::DoAdditionalWait(void) {
  // Wait for the run loop cleanup to happen in DoRunLoopCleanup
  std::unique_lock<std::mutex> lk(m_state->m_lock);
  m_state->m_stateCondition.wait(
    lk,
    [this] { return m_state->m_completed; }
  );
}

bool BasicThread::DoAdditionalWait(std::chrono::nanoseconds timeout) {
  // Wait for the run loop cleanup to happen in DoRunLoopCleanup
  std::unique_lock<std::mutex> lk(m_state->m_lock);
  return m_state->m_stateCondition.wait_for(
    lk,
    timeout,
    [this] { return m_state->m_completed; }
  );
}

void BasicThread::ForceCoreThreadReidentify(void) {
  for(const auto& ctxt : ContextEnumerator(AutoGlobalContext())) {
    for(const auto& thread : ctxt->CopyBasicThreadList())
      thread->SetCurrentThreadName();
  }
}

void ForceCoreThreadReidentify(void) {
  BasicThread::ForceCoreThreadReidentify();
}
<commit_msg>wasStarted should be set from the lambda, not in a potentially overrideable virtual function<commit_after>// Copyright (C) 2012-2015 Leap Motion, Inc. All rights reserved.
#include "stdafx.h"
#include "BasicThread.h"
#include "Autowired.h"
#include "BasicThreadStateBlock.h"
#include "ContextEnumerator.h"
#include "fast_pointer_cast.h"
#include ATOMIC_HEADER

BasicThread::BasicThread(const char* pName):
  ContextMember(pName),
  m_state(std::make_shared<BasicThreadStateBlock>()),
  m_wasStarted(false),
  m_stop(false),
  m_running(false),
  m_priority(ThreadPriority::Default)
{}

BasicThread::~BasicThread(void){}

std::mutex& BasicThread::GetLock(void) {
  return m_state->m_lock;
}

void BasicThread::DoRun(std::shared_ptr<CoreObject>&& refTracker) {
  assert(m_running);

  // Make our own session current before we do anything else:
  CurrentContextPusher pusher(GetContext());

  // Set the thread name no matter what:
  if(GetName())
    SetCurrentThreadName();

  // Now we wait for the thread to be good to go:
  try {
    Run();
  }
  catch(dispatch_aborted_exception&) {
    // Okay, this is fine, a dispatcher is terminating--this is a normal way to
    // end a dispatcher loop.
  }
  catch(...) {
    try {
      // Ask that the enclosing context filter this exception, if possible:
      GetContext()->FilterException();
    }
    catch(...) {
      // Generic exception, unhandled, we can't do anything about this
    }

    // Signal shutdown on the enclosing context--cannot wait, if we wait we WILL deadlock
    GetContext()->SignalShutdown(false);
  }

  // Run loop is over, time to clean up
  DoRunLoopCleanup(pusher.Pop(), std::move(refTracker));
}

void BasicThread::DoRunLoopCleanup(std::shared_ptr<CoreContext>&& ctxt, std::shared_ptr<CoreObject>&& refTracker) {
  // Take a copy of our state condition shared pointer while we still hold a reference to
  // ourselves.  This is the only member out of our collection of members that we actually
  // need to hold a reference to.
  auto state = m_state;

  // Perform a manual notification of teardown listeners
  NotifyTeardownListeners();

  // Transition to stopped state.  Synchronization not required, transitions are all one-way
  m_stop = true;
  m_running = false;

  // Tell our CoreRunnable parent that we're done to ensure that our reference count will be cleared.
  Stop(false);

  // Release our hold on the context.  After this point, we have to be VERY CAREFUL that we
  // don't try to refer to any of our own member variables, because our own object may have
  // already gone out of scope.  [this] is potentially dangling.
  ctxt.reset();

  // Clear our reference tracker, which will notify anyone who is asleep and also maybe
  // will destroy the entire underlying context.
  refTracker.reset();

  // MUST detach here.  By this point in the application, it's possible that `this` has already been
  // deleted.  If that's the case, `state.unique()` is true, and when we go out of scope, the destructor
  // for m_thisThread will be invoked.  If that happens, the destructor will block for the held thread
  // to quit--and, in this case, the thread which is being held is actually us.  Blocking on it, in that
  // case, would be a trivial deadlock.  So, because we're about to quit anyway, we simply detach the
  // thread and prepare for final teardown operations.
  state->m_thisThread.detach();

  // Notify other threads that we are done.  At this point, any held references that might still exist
  // notification must happen from a synchronized level in order to ensure proper ordering.
  std::lock_guard<std::mutex> lk(state->m_lock);
  state->m_completed = true;
  state->m_stateCondition.notify_all();
}

void BasicThread::WaitForStateUpdate(const std::function<bool()>& fn) {
  std::unique_lock<std::mutex> lk(m_state->m_lock);
  m_state->m_stateCondition.wait(
    lk,
    [&fn, this] {
      return fn() || ShouldStop();
    }
  );
  if(ShouldStop())
    throw dispatch_aborted_exception();
}

void BasicThread::PerformStatusUpdate(const std::function<void()>& fn) {
  std::unique_lock<std::mutex> lk(m_state->m_lock);
  fn();
  m_state->m_stateCondition.notify_all();
}

bool BasicThread::ThreadSleep(std::chrono::nanoseconds timeout) {
  std::unique_lock<std::mutex> lk(m_state->m_lock);
  return m_state->m_stateCondition.wait_for(lk, timeout, [this] { return ShouldStop(); });
}

bool BasicThread::OnStart(void) {
  std::shared_ptr<CoreContext> context = m_context.lock();
  if(!context)
    return false;

  // Currently running and started:
  m_running = true;
  m_wasStarted = true;

  // Place the new thread entity directly in the space where it goes to avoid
  // any kind of races arising from asynchronous access to this space
  auto outstanding = GetOutstanding();
  m_state->m_thisThread.~thread();
  new (&m_state->m_thisThread) std::thread(
    [this, outstanding] () mutable {
      this->DoRun(std::move(outstanding));
    }
  );
  return true;
}

void BasicThread::OnStop(bool graceful) {
  // If we were never started, we need to set our completed flag to true
  if (!m_wasStarted)
    m_state->m_completed = true;

  // Always invoke stop handler:
  OnStop();
}

void BasicThread::DoAdditionalWait(void) {
  // Wait for the run loop cleanup to happen in DoRunLoopCleanup
  std::unique_lock<std::mutex> lk(m_state->m_lock);
  m_state->m_stateCondition.wait(
    lk,
    [this] { return m_state->m_completed; }
  );
}

bool BasicThread::DoAdditionalWait(std::chrono::nanoseconds timeout) {
  // Wait for the run loop cleanup to happen in DoRunLoopCleanup
  std::unique_lock<std::mutex> lk(m_state->m_lock);
  return m_state->m_stateCondition.wait_for(
    lk,
    timeout,
    [this] { return m_state->m_completed; }
  );
}

void BasicThread::ForceCoreThreadReidentify(void) {
  for(const auto& ctxt : ContextEnumerator(AutoGlobalContext())) {
    for(const auto& thread : ctxt->CopyBasicThreadList())
      thread->SetCurrentThreadName();
  }
}

void ForceCoreThreadReidentify(void) {
  BasicThread::ForceCoreThreadReidentify();
}
<|endoftext|>


<commit_before><commit_msg>Focus new editor windows<commit_after><|endoftext|>


<commit_before><commit_msg>Fix typo && thus Lua scripting bug.<commit_after><|endoftext|>


<commit_before>// Copyright (c) 2010-2021, Lawrence Livermore National Security, LLC. Produced
// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
// LICENSE and NOTICE for details. LLNL-CODE-443271.
//
// This file is part of the GLVis visualization tool and library. For more
// information and source code availability see https://glvis.org.
//
// GLVis is free software; you can redistribute it and/or modify it under the
// terms of the BSD-3 license. We welcome feedback and contributions, see file
// CONTRIBUTING.md for details.

#include "shader.hpp"
#include <regex>

#ifdef __EMSCRIPTEN__
// TODO: for webgl glsl the version ends in "es": #version GLSL_VER es
const std::string GLSL_HEADER = "precision mediump float;\n";
#else
const std::string GLSL_HEADER = "#version GLSL_VER\n";
#endif

namespace gl3
{

bool ShaderProgram::create(std::string vertexShader,
                           std::string fragmentShader,
                           std::unordered_map<int, std::string> inAttributes,
                           int numOutputs)
{
   attrib_idx = inAttributes;
   num_outputs = numOutputs;
   is_compiled = false;
   GetGLSLVersion();

   std::string fmtVS = formatShader(vertexShader, GL_VERTEX_SHADER);
   vertex_shader = compileShader(fmtVS, GL_VERTEX_SHADER);
   if (vertex_shader == 0)
   {
      return false;
   }

   std::string fmtFS = formatShader(fragmentShader, GL_FRAGMENT_SHADER);
   fragment_shader = compileShader(fmtFS, GL_FRAGMENT_SHADER);
   if (fragment_shader == 0)
   {
      return false;
   }

   if (!linkShaders({vertex_shader, fragment_shader}))
   {
      std::cerr << "Failed to link shaders for program." << std::endl;
      return false;
   }

   mapShaderUniforms();

   is_compiled = true;
   return is_compiled;
}

int ShaderProgram::glsl_version = -1;

void ShaderProgram::GetGLSLVersion()
{
   if (glsl_version == -1)
   {
      std::string verStr = (char*)glGetString(GL_VERSION);
      int ver_major, ver_minor;
      int vs_idx = verStr.find_first_of(".");
      ver_major = std::stoi(verStr.substr(vs_idx - 1, vs_idx));
      ver_minor = std::stoi(verStr.substr(vs_idx + 1, 1));
      int opengl_ver = ver_major * 100 + ver_minor * 10;

#ifndef __EMSCRIPTEN__
      // The GLSL version is the same as the OpenGL version when the OpenGL
      // version is >= 3.30, otherwise it is:
      //
      // GL Version | GLSL Version
      // -------------------------
      //    2.0     |   1.10
      //    2.1     |   1.20
      //    3.0     |   1.30
      //    3.1     |   1.40
      //    3.2     |   1.50

      if (opengl_ver < 330)
      {
         if (ver_major == 2)
         {
            glsl_version = opengl_ver - 90;
         }
         else if (ver_major == 3)
         {
            glsl_version = opengl_ver - 170;
         }
         else
         {
            std::cerr << "fatal: unsupported OpenGL version " << opengl_ver << std::endl;
            glsl_version = 100;
         }
      }
      else
      {
         glsl_version = opengl_ver;
      }
#else
      // GL Version | WebGL Version | GLSL Version
      //    2.0     |      1.0      |   1.00 ES
      //    3.0     |      2.0      |   3.00 ES
      //    3.1     |               |   3.10 ES
      if (opengl_ver < 300)
      {
         glsl_version = 100;
      }
      else
      {
         glsl_version = 300;
      }
#endif
      std::cerr << "Using GLSL " << glsl_version << std::endl;
   }
}

std::string ShaderProgram::formatShader(const std::string& inShader,
                                        GLenum shaderType)
{
   std::string formatted = inShader;

   // replace some identifiers depending on the version of glsl we're using
   if (glsl_version >= 130)
   {
      if (shaderType == GL_VERTEX_SHADER)
      {
         formatted = std::regex_replace(formatted, std::regex("attribute"), "in");
         formatted = std::regex_replace(formatted, std::regex("varying"), "out");
      }

      else if (shaderType == GL_FRAGMENT_SHADER)
      {
         formatted = std::regex_replace(formatted, std::regex("varying"), "in");

         // requires GL_ARB_explicit_attrib_location extension or GLSL 3.30
         // although gl_FragColor was deprecated in GLSL 1.3
         for (int i = 0; i < num_outputs; i++)
         {
            std::string indexString = "gl_FragData[";
            indexString += std::to_string(i) + "]";
            std::string outputString = "out vec4 fragColor_";
            outputString += std::to_string(i) + ";\n";
            if (glsl_version > 130 && glsl_version < 330)
            {

               formatted = outputString + formatted;
               formatted = std::regex_replace(formatted, std::regex(indexString),
                                              "fragColor");
            }
            else if (glsl_version >= 330)
            {
               std::string layoutString = "layout(location = ";
               layoutString += std::to_string(i) + ") ";
               formatted = layoutString + outputString + formatted;
            }
            if (i == 0)
            {
               formatted = std::regex_replace(formatted, std::regex("gl_FragColor"),
                                              "fragColor_0");
            }
         }
      }

      else
      {
         std::cerr << "buildShaderString: unknown shader type" << std::endl;
         return {};
      }

      formatted = std::regex_replace(formatted, std::regex("texture2D"), "texture");
   }

   if (GLDevice::useLegacyTextureFmts())
   {
      formatted = "#define USE_ALPHA\n" + formatted;
   }
   // add the header
   formatted = std::regex_replace(GLSL_HEADER, std::regex("GLSL_VER"),
                                  std::to_string(glsl_version)) + formatted;
#ifdef __EMSCRIPTEN__
   // special prepend for WebGL 2 shaders
   if (glsl_version == 300)
   {
      formatted = "#version 300 es\n" + formatted;
   }
#endif

   return formatted;
}

GLuint ShaderProgram::compileShader(const std::string& inShader,
                                    GLenum shaderType)
{
   int shader_len = inShader.length();
   const char *shader_cstr = inShader.c_str();

   GLuint shader = glCreateShader(shaderType);
   glShaderSource(shader, 1, &shader_cstr, &shader_len);
   glCompileShader(shader);

   GLint stat;
   glGetShaderiv(shader, GL_COMPILE_STATUS, &stat);
   // glGetObjectParameteriv
   if (stat == GL_FALSE)
   {
      std::cerr << "failed to compile shader" << std::endl;
      int err_len;
      glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &err_len);
      char *error_text = new char[err_len];
      glGetShaderInfoLog(shader, err_len, &err_len, error_text);
      std::cerr << error_text << std::endl;
      delete[] error_text;
      return 0;
   }
   return shader;
}

bool ShaderProgram::linkShaders(const std::vector<GLuint>& shaders)
{
   // Bind all incoming attributes to their VAO indices.
   for (auto attrib_pair : attrib_idx)
   {
      glBindAttribLocation(program_id, attrib_pair.first,
                           attrib_pair.second.c_str());
   }

   // Bind fragment output variables to MRT indices.
   for (int i = 0; i < num_outputs; i++)
   {
      std::string fragOutVar = "fragColor_" + std::to_string(i);
      glBindFragDataLocation(program_id, i, fragOutVar.c_str());
   }

   for (GLuint i : shaders)
   {
      glAttachShader(program_id, i);
   }
   glLinkProgram(program_id);

   GLint stat;
   glGetProgramiv(program_id, GL_LINK_STATUS, &stat);
   if (stat == GL_FALSE)
   {
      cerr << "fatal: Shader linking failed" << endl;
   }
   return (stat == GL_TRUE);
}

void ShaderProgram::mapShaderUniforms()
{
   int num_unifs;
   glGetProgramiv(program_id, GL_ACTIVE_UNIFORMS, &num_unifs);
   int max_unif_len;
   glGetProgramiv(program_id, GL_ACTIVE_UNIFORM_MAX_LENGTH, &max_unif_len);

   for (int i = 0; i < num_unifs; i++)
   {
      vector<char> unif_buf(max_unif_len+1);
      GLsizei name_length;
      GLint gl_size;
      GLenum gl_type;
      glGetActiveUniform(program_id, i, max_unif_len, &name_length, &gl_size,
                         &gl_type,
                         unif_buf.data());
      std::string unif_name(unif_buf.data(), name_length);
      GLuint location = glGetUniformLocation(program_id, unif_name.c_str());
      uniform_idx[unif_name] = location;
   }
}

}
<commit_msg>guard use of glBindFragDataLocation in emscripten<commit_after>// Copyright (c) 2010-2021, Lawrence Livermore National Security, LLC. Produced
// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
// LICENSE and NOTICE for details. LLNL-CODE-443271.
//
// This file is part of the GLVis visualization tool and library. For more
// information and source code availability see https://glvis.org.
//
// GLVis is free software; you can redistribute it and/or modify it under the
// terms of the BSD-3 license. We welcome feedback and contributions, see file
// CONTRIBUTING.md for details.

#include "shader.hpp"
#include <regex>

#ifdef __EMSCRIPTEN__
// TODO: for webgl glsl the version ends in "es": #version GLSL_VER es
const std::string GLSL_HEADER = "precision mediump float;\n";
#else
const std::string GLSL_HEADER = "#version GLSL_VER\n";
#endif

namespace gl3
{

bool ShaderProgram::create(std::string vertexShader,
                           std::string fragmentShader,
                           std::unordered_map<int, std::string> inAttributes,
                           int numOutputs)
{
   attrib_idx = inAttributes;
   num_outputs = numOutputs;
   is_compiled = false;
   GetGLSLVersion();

   std::string fmtVS = formatShader(vertexShader, GL_VERTEX_SHADER);
   vertex_shader = compileShader(fmtVS, GL_VERTEX_SHADER);
   if (vertex_shader == 0)
   {
      return false;
   }

   std::string fmtFS = formatShader(fragmentShader, GL_FRAGMENT_SHADER);
   fragment_shader = compileShader(fmtFS, GL_FRAGMENT_SHADER);
   if (fragment_shader == 0)
   {
      return false;
   }

   if (!linkShaders({vertex_shader, fragment_shader}))
   {
      std::cerr << "Failed to link shaders for program." << std::endl;
      return false;
   }

   mapShaderUniforms();

   is_compiled = true;
   return is_compiled;
}

int ShaderProgram::glsl_version = -1;

void ShaderProgram::GetGLSLVersion()
{
   if (glsl_version == -1)
   {
      std::string verStr = (char*)glGetString(GL_VERSION);
      int ver_major, ver_minor;
      int vs_idx = verStr.find_first_of(".");
      ver_major = std::stoi(verStr.substr(vs_idx - 1, vs_idx));
      ver_minor = std::stoi(verStr.substr(vs_idx + 1, 1));
      int opengl_ver = ver_major * 100 + ver_minor * 10;

#ifndef __EMSCRIPTEN__
      // The GLSL version is the same as the OpenGL version when the OpenGL
      // version is >= 3.30, otherwise it is:
      //
      // GL Version | GLSL Version
      // -------------------------
      //    2.0     |   1.10
      //    2.1     |   1.20
      //    3.0     |   1.30
      //    3.1     |   1.40
      //    3.2     |   1.50

      if (opengl_ver < 330)
      {
         if (ver_major == 2)
         {
            glsl_version = opengl_ver - 90;
         }
         else if (ver_major == 3)
         {
            glsl_version = opengl_ver - 170;
         }
         else
         {
            std::cerr << "fatal: unsupported OpenGL version " << opengl_ver << std::endl;
            glsl_version = 100;
         }
      }
      else
      {
         glsl_version = opengl_ver;
      }
#else
      // GL Version | WebGL Version | GLSL Version
      //    2.0     |      1.0      |   1.00 ES
      //    3.0     |      2.0      |   3.00 ES
      //    3.1     |               |   3.10 ES
      if (opengl_ver < 300)
      {
         glsl_version = 100;
      }
      else
      {
         glsl_version = 300;
      }
#endif
      std::cerr << "Using GLSL " << glsl_version << std::endl;
   }
}

std::string ShaderProgram::formatShader(const std::string& inShader,
                                        GLenum shaderType)
{
   std::string formatted = inShader;

   // replace some identifiers depending on the version of glsl we're using
   if (glsl_version >= 130)
   {
      if (shaderType == GL_VERTEX_SHADER)
      {
         formatted = std::regex_replace(formatted, std::regex("attribute"), "in");
         formatted = std::regex_replace(formatted, std::regex("varying"), "out");
      }

      else if (shaderType == GL_FRAGMENT_SHADER)
      {
         formatted = std::regex_replace(formatted, std::regex("varying"), "in");

         // requires GL_ARB_explicit_attrib_location extension or GLSL 3.30
         // although gl_FragColor was deprecated in GLSL 1.3
         for (int i = 0; i < num_outputs; i++)
         {
            std::string indexString = "gl_FragData[";
            indexString += std::to_string(i) + "]";
            std::string outputString = "out vec4 fragColor_";
            outputString += std::to_string(i) + ";\n";
            if (glsl_version > 130 && glsl_version < 330)
            {

               formatted = outputString + formatted;
               formatted = std::regex_replace(formatted, std::regex(indexString),
                                              "fragColor");
            }
            else if (glsl_version >= 330)
            {
               std::string layoutString = "layout(location = ";
               layoutString += std::to_string(i) + ") ";
               formatted = layoutString + outputString + formatted;
            }
            if (i == 0)
            {
               formatted = std::regex_replace(formatted, std::regex("gl_FragColor"),
                                              "fragColor_0");
            }
         }
      }

      else
      {
         std::cerr << "buildShaderString: unknown shader type" << std::endl;
         return {};
      }

      formatted = std::regex_replace(formatted, std::regex("texture2D"), "texture");
   }

   if (GLDevice::useLegacyTextureFmts())
   {
      formatted = "#define USE_ALPHA\n" + formatted;
   }
   // add the header
   formatted = std::regex_replace(GLSL_HEADER, std::regex("GLSL_VER"),
                                  std::to_string(glsl_version)) + formatted;
#ifdef __EMSCRIPTEN__
   // special prepend for WebGL 2 shaders
   if (glsl_version == 300)
   {
      formatted = "#version 300 es\n" + formatted;
   }
#endif

   return formatted;
}

GLuint ShaderProgram::compileShader(const std::string& inShader,
                                    GLenum shaderType)
{
   int shader_len = inShader.length();
   const char *shader_cstr = inShader.c_str();

   GLuint shader = glCreateShader(shaderType);
   glShaderSource(shader, 1, &shader_cstr, &shader_len);
   glCompileShader(shader);

   GLint stat;
   glGetShaderiv(shader, GL_COMPILE_STATUS, &stat);
   // glGetObjectParameteriv
   if (stat == GL_FALSE)
   {
      std::cerr << "failed to compile shader" << std::endl;
      int err_len;
      glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &err_len);
      char *error_text = new char[err_len];
      glGetShaderInfoLog(shader, err_len, &err_len, error_text);
      std::cerr << error_text << std::endl;
      delete[] error_text;
      return 0;
   }
   return shader;
}

bool ShaderProgram::linkShaders(const std::vector<GLuint>& shaders)
{
   // Bind all incoming attributes to their VAO indices.
   for (auto attrib_pair : attrib_idx)
   {
      glBindAttribLocation(program_id, attrib_pair.first,
                           attrib_pair.second.c_str());
   }

#ifndef __EMSCRIPTEN__
   // Bind fragment output variables to MRT indices.
   for (int i = 0; i < num_outputs; i++)
   {
      std::string fragOutVar = "fragColor_" + std::to_string(i);
      glBindFragDataLocation(program_id, i, fragOutVar.c_str());
   }
#endif

   for (GLuint i : shaders)
   {
      glAttachShader(program_id, i);
   }
   glLinkProgram(program_id);

   GLint stat;
   glGetProgramiv(program_id, GL_LINK_STATUS, &stat);
   if (stat == GL_FALSE)
   {
      cerr << "fatal: Shader linking failed" << endl;
   }
   return (stat == GL_TRUE);
}

void ShaderProgram::mapShaderUniforms()
{
   int num_unifs;
   glGetProgramiv(program_id, GL_ACTIVE_UNIFORMS, &num_unifs);
   int max_unif_len;
   glGetProgramiv(program_id, GL_ACTIVE_UNIFORM_MAX_LENGTH, &max_unif_len);

   for (int i = 0; i < num_unifs; i++)
   {
      vector<char> unif_buf(max_unif_len+1);
      GLsizei name_length;
      GLint gl_size;
      GLenum gl_type;
      glGetActiveUniform(program_id, i, max_unif_len, &name_length, &gl_size,
                         &gl_type,
                         unif_buf.data());
      std::string unif_name(unif_buf.data(), name_length);
      GLuint location = glGetUniformLocation(program_id, unif_name.c_str());
      uniform_idx[unif_name] = location;
   }
}

}
<|endoftext|>


<commit_before><commit_msg>	修改：     core/particle_smoother.hpp<commit_after><|endoftext|>


<commit_before>// License: Apache 2.0. See LICENSE file in root directory.
// Copyright(c) 2016 Intel Corporation. All Rights Reserved.

// Video Module Asynchronized Sample
// This sample demonstrates an application usage of a computer vision module, which implements asynchronous samples processing.
// The video module implements the video module interface, which is a common way for the application or SDK to interact with
// the module. It also implements a module specific interface, in this example - the module calculates the maximal depth value
// in the image.

#include <memory>
#include <vector>
#include <iostream>
#include <functional>
#include <map>
#include <unistd.h>
#include <librealsense/rs.hpp>

#include "rs_sdk.h"
#include "rs/cv_modules/max_depth_value_module/max_depth_value_module.h"

using namespace std;
using namespace rs::core;
using namespace rs::utils;
using namespace rs::cv_modules;

int main (int argc, char* argv[])
{
    // initialize the device from live device or playback file, based on command line parameters.
    std::unique_ptr<context_interface> ctx;

    if (argc > 1)
    {
        if (access(argv[1], F_OK) == -1)
        {
            cerr<<"error : playback file does not exists" << endl;
            return -1;
        }
        //use the playback file context
        ctx.reset(new rs::playback::context(argv[1]));
    }
    else
    {
        //use a real context
        ctx.reset(new context());
        if(ctx->get_device_count() == 0)
        {
            cerr<<"error : cant find devices" << endl;
            return -1;
        }
    }

    rs::device * device = ctx->get_device(0); //device memory managed by the context

    // initialize the module
    uint64_t milliseconds_added_to_simulate_larger_computation_time = 100;
    bool is_async_processing = true;
    std::unique_ptr<max_depth_value_module> module(new max_depth_value_module(milliseconds_added_to_simulate_larger_computation_time,
                                                                              is_async_processing));

    // get the first supported module configuration
    const auto device_name = device->get_name();
    video_module_interface::supported_module_config supported_config = {};
    for(auto i = 0;; i++)
    {
        if (module->query_supported_module_config(i, supported_config) < status_no_error)
        {
            cerr<<"error : failed to query supported module configuration for index : " << i <<endl;
            return -1;
        }

        auto is_current_device_valid = (std::strcmp(device_name, supported_config.device_name) == 0) ||
                                       (std::strcmp(supported_config.device_name, "") == 0);
        if (!is_current_device_valid)
        {
            //skip config due to miss-matching the current connected device
            continue;
        }

        assert(supported_config.async_processing == true && "the module config must support async processing");

        break;
    }

    //construct an actual model configuration to be set on the module
    video_module_interface::actual_module_config actual_config = {};
    std::memcpy(actual_config.device_info.name, supported_config.device_name, std::strlen(supported_config.device_name));
    rs::source active_sources = static_cast<rs::source>(0);

    //enable the camera streams from the selected module configuration
    vector<stream_type> actual_streams;
    vector<stream_type> possible_streams =  { stream_type::depth,
                                              stream_type::color,
                                              stream_type::infrared,
                                              stream_type::infrared2,
                                              stream_type::fisheye
                                            };
    for(auto &stream : possible_streams)
    {
        auto supported_stream_config = supported_config[stream];

        if (!supported_stream_config.is_enabled)
            continue;

        rs::stream librealsense_stream = convert_stream_type(stream);

        bool is_matching_stream_mode_found = false;
        auto stream_mode_count = device->get_stream_mode_count(librealsense_stream);
        for(int i = 0; i < stream_mode_count; i++)
        {
            int width, height, frame_rate;
            rs::format format;
            device->get_stream_mode(librealsense_stream, i, width, height, format, frame_rate);
            bool is_acceptable_stream_mode = (width == supported_stream_config.size.width &&
                                              height == supported_stream_config.size.height &&
                                              frame_rate == supported_stream_config.frame_rate);
            if(is_acceptable_stream_mode)
            {
                device->enable_stream(librealsense_stream, width, height, format, frame_rate);

                video_module_interface::actual_image_stream_config &actual_stream_config = actual_config[stream];
                actual_stream_config.size.width = width;
                actual_stream_config.size.height= height;
                actual_stream_config.frame_rate = static_cast<float>(frame_rate);
                actual_stream_config.intrinsics = convert_intrinsics(device->get_stream_intrinsics(librealsense_stream));
                actual_stream_config.extrinsics = convert_extrinsics(device->get_extrinsics(rs::stream::depth, librealsense_stream));
                if (device->supports(rs::capabilities::motion_events))
                {
                    try
                    {
                        actual_stream_config.extrinsics_motion = convert_extrinsics(device->get_motion_extrinsics_from(librealsense_stream));
                    }
                    catch(const std::exception& ex)
                    {
                        std::cout << "WARNING: cant get motion intrinsics from stream " << static_cast<int>(stream) << ", " << ex.what();
                    }

                }
                actual_stream_config.is_enabled = true;

                active_sources = rs::source::video;
                is_matching_stream_mode_found = true;
                break;
            }
        }

        if(is_matching_stream_mode_found)
        {
            actual_streams.push_back(stream);
        }
        else
        {
            cerr<<"error : didnt find matching stream configuration" << endl;
            return -1;
        }
    }

    //define callbacks to the actual streams and set them, the callback lifetime assumes the module is available.
    std::map<stream_type, std::function<void(rs::frame)>> stream_callback_per_stream;
    for(auto stream : actual_streams)
    {
        stream_callback_per_stream[stream] = [stream, &module](rs::frame frame)
        {
            correlated_sample_set sample_set = {};
            //the image is created with ref count 1 and must release it out of this scope.
            auto image = get_unique_ptr_with_releaser(image_interface::create_instance_from_librealsense_frame(frame, image_interface::flag::any));
            sample_set[stream] = image.get();
            //send asynced sample set to the module
            if(module->process_sample_set(sample_set) < status_no_error)
            {
                cerr<<"error : failed to process sample" << endl;
            }
        };

        device->set_frame_callback(convert_stream_type(stream), stream_callback_per_stream[stream]);
    }

    //define callback to the motion events and set it, the callback lifetime assumes the module is available.
    std::function<void(rs::motion_data)> motion_callback;
    std::function<void(rs::timestamp_data)> timestamp_callback;
    if (device->supports(rs::capabilities::motion_events))
    {
        vector<motion_type> actual_motions;
        auto motion_intrinsics = device->get_motion_intrinsics();
        auto motion_extrinsics_from_depth = device->get_motion_extrinsics_from(rs::stream::depth);
        for(auto motion_index = 0u; motion_index < static_cast<uint32_t>(motion_type::max); ++motion_index)
        {
            motion_type motion = static_cast<motion_type>(motion_index);
            auto supported_motion_config = supported_config[motion];

            if (!supported_motion_config.is_enabled)
                continue;

            video_module_interface::actual_motion_sensor_config &actual_motion_config = actual_config[motion];
            actual_motion_config.flags = sample_flags::none;
            actual_motion_config.sample_rate = 0; // not implemented by librealsense
            switch (motion) {
            case motion_type::accel:
                actual_motion_config.intrinsics = convert_motion_device_intrinsics(motion_intrinsics.acc);
                break;
            case motion_type::gyro:
                actual_motion_config.intrinsics = convert_motion_device_intrinsics(motion_intrinsics.gyro);
                break;
            default:
                throw std::runtime_error("unknown motion type, can't translate intrinsics");
            }
            actual_motion_config.extrinsics = convert_extrinsics(motion_extrinsics_from_depth);
            actual_motion_config.is_enabled = true;
            actual_motions.push_back(motion);
        }

        if(actual_motions.size()< 0)
        {
            //enable motion from the selected module configuration
            motion_callback = [actual_motions, &module](rs::motion_data entry)
            {
                correlated_sample_set sample_set = {};
                auto actual_motion = convert_motion_type(static_cast<rs::event>(entry.timestamp_data.source_id));
                sample_set[actual_motion].timestamp = entry.timestamp_data.timestamp;
                sample_set[actual_motion].type = actual_motion;
                sample_set[actual_motion].frame_number = entry.timestamp_data.frame_number;
                sample_set[actual_motion].data[0] = entry.axes[0];
                sample_set[actual_motion].data[1] = entry.axes[1];
                sample_set[actual_motion].data[2] = entry.axes[2];

                //send asynced sample set to the module
                if(module->process_sample_set(sample_set) < status_no_error)
                {
                    cerr<<"error : failed to process sample" << endl;
                }
            };

            timestamp_callback = [](rs::timestamp_data entry) { /* no operation */ };

            device->enable_motion_tracking(motion_callback, timestamp_callback);

            //set the camera to produce all streams timestamps from a single clock - the microcontroller's clock.
            //this option takes effect only if motion tracking is enabled and device->start() is called with rs::source::all_sources argument.
            device->set_option(rs::option::fisheye_strobe, 1);

            if(active_sources == rs::source::video)
            {
                active_sources = rs::source::all_sources;
            }
            else // none sources
            {
                active_sources = rs::source::motion_data;
            }
        }
    }

    //setting the projection object
    rs::utils::unique_ptr<rs::core::projection_interface> projection;
    if(device->is_stream_enabled(rs::stream::color) && device->is_stream_enabled(rs::stream::depth))
    {
        intrinsics color_intrin = convert_intrinsics(device->get_stream_intrinsics(rs::stream::color));
        intrinsics depth_intrin = convert_intrinsics(device->get_stream_intrinsics(rs::stream::depth));
        extrinsics extrin = convert_extrinsics(device->get_extrinsics(rs::stream::depth, rs::stream::color));
        projection.reset(rs::core::projection_interface::create_instance(&color_intrin, &depth_intrin, &extrin));
        actual_config.projection = projection.get();
    }

    // setting the enabled module configuration
    if(module->set_module_config(actual_config) < status_no_error)
    {
        cerr<<"error : failed to set the enabled module configuration" << endl;
        return -1;
    }

    device->start(active_sources);

    auto start = std::chrono::system_clock::now();
    while(std::chrono::system_clock::now() - start < std::chrono::seconds(3))
    {
        auto output_data = module->get_max_depth_value_data();
        cout<<"got module max depth value : "<< output_data.max_depth_value << ", for frame number : " << output_data.frame_number << endl;
    }

    if(module->flush_resources() < status_no_error)
    {
        cerr<<"error : failed to flush the module resources" << endl;
        return -1;
    }

    device->stop(active_sources);
    return 0;
}
<commit_msg>fixed video module async sample crush due to missing instinsics values, bug : 510685<commit_after>// License: Apache 2.0. See LICENSE file in root directory.
// Copyright(c) 2016 Intel Corporation. All Rights Reserved.

// Video Module Asynchronized Sample
// This sample demonstrates an application usage of a computer vision module, which implements asynchronous samples processing.
// The video module implements the video module interface, which is a common way for the application or SDK to interact with
// the module. It also implements a module specific interface, in this example - the module calculates the maximal depth value
// in the image.

#include <memory>
#include <vector>
#include <iostream>
#include <functional>
#include <map>
#include <unistd.h>
#include <librealsense/rs.hpp>

#include "rs_sdk.h"
#include "rs/cv_modules/max_depth_value_module/max_depth_value_module.h"

using namespace std;
using namespace rs::core;
using namespace rs::utils;
using namespace rs::cv_modules;

int main (int argc, char* argv[])
{
    // initialize the device from live device or playback file, based on command line parameters.
    std::unique_ptr<context_interface> ctx;

    if (argc > 1)
    {
        if (access(argv[1], F_OK) == -1)
        {
            cerr<<"error : playback file does not exists" << endl;
            return -1;
        }
        //use the playback file context
        ctx.reset(new rs::playback::context(argv[1]));
    }
    else
    {
        //use a real context
        ctx.reset(new context());
        if(ctx->get_device_count() == 0)
        {
            cerr<<"error : cant find devices" << endl;
            return -1;
        }
    }

    rs::device * device = ctx->get_device(0); //device memory managed by the context

    // initialize the module
    uint64_t milliseconds_added_to_simulate_larger_computation_time = 100;
    bool is_async_processing = true;
    std::unique_ptr<max_depth_value_module> module(new max_depth_value_module(milliseconds_added_to_simulate_larger_computation_time,
                                                                              is_async_processing));

    // get the first supported module configuration
    const auto device_name = device->get_name();
    video_module_interface::supported_module_config supported_config = {};
    for(auto i = 0;; i++)
    {
        if (module->query_supported_module_config(i, supported_config) < status_no_error)
        {
            cerr<<"error : failed to query supported module configuration for index : " << i <<endl;
            return -1;
        }

        auto is_current_device_valid = (std::strcmp(device_name, supported_config.device_name) == 0) ||
                                       (std::strcmp(supported_config.device_name, "") == 0);
        if (!is_current_device_valid)
        {
            //skip config due to miss-matching the current connected device
            continue;
        }

        assert(supported_config.async_processing == true && "the module config must support async processing");

        break;
    }

    //construct an actual model configuration to be set on the module
    video_module_interface::actual_module_config actual_config = {};
    std::memcpy(actual_config.device_info.name, supported_config.device_name, std::strlen(supported_config.device_name));
    rs::source active_sources = static_cast<rs::source>(0);

    //check if the motion event is required
    bool is_motion_event_required_by_config = false;
    for(auto motion_index = 0u; motion_index < static_cast<uint32_t>(motion_type::max); ++motion_index)
    {
        if(supported_config.motion_sensors_configs[motion_index].is_enabled)
        {
            is_motion_event_required_by_config = true;
            if(!device->supports(rs::capabilities::motion_events))
            {
                cerr<<"motion event is required by the configuration but the device does not support it"<<endl;
                return -1;
            }
            break;
        }
    }

    //enable the camera streams from the selected module configuration
    vector<stream_type> actual_streams;
    vector<stream_type> possible_streams =  { stream_type::depth,
                                              stream_type::color,
                                              stream_type::infrared,
                                              stream_type::infrared2,
                                              stream_type::fisheye
                                            };
    for(auto &stream : possible_streams)
    {
        auto supported_stream_config = supported_config[stream];

        if (!supported_stream_config.is_enabled)
            continue;

        rs::stream librealsense_stream = convert_stream_type(stream);

        bool is_matching_stream_mode_found = false;
        auto stream_mode_count = device->get_stream_mode_count(librealsense_stream);
        for(int i = 0; i < stream_mode_count; i++)
        {
            int width, height, frame_rate;
            rs::format format;
            device->get_stream_mode(librealsense_stream, i, width, height, format, frame_rate);
            bool is_acceptable_stream_mode = (width == supported_stream_config.size.width &&
                                              height == supported_stream_config.size.height &&
                                              frame_rate == supported_stream_config.frame_rate);
            if(is_acceptable_stream_mode)
            {
                device->enable_stream(librealsense_stream, width, height, format, frame_rate);

                video_module_interface::actual_image_stream_config &actual_stream_config = actual_config[stream];
                actual_stream_config.size.width = width;
                actual_stream_config.size.height= height;
                actual_stream_config.frame_rate = static_cast<float>(frame_rate);
                actual_stream_config.intrinsics = convert_intrinsics(device->get_stream_intrinsics(librealsense_stream));
                actual_stream_config.extrinsics = convert_extrinsics(device->get_extrinsics(rs::stream::depth, librealsense_stream));
                if (is_motion_event_required_by_config)
                {
                    try
                    {
                        actual_stream_config.extrinsics_motion = convert_extrinsics(device->get_motion_extrinsics_from(librealsense_stream));
                    }
                    catch(const std::exception& ex)
                    {
                        std::cerr << "WARNING : cant get motion intrinsics from stream " << static_cast<int>(stream) << ", " << ex.what() << endl;
                    }

                }
                actual_stream_config.is_enabled = true;

                active_sources = rs::source::video;
                is_matching_stream_mode_found = true;
                break;
            }
        }

        if(is_matching_stream_mode_found)
        {
            actual_streams.push_back(stream);
        }
        else
        {
            cerr<<"error : didnt find matching stream configuration" << endl;
            return -1;
        }
    }

    //define callbacks to the actual streams and set them, the callback lifetime assumes the module is available.
    std::map<stream_type, std::function<void(rs::frame)>> stream_callback_per_stream;
    for(auto stream : actual_streams)
    {
        stream_callback_per_stream[stream] = [stream, &module](rs::frame frame)
        {
            correlated_sample_set sample_set = {};
            //the image is created with ref count 1 and must release it out of this scope.
            auto image = get_unique_ptr_with_releaser(image_interface::create_instance_from_librealsense_frame(frame, image_interface::flag::any));
            sample_set[stream] = image.get();
            //send asynced sample set to the module
            if(module->process_sample_set(sample_set) < status_no_error)
            {
                cerr<<"error : failed to process sample" << endl;
            }
        };

        device->set_frame_callback(convert_stream_type(stream), stream_callback_per_stream[stream]);
    }

    //define callback to the motion events and set it, the callback lifetime assumes the module is available.
    std::function<void(rs::motion_data)> motion_callback;
    std::function<void(rs::timestamp_data)> timestamp_callback;
    if (is_motion_event_required_by_config)
    {
        vector<motion_type> actual_motions;
        rs::motion_intrinsics motion_intrinsics = {};
        try
        {
            motion_intrinsics = device->get_motion_intrinsics();
        }
        catch(const std::runtime_error & ex)
        {
            cerr<<"WARNING : failed to get motion intrinsics : "<< ex.what()<<endl;
        }

        rs::extrinsics motion_extrinsics_from_depth = {};
        try
        {
            motion_extrinsics_from_depth = device->get_motion_extrinsics_from(rs::stream::depth);
        }
        catch(const std::runtime_error & ex)
        {
            cerr<<"WARNING : failed to get motion extrinsics : "<< ex.what()<<endl;
        }

        for(auto motion_index = 0u; motion_index < static_cast<uint32_t>(motion_type::max); ++motion_index)
        {
            motion_type motion = static_cast<motion_type>(motion_index);
            auto supported_motion_config = supported_config[motion];

            if (!supported_motion_config.is_enabled)
                continue;

            video_module_interface::actual_motion_sensor_config &actual_motion_config = actual_config[motion];
            actual_motion_config.flags = sample_flags::none;
            actual_motion_config.sample_rate = 0; // not implemented by librealsense
            switch (motion) {
            case motion_type::accel:
                actual_motion_config.intrinsics = convert_motion_device_intrinsics(motion_intrinsics.acc);
                break;
            case motion_type::gyro:
                actual_motion_config.intrinsics = convert_motion_device_intrinsics(motion_intrinsics.gyro);
                break;
            default:
                throw std::runtime_error("unknown motion type, can't translate intrinsics");
            }
            actual_motion_config.extrinsics = convert_extrinsics(motion_extrinsics_from_depth);
            actual_motion_config.is_enabled = true;
            actual_motions.push_back(motion);
        }

        if(actual_motions.size()< 0)
        {
            //enable motion from the selected module configuration
            motion_callback = [actual_motions, &module](rs::motion_data entry)
            {
                correlated_sample_set sample_set = {};
                auto actual_motion = convert_motion_type(static_cast<rs::event>(entry.timestamp_data.source_id));
                sample_set[actual_motion].timestamp = entry.timestamp_data.timestamp;
                sample_set[actual_motion].type = actual_motion;
                sample_set[actual_motion].frame_number = entry.timestamp_data.frame_number;
                sample_set[actual_motion].data[0] = entry.axes[0];
                sample_set[actual_motion].data[1] = entry.axes[1];
                sample_set[actual_motion].data[2] = entry.axes[2];

                //send asynced sample set to the module
                if(module->process_sample_set(sample_set) < status_no_error)
                {
                    cerr<<"error : failed to process sample" << endl;
                }
            };

            timestamp_callback = [](rs::timestamp_data entry) { /* no operation */ };

            device->enable_motion_tracking(motion_callback, timestamp_callback);

            //set the camera to produce all streams timestamps from a single clock - the microcontroller's clock.
            //this option takes effect only if motion tracking is enabled and device->start() is called with rs::source::all_sources argument.
            device->set_option(rs::option::fisheye_strobe, 1);

            if(active_sources == rs::source::video)
            {
                active_sources = rs::source::all_sources;
            }
            else // none sources
            {
                active_sources = rs::source::motion_data;
            }
        }
    }

    //setting the projection object
    rs::utils::unique_ptr<rs::core::projection_interface> projection;
    if(device->is_stream_enabled(rs::stream::color) && device->is_stream_enabled(rs::stream::depth))
    {
        intrinsics color_intrin = convert_intrinsics(device->get_stream_intrinsics(rs::stream::color));
        intrinsics depth_intrin = convert_intrinsics(device->get_stream_intrinsics(rs::stream::depth));
        extrinsics extrin = convert_extrinsics(device->get_extrinsics(rs::stream::depth, rs::stream::color));
        projection.reset(rs::core::projection_interface::create_instance(&color_intrin, &depth_intrin, &extrin));
        actual_config.projection = projection.get();
    }

    // setting the enabled module configuration
    if(module->set_module_config(actual_config) < status_no_error)
    {
        cerr<<"error : failed to set the enabled module configuration" << endl;
        return -1;
    }

    device->start(active_sources);

    auto start = std::chrono::system_clock::now();
    while(std::chrono::system_clock::now() - start < std::chrono::seconds(3))
    {
        auto output_data = module->get_max_depth_value_data();
        cout<<"got module max depth value : "<< output_data.max_depth_value << ", for frame number : " << output_data.frame_number << endl;
    }

    if(module->flush_resources() < status_no_error)
    {
        cerr<<"error : failed to flush the module resources" << endl;
        return -1;
    }

    device->stop(active_sources);
    return 0;
}
<|endoftext|>


<commit_before>#include "samson/stream/WorkerSystemTask.h"                       // Own interface

#include <list>

#include "engine/Engine.h"
#include "engine/Notification.h"
#include "samson/common/MessagesOperations.h"
#include "samson/common/NotificationMessages.h"
#include "samson/network/Packet.h"                  // network::Packet
#include "samson/stream/Block.h"                                  // samson::stream::Block
#include "samson/stream/BlockList.h"                              // samson::stream::BlockList
#include "samson/stream/BlockManager.h"
#include "samson/worker/SamsonWorker.h"

namespace samson {
namespace stream {

// ------------------------------------------------------------------------
//
// BlockRequestTask
//
// ------------------------------------------------------------------------

BlockDistributionTask::BlockDistributionTask(SamsonWorker *samson_worker, size_t id, size_t block_id,
                                             const std::vector<size_t>& worker_ids) :
      WorkerTaskBase(samson_worker, id,
                     au::str("BlockDistribution %lu to workers %s", block_id, au::str(worker_ids).c_str())) {
  block_id_ = block_id;
  worker_ids_ = worker_ids;

  // Selected block
  block_ = stream::BlockManager::shared()->GetBlock(block_id);

  if (block_ == NULL) {
    LM_W(("DistributeBlockTask for unknown block %lu", block_id));
  }
  AddInput(0, block_, block_->getKVRange(), block_->getKVInfo());

  std::string message = au::str("<< Block distribution %lu to workers %s >>", block_id, au::str(worker_ids_).c_str());
  environment().Set("worker_command_id", message);
}

// Virtual method from engine::ProcessItem
void BlockDistributionTask::run() {
  if (block_ == NULL) {
    return;   // Nothing to distribute
  }
  // Block is suppouse to be on memory since this is a task
  if (!block_->is_content_in_memory()) {
    LM_X(1, ("Internal error"));
  }

  // Send a packet to all selected workers
  for (size_t i = 0; i < worker_ids_.size(); i++) {
    PacketPointer packet(new Packet(Message::BlockDistribution));
    packet->set_buffer(block_->buffer());
    packet->message->set_block_id(block_id_);
    packet->to = NodeIdentifier(WorkerNode, worker_ids_[i]);

    // Sending a engine notification to really sent this packet
    engine::Notification *notification = new engine::Notification(notification_send_packet);
    notification->dictionary().Set<Packet> ("packet", packet);
    engine::Engine::shared()->notify(notification);
  }
}

// ------------------------------------------------------------------------
//
// PopBlockRequestTask
//
// ------------------------------------------------------------------------

PopBlockRequestTask::PopBlockRequestTask(SamsonWorker *samson_worker
                                         , size_t id
                                         , size_t block_id
                                         , size_t delilah_id
                                         , size_t delilah_component_id
                                         , size_t pop_id) :
  WorkerTaskBase(samson_worker, id, au::str("BlockPopRequest %lu [ delilah %lu ]", block_id, delilah_id)) {
  block_id_ = block_id;
  delilah_id_ = delilah_id;
  delilah_component_id_ = delilah_component_id;
  pop_id_ = pop_id;

  // Selected block
  block_ = stream::BlockManager::shared()->GetBlock(block_id);

  // add this block as input to make sure it is in memory when task is executed
  AddInput(0, block_, block_->getKVRange(), block_->getKVInfo());
}

// Virtual method from engine::ProcessItem
void PopBlockRequestTask::run() {

  if (!block_->is_content_in_memory()) {
    LM_X(1, ("Internal error"));   // Get kv file for this block
  }

  // Send a packet to delilah with contents of this buffer
  PacketPointer packet(new Packet(Message::PopBlockRequestResponse));

  packet->to = NodeIdentifier(DelilahNode, delilah_id_);
  packet->message->set_block_id(block_id_);
  packet->message->set_delilah_component_id(delilah_component_id_);
  packet->message->set_pop_id(pop_id_);
  packet->set_buffer( block_->buffer() );

  // Sending a engine notification to really sent this packet
  engine::Notification *notification = new engine::Notification(notification_send_packet);
  notification->dictionary().Set<Packet> ("packet", packet);
  engine::Engine::shared()->notify(notification);

}

void DefragTask::AddOutputBuffer(engine::BufferPointer buffer) {
  // Information for generated block
  KVHeader *header = reinterpret_cast<KVHeader *>(buffer->data());

  // Create a block ( and distribute it )
  size_t block_id = samson_worker_->worker_block_manager()->CreateBlock(buffer);
  BlockPointer block = BlockManager::shared()->GetBlock(block_id);

  // Add output to this operation
  AddOutput(0, block, header->range, header->info);
}

void DefragTask::run() {

  // Review input blocks
  BlockList *list = block_list_container_.getBlockList("input_0");
  list->ReviewBlockReferences(error_);

  if (error_.IsActivated()) {
    AU_LM_W((">>>> Error in defrag operation: %s" , error_.GetMessage().c_str() ));
    return;
  }

  // Get vector with all KVFiles at the input
  // ------------------------------------------------------------------------------
  std::vector<au::SharedPointer<KVFile> > kv_files;
  au::list<BlockRef>::iterator bi;
  for (bi = list->blocks.begin(); bi != list->blocks.end(); bi++) {
    BlockRef *block_ref = *bi;
    BlockPointer block = block_ref->block();
    engine::BufferPointer buffer = block->buffer();

    if (buffer == NULL) {
      error_.set(au::str("Block %lu is apparently not in memory", block_ref->block_id()));
      return;
    }

    // Check header for valid block
    KVHeader *header = reinterpret_cast<KVHeader *>(buffer->data());
    if (!header->check()) {
      error_.set("Not valid header in block reference");
      return;
    }

    // Analyse all key-values and hashgroups
    au::SharedPointer<KVFile> file = block_ref->file();

    if (file == NULL) {
      error_.set(au::str("Error getting KVFile for block %lu", block_ref->block_id()));
      return;
    }

    kv_files.push_back(file);
  }

  if (kv_files.size() == 0) {
    error_.set("No data provided for defrag operation");
    return;
  }

  // Generate output buffers putting toguether all data for each hash-group
  // ------------------------------------------------------------------------------

  KVHeader header = kv_files[0]->header();

  for ( size_t r = 0 ; r < ranges_.size() ; r++ )
  {

    // Generate block ( if any data is present for this range )
    KVRange range = ranges_[r];

    // Compute info for this range
    KVInfo info;
    for ( int hg = range.hg_begin ; hg < range.hg_end ; hg++ )
      for ( int i = 0 ; i < kv_files.size() ; i++ )
        info.append( kv_files[i]->info[hg] );

    if ( info.size == 0 )
      continue;

    // Create output buffer ( hg_begin hg_end )
    size_t buffer_size = sizeof(KVHeader) + info.size;
    engine::BufferPointer buffer = engine::Buffer::Create("defrag", "normal", buffer_size);
    buffer->set_size(buffer_size);

    // Copy header and modify info
    KVHeader* buffer_header = reinterpret_cast<KVHeader*>(buffer->data());
    memcpy(buffer_header, &header, sizeof(KVHeader));
    buffer_header->info = info;
    buffer_header->range = range; // Set this range ( it could be better adjusted )

    // Copy data
    char* buffer_data = buffer->data();
    size_t offset = sizeof(KVHeader);
    for (int hg = range.hg_begin; hg < range.hg_end; hg++)
      for (size_t i = 0; i < kv_files.size(); i++) {
        size_t size = kv_files[i]->info[hg].size;
        if (size > 0) {
          char* data = kv_files[i]->data_for_hg(hg);
          memcpy(buffer_data + offset, data, size);
          offset += size;
        }
      }

    if (offset != buffer_size) {
      error_.set("Internal error in defrag operation");
      return;
    }

    // add generated buffer to the output
    AddOutputBuffer(buffer);

  }

}

std::string DefragTask::commit_command() {
  std::vector<std::string> inputs;
  std::vector<std::string> outputs;
  inputs.push_back(queue_name_);
  outputs.push_back(queue_name_);
  return generate_commit_command(inputs, outputs);
}
}
}

<commit_msg>Minor bug to compile in linux<commit_after>#include "samson/stream/WorkerSystemTask.h"                       // Own interface

#include <list>

#include "engine/Engine.h"
#include "engine/Notification.h"
#include "samson/common/MessagesOperations.h"
#include "samson/common/NotificationMessages.h"
#include "samson/network/Packet.h"                  // network::Packet
#include "samson/stream/Block.h"                                  // samson::stream::Block
#include "samson/stream/BlockList.h"                              // samson::stream::BlockList
#include "samson/stream/BlockManager.h"
#include "samson/worker/SamsonWorker.h"

namespace samson {
namespace stream {

// ------------------------------------------------------------------------
//
// BlockRequestTask
//
// ------------------------------------------------------------------------

BlockDistributionTask::BlockDistributionTask(SamsonWorker *samson_worker, size_t id, size_t block_id,
                                             const std::vector<size_t>& worker_ids) :
      WorkerTaskBase(samson_worker, id,
                     au::str("BlockDistribution %lu to workers %s", block_id, au::str(worker_ids).c_str())) {
  block_id_ = block_id;
  worker_ids_ = worker_ids;

  // Selected block
  block_ = stream::BlockManager::shared()->GetBlock(block_id);

  if (block_ == NULL) {
    LM_W(("DistributeBlockTask for unknown block %lu", block_id));
  }
  AddInput(0, block_, block_->getKVRange(), block_->getKVInfo());

  std::string message = au::str("<< Block distribution %lu to workers %s >>", block_id, au::str(worker_ids_).c_str());
  environment().Set("worker_command_id", message);
}

// Virtual method from engine::ProcessItem
void BlockDistributionTask::run() {
  if (block_ == NULL) {
    return;   // Nothing to distribute
  }
  // Block is suppouse to be on memory since this is a task
  if (!block_->is_content_in_memory()) {
    LM_X(1, ("Internal error"));
  }

  // Send a packet to all selected workers
  for (size_t i = 0; i < worker_ids_.size(); i++) {
    PacketPointer packet(new Packet(Message::BlockDistribution));
    packet->set_buffer(block_->buffer());
    packet->message->set_block_id(block_id_);
    packet->to = NodeIdentifier(WorkerNode, worker_ids_[i]);

    // Sending a engine notification to really sent this packet
    engine::Notification *notification = new engine::Notification(notification_send_packet);
    notification->dictionary().Set<Packet> ("packet", packet);
    engine::Engine::shared()->notify(notification);
  }
}

// ------------------------------------------------------------------------
//
// PopBlockRequestTask
//
// ------------------------------------------------------------------------

PopBlockRequestTask::PopBlockRequestTask(SamsonWorker *samson_worker
                                         , size_t id
                                         , size_t block_id
                                         , size_t delilah_id
                                         , size_t delilah_component_id
                                         , size_t pop_id) :
  WorkerTaskBase(samson_worker, id, au::str("BlockPopRequest %lu [ delilah %lu ]", block_id, delilah_id)) {
  block_id_ = block_id;
  delilah_id_ = delilah_id;
  delilah_component_id_ = delilah_component_id;
  pop_id_ = pop_id;

  // Selected block
  block_ = stream::BlockManager::shared()->GetBlock(block_id);

  // add this block as input to make sure it is in memory when task is executed
  AddInput(0, block_, block_->getKVRange(), block_->getKVInfo());
}

// Virtual method from engine::ProcessItem
void PopBlockRequestTask::run() {

  if (!block_->is_content_in_memory()) {
    LM_X(1, ("Internal error"));   // Get kv file for this block
  }

  // Send a packet to delilah with contents of this buffer
  PacketPointer packet(new Packet(Message::PopBlockRequestResponse));

  packet->to = NodeIdentifier(DelilahNode, delilah_id_);
  packet->message->set_block_id(block_id_);
  packet->message->set_delilah_component_id(delilah_component_id_);
  packet->message->set_pop_id(pop_id_);
  packet->set_buffer( block_->buffer() );

  // Sending a engine notification to really sent this packet
  engine::Notification *notification = new engine::Notification(notification_send_packet);
  notification->dictionary().Set<Packet> ("packet", packet);
  engine::Engine::shared()->notify(notification);

}

void DefragTask::AddOutputBuffer(engine::BufferPointer buffer) {
  // Information for generated block
  KVHeader *header = reinterpret_cast<KVHeader *>(buffer->data());

  // Create a block ( and distribute it )
  size_t block_id = samson_worker_->worker_block_manager()->CreateBlock(buffer);
  BlockPointer block = BlockManager::shared()->GetBlock(block_id);

  // Add output to this operation
  AddOutput(0, block, header->range, header->info);
}

void DefragTask::run() {

  // Review input blocks
  BlockList *list = block_list_container_.getBlockList("input_0");
  list->ReviewBlockReferences(error_);

  if (error_.IsActivated()) {
    AU_LM_W((">>>> Error in defrag operation: %s" , error_.GetMessage().c_str() ));
    return;
  }

  // Get vector with all KVFiles at the input
  // ------------------------------------------------------------------------------
  std::vector<au::SharedPointer<KVFile> > kv_files;
  au::list<BlockRef>::iterator bi;
  for (bi = list->blocks.begin(); bi != list->blocks.end(); bi++) {
    BlockRef *block_ref = *bi;
    BlockPointer block = block_ref->block();
    engine::BufferPointer buffer = block->buffer();

    if (buffer == NULL) {
      error_.set(au::str("Block %lu is apparently not in memory", block_ref->block_id()));
      return;
    }

    // Check header for valid block
    KVHeader *header = reinterpret_cast<KVHeader *>(buffer->data());
    if (!header->check()) {
      error_.set("Not valid header in block reference");
      return;
    }

    // Analyse all key-values and hashgroups
    au::SharedPointer<KVFile> file = block_ref->file();

    if (file == NULL) {
      error_.set(au::str("Error getting KVFile for block %lu", block_ref->block_id()));
      return;
    }

    kv_files.push_back(file);
  }

  if (kv_files.size() == 0) {
    error_.set("No data provided for defrag operation");
    return;
  }

  // Generate output buffers putting toguether all data for each hash-group
  // ------------------------------------------------------------------------------

  KVHeader header = kv_files[0]->header();

  for ( size_t r = 0 ; r < ranges_.size() ; r++ )
  {

    // Generate block ( if any data is present for this range )
    KVRange range = ranges_[r];

    // Compute info for this range
    KVInfo info;
    for ( int hg = range.hg_begin ; hg < range.hg_end ; hg++ )
      for ( int i = 0 ; i < (int)kv_files.size() ; i++ )
        info.append( kv_files[i]->info[hg] );

    if ( info.size == 0 )
      continue;

    // Create output buffer ( hg_begin hg_end )
    size_t buffer_size = sizeof(KVHeader) + info.size;
    engine::BufferPointer buffer = engine::Buffer::Create("defrag", "normal", buffer_size);
    buffer->set_size(buffer_size);

    // Copy header and modify info
    KVHeader* buffer_header = reinterpret_cast<KVHeader*>(buffer->data());
    memcpy(buffer_header, &header, sizeof(KVHeader));
    buffer_header->info = info;
    buffer_header->range = range; // Set this range ( it could be better adjusted )

    // Copy data
    char* buffer_data = buffer->data();
    size_t offset = sizeof(KVHeader);
    for (int hg = range.hg_begin; hg < range.hg_end; hg++)
      for (size_t i = 0; i < kv_files.size(); i++) {
        size_t size = kv_files[i]->info[hg].size;
        if (size > 0) {
          char* data = kv_files[i]->data_for_hg(hg);
          memcpy(buffer_data + offset, data, size);
          offset += size;
        }
      }

    if (offset != buffer_size) {
      error_.set("Internal error in defrag operation");
      return;
    }

    // add generated buffer to the output
    AddOutputBuffer(buffer);

  }

}

std::string DefragTask::commit_command() {
  std::vector<std::string> inputs;
  std::vector<std::string> outputs;
  inputs.push_back(queue_name_);
  outputs.push_back(queue_name_);
  return generate_commit_command(inputs, outputs);
}
}
}

<|endoftext|>


<commit_before><commit_msg>Undo last change.<commit_after><|endoftext|>


<commit_before>#include "baciROpattern.h"
#include "baciAlarmSystemMonitorPattern.h"
#include "baciAlarmSystemMonitor_T.i"
#include "baciAlarmSystemMonitorDisc_T.i"

namespace baci
{

AlarmSystemMonitorPattern::AlarmSystemMonitorPattern(ROpatternImpl* property,EventDispatcher * eventDispatcher)
	: AlarmSystemMonitorDisc<ACS::pattern, ROpatternImpl>(property, eventDispatcher),
	patternSize_m(sizeof(ACS::pattern)*8)
{
	// setting lastValue to NOT of alarm_trigger will trigger alarms at the first check
	lastValue_m = ~(property_mp->alarm_trigger());
}//AlarmSystemMonitorPattern

AlarmSystemMonitorPattern::~AlarmSystemMonitorPattern()
{
}//~AlarmSystemMonitorPattern

void AlarmSystemMonitorPattern::check(BACIValue &val,
								const ACSErr::Completion & c,
								const ACS::CBDescOut & desc
    )
{
    ACE_UNUSED_ARG(c);

    ACS::pattern value = val.getValue(static_cast<ACS::pattern*>(0)); //val.patternValue();

    // first we just check if the value has been changed since last time
    if (value!=lastValue_m)
    {
    	// here we read the values every time! This can be done just once in ctor, but what if values in CDB change
    	alarmMask_m = property_mp->alarm_mask();
    	alarmTrigger_m = property_mp->alarm_trigger();
    	bitDescriptions_mp = property_mp->bitDescription();

    	ACS::pattern tmpVal = value; //tmp storage of the value
    	for(bitPos_m=0; bitPos_m<patternSize_m; bitPos_m++)
    	{
    		//we check if the bit at position bitPos has been changed
    		if ((alarmMask_m & (value ^ lastValue_m ) & 1) )
    		{
    			setProperty("BACI_BitPosition", bitPos_m);
    			const char *bitDesc;
    			if (bitPos_m<bitDescriptions_mp->length())
    			{
    			   bitDesc = (*bitDescriptions_mp)[bitPos_m];
    			}
    			else
    			{
    				bitDesc = "w/o description";
    			}
    			setProperty("BACI_BitDescription", bitDesc);
    			setProperty("BACI_Value", value);

    			// how the bit has changed (we could merge this with if above but would	 not be cleared then)
    			if ( ~(value ^ alarmTrigger_m) & 1 )
    			{
    				ACS_SHORT_LOG((LM_ALERT, "Alarm for property: %s, bit %d (%s) raised. Value change to: %d", property_mp->name(), bitPos_m, bitDesc, value));
    				this->sendAlarm(1, true);
      			}
    			else
    			{
    				ACS_SHORT_LOG((LM_ALERT, "Alarm for property: %s, bit %d (%s) cleared. Value change to: %d", property_mp->name(), bitPos_m, bitDesc, value));
    				this->sendAlarm(1, false);
      			}//if-else
    		}//if
    		// shift to the next bit
    		value >>= 1;
    		lastValue_m >>= 1;
    		alarmMask_m >>= 1;
    		alarmTrigger_m >>= 1;
    	}//for
    	lastValue_m = tmpVal;
    }//if
}//check

}//namespace baci
<commit_msg>Added for pattern specialized implementation of clearAlarm. Modified check method that:   - increase/decrease  alarmRaised_m when an alarm is reased/cleared   - is stored value that triggered alarm (lastAlarmValue_m)<commit_after>#include "baciROpattern.h"
#include "baciAlarmSystemMonitorPattern.h"
#include "baciAlarmSystemMonitor_T.i"
#include "baciAlarmSystemMonitorDisc_T.i"

namespace baci
{

AlarmSystemMonitorPattern::AlarmSystemMonitorPattern(ROpatternImpl* property,EventDispatcher * eventDispatcher)
	: AlarmSystemMonitorDisc<ACS::pattern, ROpatternImpl>(property, eventDispatcher),
	patternSize_m(sizeof(ACS::pattern)*8)
{
	// setting lastValue to NOT of alarm_trigger will trigger alarms at the first check
	lastValue_m = ~(property_mp->alarm_trigger());
}//AlarmSystemMonitorPattern

AlarmSystemMonitorPattern::~AlarmSystemMonitorPattern()
{
}//~AlarmSystemMonitorPattern

void AlarmSystemMonitorPattern::clearAlarm()
{
	ACE_TRACE("baci::AlarmSystemMonitorPattern::clearAlarm");
	ACE_Guard<ACE_Recursive_Thread_Mutex>  protSect(faultStructMutex_m);

	alarmMask_m = property_mp->alarm_mask();
	alarmTrigger_m = property_mp->alarm_trigger();
	bitDescriptions_mp = property_mp->bitDescription();

	ACS::pattern tmpVal = lastValue_m; //tmp storage of the value
	// here we artifficaly set the last value, so that next check can trigger alarm(s)
	lastValue_m = (~alarmMask_m & lastValue_m) | (alarmMask_m & ~alarmTrigger_m);

	for(bitPos_m=0; bitPos_m<patternSize_m; bitPos_m++)
	{
		// we check if bit by bit
		if ((alarmMask_m & ~(alarmTrigger_m ^ tmpVal ) & 1) )
		{
			setProperty("BACI_BitPosition", bitPos_m);
			const char *bitDesc;
			if (bitPos_m<bitDescriptions_mp->length())
			{
			   bitDesc = (*bitDescriptions_mp)[bitPos_m];
			}
			else
			{
				bitDesc = "w/o description";
			}
			setProperty("BACI_BitDescription", bitDesc);
			setProperty("BACI_Value", tmpVal);
			ACS_SHORT_LOG((LM_ALERT, "Alarm for property: %s, bit %d (%s) cleared. Value change to: %d", property_mp->name(), bitPos_m, bitDesc, tmpVal));
			this->sendAlarm(1, false);
			this->alarmRaised_m --;
		}//if
		// shift to the next bit
		tmpVal >>= 1;
		alarmMask_m >>= 1;
		alarmTrigger_m >>= 1;
	}//for
}//clearAlarm

void AlarmSystemMonitorPattern::check(BACIValue &val,
								const ACSErr::Completion & c,
								const ACS::CBDescOut & desc
    )
{
    ACE_UNUSED_ARG(c);
    ACE_Guard<ACE_Recursive_Thread_Mutex>  protSect(faultStructMutex_m);

    ACS::pattern value = val.getValue(static_cast<ACS::pattern*>(0)); //val.patternValue();

    // first we just check if the value has been changed since last time
    if (value!=lastValue_m)
    {
    	// here we read the values every time! This can be done just once in ctor, but what if values in CDB change
    	alarmMask_m = property_mp->alarm_mask();
    	alarmTrigger_m = property_mp->alarm_trigger();
    	bitDescriptions_mp = property_mp->bitDescription();

    	ACS::pattern tmpVal = value; //tmp storage of the value

    	for(bitPos_m=0; bitPos_m<patternSize_m; bitPos_m++)
    	{
    		//we check if the bit at position bitPos has been changed
    		if ((alarmMask_m & (value ^ lastValue_m ) & 1) )
    		{
    			setProperty("BACI_BitPosition", bitPos_m);
    			const char *bitDesc;
    			if (bitPos_m<bitDescriptions_mp->length())
    			{
    			   bitDesc = (*bitDescriptions_mp)[bitPos_m];
    			}
    			else
    			{
    				bitDesc = "w/o description";
    			}
    			setProperty("BACI_BitDescription", bitDesc);
    			setProperty("BACI_Value", value);

    			// how the bit has changed (we could merge this with if above but would	 not be cleared then)
    			if ( ~(value ^ alarmTrigger_m) & 1 )
    			{
    				ACS_SHORT_LOG((LM_ALERT, "Alarm for property: %s, bit %d (%s) raised. Value change to: %d", property_mp->name(), bitPos_m, bitDesc, value));
    				this->sendAlarm(1, true);
    				this->lastAlarmValue_m = val;
    				this->alarmRaised_m ++;
      			}
    			else
    			{
    				ACS_SHORT_LOG((LM_ALERT, "Alarm for property: %s, bit %d (%s) cleared. Value change to: %d", property_mp->name(), bitPos_m, bitDesc, value));
    				this->sendAlarm(1, false);
    				this->lastAlarmValue_m = val;
    				this->alarmRaised_m --;
      			}//if-else
    		}//if
    		// shift to the next bit
    		value >>= 1;
    		lastValue_m >>= 1;
    		alarmMask_m >>= 1;
    		alarmTrigger_m >>= 1;
    	}//for
    	lastValue_m = tmpVal;
    }//if
}//check

}//namespace baci
<|endoftext|>