Greenfoot Actor not in World error - object

When my enemy gets to the bottom of the screen I want to remove and if the enemy gets hit by bullets i want to remove it. The error is : java.lang.IllegalStateException: Actor not in world. An attempt was made to use the actor's location while it is not in the world. Either it has not yet been inserted, or it has been removed.
I think the problem is because there is two calls to removeObject or the getOneIntersectingObject method is causing an error. How do I fix this?
This is the code causing the error
public class Enemy extends Actor
{
public void act()
{
setLocation(getX(), getY() + 3);
if (getY() > getWorld().getHeight() + 30 )
getWorld().removeObject(this);
Actor fire = getOneIntersectingObject(Fire.class);
if(fire != null)
getWorld().removeObject(this);
}
}

Greenfoot doesn't allow any interactions with the world after an actor has been removed from it. If your Y coordinate causes this actor to be removed from the world in the first if statement, it is an error to call getOneIntersectingObject afterwards.
There's several ways to solve this: you could wrap the ensuing lines in an else clause, you could make an early return if you remove yourself in the first if, or you could use a boolean flag to keep track of whether you want to remove yourself, but only do the removal as the very last item in the act() method.

Related

How to show the flow termination in Sequence Diagram

Basically, I'd like to depict the below logic in a Sequence Diagram:
if (ShopIsOpen) {
if (AccessTokenIsExpired) {
if (RefreshTokenInExpired) {
return "Not Authorized";
}
IdentityServer.RequestAccessTokenByRefreshToken();
return Resource.RequestResourceByAccessToken();
}
} else {
return "Shop is closed";
}
I've come up with the below diagram, but I am not sure if it is correct.
Mainly, I am not sure if break in the diagram correctly communicates the intention of termination of flow: does it imply jumping out of the outer opt or the outer alt?
Any help is much appreciated.
The break fragment leaves the immediately enclosing fragment. In your case that would be the opt fragment. So, it is not correct. Why don’t you use nested alt fragments?
Some additional remarks: The reply to a synchronous message is shown with a dashed line and the returned value is shown with a leading colon (and the name of the original message, but I think it is obvious here anyway).

Running methods on different threads

simply put for a hw problem I need to run a bubble sort with 3 million elements. Do this normally. and then sort 4 individual lists (not nearly accurate but is all thats required) of 750000 elements each on a different thread.
I have a class that extends thread that simply prints a line if im running the thread. But I'm not sure how to get it to run a method
class thread extends Thread{
override def run()
{
// Displaying the thread that is running
println("Thread " + Thread.currentThread().getName() +" is running.")
}
}
//this for loop is in an object
for (c <- 1 to 5)
{
var th = new thread()
th.setName(c.toString())
th.start()
}
I am going to stick to answering the question you asked instead of trying to do your homework for you. I hope that is enough to get your started trying things out for yourself.
Recall that class names should be capitalized. That is probably a good thing to remember as your instructor will probably mark you down if you forget that during an exam.
class MyThread extends Thread{
override def run() = {
// Displaying the thread that is running
println("Thread " + Thread.currentThread().getName() +" is running.")
sort()
}
def sort() = {
// my sorting code here
}
}
If your instructor has not restricted you to using Thread only, I would also, similar to Luis Miguel Mejía Suárez, recommend Future instead of Thread. The syntax it uses is cleaner and preferable for how I would do multithreading in a professional setting. However, the choice may not be yours, so if your teacher says use Thread, use Thread.
For a primer on using Futures, see here.
Good luck!

FLTK: Fl_Value_Input subclass does not receive FL_KEYDOWN events (only FL_KEYUP)

I subclassed FL_Value_Input such that I can give the widget a color when it is modified, but the user has not yet pressed enter.
The silly thing is that the handle(int e) function is never invoked in case the event is a FL_KEYDOWN event, other events (such as FL_KEYUP, FL_DRAG, FL_FOCUS etc) are being propagated fine.
The widget is part of a widget hierarchy... Could it be that one of its parents in this hierarchy is absorbing this specific FL_KEYDOWN event?
EDIT: apparently, the widget also doesn't have focus (tested by comparing this to Fl::focus()), which is odd, as I am typing into it.
Any help would be appreciated.
Fx_Value_Input::Fx_Value_Input(int x, int y, int w, int h, const char* l)
: Fl_Value_Input(x, y, w, h, l)
{}
int Fx_Value_Input::handle(int e)
{
int r = Fl_Value_Input::handle(e);
if (e == FL_KEYBOARD)
{
if ((Fl::event_key() != FL_Enter && Fl::event_key() != FL_KP_Enter ) )
color(Fx::get_modified_color());
else if ((Fl::event_key() == FL_Enter || Fl::event_key() == FL_KP_Enter) && color() == Fx::get_modified_color())
color(FL_WHITE);
redraw();
}
return r;
}
Using FL_KEYDOWN is the Windows way of doing things, which, as you have found, doesn't work because you need to subclass Fl_Input_: not Fl_Input and even then, it doesn't work properly.
Instead, use when(FL_WHEN_CHANGED|FL_WHEN_ENTER_KEY). Check changed() when keys are pressed and clear_changed(). It isn't set when the enter key is pressed. You can change colours back when that condition is met.
inputkey = new Fl_Input...
inputkey->when(FL_WHEN_CHANGED| FL_WHEN_ENTER_KEY);
inputkey->callback(cb);
....
void cb(Fl_Widget *ob)
{
Fl_Input* ip = dynamic_cast<Fl_Input*>(ob);
if (ip->changed())
{
// change colour
ip->clear_changed();
}
else
{
// change colour
}
}
Got a reply on the FLTK Google group, explaining the issue... There is no easy workaround for this...
FLTK delivers key strokes directly to the focus widget. Fl_Value_Input
includes an Fl_Input widget, and that widget becomes the focus widget when you click in the input field.
Hence the "parent" Fl_Value_Input never sees the Fl_KEYDOWN events.
Note that I quoted "parent" because Fl_Value_Input is a very
special case. It's not derived from Fl_Group, but it behaves somewhat
like an Fl_Group widget.
So why does your derived widget get FL_KEYUP events? That's another
feature of FLTK: FL_KEYUP events are also delivered to the focus
widget in the first place. However, AFAICT no core FLTK widget
handles FL_KEYUP events - they all return 0 in their handle()
methods. If the focus widget doesn't handle an event FLTK tries to
deliver it to the parent widget and then up through the widget
hierarchy until it reaches the top level window. Hence (and this is
IMHO weird) eventually all widgets will receive all FL_KEYUP events
unless one widget returns 1 from its handle() method (which is
usually not the case). Depending on the depth of the focus widget in
the total widget hierarchy it may be that some widgets get the same
FL_KEYUP event multiple times, because all parent groups of the focus
widget try to deliver the event to all their children.

Sequence diagram multiple calls to same method from different locations

I want to create a sequence diagram of my program.
The code goes like this:
I have a class SFC, this class starts with the method parseScenario(). The parseScenario() method is a loop until all elements in a list are looped over. In this loop I call the parseEntryLine(e) method, where e is an entry in that list.
Now my problem occurs.
In parseEntryLine(e) there is an IF statement as follows:
if (currentGM.isBrick ()) {
animateExpr(currentGM);
//Check if it has a next
if (currentGM._next != null) { parseEntryLine (currentGM._next); }
} else {
//random code
parseEntryLine(buttonStringClicked);
}
}
How do I model this in a sequence diagram?
I managed to work until this point:
(I realize this might already be a wrong start).

CRM PlugIn Pass Variable Flag to New Execution Pipeline

I have records that have an index attribute to maintain their position in relation to each other.
I have a plugin that performs a renumbering operation on these records when the index is changed or new one created. There are specific rules that apply to items that are at the first and last position in the list.
If a new (or existing changed) item is inserted into the middle (not technically the middle...just somewhere between start and end) of the list a renumbering kicks off to make room for the record.
This renumbering process fires in a new execution pipeline...We are updating record D. When I tell record E to change (to make room for D) that of course fires the plugin on update message.
This renumbering is fine until we reach the end of the list where the plugin then gets into a loop with the first business rule that maintains the first and last record differently.
So I am trying to think of ways to pass a flag to the execution context spawned by the renumbering process so the recursion skips the boundary edge business rules if IsRenumbering == true.
My thoughts / ideas:
I have thought of using the Depth check > 1 but that isn't a reliable value as I can't explicitly turn it on or off....it may happen to work but that is not engineering a solid solution that is hoping nothing goes bump. Further a colleague far more knowledgeable than I said that when a workflow calls a plugin the depth value is off and can't be trusted.
All my variables are scoped at the execute level so as to avoid variable pollution at the class level....However if I had a dictionary object, tuple, something at the class level and one value would be the thread id and the other the flag value then perhaps my subsequent execution context could check if the same owning thread id had any values entered.
Any thoughts or other ideas on how to pass context information to a new pipeline would be greatly appreciated.
Per Nicknow sugestion I tried sharedvariables but they seem to be going out of scope...:
First time firing post op:
if (base.Stage == EXrmPluginStepStage.PostOperation)
{
...snip...
foreach (var item in RenumberSet)
{
Context.ParentContext.SharedVariables[recordrenumbering] = "googly";
Entity renumrec = new Entity("abcd") { Id = item.Id };
#region We either add or subtract indexes based upon sortdir
...snip...
renumrec["abc_indexfield"] = TmpIdx + 1;
break;
.....snip.....
#endregion
OrganizationService.Update(renumrec);
}
}
Now we come into Pre-Op of the recursion process kicked off by the above post-op OrganizationService.Update(renumrec); and it seems based upon this check the sharedvariable didn't carry over...???
if (!Context.SharedVariables.Contains(recordrenumbering))
{
//Trace.Trace("Null Set");
//Context.SharedVariables[recordrenumbering] = IsRenumbering;
Context.SharedVariables[recordrenumbering] = "Null Set";
}
throw invalidpluginexception reveals:
Sanity Checks:
Depth : 2
Entity: ...
Message: Update
Stage: PreOperation [20]
User: 065507fe-86df-e311-95fe-00155d050605
Initiating User: 065507fe-86df-e311-95fe-00155d050605
ContextEntityName: ....
ContextParentEntityName: ....
....
IsRenumbering: Null Set
What are you looking for is IExecutionContext.SharedVariables. Whatever you add here is available throughout the entire transaction. Since you'll have child pipelines you'll want to look at the ParentContext for the value. This can all get a little tricky, so be sure to do a lot of testing - I've run into many issues with SharedVariables and looping operations in Dynamics CRM.
Here is some sample (very untested) code to get you started.
public static bool GetIsRenumbering(IPluginExecutionContext pluginContext)
{
var keyName = "IsRenumbering";
var ctx = pluginContext;
while (ctx != null)
{
if (ctx.SharedVariables.Contains(keyName))
{
return (bool)ctx.SharedVariables[keyName];
}
else ctx = ctx.ParentContext;
}
return false;
}
public static void SetIsRenumbering(IPluginExecutionContext pluginContext)
{
var keyName = "IsRenumbering";
var ctx = pluginContext;
ctx.SharedVariables.Add(keyName, true);
}
A very simple solution: add a bit field to the entity called "DisableIndexRecalculation." When your first plugin runs, make sure to set that field to true for all of your updates. In the same plugin, check to see if "DisableIndexRecalculation" is set to true: if so, set it to null (by removing it from the TargetEntity entirely) and stop executing the plugin. If it is null, do your index recalculation.
Because you are immediately removing the field from the TargetEntity if it is true the value will never be persisted to the database so there will be no performance penalty.

Resources