|
|
@@ -1002,28 +1002,23 @@ static void register_array2d_view(py_Ref mod) {
|
|
|
#include "pocketpy/xmacros/smallmap.h"
|
|
|
#undef SMALLMAP_T__SOURCE
|
|
|
|
|
|
-static py_TValue* c11_chunked_array2d__new_chunk(c11_chunked_array2d* self, c11_vec2i pos) {
|
|
|
-#ifndef NDEBUG
|
|
|
+static py_TValue* c11_chunked_array2d__new_chunk(c11_chunked_array2d* self, c11_vec2i pos, py_Ref context) {
|
|
|
bool exists = c11_chunked_array2d_chunks__contains(&self->chunks, pos);
|
|
|
- assert(!exists);
|
|
|
-#endif
|
|
|
+ if(exists) {
|
|
|
+ ValueError("chunk already exists at pos (%d, %d)", pos.x, pos.y);
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
int chunk_numel = self->chunk_size * self->chunk_size + 1;
|
|
|
py_TValue* data = PK_MALLOC(sizeof(py_TValue) * chunk_numel);
|
|
|
- if(!py_isnone(&self->context_builder)) {
|
|
|
- py_newvec2i(&data[0], pos);
|
|
|
- bool ok = py_call(&self->context_builder, 1, &data[0]);
|
|
|
- if(!ok) {
|
|
|
- PK_FREE(data);
|
|
|
- return NULL;
|
|
|
- }
|
|
|
- data[0] = *py_retval();
|
|
|
- } else {
|
|
|
- data[0] = *py_None();
|
|
|
- }
|
|
|
+ data[0] = *context;
|
|
|
memset(&data[1], 0, sizeof(py_TValue) * (chunk_numel - 1));
|
|
|
c11_chunked_array2d_chunks__set(&self->chunks, pos, data);
|
|
|
self->last_visited.key = pos;
|
|
|
self->last_visited.value = data;
|
|
|
+ // init data with default value
|
|
|
+ for(int i = 1; i < chunk_numel; i++) {
|
|
|
+ data[i] = self->default_T;
|
|
|
+ }
|
|
|
return data;
|
|
|
}
|
|
|
|
|
|
@@ -1077,37 +1072,34 @@ static py_TValue* c11_chunked_array2d__parse_col_row(c11_chunked_array2d* self,
|
|
|
py_Ref c11_chunked_array2d__get(c11_chunked_array2d* self, int col, int row) {
|
|
|
c11_vec2i chunk_pos, local_pos;
|
|
|
py_TValue* data = c11_chunked_array2d__parse_col_row(self, col, row, &chunk_pos, &local_pos);
|
|
|
- if(data == NULL) return &self->default_T;
|
|
|
- py_Ref retval = &data[1 + local_pos.y * self->chunk_size + local_pos.x];
|
|
|
- if(py_isnil(retval)) return &self->default_T;
|
|
|
- return retval;
|
|
|
+ if(data == NULL) return NULL;
|
|
|
+ return &data[1 + local_pos.y * self->chunk_size + local_pos.x];
|
|
|
}
|
|
|
|
|
|
bool c11_chunked_array2d__set(c11_chunked_array2d* self, int col, int row, py_Ref value) {
|
|
|
c11_vec2i chunk_pos, local_pos;
|
|
|
py_TValue* data = c11_chunked_array2d__parse_col_row(self, col, row, &chunk_pos, &local_pos);
|
|
|
if(data == NULL) {
|
|
|
- data = c11_chunked_array2d__new_chunk(self, chunk_pos);
|
|
|
- if(data == NULL) return false;
|
|
|
+ if(self->auto_add_chunk) {
|
|
|
+ data = c11_chunked_array2d__new_chunk(self, chunk_pos, py_None());
|
|
|
+ if(data == NULL) return false;
|
|
|
+ } else {
|
|
|
+ return IndexError("(%d, %d) is out of bounds and !auto_add_chunk", col, row);
|
|
|
+ }
|
|
|
}
|
|
|
data[1 + local_pos.y * self->chunk_size + local_pos.x] = *value;
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
-static void c11_chunked_array2d__del(c11_chunked_array2d* self, int col, int row) {
|
|
|
- c11_vec2i chunk_pos, local_pos;
|
|
|
- py_TValue* data = c11_chunked_array2d__parse_col_row(self, col, row, &chunk_pos, &local_pos);
|
|
|
- if(data != NULL) data[1 + local_pos.y * self->chunk_size + local_pos.x] = *py_NIL();
|
|
|
-}
|
|
|
-
|
|
|
static bool chunked_array2d__new__(int argc, py_Ref argv) {
|
|
|
PY_CHECK_ARGC(4);
|
|
|
PY_CHECK_ARG_TYPE(1, tp_int);
|
|
|
+ PY_CHECK_ARG_TYPE(3, tp_bool);
|
|
|
py_Type cls = py_totype(argv);
|
|
|
c11_chunked_array2d* self = py_newobject(py_retval(), cls, 0, sizeof(c11_chunked_array2d));
|
|
|
int chunk_size = py_toint(&argv[1]);
|
|
|
self->default_T = argv[2];
|
|
|
- self->context_builder = argv[3];
|
|
|
+ self->auto_add_chunk = py_tobool(&argv[3]);
|
|
|
c11_chunked_array2d_chunks__ctor(&self->chunks);
|
|
|
self->chunk_size = chunk_size;
|
|
|
switch(chunk_size) {
|
|
|
@@ -1137,26 +1129,13 @@ static bool chunked_array2d_chunk_size(int argc, py_Ref argv) {
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
-static bool chunked_array2d_default(int argc, py_Ref argv) {
|
|
|
- PY_CHECK_ARGC(1);
|
|
|
- c11_chunked_array2d* self = py_touserdata(argv);
|
|
|
- py_assign(py_retval(), &self->default_T);
|
|
|
- return true;
|
|
|
-}
|
|
|
-
|
|
|
-static bool chunked_array2d_context_builder(int argc, py_Ref argv) {
|
|
|
- PY_CHECK_ARGC(1);
|
|
|
- c11_chunked_array2d* self = py_touserdata(argv);
|
|
|
- py_assign(py_retval(), &self->context_builder);
|
|
|
- return true;
|
|
|
-}
|
|
|
-
|
|
|
static bool chunked_array2d__getitem__(int argc, py_Ref argv) {
|
|
|
PY_CHECK_ARGC(2);
|
|
|
PY_CHECK_ARG_TYPE(1, tp_vec2i);
|
|
|
c11_chunked_array2d* self = py_touserdata(argv);
|
|
|
c11_vec2i pos = py_tovec2i(&argv[1]);
|
|
|
py_Ref res = c11_chunked_array2d__get(self, pos.x, pos.y);
|
|
|
+ if(res == NULL) return IndexError("(%d, %d) is out of bounds", pos.x, pos.y);
|
|
|
py_assign(py_retval(), res);
|
|
|
return true;
|
|
|
}
|
|
|
@@ -1172,16 +1151,6 @@ static bool chunked_array2d__setitem__(int argc, py_Ref argv) {
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
-static bool chunked_array2d__delitem__(int argc, py_Ref argv) {
|
|
|
- PY_CHECK_ARGC(2);
|
|
|
- PY_CHECK_ARG_TYPE(1, tp_vec2i);
|
|
|
- c11_chunked_array2d* self = py_touserdata(argv);
|
|
|
- c11_vec2i pos = py_tovec2i(&argv[1]);
|
|
|
- c11_chunked_array2d__del(self, pos.x, pos.y);
|
|
|
- py_newnone(py_retval());
|
|
|
- return true;
|
|
|
-}
|
|
|
-
|
|
|
static bool chunked_array2d__iter__(int argc, py_Ref argv) {
|
|
|
PY_CHECK_ARGC(1);
|
|
|
c11_chunked_array2d* self = py_touserdata(argv);
|
|
|
@@ -1258,13 +1227,13 @@ static bool chunked_array2d_world_to_chunk(int argc, py_Ref argv) {
|
|
|
}
|
|
|
|
|
|
static bool chunked_array2d_add_chunk(int argc, py_Ref argv) {
|
|
|
- PY_CHECK_ARGC(2);
|
|
|
+ PY_CHECK_ARGC(3);
|
|
|
PY_CHECK_ARG_TYPE(1, tp_vec2i);
|
|
|
c11_chunked_array2d* self = py_touserdata(argv);
|
|
|
c11_vec2i pos = py_tovec2i(&argv[1]);
|
|
|
- py_TValue* data = c11_chunked_array2d__new_chunk(self, pos);
|
|
|
+ py_TValue* data = c11_chunked_array2d__new_chunk(self, pos, &argv[2]);
|
|
|
if(data == NULL) return false;
|
|
|
- py_assign(py_retval(), &data[0]); // context
|
|
|
+ py_newnone(py_retval());
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
@@ -1313,7 +1282,7 @@ static bool chunked_array2d_get_context(int argc, py_Ref argv) {
|
|
|
c11_vec2i pos = py_tovec2i(&argv[1]);
|
|
|
py_TValue* data = c11_chunked_array2d_chunks__get(&self->chunks, pos, NULL);
|
|
|
if(data == NULL) {
|
|
|
- py_newnone(py_retval());
|
|
|
+ return IndexError("no chunk found at (%d, %d)", pos.x, pos.y);
|
|
|
} else {
|
|
|
py_assign(py_retval(), &data[0]);
|
|
|
}
|
|
|
@@ -1328,7 +1297,6 @@ void c11_chunked_array2d__dtor(c11_chunked_array2d* self) {
|
|
|
void c11_chunked_array2d__mark(void* ud, c11_vector* p_stack) {
|
|
|
c11_chunked_array2d* self = ud;
|
|
|
pk__mark_value(&self->default_T);
|
|
|
- pk__mark_value(&self->context_builder);
|
|
|
int chunk_numel = self->chunk_size * self->chunk_size + 1;
|
|
|
for(int i = 0; i < self->chunks.length; i++) {
|
|
|
py_TValue* data = c11__getitem(c11_chunked_array2d_chunks_KV, &self->chunks, i).value;
|
|
|
@@ -1408,16 +1376,13 @@ static void register_chunked_array2d(py_Ref mod) {
|
|
|
assert(type == tp_chunked_array2d);
|
|
|
|
|
|
py_bind(py_tpobject(type),
|
|
|
- "__new__(cls, chunk_size, default=None, context_builder=None)",
|
|
|
+ "__new__(cls, chunk_size, default=None, auto_add_chunk=True)",
|
|
|
chunked_array2d__new__);
|
|
|
|
|
|
py_bindproperty(type, "chunk_size", chunked_array2d_chunk_size, NULL);
|
|
|
- py_bindproperty(type, "default", chunked_array2d_default, NULL);
|
|
|
- py_bindproperty(type, "context_builder", chunked_array2d_context_builder, NULL);
|
|
|
|
|
|
py_bindmagic(type, __getitem__, chunked_array2d__getitem__);
|
|
|
py_bindmagic(type, __setitem__, chunked_array2d__setitem__);
|
|
|
- py_bindmagic(type, __delitem__, chunked_array2d__delitem__);
|
|
|
py_bindmagic(type, __iter__, chunked_array2d__iter__);
|
|
|
py_bindmagic(type, __len__, chunked_array2d__len__);
|
|
|
|