Call a method or function from Objective-c in AppleScript - applescript-objc

I'm trying to use LestMove to be more precise
the second implementation method where it says:
Option 2:
Copy the following files into your project:
PFMoveApplication.h
PFMoveApplication.m
If your project has ARC enabled, you'll want to disable ARC on the above files. You can do so by adding -fno-objc-arc compiler flag to your PFMoveApplication.m source file. See How can I disable ARC for a single file in a project?
If your application is localized, also copy the 'MoveApplication.string' files into your project.
Link your application against Security.framework.
In your app delegate's "-[applicationWillFinishLaunching:]" method, call the PFMoveToApplicationsFolderIfNecessary function at the very top.
but I'm not able to call the method / Class, could someone help me with this issue? Thanks in advance!

In general, there are a couple of ways to set up an Objective-C class in your AppleScriptObjC project:
Add the file(s) to the project - the Objective-C class name will be
the one used in the #interface/#implementation declarations
Add an outlet property in the AppleScript class/script you are using, e.g. property someProperty : missing value
Instantiate the class programmatically:
set someProperty to current application's ClassName's alloc's init()
or
Connect stuff up with the Interface Builder:
Add an NSObject (blue cube) from the library to your project
Set the class of the object/cube to the class name of the Objective-C file(s) in the Identity Inspector
Connect the AppDelegate IB Outlet to the object/cube in the Connections Inspector
After setting up the outlet property, the Objective-C methods can be used like any other script/class:
someProperty's handler()
That LetsMove project wasn't really set up for AppleScriptObjC, but I was able to tweak it a bit to get it running. I'm not that great at writing Objective-C, but the following worked for me using a new default AppleScript project with Xcode 10 in Mojave (the original file is over 500 lines long, so I'm just highlighting the changes):
Add PFMoveApplication.h and PFMoveApplication.m files to the project (the class name is LetsMove)
Add Security.framework to Link Binary With Libraries in Build Phases
As described in the original project README, add the compiler flag -fno-objc-arc to the Objective-C file in Compile Sources of the Build Phases
-- Now to alter the Objective-C files a bit:
Move the #interface declaration to the .h file and include the redefined method signatures below in it:
The PFMoveToApplicationsFolderIfNecessary and PFMoveIsInProgress methods are redefined as instance methods:
- (void)PFMoveToApplicationsFolderIfNecessary;
- (BOOL)PFMoveIsInProgress;
Redefine the above method signatures in the .m file, and include those methods in the #implementation section - to do this, move the #end to just before the helper methods (after the PFMoveIsInProgress method)
Remove the isMainThread statement at the beginning of the PFMoveToApplicationsFolderIfNecessary method - this is not not needed (AppleScript normally runs on the main thread), and fixes another issue
There is still a little stuff in there from the original app such as NSUserDefaults, so for your own project, give it a look to see if anything else needs changing (dialog text, etc)
And finally, in the AppDelegate.applescipt file, the following was added to applicationWillFinishLaunching:
current application's LetsMove's alloc's init()'s PFMoveToApplicationsFolderIfNecessary()

Related

How to correctly create a .gdns to instantiate it?

I have a gdnative library loaded in my godot. I can also call functions on it, that works. But I want to instantiate c++-Classes from it inside Godot.
I think I have to generate .gdns files for that to work, but i dont really find a example of that.
I created a .gdns script already with the New Script Dialogue. I named it exactly like the c++ class. And I set the Library in the scripts inspector and set ClassName to MyClass. But the following does not work as someClass is Null:
var someclass = load("res://MyClass.gdns").new();
someclass.method("myMethod");
What did I do wrong?
I tried to follow this tutorial.
Im Using Godot 1.1 and compiled the gdnative-library with the appropriate Godot-cpp headers.
I created a .gdns file with the New Resource Dialogue and it worked then (after setting the library and Class-name of the .gdns in the Inspector).
I'll add more here when I found out why it didn't work before.

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.

How to load PNG file into my custom component? Cannot get correct instance

I want to create a custom control (from TPanel) that holds some TImages.
I want to display PNG (with transparency) into those mages. Therefore, I am TRYING to attach the PNG via IDE's "Resource and Images" to the package.
The problem is that when I put the component into a test application it will fail on MyPng->LoadFromResourceName line with "resource not found". Interestingly, if I add the PNG as a resource to the test application, it will work.
This means that the component is looking into the wrong module for the PNG resource.
I print the instance with ShowMessage it shows indeed "ComponentTester.exe".
__fastcall TVolumeCtrl::TVolumeCtrl(TComponent* Owner)
: TPanel(Owner)
{
HINST h = FindClassHInstance(__classid(TVolumeCtrl));
ShowMessage(GetModuleName(h));
TPngImage *Png3 = new TPngImage();
MyPng->LoadFromResourceName(h, "Btn1");
How to get the correct instance?
Note: The PNG files ARE compiled into the RES file generated. I looked inside with a Hex viewer.
The only explanation that makes sense is that you are not using runtime packages. So you aren't loading the module that contains the resource.
The right way to link the resource for the component is to use a $R directive in the source file that declares the type, TVolumeCtrl in this case. That way the resource will be linked to whichever module contains the implementation of TVolumeCtrl. That's going to be a package when you are compiling the runtime package (which is used at designtime by your designtime package), and it will be the executable when you compile an executable that does not use runtime packages.

A quick way to remove properties from .dfm files in Delphi

I have recently modified one of my components, and it so happens it is no longer using one of the properties it used before.
However, those properties are written in multiple .dfm files throughout the project.
Now, when i try to compile the project, i get
"Error reading .: Property <...> does not exist"
The complicated part is that the property value is binary data (stored in multiple lines), and i cant just delete it with Delphi replace or notepad++ regexp (since they are single-line based).
So my question would be:
Are there any third party tools or ways to easily remove properties from multiple .dfm files?
Try this tool Delphi DFM properties remover, works with old versions of delphi but maybe can help you.
One possible approach is to modify your component so that it is capable of simply ignoring these properties. That way you don't have to hunt them down in each and every .dfm file.
For example:
type
TIgnoreFormPropertyHelper = class
public
class procedure IgnoreBooleanProperty(Reader: TReader);
class procedure IgnoreIntegerProperty(Reader: TReader);
end;
{ TIgnoreFormPropertyHelper }
class procedure TIgnoreFormPropertyHelper.IgnoreBooleanProperty(Reader: TReader);
begin
Reader.ReadBoolean;
end;
class procedure TIgnoreFormPropertyHelper.IgnoreIntegerProperty(Reader: TReader);
begin
Reader.ReadInteger;
end;
type
TMyComponent = class(...)
....
protected
procedure DefineProperties(Filer: TFiler); override;
....
procedure TMyComponent.DefineProperties(Filer: TFiler);
begin
inherited;
Filer.DefineProperty('MyLegacyBooleanProperty',
TIgnoreFormPropertyHelper.IgnoreBooleanProperty, nil, False);
Filer.DefineProperty('MyLegacyIntegerProperty',
TIgnoreFormPropertyHelper.IgnoreIntegerProperty, nil, False);
end;
The Jedi VCL contains a tool called DFMCleaner:
DFMCleaner is a tool to remove unsupported properties from DFMs. If
you save a dfm file in one version of Delphi and want to use it in an
earlier version, chances are there are some unsupported properties in
it, generating an error when the form is opened in Delphi. What's even
worse, if the dfm is part of a design-time package, Delphi will
install the package without errors but when you try to access the form
at design-time (f ex if the form is used by a property editor), Delphi
generates an AV instead.
It is located in jvcl-install\devtools\DFMCleaner (project with source code and example configuration file)
In my case simply closing the project and deleting the DProj file helped.

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 .