Skip to content
This repository has been archived by the owner on Sep 22, 2024. It is now read-only.

Commit

Permalink
Merge pull request #6 from metatablecatgames/docs-dev
Browse files Browse the repository at this point in the history
API reference
  • Loading branch information
metatablecat authored Apr 19, 2024
2 parents 85900c8 + c7acc49 commit 494aa12
Show file tree
Hide file tree
Showing 9 changed files with 561 additions and 8 deletions.
98 changes: 97 additions & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,100 @@

# Catwork

This is a landing page.
## The cat framework, written by cats, for cats!

Catwork is a tiny, ergonomic, declarative framework for creating runtime code.

---

## Weave dependencies with asynchronous design patterns.

Catwork implements all of its code through Fragments! These allow you to manage
dependencies in a simple and easy to understand way!

```lua title="MeowService.lua"
return Catwork.Fragment {
Init = function(self)
task.wait(1)
self.Value = "cat"
end,

ConsumeValue = function(self)
print(self.Value)
end
}
```

```lua
local MeowService = require(script.MeowService)

MeowService:Await() -- waits for the service to initialise before grabbing the value

-- If we called this without awaiting, it'd print nothing, Catwork wraps messy
-- asynchronous design behind `Await` and `HandleAsync`
MeowService:ConsumeValue()
```

---

## You build the framework!

Catwork exports an object called a `Service`, this lets you add almost any
behaviour to Fragments beyond what Catwork originally allows.

```lua title="RemoteService.lua"
return Catwork.Service {
Name = "RemoteService",

Fragment = function(self, params)
params.Remote = makeRemote(params)
return Catwork:CreateFragmentForService(params, self)
end,

Spawning = function(self, f)
if f.RemoteConnection then
f.Remote.OnServer:Connect(f.RemoteConnection)
end
end
}
```

```lua

local MeowRemote = RemoteService:Fragment {
Name = "MeowRemote",

RemoteConnection = function(plr)
print(`meows as {plr.Name} cutely`)
end
}
```

---

## Run Fragments, anywhere.

Catwork doesn't care about what you return, only that you call one of it's
constructors.

This means as long as the code is executed, you can create a Fragment just about
anywhere, a ModuleScript? A Script? Go for it!

```lua title="LocalScript in ReplicatedFirst"
local Catwork = require(ReplicaedFirst.Catwork)

local LoadingScreenManager = Catwork.Fragment {
Name = "LoadingScreenManager",

Init = function()
ReplicatedFirst:RemoveDefaultLoadingScreen()
-- code to execute guis or whatever
end
}
```

---

# Lets go on an adventure together

Ready to start with Catwork? Then lets go into the tutorials!
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Fragment

The basic building block of all running Catwork code.

!!! note
Due to the dynamic nature of Fragments, this documentation only describes
the built-in logic.
Expand Down
File renamed without changes.
182 changes: 182 additions & 0 deletions docs/reference/catwork/service.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
# Service

Services are singletons that let you change how Fragments behave.

??? tip "TemplateServices are now implicit"
Catwork previously had an explicit method called `Catwork.TemplateService`,
this has since been removed. You now simply need to use one of two methods
to enable templates

=== "Explicit"
```lua
return Catwork.Service {
EnableTemplates = true
}
```
=== "Implicit"
```lua
return Catwork.Service {
TemplateAdded = function(self, template)

end
}
```

## Properties

### Service.EnableTemplates

`boolean`

Dictates if the service is a TemplateService, and that methods such as `Template`
can be used.

!!! warning "Assume template methods are undefined if this property is `false`"
This setting disables all template logic, however, some objects may be left
over such as the `Service.Templates` table.

### Service.Fragments

`{[string]: Fragment<any>}`

A table representing which fragments belong to this specific Service, these
are stored the same way as Catwork.Fragments(1).
{ .annotate}

1. Fragments are stored using the format
`{Fragment.Service.Name}_{Fragment.ID}`

### Service.FragmentNameStore

`{[string]: {[string]: Fragment<any>}}`

An internal storage tree for `Service.GetFragmentsOfName`.

!!! danger "Do not use this property externally"
This table is unpredictable, it is safer to use `GetFragmentsOfName` as this
returns an immutable chunk of this data

### Service.Templates

`{[string]: Template}`

A storage table of this service's templates.

## Callbacks

These are built-in lifecycle callbacks that you can define in your Service.
They are generally defined as the following syntax in `Catwork.Service`:

```lua
Catwork.Service {
Fragment = function(self, params)

end
}
```

### Service.Fragment

Defined as `Fragment = function(self, params)`

The main method for constructing fragments out of the service. This method
is provided with a list of parameters that are then built into a Fragment.

```lua
Fragment = function(self, params)
function params:Meow()
return "meow!!!"
end

return Catwork:CreateFragmentForService(params, self)
end
```

This is eventually transformed into the method `Service:Fragment`.

!!! warning "You MUST call `CreateFragmentForService`"
This method links up everything internal related to the fragment, and must
be called **once** in your `Fragment` callback definition.

### Service.FragmentAdded

Defined as `FragmentAdded = function(self, Fragment<any>)`

This method is invoked just after a `CreateFragmentForService` call, and
represents the actual Fragment, and not just a tree of constructed parameters.

This callback is intended for setting up code around the fragment, instead of
enforcing it's shape.

### Service.FragmentRemoved

Defined as `FragmentRemoved = function(self, Fragment<any>)`

Invoked after a Fragment has been destroyed, this method should be used for
definining internal cleanup logic.

### Service.Spawning

Defined as `Spawning = function(self, Fragment<any>)`

The asynchronous entry point that is called when `Fragment:Spawn` is called.
Since this callback executed asynchronously, it is safe to perform stateful code
here as it's escaped from the declarative callbacks of `Fragment` and `FragmentAdded`.

??? question "Fragment, FragmentAdded or Spawning?"
`Service.Fragment` should be used for setting up the Fragment itself, but
should not perform any runtime behaviour.

`Service.FragmentAdded` should react to constructed fragments, and may perform
simple runtime actions that do not require state. FragmentAdded should also (but
does not have to) call `Spawn`.

`Service.Spawning` runs in an asynchronous thread, and stateful runtime behaviour
should be performed here.

### Service.TemplateAdded

Defined as `TemplateAdded = function(self, Template)`

Invoked when a new Template is added through `Service:Template`. The definition
of this key implicitly enables `TemplateServices`.


## Methods

## Service:CreateFragmentFromTemplate

`<A>(Template|string, A) -> Fragment<A>`

Creates a fragment from a given template, or template identifier. This function
will error if the template identifier is nil.

!!! danger "Dont give this templates from other services"
This creates undefined behaviour, keep templates to their own service.

## Service:GetFragmentsOfName

`(name: string) -> {[string]: Fragment<A>}`

Returns an immutable chunk from `Service.FragmentNameStore`, of all fragments
defined with the given name. Keys of the return table are full fragment IDs(1)
of each fragment.
{.annotate}

1. Fragments are stored using the format
`{Fragment.Service.Name}_{Fragment.ID}`

## Service:Template

`(TemplateParams) -> Template`

Builds a template from the given params table.

```lua
Service:Template {
Name = "CatGenerator",
CreateFragment = function(self, fragment)

end
}
```
29 changes: 29 additions & 0 deletions docs/reference/catwork/template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Template

Templates are small factory objects that create Fragments. Unlike other objects,
they are incredibly simple.

## Properties

### Template.Name

`string`

The unique identifier for the template, each Service may only have one template
of the given name.

### Template.Service

`Service`

The service this template originates from, and should be the only service you
create it with.

## Methods

### Template:CreateFragment

`<A>(A) -> Fragment<A>`

Builds a Fragment using the template and given parameters, returns the Fragment
after being created.
Loading

0 comments on commit 494aa12

Please sign in to comment.