Hi Ziqing,
Il 29/07/21 03:30, Ziqing Hui ha scritto:
Thanks for your reply. My plan is to add something like " struct d2d_effect_ops", which is a vtable. And each effect class needs to implement this vtable. It may look like this:
I think this strategy makes the code less idiomatic, therefore harder to read and maintain, and it requires a double virtual dispatching, for which I see no use. The COM virtual dispatching mechanism is already good enough to implement all the dynamic behavior you need, so I would use that one, putting each effect in its own class.
This would mean something like:
struct d2d_affine_effect { ID2D1Effect ID2D1Effect_iface; ... };
static const ID2D1EffectVtbl d2d_affine_effect_vtbl = { d2d_affine_effect_QueryInterface, d2d_affine_effect_AddRef, d2d_affine_effect_Release, d2d_affine_effect_GetPropertyCount, ... };
void d2d_effect_init(ID2D1Effect **effect, ID2D1Factory *factory, const CLSID *effect_id) { if (IsEqualGUID(effect_id, &CLSID_D2D12DAffineTransform)) { struct d2d_affine_effect *object = heap_alloc_zero(sizeof(*object)); object->ID2D1Effect_iface.lpVtbl = &d2d_affine_effect; ... *effect = object->ID2D1Effect_iface.lpVtbl; return S_OK; } else if (IsEqualGUID(effect_id, &CLSID_D2D12DPerspectiveTransform)) ...
FIXME("Effect not implemented: %p\n", wine_dbgstr_guid(effect_id)); return D2DERR_EFFECT_IS_NOT_REGISTERED; }
(coding out of my mind, might require some tweaks, of course)
The implementations of the methods in the three different classes can very well share code by mean of helper functions, if that's useful.
Again, just my 2 cents.
Giovanni.