Resolved Делегированные ивенты не отписываются.

Автор темы #1
Дата рег
19 Фев 2011
Сообщения
196
Симпатии
71
От ивента подписанного через делегацию не возможно отписаться.
Соответственно такие ивенты на подписке навсегда, как и объект в памяти.

Код:
Delegate delegate = Delegate();
 
__EventFinish.Subscribe( EventFinishFunc( delegate.Finish ) );
__EventFinish.Unsubscribe( EventFinishFunc( delegate.Finish ) ); // Nope
 
Дата рег
16 Сен 2011
Сообщения
208
Симпатии
72
Вот так должно работать:
Код:
EventFinishFunc delegate = EventFinishFunc( delegate.Finish );
__EventFinish.Subscribe( delegate );
__EventFinish.Unsubscribe( delegate );
 
Автор темы #3
Дата рег
19 Фев 2011
Сообщения
196
Симпатии
71
Вот так должно работать:
Код:
EventFinishFunc delegate = EventFinishFunc( delegate.Finish );
__EventFinish.Subscribe( delegate );
__EventFinish.Unsubscribe( delegate );
Ты же понимаешь что в реальном коде мало вероятна подобная структура? То есть подписываться и сразу-же одписываться имеет мало смысла. А если придется самому заниматься дополнительным менеджментом подписей, то и смысла в системе ивентов не очень много остается ( в плане работы с делегатами, так то лучше тогда от них отказаться, чего не хотелось бы ).

То есть такая структура:
Код:
# pragma event "EventDelegateTest()"
 
class Delegate
{
	void Test()
	{
		Log( "ptr " );
	}
}
 
void ModuleInit()
{
	Delegate delegate = Delegate();
	{
		auto delegate = EventDelegateTestFunc( delegate.Test );
		__EventDelegateTest.Subscribe( delegate );
	}
 
	__EventDelegateTest.Raise();
 
	{
		auto delegate = EventDelegateTestFunc( delegate.Test );
		__EventDelegateTest.Unsubscribe( delegate );
	}
 
	__EventDelegateTest.Raise();
}
будет более реальна, но она не рабочая. Чтобы она работала нужно делать:

Код:
// FOS Server Sort 2
 
# pragma event "EventDelegateTest()"
 
class Delegate
{
	Delegate( )
	{
		@DelegateTest = EventDelegateTestFunc( this.realTest );
	}
 
	EventDelegateTestFunc get_Test(){ return DelegateTest; }
 
	private void realTest()
	{
		Log( "ptr " );
	}
 
	private EventDelegateTestFunc DelegateTest;
}
 
void ModuleInit()
{
	Delegate delegate = Delegate();
 
	{
		__EventDelegateTest.Subscribe( delegate.Test );
	}
 
	__EventDelegateTest.Raise();
 
	{
		__EventDelegateTest.Unsubscribe( delegate.Test );
	}
 
	__EventDelegateTest.Raise();
}

что само по себе имеет мало смысла, тем более для скриптового языка. Кроме того в дальнейшем обрекает на ряд подводных камней.

При сравнении функций проверяются просто адреса? Почему не сделать:

Код:
bool equality(const asIScriptFunction *function0, const asIScriptFunction *function1 )
{
	if( function0 == function1 )
		return true;
 
	if( function0->GetFuncType() == asEFuncType::asFUNC_DELEGATE && function1->GetFuncType() == asEFuncType::asFUNC_DELEGATE
		&& function0->GetDelegateObject() == function1->GetDelegateObject() && function0->GetDelegateFunction() == function1->GetDelegateFunction() )
			return true;
	  
	return false;
}

Ну или как вариант просто озвучить отказ поддержки делегаций.

П.С. код проверил на AngelScript: 2.33.0 WIP ( 2544 ревизия ), делегации корректно сравнивает.
 
Последнее редактирование: