void RCSetAssociatedObject_MainThreadAffined()

in RenderCore/Utilities/RCAssociatedObject.mm [62:96]


void RCSetAssociatedObject_MainThreadAffined(__unsafe_unretained id object,
                                             const void *key,
                                             __unsafe_unretained id _Nullable value)
{
  RCCAssertMainThread();
  const auto map = CKMainThreadAffinedAssociatedObjectMap();
  const auto address = (uintptr_t)object;
  const auto it = map->find(address);
  if (it == map->end()) {
    if (value != nil) {
      map->emplace(address, std::vector<KeyValue> {{key, value}});
      // Set associated object from objc/runtime so that we will get notified when `object` is deallocated.
      objc_setAssociatedObject(object,
                               &CKObjectDeallocationObserverKey,
                               [[CKObjectDeallocationObserver alloc] initWithAddress:address],
                               OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
  } else {
    auto &keyValues = it->second;
    const auto rs = CK::find_if(keyValues, [&](const auto &pair) {
      return std::get<0>(pair) == key;
    });
    if (rs == keyValues.end()) {
      if (value != nil) {
        keyValues.push_back({key, value});
      }
    } else {
      if (value != nil) {
        *rs = {key, value};
      } else {
        keyValues.erase(rs);
      }
    }
  }
}