concept?
All checks were successful
test / run-tests-client (push) Successful in 43s
test / run-tests-backend (push) Successful in 15s

This commit is contained in:
BinarySandia04 2024-10-12 11:20:10 +02:00
parent 6f29f54f60
commit c6e07e7b41
5 changed files with 137 additions and 30 deletions

View File

@ -7,6 +7,7 @@ import * as _Sound from "@/services/Sound"
import * as _Tooltip from "@/services/Tooltip" import * as _Tooltip from "@/services/Tooltip"
import * as _Windows from "@/services/Windows" import * as _Windows from "@/services/Windows"
import Server from '@/services/Server'; import Server from '@/services/Server';
import { socket } from '@/services/Socket';
/** /**
* Class for managing the client api * Class for managing the client api
@ -16,6 +17,7 @@ class ClientApi {
#_plugin #_plugin
#_router #_router
#_windows #_windows
#_socket
/** /**
* @param {*} plugin * @param {*} plugin
@ -24,6 +26,7 @@ class ClientApi {
this.#_plugin = plugin this.#_plugin = plugin
this.#_router = new ClientRouter(plugin.package) this.#_router = new ClientRouter(plugin.package)
this.#_windows = new ClientWindows(plugin.package) this.#_windows = new ClientWindows(plugin.package)
this.#_socket = new ClientSocket(plugin.package)
} }
/** /**
@ -86,6 +89,10 @@ class ClientApi {
get windows(){ get windows(){
return this.#_windows; return this.#_windows;
} }
get socket(){
return this.#_socket;
}
} }
/** /**
@ -245,6 +252,18 @@ class ClientModule {
} }
} }
class ClientSocket {
#_package
constructor(plugin){
this.#_package = plugin;
}
on(msg, callback){
socket.on(`${this.#_package}/${msg}`, callback);
}
}
/** /**
* @typedef {Object} Response * @typedef {Object} Response
* @property {Object} data * @property {Object} data

View File

@ -18,7 +18,7 @@ export default defineUserConfig({
text: "Guides", text: "Guides",
prefix: "/guide/", prefix: "/guide/",
link: "/guide/", link: "/guide/",
children: ['/get-started'] children: ['/get-started', '/firstplugin']
}, },
{ {

View File

@ -1,3 +1,5 @@
# Creating a plugin
This guide will help you through creating a plugin for Dragonroll This guide will help you through creating a plugin for Dragonroll
## Downloading the example plugin ## Downloading the example plugin
@ -34,36 +36,118 @@ Your `plugin.json` file defines important information about your plugin, like it
**Important**: The `package` field must be identical to the name of the folder containing your entire plugin **Important**: The `package` field must be identical to the name of the folder containing your entire plugin
> `plugin.json` > `plugin.json`
> ```json ```json
> { {
> "package": "your-plugin", "package": "your-plugin",
> "name": "My custom plugin", "name": "My custom plugin",
> "description": "This is my first custom plugin", "description": "This is my first custom plugin",
> "authors": [ "authors": [
> { {
> "name": "Aran Roig" "name": "Aran Roig"
> } }
> ], ],
> "version": "1.0", "version": "1.0",
> "client": { "client": {
> "entrypoint": "main.js" "entrypoint": "main.js"
> }, },
> "backend": { "backend": {
> "entrypoint": "main.js" "entrypoint": "main.js"
> } }
> } }
> ``` ```
## Entrypoints ## Entrypoints
When Dragonroll registers a plugin, it calls the `Main` method of the file specified in the entrypoint field inside the `plugin.json`, so if you don't export a function with that name your plugin won't load. Dragonroll passes its entire API through the main method When Dragonroll registers a plugin, it calls the `Main` method of the file specified in the entrypoint field inside the `plugin.json`, so if you don't export a function with that name your plugin won't load. Dragonroll passes its entire API through the main method
> `client/main.js` and `backend/main.js` > `client/main.js`
> ```js main.js > `backend/main.js`
> function Main(Api){ ```js main.js
> console.log("Hello World!"); function Main(Api){
> } console.log("Hello World!");
> export { Main }; }
> ``` export { Main };
```
In the client entrypoint, the `Api` variable will be a `ClientApi` object. In the backend entrypoint, the `Api` will be instead a `BackendApi` object. In the client entrypoint, the `Api` variable will be a `ClientApi` object. In the backend entrypoint, the `Api` will be instead a `BackendApi` object.
If you want to make the `Api` object accessible throught your plugin files, you need to export it and then import `main.js` using relative paths:
> `client/main.js`
> `backend/main.js`
```js main.js
let Api;
function Main(api){
Api = api;
console.log("Hello World!");
}
export { Main, Api };
```
> `client/otherfile.js`
```js
import { Api } from './main.js'
// Do whatever
```
## Creating a window
In Dragonroll, windows are managed in a data-oriented approach, each window has a `type` that defines what view corresponds to it, and then it has an `id` to identify every window. These two fields are mandatory for creating a window, and `id` must be unique. For ensuring that `type` and `id` won't collide with other plugins, the Dragonroll Api handles a prefix with the name of your package for all the ids you set.
### Window view
You can spawn Dragonroll internal windows or also you can create your own type with the `registerWindow` method. First, you need to create a view inside `client/views` folder:
> `ExampleWindow.vue`
```vue
<script setup>
import { onMounted, ref } from 'vue';
import { SetupHandle, SetSize, ResetPosition } from '@/services/Windows';
import WindowHandle from '@/views/partials/WindowHandle.vue';
const handle = ref(null);
const props = defineProps(['data']);
const data = props.data;
let id = data.id;
onMounted(() => {
SetupHandle(id, handle);
SetSize(id, {width: 500, height: 380});
ResetPosition(id, "center");
});
</script>
<template>
<div class="window-wrapper" :id="'window-wrapper-' + id">
<WindowHandle :window="id" ref="handle"></WindowHandle>
<h1>Hello window world!</h1>
</div>
</template>
<style scoped></style>
```
There's a lot to unpack here. Each Dragonroll window that is created contains a `data` prop. This contains all the information that has been supplied from the `createWindow` method, including the id and its type. Also, you will see that it has a `WindowHandle` partial. This draws the handle, and the `SetupHandle` function adds internal logic to it.
You should add the body of the window where `<h1>Hello window world!</h1>` is placed.
### Registering the window
Call `registerWindow`, passing the view (without the .vue extension):
```js
let exampleWindowView = Api.createView('ExampleWindow')
let exampleWindow = Api.registerWindow('example_window', exampleWindowView);
```
the first parameter of `registerWindow` is the `type` of the new window that is being registered, and the view is what Dragonroll will spawn as the window.
### Creating the window
```js
Api.createWindow(exampleWindow)
```
Keep in mind that `registerWindow` returns a `String` with the type of the registered window with the plugin prefix appended

View File

@ -4,7 +4,6 @@ import Server from '@/services/Server'
import { reactive } from 'vue'; import { reactive } from 'vue';
import { GetCampaign } from "@/services/Dragonroll"; import { GetCampaign } from "@/services/Dragonroll";
import { socket } from '@/services/Socket';
let data = reactive({}); let data = reactive({});
@ -24,9 +23,15 @@ function FetchData(){
FetchConcepts(); FetchConcepts();
} }
Api.socket.on('update-concepts', () => {
FetchConcepts();
});
/*
socket.on('update-concepts', () => { socket.on('update-concepts', () => {
FetchConcepts(); FetchConcepts();
}); });
*/
let GetConcepts = () => data.value.concepts; let GetConcepts = () => data.value.concepts;
let GetConcept = (id) => Server().get('/concept/get?campaign=' + GetCampaign()._id + "&id=" + id) let GetConcept = (id) => Server().get('/concept/get?campaign=' + GetCampaign()._id + "&id=" + id)

View File

@ -59,7 +59,6 @@ function Main(api){
// Api.windows.registerWindow('create_item_prompt', Api.createView('CreateItemPrompt')); // Api.windows.registerWindow('create_item_prompt', Api.createView('CreateItemPrompt'));
dndModule.init = () => { dndModule.init = () => {
console.log("INIT")
InitData(); InitData();
FetchData(); FetchData();
} }