Coder Social home page Coder Social logo

Comments (9)

Y-Less avatar Y-Less commented on June 5, 2024

Absolutely, and to prove it, here is one of several thousands tests of exactly that:

https://github.com/Misiur/YSI-Includes/blob/8bdf76d5a17366e2813b4ec7623913fc4c6590ac/YSI_Data/y_foreach/tests.inc#L2288-L2368

Ignore the excessive spacing - the tests cover all whitespace variants I could think of.

from ysi-includes.

Crayder avatar Crayder commented on June 5, 2024

That's pretty nice, I wish all the small (or huge really) things like this were documented.

Also, how would you clear a player's groups all at once?
Iter_Clear(ObjectGroup[playerid]) or Iter_Clear(ObjectGroup[playerid]<>)

I see that it's the second one, in the tests you do did Iter_Clear(c<>);.

from ysi-includes.

Crayder avatar Crayder commented on June 5, 2024

Another thing.
Given my above example, is there a way to get which of the player's group contains the object without looping through the groups and using Iter_Contains on each of them?

Or given your vehicle examples, is there a way to get which player owns a specified vehicle id?

from ysi-includes.

Y-Less avatar Y-Less commented on June 5, 2024

Yes and no - yes, it can be done in a slightly ugly way, no there's no native way.

Quick background:

An element is NOT in an iterator if its value is <= its index.
An element is in an iterator otherwise, and points to the next item in the iterator.
Elements beyond the apparently declared size of the iterator are start points, so elements that point beyond the end of an array point to their start point.

Thus, the code is something roughly like:

GetStart(Iterator:x<>, elems, value)
{
    if (x[value] <= value) return -1;
    new next;
    while ((next = x[value]) < elems)
    {
        value = next;
    }
    return next - elems;
}

That needs wrapping up nicely though and I can't remember the macros to do so. It still has a loop, but it is a loop from the current element to the end of that element's group, which also happens to be the start.

from ysi-includes.

Y-Less avatar Y-Less commented on June 5, 2024

Try:

#define Iter_GetGroup _ITER<GetGroup>
#define Iter_GetGroup_InternalA(%0,%1,%9)    Iter_GetGroup_InternalC(%1,F@s(%1)-1,%9)
#define Iter_GetGroup_InternalB(%0,%2,%1,%9) Iter_GetGroup_InternalD(%1,F@s(%1),F@s(%1)-F@s(%0),%9)

stock Iter_GetGroup_InternalC(array[], size, value)
{
    // For standard iterators it is either in the first slot (0) or none (-1).
    return (0 <= value < size && array[value] > value) ? 0 : -1;
}

stock Iter_GetGroup_InternalD(array[], trueSize, size, value)
{
    if (0 <= value < size && array[value] > value)
    {
        // Find the end of this list.
        while ((value = array[value]) < size) {}
        // Start points are actually backwards.
        return trueSize - value - 1;
    }
    return -1;
}

from ysi-includes.

Y-Less avatar Y-Less commented on June 5, 2024

I'm pretty sure that you have to call that code in a similar manner to Iter_Clear, i.e. WITH the <> given explicitly so that the compiler knows which to use:

Iter_GetGroup(MyIter<>, value);

However, there is another way maybe...

#define Iter_GetGroup _ITER<GetGroup>
#define Iter_GetGroup_InternalA(%0,%1,%9)    Iter_GetGroup_Internal(%1,F@s(%1),F@s(%1)-F@s(%0),%9)
#define Iter_GetGroup_InternalB(%0,%2,%1,%9) Iter_GetGroup_Internal(%1,F@s(%1),F@s(%1)-F@s(%0),%9)

stock Iter_GetGroup_Internal(array[], trueSize, size, value)
{
    if (0 <= value < size && array[value] > value)
    {
        // Find the end of this list.
        while ((value = array[value]) < size) {}
        // Start points are actually backwards.
        return trueSize - value - 1;
    }
    return -1;
}

That will unify both, so you can just do:

Iter_GetGroup(MyIter, value);

Regardless of whether it is a multi-iterator or not, but I'm not sure if that is a good idea or not - everything else is explicit in their calls.

Edit: Actually, with this code EITHER method will work - MyIter AND MyIter<>.

from ysi-includes.

Crayder avatar Crayder commented on June 5, 2024

So it would be like this to remove an object if it is in one of the player's group, for my first example:

new cGroup = Iter_GetGroup(ObjectGroup[playerid]<>, objectid);
if(cGroup != -1)
    Iter_Remove(ObjectGroup[playerid]<cGroup>, objectid);

Maybe you could add an InternalB wrapper for Iter_Remove that does the above for multi-iterators.

On a completely separate subject, sometimes when I reload a filterscript I an (sometimes two, but usually one) y_malloc error. It's something about CallLocalFunction, remote possibility, and corruption. I'll look it up now to show exactly what it is. EDIT: https://github.com/Misiur/YSI-Includes/blob/f4d85a8d1c7552618c0546d3f93d5ef625ed59c5/YSI_Coding/y_malloc/heapalloc.inc#L249

from ysi-includes.

Crayder avatar Crayder commented on June 5, 2024

In addition to the Iter_GetGroup function above (which I hope @Misiur adds), is there a way to get a free "group?"

from ysi-includes.

Y-Less avatar Y-Less commented on June 5, 2024
  1. I still don't like the name Iter_GetGroup - it is very confusing given that YSI already has groups and they are nothing to do with this. Iter_GetMulti or Iter_GetStart maybe...

  2. Yes:

#define Iter_FreeMulti _ITER<FreeMulti>
#define Iter_FreeMulti_InternalA(%0,%1)    Iter_FreeMulti_Internal(%1,F@s(%1),F@s(%1)-F@s(%0))
#define Iter_FreeMulti_InternalB(%0,%2,%1) Iter_FreeMulti_Internal(%1,F@s(%1),F@s(%1)-F@s(%0))

stock Iter_FreeMulti_Internal(array[], trueSize, start)
{
    for (new i = 0; trueSize-- > start; ++i)
    {
        if (array[trueSize] >= start)
            return i;
    }
    return -1;
}

#define Iter_GetMulti _ITER<GetMulti>
#define Iter_GetMulti_InternalA(%0,%1,%9)    Iter_GetMulti_Internal(%1,F@s(%1),F@s(%1)-F@s(%0),%9)
#define Iter_GetMulti_InternalB(%0,%2,%1,%9) Iter_GetMulti_Internal(%1,F@s(%1),F@s(%1)-F@s(%0),%9)

stock Iter_GetMulti_Internal(array[], trueSize, size, value)
{
    if (0 <= value < size && array[value] > value)
    {
        // Find the end of this list.
        while ((value = array[value]) < size) {}
        // Start points are actually backwards.
        return trueSize - value - 1;
    }
    return -1;
}

You really need to learn the internals - I'm not going to keep doing this and there's more than enough information about now...

from ysi-includes.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.