LCOV - code coverage report
Current view: top level - include/controls - WebServerControlTypeRegistry.h (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 8601ad Lines: 24 28 85.7 %
Date: 2025-07-18 13:27:08 Functions: 38 43 88.4 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //* This file is part of the MOOSE framework
       2             : //* https://mooseframework.inl.gov
       3             : //*
       4             : //* All rights reserved, see COPYRIGHT for full restrictions
       5             : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
       6             : //*
       7             : //* Licensed under LGPL 2.1, please see LICENSE for details
       8             : //* https://www.gnu.org/licenses/lgpl-2.1.html
       9             : 
      10             : #pragma once
      11             : 
      12             : #include <string>
      13             : #include <map>
      14             : #include <type_traits>
      15             : 
      16             : #include "MooseError.h"
      17             : 
      18             : #include "minijson/minijson.h"
      19             : 
      20             : class WebServerControl;
      21             : 
      22             : namespace Moose
      23             : {
      24             : /**
      25             :  * A static registry used to register and build values of different types for the WebServerControl
      26             :  *
      27             :  * Needed due to the complexities of parsing parameter types from generic JSON received
      28             :  * by the web server.
      29             :  */
      30             : class WebServerControlTypeRegistry
      31             : {
      32             : public:
      33             :   /**
      34             :    * @return The WebServerControlTypeRegistry singleton
      35             :    */
      36             :   static WebServerControlTypeRegistry & getRegistry();
      37             : 
      38             :   /**
      39             :    * The base class for a value that is produced by this registry.
      40             :    */
      41             :   class ValueBase
      42             :   {
      43             :   public:
      44             :     /**
      45             :      * Constructor.
      46             :      * @param name The name that the value is for (typically a controllable path)
      47             :      * @param type The string representationg of the type
      48             :      */
      49         168 :     ValueBase(const std::string & name, const std::string & type) : _name(name), _type(type) {}
      50         168 :     virtual ~ValueBase() {}
      51             : 
      52             :     /**
      53             :      * @return The name that the value is for
      54             :      */
      55         280 :     const std::string & name() const { return _name; }
      56             :     /**
      57             :      * @return The string representation of the type
      58             :      */
      59         112 :     const std::string & type() const { return _type; }
      60             : 
      61             :     /**
      62             :      * Sets the controllable value given the name and type via the controllable
      63             :      * interface in \p control.
      64             :      *
      65             :      * Will broadcast the value for setting it.
      66             :      */
      67             :     virtual void setControllableValue(WebServerControl & control) = 0;
      68             : 
      69             :     /**
      70             :      * Common exception for parsing related errors in converting JSON to a value.
      71             :      */
      72             :     struct Exception : public std::exception
      73             :     {
      74             :     public:
      75           0 :       Exception(const std::string & message) : _message(message) {}
      76           0 :       virtual const char * what() const noexcept override final { return _message.c_str(); }
      77             : 
      78             :     private:
      79             :       const std::string _message;
      80             :     };
      81             : 
      82             :   private:
      83             :     /// The name that the value is for
      84             :     const std::string _name;
      85             :     /// The string representation of the type
      86             :     const std::string _type;
      87             :   };
      88             : 
      89             :   /**
      90             :    * Registers a type with string name \p type_name and the given derived type.
      91             :    */
      92             :   template <typename DerivedValueType>
      93      359632 :   static char add(const std::string & type_name)
      94             :   {
      95             :     static_assert(std::is_base_of_v<ValueBase, DerivedValueType>, "Is not derived from ValueBase");
      96      359632 :     getRegistry()._types.emplace(type_name, std::make_unique<Type<DerivedValueType>>(type_name));
      97      359632 :     return 0;
      98             :   }
      99             : 
     100             :   /**
     101             :    * @return Whether or not the type \p type is registered.
     102             :    */
     103         112 :   static bool isRegistered(const std::string & type) { return getRegistry()._types.count(type); }
     104             : 
     105             :   /**
     106             :    * Builds a value with the type \p type, name \p name, and a default value.
     107             :    */
     108          56 :   static std::unique_ptr<ValueBase> build(const std::string & type, const std::string & name)
     109             :   {
     110          56 :     return get(type).build(name);
     111             :   }
     112             :   /**
     113             :    * Builds a value with the type \p type, name \p name, and a value parsed from \p json_value.
     114             :    *
     115             :    * Will throw ValueBase::Exception on a parsing error.
     116             :    */
     117             :   static std::unique_ptr<ValueBase>
     118         112 :   build(const std::string & type, const std::string & name, const miniJson::Json & json_value)
     119             :   {
     120         112 :     return get(type).build(name, json_value);
     121             :   }
     122             : 
     123             : private:
     124             :   /**
     125             :    * Base registry class for a type that is used to build values.
     126             :    */
     127             :   class TypeBase
     128             :   {
     129             :   public:
     130      359632 :     TypeBase(const std::string & type) : _type(type) {}
     131           0 :     virtual ~TypeBase() {}
     132             : 
     133             :     /**
     134             :      * @return The string representation of the type
     135             :      */
     136         168 :     const std::string & type() const { return _type; }
     137             :     /**
     138             :      * Builds a value with the given type, name \p name, and JSON value \p json_value.
     139             :      *
     140             :      * This will parse the JSON value into the underlying type and will be called
     141             :      * on only rank 0 where server listens.
     142             :      */
     143             :     virtual std::unique_ptr<ValueBase> build(const std::string & name,
     144             :                                              const miniJson::Json & json_value) const = 0;
     145             :     /**
     146             :      * Builds a value with the given type, name \p name, and a default value.
     147             :      *
     148             :      * This will be called on processors that are not rank 0 for cloning.
     149             :      */
     150             :     virtual std::unique_ptr<ValueBase> build(const std::string & name) const = 0;
     151             : 
     152             :   private:
     153             :     /// The string representation of the underlying type
     154             :     const std::string _type;
     155             :   };
     156             : 
     157             :   template <class DerivedValueType>
     158             :   struct Type : public TypeBase
     159             :   {
     160      359632 :     Type(const std::string & type) : TypeBase(type) {}
     161             : 
     162          56 :     virtual std::unique_ptr<ValueBase> build(const std::string & name) const override final
     163             :     {
     164          56 :       return std::make_unique<DerivedValueType>(name, type());
     165             :     }
     166         112 :     virtual std::unique_ptr<ValueBase> build(const std::string & name,
     167             :                                              const miniJson::Json & json_value) const override final
     168             :     {
     169         112 :       return std::make_unique<DerivedValueType>(name, type(), json_value);
     170             :     }
     171             :   };
     172             : 
     173             :   /**
     174             :    * Internal getter for the registration object for type \p type.
     175             :    */
     176         168 :   static const TypeBase & get(const std::string & type)
     177             :   {
     178         168 :     auto & registry = getRegistry();
     179         168 :     const auto it = registry._types.find(type);
     180         168 :     if (it == registry._types.end())
     181           0 :       mooseError("WebServerControlTypeRegistry: The type '", type, "' is not registered");
     182         336 :     return *it->second;
     183             :   }
     184             : 
     185             :   /// The registration data
     186             :   std::map<std::string, std::unique_ptr<TypeBase>> _types;
     187             : };
     188             : }

Generated by: LCOV version 1.14