apple / HomeKitADK

Apache License 2.0
2.56k stars 232 forks source link

Add a context pointer to HAPAccessory, HAPService and and HAPCharacteristic #68

Open rojer opened 4 years ago

rojer commented 4 years ago

Currently characteristic callbacks get server-wide context and a pointer to characteristic (via request). This presents a problem when a mechanism is required to map instances of HAPCharacteristic to some other entity (in my case, a C++ wrapper class). A separate list of instances is required, with lookup to find the right one. Same applies to HAPService and HAPAccessory - wrappers need to keep track of their instances separately. Would it be possible to add a void *context pointer to each of these structs, so finer-grained context can be attached to them?

maximkulkin commented 4 years ago

:+1:

I'm all supportive for having a contexts on a fine grained level, e.g. characteristic. Not sure why you need a server-wide context that is explicitly passed to every characteristic callback. It's not like you gonna have multiple instances of HAPAccessoryServer anyways, if I wanted to have a global context, I would just create a global variable and reference it directly.

Now, I think you can do it yourself: just create your own structures for HAPAccessory, HAPService and HAP*Characteristic and extend them with additional fields:

typedef struct {
  HAPAccessory base;
  // here go extra fields
  void *context;
} MyHAPAccessory;

Then in your callbacks you can cast structures passed to you in request to your structures and pull whatever extra information you planted there.

rojer commented 4 years ago

good idea! this will work for accessory and service but will be extremely ugly for characteristics because HAPCharacteristic is cast to a specific characteristic types (poor-man's OOP in C). we'll need to wrap all of those.

maximkulkin commented 4 years ago

It's not that bad, there's just 10 of them.

maximkulkin commented 4 years ago

Oh, here is an idea: for characteristic you can create your mega wrapper structure like so:

typedef struct {
  union {
    HAPDataCharacteristic data_base;
    HAPBoolCharacteristic bool_base;
    HAPUInt8Characteristic uint8_base;
    // ...
  };

  void *context;
} MyHAPCharacteristic;

So, in your own code you can work with all characteristic types the same way. Assuming you're doing C++ wrappers anyways.