Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optional natives coming from an extension stop working when the extension is reloaded #2169

Open
bottiger1 opened this issue May 24, 2024 · 3 comments

Comments

@bottiger1
Copy link
Contributor

If you have optional natives coming from an extension, they stop working when you reload the extension.

If they come from a plugin instead, if you reload the plugin that provides the natives, they continue to work.

I've spent some time trying to see if it's an easy solution but it appears to be quite complex because "fake natives" which I assume are plugin natives, seem to have an entirely different implementation.

@KyleSanderson
Copy link
Member

If you have optional natives coming from an extension, they stop working when you reload the extension.

If they come from a plugin instead, if you reload the plugin that provides the natives, they continue to work.

I've spent some time trying to see if it's an easy solution but it appears to be quite complex because "fake natives" which I assume are plugin natives, seem to have an entirely different implementation.

It's unfortunate that you deleted the template, as this has (binding) seen significant work since 1.5, 1.6, 1.7, 1.8, and I think 1.10.

What version of sourcemod are you running?

@bottiger1
Copy link
Contributor Author

If you have optional natives coming from an extension, they stop working when you reload the extension.
If they come from a plugin instead, if you reload the plugin that provides the natives, they continue to work.
I've spent some time trying to see if it's an easy solution but it appears to be quite complex because "fake natives" which I assume are plugin natives, seem to have an entirely different implementation.

It's unfortunate that you deleted the template, as this has (binding) seen significant work since 1.5, 1.6, 1.7, 1.8, and I think 1.10.

What version of sourcemod are you running?

I'm using bleeding edge sourcemod and this has been a problem for as long as I can remember.

e07c120

@bottiger1
Copy link
Contributor Author

bottiger1 commented May 24, 2024

I wrote some untested pseudocode.

The logic is to go through all the plugins, find any unbound optional natives, and rebind them.

Do you know if this will work?

bool CPluginManager::RequireExtensions(CPlugin *pPlugin)

if(!ext.required)
{
	pPlugin->optionalExtensions.add(ext.name); // std::set
}

////////////////////////////////////

void CExtension::MarkAllLoaded()

if (!bridge->IsMapLoading())
{

	std::set<string> libs = m_libraries

	for (PluginIter iter(g_PluginSys.m_plugins); !iter.done(); iter.next()) {
		CPlugin *pPlugin = (*iter);
		IPluginContext *pContext = pPlugin->GetBaseContext();

		if(pPlugin->optionalExtensions.contains(GetAPI()->GetExtensionName()))
		{
			sharesys->BeginBindingFor(pPlugin); // maybe not needed?

			uint32_t native_count = pContext->GetNativesNum();
			auto rt = pPlugin->GetRuntime();

			// find unbound optional natives
			for (uint32_t i = 0; i < native_count; i++)
			{
				const sp_native_t *native = pContext->GetRuntime()->GetNative(i);
				if (!native)
					continue;

				if ( (native->flags & SP_NTVFLAG_OPTIONAL) == 0 || native->func != nullptr)
					continue;

				auto extensionNative = sharesys->FindNative(native->name);
				if(!extensionNative)
					continue;

				rt->UpdateNativeBinding(i, extensionNative->native->func, native->flags, nullptr);
			}
		}
	}

}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants