AssemblyScript - Linear Nested Class Layout - class

I'm working on a linear data layout where components are alongside each other in memory. Things were going ok until I realized I don't have a way for making offsetof and changetype calls when dealing with nested classes.
For instance, this works as intended:
class Vec2{
x:u8
y:u8
}
const size = offsetof<Vec2>() // 2 -- ok
const ptr = heap.alloc(size)
changeType<Vec2>(ptr).x = 7 // memory = [7,0] -- ok
Naturally this approach fails when nesting classes
class Player{
position:Vec2
health:u8
}
const size = offsetof<Player>() //5 -- want 3, position is a pointer
const ptr = heap.alloc(size)
changeType<Player>(ptr).position.x = 7 //[0,0,0,0,0] -- want [7,0,0], instead accidentally changed pointer 0
The goal is for the memory layout to look like this:
| Player 1 | Player 2 | ...
| x y z h | x y z h |
Ideally I'd love to be able to create 'value-type' fields, or if this isnt a thing, are there alternative approaches?
I'm hoping to avoid extensive boilerplate whenever writing a new component, ie manual size calculation and doing a changetype for each field at its offset etc.

In case anybody is interested I'll post my current solution here. The implementation is a little messy but is certainly automatable using custom scripts or compiler transforms.
Goal: Create a linear proxy for the following class so that the main function behaves as expected:
class Foo {
position: Vec2
health: u8
}
export function main(): Info {
const ptr = heap.alloc(FooProxy.size)
const foo = changetype<FooProxy>(ptr)
foo.health = 3
foo.position.x = 9
foo.position.y = 10
}
Solution: calculate offsets and alignments for each field.
class TypeMetadataBase{
get align():u32{return 0}
get offset():u32{return 0}
}
class TypeMetadata<T> extends TypeMetadataBase{
get align():u32{return alignof<T>()}
get offset():u32{return offsetof<T>()}
constructor(){
super()
if(this.offset == 0)
throw new Error('offset shouldnt be zero, for primitive types use PrimitiveMetadata')
}
};
class PrimitiveMetadata<T> extends TypeMetadataBase{
get align():u32{return sizeof<T>()}
get offset():u32{return sizeof<T>()}
};
class LinearSchema{
metadatas:StaticArray<TypeMetadataBase>
size:u32
offsets:StaticArray<u32>
constructor(metadatas:StaticArray<TypeMetadataBase>){
let align:u32 = 0
const offsets = new StaticArray<u32>(metadatas.length)
for (let i = 0; i < metadatas.length; i++){
if(metadatas[i].align !== 0)
while(align % metadatas[i].align !== 0)
align++
offsets[i] = align
align += metadatas[i].offset
}
this.offsets = offsets
this.metadatas = metadatas
this.size = align
}
}
class Vec2 {
x: u8
y: u8
}
class FooSchema extends LinearSchema{
constructor(){
super([
new PrimitiveMetadata<u8>(),
new TypeMetadata<Vec2>(),
])
}
}
const schema = new FooSchema()
class FooProxy{
static get size():u32{return schema.size}
set health(value:u8){store<u8>(changetype<usize>(this) + schema.offsets[0],value)}
get health():u8{return load<u8>(changetype<usize>(this) + schema.offsets[0])}
get position():Vec2{return changetype<Vec2>(changetype<usize>(this) + schema.offsets[1])}
}

Related

Generate a list of weighted random letters

I'm trying to create a word game and want to present letters to a user for them to build words. Given that, I have a source list of available letters named lettersList that for now is just the 26 letters of the English alphabet.
For the user, I only want them to have say 5 letters to build a word with. To generate that list of 5 letters, I have the following:
var randomList = new List.generate(5, (_) => lettersList[Random().nextInt(lettersList.length)]).toList();
This sort of works since I don't mind duplicates, but I want certain letters to appear more than others such as vowels and the most common consonants.
So the only solution I could think of was to augment my lettersList to add more of the characters I want to show up more often (e.g., so for the letter E maybe I'll add 5 more instances of it in the letterList or add 3 instances of the letter N) and change my code to use shuffle instead.
lettersList.shuffle();
return lettersList.take(5).toList();
So even though that works, I'm just curious, is there a better or more efficient way to do this?
The way you have suggested (using multiples of some letters) isn't a bad idea per-se but doesn't have a lot of flexibility.
What you really want to be able to do is to have a weighted set of values for each letter, and then choose between them.
A simple way of doing this would be to just define the weights for each letter in the alphabet, i.e.
{ 'a': 1, "b": 0.8, "c": 1.2 ... }
Then, to get a random distribution, you could use random.nextDouble() * <sum of all the weights>. This would result in a number between 0 and the sum total - all you need to do is figure out which position corresponds to that. You could do that by starting at 0, and checking if each respective number's weight added to the running total is bigger than the random double.
You could then wrap this up in a class, potentially doing some initialization of defaults. You can check it out on dartpad but I've included it below as well.
This class handles the random distribution in a generic way:
import 'dart:math';
import 'package:collection/collection.dart';
class WeightedRandom<T> {
WeightedRandom(Map<T, double> allWeights)
: _totalWeight = allWeights.values.sum,
_allWeightsList = allWeights.entries.toList(growable: false);
final double _totalWeight;
final Random _random = Random.secure();
final List<MapEntry<T, double>> _allWeightsList;
T getNext() {
final weightedRandom = _random.nextDouble() * _totalWeight;
double totalSoFar = 0;
for (final entry in _allWeightsList) {
if (weightedRandom < totalSoFar + entry.value) {
return entry.key;
}
totalSoFar += entry.value;
}
return _allWeightsList.last.key;
}
}
And this one makes it letter-specific with the added bonus of setting defaults:
class RandomWeightedLetter extends WeightedRandom<String> {
static final _defaultWeights = Map.fromEntries(
List.generate(26, (ind) => MapEntry(String.fromCharCode(ind + 97), 1.0)));
RandomWeightedLetter._(Map<String, double> allWeights): super(allWeights);
factory RandomWeightedLetter(Map<String, double> specialWeights) {
for (final entry in specialWeights.entries) {
assert(entry.key.length == 1 &&
entry.key.codeUnits.first >= 97 &&
entry.key.codeUnits.first <= 122);
}
final allWeights = _defaultWeights..addAll(specialWeights);
return RandomWeightedLetter._(allWeights);
}
}
You can use it in a pretty simple way, i.e.:
void main() {
final random = RandomWeightedLetter({'f': 26});
final counts = Map.fromEntries(
List.generate(26, (ind) => MapEntry(String.fromCharCode(ind + 97), 0)));
const rounds = 100000;
for (int i = 0; i < rounds; ++i) {
final randomLetter = random.getNext();
counts[randomLetter] = counts[randomLetter]! + 1;
}
print(counts.map((key, value) => MapEntry(key, value / (rounds / random._totalWeight))));
}
(which prints out something like this, showing that the distribution works):
{a: 0.95421, b: 0.99144, c: 0.9894000000000001, d: 0.98634, e: 0.99297, f: 26.18646, g: 0.9679800000000001, h: 1.03479, i: 0.9741, j: 0.9945, k: 1.02408, l: 0.9639, m: 0.98481, n: 0.9537, o: 1.0098, p: 0.99093, q: 1.00827, r: 0.97971, s: 1.0251000000000001, t: 1.02204, u: 0.97104, v: 1.01286, w: 0.98634, x: 0.94911, y: 1.04142, z: 1.0047}
Then, to exactly what you want, you could simply to this:
final random = RandomWeightedLetter(...);
final randomList = List.generate((_) => random.next());
Note that this isn't particularly optimized - you could pre-calculate the 'buckets' and do some fancier algorithm than just iterating through each time to go from the random double to the letter, but this is probably good enough for a fairly small set of potential values. If you were going to have a ton of potential values, you'd want to do something smarter - a simple way to do it would be to calculate the max for each potential response, and then use something like a balanced tree to 'sort' the new value into it.

How to print fields with numeric names in mongo shell? [duplicate]

I'm trying to access a property of an object using a dynamic name. Is this possible?
const something = { bar: "Foobar!" };
const foo = 'bar';
something.foo; // The idea is to access something.bar, getting "Foobar!"
There are two ways to access properties of an object:
Dot notation: something.bar
Bracket notation: something['bar']
The value between the brackets can be any expression. Therefore, if the property name is stored in a variable, you have to use bracket notation:
var something = {
bar: 'foo'
};
var foo = 'bar';
// both x = something[foo] and something[foo] = x work as expected
console.log(something[foo]);
console.log(something.bar)
This is my solution:
function resolve(path, obj) {
return path.split('.').reduce(function(prev, curr) {
return prev ? prev[curr] : null
}, obj || self)
}
Usage examples:
resolve("document.body.style.width")
// or
resolve("style.width", document.body)
// or even use array indexes
// (someObject has been defined in the question)
resolve("part.0.size", someObject)
// returns null when intermediate properties are not defined:
resolve('properties.that.do.not.exist', {hello:'world'})
In javascript we can access with:
dot notation - foo.bar
square brackets - foo[someVar] or foo["string"]
But only second case allows to access properties dynamically:
var foo = { pName1 : 1, pName2 : [1, {foo : bar }, 3] , ...}
var name = "pName"
var num = 1;
foo[name + num]; // 1
// --
var a = 2;
var b = 1;
var c = "foo";
foo[name + a][b][c]; // bar
Following is an ES6 example of how you can access the property of an object using a property name that has been dynamically generated by concatenating two strings.
var suffix = " name";
var person = {
["first" + suffix]: "Nicholas",
["last" + suffix]: "Zakas"
};
console.log(person["first name"]); // "Nicholas"
console.log(person["last name"]); // "Zakas"
This is called computed property names
You can achieve this in quite a few different ways.
let foo = {
bar: 'Hello World'
};
foo.bar;
foo['bar'];
The bracket notation is specially powerful as it let's you access a property based on a variable:
let foo = {
bar: 'Hello World'
};
let prop = 'bar';
foo[prop];
This can be extended to looping over every property of an object. This can be seem redundant due to newer JavaScript constructs such as for ... of ..., but helps illustrate a use case:
let foo = {
bar: 'Hello World',
baz: 'How are you doing?',
last: 'Quite alright'
};
for (let prop in foo.getOwnPropertyNames()) {
console.log(foo[prop]);
}
Both dot and bracket notation also work as expected for nested objects:
let foo = {
bar: {
baz: 'Hello World'
}
};
foo.bar.baz;
foo['bar']['baz'];
foo.bar['baz'];
foo['bar'].baz;
Object destructuring
We could also consider object destructuring as a means to access a property in an object, but as follows:
let foo = {
bar: 'Hello World',
baz: 'How are you doing?',
last: 'Quite alright'
};
let prop = 'last';
let { bar, baz, [prop]: customName } = foo;
// bar = 'Hello World'
// baz = 'How are you doing?'
// customName = 'Quite alright'
You can do it like this using Lodash get
_.get(object, 'a[0].b.c');
UPDATED
Accessing root properties in an object is easily achieved with obj[variable], but getting nested complicates things. Not to write already written code I suggest to use lodash.get.
Example
// Accessing root property
var rootProp = 'rootPropert';
_.get(object, rootProp, defaultValue);
// Accessing nested property
var listOfNestedProperties = [var1, var2];
_.get(object, listOfNestedProperties);
Lodash get can be used in different ways, the documentation lodash.get
To access a property dynamically, simply use square brackets [] as follows:
const something = { bar: "Foobar!" };
const userInput = 'bar';
console.log(something[userInput])
The problem
There's a major gotchya in that solution! (I'm surprised other answers have not brought this up yet). Often you only want to access properties that you've put onto that object yourself, you don't want to grab inherited properties.
Here's an illustration of this issue. Here we have an innocent-looking program, but it has a subtle bug - can you spot it?
const agesOfUsers = { sam: 16, sally: 22 }
const username = prompt('Enter a username:')
if (agesOfUsers[username] !== undefined) {
console.log(`${username} is ${agesOfUsers[username]} years old`)
} else {
console.log(`${username} is not found`)
}
When prompted for a username, if you supply "toString" as a username, it'll give you the following message: "toString is function toString() { [native code] } years old". The issue is that agesOfUsers is an object, and as such, automatically inherits certain properties like .toString() from the base Object class. You can look here for a full list of properties that all objects inherit.
Solutions
Use a Map data structure instead. The stored contents of a map don't suffer from prototype issues, so they provide a clean solution to this problem.
const agesOfUsers = new Map()
agesOfUsers.set('sam', 16)
agesOfUsers.set('sally', 2)
console.log(agesOfUsers.get('sam')) // 16
Use an object with a null prototype, instead of the default prototype. You can use Object.create(null) to create such an object. This sort of object does not suffer from these prototype issues, because you've explicitly created it in a way that it does not inherit anything.
const agesOfUsers = Object.create(null)
agesOfUsers.sam = 16
agesOfUsers.sally = 22;
console.log(agesOfUsers['sam']) // 16
console.log(agesOfUsers['toString']) // undefined - toString was not inherited
You can use Object.hasOwn(yourObj, attrName) to first check if the dynamic key you wish to access is directly on the object and not inherited (learn more here). This is a relatively newer feature, so check the compatibility tables before dropping it into your code. Before Object.hasOwn(yourObj, attrName) came around, you would achieve this same effect via Object.prototype.hasOwnProperty.call(yourObj, attrName). Sometimes, you might see code using yourObj.hasOwnProperty(attrName) too, which sometimes works but it has some pitfalls that you can read about here.
// Try entering the property name "toString",
// you'll see it gets handled correctly.
const user = { name: 'sam', age: 16 }
const propName = prompt('Enter a property name:')
if (Object.hasOwn(user, propName)) {
console.log(`${propName} = ${user[propName]}`)
} else {
console.log(`${propName} is not found`)
}
If you know the key you're trying to use will never be the name of an inherited property (e.g. maybe they're numbers, or they all have the same prefix, etc), you can choose to use the original solution.
I came across a case where I thought I wanted to pass the "address" of an object property as data to another function and populate the object (with AJAX), do lookup from address array, and display in that other function. I couldn't use dot notation without doing string acrobatics so I thought an array might be nice to pass instead. I ended-up doing something different anyway, but seemed related to this post.
Here's a sample of a language file object like the one I wanted data from:
const locs = {
"audioPlayer": {
"controls": {
"start": "start",
"stop": "stop"
},
"heading": "Use controls to start and stop audio."
}
}
I wanted to be able to pass an array such as: ["audioPlayer", "controls", "stop"] to access the language text, "stop" in this case.
I created this little function that looks-up the "least specific" (first) address parameter, and reassigns the returned object to itself. Then it is ready to look-up the next-most-specific address parameter if one exists.
function getText(selectionArray, obj) {
selectionArray.forEach(key => {
obj = obj[key];
});
return obj;
}
usage:
/* returns 'stop' */
console.log(getText(["audioPlayer", "controls", "stop"], locs));
/* returns 'use controls to start and stop audio.' */
console.log(getText(["audioPlayer", "heading"], locs));
ES5 // Check Deeply Nested Variables
This simple piece of code can check for deeply nested variable / value existence without having to check each variable along the way...
var getValue = function( s, context ){
return Function.call( context || null, 'return ' + s )();
}
Ex. - a deeply nested array of objects:
a = [
{
b : [
{
a : 1,
b : [
{
c : 1,
d : 2 // we want to check for this
}
]
}
]
}
]
Instead of :
if(a && a[0] && a[0].b && a[0].b[0] && a[0].b[0].b && a[0].b[0].b[0] && a[0].b[0].b[0].d && a[0].b[0].b[0].d == 2 ) // true
We can now :
if( getValue('a[0].b[0].b[0].d') == 2 ) // true
Cheers!
Others have already mentioned 'dot' and 'square' syntaxes so I want to cover accessing functions and sending parameters in a similar fashion.
Code jsfiddle
var obj = {method:function(p1,p2,p3){console.log("method:",arguments)}}
var str = "method('p1', 'p2', 'p3');"
var match = str.match(/^\s*(\S+)\((.*)\);\s*$/);
var func = match[1]
var parameters = match[2].split(',');
for(var i = 0; i < parameters.length; ++i) {
// clean up param begninning
parameters[i] = parameters[i].replace(/^\s*['"]?/,'');
// clean up param end
parameters[i] = parameters[i].replace(/['"]?\s*$/,'');
}
obj[func](parameters); // sends parameters as array
obj[func].apply(this, parameters); // sends parameters as individual values
I asked a question that kinda duplicated on this topic a while back, and after excessive research, and seeing a lot of information missing that should be here, I feel I have something valuable to add to this older post.
Firstly I want to address that there are several ways to obtain the value of a property and store it in a dynamic Variable. The first most popular, and easiest way IMHO would be:
let properyValue = element.style['enter-a-property'];
however I rarely go this route because it doesn't work on property values assigned via style-sheets. To give you an example, I'll demonstrate with a bit of pseudo code.
let elem = document.getElementById('someDiv');
let cssProp = elem.style['width'];
Using the code example above; if the width property of the div element that was stored in the 'elem' variable was styled in a CSS style-sheet, and not styled inside of its HTML tag, you are without a doubt going to get a return value of undefined stored inside of the cssProp variable. The undefined value occurs because in-order to get the correct value, the code written inside a CSS Style-Sheet needs to be computed in-order to get the value, therefore; you must use a method that will compute the value of the property who's value lies within the style-sheet.
Henceforth the getComputedStyle() method!
function getCssProp(){
let ele = document.getElementById("test");
let cssProp = window.getComputedStyle(ele,null).getPropertyValue("width");
}
W3Schools getComputedValue Doc This gives a good example, and lets you play with it, however, this link Mozilla CSS getComputedValue doc talks about the getComputedValue function in detail, and should be read by any aspiring developer who isn't totally clear on this subject.
As a side note, the getComputedValue method only gets, it does not set. This, obviously is a major downside, however there is a method that gets from CSS style-sheets, as well as sets values, though it is not standard Javascript.
The JQuery method...
$(selector).css(property,value)
...does get, and does set. It is what I use, the only downside is you got to know JQuery, but this is honestly one of the very many good reasons that every Javascript Developer should learn JQuery, it just makes life easy, and offers methods, like this one, which is not available with standard Javascript.
Hope this helps someone!!!
For anyone looking to set the value of a nested variable, here is how to do it:
const _ = require('lodash'); //import lodash module
var object = { 'a': [{ 'b': { 'c': 3 } }] };
_.set(object, 'a[0].b.c', 4);
console.log(object.a[0].b.c);
// => 4
Documentation: https://lodash.com/docs/4.17.15#set
Also, documentation if you want to get a value: https://lodash.com/docs/4.17.15#get
You can do dynamically access the property of an object using the bracket notation. This would look like this obj[yourKey] however JavaScript objects are really not designed to dynamically updated or read. They are intended to be defined on initialisation.
In case you want to dynamically assign and access key value pairs you should use a map instead.
const yourKey = 'yourKey';
// initialise it with the value
const map1 = new Map([
['yourKey', 'yourValue']
]);
// initialise empty then dynamically assign
const map2 = new Map();
map2.set(yourKey, 'yourValue');
console.log(map1.get(yourKey));
console.log(map2.get(yourKey));
demo object example
let obj = {
name: {
first_name: "Bugs",
last_name: "Founder",
role: "Programmer"
}
}
dotted string key for getting the value of
let key = "name.first_name"
Function
const getValueByDottedKeys = (obj, strKey)=>{
let keys = strKey.split(".")
let value = obj[keys[0]];
for(let i=1;i<keys.length;i++){
value = value[keys[i]]
}
return value
}
Calling getValueByDottedKeys function
value = getValueByDottedKeys(obj, key)
console.log(value)
output
Bugs
const getValueByDottedKeys = (obj, strKey)=>{
let keys = strKey.split(".")
let value = obj[keys[0]];
for(let i=1;i<keys.length;i++){
value = value[keys[i]]
}
return value
}
let obj = {
name: {
first_name: "Bugs",
last_name: "Founder",
role: "Programmer"
}
}
let key = "name.first_name"
value = getValueByDottedKeys(obj, key)
console.log(value)
I bumped into the same problem, but the lodash module is limited when handling nested properties. I wrote a more general solution following the idea of a recursive descendent parser. This solution is available in the following Gist:
Recursive descent object dereferencing
Finding Object by reference without, strings,
Note make sure the object you pass in is cloned , i use cloneDeep from lodash for that
if object looks like
const obj = {data: ['an Object',{person: {name: {first:'nick', last:'gray'} }]
path looks like
const objectPath = ['data',1,'person',name','last']
then call below method and it will return the sub object by path given
const child = findObjectByPath(obj, objectPath)
alert( child) // alerts "last"
const findObjectByPath = (objectIn: any, path: any[]) => {
let obj = objectIn
for (let i = 0; i <= path.length - 1; i++) {
const item = path[i]
// keep going up to the next parent
obj = obj[item] // this is by reference
}
return obj
}
You can use getter in Javascript
getter Docs
Check inside the Object whether the property in question exists,
If it does not exist, take it from the window
const something = {
get: (n) => this.n || something.n || window[n]
};
You should use JSON.parse, take a look at https://www.w3schools.com/js/js_json_parse.asp
const obj = JSON.parse('{ "name":"John", "age":30, "city":"New York"}')
console.log(obj.name)
console.log(obj.age)

What's the best way to save terraindata to file in Runtime?

My game lets the user modify the terrain at runtime, but now I need to save said terrain. I've tried to directly save the terrain's heightmap to a file, but this takes almost up to two minutes to write for this 513x513 heightmap.
What would be a good way to approach this? Is there any way to optimize the writing speed, or am I approaching this the wrong way?
public static void Save(string pathraw, TerrainData terrain)
{
//Get full directory to save to
System.IO.FileInfo path = new System.IO.FileInfo(Application.persistentDataPath + "/" + pathraw);
path.Directory.Create();
System.IO.File.Delete(path.FullName);
Debug.Log(path);
//Get the width and height of the heightmap, and the heights of the terrain
int w = terrain.heightmapWidth;
int h = terrain.heightmapHeight;
float[,] tData = terrain.GetHeights(0, 0, w, h);
//Write the heights of the terrain to a file
for (int y = 0; y < h; y++)
{
for (int x = 0; x < w; x++)
{
//Mathf.Round is to round up the floats to decrease file size, where something like 5.2362534 becomes 5.24
System.IO.File.AppendAllText(path.FullName, (Mathf.Round(tData[x, y] * 100) / 100) + ";");
}
}
}
As a sidenote, the Mathf.Round doesn't seem to influence the saving time too much, if at all.
You are making a lot of small individual File IO calls. File IO is always time consuming and expensive as it contains opening the file, writing to it, saving the file and closing the file.
Instead I would rather generate the complete string using e.g. a StringBuilder which is also more efficient than using something like
var someString
for(...)
{
someString += "xyz"
}
because the latter always allocates a new string.
Then use e.g. a FileStream and StringWriter.WriteAsync(string) for writing async.
Also rather use Path.Combine instead of directly concatenating string via /. Path.Combine automatically uses the correct connectors according to the OS it is used on.
And instead of FileInfo.Directory.Create rather use Directory.CreateDirectory which doesn't throw an exception if the directory already exists.
Something like
using System.IO;
...
public static void Save(string pathraw, TerrainData terrain)
{
//Get full directory to save to
var filePath = Path.Combine(Application.persistentDataPath, pathraw);
var path = new FileInfo(filePath);
Directory.CreateDirectory(path.DirectoryName);
// makes no sense to delete
// ... rather simply overwrite the file if exists
//File.Delete(path.FullName);
Debug.Log(path);
//Get the width and height of the heightmap, and the heights of the terrain
var w = terrain.heightmapWidth;
var h = terrain.heightmapHeight;
var tData = terrain.GetHeights(0, 0, w, h);
// put the string together
// StringBuilder is more efficient then using
// someString += "xyz" because latter always allocates a new string
var stringBuilder = new StringBuilder();
for (var y = 0; y < h; y++)
{
for (var x = 0; x < w; x++)
{
// also add the linebreak if needed
stringBuilder.Append(Mathf.Round(tData[x, y] * 100) / 100).Append(';').Append('\n');
}
}
using (var file = File.Open(filePath, FileMode.OpenOrCreate, FileAccess.Write))
{
using (var streamWriter = new StreamWriter(file, Encoding.UTF8))
{
streamWriter.WriteAsync(stringBuilder.ToString());
}
}
}
You might want to specify how exactly the numbers shall be printed with a certain precision like e.g.
(Mathf.Round(tData[x, y] * 100) / 100).ToString("0.00000000");

Specify Variable Initialization Order in Scala

I have a special class Model that needs to have its methods called in a very specific order.
I tried doing something like this:
val model = new Model
new MyWrappingClass {
val first = model.firstMethod()
val second = model.secondMethod()
val third = model.thirdMethod()
}
The methods should be called in the order listed, however I am seeing an apparently random order.
Is there any way to get the variable initialization methods to be called in a particular order?
I doubt your methods are called in the wrong order. But to be sure, you can try something like this:
val (first, second, third) = (
model.firstMethod(),
model.secondMethod(),
model.thirdMethod()
)
You likely have some other problem with your code.
I can run 100 million loops where it never gets the order wrong, as follows:
class Model {
var done = Array(false,false,false);
def firstMethod():Boolean = { done(0) = true; done(1) || done(2) };
def secondMethod():Boolean = { done(1) = true; !done(0) || done(2) };
def thirdMethod():Boolean = { done(2) = true; !done(0) || !done(1) };
};
Notice that these methods return a True if done out of order and false when called in order.
Here's your class:
class MyWrappingClass {
val model = new Model;
val first = model.firstMethod()
val second = model.secondMethod()
val third = model.thirdMethod()
};
Our function to check for bad behavior on each trial:
def isNaughty(w: MyWrappingClass):Boolean = { w.first || w.second || w.third };
A short program to test:
var i = 0
var b = false;
while( (i<100000000) && !b ){
b = isNaughty(new MyWrappingClass);
i += 1;
}
if (b){
println("out-of-order behavior occurred");
println(i);
} else {
println("looks good");
}
Scala 2.11.7 on OpenJDK8 / Ubuntu 15.04
Of course this doesn't prove it impossible to have wrong order, only that correct behavior seems highly repeatable in a fairly simple case.

How to expose aligned class with boost.python

When trying to expose aligned class like this:
class __declspec(align(16)) foo
{
public:
void foo_method() {}
};
BOOST_PYTHON_MODULE(foo_module)
{
class_<foo>("foo")
.def("foo_method", &foo::foo_method);
}
You end up with error (msvs 2010):
error C2719: 'unnamed-parameter': formal parameter with __declspec(align('16')) won't be aligned,
see reference to class template instantiation 'boost::python::converter::as_to_python_function<T,ToPython>' being compiled
The solution I found so far, is to use smart pointer to store object:
BOOST_PYTHON_MODULE(foo_module)
{
class_<foo, boost::shared_ptr<foo>, boost::noncopyable>("foo")
.def("foo_method", &foo::foo_method);
}
Isn't there a better solution? This is quite annoying, because you should wrap all your functions returning objects by value to return smart pointers instead, and performance also degrades.
I had the same problem and wanted a solution that doesn't involve shared_ptr. It involves specializing some boost::python classes to make sure we get a storage area big enough to be able to align our object within it.
I have written a somewhat long blog post explaining how I arrived at this solution here. Below is the solution I found. I feel it is quite a hack, so maybe it will break other things. But so far it seems to work and I haven't found anything better.
I was trying to expose an Eigen::Quaternionf (which requires 16 bytes alignment) :
bp::class_<Quaternionf>("Quaternion", bp::init<float, float, float, float>())
.def(bp::init<Matrix3f>())
.add_property("w", get_prop_const(&Quaternionf::w))
.add_property("x", get_prop_const(&Quaternionf::x))
.add_property("y", get_prop_const(&Quaternionf::y))
.add_property("z", get_prop_const(&Quaternionf::z))
.def("matrix", &Quaternionf::matrix)
.def("rotvec", &quaternion_to_rotvec);
The solution involves specializing 3 classes :
boost::python::objects::instance to request 16 bytes more than what our type requires to ensure we can align
...
union
{
align_t align;
char bytes[sizeof(Data) + 16];
} storage;
...
boost::python::objects::make_instance_impl to correctly set the Py_SIZE of our instance
...
Holder* holder = Derived::construct(
&instance->storage, (PyObject*)instance, x);
holder->install(raw_result);
// Note the position of the internally-stored Holder,
// for the sake of destruction
// Since the holder not necessarily allocated at the start of
// storage (to respect alignment), we have to add the holder
// offset relative to storage
size_t holder_offset = reinterpret_cast<size_t>(holder)
- reinterpret_cast<size_t>(&instance->storage)
+ offsetof(instance_t, storage);
Py_SIZE(instance) = holder_offset;
...
boost::python::objects::make_instance so that the construct method will align the holder in the storage
...
static inline QuaternionfHolder* construct(void* storage, PyObject* instance, reference_wrapper<Quaternionf const> x)
{
// From the specialized make_instance_impl above, we are guaranteed to
// be able to align our storage
void* aligned_storage = reinterpret_cast<void*>(
(reinterpret_cast<size_t>(storage) & ~(size_t(15))) + 16);
QuaternionfHolder* new_holder = new (aligned_storage)
QuaternionfHolder(instance, x);
return new_holder;
}
...
The full code is below :
typedef bp::objects::value_holder<Eigen::Quaternionf> QuaternionfHolder;
namespace boost { namespace python { namespace objects {
using namespace Eigen;
//template <class Data = char>
template<>
struct instance<QuaternionfHolder>
{
typedef QuaternionfHolder Data;
PyObject_VAR_HEAD
PyObject* dict;
PyObject* weakrefs;
instance_holder* objects;
typedef typename type_with_alignment<
::boost::alignment_of<Data>::value
>::type align_t;
union
{
align_t align;
char bytes[sizeof(Data) + 16];
} storage;
};
// Adapted from boost/python/object/make_instance.hpp
//template <class T, class Holder, class Derived>
template<class Derived>
struct make_instance_impl<Quaternionf, QuaternionfHolder, Derived>
{
typedef Quaternionf T;
typedef QuaternionfHolder Holder;
typedef objects::instance<Holder> instance_t;
template <class Arg>
static inline PyObject* execute(Arg& x)
{
BOOST_MPL_ASSERT((mpl::or_<is_class<T>, is_union<T> >));
PyTypeObject* type = Derived::get_class_object(x);
if (type == 0)
return python::detail::none();
PyObject* raw_result = type->tp_alloc(
type, objects::additional_instance_size<Holder>::value);
if (raw_result != 0)
{
python::detail::decref_guard protect(raw_result);
instance_t* instance = (instance_t*)raw_result;
// construct the new C++ object and install the pointer
// in the Python object.
//Derived::construct(&instance->storage, (PyObject*)instance, x)->install(raw_result);
Holder* holder = Derived::construct(
&instance->storage, (PyObject*)instance, x);
holder->install(raw_result);
// Note the position of the internally-stored Holder,
// for the sake of destruction
// Since the holder not necessarily allocated at the start of
// storage (to respect alignment), we have to add the holder
// offset relative to storage
size_t holder_offset = reinterpret_cast<size_t>(holder)
- reinterpret_cast<size_t>(&instance->storage)
+ offsetof(instance_t, storage);
Py_SIZE(instance) = holder_offset;
// Release ownership of the python object
protect.cancel();
}
return raw_result;
}
};
//template <class T, class Holder>
template<>
struct make_instance<Quaternionf, QuaternionfHolder>
: make_instance_impl<Quaternionf, QuaternionfHolder, make_instance<Quaternionf,QuaternionfHolder> >
{
template <class U>
static inline PyTypeObject* get_class_object(U&)
{
return converter::registered<Quaternionf>::converters.get_class_object();
}
static inline QuaternionfHolder* construct(void* storage, PyObject* instance, reference_wrapper<Quaternionf const> x)
{
LOG(INFO) << "Into make_instance";
LOG(INFO) << "storage : " << storage;
LOG(INFO) << "&x : " << x.get_pointer();
LOG(INFO) << "&x alignment (0 = aligned): " << (reinterpret_cast<size_t>(x.get_pointer()) & 0xf);
// From the specialized make_instance_impl above, we are guaranteed to
// be able to align our storage
void* aligned_storage = reinterpret_cast<void*>(
(reinterpret_cast<size_t>(storage) & ~(size_t(15))) + 16);
QuaternionfHolder* new_holder = new (aligned_storage) QuaternionfHolder(instance, x);
LOG(INFO) << "&new_holder : " << new_holder;
return new_holder;
//return new (storage) QuaternionfHolder(instance, x);
}
};
}}} // namespace boost::python::objects