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

Migrate CDataPack from a Compact Cassette tape. #688

Merged
merged 5 commits into from Dec 30, 2017

Conversation

@KyleSanderson
Copy link
Member

KyleSanderson commented Sep 19, 2017

This lift and shifts CDataPack from a linear datatype to something using a vector with type mixed in. Iterators will change (again), so plugins manually using SetPackPosition without ReadPackPosition (against the API) will experience breakage; if this even builds.

@KyleSanderson KyleSanderson force-pushed the tapedeck branch from a507ab7 to 1972508 Sep 19, 2017
@KyleSanderson KyleSanderson requested a review from Fyren Sep 20, 2017
@Headline

This comment has been minimized.

Copy link
Member

Headline commented Sep 20, 2017

Floats seem to show 0.0 on ReadFloat.

public void OnPluginStart()
{
	int integer = 32;
	float floatingPoint = 32.0;
	char[] string = "Hello.";
	
	DataPack pack = new DataPack();
	
	pack.WriteCell(integer);
	pack.WriteFloat(floatingPoint);
	pack.WriteString(string);
	
	DataPackPos pos = pack.Position;
	
	pack.Reset();
	
	int integer2;
	float floatingPoint2;
	char string2[8];
	
	integer2 = pack.ReadCell();
	floatingPoint2 = pack.ReadFloat();
	pack.ReadString(string2, sizeof(string2));
	
	PrintToServer("int: %i, float: %.2f, string: %s, pos: %i",
					integer2,
					floatingPoint2,
					string2,
					pos);
	
	

	delete pack;
}

Output:

int: 32, float: 0.00, string: Hello., pos: 1
[SM] Plugin testcase.smx reloaded successfully.
Tested-By: Headline22.
@KyleSanderson KyleSanderson force-pushed the tapedeck branch from 5570cda to 35420d6 Sep 20, 2017
@Headline

This comment has been minimized.

Copy link
Member

Headline commented Sep 20, 2017

So the test case for DataPack operations seems to work as expected now. Added errors for invalid type works great too.

👍 From me

Test case
public void OnPluginStart()
{
	int integer = 32;
	float floatingPoint = 32.0;
	char[] string = "Hello.";
	
	DataPack pack = new DataPack();
	
	pack.WriteCell(integer);
	pack.WriteFloat(floatingPoint);
	pack.WriteString(string);
		
	pack.Reset();
	
	int integer2;
	float floatingPoint2;
	char string2[8];
	
	integer2 = pack.ReadCell();
	floatingPoint2 = pack.ReadFloat();
	
	pack.ReadString(string2, sizeof(string2));
	
	PrintToServer("int: %i, float: %.2f, string: %s",
					integer2,
					floatingPoint2,
					string2);
	
	char string3[8];
	PrintToServer("%i", pack.Position);
	pack.Position--; // go back to string
	PrintToServer("%i", pack.Position);

	pack.ReadString(string3, sizeof(string3));
	PrintToServer("%s", string3);
	
	delete pack;
}
Actual output
int: 32, float: 32.00, string: Hello.
3
2
Hello.
[SM] Plugin testcase.smx reloaded successfully.
@KyleSanderson KyleSanderson requested a review from asherkin Sep 20, 2017
Copy link
Contributor

Fyren left a comment

In theory, I think we want an IDataPack2. IsReadable's semantics basically assume the one contiguous block of memory model and this has pretty different performance characteristics.

In practice, do we care? Does any extension even use this?

typedef union {
cell_t cval;
float fval;
void *vval;

This comment has been minimized.

Copy link
@Fyren

Fyren Oct 3, 2017

Contributor

This should definitely not be a void*, as mentioned in IRC. An AString* and a uint8_t* if raw is kept, otherwise just the AString*. This allows you to get rid of the casts.

{
return pContext->ThrowNativeError("DataPack operation is out of bounds.");
}

if (pDataPack->GetCurrentType() != CDataPackType::Cell)
{
return pContext->ThrowNativeError("Invalid Datapack Type (got %d / expected %d).", pDataPack->GetCurrentType(), CDataPackType::Cell);

This comment has been minimized.

Copy link
@Fyren

Fyren Oct 3, 2017

Contributor

Please check all the error messages for consistency, including the ones you didn't touch. The docs use "data pack" and errors shouldn't be in title case but normal sentence case.

I'd also recommend prettifying the enum types for the user so they see names and not the integer value of the enum. Lots (most? all?) of our other errors don't do anything like that, so it's definitely not required.

}

void CDataPack::ResetSize()
{
m_size = 0;
this->Initialize();
}

size_t CDataPack::CreateMemory(size_t size, void **addr)

This comment has been minimized.

Copy link
@Fyren

Fyren Oct 3, 2017

Contributor

Do we even know if a single person is using the generic/raw memory functions? This functionality is not exposed to plugins, so it'd have to be an extension. I'd be in favor of axing these completely. (Since they're in the interface, just make them no-ops/return null.)

If they're kept, the docs in IDataPack.h about pointers being invalidated (in the case of realloc) are wrong and should be updated.

You also alloc a byte more than necessary? Did you mean to store the size here (originally stored as 32-bits)? Related to the behavior change I mention for ReadMemory?


size_t real_len = *(size_t *)m_curptr;
if (!this->IsReadable())
return "";

This comment has been minimized.

Copy link
@Fyren

Fyren Oct 3, 2017

Contributor

The API says "pointer to the string, or NULL if out of bounds," so the old behavior seems correct to me. We should actually use nullptr now, though (and switch any other uses in the file as well).

return NULL;
}
if (this->elements[this->position].type != CDataPackType::String)
return "";

This comment has been minimized.

Copy link
@Fyren

Fyren Oct 3, 2017

Contributor

The API doesn't say what would happen in this case, but the old behavior was to return NULL, so I'd also make it nullptr.

if (this->elements[this->position].type != CDataPackType::Raw)
return nullptr;

return this->elements[this->position].pData.vval;
}

void *CDataPack::ReadMemory(size_t *size) const

This comment has been minimized.

Copy link
@Fyren

Fyren Oct 3, 2017

Contributor

Behavior here appears to have changed? The old behavior checked the stored size was <= the requested size and returned null if it wasn't. It also returned the real size of the memory chunk, which you haven't stored.

m_pBase = (char *)malloc(DATAPACK_INITIAL_SIZE);
m_capacity = DATAPACK_INITIAL_SIZE;
Initialize();
this->Initialize();

This comment has been minimized.

Copy link
@Fyren

Fyren Oct 3, 2017

Contributor

Style: Why are you using this-> everywhere? SM code in general doesn't appear to use this style.

void CDataPack::CheckSize(size_t typesize)
{
if (m_curptr - m_pBase + typesize <= m_capacity)
for (size_t iter = 0; iter < this->elements.length(); ++iter)

This comment has been minimized.

Copy link
@Fyren

Fyren Oct 3, 2017

Contributor

Style: this isn't an iterator, it's an index.

m_curptr += real_len + 1;

return str;
return val.chars();
}

void *CDataPack::GetMemory() const

This comment has been minimized.

Copy link
@Fyren

Fyren Oct 3, 2017

Contributor

This is not the same behavior. The analogue in the new implementation would be returning the address of the InternalPack. However, I don't see how/why anyone would ever use this function because the pointer is opaque to the user.

m_curptr += sizeof(float);
return val;

return this->elements[this->position++].pData.fval;
}

bool CDataPack::IsReadable(size_t bytes) const

This comment has been minimized.

Copy link
@Fyren

Fyren Oct 3, 2017

Contributor

The docs here utterly suck. The imply the old implementation and so this is not really satisfiable with the new one.

@KyleSanderson KyleSanderson force-pushed the tapedeck branch from d076236 to 6a16ddc Oct 3, 2017
@KyleSanderson KyleSanderson merged commit 5f5a6b3 into master Dec 30, 2017
2 checks passed
2 checks passed
continuous-integration/appveyor/pr AppVeyor build succeeded
Details
continuous-integration/travis-ci/pr The Travis CI build passed
Details
@CrazyHackGUT CrazyHackGUT referenced this pull request Jan 19, 2018
@asherkin asherkin deleted the tapedeck branch Feb 2, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants
You can’t perform that action at this time.