Raised This Month: $32 Target: $400
 8% 

Solved Safe method of copying an ArrayList via a native?


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
shavit
AlliedModders Donor
Join Date: Dec 2011
Location: Israel
Old 08-01-2017 , 07:43   Safe method of copying an ArrayList via a native?
Reply With Quote #1

I'm trying to transfer very large amounts of data with ArrayList via a native. "very large" as in UP TO (usually much much less) 691,200 cells with a block size of 6.
What's the safest method of doing so? I can't really find examples nor any documentation of how to use handle 'pointers' in SourcePawn.

Note: I'm trying to copy the ArrayList's data (not a memory address) from one plugin with an ArrayList to another one with an ArrayList.

Cheers.
__________________
retired

Last edited by shavit; 08-01-2017 at 08:19.
shavit is offline
hmmmmm
Great Tester of Whatever
Join Date: Mar 2017
Location: ...
Old 08-01-2017 , 08:06   Re: Safe method of copying an ArrayList via a native?
Reply With Quote #2

Wouldn't cloning the ArrayList work? https://sm.alliedmods.net/new-api/ad...rrayList/Clone

Last edited by hmmmmm; 08-01-2017 at 08:07.
hmmmmm is offline
shavit
AlliedModders Donor
Join Date: Dec 2011
Location: Israel
Old 08-01-2017 , 08:19   Re: Safe method of copying an ArrayList via a native?
Reply With Quote #3

Quote:
Originally Posted by hmmmmm View Post
Wouldn't cloning the ArrayList work? https://sm.alliedmods.net/new-api/ad...rrayList/Clone
It actually did! I just had to return it via the native in a sort of weird way...

Code:
public int Native_GetReplayData(Handle handler, int numParams)
{
	int client = GetNativeCell(1);

	if(gA_PlayerFrames[client] != null)
	{
		return view_as<int>(gA_PlayerFrames[client].Clone());
	}

	return -1;
}
At first I thought I'm supposed to use some kind of a pointer or native reference, guess not.
__________________
retired
shavit is offline
hmmmmm
Great Tester of Whatever
Join Date: Mar 2017
Location: ...
Old 08-01-2017 , 08:26   Re: Safe method of copying an ArrayList via a native?
Reply With Quote #4

Not sure how that view_as<int> on the handle works, shouldn't you be returning an ArrayList handle?
e.g. https://wiki.alliedmods.net/Handles_...loning_Handles
hmmmmm is offline
shavit
AlliedModders Donor
Join Date: Dec 2011
Location: Israel
Old 08-01-2017 , 08:55   Re: Safe method of copying an ArrayList via a native?
Reply With Quote #5

Quote:
Originally Posted by hmmmmm View Post
Not sure how that view_as<int> on the handle works, shouldn't you be returning an ArrayList handle?
e.g. https://wiki.alliedmods.net/Handles_...loning_Handles
That's what I do, but..
Code:
/**
 * Defines a native function.
 *
 * It is not necessary to validate the parameter count 
 *
 * @param plugin			Handle of the calling plugin.
 * @param numParams			Number of parameters passed to the native.
 * @return 					Value for the native call to return.
 */
typedef NativeCall = function int (Handle plugin, int numParams);
From functions.inc. I have to cast it to int otherwise I get a tag mismatch warning.
Upon testing, it worked.
__________________
retired

Last edited by shavit; 08-01-2017 at 08:56.
shavit is offline
asherkin
SourceMod Developer
Join Date: Aug 2009
Location: OnGameFrame()
Old 08-01-2017 , 09:47   Re: Safe method of copying an ArrayList via a native?
Reply With Quote #6

You should probably passing a cloned handle to the plugin so that it owns it (and can thus free it when it is done).

The view_as thing is correct.
__________________
asherkin is offline
shavit
AlliedModders Donor
Join Date: Dec 2011
Location: Israel
Old 08-01-2017 , 09:51   Re: Safe method of copying an ArrayList via a native?
Reply With Quote #7

Quote:
Originally Posted by asherkin View Post
You should probably passing a cloned handle to the plugin so that it owns it (and can thus free it when it is done).
What do you mean? I want two separate copies of the data of the ArrayList, I don't see a reason to clone the handle.. that's not what I'm trying to achieve.
What I'm trying to achieve (which also worked) was to save a snapshot of an ArrayList's contents into another plugin, and then write it back into the original plugin after applying modifications to it.
__________________
retired
shavit is offline
WildCard65
Veteran Member
Join Date: Aug 2013
Location: Canada
Old 08-01-2017 , 11:26   Re: Safe method of copying an ArrayList via a native?
Reply With Quote #8

Quote:
Originally Posted by shavit View Post
What do you mean? I want two separate copies of the data of the ArrayList, I don't see a reason to clone the handle.. that's not what I'm trying to achieve.
What I'm trying to achieve (which also worked) was to save a snapshot of an ArrayList's contents into another plugin, and then write it back into the original plugin after applying modifications to it.
ArrayList.Clone returns a handle owned by the plugin who called the native, while that may work for reading and writing, the plugin your giving the handle to won't be able to close it.
__________________
WildCard65 is offline
shavit
AlliedModders Donor
Join Date: Dec 2011
Location: Israel
Old 08-01-2017 , 12:23   Re: Safe method of copying an ArrayList via a native?
Reply With Quote #9

Quote:
Originally Posted by WildCard65 View Post
ArrayList.Clone returns a handle owned by the plugin who called the native, while that may work for reading and writing, the plugin your giving the handle to won't be able to close it.
I clone it inside the child plugin though, and then delete it when I don't need it anymore.
__________________
retired

Last edited by shavit; 08-01-2017 at 12:24.
shavit is offline
Cookies.net
Senior Member
Join Date: Jan 2011
Old 08-01-2017 , 13:55   Re: Safe method of copying an ArrayList via a native?
Reply With Quote #10

Quote:
Originally Posted by shavit View Post
I clone it inside the child plugin though, and then delete it when I don't need it anymore.
Have you tried to dump handles after using that native a few times? It might look rather unsatisfactory. What you're doing, from what I can see in your native, is creating a lot of unclosed handles from the clones.

The child plugin cannot close your clone, it doesn't own the handle, and your clone isn't cleaned up by your main plugin, unless you reload the main plugin.

You can fix that, however, by doing the following in your native:
PHP Code:
public int Native_GetReplayData(Handle handlerint numParams)
{
    
Handle playerFrames null;
    
int client GetNativeCell(1);

    if(
gA_PlayerFrames[client] != null)
    {
        
ArrayList copy gA_PlayerFrames[client].Clone();
        
playerFrames CloneHandle(copyplugin);
        
delete copy;
    }

    return 
view_as<int>(playerFrames);

What this does, is:
  1. It clones the player frames array, copying the data
  2. Makes a clone of the copy, however of the reference - not the data, and makes the child plugin the owner of the clone
  3. Deletes the original handle to the copy, so only the child plugin has ownership
  4. Returns the copy which the child plugin owns (or null, if there were no player frames)

This way, the array the child plugin gets, is a clone - changes to it wont affect anything in your main plugin. You own the array and it's data right away from calling the native, it's no different from if you had just created an ArrayList and populated it yourself, so it should be deleted like any handle you create in your own plugin.
Cookies.net is offline
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 05:53.


Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Theme made by Freecode