Skip to content

Commit b50d9ff

Browse files
committed
improve structs again
1 parent 4e1decb commit b50d9ff

8 files changed

Lines changed: 807 additions & 0 deletions

File tree

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package com.jme3.util.struct;
2+
3+
public interface FieldDesc<T> {
4+
5+
int getSize(StructLayout layout, T value);
6+
7+
int getAlignment(StructLayout layout, T value);
8+
9+
void write(StructLayout layout, long address, T value);
10+
11+
T read(StructLayout layout, long address, T store);
12+
13+
}
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
package com.jme3.util.struct;
2+
3+
import com.jme3.math.FastMath;
4+
5+
import java.util.Arrays;
6+
import java.util.LinkedList;
7+
import java.util.List;
8+
9+
public abstract class Struct {
10+
11+
private final List<Field> fields = new LinkedList<>();
12+
private StructLayout layout;
13+
private int size, alignment;
14+
15+
public Struct() {}
16+
17+
public Struct(StructLayout layout, long address) {
18+
read(layout, address);
19+
}
20+
21+
public void write(StructLayout layout, long address) {
22+
setLayout(layout);
23+
for (Field f : fields) {
24+
f.write(layout, address);
25+
}
26+
}
27+
28+
public void read(StructLayout layout, long address) {
29+
setLayout(layout);
30+
for (Field f : fields) {
31+
f.read(layout, address);
32+
}
33+
}
34+
35+
protected void addFields(Field... fields) {
36+
this.fields.addAll(Arrays.asList(fields));
37+
}
38+
39+
public void setLayout(StructLayout layout) {
40+
if (this.layout == layout) {
41+
return;
42+
}
43+
this.layout = layout;
44+
size = 0;
45+
alignment = Float.BYTES * 4;
46+
for (Field f : fields) {
47+
FieldDesc d = layout.getFieldDescription(f.get().getClass());
48+
int align = d.getAlignment(layout, f.get());
49+
f.bind(d, size = FastMath.toMultipleOf(size, align));
50+
size += d.getSize(layout, f.get());
51+
alignment = Math.max(alignment, align);
52+
}
53+
size = FastMath.toMultipleOf(size, alignment);
54+
}
55+
56+
public StructLayout getLayout() {
57+
return layout;
58+
}
59+
60+
public int getSize(StructLayout layout) {
61+
setLayout(layout);
62+
return size;
63+
}
64+
65+
public int getAlignment(StructLayout layout) {
66+
setLayout(layout);
67+
return alignment;
68+
}
69+
70+
public static class Field <T> {
71+
72+
private T value;
73+
private FieldDesc<T> description;
74+
private int offset;
75+
76+
public Field(T value) {
77+
assert value != null : "Struct value cannot be null.";
78+
this.value = value;
79+
}
80+
81+
protected void bind(FieldDesc<T> description, int offset) {
82+
this.description = description;
83+
this.offset = offset;
84+
}
85+
86+
protected void write(StructLayout layout, long structAddress) {
87+
description.write(layout, structAddress + offset, value);
88+
}
89+
90+
protected void read(StructLayout layout, long structAddress) {
91+
value = description.read(layout, structAddress + offset, value);
92+
}
93+
94+
public void set(T value) {
95+
this.value = value;
96+
}
97+
98+
public T get() {
99+
return value;
100+
}
101+
102+
public FieldDesc<T> getDescription() {
103+
return description;
104+
}
105+
106+
public int getOffset() {
107+
return offset;
108+
}
109+
110+
}
111+
112+
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package com.jme3.util.struct;
2+
3+
import com.jme3.vulkan.buffers.BufferMapping;
4+
import com.jme3.vulkan.buffers.MappableBuffer;
5+
import com.jme3.vulkan.memory.MemorySize;
6+
7+
import java.util.Iterator;
8+
import java.util.function.Function;
9+
10+
public class StructBuffer <T extends Struct> implements MappableBuffer, Iterable<T> {
11+
12+
private final StructLayout layout;
13+
private final T[] structs;
14+
private final MappableBuffer buffer;
15+
16+
public StructBuffer(StructLayout layout, T[] structs, Function<MemorySize, MappableBuffer> buffer) {
17+
assert structs.length > 0 : "Struct buffer must contain at least one struct.";
18+
this.layout = layout;
19+
this.structs = structs;
20+
this.buffer = buffer.apply(MemorySize.bytes(structs[0].getSize(layout)));
21+
}
22+
23+
@Override
24+
public BufferMapping map(long offset, long size) {
25+
return buffer.map(offset, size);
26+
}
27+
28+
@Override
29+
public void stage(long offset, long size) {
30+
buffer.stage(offset, size);
31+
}
32+
33+
@Override
34+
public ResizeResult resize(MemorySize size) {
35+
return buffer.resize(size);
36+
}
37+
38+
@Override
39+
public MemorySize size() {
40+
return buffer.size();
41+
}
42+
43+
@Override
44+
public Iterator<T> iterator() {
45+
return new IteratorImpl<>(structs);
46+
}
47+
48+
private static class IteratorImpl <T extends Struct> implements Iterator<T> {
49+
50+
private final T[] array;
51+
private int index = 0;
52+
53+
public IteratorImpl(T[] array) {
54+
this.array = array;
55+
}
56+
57+
@Override
58+
public boolean hasNext() {
59+
return index < array.length;
60+
}
61+
62+
@Override
63+
public T next() {
64+
return array[index++];
65+
}
66+
67+
}
68+
69+
}

0 commit comments

Comments
 (0)