This page describes standard solutions for recurring oddities and nasties that we have ran into over the years when building EwE6.
The following issues are discussed on this page:
Take it from us. Users can find very creative ways to use a software product in ways that a programmer could never, ever have predicted. As such, it is of vital importance that your code is robust to failures, even if you do not know in what ways your product may fail. It's rarely a good think to be caught with your pants down, and this section aims to provide a few simple guidelines.
Make your code robust to failures by encapsulating big function calls in ?Try / Catch blocks. Public methods on public classes are often the entry point to deeper functionality, and placing a Try / Catch inside the public methods is a good way to capture any internal failures within your code. We've done the same in the plug-in framework, where every plug-in point call is wrapped in a Try / Catch block to make sure EwE is not affected by a failing plug-in point or button click.
Take for instance the code that runs in response to a 'Run' button click on the Run Ecosim form:
Private Sub OnRun(ByVal sender As System.Object, ByVal e As System.EventArgs) _ Handles m_btnRun.Click Try If Not Me.IsRunning Then Me.m_iTimeSteps = Me.Core.nEcosimTimeSteps Me.m_graph.Refresh() Me.Core.RunEcoSim(AddressOf TimeStepFromEcoSim_handler, True) End If Catch ex As Exception cLog.Write(ex, "form RunEcosim.OnRun") End Try End Sub
Note that in EwE we prefer not to rely on exceptions for regular error testing. Exception handling is very processor intensive, and a simple ?If / Then test is endlessly faster than bluntly executing code and waiting for the exceptions to happen. As such, we suggest to only use exceptions to capture unforeseen problems.
The EwE Log file, created and managed by the core, and stored in the Windows application data folder, contains a track list of important actions taken by !EwE in response to user requests and a track record of failures and successes. The purpose of the log is to provide postmortem diagnostics when an error has occurred. You can use the log as well in your plug-ins. Frankly, we think you should, because
.NET is in theory system-independent, and .NET applications can be deployed under Unix, Linux, MacOS, etc using runtime environments such as ?Mono. However, not all .NET features work under Mono, most notably the Microsoft.VisualBasic assembly. This can prove problematic since every Visual Basic project by default receives a reference to this assembly.
In EwE we have worked around this problem by redefining key types and constants from the Microsoft.VisualBasic assembly in ?EwEUtils. You should not use Chr, Asc, IIF, TriState, MsgBox, UBound, InStr, vbTab, vbCrLF and a whole whack of other old and familiar constructs if you wish your application to run on any other OS than Windows.
To remove reliance on Microsoft.VisualBasic simply remove the auto-generated reference in the project properties References page. For most constructs .NET offers a solid alternative (for instance Array.GetUpperBound()), but for other constructs you may have to be creative (vcTab becomes Convert.ToChar(9).ToString() - or do you have a better idea?).
The EwE source code now fully utilizes 64-bit capabilities. In order to make sure that Windows finds the correct 32 or 64 bit Access drivers make sure you always compile your EwE6 main project against x86 or x64, never against AnyCPU in Menu > Build > Configuration Manager.
Note that 64-bit EwE will not be able to find 32-bit Access database drivers and vice-versa.
Please adhere to the User Interface Guidelines when building user interfaces.
Theoretically, the EwE6 scientific interface can be localized to any language. In intention all language-specific elements in EwE are provided in either localizable forms or in localizable resource tables. We have tried to consistently implement this but exceptions may exist; please let us know if you find any.
The ScientificInterfaceShared assembly offers a whack of shared resources, such as strings and images, for plug-ins and the main Scientific Interface to share to reduce the amount of scattered resources that need localizing. In your assembly simply add a statement such as import ScientificInterfaceShared.My.Resources = SharedResources, and access all shared resources on the imported SharedResources thingy.
When you develop your own plug-ins with a user interface, please try to stick to the following resource guidelines: