Mikhail Yanakayev
Topic Author
Posts: 15
Joined: 20 Sep 2023, 12:13

"Insufficient buffer size" while making delegate

18 Dec 2024, 00:47

Hello!
I'm trying to create delegate and attach it to ScrollChanged event in my ScrollViewer. It works OK if I doing it with lambda, something like this:
myScroll->StatusChanged() += [](Noesis::BaseObject* sender, const Noesis::ScrollChangedEventArgs&) {dosomething();};
But if I want to make it with delegate
Noesis::ScrollChangedEventHandler delegate = Noesis::MakeDelegate(this, &MyClass::OnScrollChanged);
myScroll->ScrollChanged() += delegate;
then get static assert "Insufficient buffer size" in MakeDelegate function.

How it can be solved?
I'm using Noesis 3.2.6

Thank you!
 
Mikhail Yanakayev
Topic Author
Posts: 15
Joined: 20 Sep 2023, 12:13

Re: "Insufficient buffer size" while making delegate

18 Dec 2024, 02:11

Also, to not create new topic:
I want to scroll content a bit after ScrollChanged delegate will called. If I call ScrollToVerticalOffset inside this delegate, it called recursively. So I call
myScroll->StatusChanged() -= delegate;
right before ScrollToVerticalOffset to not call this delegate on my scrolling. But seems it doesn't work since it still called recursively while ScrollViewer reached bottom elements.
It seems that delegate removing doesn't work properly or I'm doing something wrong.
Could you give a clue?

Thanks!
 
User avatar
jsantos
Site Admin
Posts: 4829
Joined: 20 Jan 2012, 17:18
Contact:

Re: "Insufficient buffer size" while making delegate

18 Dec 2024, 11:51

I am a bit confused by your message because you mention the ScrollChanged event, but in your code, you appear to be mixing StatusChanged and ScrollChanged.

That said, there is a limitation (#1141) in our lambda implementation: to avoid extra heap allocations, there is a limit to the size of the context captured by a lambda.

However, you shouldn’t encounter any errors when using non-lambda delegates. Could you please share the exact code that produces the error, along with the specific compiler error message?

Additionally, note that lambda delegates cannot be removed from event handlers (#1081). Therefore, although it may be more tedious, we recommend using standard member delegates
 
Mikhail Yanakayev
Topic Author
Posts: 15
Joined: 20 Sep 2023, 12:13

Re: "Insufficient buffer size" while making delegate

18 Dec 2024, 18:41

Sorry, ofcourse I meant ScrollChanged and confused events when wrote code by memory )

Here's parts of code which related to topic:
bool MYNAMESPACE::MyClass::ScrollToExactPosition(int rowToScroll, int elementToOpen)
{
	Noesis::VirtualizingStackPanel* panel = m_scroll->GetTemplateChild<Noesis::VirtualizingStackPanel>("Virtualizer");
	if (panel)
	{
		Noesis::ItemsControl* owner = Noesis::ItemsControl::GetItemsOwner(panel);
		if (!owner || owner->GetItems()->Count() < rowToScroll)
			return false;
		panel->BringIndexIntoView(rowToScroll);
		
		if (m_itemsControl && m_itemsControl->IsLoaded())
		{
			if (m_itemsControl->GetItemContainerGenerator()->GetStatus() == Noesis::GeneratorStatus_ContainersGenerated)
			{
				Noesis::ItemCollection* itemCollection = m_itemsControl->GetItems();
				if (itemCollection)
				{
					Noesis::ContentPresenter* presenter = Noesis::DynamicCast<Noesis::ContentPresenter*>(m_itemsControl->GetItemContainerGenerator()-		>ContainerFromIndex(rowToScroll));
			if (presenter && presenter->IsLoaded())
			{
				Noesis::UniformGrid* uniformGrid = Noesis::DynamicCast<Noesis::UniformGrid*>(Noesis::VisualTreeHelper::GetChild(Noesis::DynamicCast<Noesis::Visual*>(presenter), 0));
				Noesis::ContentPresenter* elementContent = Noesis::DynamicCast<Noesis::ContentPresenter*>(Noesis::VisualTreeHelper::GetChild(Noesis::DynamicCast<Noesis::Visual*>(uniformGrid), elementToOpen));
				Noesis::FrameworkElement* animatedElement = Noesis::DynamicCast<Noesis::FrameworkElement*>(elementContent->GetTemplateChild("MainGrid"));

				m_scroll->ScrollChanged() += Noesis::MakeDelegate(this, &MyClass::OnScrollChanged); // ==> here we got static assert
				if (animatedElement)
				{
					Noesis::VisualStateManager::GoToElementState(animatedElement, Noesis::Symbol("Opening"), false);
				}
			}
		}
		return true;
	}
	return false;
}

void MYNAMESPACE::MyClass::OnScrollChanged(Noesis::BaseObject* sender, const Noesis::ScrollChangedEventArgs&)
{
	Noesis::ScrollViewer* scroll = Noesis::DynamicCast<Noesis::ScrollViewer*>(sender);
	printf("%f\n", scroll->GetVerticalOffset());
	scroll->ScrollChanged() -= Noesis::MakeDelegate(this, &MyClass::OnScrollChanged);
	scroll->ScrollToVerticalOffset(scroll->GetVerticalOffset() + scroll->GetActualHeight() * 0.5f);
}
Last edited by Mikhail Yanakayev on 18 Dec 2024, 20:50, edited 1 time in total.
 
User avatar
jsantos
Site Admin
Posts: 4829
Joined: 20 Jan 2012, 17:18
Contact:

Re: "Insufficient buffer size" while making delegate

18 Dec 2024, 19:41

Thanks, can I also have a look at the layout of MyClass (at least see the parent classes, could it be that you are using multiple virtual base classes?)
 
Mikhail Yanakayev
Topic Author
Posts: 15
Joined: 20 Sep 2023, 12:13

Re: "Insufficient buffer size" while making delegate

18 Dec 2024, 20:49

This class inherits this VM_Base class that inherits NoesisApp::NotifyPropertyChangedBase. Also, we're used already MakeDelegate inside same class and everything worked like a charm. This call is only problem place actually
	class VM_Base : public NoesisApp::NotifyPropertyChangedBase
	{
	public:
		VM_Base() {}
	};
UPD: this MakeDelegate don't lead to any issues if don't assigned to any delegate variable and just called just like that
MakeDelegate(this, MyClass::OnScrollChanged)
Maybe because of optimizations, but optimization is turned off in my config.

UPD2: It worked when I made just function, not member of class, and assigned it to ScrollChanged(). So looks like it's really class structure problem. What in theory it can be?
 
User avatar
jsantos
Site Admin
Posts: 4829
Joined: 20 Jan 2012, 17:18
Contact:

Re: "Insufficient buffer size" while making delegate

20 Dec 2024, 10:11

I am not able to reproduce this in a minimal sample like this one:
#include <NsApp/NotifyPropertyChangedBase.h>
#include <NsCore/Delegate.h>

class VM_Base : public NoesisApp::NotifyPropertyChangedBase
{
public:
    VM_Base() {}
};

class MyClass : public VM_Base
{
public:
    MyClass()
    {
        Delegate<void()> func;
        func += MakeDelegate(this, &MyClass::OnScrollChanged);
    }

    void OnScrollChanged()
    {
    }
};
This works fine, could you please indicate what changes are needed to reproduce your error? Is this on Visual Visual Studio?
 
Mikhail Yanakayev
Topic Author
Posts: 15
Joined: 20 Sep 2023, 12:13

Re: "Insufficient buffer size" while making delegate

26 Dec 2024, 18:26

Sorry for a long answer.
I've tried this, and got same error:
	class VM_Base : public NoesisApp::NotifyPropertyChangedBase
	{
	public:
		VM_Base() {}
	};

	class MyClass : public VM_Base
	{
		MyClass()
		{
			viewer->ScrollChanged() += Noesis::MakeDelegate(this, &MyClass::OnScrollChanged);
		}

		void OnScrollChanged() {}

	private:
		Noesis::ScrollViewer* viewer;
	};
 
User avatar
sfernandez
Site Admin
Posts: 3364
Joined: 22 Dec 2011, 19:20

Re: "Insufficient buffer size" while making delegate

27 Dec 2024, 11:17

The problem with your last code is that the method signature does not match the event handler. This should work:
void OnScrollChanged(Noesis::BaseComponent* sender, const Noesis::ScrollChangedEventArgs& e) {}
 
User avatar
jsantos
Site Admin
Posts: 4829
Joined: 20 Jan 2012, 17:18
Contact:

Re: "Insufficient buffer size" while making delegate

27 Dec 2024, 12:24

The error we are giving is not very correct though... let me see if we can do better.

Who is online

Users browsing this forum: No registered users and 9 guests