<commit_before>/****************************************************************************

    worker.hpp - Support file for writing LV2 plugins in C++

    Copyright (C) 2012 <NAME> <<EMAIL>>

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

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 01222-1307  USA

****************************************************************************/

#ifndef LVTK_LV2_WORKER_HPP
#define LVTK_LV2_WORKER_HPP

#include <cstring>

#include <lv2/lv2plug.in/ns/ext/worker/worker.h>

#include "lvtk/private/types.hpp"

namespace lvtk {

   /** Convenience enum to get LV2_Worker_Status into a C++ namespace */
   typedef enum {
      WORKER_SUCCESS      = LV2_WORKER_SUCCESS,      /**< Work Completed. */
      WORKER_ERR_UNKNOWN  = LV2_WORKER_ERR_UNKNOWN,  /**< Unknown error. */
      WORKER_ERR_NO_SPACE = LV2_WORKER_ERR_NO_SPACE  /**< Fail due to Lack of Space. */
   } WorkerStatus;


   /**
       Worker reponse. This wraps an LV2_Worker_Respond_Function
       and exeucutes via operator ()
    */
   struct WorkerRespond {
      WorkerRespond(LV2_Handle instance,
                    LV2_Worker_Respond_Function wrfunc,
                    LV2_Worker_Respond_Handle handle)
          : p_instance(instance),
            p_handle(handle), 
            p_wrfunc (wrfunc) 
      { }

      /**
          Execute the worker retrieval functor.
          @param size
          @param data
          @return WORKER_SUCCESS on success
       */
      WorkerStatus operator () (uint32_t size, const void* data) const
      {
         return (WorkerStatus) p_wrfunc (p_handle, size, data);
      }

   private:
      LV2_Handle                        p_instance;
      LV2_Worker_Respond_Handle         p_handle;
      LV2_Worker_Respond_Function       p_wrfunc;
   };

   /** The LV2 Worker Feature Mixin
       @struct lvtk::Worker lvtk/ext/worker.hpp
       @ingroup pluginmixins
   */
   template <bool Required = true>
   struct Worker
   {
        template <class Derived>
        struct I : Extension<Required>
        {

         /** @skip */
         static void
         map_feature_handlers(FeatureHandlerMap& hmap)
         {
            hmap[LV2_WORKER__schedule] = &I<Derived>::handle_feature;
         }

         /** @skip */
         static void
         handle_feature(void* instance, FeatureData data)
         {
            Derived* d = reinterpret_cast<Derived*>(instance);
            I<Derived>* fe = static_cast<I<Derived>*>(d);
            LV2_Worker_Schedule *ws = reinterpret_cast<LV2_Worker_Schedule*>(data);

            fe->m_work_schedule_handle = ws->handle;
            fe->m_schedule_work_func = ws->schedule_work;
            fe->m_ok = true;
         }

         /** Sanity check the mixin */
         bool
         check_ok()
         {
            if (LVTK_DEBUG) {
              std::clog<<"    [Worker] validation "
                       <<(this->m_ok ? "succeeded" : "failed")<<"."<<std::endl;
            }
            return this->m_ok;
         }

         /** @skip */
         static const void*
         extension_data (const char* uri)
         {
            if (!std::strcmp (uri, LV2_WORKER__interface)) {
               static LV2_Worker_Interface worker = { &I<Derived>::_work,
                                                      &I<Derived>::_work_response,
                                                      &I<Derived>::_end_run };
               return &worker;
            }

            return 0;
         }

         /* =============== LV2 Worker C++ Interface =============== */


         /**
            Request from run() that the host call the worker.

            This function is in the audio threading class.  It should be called from
            run() to request that the host call the work() method in a non-realtime
            context with the given arguments.

            This function is always safe to call from run(), but it is not
            guaranteed that the worker is actually called from a different thread.
            In particular, when free-wheeling (e.g. for offline rendering), the
            worker may be executed immediately.  This allows single-threaded
            processing with sample accuracy and avoids timing problems when run() is
            executing much faster or slower than real-time.

            Plugins SHOULD be written in such a way that if the worker runs
            immediately, and responses from the worker are delivered immediately,
            the effect of the work takes place immediately with sample accuracy.

            The @p data MUST be safe for the host to copy and later pass to work(),
            and the host MUST guarantee that it will be eventually passed to work()
            if this function returns WORKER_SUCCESS.

            @param size   The size of @p data.
            @param data   Message to pass to work(), or NULL.
         */
          WorkerStatus
          schedule_work (uint32_t size, void *data)
          {
            return (WorkerStatus)m_schedule_work_func(
                                    m_work_schedule_handle, size, data);
          }

         /**
            This is called by the host in a non-realtime context as requested,
            possibly with an arbitrary message to handle. A response can be sent
            to run() using @p respond.  The plugin MUST NOT make any assumptions
            about which thread calls this method, other than the fact that there
            are no real-time requirements.

            @param respond  A functor for sending a response to run().
            @param size     The size of @p data.
            @param data     Data from run(), or NULL.
         */
          WorkerStatus
          work (WorkerRespond &respond, uint32_t size, const void* data)
          {<commit_msg>schedule_work method. Signature matches c counterpart<commit_after>/****************************************************************************

    worker.hpp - Support file for writing LV2 plugins in C++

    Copyright (C) 2012 <NAME> <<EMAIL>>

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

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 01222-1307  USA

****************************************************************************/

#ifndef LVTK_LV2_WORKER_HPP
#define LVTK_LV2_WORKER_HPP

#include <cstring>

#include <lv2/lv2plug.in/ns/ext/worker/worker.h>

#include "lvtk/private/types.hpp"

namespace lvtk {

   /** Convenience enum to get LV2_Worker_Status into a C++ namespace */
   typedef enum {
      WORKER_SUCCESS      = LV2_WORKER_SUCCESS,      /**< Work Completed. */
      WORKER_ERR_UNKNOWN  = LV2_WORKER_ERR_UNKNOWN,  /**< Unknown error. */
      WORKER_ERR_NO_SPACE = LV2_WORKER_ERR_NO_SPACE  /**< Fail due to Lack of Space. */
   } WorkerStatus;


   /**
       Worker reponse. This wraps an LV2_Worker_Respond_Function
       and exeucutes via operator ()
    */
   struct WorkerRespond {
      WorkerRespond(LV2_Handle instance,
                    LV2_Worker_Respond_Function wrfunc,
                    LV2_Worker_Respond_Handle handle)
          : p_instance(instance),
            p_handle(handle), 
            p_wrfunc (wrfunc) 
      { }

      /**
          Execute the worker retrieval functor.
          @param size
          @param data
          @return WORKER_SUCCESS on success
       */
      WorkerStatus operator () (uint32_t size, const void* data) const
      {
         return (WorkerStatus) p_wrfunc (p_handle, size, data);
      }

   private:
      LV2_Handle                        p_instance;
      LV2_Worker_Respond_Handle         p_handle;
      LV2_Worker_Respond_Function       p_wrfunc;
   };

   /** The LV2 Worker Feature Mixin
       @struct lvtk::Worker lvtk/ext/worker.hpp
       @ingroup pluginmixins
   */
   template <bool Required = true>
   struct Worker
   {
        template <class Derived>
        struct I : Extension<Required>
        {

         /** @skip */
         static void
         map_feature_handlers(FeatureHandlerMap& hmap)
         {
            hmap[LV2_WORKER__schedule] = &I<Derived>::handle_feature;
         }

         /** @skip */
         static void
         handle_feature(void* instance, FeatureData data)
         {
            Derived* d = reinterpret_cast<Derived*>(instance);
            I<Derived>* fe = static_cast<I<Derived>*>(d);
            LV2_Worker_Schedule *ws = reinterpret_cast<LV2_Worker_Schedule*>(data);

            fe->m_work_schedule_handle = ws->handle;
            fe->m_schedule_work_func = ws->schedule_work;
            fe->m_ok = true;
         }

         /** Sanity check the mixin */
         bool
         check_ok()
         {
            if (LVTK_DEBUG) {
              std::clog<<"    [Worker] validation "
                       <<(this->m_ok ? "succeeded" : "failed")<<"."<<std::endl;
            }
            return this->m_ok;
         }

         /** @skip */
         static const void*
         extension_data (const char* uri)
         {
            if (!std::strcmp (uri, LV2_WORKER__interface)) {
               static LV2_Worker_Interface worker = { &I<Derived>::_work,
                                                      &I<Derived>::_work_response,
                                                      &I<Derived>::_end_run };
               return &worker;
            }

            return 0;
         }

         /* =============== LV2 Worker C++ Interface =============== */


         /**
            Request from run() that the host call the worker.

            This function is in the audio threading class.  It should be called from
            run() to request that the host call the work() method in a non-realtime
            context with the given arguments.

            This function is always safe to call from run(), but it is not
            guaranteed that the worker is actually called from a different thread.
            In particular, when free-wheeling (e.g. for offline rendering), the
            worker may be executed immediately.  This allows single-threaded
            processing with sample accuracy and avoids timing problems when run() is
            executing much faster or slower than real-time.

            Plugins SHOULD be written in such a way that if the worker runs
            immediately, and responses from the worker are delivered immediately,
            the effect of the work takes place immediately with sample accuracy.

            The @p data MUST be safe for the host to copy and later pass to work(),
            and the host MUST guarantee that it will be eventually passed to work()
            if this function returns WORKER_SUCCESS.

            @param size   The size of @p data.
            @param data   Message to pass to work(), or NULL.
         */
          WorkerStatus
          schedule_work (uint32_t size, const void* data)
          {
            return (WorkerStatus)m_schedule_work_func(
                                    m_work_schedule_handle, size, data);
          }

         /**
            This is called by the host in a non-realtime context as requested,
            possibly with an arbitrary message to handle. A response can be sent
            to run() using @p respond.  The plugin MUST NOT make any assumptions
            about which thread calls this method, other than the fact that there
            are no real-time requirements.

            @param respond  A functor for sending a response to run().
            @param size     The size of @p data.
            @param data     Data from run(), or NULL.
         */
          WorkerStatus
          work (WorkerRespond &respond, uint32_t size, const void* data)
          {
{'fraction_non_alphanumeric': 0.09673172242874845, 'fraction_numerical': 0.007589838909541511, 'mean_word_length': 1.930776214253291, 'pattern_counts': {'":': 0, '<': 59, '<?xml version=': 0, '>': 51, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 10, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '70187', 'n_tokens_mistral': 3458, 'n_tokens_neox': 3205, 'n_words': 1196}