How can I use the .getServicedEntity() method on a Resource Unit without casting the agent type? - anylogic

I built a custom block that, among other things, tells the resource entering portIn of the block to move to the resource's seizing unit. I use a moveTo block with the destination node as: (Node)((Cart)agent).getServicedEntity().getNetworkNode(); but I need to know the agent type and cast it into the method. I would like to make this a generic block that can be used in other models and with any Resource Unit.
I've tried using generic parameters in the custom block
then selecting the agent type:
and then trying: (Node)T.getServicedEntity().getNetworkNode(); but this results in compiling error: The method getServicedEntity() is undefined for the type T. Is there a way to do what I'm looking to do? I'm fine if the user has to select the agent type using the generic parameter pulldown, but I'd like to avoid having to change the code every time to add in all of the resource types available in the model using the instanceof command and then duplicating the code. Seems inefficient.

Well, your "T" extends Agent, and Agent does not know about getServicedEntity.
What your T extends needs to know it is a resource unit. Easiest solution I can see:
Create a parent class MyResourceUnit (but do not instantiate it)
Make sure it is "used in flowcharts as Resource Unit"
Make all agent types that should ever use your custom block to extend MyResourceUnit
Now in your custom block, you should make T extends MyResourceUnit

Related

Accessibility of main from agent's statechart

May I know if main is accessible to all elements in the model?
The reason I ask is that I have created a simple M/M/n model with one resource type created through ResourcePool. The behaviour of the resource type is implemented using a statechart. I write a simple code in the action of a transition in the statechart, i.e.
if (agent_variable < main.my_parameter) { /* do something */ }
The code does not compile and give an error message "main cannot be resolved to a variable". I cannot figure out why the statechart cannot recognise main.
Thanks
Welcome to SOF, Stephan.
First, always use code-complete (Ctrl+space). You will then see what is and what is not possible to access from where you are. In your case, main would not even be an option :-)
Now, your model root (typically that is main) is always accessible via getModelRootAgent() but you will need to cast it to your Main class, i.e. ((Main)getModelRootAgent())
Otherwise, Main is accessible to all agents that are somehow embedded into Main. This is classic OOP principles. Your Resource agents are not actually an embedded population so no direct access to Main. (You can make that happen in the ResourcePool properties, though)

Anylogic: Declare parameter of type ArrayList

I'm building a class (sorry - Agent) that will work with a set of Tank objects (Fluid Library) - doing things like monitoring individual levels or total level of all tanks, reporting on levels and initiating actions based on levels - things of that nature. For argument's sake let's call it a "TankMonitor" agent.
Ideally I'd like to be able to define a Parameter in my "TankMonitor" agent that allows me to define the tanks of interest when I place a TankMonitor in main. I have tried to define the type of the parameter as Other - ArrayList<Tank> however I don't know how to set up the next step to allow me to populate the ArrayList of Tanks when I put an instance of this agent in main. My preference would be to have a list type control to populate the ArrayList - much like the way the AnyLogic Seize block allows you to specify multiple resource pools to choose from.
Has anyone attempted this before and been successful?
This is possible as follows:
Change the type to "Other" and then 'Tank[]' , i.e. an Array of Tanks
Change the control type to "one-dimensional array"
Example below. Now you have the same UI to pre-define tanks at design time for your agent instance.
In addition to Benjamin's perfect answer, I'd just add the manual workaround, which is not needed here but can be useful when the parameter in question has a more complicated structure than covered by the pre-made controls, say a list of lists, a map, or similar.
In such a case, the Control Type is still Text, and populating it in an instance happens by pointing it to a new object of the parameter's type. E.g. for an ArrayList<Tank> parameter, you might instantiate a new ArrayList object, which you fill with a list of objects like so:
new ArrayList<Tank>(Arrays.asList(tankA, tankB))
In the Java code, whatever is written into that text box will end up on the right side of a parameter assignment statement in the embedded Agent instance's auto-generated parameter setup function. Therefore, multi-statement code won't work in this spot. Instead, if the process of building the parameter value doesn't fit neatly into a single expression, you can hide the code in a function which returns the desired object, and call that from the parameter's text box.

How to Install a module that needs an instance per something else that is registered in Castle Windsor

I am trying to get the hang of IoC and DI and am using Castle Windsor. I have an object I have created that can be multiply instantiated but over different generic types. For example
MyType<Generic, Generic2>
on Installation of MyType's assembly
container.Register(Component.For(typeof (IMyType<>)).ImplementedBy(typeof (MyType<>)));
Then in my main modules initialization I install MyTypes module with MyTypeInstaller which is a IWindsorInstaller.
Then I am manually resolving the various types of MyType that I want (this will actually be spread around different installers). But something like
container.Resolve<IMyType<type1, type2>();
That creates an actual instance of MyType registered for the generic types passed in.
This works fine, I get the instances of MyType<,> I need created.
Now, finally I have another module I have created that I will install last. I want to say,
container.ResolveAll<IMyType<,>>()
then create this instances of this new object for each object that exists.
However I cant seem to resolve all of the IMyTypes<,> without knowing the concrete types that each one were instantiated as.
At any rate, it is possible I am just doing this wrong and want feedback in general as well.
First, if MyType<T1,T2> can only be instantiated once for each combination of T1,T2 then you should be registering it is a Singleton.
Second, You cannot call strongly type container methods (like ResolveAll<T>) with an open generic - it MUST be a closed type.
Third, MyType is an open generic type and the number of closed generic classes is infinite (generic type constraints are not considered by the container). So, as far as the container is concerned you can call Resolve<ANYTHING, ANYTHINGELSE> and it will attempt to provide a MyType<ANYTHING,ANYTHINGELSE> for you. If ANYTHING and ANYTHINGELSE don't satisfy the type constraints then you will simply get a run time error.
Even if you could call ResolveAll<IMyType<,>>() what would you expect it to return given that you have registered an open generic implementation?

AppleScript application support: 'duplicate' command fails

I am trying to support the 'duplicate' command. It works fine for duplicating the top class:
tell application "SpellAnalysis" to duplicate level 1
This, however, crashes:
tell application "SpellAnalysis" to duplicate (get unit 1 of (get level 1))
I have provided index specifiers for both classes, where the outer container for 'unit' is 'level'. Oddly, I can specify a property of the unit class like this:
tell application "SpellAnalysis" to (get general rule of unit 1 of (get level 1))
The culprit seems to be that the 'objectsByEvaluatingSpecifier' always returns a null value when used within NSCloneCommand subclass, as well as the unit class' objectSpecifier method, where its needed.
I was finally able to support AppleScript 'duplicate' command. Although the normal way to support the command is by sub-classing 'NSCloneCommand', with this method, your direct parameter results in a specifier that specifies the containing object and not the direct object--as a special provision of the 'NSCloneCommand'. I suppose this is meant to facilitate the case when you would be duplicating an object belonging to a document, where the document class provides the means for creating new constituent objects. Unfortunately, in my case, my constituent objects take part in their own duplication and need to know their specifiers to do so. The solution was to support the 'duplicate' command by the optional technique of creating a custom 'duplicate' command within my application's suite that entailed subclassing the more general 'NSScriptCommand'. This alternative avoids any redirection of the specifier returned from the 'directParameter' method of the 'NSScriptCommand' class. I was able to work from there to derive all the child class-objects for cloning.

Does GWT deferred binding return singletons of the same type within the scope of a single EntryPoint?

Let's say I have a number of GWT modules which are used as libraries, and one module with an entry point which inherits all of the library modules.
Each of the submodules needs to access a single instance of SomeClass.
If I call GWT.create(SomeClass.class) in modules A & B, do I get the same instance? If so, is this guaranteed?
No. GWT.create(SomeClass.class) compiles to new SomeClass(), unless there is a rebind rule of some kind - a replace-with or a generate-with rule will cause this to instead invoke the default constructor of whatever type is selected by those rules.
This means that GWT.create is not a suitable way to provide access to a singleton instance. Instead, consider some DI tool like Gin, or manual DI by always passing around the same instance. It is also possible to use the static keyword to keep a single instance where all code compiled into the same app can reference it.