Code Monkey home page Code Monkey logo

owlcore's Introduction

Arlo Godfrey




Stats

To defend and preserve the honor of the profession of computer programmers, I promise that, to the best of my ability and judgement:[0][1]

  1. I will not produce harmful code.

  2. The code that I produce will always be my best work. I will not knowingly allow code that is defective either in behavior or structure to accumulate.

  3. I will produce, with each release, a quick, sure, and repeatable proof that every element of the code works as it should.

  4. I will make frequent, small, releases so that I do not impede the progress of others.

  5. I will fearlessly and relentlessly improve my creations at every opportunity. I will never degrade them.

  6. I will do all that I can to keep the productivity of myself, and others, as high as possible. I will do nothing that decreases that productivity.

  7. I will continuously ensure that others can cover for me, and that I can cover for them.

  8. I will produce estimates that are honest both in magnitude and precision. I will not make promises without certainty.

  9. I will never stop learning and improving my craft.

owlcore's People

Contributors

amaid avatar arlodotexe avatar d2dyno1 avatar yoshiask avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

owlcore's Issues

SettingsBase.SetSetting(null) doesn't fire PropertyChange event

How to reproduce:

  • Create a settings class that inherits from SettingsBase
  • Add a property backed by Set- and GetSetting
  • Subscribe to the settings class's PropertyChanged event
  • Add a button that sets the property to null when clicked
  • Note that setting the property to null effectively resets the setting (by forcing it to re-evaluate the default value function), but does not invoke PropertyChanged

This issue is particularly noticeable when attempting to reset a property that is bound to a UI element, as the UI doesn't know the property value changed and therefore won't update.

Acceptable solutions are:

  • Correcting the SetSetting method to invoke PropertyChanged even when a null value is passed
  • Add a ResetSetting/SetDefault method to explicitly set a property to its default
  • Both of the above

Filesystem changed events in AbstractStorage

The problem

Most file systems provide a way to notify when the contents of a folder is changed. However, AbstractStorage doesn't have the same thing.

The solution

Add events to IFolderData to notify when

  • A file is added
  • A file is removed

AbstractUI view models should not use Threading.OnPrimaryThread

The AbstractUI view models use Threading.OnPrimaryThread, which requires user setup, namely calling Threading.SetPrimarySynchronizationContext and Threading.SetPrimaryThreadInvokeHandler. View models should work as-is, without any setup.
The current requirements are a little obtuse, and it personally took me a while to figure out why my property bindings weren't working, because OnPrimaryThread was failing silently.

Classware: Middleware for classes

Overview

Introduce a source generator to facilitate compile-time dynamic behavior injection. This generator will produce "plugin" implementations for classes or interfaces, allowing for behavior extension and customization without altering the original code.

Inspiration

This concept is inspired by the Strix Music SDK's "model plugin" system, which lets developers enhance the SDK by wrapping around and overriding SDK model members. Our goal is to generalize this idea for any class or interface.

Key Features

  • Plugin Generation: Automatically derive a "plugin" for any class or interface.
  • Delegation Mechanism: Utilize IDelegable<T> to delegate to other T instances when members aren't overridden.
  • Fallback Strategy: Non-overridden members default to IDelegable<T>.Inner.
  • Plugin Chaining: Chain multiple plugins, replacing the original object upon execution.
  • Interface Plugins: Apply interface plugins to any class inheriting the interface.
  • Generated Plugin Container: A container class that holds all the ChainedProxyBuilder instances for possible plugins.
  • Generated Wrapper Class: For each concrete class, a wrapper class is generated that applies the relevant plugins and delegates calls to the enhanced instance.

Workflow

  1. Identify classes/interfaces marked for plugin generation.
  2. Generate a derived "plugin" for each, implementing both T and IDelegable<T>.
  3. The plugin accepts a T and an IDelegable<T> instance during construction.
  4. Developers can extend the generated base class to craft custom plugins.
  5. Non-overridden plugin members delegate to IDelegable<T>.Inner.
  6. Use base or Inner to invoke the next plugin or the base class.
  7. Generate a Plugin Container class that holds all the ChainedProxyBuilder instances for possible plugins.
  8. Generate a Wrapper class for each concrete class that uses the Plugin Container to apply the relevant plugins and delegates calls to the enhanced instance.

Applications

  • RPC Library: Generate proxy implementations for interfaces, enabling a Remote Procedure Call library for distant method calls.
  • Dynamic Behavior: Craft plugins for behavior modification, logging, caching, validation, etc.
  • Modularity: Promote a modular design where core functionalities stem from base classes/interfaces, and plugins offer additional features.

Conclusion

This source generator promises a robust method to extend and customize class/interface behavior during compile-time. By crafting "plugin" implementations that can encapsulate and override originals, we're paving the way for a modular and scalable software architecture.

Sources

Example

Usage:

// Unsealed class, original implementation.
public class MyClass : SomeBase, ISomething, ISomethingElse
{
    public void DoSomething() { }
    public void MyMethod() { } 
}

// Custom plugin derived from the generated plugin base class.
// `Inner` may be the original implementation, a plugin, or a collapsed chain of plugins.
public partial class LoggingPlugin : SomethingPlugin
{
    public LoggingPlugin(ISomething inner) : base(inner) { }

    public override void DoSomething()
    {
        Console.WriteLine("Before DoSomething");
        base.DoSomething();
        Console.WriteLine("After DoSomething");
    }
}

// Use the source generator to request a plugin and trigger Wrapper generation
MyClass original = new();

MyClass wrapped = original.CreatePlugin(plugins: x => new LoggingPlugin(x));

Generated code:

// Generated plugin base class (by the source generator)
// Generate virtual call delegation for all members in ISomething.
public partial class SomethingPlugin : ISomething, IDelegable<ISomething>
{
    protected ISomething Inner { get; }

    public SomethingPlugin(ISomething inner)
    {
        Inner = inner;
    }

    public virtual void DoSomething()
    {
        Inner.DoSomething();
    }
}

// Generated plugin container (by the source generator)
public class MyClassPluginContainer
{
    public ChainedProxyBuilder<ISomething> SomethingPlugins { get; } = new ChainedProxyBuilder<ISomething>();
    // ... other ChainedProxyBuilders for other interfaces and base class
}

// Generated plugin wrapper class (by the source generator)
public partial class MyClassWrapper : MyClass
{
    private readonly MyClass _inner;
    private readonly ISomething _innerSomething;

    public MyClassWrapper(MyClass inner, MyClassPluginContainer pluginContainer)
    {
        _inner = inner;
        _innerSomething = pluginContainer.SomethingPlugins.Execute(inner);
        // ... apply other plugins from the container
    }

    public override void DoSomething()
    {
        _innerSomething.DoSomething();
    }

    public override void MyMethod()
    {
        _inner.MyMethod();
    }
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.