-
Notifications
You must be signed in to change notification settings - Fork 0
Plugins
If you find a piece of functionality is lacking from Algo, you can create a C# plugin to add that functionality to the language! This article will give a quick tutorial as to how.
First, you will need to create a new .NET Framework 4.x Class Library, from template if possible.
After that, download the Algo SDK, and load it in Visual Studio. You can download it from the Releases tab, or grab it from your root Algo directory, then simply add a reference to it in Visual Studio.
Now, create a new class, such as the one outlined below, for your plugin.
using System;
using AlgoSDK;
namespace YourNamespaceHere
{
public class AwesomeAlgoPlugin : IFunctionPlugin
{
}
}
Next, implement the required methods and properties outlined in IFunctionPlugin
(Visual Studio should have an option for this with the CTRL + .
shortcut, but if not, there is an example below).
public class AwesomeAlgoPlugin : IFunctionPlugin
{
public string Name { get; set; } = "awesomeAlgoPlugin";
public List<AlgoPluginFunction> Functions { get; set; } = new List<AlgoPluginFunction>()
{
}
}
Now you can get round to implementing your custom functionality! To create a runnable function in Algo, your functions must all adhere to the AlgoFunctionDelegate
delegate, which is outlined below in case you can't see in VS.
public static AlgoValue SomeCustomFunctionality(ParserRuleContext context, params AlgoValue[] args)
{
...
}
Here are some key tips for writing clean Algo functions:
- If you want to return nothing from a function, use
return null
.AlgoValue.Null
is an actual null Algo value, whereasnull
is returning nothing. - You can check the types of your arguments by using
args[i].Type == AlgoValueType.x
. - Use
Error.Fatal
to throw errors instead ofError.FatalNoContext
, it helps the user trace the error. You can pass in theParserRuleContext
provided in the arguments of the function.
Now that your function is written, go back up to your property definition for Functions
, and add a new AlgoPluginFunction
instance, customized to your needs. Here's an example:
public List<AlgoPluginFunction> Functions { get; set; } = new List<AlgoPluginFunction>()
{
//input.get();
new AlgoPluginFunction()
{
Name = "input_get",
Function = GetConsoleInput,
ParameterCount = 0
}
}
Now that your custom functionality is complete, you just have to load your function into Algo itself. Build your class library, and place the .dll
file that is generated inside a new folder in /algo/packages
. For example, if my plugin was called "CustomFuncPlug", I'd place my .dll
inside /algo/packages/customFuncPlug
. This isn't important, but helps organise your different plugins.
Now that your DLL is placed into packages, create a new Algo file in the root packages directory. In my example, I'd call it "customFuncPlug.ag
". Inside it, you can then create a library for your plugin, and load in your custom functions.
Here's an example of how that looks:
//customFuncPlug.ag
//(c) Larry T, 2019
library customFuncPlug
{
external myFunc <- awesomeAlgoPlugin.input_get;
}
To break it down:
- The "library" statement wrapped around it creates a separate namespace for it, such as
input.get()
rather thanget()
. - The "external" signals that it's a plugin function that needs to be loaded.
- The
awesomeAlgoPlugin.input_get
is derived like so:name.func
. So, if the "Name" property in your plugin is set to "foo", and you had a function called "bar", it would be "foo.bar". - You can load as many external functions as you need.
You've successfully created a plugin for Algo! Now, to run it, simply use import "myPluginName"
in a script, and you can use whatever functions you've defined (in my case, customFuncPlug.myFunc()
).
Algo (c) Larry Tang, 2019.
Commercial use of Algo must include the LICENSE
file in the same directory as the executable.
Standard Library Documentation: