Spaces:
Sleeping
Sleeping
| <% | |
| const { | |
| className, | |
| members, | |
| size, | |
| usedTypes | |
| } = locals | |
| const StructArrayLayoutClass = className; | |
| -%> | |
| /** | |
| * Implementation of the StructArray layout: | |
| <% | |
| for (const member of members) { | |
| -%> | |
| * [<%=member.offset%>]: <%=member.type%>[<%=member.components%>] | |
| <% | |
| } | |
| -%> | |
| * | |
| * @private | |
| */ | |
| class <%=StructArrayLayoutClass%> extends StructArray { | |
| <% | |
| for (const type of usedTypes) { | |
| -%> | |
| <%=type.toLowerCase()%>: <%=type%>Array; | |
| <% | |
| } | |
| -%> | |
| _refreshViews() { | |
| <% | |
| for (const type of usedTypes) { | |
| -%> | |
| this.<%=type.toLowerCase()%> = new <%=type%>Array(this.arrayBuffer); | |
| <% | |
| } | |
| -%> | |
| } | |
| <% | |
| // prep for emplaceBack: collect type sizes and count the number of arguments | |
| // we'll need | |
| const bytesPerElement = size; | |
| const usedTypeSizes = []; | |
| const argNames = []; | |
| const argNamesTyped = []; | |
| for (const member of members) { | |
| if (usedTypeSizes.indexOf(member.size) < 0) { | |
| usedTypeSizes.push(member.size); | |
| } | |
| for (let c = 0; c < member.components; c++) { | |
| // arguments v0, v1, v2, ... are, in order, the components of | |
| // member 0, then the components of member 1, etc. | |
| const name = `v${argNames.length}`; | |
| argNames.push(name); | |
| argNamesTyped.push(`${name}: number`); | |
| } | |
| } | |
| -%> | |
| emplaceBack(<%=argNamesTyped.join(', ')%>) { | |
| const i = this.length; | |
| this.resize(i + 1); | |
| return this.emplace(i, <%=argNames.join(', ')%>); | |
| } | |
| emplace(i: number, <%=argNamesTyped.join(', ')%>) { | |
| <% | |
| { | |
| for (const size of usedTypeSizes) { | |
| -%> | |
| const o<%=size.toFixed(0)%> = i * <%=(bytesPerElement / size).toFixed(0)%>; | |
| <% | |
| } | |
| let argIndex = 0; | |
| for (const member of members) { | |
| for (let c = 0; c < member.components; c++) { | |
| // The index for `member` component `c` into the appropriate type array is: | |
| // this.{TYPE}[o{SIZE} + MEMBER_OFFSET + {c}] = v{X} | |
| // where MEMBER_OFFSET = ROUND(member.offset / size) is the per-element | |
| // offset of this member into the array | |
| const index = `o${member.size.toFixed(0)} + ${(member.offset / member.size + c).toFixed(0)}`; | |
| -%> | |
| this.<%=member.view%>[<%=index%>] = v<%=argIndex++%>; | |
| <% | |
| } | |
| } | |
| } | |
| -%> | |
| return i; | |
| } | |
| -%> | |
| } | |
| <%=StructArrayLayoutClass%>.prototype.bytesPerElement = <%= size %>; | |
| register('<%=StructArrayLayoutClass%>', <%=StructArrayLayoutClass%>); | |