How can I automate the t4 code generation for SubSonic - subsonic3

I'm using SubSonic 3 (ActiveRecord mode) to generate the code for my DAL. It uses T4 templates (.tt) files that as soon as you save, generate the code for you.
I want to automate this as part of my NANT build, but I can't get this to work. I know that MS provide a tool called TextTransform to generate the code from T4 templates, but in the case of the SubSonic templates this doesn't seem to work - I think the templates make some assumptions about the template being run from within Visual Studio, which doesn't seem to work from the command line. The error I get when I try to run it against ActiveRecord.tt is:
Subsonic\ActiveRecord.tt(0,0) : error : Running transformation: System.InvalidCastException: Unable to cast object of type 'Microsoft.VisualStudio.TextTemplating.CommandLine.CommandLineHost' to type 'System.IServiceProvider'.
at Microsoft.VisualStudio.TextTemplating3d54bbced2424853b667e74a81b9089b. GeneratedTextTransformation.GetCurrentProject() in c:\Users\matt.roberts\AppData\Loc
al\Temp\subsonic\Settings.ttinclude:line 103
at Microsoft.VisualStudio.TextTemplating3d54bbced2424853b667e74a81b9089b. GeneratedTextTransformation.GetConnectionString(String connectionStringName) in c:\U
sers\matt.roberts\AppData\Local\Temp\subsonic\Settings.ttinclude:line 51
at Microsoft.VisualStudio.TextTemplating3d54bbced2424853b667e74a81b9089b. GeneratedTextTransformation.get_ConnectionString() in c:\Users\matt.roberts\AppData\
Local\Temp\subsonic\Settings.ttinclude:line 87
Has anyone managed to automate this generation?
Thanks
Matt.

I wrote a blog entry that covers this ground somewhat:
Options for running T4 templates from .NET code
To do what you are trying to do will require some surgery on the SubSonic T4 templates. Specifically, you'll have to (minimally) replace all references to EnvDTE.DTE with something that doesn't require Visual Studio to be running. That may be as simple as hard coding some paths and/or configuration information into your T4 templates if you want to just "get it working".
It's important to remember that T4 templates are a somewhat thin wrapper around .NET code. If you can do it from .NET, you can very likely do it from T4, you just have to understand how to work within the different set of constraints that T4 provides. Different T4 "hosts" (like Visual Studio vs. TextTransform.exe) behave in different ways and just because a T4 template runs fine under one host doesn't not mean it will run fine under another host.

setting.ttinclude needs to be run inside the project of visual studio, if you want to run from command line you will have to give the settings file the connection string rather than pointing to it in the config files, you may also have to set a project path.
you seee it calling this:
string GetConnectionString(string connectionStringName){
var _CurrentProject = GetCurrentProject();
string result="";
ExeConfigurationFileMap configFile = new ExeConfigurationFileMap();
configFile.ExeConfigFilename = GetConfigPath();
thats probably where the problem stems, so if you set these by hand then you oproblem could then be solved

Related

(ROS) Failed to create global planner

My setup is: ROS melodic, Ubuntu: 18.04
I want simulate turtlebot3 moving with my own global planner and have been following this tutorial to get started: http://wiki.ros.org/navigation/Tutorials/Writing%20A%20Global%20Path%20Planner%20As%20Plugin%20in%20ROS#Running_the_Plugin_on_the_Turtlebot. The tutorial seem to be made for ROS hydro, but as it was the best source of guidance I could find I hoped it would work.
The error I'm having is:
Failed to create the global_planner/GlobalPlanner planner, are you sure it is properly registered and that the containing library is built? Exception: MultiLibraryClassLoader: Could not create object of class type global_planner::GlobalPlanner as no factory exists for it. Make sure that the library exists and was explicitly loaded through MultiLibraryClassLoader::loadLibrary()
To my knowledge I've followed the tutorial as much as possible with a only a few things done differently because I wanted to test it, couldn't do as the tutorial asked, or because I thought it wouldn't impact the results. What I have done differently is:
I use the carrot_planner.h and carrot_planner.cpp files in the tutorial section 1 to test that it works before trying with my own code to avoid confusion about where possible errors come from. It's not 'different' from the tutorial to my knowledge, but figured I'd mention it. They are placed in catkin_ws/src/carrot_planner/src/global_planner/
The ros package I'm working from is in catkin_ws/src and is called the carrot_planner. In the tutorial step 1.3 I use add_library(global_planner_lib src/global_planner/carrot_planner.cpp). Would not imagine it affects the results either.
In section 3 of the tutorial it mentions that 'First, you need to copy the package that contains your global planner (in our case global_planner) into the catkin workspace of your Turtlebot (e.g. catkin_ws).' Since my package was already in catkin_ws/src/ I haven't moved it since I guess I didn't need to.
I've altered the 'move_base.launch' file in '/opt/ros/melodic/share/turtlebot3_navigation/launch/' instead of the 'move_base.launch.xml' in '/opt/ros/hydro/share/turtlebot_navigation/launch/includes/' as there doesn't seem to be a destination '...turtlebot3_navigation/launch/includes/'. There are files in launch, but no includes folder. Maybe that a difference from Hydro to Melodic, I don't know. There may be a whole lot of things that need to be done differently from the tutorial when using Melodic, or with turtlebot3, but I don't know.
I haven't made my own launch file for bringup of the turtlebot, but have instead followed this tutorial (https://emanual.robotis.com/docs/en/platform/turtlebot3/nav_simulation/) to guide me with turtlebot3. After finishing this step in the global planner tutorial 'Save and close the move_base.launch.xml. Note that the name of the planner is global_planner/GlobalPlanner the same specified in global_planner_plugin.xml. Now, you are ready to use your new planner' I tested whether it worked by running: 'roslaunch turtlebot3_gazebo turtlebot3_world.launch' and then I tried running: 'roslaunch turtlebot3_navigation turtlebot3_navigation.launch map_file:=$HOME/map.yaml' which led to the error I showed above. I have created the map-yaml, so there's no misunderstanding whether that's missing.
I would be very glad for any help, thank you ^^
Edit: My system only had 'navfn' on it, not 'global_planner' or 'carrot_planner', if that makes a difference.
After looking over the code I found a solution. It doesn't make everything work perfectly yet, but seems to solve the immediate problem.
The problem was that in my 'global_planner_plugin.xml' I just used the code provided in the tutorial:
<library path="lib/libglobal_planner_lib">
<class name="global_planner/GlobalPlanner" type="global_planner::GlobalPlanner" base_class_type="nav_core::BaseGlobalPlanner">
<description>This is a global planner plugin by iroboapp project.</description>
</class>
</library>
But in the carrot_planner.cpp file it says:
PLUGINLIB_EXPORT_CLASS(carrot_planner::CarrotPlanner, nav_core::BaseGlobalPlanner)
Changing type="global_planner::GlobalPlanner to type="carrot_planner::CarrotPlanner and then launching turtlebot3 doesn't give the same error anymore.

In Unity3d test scripts, how do I call a static function from another class?

I have two files in a Unity3d project. One is a test script that runs in edit mode. The other is a single class with static functions that I'd like to call from the test scripts.
here's my test script:
using UnityEngine;
using UnityEngine.TestTools;
using NUnit.Framework;
using System.Collections;
public class NewTestScript
{
[Test]
public void TestAnotherStaticFunction()
{
int a = NewBehaviourScript.FunctionUnderTest(1);
int b = 1;
// Use the Assert class to test conditions.
Assert.IsTrue(a == b);
}
}
here's my function under test:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class NewBehaviourScript : MonoBehaviour
{
/// <summary>
/// the stupidest function in the world,
/// used to verify tests.
/// </summary>
public static int FunctionUnderTest(int a)
{
return a;
}
}
This gives me the error from the Unity compiler (I'm not building outside of Unity):
Assets/TestS/NewTestScript.cs(12,17): error CS0103: The name `NewBehaviourScript' does not exist in the current context
These are running in edit-mode.
I've tried adding and removing the SuperTestNameSpace namespace from the function under test and the calling code.
I've attempted adding/removing files from the .asmdef file that was autogenerated by unity, although this usually leads to other compile errors.
My previous unit test experience is largely in Visual Studio or VSCode, and I'm trying to get my unity3d test experience to match my prior test environment experiences.
Is there a fundamentally limited functionality in the edit-mode tests, or am I missing something stupid?
Further elaboration on the assemblies involved. It looks like there are two assemblies at play here: Assembly-CSharp.dll contains my code under test and TestS.dll contains my testing code. I believe my questions boils down to: how do I add a reference from the TestS.dll assembly to the Assembly-CSharp.dll. I'd know how to do this in Visual Studio (either via the context menu in VS or directly editing the csproj file), however I don't see how to do it in Unity3d. Any edit I make to the csproj file is frequently overwritten by unity, and while there is a 'references' section in the inspector (see picture) I can't add Assembly-CSharp.dll as a reference.
These are the inspector settings for TestS.asmdef. While there's an option to add references, I can't add a reference to Assembly-CSharp.dll, which is where my code-under-test lives.
Ok, I figured this out. There were two things going on:
Editor tests need to be underneath a folder called editor. It's really annoying that the unity editor doesn't do this for you.
You need to have an assembly definition for the code under test and add a reference from the test code to the newly created assembly definition. This must be done in the Unity editor UI.
by default, unity adds your script code to an assembly called Assembly-CSharp.dll, and, for reasons unknown, this assembly isn't referenced by my edit mode test code. I'm not sure if this is a bug in Unity or if it's by design, but explicitly creating and referencing the assembly definition has cleared things up.
The main issue is currently you are trying to call the
NewBehaviourScript(1);
constructor which does not exist...
instead of the method
using SuperTestNameSpace;
//...
NewBehaviourScript.FunctionUnderTest(1);
or alternatively with the namespace in the call directly
SuperTestNameSpace.NewBehaviourScript.FunctionUnderTest(1);
Also make sure the filename matches exactly the class name. So in your case it should be
NewBehaviourScript.cs
Note that the .cs is not printed by Unity in the Project view so there it should say NewBehaviourScript.
Why does it not compile with the using SuperTestNameSpace;? What is the error?
If that exception
Assets/TestS/NewTestScript.cs(14,17): error CS0103: The name `NewBehaviourScript' does not exist in the current context
is only shown in VisualStudio but the script compiling fine in Unity especially after adding a new script it helps to simply close and restart VS.
In some cases it also helps to close Unity and VS, remove all files and folders except Assets and ProjectSettings (and if you are under version control anything that belongs to it like e.g. .git, .gitignore, .gitattributes etc) in particular delete the Library, .vs folder and all .csproj and .sln files.
Than open Unity again and let it recompile everything.
Make sure the file that contains your NewBehaviourScript class IS NOT inside an Editor folder.
Move both the scripts in the Assets (root) folder and try again.

Can I use applicationDirPath() to access resources at a higher directory level?

In the application that I am developing (using C++ and Qt), I am using QApplication::applicationDirPath() to access some resources, with respect of the application's path.
As an example, since I want to open a HTML manual from the application, I act this way:
void MainWindow::on_actionHelp_triggered()
{
QString link = QApplication::applicationDirPath() + "/Guide/guide.html";
bool r = QDesktopServices::openUrl(QUrl::fromLocalFile(link));
}
This snippet works if the project's structure presents the path "ProjectName/bin/Release/Guide/guide.html" (since the .exe file is in "ProjectName/bin/Release/AppName.exe").
But what can I do to refer to a higher-directory-level resource? As an example, I wish my HTML file to be in "ProjectName/data/Guide/guide.html". But this way, it seems not possible to compose the path in the way I'm acting.
EDIT: After #olive's comment, I wish to clarify a thing:
"Why am I not using '../'?"
Because it won't work from Visual Studio, where I am massively launch the application to test it. From VS, in fact, I shall use "../data/Guide/guide.html", when "from the outside", I'd have to do "../../data/Guide/guide.html".
That's why (I think) QApplication::applicationDirPath() exists. However, I am not an expert, so don't blame me and correct any eventual mistake of mine, please!
Just use ... QApplication::applicationDirPath() + "/../../data/Guide/guide.html" is perfectly valid path!
Of course there is another problem. When the application is installed, the relative path will probably be different again. You either need to configure the paths in visual studio so that the relative path works both during development and after deployment, or you need to detect the layout.

VARIANT members not resolved in C++ OLE automation application (Eclipse IDE)

I'm developing a C++ application that reads and writes to Excel using OLE automation (code based on this: http://support.microsoft.com/kb/216686).
The application has been up and running just fine when I was using VS2010. However recently I decided to move to Eclipse, and all of a sudden the compiler (CL) won't recognize the structure of the VARIANT struct (doc: http://msdn.microsoft.com/en-us/library/aa908601.aspx). For instance in this piece of code:
VARIANT tmp;
tmp.vt = VT_R4;
tmp.fltVal = 5.0f;
tmp.fltVal cannot be resolved in Eclipse (while it works just fine in VS2010, and every code sample I've seen online). The only way to get Eclipse to stop displaying an error is to replace the last two lines with:
tmp.n1.n2.vt = VT_R4;
tmp.n1.n2.n3.fltVal = 5.0f;
Same goes for tmp.parray and all other members of VARIANT.
Has anyone come across this before ? What am I missing here ?
PS: No, replacing the code everywhere is not exactly an option

Visual C++ - Throwing unhandled exception from setting forms icon?

I can compile the solution with no errors, but when I'll try to run it, I get a crash window:
An unhandled exception of type
'System.Resources.MissingManifestResourceException' occurred in mscorlib.dll
Additional information: Could not find any resources appropriate for the specified culture or the neutral culture. Make sure "<myformname>.resources" was corerctly embedded or linked into assembly "<myprojectname>" at compile time, or that all the satellite assemblies required are loaded and fully signed.
And after I press Break it throws me to the line:
this->Icon = (cli::safe_cast<System::Drawing::Icon^ >(resources->GetObject(L"$this.Icon")));
If I comment this line out, everything works just fine, but my program doesn't have icon.
Anyone else had this problem? Found a solution? I couldn't find anything clear enough for me to understand, problem is really annoying me, only solution I found was to declare my form class before any other classes, but I don't even have any other classes in my solution?
I also have only one project in this solution, ms support said something about having multiple projects, which I don't have, so it was no use either.
Take a look here :
http://www.mztools.com/articles/2005/MZ2005007.aspx
The exception is thrown because your icon cannot be located. You will probably need to compiles your resources under one .dll and put this under en-US subfolder on your project output. It did the trick for me at least. There are probably other solutions to your problem too.
Do not panic like I did. The root cause of the problem is that the compiled resource file is different from the one that is asked to load at runtime. This happens because the underlying build-script cannot detect the filename or namespace changes made after the form is created.
For example, At first we started a project named x . And our $(RootNamespace) becomes x. And we created a form named y. So our XML resource file y.resx gets compiled into x.y.resource . At this point the icon change works.
Now somehow we changed the project name or the namespace to z. But our $(RootNamespace) remains the x. While at compile-time it wrongly generates old x.y.resource, but at links-time it links z.y.resource. And at this point the icon change does not work.
It can also happen if the form is under some nested namespace which is not known in the project file.
It can be fixed by changing the compilation output of the y.resx file . It can be done by right-clicking the resource and changing the Resource Logical Name to $(RootNamespace).%(Filename).resources .
I will also make sure that ProjectName,AssemblyName and RootNamespace are the same in the .vcxproj file. Somehow if the form is declared under a nested namespace like RootNamespace.gui , then the output file of the resource should be $(RootNamespace).gui.%(Filename).resources .