pradosoft / prado

Prado - Component Framework for PHP
Other
187 stars 70 forks source link

TEventHandler with embedded data #939

Closed belisoful closed 1 year ago

belisoful commented 1 year ago

I've been studying Yii a bit to see how we can enhance PRADO. Yii has some great ideas, some interesting ideas, and some bad ideas. what system doesn't have a negative side? (even Prado)

In looking at Yii, they have encode the idea of "event handler data" into event handlers. I don't actually like that because it adds more cruft to the system than needed. Adding that to Prado also intersects with the priority system for event handlers.

This object is base enough that I think it deserves to go in the main folder beside TComponent and TModule.

It's the TEventHandler, It is a wrapper for Callable and is itself an invokable, but also contains embedded data that the callable may need. It implements the Event Handler as

public function handler($sender, $param, $data)
{
}

like Yii does but without all the modifications to the event system. to force re-create such a simple solution.

It's basically an "appliance" solution to incorrectly renovating your home to make something a thing.

belisoful commented 1 year ago

This affects the way TWeakCallableCollection works. TWeakList should also work similarly, preserving TEventHandlers like Closures in not making them WeakReferences. That is to say. TEventHandlers might not be held onto by the object, like a Closure, so the TEventHandler in TWeakCallableCollection may be the only instance, and it should be preserved.

I am making the callable internal to the TEventHandler convertible into WeakReference and back. This way, when the TEventHandler is in the TWeakCallableCollection it can be stored in a WeakReference form. This does require specialized searching though.

belisoful commented 1 year ago

There is regression into TWeakList and TWeakCallableCollection. as they need to be tuned to return the TEventHandler when its callable is given for a search, despite the data. And if the TEventHandler is used to search (eg indexOf, priorityOf), then it should be specific.

belisoful commented 1 year ago

Due to the way TWeakList and TWeakCallableCollection work, the TEventHandler will have a Callable, its associated Data, and then a weak Status flag (getter and setter). The ability for the class to make itself weak is because the handler must not be able to be set (to prevent the weak maps from going stale). So Making its callable weak and re-referencing is a feature of TEventHandler.

It also has ArrayAccess:

belisoful commented 1 year ago

@ctrlaltca To make TEventHandler happen, the undocumented feature of adding the event $name after $sender and $param will be removed. I figured that __dycall "needs" the info, and that is one way. (it is unnecessary, btw). I left it undocumented because I was unsure about its inclusion.

To compensate for this, I'm going to move the functionality of TBroadcastEventParameter into TEventParameter, remove the "name" from the constructor, and set the name property in the TEventParameter to the event name within raiseEvent. This automatically captures the event name rather than relying upon passing it as a parameter. It standardizes event name capture.

< / important part >

TEventContent relies upon this undocumented name parameter feature and is being updated as well. Its the only class that uses the undocumented feature. The new modality is better anyway.

I have the unit tests done for TEventHandler. It's looking nice. This was only possible because of the most recent merge to allow invokable objects as event handlers in raiseEvent.

I need to do the regression unit tests on TWeakList and TWeakCallableCollection. Basically, when searching for TEventHandlers they only match themselves, but when searching the list with just a callable, they need to match the TEventHandlers regardless of data. That is how Yii2 does it, but without the encapsulating class.

Yii2 "matches" the callable on removal (regardless of data). In effect enforcing only one object/method callable per event regardless of data.

By making the callable with data a unique object, despite being found in searches for just the callable, we can support the same handler with different data in the event multiple times. I don't know what the use case is for this, but it is "enabled."

belisoful commented 1 year ago

I'm finalizing the unit tests for TWeakCallableCollection tonight. Today was making sure that nested TEventHandler work properly.

belisoful commented 1 year ago

I'm touching up the php doc on TEventHandler and I think it'll be ready relatively soon.

belisoful commented 1 year ago

I have a few more unit tests to submit.

belisoful commented 1 year ago

This is just waiting on the pull request.