Skip to content

Commit

Permalink
entity: add sorting functions
Browse files Browse the repository at this point in the history
Signed-off-by: Matthias Gatto <[email protected]>
  • Loading branch information
cosmo-ray committed Jun 24, 2024
1 parent e46cfd4 commit 13ee1cc
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 23 deletions.
92 changes: 92 additions & 0 deletions core/entity/entity.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <unistd.h>

#include "entity.h"
#include "entity-script.h"
#include "utils.h"
#include "stack.h"
#include "script.h"
Expand Down Expand Up @@ -1971,6 +1972,97 @@ int yeIsPureArray(Entity *e)
return 1;
}

int yeDumbSort(Entity *a, Entity *func, int start)
{
int have_change;

do {
int last = yeLen(a) - 1;
have_change = 0;

for (int i = start; i < last; ++i) {
int i2 = i + 1;

int cmp = (intptr_t)yesCall(func, yeGet(a, i),
yeGet(a, i2));
if (cmp > 0) {
yeSwapByIdx(a, i, i2);
have_change = 1;
}
}
} while (have_change);
return 0;
}

static void yeQuickSort_pivot(Entity *array, Entity *func, int start, int last)
{
if (last <= start)
return;
int pivot = start + (last - start) / 2;

if (pivot <= start)
return;

Entity *pivot_ent = yeGet(array, pivot);
yeSwapByIdx(array, pivot, last);
int pivot_left = start - 1;
int pivot_right = start - 1;
do
{
++pivot_right;
int cmp = (intptr_t)yesCall(func, yeGet(array, pivot_right), pivot_ent);
if (cmp <= 0) {
++pivot_left;
if (pivot_left == pivot_right)
continue;
int cmp = (intptr_t)yesCall(func, yeGet(array, pivot_left), yeGet(array, pivot_right));
if (cmp > 0) {
yeSwapByIdx(array, pivot_right, pivot_left);
}
}
} while (pivot_right + 1 < last);
yeSwapByIdx(array, last, pivot_left + 1);
yeQuickSort_pivot(array, func, start, pivot);
yeQuickSort_pivot(array, func, pivot, last);
}

int yeQuickSort(Entity *array, Entity *func, int start)
{
int last = yeLen(array) - 1;

start = start < 1 ? 0 : start;

yeQuickSort_pivot(array, func, start, last);
return 0;
}

int yeShuffle(Entity *array)
{
if (!array || yeType(array) != YARRAY)
return -1;

int array_l = yeLen(array);
for (int i = 0; i < array_l; ++i) {
int b = yuiRand() % array_l;

if (i == b)
continue;

yeSwapByIdx(array, i, b);
}

for (int i = 0; i < array_l; ++i) {
int a = yuiRand() % array_l;
int b = yuiRand() % array_l;

if (a == b)
continue;
yeSwapByIdx(array, a, b);
}
return 0;
}


#undef YE_DECR_REF

#undef YE_DESTROY_ENTITY
Expand Down
2 changes: 2 additions & 0 deletions core/script/binding.c
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,8 @@ BIND_EII(ywCanvasForceSizeXY, 3, 0);

BIND_EES(yePushFront, 2, 1);

BIND_EEI(yeQuickSort, 2, 1);

BIND_EEI(ywRectContainPos, 3, 0);

BIND_EEI(yeMergeInto, 3, 0);
Expand Down
4 changes: 4 additions & 0 deletions core/script/tcc-syms.c
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,10 @@ void tccAddSyms(TCCState *l)
ADD_SYM(ywCanvasHFlip);
ADD_SYM(ygCallInt);
ADD_SYM(ygGetProgramArg);
ADD_SYM(yeQuickSort);
ADD_SYM(yeDumbSort);
ADD_SYM(yeShuffle);

#if defined(__unix__) || defined(__APPLE__)
tcc_add_symbol(l, "yuiDebugPrint", yuiDebugPrint);
ADD_SYM(fprintf);
Expand Down
37 changes: 14 additions & 23 deletions include/yirl/entity.h
Original file line number Diff line number Diff line change
Expand Up @@ -1880,31 +1880,22 @@ NO_SIDE_EFFECT static inline Entity *yeGetRandomElem(Entity *array)
return yeGet(array, yuiRand() % array_l);
}

static inline int yeShuffle(Entity *array)
{
if (!array || yeType(array) != YARRAY)
return -1;

int array_l = yeLen(array);
for (int i = 0; i < array_l; ++i) {
int b = yuiRand() % array_l;

if (i == b)
continue;

yeSwapByIdx(array, i, b);
}
/**
* @brief Quick Sort an array, or part of it
* @param func comparison function which returns a negative integer value
* if the first argument is less than the second,
* a positive integer value if the first argument is greater than the second
* and zero if the arguments are equivalent.
*/
int yeQuickSort(Entity *array, Entity *func, int start);

for (int i = 0; i < array_l; ++i) {
int a = yuiRand() % array_l;
int b = yuiRand() % array_l;
/**
* Dumb Sort, is generally slower than QuickSort, exept in the case where a few element are swap
* I use it for debug at first, but because in a few case it can be faster, I let it here
*/
int yeDumbSort(Entity *a, Entity *func, int start);

if (a == b)
continue;
yeSwapByIdx(array, a, b);
}
return 0;
}
int yeShuffle(Entity *array);

/**
* @return 1 if content of a and b is the same, work only for string, int and float
Expand Down

0 comments on commit 13ee1cc

Please sign in to comment.