Repository: xbmc/xbmc
File: xbmc/pvr/addons/PVRClient.cpp (C++)

Code before:
void CPVRClient::HandleAddonCallback(const char* strFunctionName,
                                     void* kodiInstance,
                                     F function,
                                     bool bForceCall /* = false */)
{
  // Check preconditions.
  auto* client{static_cast<CPVRClient*>(kodiInstance)};
  if (!client)
  {
    CLog::Log(LOGERROR, "{}: No instance pointer given!", strFunctionName);
    return;
  }

  if (!bForceCall && client->m_bBlockAddonCalls && client->m_iAddonCalls == 0)
  {
    CLog::Log(LOGWARNING, LOGPVR, "{}: Ignoring callback from PVR client '{}'", strFunctionName,
              client->ID());
    return;
  }

  // Call.
  function(client);
}

template<typename F>
void CPVRClient::HandleAddonCallback(const char* strFunctionName,
                                     const void* kodiInstance,
                                     F function,
                                     bool bForceCall /* = false */)
{
  // Check preconditions.
  auto* client{static_cast<const CPVRClient*>(kodiInstance)};
  if (!client)
  {
    CLog::Log(LOGERROR, "{}: No instance pointer given!", strFunctionName);
    return;
  }

  if (!bForceCall && client->m_bBlockAddonCalls && client->m_iAddonCalls == 0)
  {
    CLog::Log(LOGWARNING, LOGPVR, "{}: Ignoring callback from PVR client '{}'", strFunctionName,
              client->ID());
    return;
  }

  // Call.
  function(client);
}

void CPVRClient::cb_transfer_channel_group(void* kodiInstance,
                                           const PVR_HANDLE handle,

Review comment (suggestion):
Just a suggestion, instead of creating an almost copy  of the function you could also change the existing function in this way:
```cpp
template<typename F, typename KodiInstance>
void CPVRClient::HandleAddonCallback(const char* strFunctionName,
                                     KodiInstance* kodiInstance,
                                     F function,
                                     bool bForceCall /* = false */)
{
  using Client = std::conditional_t<std::is_const_v<KodiInstance>, const CPVRClient, CPVRClient>;

  // Check preconditions.
  auto* client{static_cast<Client*>(kodiInstance)};
  if (!client)
  // ...
```

Code after:
template<typename F, typename KodiInstance>
void CPVRClient::HandleAddonCallback(const char* strFunctionName,
                                     KodiInstance* kodiInstance,
                                     F function,
                                     bool bForceCall /* = false */)
{
  using Client = std::conditional_t<std::is_const_v<KodiInstance>, const CPVRClient, CPVRClient>;

  // Check preconditions.
  auto* client{static_cast<Client*>(kodiInstance)};
  if (!client)
  {
    CLog::Log(LOGERROR, "{}: No instance pointer given!", strFunctionName);
    return;
  }

  if (!bForceCall && client->m_bBlockAddonCalls && client->m_iAddonCalls == 0)
  {
    CLog::Log(LOGWARNING, LOGPVR, "{}: Ignoring callback from PVR client '{}'", strFunctionName,
              client->ID());
    return;
  }

  // Call.
  function(client);
}

void CPVRClient::cb_transfer_channel_group(void* kodiInstance,
                                           const PVR_HANDLE handle,
                                           const PVR_CHANNEL_GROUP* group)
{
  HandleAddonCallback(std::source_location::current().function_name(), kodiInstance,
                      [handle, group](const CPVRClient* client)
                      {
                        if (!handle || !group)
                        {
                          CLog::LogF(LOGERROR, "Invalid callback parameter(s)");
                          return;
                        }

                        if (strlen(group->strGroupName) == 0)
                        {
                          CLog::LogF(LOGERROR, "Empty group name");
                          return;
                        }

                        // transfer this entry to the groups container
                        auto* kodiGroups{static_cast<CPVRChannelGroups*>(handle->dataAddress)};
                        const auto transferGroup = kodiGroups->GetGroupFactory()->CreateClientGroup(
                            *group, client->GetID(), kodiGroups->GetGroupAll());
                        kodiGroups->UpdateFromClient(transferGroup);