Getting the world's contactListener in Box2D - objective-c

I'm writing a game for Mac OS using cocos2D and Box2D. I've added a b2ContactListener subclass to my world as follows:
contactListener = new ContactListener();
world->SetContactListener(contactListener);
This works perfectly, but I am unsure of the best/accepted way to access the contact listener from other classes that don't currently have a direct reference to the contact listener.
I know I can pass a reference to other classes that need it, but what I was wondering is if there is a better way. More specifically, although I can't find a method to do this, is there some equivalent of this:
world->GetContactListener();
in Box2D?
The reason I am trying to do this is simply because I would prefer to move some game logic (i.e. whether a body is able to jump based on information from the contact listener) to the relevant classes themselves, rather than putting everything in the main gameplay class.
Thanks!

A contact listener just serves as an entry point for the four functions BeginContact, EndContact, PreSolve and PostSolve. Typically it has no member variables, so there is no reason to get it, because there is nothing to get from it.
When one of these functions is called during a world Step, you can make a note of which two things touched/stopped touching etc, but you should not change anything in the world right away, until the time step is complete.
I think the crux of this question is the method used to 'make a note' of which things touched, but that's really up to you and depends on what kind of information you need. For example if you're only interested in BeginContact, then the absolute simplest way might be to just store which two fixtures touched as a list of pairs:
std::vector< std::pair<b2Fixture*, b2Fixture*> > thingsThatTouched;
//in BeginContact
thingsThatTouched.push_back( make_pair(contact->GetFixtureA(), contact->GetFixtureB()) );
//after the time step
for (int i = 0; i < thingsThatTouched.size(); i++) {
b2Fixture* fixtureA = thingsThatTouched[i].first;
b2Fixture* fixtureB = thingsThatTouched[i].second;
// ... do something clever ...
}
thingsThatTouched.clear(); //important!!
For this to work you'll need to make the thingsThatTouched list visible from the contact listener function, so it could either be a global variable, or you could set a pointer to it in the contact listener class, or maybe have a global function that returns a pointer to the list.
If you need to keep track of more information such as what things stopped touching, or do something after the time step based on how hard things impacted when they touched etc, it will take a bit more work and becomes more specific. You might find these tutorials useful:
This one uses BeginContact/EndContact to update a list of which other things a body is touching, and uses it to decide if a player can jump at any given time:
http://www.iforce2d.net/b2dtut/jumpability
This one uses a similar method to look at what type of surfaces are currently under a car tire, to decide how much friction the surface has:
http://www.iforce2d.net/b2dtut/top-down-car
This one uses PreSolve to decide whether two bodies (arrow and target) should stick together when they collide, based on the speed of the impact. The actual 'sticking together' processing is done after the time step finishes:
http://www.iforce2d.net/b2dtut/sticky-projectiles

I think you simply can call GetContactList and then process all the contacts using iterator if you need to do it in some other place

Related

Optaplanner, update shadow variables after every step

I am trying to add moves selectors which consider the state of the current working solution. For example, suppose in the cloud balancing problem I was trying to make a move which preferentially moved a process onto a computer which already holds few processes. I have a shadow variable which tracks the number of processes on the computer, then I have a valueSelector which implements SelectionProbabilityWeightFactory that gives a higher weight to computers with fewer processes.
This setup works fine and produces the moves that I want. But it is terribly slow because it is updating the shadow variable far more often than I need it to. Since I am not using this shadow variable for scoring, I don't need it to be updated after every move attempted during the step. I only need the shadow variable to be updated after each accepted move (i.e. the end of the step).
Alternately, I could use a custom move factory, but that requires that every computer have its process count fully re-calculated at each step. This means I would lose the incremental calculation benefit I get with the shadow variables.
So is there a way to force shadow variables to update after each step, rather than after each move. Or is there a better way to track the status of the working solution for use in move selectors?
Bad news first:
It's not possible to have VariableListener only update a shadow variable per step and not per move. And it's unlikely we'll ever want to allow that particular change, as it would hurt the predictability and integrity of the state of the domain model between move iterations. This could create a lot of havoc, including multiple forms of corruptions, if used slightly incorrectly.
Good news next:
Yes, you need to calculate some state per step to generate moves efficiently. This is a common problem I've run into a few times before too.
But why put that on the domain model? It doesn't belong there.
It belongs on the the move selector. For example, if you use a MoveIteratorFactory, that has a method called phaseStarted() (called when the phase starts) and a method createRandomMoveIterator() (called when a step starts even with SelectionCacheType.JIT).
Some something like this should do the trick:
public class MyMoveIteratorFactory implements MoveIteratorFactory<...> {
default void phaseStarted(ScoreDirector<...> scoreDirector) {
}
Iterator<Move_> createRandomMoveIterator(ScoreDirector<...> scoreDirector, Random workingRandom) {
List<Computer> alreadyUsedComputerList = ...; // runs once per step
return new MyIterator(alreadyUsedComputerList, workingRandom);
}
Now, the plot thickens when multiple move selectors need to reuse the same calculation. That's where SupplyManager comes into play, which is not public API. But this is definitely a good requirement for our "move streams API" experiment that we'll do next year.

How to Instance an object in Godot?

So I basically have some fair knowledge of Opengl 4.0. In OpenGL you can render the same object at many places. This is a technique called Instancing. This saves up some CPU calls or something.
I wanted to do this in Godot. So I looked up in the docs and it basically just tells me to duplicate an object. But I think this does not save the CPU calls to the GPU, like how Instancing does (please let me know if I'm wrong about this).
Plus I cannot have all the nodes beforehand. Because the number of times I need to render the object(at different places) is determined during runtime and can change.
Is there a solution to this?
Any help would be appreciated.
Thank you
Instancing can be thought of as making copies of an object from a blueprint. The reason it saves memory and draw calls is that essentially, only the "blueprint" must be kept in memory. The recommended way that Godot addresses this (as per the documentation) is through (packed) scenes.
To do this, create the object as it's own scene - remember that you can right click on the root node of a scene (even an empty one) and change the type to whatever you want. Once you have the object set up the way you like, save it as it's own scene (ex: myInstance.tscn).
From there, you can call upon the instance from your main scene (or whatever scene you need it in). To do this you need to do a couple of things:
First, create a variable for your instance in the script you want to call it from by declaring something like onready var instancedObject = preload("res://myInstance.tscn"). (Using whatever path you used for the scene).
From there, you call the variable from whatever function you need by writing something like: var myObject = instancedObject.instance()
You then must add the instance to the current scene with add_child(myObject)
After this, you can (optionally) specify things like transforms and rotations to determine where the instance gets put (Ex: myObject.transform.origin = Vector3(0,10,0) - For 3D, or myObject.position = Vector2(10,0) for 2D)
Alternatively, you can initialize and instance the object at the same time by writing onready var instancedObject = preload(res://myInstance.tscn).instance(), and then adding it in functions by using add_child(instancedObject), however although it requires fewer steps, there are limitations to doing it this way, and I personally have had much more success using the first approach.
If, however, you are looking to instance multiple thousands of objects (or more) in the same scene, I recommend using Calinou's answer and using a MultiMeshInstance. However, one of the limitations of the MultiMeshInstance is that it uses an all or nothing approach to drawing, meaning all instances will either be all drawn at once, or not drawn at all. There is no in-between. This could be good or bad depending on what you need it for.
Hope this helps.
Instancing in Godot is handled using the MultiMeshInstance node. It's the instanced counterpart to MeshInstance. See Optimization using MultiMeshes in the documentation for more information.
Keep in mind MultiMeshes aren't suited if you need to move the objects in different directions every frame (although you can can achieve this by using INSTANCE_ID in a shader shared among all instances). MultiMeshInstance lets you change how many instances are visible by setting its visible_instance_count property.

Can I build auto-firing guns with ScriptCraft in Minecraft?

I am reading https://github.com/walterhiggins/ScriptCraft/blob/master/docs/YoungPersonsGuideToProgrammingMinecraft.md and want to try it out with my son.
I see there is a list of events available, though, being new to this mod, I am not sure I can implement what I am thinking of.
Say, I have a territory around my castle, say, square of 300x300 blocks on a plain field. I know the coordinates of the square.
Now, can I track if any mob intersects the bounds from outside to inside?
If it's possible, what's the event I should look for?
Then, can I add some mechanism that would through something in the direction of the mob's position? How could it look like? Or, even just signalling that a mob is in the zone.
Generally, I want to track mobs and do perform some actions for events.
First and foremost, kudos for exploring this with your son.
I wish I could provide exacting details, but my familiarity with ScriptCraft is limited. However, given that is based on Spigot (not Forge, as suggested in the comments), I can provide an answer from that perspective. I’ll leave the nitty-gritty details of accessing POJOs to your expertise with JavaScript.
While player movements fire PlayerMoveEvent events, there is no corresponding event for other entities/mobs. If there were, it would be a matter of checking whether an entity’s location has breached your perimeter and handling it accordingly.
The simplest approach would be to define a function that calls getLivingEntities() on a World, iterator over the list to determine the type of entity and perform whatever actions are desired; say, announce that it has breached your barrier. This function would be registered as a scheduled task with the BukkitScheduler as a repeating synchronous task. I found this example for scheduling a task, though it is for a single delayed asynchronous task.
load(__folder + "../drone/drone.js");
load(__folder + "../core/scriptcraft.js");
Drone.extend("big",function(){
server.scheduler.scheduleAsyncDelayedTask(global.plugin,function(){
(new Drone()).box(1,500,100,500);
print("done");
});
});
On a large server with many entities, the approach would be optimized by accessing each Chunk containing the protected area and retrieving entities contained therein with getEntities().

Scripting Bridge: Combining SBElementArrays

According to Apple's documentation on Scripting Bridge performance, we should strive to use batch operations on SBElementArrays, since Apple event calls are expensive.
... whenever possible you should always use one of the “batch
operation” array methods instead of enumerating the array. These
methods avoid the inefficiency of enumeration because they send a
single Apple event rather than one Apple event per item in the array.
I'm using Scripting Bridge with the System Events application, and I'm able to get menu items from the menus successfully. It's much faster than the NSAppleScript method I was using previously.
What I'd like to do is combine together several SBElementArrays, each of which is holding menu items from different menus. The plan is to then run the batch operation once instead of doing it for each menu individually.
It seems to me like this shouldn't be that complicated, though obviously my knowledge in this area is limited at best. Unfortunately I'm running into serious errors.
First Attempt
If I attempt to create an empty SBElementArray element and then loop through the menu items adding each set of menuitems, like so:
SBElementArray* menuItemCombinedArray = [[SBElementArray alloc] init];
for (SystemEventsMenuBarItem* menu in menuBar.menus) {
menuItemCombinedArray = [[menuItemCombinedArray arrayByAddingObjectsFromArray:menu.menuItems] mutableCopy];
}
NSArray* menuItemNameArray = [menuItemCombinedArray arrayByApplyingSelector:#selector(name)];
I get an error saying that [SBElementArray init] should never be used, which is a bit odd since SBElementArray is a subclass of NSMutableArray.
Second Attempt
Next I tried a hackier way, where I created the SBElementArray separately for the first menu, then looped through the remaining menus and added those SBObjects one at a time, like so:
SBElementArray* menus = menuBar.menus;
SystemEventsMenuBar* firstMenu = menus.firstObject;
SBElementArray* menuItemCombinedArray = firstMenu.menuItems;
[menus removeObjectAtIndex:0];
for (SystemEventsMenuBarItem* menu in menus) {
SBElementArray* tempMenuItemsArray = menu.menuItems;
for (int i = 0; i < tempMenuItemsArray.count; i++) {
[menuItemCombinedArray addObject:[tempMenuItemsArray objectAtIndex:i]];
}
}
NSArray* menuItemNameArray = [menuItemCombinedArray arrayByApplyingSelector:#selector(name)];
But now I get a different error: [SBElementArray addObject:]: can't add an object that already exists.'
Summary
From what I've read searching around, it sounds like Scripting Bridge in general, and SBElementArray specifically, are kind of wonky. But Scripting Bridge has been much faster for me than NSAppleScript, much closer to what I'm aiming for. I think if I could get this optimization working I'd be in great shape.
Thanks in advance for any help!
SBElementArray is not an Array - it's a lot of smoke-n-mirrors BS disguising the otherwise simple fact that Apple event IPC is not OOP but RPC plus simple relational queries.
What you really have beneath all that SBElementArray dross is a single object specifier that describes a one-to-many relationship between 'objects' in the application's Apple Event Object Model, an idealized, virtual representation of the user's data presented in a programmatic user interface.
The application also defines various Apple event handlers for performing operations on its AEOM - creating, deleting, moving, duplicating, etc. - the idea being that you send a request to the app, e.g. duplicate (every track whose artist is "Bjork") to (playlist "Icelandic"), and the receiving handler figures out precisely how to carry out that operation for you.
How well this query-driven approach works in practice depends on how well the app's AEOM support is implemented: often the underlying Model layer implements collections as ordered Arrays rather than unordered Sets, and since you're basically performing set operations of the sort more commonly seen in RDBMSes, well, there's all sorts of opportunities for misorderings and other errors to creep in when moving array elements around in relation to one another. But the basic concept is not unsound (just a PITA to implement reliably); alas, the SB authors seem to think that "Relational Graphs Is Too Hard for Cocoa users" (which no doubt comes a big suprise to CoreData users), so try to hide it all beneath a stinky, incompetent ORM.
Thus there's absolutely no point trying to apply NS[Mutable]Array semantics to the problem as you're doing, because SBElementArrays are not local (or remote) arrays, but crippled obfuscated wrappers around AEOM queries. In other words, to understand why what you're doing doesn't work and how to do it so it does, you need to understand how AEOM actually works, how SB lies about how it works, and how SB translates its lies into [very limited] AEOM behaviors.
Thus, when you apply -[SBElementArray arrayByApplyingSelector:], it isn't actually performing array iteration at all; instead, it's constructing an object specifier of form |selector name| of |elements| of... and sending it to the application in a get event to resolve; the result being a list of values of the specified properties. Of course, this all turns out to be completely useless when you want to perform anything other than a simple get operation, e.g. set (rating of every track of playlist "Icelandic") to 100, because the SB API's too crippled and prejudiced to let you express this, even though it's a perfectly valid request.
...
TL;DR: It's a complete waste of time trying to do anything non-trivial in SB, because the harder you push it, the more its pseudo-OO fakery falls apart. The only [officially supported] way to do Apple events correctly is via AppleScript, and as you say using AS via NSAppleScript is an exercise in groin-punching that's barely less painful than SB (although partly that will be because you're no doubt doing it wrong, i.e. generating custom AS source code via string-mashing and compiling and executing it on the fly instead of calling parameterized handlers in precompiled .scpt files loaded from your app bundle).
Fortunately, 10.6 introduced the AppleScript-ObjC bridge which, while not without some shortcomings of its own, is by far the easiest and quickest way to integrate AS and ObjC code as it allows you to define AppleScript script objects that appear to your ObjC code almost as if they were native Cocoa classes and instances. That would be my recommended approach to you, and forget about SB for anything but trivial tasks (or just forget it altogether and stick with AS, which may be naff but at least it's mostly understood, less dishonest naff).

Singleton pattern - doubt in Head First Design Patterns book

On page 175, there is an example of Chocolate Boiler class. Something like this:
public class ChocolateBoiler {
private boolean empty;
private boolean boiled;
public ChocolateBoiler {
empty = true;
boiled = false;
}
// and then three methods to fill, drain and boil which changes the
// status of these two flag depending of situation
}
In section "brain power" they ask a question "How might things go wrong if more than one instance of ChocolateBoiler is created in an application?"
I'm not sure what's the problem with this class. Why do we introduce a singleton pattern here? These two flags are not static and so one per instance. So how creating more than one instance can mess things up?
The question isn't about making an instance of an object.
It's about the confusion caused by having two instances of the object, both of which purport to have the status of the ChocolateBoiler.
If some Object (for example, Cooker) thinks it has the status of the ChocolateBoiler, and some other Object (for example, Recipe) things it has the status of the ChocolateBoiler, what happens now?
Since the variables are instance variables, the ChocolateBoiler objects won't agree on the status of the ChocolateBoiler. Now what happens?
It's only a problem if there only can be one ChocolateBoiler, and if there only can be one, it should be a singleton.
I believe in that example you only had only ONE Chocolate boiler. And so you should only be able to create one instance of the object representing it. If you were allowed to create multiple instances, you would then perhaps issue the command if (boiler.hotEnough()) boiler.stop() somewhere in you system and would be surprised that although the boiler is already way too hot, it's not stopping because you are talking to some 'dead' instance of a Boiler, which returns hotEnough() : false.
Using the singleton pattern you are making sure that no matter where in your code you say Boiler.getInstance() you will get the one and only boiler object there is, and that when you then talk to it, it will do as you would expect.
The entire example of the chocolateboiler in a singleton bothered me a lot while I was reading it.
On a really fundamental level, I don't see why its necessary when you only have one physical thing, to enforce that fact in software. What happens if you get another one? what are you going to do, add the second to the same singleton? make 2 different singletons? a simple global variable would do the job.
IMO, its not the boiler itself that you can only have one thing of , its access to that particular boiler's controls. You can't allow a second person to start making a new batch of chocolate while its already in that process for someone else, or even allow the same person to make a second batch before the first is finished. From that point of view, a simple queueing or batch processing system would do the job. Using another pattern from the book, the command pattern would be a much better way of handling it , as there's only one waitress , and all new orders get queued up until the cook's done with the current food order. (er, if you haven't seen the book, what I just said might not make much sense, sorry)
Maybe I'm just not getting the point. I haven't done much OOP or anything with design patterns before, and I'm losing job opportunities because of it, so I'm reading up on it.