{"id":18954683,"url":"https://github.com/hellblazer/prime-mover","last_synced_at":"2026-01-03T03:15:28.921Z","repository":{"id":147576823,"uuid":"2311551","full_name":"Hellblazer/Prime-Mover","owner":"Hellblazer","description":"Event Driven Simulation Framework","archived":false,"fork":false,"pushed_at":"2025-04-06T00:32:11.000Z","size":7645,"stargazers_count":5,"open_issues_count":2,"forks_count":2,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-06T01:22:15.477Z","etag":null,"topics":["continuation","eventdriven","java","simulation"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Hellblazer.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2011-09-02T02:42:52.000Z","updated_at":"2025-04-06T00:28:47.000Z","dependencies_parsed_at":"2024-07-21T18:10:50.823Z","dependency_job_id":"9282a7de-4431-4cf8-b031-55db16f95cbb","html_url":"https://github.com/Hellblazer/Prime-Mover","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Hellblazer%2FPrime-Mover","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Hellblazer%2FPrime-Mover/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Hellblazer%2FPrime-Mover/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Hellblazer%2FPrime-Mover/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Hellblazer","download_url":"https://codeload.github.com/Hellblazer/Prime-Mover/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249184609,"owners_count":21226419,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["continuation","eventdriven","java","simulation"],"created_at":"2024-11-08T13:45:47.508Z","updated_at":"2026-01-03T03:15:28.915Z","avatar_url":"https://github.com/Hellblazer.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Prime Mover: Event-Driven Simulation Framework for Java\n\n![Build Status](https://github.com/hellblazer/prime-mover/actions/workflows/maven.yml/badge.svg)\n![License: AGPL v3](https://img.shields.io/badge/License-AGPL%20v3-blue.svg)\n![Java Version](https://img.shields.io/badge/Java-25%2B-blue)\n\nPrime Mover is a modern, high-performance discrete event simulation framework for Java. It uses bytecode transformation to convert regular Java code into event-driven simulations, with native support for blocking operations via Java virtual threads (Project Loom).\n\n## Quick Start\n\n### 1. Add Dependencies\n\nFirst, configure access to GitHub Packages in your `~/.m2/settings.xml`:\n\n```xml\n\u003csettings\u003e\n    \u003cservers\u003e\n        \u003cserver\u003e\n            \u003cid\u003egithub\u003c/id\u003e\n            \u003cusername\u003eYOUR_GITHUB_USERNAME\u003c/username\u003e\n            \u003cpassword\u003eYOUR_GITHUB_TOKEN\u003c/password\u003e\n        \u003c/server\u003e\n    \u003c/servers\u003e\n\u003c/settings\u003e\n```\n\n\u003e **Note**: Generate a GitHub Personal Access Token with `read:packages` scope at https://github.com/settings/tokens\n\nThen add the repository and dependencies to your `pom.xml`:\n\n```xml\n\u003crepositories\u003e\n    \u003crepository\u003e\n        \u003cid\u003egithub\u003c/id\u003e\n        \u003curl\u003ehttps://maven.pkg.github.com/Hellblazer/Prime-Mover\u003c/url\u003e\n    \u003c/repository\u003e\n\u003c/repositories\u003e\n\n\u003cpluginRepositories\u003e\n    \u003cpluginRepository\u003e\n        \u003cid\u003egithub\u003c/id\u003e\n        \u003curl\u003ehttps://maven.pkg.github.com/Hellblazer/Prime-Mover\u003c/url\u003e\n    \u003c/pluginRepository\u003e\n\u003c/pluginRepositories\u003e\n\n\u003cdependencies\u003e\n    \u003c!-- API for @Entity, Kronos, etc. --\u003e\n    \u003cdependency\u003e\n        \u003cgroupId\u003ecom.hellblazer.primeMover\u003c/groupId\u003e\n        \u003cartifactId\u003eapi\u003c/artifactId\u003e\n        \u003cversion\u003e1.0.5-SNAPSHOT\u003c/version\u003e\n    \u003c/dependency\u003e\n\n    \u003c!-- Runtime (needed for test/runtime) --\u003e\n    \u003cdependency\u003e\n        \u003cgroupId\u003ecom.hellblazer.primeMover\u003c/groupId\u003e\n        \u003cartifactId\u003eruntime\u003c/artifactId\u003e\n        \u003cversion\u003e1.0.5-SNAPSHOT\u003c/version\u003e\n        \u003cscope\u003etest\u003c/scope\u003e  \u003c!-- or compile if needed --\u003e\n    \u003c/dependency\u003e\n\u003c/dependencies\u003e\n```\n\n### 2. Configure Transformation\n\nChoose one of three transformation methods:\n\n**Option A: IntelliJ IDEA Plugin** (Recommended for IDE users)\n- Install from **Settings** \u003e **Plugins** \u003e Search \"Prime Mover\"\n- Automatically transforms classes on build\n- See [primemover-intellij-plugin/README.md](./primemover-intellij-plugin/README.md)\n\n**Option B: Maven Plugin** (Recommended for CI/CD)\n```xml\n\u003cbuild\u003e\n    \u003cplugins\u003e\n        \u003cplugin\u003e\n            \u003cgroupId\u003ecom.hellblazer.primeMover\u003c/groupId\u003e\n            \u003cartifactId\u003eprimemover-maven-plugin\u003c/artifactId\u003e\n            \u003cversion\u003e1.0.5-SNAPSHOT\u003c/version\u003e\n            \u003cexecutions\u003e\n                \u003cexecution\u003e\n                    \u003cphase\u003eprocess-classes\u003c/phase\u003e\n                    \u003cgoals\u003e\n                        \u003cgoal\u003etransform\u003c/goal\u003e\n                        \u003cgoal\u003etransform-test\u003c/goal\u003e\n                    \u003c/goals\u003e\n                \u003c/execution\u003e\n            \u003c/executions\u003e\n        \u003c/plugin\u003e\n    \u003c/plugins\u003e\n\u003c/build\u003e\n```\n\n**Option C: Runtime Java Agent** (For testing/prototyping)\n```bash\njava -javaagent:path/to/sim-agent.jar -cp ... YourSimulation\n```\n\n### 3. Write Your First Simulation\n\n```java\nimport com.hellblazer.primeMover.annotations.Entity;\nimport com.hellblazer.primeMover.api.Kronos;\nimport com.hellblazer.primeMover.controllers.SimulationController;\n\n@Entity\npublic class HelloWorld {\n    public static void main(String[] args) {\n        // Create simulation controller\n        SimulationController controller = new SimulationController();\n        Kronos.setController(controller);\n\n        // Schedule initial event\n        new HelloWorld().event1();\n\n        // Run simulation\n        controller.eventLoop();\n    }\n\n    public void event1() {\n        Kronos.sleep(1);           // Advance time by 1 unit\n        event1();                   // Schedule next occurrence\n        System.out.println(\"Hello @ \" + Kronos.currentTime());\n    }\n}\n```\n\n### 4. Build and Run\n\n```bash\n./mvnw clean package\njava -cp target/classes:... HelloWorld\n```\n\n## Key Concepts\n\n### Entities (`@Entity`)\n\nMark any class as a simulation entity - its methods become simulation events:\n\n```java\n@Entity\npublic class Bank {\n    public void openAccount(String name) {\n        System.out.println(\"Opening: \" + name);\n        Kronos.sleep(100);  // Advance simulation time\n        System.out.println(\"Account opened\");\n    }\n}\n```\n\nWhen called, methods don't execute directly - they're scheduled as time-ordered events.\n\n### Kronos API\n\nThe static API for simulation code:\n\n```java\nKronos.sleep(duration)              // Non-blocking time advance\nKronos.blockingSleep(duration)      // Blocking time advance\nKronos.currentTime()                // Query simulation time\nKronos.getController()              // Access the controller\nKronos.createChannel()              // Create inter-entity communication\n```\n\nAll these calls are rewritten during transformation to use the actual runtime implementation.\n\n### Blocking Operations (`@Blocking`)\n\nMark methods that need to suspend execution:\n\n```java\n@Entity\npublic class Task {\n    @Blocking\n    public void longOperation() {\n        Kronos.blockingSleep(1000);  // Suspends using virtual thread continuation\n        System.out.println(\"Done\");\n    }\n}\n```\n\nBlocking uses Java virtual threads - no threads actually block, just virtual continuations.\n\n### Controllers\n\nThe simulation engine that processes events:\n\n```java\n// Standard discrete event simulation\nSimulationController controller = new SimulationController();\ncontroller.eventLoop();\n\n// Step through events for debugging\nSteppingController controller = new SteppingController();\nwhile (controller.hasEvents()) {\n    controller.processOneEvent();\n}\n\n// Real-time paced simulation\nRealTimeController controller = new RealTimeController();\ncontroller.eventLoop();\n```\n\n## Architecture\n\n### Module Structure\n\n```\napi/                          - Public API (@Entity, Kronos, Controller)\n  |\nframework/ (runtime)          - Runtime implementation (Kairos, SimulationController)\n  |\ntransform/                    - Bytecode transformation engine\n  |\nprimemover-maven-plugin/      - Build-time transformation (Maven)\n  |\nprimemover-intellij-plugin/   - IDE integration (IntelliJ IDEA)\n  |\nsim-agent/                    - Runtime transformation (Java agent)\n  |\ndemo/                         - Example simulations\n  |\njanus/                        - Composite/mixin pattern support\n  |\nspace-ghost/                  - Example application using Janus\n  |\ndesmoj-ish/                   - DESMOJ-compatible simulation framework\n  |\nmaven-testing/                - Plugin testing infrastructure\n```\n\n### Transformation Pipeline\n\n```\nOriginal Java Code (@Entity classes)\n    |\n    v\nBytecode Transformation (ClassFile API)\n    - Identify event methods\n    - Rewrite method calls to event scheduling\n    - Generate EntityReference for dispatch\n    - Rewrite Kronos -\u003e Kairos\n    |\n    v\nTransformed Bytecode\n    |\n    v\nExecution (Virtual Threads + Priority Queue)\n    - Events execute in time order\n    - Blocking suspends/resumes continuations\n    - Concurrent entities at same time\n    |\n    v\nSimulation Results\n```\n\n## Performance\n\n**Typical Performance**:\n- **Event Throughput**: 50,000+ events per second\n- **Blocking Events**: 600+ blocking events per second\n- **Memory Efficiency**: Minimal overhead with virtual threads\n- **Scales Linearly**: With available CPU cores\n\n## Documentation\n\n### Conceptual Foundations\n\n- **[CONCEPTS.md](./CONCEPTS.md)** - Deep-dive into DES theory, Kronos/Kairos design, event semantics, and virtual thread continuations\n\n### Module Documentation\n\nEach module has detailed documentation:\n\n- **[api/README.md](./api/README.md)** - Public API and annotations\n- **[framework/README.md](./framework/README.md)** - Runtime implementation and controllers\n- **[transform/README.md](./transform/README.md)** - Bytecode transformation details\n- **[primemover-maven-plugin/README.md](./primemover-maven-plugin/README.md)** - Build-time integration (Maven)\n- **[primemover-intellij-plugin/README.md](./primemover-intellij-plugin/README.md)** - IDE integration (IntelliJ IDEA)\n- **[sim-agent/README.md](./sim-agent/README.md)** - Runtime transformation via Java agent\n- **[demo/README.md](./demo/README.md)** - Example programs and patterns\n- **[janus/README.md](./janus/README.md)** - Composite/mixin pattern support\n- **[desmoj-ish/README.md](./desmoj-ish/README.md)** - DESMOJ-compatible simulation features\n- **[CLASSFILE_API_ANALYSIS.md](./CLASSFILE_API_ANALYSIS.md)** - Technical deep-dive on ClassFile API\n\n## Build and Test\n\n**Requirements**: Java 25 or later (GraalVM recommended)\n\n```bash\n# Build entire project\n./mvnw clean install\n\n# Build specific module\n./mvnw clean install -pl api\n\n# Run tests\n./mvnw test\n\n# Run specific test\n./mvnw test -pl demo -Dtest=TestClassName\n\n# Build with verbose output\n./mvnw clean install -X\n```\n\n## Current Status\n\n**Version**: 1.0.5-SNAPSHOT\n\n**Recent Changes**:\n- IntelliJ IDEA plugin released for seamless IDE integration\n- Migrated from ASM to Java 25 ClassFile API (complete)\n- Removed external bytecode manipulation dependencies\n- Full virtual thread (Project Loom) support\n- Enhanced documentation and examples\n- Published to GitHub Packages\n\n**Roadmap**:\n- Performance optimization\n- More example simulations\n- Advanced debugging tools\n- Tutorial documentation\n- Additional IDE integrations (Eclipse, VS Code)\n\n## Transformation Example\n\n**Original Code**:\n```java\n@Entity\npublic class Account {\n    public void deposit(double amount) {\n        Kronos.sleep(50);\n        System.out.println(\"Deposited: \" + amount);\n    }\n}\n```\n\n**After Transformation** (conceptual):\n```java\n@Transformed\n@Entity\npublic class Account implements EntityReference {\n\n    // Generated dispatch method - invoked by Controller\n    public Object __invoke(int eventIndex, Object[] args) throws Throwable {\n        return switch (eventIndex) {\n            case 0 -\u003e { __event_deposit((Double) args[0]); yield null; }\n            default -\u003e throw new IllegalArgumentException(\"Unknown event: \" + eventIndex);\n        };\n    }\n\n    // Generated signature method - for debugging\n    public String __signatureFor(int eventIndex) {\n        return switch (eventIndex) {\n            case 0 -\u003e \"deposit(double)\";\n            default -\u003e throw new IllegalArgumentException(\"Unknown event: \" + eventIndex);\n        };\n    }\n\n    // Original public method - now schedules event\n    public void deposit(double amount) {\n        Kairos.getController().postContinuingEvent(this, 0, amount);\n    }\n\n    // Original implementation renamed - executed by framework\n    public void __event_deposit(double amount) {\n        Kairos.sleep(50);  // Rewritten from Kronos\n        System.out.println(\"Deposited: \" + amount);\n    }\n}\n```\n\nThe entity class becomes its own `EntityReference` implementation with `__invoke()` and `__signatureFor()` methods.\n\n## Advanced Features\n\n### Inter-Entity Communication\n\nUse synchronous channels for safe communication:\n\n```java\n@Entity\npublic class Producer {\n    public void produce(SynchronousQueue\u003cString\u003e channel) {\n        channel.put(\"item\");\n    }\n}\n\n@Entity\npublic class Consumer {\n    public void consume(SynchronousQueue\u003cString\u003e channel) {\n        String item = channel.take();  // Blocks until item available\n    }\n}\n```\n\n### Composite Entities (Janus)\n\nCombine multiple behaviors using the Janus mixin system:\n\n```java\npublic interface ComplexAgent extends Movable, Communicative, Intelligent {\n}\n\nvar assembler = Composite.instance();\nComplexAgent agent = assembler.assemble(ComplexAgent.class,\n    new Composite.CompositeClassLoader(getClass().getClassLoader()),\n    new MovementBehavior(),\n    new CommunicationBehavior(),\n    new DecisionMaking());\n```\n\n### DESMOJ-Compatible API\n\nFor users familiar with DESMOJ, there's a compatibility layer with distributions, queues, and resources.\n\n## Repository Structure\n\n```\nPrime-Mover/\n├── README.md                     (this file)\n├── CLAUDE.md                     (AI assistant guidance)\n├── CLASSFILE_API_ANALYSIS.md    (technical analysis)\n├── CONCEPTS.md                   (conceptual deep-dive)\n├── pom.xml                       (root Maven POM)\n├── api/                          (public API module)\n├── framework/                    (runtime module)\n├── transform/                    (transformation engine)\n├── primemover-maven-plugin/      (Maven plugin)\n├── primemover-intellij-plugin/   (IntelliJ IDEA plugin)\n├── sim-agent/                    (Java agent)\n├── demo/                         (examples)\n├── janus/                        (composite/mixin)\n├── space-ghost/                  (example app)\n├── desmoj-ish/                   (DESMOJ compatibility)\n└── maven-testing/                (plugin testing)\n```\n\n## License\n\nLicensed under AGPL v3.0. See [LICENSE](./LICENSE) for details.\n\n## Contributing\n\nContributions welcome! Please ensure:\n- Java 25+ code style (modern patterns, `var`, virtual threads)\n- All tests pass (`./mvnw test`)\n- Documentation updated\n- Clear commit messages\n\n## Troubleshooting\n\n### Common Issues\n\n**`UnsupportedOperationException` when calling Kronos methods**\n- **Cause**: Code is not transformed. Kronos methods throw by default and are rewritten to Kairos during transformation.\n- **Fix**: Ensure transformation is configured (Maven plugin, IntelliJ plugin, or sim-agent).\n\n**Classes not being transformed**\n- **Cause**: Missing `@Entity` annotation or wrong import.\n- **Fix**: Verify `import com.hellblazer.primeMover.annotations.Entity` (not javax.persistence.Entity).\n\n**`NoClassDefFoundError` for Kairos**\n- **Cause**: Runtime dependency missing.\n- **Fix**: Add `runtime` artifact to dependencies with appropriate scope.\n\n**Events executing in unexpected order**\n- **Cause**: Misunderstanding event scheduling vs direct execution.\n- **Fix**: Remember that method calls on `@Entity` classes schedule events at the current simulation time. Use `Kronos.sleep()` to advance time between events.\n\n**Blocking method not suspending**\n- **Cause**: Missing `@Blocking` annotation or not using `blockingSleep()`.\n- **Fix**: Mark method with `@Blocking` and use `Kronos.blockingSleep()` instead of `sleep()`.\n\n### Debugging Tips\n\n1. Use `SteppingController` to step through events one at a time\n2. Check `controller.getTotalEvents()` to verify events are being scheduled\n3. Enable logging to see event posting and execution\n4. Verify transformation with `javap -c YourClass` to inspect bytecode\n\n## Getting Help\n\n1. **Read the module READMEs** - Each module has detailed documentation\n2. **Review examples** - See `demo/` module for usage patterns\n3. **Check CLASSFILE_API_ANALYSIS.md** - Technical deep-dive on transformation\n4. **Run demos** - Execute example programs to understand concepts\n\n## Contact\n\nFor questions, issues, or suggestions:\n- Open an issue on GitHub\n- Visit the repository: https://github.com/hellblazer/Prime-Mover\n\n---\n\n**Happy simulating!**\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhellblazer%2Fprime-mover","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhellblazer%2Fprime-mover","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhellblazer%2Fprime-mover/lists"}