Skip to content

untrustedmodders/plugify

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Documentation Discord channel

A Modern C++ Plugin Manager with Multi-Language Support
Report a Bug Β· Request a Feature . Ask a Question

Table of Contents

About

Unlock a new era in plugin development with Plugify, a revolutionary library designed to streamline and enhance the way plugins are created and utilized. Plugify goes beyond traditional plugin management by introducing innovative language modules, redefining the boundaries of cross-language communication.

Key Features

  1. Dynamic Language Diversity:
    Plugify’s power is in its flexibility. It allows you to use multiple programming languages. Choose the languages you need for the project, and go. This will make your development environment more diverse and flexible.

  2. Language Modules:
    Plugify allows you to install language modules for various programming languages, so you can use the language of your choice and develop plugins with the core without any doubt about language incompatibilities.

  3. Inter-Language Communication:
    Make plugins communicate to each other in any existing language. Export methods, and share data between plugins, without regard for the programming language used.

Motivation

The plan was to build a new plugin system for CS in C#, but some of the decisions that were made in the early version led to a decision to β€˜remove the training wheels’, unshackle the system from any game or embeddable language and create a system which allows the developers of plugins to build them in whatever language they like. For as long as that language module is installed, the system is able to support it. So by no longer trying to force it to be deemed a β€˜good’ solution to be embedded in a variety of games, Plugify now goes far beyond the logical limitations a C#-specific solution has. What this means is that Plugify not only has the potential to have a larger community of developers, but is now flexible from the beginning to last a long time. Longevity was always a selling point, since if it was to work, it always had to be a β€˜forever’ feature. It’s not just games development that stands to benefit. The flexibility of Plugify should mean it has uses in many projects, not just in games.

Integration

Requirements

  • CMake version 3.14 or later.
  • Doxygen version 1.8 or later.
  • Requires C++20 or later.
  • Designed for x86 and Arm.
  • Tested on 64bit little-endian systems.

Supported platforms:

  • Windows (7+)
  • Linux
  • macOS (13.0+)
  • PlayStation 4/5
  • Nintendo Switch
  • Android (14+)
  • iOS/iPadOS/tvOS (16.0+)
  • UWP (Universal Windows, Xbox One)

Supported compilers:

Actions build created for windows, linux and apple.

clang build gcc build msvc build msys build

CMake

You can also use the plugify::plugify interface target in CMake.

External

To use this library from a CMake project, you can locate it directly with find_package() and use the namespaced imported target from the generated package configuration:

# CMakeLists.txt
find_package(plugify REQUIRED)
...
add_library(foo ...)
...
target_link_libraries(foo PRIVATE plugify::plugify)

Embedded

To embed the library directly into an existing CMake project, place the entire source tree in a subdirectory and call add_subdirectory() in your CMakeLists.txt file:

# Typically you don't care so much for a third party library's tests to be
# run from your own project's code.
set(PLUGIFY_BUILD_TESTS OFF CACHE INTERNAL "")

# Don't use include(plugify/CMakeLists.txt) since that carries with it
# unintended consequences that will break the build.  It's generally
# discouraged (although not necessarily well documented as such) to use
# include(...) for pulling in other CMake projects anyways.
add_subdirectory(plugify)
...
add_library(foo ...)
...
target_link_libraries(foo PRIVATE plugify::plugify)
Embedded (FetchContent)

Since CMake v3.11, FetchContent can be used to automatically download a release as a dependency at configure time.

Example:

include(FetchContent)

FetchContent_Declare(plugify GIT_REPOSITORY https://github.com/untrustedmodders/plugify.git)
FetchContent_MakeAvailable(plugify)

target_link_libraries(foo PRIVATE plugify::plugify)

Note: It is recommended to use the URL approach described above which is supported as of version 1.0.0. See wiki for more information.

Supporting Both

To allow your project to support either an externally supplied or an embedded Plugify library, you can use a pattern akin to the following:

# Top level CMakeLists.txt
project(FOO)
...
option(FOO_USE_EXTERNAL_PLUGIFY "Use an external Plugify library" OFF)
...
add_subdirectory(thirdparty)
...
add_library(foo ...)
...
# Note that the namespaced target will always be available regardless of the
# import method
target_link_libraries(foo PRIVATE plugify::plugify)
# thirdparty/CMakeLists.txt
...
if(FOO_USE_EXTERNAL_PLUGIFY)
  find_package(plugify REQUIRED)
else()
  add_subdirectory(plugify)
endif()
...

thirdparty/plugify is then a complete copy of this source tree.

Example

This code creates an instance of the plugify::Plugify object. It sets up services, initializes the instance, and then interacts with a plugin manager. Error handling is included for initialization failures.

// Example 1: Simple usage with defaults
int main() {
    auto result = plugify::MakePlugify("./app");
    if (!result) {
        std::cerr << "Failed to create Plugify: " << result.error().message << std::endl;
        return 1;
    }

    auto plugify = result.value();
    if (auto initResult = plugify->Initialize(); !initResult) {
        std::cerr << "Failed to initialize: " << initResult.error().message << std::endl;
        return 1;
    }

    // Load extensions
    const auto& manager = plugify->GetManager();
    manager->Initialize();

    // Main loop
    bool running = true;
    while (running) {
        plugify->Update();
        // Your application logic here
    }

    plugify->Terminate();
    return 0;
}
// Example 2: Advanced configuration
int main() {
    // Create custom logger
    auto logger = std::make_shared<plugify::impl::AsyncLogger>(
        std::make_shared<plugify::impl::FileLogger>("./logs/app.log")
    );

    // Configure plugin manager
    plugify::Config config;
    config.paths.baseDir = "./app";
    config.paths.extensionsDir = "extensions";
    config.loading.enableHotReload = true;
    config.loading.parallelLoading = true;
    config.runtime.updateInterval = std::chrono::milliseconds(16);

    // Build Plugify instance
    auto result = plugify::Plugify::CreateBuilder()
        .WithConfig(config)
        .WithLogger(logger)
        .WithService<MyCustomService>(std::make_shared<MyCustomServiceImpl>())
        .Build();

    if (!result) {
        std::cerr << "Failed: " << result.error().message << std::endl;
        return 1;
    }

    auto plugify = result.value();

    // Initialize asynchronously
    auto initFuture = plugify->InitializeAsync();

    // Do other initialization...

    // Wait for initialization
    if (auto initResult = initFuture.get(); !initResult) {
        std::cerr << "Failed to initialize: " << initResult.error().message << std::endl;
        return 1;
    }

    // Access service locator for convenient operations
    auto logger = plugify->GetServices().Resolve<ILogger>();
    logger->Log("Application started", Severity::Info);

    // Main loop
    bool running = true;
    while (running) {
        plugify->Update();
    }

    plugify->Terminate();
    return 0;
}

(back to top)

Documentation

The documentation is based on doxygen. To build it:

cd build
cmake .. -DPLUGIFY_BUILD_DOCS=ON
cmake --build . --target docs

The API reference is created in HTML format in the build/docs/html directory. To navigate it with your favorite browser:

cd build
your_favorite_browser docs/html/index.html

The same version is also available online for the latest release, that is the last stable tag.
There is also a wiki page dedicated to the project where users can find all related documentation pages. Additionally, we offer an online documentation generator that allows you to easily create documentation for your plugin's manifest file.

(back to top)

Tests

To build the basic testing app:

  1. Install dependencies:

    a. Windows

    Setting up CMake tools with Visual Studio Installer

    b. Linux:

    sudo apt-get install -y build-essential cmake ninja-build

    c. Mac:

    brew install cmake ninja
  2. Clone the repo:

    git clone https://github.com/untrustedmodders/plugify.git
  3. Create build folder:

    mkdir build
    cd build
  4. Build the project:

    cmake .. 
    cmake --build . --target plug

(back to top)

Extensions

Here is a list of all already implemented language modules:

(back to top)

In Action

While Plugify is a relatively new project, it is making waves in the realm of server-side modding, particularly in the Counter-Strike 2 community. As of now, Plugify is primarily utilized in the ance of a new project known as S2-Plugify, which is also being developed by our team.

If you know of other resources out there that are about Plugify, feel free to open an issue or a PR and we will be glad to add them here.

Roadmap

See the open issues for a list of proposed features (and known issues).

(back to top)

Support

Reach out to the maintainer at one of the following places:

(back to top)

Project assistance

If you want to say thank you or/and support active development of plugify:

  • Add a GitHub Star to the project.
  • Tweet about the plugify.
  • Write interesting articles about the project on Dev.to, Medium or your personal blog.

Together, we can make plugify better!

(back to top)

Contributing

First off, thanks for taking the time to contribute! Contributions are what make the open-source community such an amazing place to learn, inspire, and create. Any contributions you make will benefit everybody else and are greatly appreciated.

Please read our contribution guidelines, and thank you for being involved!

(back to top)

Authors & contributors

The original setup of this repository is by untrustedmodders.

For a full list of all authors and contributors, see the contributors page.

(back to top)

Security

Plugify follows good practices of security, but 100% security cannot be assured. Library is provided "as is" without any warranty. Use at your own risk.

For more information and to report security issues, please refer to our security documentation.

(back to top)

License

This project is licensed under the MIT license.

See LICENSE for more information.

(back to top)

Acknowledgements

[?] If your work was funded by any organization or institution, acknowledge their support here. In addition, if your work relies on other software libraries, or was inspired by looking at other work, it is appropriate to acknowledge this intellectual debt too.

(back to top)