internal
| 1532 | |
| 1533 | // internal |
| 1534 | void CScriptArray::CopyBuffer(SArrayBuffer* dst, SArrayBuffer* src) |
| 1535 | { |
| 1536 | asIScriptEngine* engine = objType->GetEngine(); |
| 1537 | if (subTypeId & asTYPEID_OBJHANDLE) { |
| 1538 | // Copy the references and increase the reference counters |
| 1539 | if (dst->numElements > 0 && src->numElements > 0) { |
| 1540 | std::int32_t count = dst->numElements > src->numElements ? src->numElements : dst->numElements; |
| 1541 | |
| 1542 | void** max = (void**)(dst->data + count * sizeof(void*)); |
| 1543 | void** d = (void**)dst->data; |
| 1544 | void** s = (void**)src->data; |
| 1545 | |
| 1546 | for (; d < max; d++, s++) { |
| 1547 | void* tmp = *d; |
| 1548 | *d = *s; |
| 1549 | if (*d) { |
| 1550 | engine->AddRefScriptObject(*d, objType->GetSubType()); |
| 1551 | } |
| 1552 | // Release the old ref after incrementing the new to avoid problem incase it is the same ref |
| 1553 | if (tmp) { |
| 1554 | engine->ReleaseScriptObject(tmp, objType->GetSubType()); |
| 1555 | } |
| 1556 | } |
| 1557 | } |
| 1558 | } else { |
| 1559 | if (dst->numElements > 0 && src->numElements > 0) { |
| 1560 | std::int32_t count = dst->numElements > src->numElements ? src->numElements : dst->numElements; |
| 1561 | if (subTypeId & asTYPEID_MASK_OBJECT) { |
| 1562 | // Call the assignment operator on all of the objects |
| 1563 | void** max = (void**)(dst->data + count * sizeof(void*)); |
| 1564 | void** d = (void**)dst->data; |
| 1565 | void** s = (void**)src->data; |
| 1566 | |
| 1567 | asITypeInfo* subType = objType->GetSubType(); |
| 1568 | if (subType->GetFlags() & asOBJ_ASHANDLE) { |
| 1569 | // For objects that should work as handles we must use the opHndlAssign method |
| 1570 | // TODO: Must support alternative syntaxes as well |
| 1571 | // TODO: Move the lookup of the opHndlAssign method to Precache() so it is only done once |
| 1572 | String decl = StringView(subType->GetName()) + "& opHndlAssign(const "_s + StringView(subType->GetName()) + "&in)"_s; |
| 1573 | asIScriptFunction* func = subType->GetMethodByDecl(decl.data()); |
| 1574 | if (func) { |
| 1575 | // TODO: Reuse active context if existing |
| 1576 | asIScriptContext* ctx = engine->RequestContext(); |
| 1577 | for (; d < max; d++, s++) { |
| 1578 | ctx->Prepare(func); |
| 1579 | ctx->SetObject(*d); |
| 1580 | ctx->SetArgAddress(0, *s); |
| 1581 | // TODO: Handle errors |
| 1582 | ctx->Execute(); |
| 1583 | } |
| 1584 | engine->ReturnContext(ctx); |
| 1585 | } else { |
| 1586 | // opHndlAssign doesn't exist, so try ordinary value assign instead |
| 1587 | for (; d < max; d++, s++) { |
| 1588 | engine->AssignScriptObject(*d, *s, subType); |
| 1589 | } |
| 1590 | } |
| 1591 | } else |