Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 5 additions & 23 deletions include/Gaffer/Reference.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ namespace Gaffer

IE_CORE_FORWARDDECLARE( StringPlug )

/// \deprecated Use Box instead.
class GAFFER_API Reference : public SubGraph
{

Expand All @@ -55,40 +56,21 @@ class GAFFER_API Reference : public SubGraph

GAFFER_NODE_DECLARE_TYPE( Gaffer::Reference, ReferenceTypeId, SubGraph );

/// Loads the specified script, which should have been exported
/// using Box::exportForReference().
/// \undoable.
/// \deprecated Use `SubGraph::loadReference()` instead.
void load( const std::filesystem::path &fileName );
/// Returns the name of the script currently being referenced.
/// \deprecated Use `SubGraph::referenceFileName()` instead.
const std::filesystem::path &fileName() const;

/// \deprecated Use `SubGraph::referenceChangedSignal()` instead.
using ReferenceLoadedSignal = Signals::Signal<void ( Reference * )>;
/// Emitted when a reference is loaded (or unloaded following an undo).
ReferenceLoadedSignal &referenceLoadedSignal();

/// Edits
/// =====
///
/// Edits are changes to referenced plugs that are made by the user
/// after the reference has been loaded via `load()`. The Reference
/// node provides some limited tracking of edits, exposing them
/// via the following methods.

bool hasMetadataEdit( const Plug *plug, const IECore::InternedString key ) const;
/// Returns true if `plug` has been added as a child of a referenced plug.
bool isChildEdit( const Plug *plug ) const;

private :

void loadInternal( const std::filesystem::path &fileName );
bool isReferencePlug( const Plug *plug ) const;
void referenceChanged();

std::filesystem::path m_fileName;
ReferenceLoadedSignal m_referenceLoadedSignal;

class PlugEdits;
std::unique_ptr<PlugEdits> m_plugEdits;

};

IE_CORE_DECLAREPTR( Reference )
Expand Down
62 changes: 57 additions & 5 deletions include/Gaffer/SubGraph.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@

#include "Gaffer/DependencyNode.h"

#include <filesystem>

namespace Gaffer
{

Expand All @@ -55,6 +57,46 @@ class GAFFER_API SubGraph : public DependencyNode

GAFFER_NODE_DECLARE_TYPE( Gaffer::SubGraph, SubGraphTypeId, DependencyNode );

/// Referencing
/// -----------
///
/// By default, a SubGraph's internal nodes are considered to be local,
/// meaning that they are serialised into the same `.gfr` file as the
/// SubGraph itself. In this state, the child nodes are user-editable.
/// Alternatively, SubGraphs may reference child nodes stored externally
/// in a separate `.grf` file. This allows self-contained node graphs
/// to be published and then referenced into multiple `.gfr` files. When
/// referencing, the child nodes are not user-editable.

/// Loads a previously exported `.grf` file, replacing the internal node graph.
void loadReference( const std::filesystem::path &fileName );

/// Returns the referenced file. If `isReference()` is false, returns an
/// empty path.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment ends up being a bit strange in the commit history, because the isReference() function referenced here doesn't exist until a later commit ... but it seems like it does make sense by the end of this PR.

const std::filesystem::path &referenceFileName() const;

using ReferenceChangedSignal = Signals::Signal<void ( SubGraph * )>;
/// Emitted when `referenceFileName()` changes, or when a reference
/// is reloaded.
ReferenceChangedSignal &referenceChangedSignal();

/// Reference Edits
/// ===============
///
/// Although child nodes can not be edited when referenced, promoted
/// plugs can be. This allows the user to control the internal network
/// via an interface defined when the reference was published.
///
/// The SubGraph node provides some - currently limited - tracking of
//// such edits, exposing them via the following methods.

bool hasMetadataEdit( const Plug *plug, const IECore::InternedString key ) const;
/// Returns true if `plug` has been added as a child of a referenced plug.
bool isChildEdit( const Plug *plug ) const;

/// DependencyNode API
/// ------------------

/// Does nothing
void affects( const Plug *input, AffectedPlugsContainer &outputs ) const override;

Expand All @@ -63,14 +105,24 @@ class GAFFER_API SubGraph : public DependencyNode
const BoolPlug *enabledPlug() const override;

/// Implemented to allow a user to define a pass-through behaviour
/// by wiring the nodes inside this sub graph up appropriately. The
/// input to the output plug must be connected from a node inside
/// the sub graph, where that node itself has its enabled plug driven
/// by the external enabled plug, and the correspondingInput for the
/// node comes from one of the inputs to the sub graph.
/// by connecting to the `passThrough` plug of an internal BoxOut node.
Plug *correspondingInput( const Plug *output ) override;
const Plug *correspondingInput( const Plug *output ) const override;

private :

void loadReferenceInternal( const std::filesystem::path &fileName );
bool isReferencePlug( const Plug *plug ) const;

ReferenceChangedSignal m_referenceChangedSignal;

class PlugEdits;
struct ReferenceState;
// Initialised lazily, when we first load a reference.
std::unique_ptr<ReferenceState> m_referenceState;

};

IE_CORE_DECLAREPTR( SubGraph )

} // namespace Gaffer
Loading