The DoCollision function is a callback function which is checking for collisions every frame by iterating over a collider list.
void Collision::DoCollisions(Game *game){
for (ColliderList::const_iterator colliderAIt = colliders_.begin();
colliderAIt != colliders_.end();
colliderAIt++)
{
ColliderList::const_iterator colliderBIt = colliderAIt;
for (++colliderBIt; colliderBIt != colliders_.end(); ++colliderBIt)
{
Collider *colliderA = *colliderAIt;
Collider *colliderB = *colliderBIt;
if (CollisionTest(colliderA, colliderB))
{
game->DoCollision(colliderA->entity, colliderB->entity);
}
}
}
if collision test passes for any two game entities, game entity(Base class for all game objects) class destructor invoke function DestroyCollider which removes the respective collider elements from the list.
void Collision::DestroyCollider(Collider *collider){
colliders_.remove_if(std::bind1st((std::equal_to<Collider *>()), collider));
delete collider }
You're removing the element of a list that the iterator points to. That invalidates the iterator, meaning you're not allowed to use it anymore.
A typical remove loop for a list or vector looks like this:
for (auto iterator = list.begin(); iterator != list.end(); ) {
if (should_remove(iterator)) {
iterator = list.erase(iterator);
} else {
++iterator;
}
}
Note how, if an element is to be removed, the iterator is not incremented, but instead replaced with the result of the erase call.
You will have to find a way to refactor your code to match this pattern. This is complicated because your condition is deep within the collision function, but you can do either that (which has the advantage of making your code more efficient by getting rid of the linear search, by the way), or you can, instead of immediately removing the elements, collect them in a separate list, and then remove them after you're done iterating over the main list.
Or you can turn colliders_ into an intrusive list (e.g. from Boost.Intrusive, or hand-written). Intrusive lists are very good for situations like yours.
Related
I have a array T* which is created like the following
T* array = new T[len];
// Some initialization codes
We know we can delete the array like
delete [] array;
However, I am writing a Rust FFI program with C++. I have sent this array pointer to the Rust part of my code, and I want to delete the code now.
So I can implement a function ffi_delete_array_of_T on the C++ part, and the Rust part code will call the function through FFI, attached with the argument array.
void ffi_delete_array_of_T(void * arr) {
delete [] reinterpret_cast<T *>(arr);
}
However, I already have a function which can delete single element of T.
void ffi_delete_pointer_of_T(void * arr) {
delete reinterpret_cast<T *>(arr);
}
These two functions are so similar that I wonder if I can combined them into one, so I don't need to write two copy.
void ffi_delete_whatever_of_T(void * arr, bool is_array) {
if (is_array)
delete [] reinterpret_cast<T *>(arr);
else
delete reinterpret_cast<T *>(arr);
}
However, I still think the above codes redundant. I wonder if I only give ffi_delete_pointer_of_T, is it possible the Rust do some magic, and have ffi_delete_array_of_T for me?
To the best of my knowledge, it is not possible. C++ can delete [] a array without hint of length, because it has already stored the length of array somewhere when array is allocated. However, the Rust part don't know the actual length of this array.
However, I still wonder if there are some other ways to do that?
I have an iterable PyObject that I need to pass as the list of arguments to a Python callable, ala
xs = [1,2,5,7]
some_function(*xs)
However, PyObject_CallObject only allows tuples to be passed as the arguments' container.
I'm not sure, though, what is the best way to create a new tuple containing the elements of an iterable. Here's a tentative code:
PyObject* unpack_call(PyObject* callable, PyObject* args) {
PyObject* tuple;
if (PyTuple_Check(args)) {
tuple = args;
} else {
PyObject* iter = PyObject_GetIter(args);
if (!iter) return NULL;
tuple = PyTuple_New(0);
for (Py_ssize_t pos=0; ; ++pos) {
PyObject* arg = PyIter_Next(iter);
if (!arg) break;
PyTuple_SetItem(tuple,pos,arg);
}
}
return PyObject_CallObject(callable,tuple);
}
I'm not sure if I need to grow the size of the tuple myself or not. What's confusing me is the sentence in the documentation saying:
The tuple will always grow or shrink at the end.
I'm also not sure if I need to increment or decrement reference counts for any of these objects.
You're much better using PySequence_Tuple which can create a tuple directly from an iterable. There's probably other similar options to do this too.
If you did want to do it your way then you do need to call PyTuple_Resize each time you add to it (or resize it in chunks possibly). What the sentence
The tuple will always grow or shrink at the end.
tells you is that extra space is at the end of the tuple.
PyTuple_SetItem steals a reference, so you don't need to touch the reference count of the items you're adding. You should be doing some error checking though - PyIter_Next can raise an exception. You also need to decref iter and the tuple when you're done with them.
Problem
I need to change all list items during a loop. Is it possible?
Code
List<WebElement> elements = driver.findElements(By.xpath('//*[#id="id1"]//tr[td/a]'))
elements.eachWithIndex { element, index ->
...
if(...) {
...
i = index+1
elements = driver.findElements(By.xpath('//*[#id="id1"]//tr[td/a][position()>' + i + ']')) // new list content which must be use by loop
}
}
However, new list is not used by the loop.
Can you help and explain me why?
Thanks
Regards
EDIT 1
I need to retrieve element everytime.
List<WebElement> elements = driver.findElements(By.xpath('//*[#id="dzA26"]//tr[td/a]'))
for(int i = 1; i <= elements.size(); i++) {
WebElement element = driver.findElement(By.xpath('//*[#id="dzA26"]//tr[td/a][' + i + ']'))
...
}
So first of all while iterating over a List, changing or removing elements is not safe to do. It can be possible, but you should avoid it.
That's because you are trying to change the element it is currently iterating at. So the Iterator behind the '.each' closure gets confused and doesn't know where to go on after the current iteration.
If you have to change all elements with the same operation, you could use the List.collect() closure provided by groovy, which will return whatever you like into a new List.
e.g.:
List<WebElement> elements = elements.collect { element ->
return element.doSomething()
}
Edit 1
After your update there is a new Problem, because it seems like you always want to update all Elements int the List.
So why don't you create the List inside the Loop, fill it, and use it, then go to the next iteration.
e.g.:
for(int i = 0;i < threshold; i++) {
List<WebElement> elements = useMethodToRetrieveElementsFori(i);
elements.each {
// Do whatever has to be done with this element.
}
}
Or after looking at it a little longer, it seems obvious to use code reflection at that point. Because you want to dig deeper into the WebElements, you should call a method that calls itself if it needs to go one step further. With your idea, you'd be stuck in an endless loop.
Or we are missing the the whole point of the question.
"When you've found the treasure, stop digging!"
I'm wanting to use more functional programming in Groovy, and thought rewriting the following method would be good training. It's harder than it looks because Groovy doesn't appear to build short-circuiting into its more functional features.
Here's an imperative function to do the job:
fullyQualifiedNames = ['a/b/c/d/e', 'f/g/h/i/j', 'f/g/h/d/e']
String shortestUniqueName(String nameToShorten) {
def currentLevel = 1
String shortName = ''
def separator = '/'
while (fullyQualifiedNames.findAll { fqName ->
shortName = nameToShorten.tokenize(separator)[-currentLevel..-1].join(separator)
fqName.endsWith(shortName)
}.size() > 1) {
++currentLevel
}
return shortName
}
println shortestUniqueName('a/b/c/d/e')
Result: c/d/e
It scans a list of fully-qualified filenames and returns the shortest unique form. There are potentially hundreds of fully-qualified names.
As soon as the method finds a short name with only one match, that short name is the right answer, and the iteration can stop. There's no need to scan the rest of the name or do any more expensive list searches.
But turning to a more functional flow in Groovy, neither return nor break can drop you out of the iteration:
return simply returns from the present iteration, not from the whole .each so it doesn't short-circuit.
break isn't allowed outside of a loop, and .each {} and .eachWithIndex {} are not considered loop constructs.
I can't use .find() instead of .findAll() because my program logic requires that I scan all elements of the list, nut just stop at the first.
There are plenty of reasons not to use try..catch blocks, but the best I've read is from here:
Exceptions are basically non-local goto statements with all the
consequences of the latter. Using exceptions for flow control
violates the principle of least astonishment, make programs hard to read
(remember that programs are written for programmers first).
Some of the usual ways around this problem are detailed here including a solution based on a new flavour of .each. This is the closest to a solution I've found so far, but I need to use .eachWithIndex() for my use case (in progress.)
Here's my own poor attempt at a short-circuiting functional solution:
fullyQualifiedNames = ['a/b/c/d/e', 'f/g/h/i/j', 'f/g/h/d/e']
def shortestUniqueName(String nameToShorten) {
def found = ''
def final separator = '/'
def nameComponents = nameToShorten.tokenize(separator).reverse()
nameComponents.eachWithIndex { String _, int i ->
if (!found) {
def candidate = nameComponents[0..i].reverse().join(separator)
def matches = fullyQualifiedNames.findAll { String fqName ->
fqName.endsWith candidate
}
if (matches.size() == 1) {
found = candidate
}
}
}
return found
}
println shortestUniqueName('a/b/c/d/e')
Result: c/d/e
Please shoot me down if there is a more idiomatic way to short-circuit in Groovy that I haven't thought of. Thank you!
There's probably a cleaner looking (and easier to read) solution, but you can do this sort of thing:
String shortestUniqueName(String nameToShorten) {
// Split the name to shorten, and make a list of all sequential combinations of elements
nameToShorten.split('/').reverse().inject([]) { agg, l ->
if(agg) agg + [agg[-1] + l] else agg << [l]
}
// Starting with the smallest element
.find { elements ->
fullyQualifiedNames.findAll { name ->
name.endsWith(elements.reverse().join('/'))
}.size() == 1
}
?.reverse()
?.join('/')
?: ''
}
Does any common Java library provide a method to find an element in a finite collection and ensure that there was exactly one match?
The method could, for example, return null if nothing was found and throw an exception if multiple elements were found.
Currently I use my own Implementation (see below), but I'd rather not pollute business code with such utility methods (even if extracted in a separate utility package).
I also don't want the overhead of iterating over collection more than once, or an overhead of filtering collection and looking at the length of the result.
P.S. my current solution (which works, but is to be replaced with a library method):
public static <T> T getSingleMatch(Iterable<T> lookIn, com.google.common.base.Predicate<? super T> predicate) {
T foundItem = null;
for (T item : lookIn) {
if (predicate.apply(item)) {
if (foundItem != null)
throw new RuntimeException("multiple matches"); // alternatively: `return null;`
else
foundItem = item;
}
}
// alternatively: `if (foundItem == null) throw ...`
return foundItem;
}
One option is to separate out the two ideas into two methods, so that each method does one thing - then combine the calls
One method to lazily filter, returning a sequence of matching results
One method to return an item from a sequence, requiring it to be the only item
Guava has both of those:
Iterables.filter to filter lazily
Iterables.getOnlyElement to return the sole element of a sequence
So for example:
String match = Iterables.getOnlyElement(Iterables.filter(source, predicate));
int index = collection.indexOf(item);
if (index != -1 && index == collection.lastIndexOf(item)) {
// one and only one
}
If index != -1 it means no such item. If the next if statement doesn't evaluate to true it means that there are at least 2 items. You can restructure it to throw exceptions, return null or return the index or item. I trust you know how to do this based on your question.