Access the EPartService after an RCP application has initialized - eclipse-plugin

After my application initialized, I'm trying to automatically create a part within a part stack. I need the EPartService for this but I can't think of any way to properly get a hold of this service.
I've tried using the LifeCycle management to get the current IEclipseContext. However, whenever I try to access the service using the context, it's not found.
Any idea how I can do this?

You should be able to inject the EPartService in any of the defined methods in your life cycle class. However you won't be able to show a part until the application startup is complete. So use the App Startup Complete event, by adding a method like this to the life cycle class:
#Optional
#Inject
public void appStartupComplete(#UIEventTopic(UIEvents.UILifeCycle.APP_STARTUP_COMPLETE) Event event,
EPartService partService)
{
....
}

Related

Adding a "REVERT" command to a C++ document/view application

In the app I'm writing under CS 2022 document/view architecture, I want to add a "REVERT" command to the main menu. I've tried adding a handler that invokes "Serialize" in the document class, but I get errors.
Also, I know Serialize needs to know if I'm loading or saving, and I don't know how to handle that.
I tried adding this:
void CMSDoc::OnRevert()
{
Serialize(ar);
}
...but "ar isn't recognized. Is this the right place for this function to work?

getCurrentActivity in ReactContextBaseJavaModule returns null

I'm coding a native Android module with React Native 0.46 and I have trouble getting the current activity instance from the module.
I have a class extending ReactContextBaseJavaModule, which contains a built-in getCurrentActivity() method. However, each time I call this method, I get a null.
I think it's because I'm calling this in my module constructor, which is executed at the start of the Android application, maybe before an Activity is instantiated ?
If you guys know a clean way to access the current Activity instance from within the module (without having to store an Activity instance at some point and passing it around, if possible), I'll be glad !
According to these posts on the react-native GitHub page, it is by design that you cannot access the current activity in the constructor of a native module. The modules may be used across Activities, and may be created before an associated Activity has resumed.
The expectation is that you can use getCurrentActivity when needed during operations, for example from any #ReactMethod in the module.
same as Myk Willis answer, getCurrentActivity can be accessed inside #ReactMethod like this example:
public class ExampleModule extends ReactContextBaseJavaModule {
Activity activity;
#ReactMethod(isBlockingSynchronousMethod = true)
public void MinimizeExample(String params) {
activity = getCurrentActivity(); // get current activity
}
}

In JProfiler, why does my object not show in the All Objects view?

I'm new to JProfiler. I've created a very simple test application. Here's a Main.java with a main method:
package com.example;
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException {
Example e = new Example(); //Gets gc'ed?
System.out.println(e.getMessage());
System.in.read();
System.exit(0);
}
}
Note that I pause until key-press. This way I'm sure the main scope does not end until I press a key, so I expect e to exist and not be garbage collected (please correct me if this assumption is incorrect). The Example class:
package com.example;
public class Example {
public String getMessage() {
String testString = "This is the test string. Press a key to exit.";
return testString;
}
}
I start the above application using the JProfiler Eclipse plugin. I've created a session that's based on the Full Instrumentation profile; I've removed the Java EE and JDBC specific probes and left the rest at defaults.
Now when the profiler starts, I go to the all objects view and I'd expect to find com.example.* classes, but I find none; why is that happening?
Ok, so maybe I can only find these objects when I use another view, like the Allocation call tree, so I enable Allocation Recording using the button in the view (it's disabled by default). It asks me to click on calculate allocation after that, which pops up a dialog. I accept the defaults and I'm presented with an empty view that auto-updates in eternal emptiness.
So then I try Heap Walker. It asks me to make a dump first. I get a dialog that provides me the option to "select recorded objects" which is default unselected. I leave it at defaults and am presented with an instance count view. However, my object is not findable in this Classes view I'm presented with.
So I suppose I'm doing something fundamentally wrong; What should I do to see my objects, and specifically the precise instance count of my objects?
UPDATE 1:
I've found a part of the problem. When the profiler window comes up, it presents you with the Session Startup dialog, where you can choose the profile and set various settings. There is a little section on the first tab called "Startup" which has a setting called "Initial recording profile", which by default is set to [no recordings]. When I leave this at its default, I cannot find the Example object. When I set it to "CPU recording" I can find my Example object in the All Objects view.
UPDATE 2:
I cannot find the object in Heap Walker. When I select com.example.Example in the All Objects view, I can right-click the object and choose (show object in Heap Walker). When I do so, Heap Walker tells me there's no such object on the heap! What gives?
UPDATE 3:
The com.example.Example object seems to show up sometimes, sometimes not. I cannot figure out why. Additionally, when it shows up, it will disappear from the All objects view, even though the main loop has not exited yet, even though the com.example.Example object should still be alive...
UPDATE 4:
It turns out e is garbage collected, regardless of scope ending on IBM's J9 JVM. See my answer to this which modifies main to invoke a second method after the key-press wait, which forces the object to remain alive.
I finally truly solved this mystery. It turns out I'm running IBM's J9 VM. Apparently, J9 garbage collection is quite a bit more aggressive: It will clean up e within the main scope if e is not going to be used within that scope anymore. I have verified that this specific behaviour does not happen with Oracle's JVM.
So long story short: on IBM J9, you cannot assume that objects stay alive within the scope of a block. On Oracle's JVM, at least by default, e is not garbage collected until after the block ends, regardless of further usage of e.
On IBM J9, when you want to force the object to stay in existence, there has to be a future usage of it. To prove this I modified Example.java to contain the following:
package com.example;
public class Example {
public String getFirstMessage() {
String firstTestString = "This is the first message: Hello!";
return firstTestString;
}
public String getSecondMessage() {
String secondTestString = "This is the second message: Goodbye!";
return secondTestString;
}
}
Then, in main I made sure to have an invocation of getSecondMessage() AFTER the wait-on-key-press (System.in.read()). This way, we know for sure that the GC cannot cleanup the object before main's scope ends because there's an invocation waiting in the future, happening right after the user presses a key. So Main.java looks like:
package com.example;
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException {
Example e = new Example();
System.out.println(e.getFirstMessage());
System.in.read();
System.out.println(e.getSecondMessage());
System.exit(0);
}
}
Profiling the above code regardless of CPU recording settings previously thought to be a factor in this will work as expected: the object stays alive because it cannot be garbage collected before the key is pressed.
This way I'm sure the main scope does not end until I press a key, so I >expect e to exist and not be garbage collected (please correct me if this >assumption is incorrect).
That is correct. The "Example" object will be held by a stack reference at that point and cannot be garbage collected. Both the "All objects" view and the heap walker will show this object.
I just tested your example and it works for me with both JProfiler 8.1.4 and JProfiler 9.0.2.
Use the "View->Find" action to search for "Example".

How do I make Message targets be the only recipent of a targeted Message?

First time poster.
I'm using MVVM-Light with Silverlight 4 and RIA Services. This has been a learning experience! But so far, it's working beautifully. I was wondering two things. Right now, I'm using the Messenger framework to pass EntityObjects back to the ViewModel. For instance, I need to open a View Model with a specific "Course" object. So I instantiate the View, and the View sends a Message to the ViewModel with the Course. I've got a couple questions.
First question: Is this the best way to do this? I don't want to use Prism or Unity or any of those other things because I don't have the time to learn them. (This was, for me, the big draw of MVVM Light. The Light part.) But I couldn't see any other way to pass parameters to the VM Locator.
The second part is, this means I am sending messages from the View to that View's specific ViewModel. My messages look like this:
Tuple<Models.Course, Services.VWDS> courseDomainContextTuple = new Tuple<Models.Course, Services.VWDS>(Course, DomainContext);
NotificationMessage<Tuple<Models.Course, Services.VWDS>> message = new NotificationMessage<Tuple<Models.Course, Services.VWDS>>(this, this.DataContext, courseDomainContextTuple, Models.MessageString.EditCourse);
Messenger.Default.Send<NotificationMessage<Tuple<Models.Course, Services.VWDS>>>(message);
So, as you can see, I'm bundling the Course and the DomainContext (Ah RIA. Why won't you let me get the Context from the EntityObject?) and sending them to the ViewModel (which is "this.DataContext") - and yes, I know I should make a class for that message.
Here's the problem - every object that gets a Course and a DomainContext receives that message, not just the VM that I've designated the Target.
So, second question: Is that by design, or is that a bug, or am I doing something wrong?
Thanks!
To answer your second question, if you're sending a NotificationMessage of a specific type, anything registering for that same message type will receive the message. If you want to limit who receives the message, either create a new message class inheriting from MessageBase or NotificationMessage or whatever, send your message with a Token, or have an if statement in your message receive handler to filter out messages you don't care about.
Messaging is more useful when you need to communicate from one ViewModel to another, or you need to send a message where zero to many things can take action on it. From your View's code behind, I think you should just call your ViewModel directly. Its easy enough - here's how I usually do it in my code.
public partial class ExampleView : UserControl
{
private IExampleViewModel ViewModel
{
get { return this.DataContext as IExampleViewModel; }
}
public ExampleView()
{
InitializeComponent();
// Call directly to my View Model
ViewModel.SomeMethod();
// Register for View Model's event
ViewModel.SomeEvent += ViewModel_SomeEvent;
}
private void ViewModel_SomeEvent(object sender, EventArgs e)
{
// do stuff
}
}
I also included in the example how I handle communications from the ViewModel back to the View - through events.

Explain ASP.NET Events

See Also:
understanding events and event handlers in C#
As a web dev, I don't typically have to get into building my own events for objects, since most are inherent in the page. However, now I'm into a pretty complex (web) project where I think I may have to use them. I just read a chapter out of Pro VB 2008 and the .NET 3.5 Platform regarding events, delegates and lambdas (ch. 11) and while I have a better idea of what's going on, I am still having trouble wrapping my mind around when exactly to use them and how to use them. I understand their implementation, but the example in the book is a bit contrived.
I was hoping someone with a bit more understanding on the subject of events could provide me with a really solid example.
For my real-world application, I'm trying to use an event that would let me know when an item (some class, named OrderItem) has been updated and perform actions based on whether or not it's been updated. I considered using a flag/boolean property, but I know this doesn't smell right, and it's high-time I learn about how to use events correctly.
Thanks a lot!
EDIT Ok, so I guess to clarify a bit, what is the point of calling an event when all it is doing is calling a method? Why not simply call the method? This isn't a duplicate either, as I'm talking conceptually and she wants to know about handlers specifically. Also, I want to know what the difference would be between using an event or a "flag" property. And what do people mean by "subscribe" to an event?
Lets say you had an elevator system, and the part that moves up and down is called the ElevatorCar. When a person pushes a button to go to the 5th floor, it would make sense for the ElevatorController to call the ElevatorCar.RequestToFloor(5) method. Now when the car actually arrives at the 5th floor, it makes sense for it to raise an event like ArrivedAtFloor, passing 5 as the argument. The ElevatorController class would subscribe to the ArrivedAtFloor event of the ElevatorCar class.
This is all becauase the ElevatorCar class doesn't "know" anything about the ElevatorController class, but the ElevatorController class does know about the ElevatorCar class. Therefore the ElevatorCar class is given instructions by means of Methods, and it notifies the outside world of stuff that happens by means of events.
Does that make any sense?
EDIT:
Ok, first, go read the excellent answer listed in the See Also link (assume you've done that). An event is basically an object saying "if you want me to call you whenever X happens, then register your method here". Registering an event handler with the event is "subscribing". This allows encapsulation. So you can write, for instance, your ElevatorCar class once, and use it many times by many other classes.
As for the difference between using an event, or just calling a method, you have to ask yourself, should the ElevatorCar know about the ElevatorController class. If ElevatorController calls ElevatorCar.GoToFloor(x), how could the ElevatorCar class "call back" to ElevatorController without storing a reference to ElevatorController? That means the call has to become ElevatorCar.GoToFloor(int floor, ElevatorController ctrlr). Then the ElevatorCar class eventually has to call ctrlr.ArrivedAtFloor(floor). But you get into a lot of complexities... what if there's more than one car? You probably have to call ctrlr.ArrivedAtFloor(floor, this). Passing around references to yourself isn't optimal.
As for just setting a property, how does the other class know to come and read the property? The only way is to poll the property over and over to check for it to change. You can solve this, of course, by implementing INotifyPropertyChanged, but then again you're back to events!
Events are a specific case of the Inversion of Control (IoC) pattern. The traditional control flow, the caller invokes a method on the callee (like you are suggesting). With IoC (and thus events), we change around the application control and instead of tell the callee what to do, we tell the callee to notify us when something we are interested in happens.
Consider the case of a Timer. I want to be notified every 5 seconds (say). I don't want to constantly poll the timer ("is it time yet? is it time yet? is it time yet?"). Instead, I want to invert the flow control of my application. I want to tell the timer: "When it's time, please tell me by calling this method." That way, control is "inverted", the callee is invoking a method on the caller!
Consider the following code ...
using System;
using System.Timers;
namespace TestTimer
{
class Program
{
static void Main(string[] args)
{
// create my timer.
var t = new System.Timers.Timer(1000);
// register for notification
// tell the timer, "when it's time, call TimerGoesOff method"
t.Elapsed += new ElapsedEventHandler( TimerGoesOff );
// start the timer
t.Start();
// wait
Console.ReadLine();
}
// this gets called when the timer goes off
public static void TimerGoesOff(object source, ElapsedEventArgs e)
{
Console.WriteLine("The Time is " + e.SignalTime);
}
}
}
Rather than call a method on the Timer to ask when it will go off again (as you suggest), I tell it, "when you go off, call the TimerGoesOff" method. Now, instead of just waiting for the Timer to go off, I could do some work. Consider this code ...
using System;
using System.Threading;
using System.Timers;
namespace TestTimer
{
class Program
{
static void Main(string[] args)
{
// create my timer.
var t = new System.Timers.Timer(1000);
// register for notification
t.Elapsed += new ElapsedEventHandler( TimerGoesOff );
// start the timer
t.Start();
// do some work while timer is going
new Thread(() => DoWork()).Start();
Console.ReadLine();
}
// this gets called when the timer goes off
public static void TimerGoesOff(object source, ElapsedEventArgs e)
{
Console.WriteLine("The Time is " + e.SignalTime);
}
public static void DoWork()
{
for (int i = 0; i < 5; i++)
{
Console.WriteLine( "Working ..." );
Thread.Sleep( 1000 );
}
}
}
}
Now, I get output something like ...
Working ...
The Time is 8/25/2009 1:05:59 PM
Working ...
Working ...
The Time is 8/25/2009 1:06:00 PM
Working ...
The Time is 8/25/2009 1:06:01 PM
Working ...
The Time is 8/25/2009 1:06:02 PM
The Time is 8/25/2009 1:06:03 PM
I have used the Timer.Elapsed Event to change the control flow of my application. I can go off and do work while "waiting" for the timer event to pulse. This is made possible by IoC and Events.
This is particularly visible (hehe) in User Interfaces. I don't want to keep asking "has the user done anything yet? has the user done anything yet?" (that's the way it used to be done way back when). Instead, I tell Controls for example, "when the user clicks you, let me know". That way, I can go off and do other great stuff and still be responsive to the user.