Idiomatic way to efficiently reinitialize/replace container element while recycling internals in modern C++? - stl

I am storing a custom image object type in a std::vector and treating the vector as a circular buffer. Each image has an overwrite(...) method to reinitialize it with new content (same dimensions) each time the buffer loops - my question is in 'modern' C++ (am already using C++17 for string_view) what is the idiomatic way of doing this?
Was thinking some combination of using vector.emplace() and an appropriate constructor on the image class. Or perhaps somehow using placement new.
Basically I would like to keep all my image initialization logic inside a constructor instead of split between constructor and overwrite() while avoiding the cost of destroying and initializing new internal buffers and such.

You want to move the
new content
to an existing entry in the vector, so a move assignment operator in your "custom image" class will help, e. g.:
class CustomImage
{
public:
CustomImage() = default;
CustomImage(std::vector<unsigned char>&& data)
: data_(std::move(data))
{}
// move assignment
CustomImage& operator=(CustomImage&&) = default;
private:
// possible way of storing image data
std::vector<unsigned char> data_;
};
Then you can move the new content to the ring buffer entry like so:
// initialize the ring buffer with 5 empty entries
std::vector<CustomImage> ring_buffer(5);
// some new example image
std::vector<unsigned char> first_image{2,4,5,7,9};
// move assign the new image to the current entry in the ring buffer
ring_buffer.at(0) = std::move(first_image);
This is modern (due to move semantics) and fast, because memory of the image is not copied.

Related

Check the existence of an object instance

I'm surprised I don't know how to do this, but as it turns out I really don't; simply put, I'm trying to make a side-scrolling shooter game, a basic one and in it, I have 50 stars spawned on-screen through a "for" loop upon the game starting. There is a function which does this and a listener is at the beginning. Problem is, when you lose the game and go back to main menu, 50 more stars would be spawned, which isn't what I want. So, I'm trying to make an "if" statement check at the beginning, so that the game checks whether there is an instance/movie clip of the star object/symbol before determining whether the function that spawns stars should be called out with a listener. So, how do I do this? I looked through some other checks and they didn't help as the codes presented were vastly different there and so I'm just getting errors.
Let me know if a better explanation is needed or if you would like to see some of the code. Note that the game overall already has a lot of code, so just giving all of it would probably not be helpful.
I suggest you rethink your approach. You're focusing on whether stars have been instantiated. That's ok but not the most basic way to think about it.
I would do this instead
private function setup():void{
loadLevel(1);
addListeners();
loadMusic();
// etc...
// call all functions that are needed to just get the app up and running
}
private function loadLevel(lev:int):void{
addStars();
// call all functions that are needed each time a new level is loaded
}
private function restartLevel():void{
// logic for restarting level,
// but this *won't* include adding star
// because they are already added
}
There are other ways to do this but this makes more sense to me than your approach. I always break my game functions into smaller bits of logic so they can be reused more easily. Your main workhorse functions should (IMHO) primarily (if not exclusively) just call other functions. Then those functions do the work. By doing it this way, you can make a function like resetLevel by assembling all the smaller functions that apply, while excluding the part about adding stars.
Here's what I did to solve my problem... Here's what I had before:
function startGame():void
{
starsSpawn();
//other code here
}
This is what I changed it to:
starsSpawn();
function startGame():void
{
//other code here
}
when you said existance, so there is a container, i named this container, (which contain stars , and stars was added to it) as starsRoot, which absolutely is a DisplayObject (right?)
now, to checking whole childrens of a DisplayObject, we have to do this :
for (var i:int=0; i<starsRoot.numChildren; i++) {
var child = starsRoot.getChildAt[i];
}
then, how to check if that child is really star!?
as you said
whether there is an instance/movie clip of the star
so your stars's type is MovieClip, and they don't have any identifier (name), so how to find them and make them clear from other existing movieclips. my suggestion :
define a Linkage name for stars from library, thats a Class name and should be started with a capital letter, for example Stars
now, back to the code, this time we can check if child is an instance of Stars
for (var i:int=0; i<starsRoot.numChildren; i++) {
var child = starsRoot.getChildAt[i];
if (child is Stars) {
// test passed, star exist
break;
}
}

Box2d MovieClip to original position

I want to try a simple task where if i move a object inside the world and then press a button it should go back to its original position , but its not working , below is the code i am using - the file is here - http://www.fastswf.com/yAnIvBs (when i remove the event listener)
with event listener - http://www.fastswf.com/rpYsIt8
////////========================
stop();
var startXPos:Number = level1WorldObj.box1.x;
var startYPos:Number = level1WorldObj.box1.y;
function areaS(e:Event) {
level1WorldObj.box1.y= startYPos;
level1WorldObj.box1.x= startXPos;
level1WorldObj.box1.removeEventListener(Event.ENTER_FRAME, areaS);
}
but1.addEventListener(MouseEvent.CLICK,nClick3);
function nClick3(event:MouseEvent):void{
level1WorldObj.box1.addEventListener(Event.ENTER_FRAME, areaS);
level1WorldObj.box1.y= startYPos;
level1WorldObj.box1.x= startXPos;
}
/////////////////======================
Now i want to be able to do it many time so i kept the variables that detect the initial x, y as global ...
Here you can see how it behaves in debugdraw mode , strangely only the clip moves not the actual body - http://www.fastswf.com/-Ijkta4
Can some one please guide me here ...
Thanks in advance ...
Jin
The graphics that you see (box1) aren't related to the physical object behind the scenes - you're currently only moving the graphics not the object itself.
You need to use either SetPosition() or SetTransform() on the b2Body of the object
Edit 07/7
As you're using the Box2D World Construction Kit, I took a look at the source code (available here: https://github.com/jesses/wck). The main class seems to be BodyShape (https://raw.githubusercontent.com/jesses/wck/master/wck/BodyShape.as).
Looking through it, you should be able to access the b2Body directly. If it's null (which is probably the source of the TypeError that you're getting, then you haven't called createBody(), which is what actually takes all of your properties as creates the physical object behind the scenes.
Once you have a b2Body, if you want to position it based on the graphics, there's a function syncTransform() to do just that.
You should turn on debugDraw on your World class to make it easier to see what's going on in the background. NOTE: this needs to be done before calling create()
I was able to find solution to this problem , i found the starting point by using this -
trace(level1WorldObj.box1.b2body.GetPosition().x);
trace(level1WorldObj.box1.b2body.GetPosition().y);
then once i had the position manually i took down the coordinates and used the below code ....
level1WorldObj.box1.b2body.SetTransform(new V2(-2, 2),0 );
Thanks #divillysausages for all the help ...
Regards

How to automatic alignment Fibers, Volume and Mesh use XTK

I think it is a simple question, but it really confuse me...
In the case which I try to show three object together, like Fibers, Volume and Mesh, just as you can see in this demo web.
Demo Web: http://goo.gl/NP2eUo
But there is a problem, the Fibers object can not automatic alignment with Volume and Mesh. Those files are come from the same source (one subject's DICOM file) so it should can be match together in default.
If only show the Fibers object, it can be put in the center of the view. But if show three object together, then Fibers object will be Shift!!!
Is there any possible way can let three object automatic alignment together?
And here is my source code: http://goo.gl/Ttzc84
What if you try to call reset boundingBox on showtime?
...
// .. add the mesh
r.add(mesh);
r.onShowtime = function() {
r.resetBoundingBox();
}
r.render();
...
How did you generate the surface and the trk file? Freesurfer and DTK?
I suspect the trk file does not provide any IJKToRAS transformation.

Saving the state of a movieclip containing multiple movieclips inside

this is actually a noobish question, but is there a possible way to save a certain state of a movieclip?, example i dynamically added a movieclip called big_mc, then inside big_mc contains three(3) smaller movie called child_mc1 and child_mc2 and a close_big to remove big_mc from the stage, when i click either of child_mc1 and child_mc2, the child_mc will disappear prior to which child_mc i clicked.
so the scenario is when I click child_mc1 which remove itself from the scene, then next I'll click the close_big movieclip to remove big_mc from the stage and will save it's own state, so then the next time i run the SWF file and dynamically add big_mc to stage, child_mc1 would be still missing and child_mc2 would still be displayed (EVEN IF I CLOSE THE SWF FILE, the state should be saved). please help..much is appreciated.
code in main time line:
var big_mc:mother_mc = new mother_mc;
add_big_btn.addEventListener(MouseEvent.CLICK, call_big);
function call_big(e:MouseEvent):void
{
addChild(big_mc);
}
the code inside big_mc:
child_mc1.addEventListener(MouseEvent.CLICK, remove_child1);
child_mc2.addEventListener(MouseEvent.CLICK, remove_child2);
close_big.addEventListener(MouseEvent.CLICK, bye);
function remove_child1(e:MouseEvent):void
{
removeChild(child_mc1);
}
function remove_child2(e:MouseEvent):void
{
removeChild(child_mc2);
}
function bye(e:MouseEvent):void
{
this.parent.removeChild(this);
}
You want to start with SharedObject, which as Adobe puts it, "is used to read and store limited amounts of data on a user's computer or on a server". To save the "state" of the MovieClip is more complicated.
What about it do you want to save? The x property? Perhaps the alpha? EVERYTHING? Each object is stored in a default state in your swf. Library items in the Flash IDE are technically miniature classes, as evidenced by the way we instantiate them. Assuming you create something called customButton, you could spawn thousands of them onscreen (or one) like this:
var foo:customButton = new customButton();
Like a hand-written class, a copy of the customButton is created with all the properties you defined on it before you compiled it. If you want to change those properties, you have to address each and every one you want different.
Looking at this broadly, let's assuming you want to save the position of your button every time you load the swf. Load with getLocal(), and save with flush().
var settings:Object = SharedObject.getLocal("foo");
function updateState(e:Event):void {
myButton.x = settings.x;
myButton.y = settings.y;
}
function saveState():void {
settings.x = myButton.x;
settings.y = myButton.y;
settings.flush();
}
It's not impossible; there's simply no push-button solution for it. If you wanted, you could write a function which iterates over all DisplayObjects, and loads/saves each relavent property from/into your SharedObject. Might be overkill, though.

Game logic and game loops in ActionScript 3

I am making a Shooting game in flash actionscript 3 and have some questions about the flow of logic and how to smartly use the OOPs concepts.
There are mainly 3 classes:
Main Class: Initializes the objects on the screen.
Enemy Class: For moving the enemies around on the screen.
Bullet Class: For shooting.
What I want to do is find out if the Enemy has been hit by a bullet and do things which must be done as a result ...
What I am doing right now is that I have a ENTER_FRAME event in which i check collision detection of each enemy unit (saved in an array) with the bullet instance created, and if it collides then perform all the necessary actions in the Main class .. clogging the Main class in the process ..
Is this the right technique ? or are there better solutions possible ?
Try to think more OOP, what is every object responsible for?
We have the enemies wich we can hit:
class Enemy : extends NPC implements IHittable {
. . .
function update(delta) {
// move, shoot, etc.
}
function handleHit(bullet) {
// die
}
}
A hittable object:
interface IHittable {
function handleHit(bullet);
}
The bullet is suppose to move and hit things:
class Bullet : {
function update(delta) {
// update position
}
function checkHits(world:World) {
for each(var hittable:IHittable in world.objects) { // might want to cluster objects by location if you're handling lots of objects / bullets)
if (isColidingWith(hittable))
o.handleHit(bullet);
}
}
}
And then we have the world with everything inside:
class World {
var npcs: Array ...
var bullets: Array ...
var hittables: Array ...
function update(delta) {
foreach(var c:NPC in npcs)
c.update(delta);
foreach(var b:Bullet in bullets) {
b.update(delta);
b.checkCollisions(world);
}
}
}
And your main loop is just simple as that:
var lastTime:int;
function onEnterFrame(...) {
var now:int = getTimer(); // FlashPlayer utility function to get the time since start (in ms)
world.update(now - lastTime);
lastTime = now;
}
A few other notes:
try to do all the computation based on a delta of time, otherwise the game's speed will vary with the framefrate.
what happens when a character dies? bullet disappear? Well, you could do it several ways:
fire an event, like EnemyDied and remove it from the world
implement an interface CanDie that has a (get dead():Boolean property) and use that to cleanup the world at every update.
but don't write the code to remove the enemy in the Enemy class, because then you will be polluting the class with code that should be handled by the World, and that will be hard to maintain later.
Sorry for the long answer, but I couldn't help myself :)
Was clogging the Main class the problem, or finding out what bullet hit what enemy the problem? If it was the bullet, you need to describe the bullet behavior - can it hit multiple enemies, how fast does it move (is it possible that when testing using "enterFrame" the bullet will first appear in front of the enemy, and, on the second frame, it will appear behind the enemy?). May enemy be simplified to some basic geometrical shape like circle or rectangle, or do you need pixel-perfect precision? Finally, how many bullets and how many enemies are you planning to have at any one time? It could be too expensive to have a display object per bullet, if you are going to have hundreds of them, and then it could make more sense to draw them into single shape / bitmapdata.
If the problem is that the Main class is too long, there are several possibilities here.
A nobrainer answer to this problem - use inheritance to simply put parts of the code in separate files. Not the best way, but a lot of people do it.
If you did the first, then you'd realize that there are certain groups of functions you put into superclass and subclasses - this will help you split the "clogged" class into several smaller independent pieces that have more particular specialization.
After you did the second, you may find out that there is certain dependency between how you split the big class into smaller classes, so you can try generating those smaller classes by a certain pattern.
And then you write the clogged code that generalizes those parts you just managed to split.
Above is basically the cycle from more concrete to more generic code. In the process of perfecting the last step, you'll write some concrete code again. And that will move you to the step 1. Lather, rinse, repeat :) In fact, you don't want to write OO code, or procedure code or anything that fashion of the day tells you to do. You want to write good code :) And you do it by moving from more generic to more specific and back to more generic, until it's perfect :P
Probably not the best answer, but you must admit, you didn't give much info to give you more precise answer.