Skip to content

longcanopi/rule_engine

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

32 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

rule_engine

rule_engine is a c++ rule engine library

dependency

  1. Antlr4

    to install antlr4, please see here

  2. rttr

    install rttr

  3. c++17

getting started

  1. Define the structs to be manipulated by rule_engine.

    struct Target {
        int age;
        std::string name;
    };
    
    struct Killer {
        bool has_bullet;
        Target target;
        void kill() {
            std::cout << "killing target: " << target.name << std::endl;
        }
    };
  2. Register the defined structs so that rule_engine can access them.

    RTTR_REGISTRATION {
        rttr::registration::class_<Killer>("Killer")
            .property("has_bullet", &Killer::has_bullet)
            .property("target", &Killer::target)
            .method("kill", &Killer::kill)
        ;
    
        rttr::registration::class_<Target>("Target")
            .property("age", &Target::age)
            .property("name", &Target::name)
        ;
    }
  3. in your main() function:

        // define your rule
        const char* rule = R"(
            rule kill "this is a description" {
                if 
                    Assassin.target.age > 18 && Assassin.has_bullet == true
                then
                    Assassin.kill();
                    Assassin.has_bullet = false;
            }
        )";
    
        Killer killer;
        killer.target.age = 19;
        killer.target.name = "chuck norris";
        killer.has_bullet = true;
    
        rule_engine::Engine e; // create an engine
        e.load_rules(rule);    // load your rule so that engine can execute it
        rule_engine::DataContext dctx;
    
        // register the object to data context so that rule engine can access
        // and manipulate it.
        dctx.add("Assassin", killer);  
        e.execute(&dctx); 
        assert(!killer.has_bullet);  
  4. for more complicated use case, please see here

advanced

Then Engine itself is stateless, it's safe to call execute concurrently. DataContext on the other hand not only contains objects to be accessed and manipulated by rules, but also caches intermediate data that accelerates expression evaluation. So it's users' responsibility to guard it when accessed by multiple threads. The best practice is to instantiate one DataContext for each thread, which eliminates locks and maximize performance.

About

rule_engine is a c++ rule engine library

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • C++ 92.7%
  • Java 6.0%
  • Other 1.3%