Class: Pikuri::Skill::Activation

Inherits:
Object
  • Object
show all
Defined in:
lib/pikuri/skill/activation.rb,
lib/pikuri/skill/activation/open.rb,
lib/pikuri/skill/activation/sealed.rb

Overview

Which of a catalog's gated skills are in play this conversation. A skill declaring paths: is withheld until a tool touches a matching file; until it fires, it is unloadable by name and invisible to a refusal's list of what does exist:

activation = Activation.new(catalog: catalog)
activation.get('writing-rdoc')          # => nil — withheld, same as an unknown name
activation.activate([rdoc])             # => [rdoc]  — announce these
activation.activate([rdoc])             # => []      — already announced
activation.get('writing-rdoc')          # => #<Skill name="writing-rdoc" …>
activation.reset                        # a cleared conversation re-hides it

Implementation details

Neither this state nor the gate lives on the Catalog: it is frozen, session-less and shared, and a filtered Catalog#get would also lie to an installed-skills listing. The catalog keeps telling the truth about what is on disk; every invocation route resolves through here instead.

Thread-safe.

Defined Under Namespace

Classes: Open, Sealed

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(catalog:) ⇒ Activation

Returns a new instance of Activation.

Parameters:



29
30
31
32
33
# File 'lib/pikuri/skill/activation.rb', line 29

def initialize(catalog:)
  @catalog = catalog
  @activated = Set.new
  @mutex = Mutex.new
end

Instance Attribute Details

#catalogPikuri::Skill::Catalog (readonly)

Returns the unfiltered catalog behind this view.

Returns:



36
37
38
# File 'lib/pikuri/skill/activation.rb', line 36

def catalog
  @catalog
end

Instance Method Details

#activate(skills) ⇒ Array<Pikuri::Skill::Catalog::Skill>

Record a promotion and answer what is new: a skill is announced at most once per conversation, however many matching files are touched.

Parameters:

Returns:



70
71
72
# File 'lib/pikuri/skill/activation.rb', line 70

def activate(skills)
  @mutex.synchronize { skills.select { |skill| @activated.add?(skill.name) } }
end

#get(name) ⇒ Pikuri::Skill::Catalog::Skill?

Catalog#get as this conversation sees it.

Parameters:

  • name (String)

Returns:

  • (Pikuri::Skill::Catalog::Skill, nil)

    nil when withheld — which is the same answer a name that exists nowhere gets, so a refusal cannot be read as "exists, but hidden"



54
55
56
# File 'lib/pikuri/skill/activation.rb', line 54

def get(name)
  in_play?(name) ? @catalog.get(name) : nil
end

#in_play?(name) ⇒ Boolean

Returns false for an unknown name, and for a gated skill whose path has not fired yet.

Parameters:

  • name (String)

Returns:

  • (Boolean)

    false for an unknown name, and for a gated skill whose path has not fired yet



41
42
43
44
45
46
# File 'lib/pikuri/skill/activation.rb', line 41

def in_play?(name)
  skill = @catalog.get(name)
  return false if skill.nil?

  !skill.gated? || @mutex.synchronize { @activated.include?(name) }
end

#namesArray<String>

Returns sorted names in play; the only enumeration a refusal or a listing may recite.

Returns:

  • (Array<String>)

    sorted names in play; the only enumeration a refusal or a listing may recite



60
61
62
# File 'lib/pikuri/skill/activation.rb', line 60

def names
  @catalog.list.filter_map { |skill| skill.name if in_play?(skill.name) }.sort
end

#resetvoid

This method returns an undefined value.

Re-hide every gated skill.



77
78
79
80
# File 'lib/pikuri/skill/activation.rb', line 77

def reset
  @mutex.synchronize { @activated.clear }
  nil
end